-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
중복선택 버튼 컴포넌트 (체크박스) 작성 #27
Changes from 7 commits
83ec37b
6124c7a
4691b4c
71ef0c0
32d081e
e7bb5ab
4f3e5ba
b11f3a8
775bfc8
c356813
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { css } from "@emotion/react"; | ||
import { useContext } from "react"; | ||
|
||
import ListItemCard from "@/component/common/Card/ListItemCard"; | ||
import { CheckBoxContext } from "@/store/context/CheckBoxContext"; | ||
|
||
type CheckBoxProps = { | ||
value: string; | ||
children: React.ReactNode; | ||
}; | ||
|
||
const CheckBox = ({ value, children }: CheckBoxProps) => { | ||
const checkboxContext = useContext(CheckBoxContext); | ||
return ( | ||
<ListItemCard variant={checkboxContext?.isChecked(value) ? "theme" : "default"}> | ||
<label | ||
htmlFor={value} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
css={css` | ||
font-weight: 600; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100%; | ||
width: 100%; | ||
cursor: pointer; | ||
`} | ||
> | ||
{children} | ||
</label> | ||
<input | ||
type="checkbox" | ||
id={value} | ||
value={value} | ||
onChange={(e) => { | ||
checkboxContext?.onChange && checkboxContext.onChange(e.target.value); | ||
}} | ||
css={css` | ||
display: none; | ||
`} | ||
/> | ||
</ListItemCard> | ||
); | ||
}; | ||
|
||
export default CheckBox; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { css } from "@emotion/react"; | ||
|
||
import { CheckBoxContext, CheckBoxContextState } from "@/store/context/CheckBoxContext"; | ||
|
||
type CheckBoxGroupProps = { | ||
children: React.ReactNode; | ||
} & CheckBoxContextState; | ||
|
||
const CheckBoxGroup = ({ children, ...props }: CheckBoxGroupProps) => { | ||
return ( | ||
<div | ||
css={css` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1rem; | ||
`} | ||
> | ||
<CheckBoxContext.Provider value={props}>{children}</CheckBoxContext.Provider> | ||
</div> | ||
); | ||
}; | ||
|
||
export default CheckBoxGroup; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { useState } from "react"; | ||
|
||
import { CheckBoxContextState } from "@/store/context/CheckBoxContext"; | ||
|
||
type UseCheckBoxReturn = [CheckBoxContextState["isChecked"], CheckBoxContextState["onChange"], string[]]; | ||
|
||
export const useCheckBox = (): UseCheckBoxReturn => { | ||
const [checkedStates, setCheckedStates] = useState<Record<string, boolean>>({}); | ||
const isChecked = (value: string) => checkedStates[value]; | ||
const toggle = (value: string) => setCheckedStates((prev) => ({ ...prev, [value]: !prev[value] })); | ||
const selectedValues = Object.keys(checkedStates).filter((key) => checkedStates[key]); | ||
return [isChecked, toggle, selectedValues]; | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,13 @@ | ||||||||||||||||||||||||||||||||||||||
import { useState } from "react"; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
import { RadioContextState } from "@/store/context/RadioContext"; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
type UseRadioButtonReturn = [RadioContextState["isChecked"], RadioContextState["onChange"], string | undefined]; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
export const useRadioButton = (): UseRadioButtonReturn => { | ||||||||||||||||||||||||||||||||||||||
const [selectedValue, setSelectedValue] = useState<string>(); | ||||||||||||||||||||||||||||||||||||||
const isChecked = (value: string) => selectedValue === value; | ||||||||||||||||||||||||||||||||||||||
const onChange = (value: string) => setSelectedValue(value); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return [isChecked, onChange, selectedValue]; | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
저는 custom hook에서 배열로 반환 시 return type을 설정해줄 때 as const로 명시해주는게 깔끔하더라구요~!! 별개로 object return 이 아닌 array return을 채택하신 이유도 궁금해요~!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아!! 맞네요 as const로 수정하겠습니다! 감사합니다 🙇♀️ +) Staging.tsx 파일에 예시 작성하면서 라디오버튼과 체크박스를 같이 사용할 때 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자세한 설명 감사합니다👍👍 |
||||||||||||||||||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { createContext } from "react"; | ||
|
||
export type CheckBoxContextState = { | ||
isChecked: (value: string) => boolean; | ||
onChange: (value: string) => void; | ||
}; | ||
|
||
export const CheckBoxContext = createContext<CheckBoxContextState | undefined>(undefined); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
import { createContext } from "react"; | ||
|
||
type RadioContextState = { | ||
export type RadioContextState = { | ||
radioName: string; | ||
selectedValue?: string; | ||
onChange?: (value: string) => void; | ||
isChecked: (value: string) => boolean; | ||
onChange: (value: string) => void; | ||
}; | ||
|
||
export const RadioContext = createContext<RadioContextState | undefined>(undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용방법이 직관적이어서 좋네요!!