Select
합성 컴포넌트 구현Root
, Trigger
, Content
, Option
컴포넌트로 구성된 Select 컴포넌트를 구현했습니다.
Trigger
컴포넌트는 선택된 옵션을 트리거로 렌더링하며, 아이콘을 옵셔널하게 받을 수 있도록 했습니다.
type Props = {
icon?: ReactNode;
} & PropsWithChildren;
Option
컴포넌트는 value
와 onClick
을 통해 옵션이 선택될 때 실행될 동작을 정의했습니다.
type Props = {
value: string;
onClick?: () => void;
} & PropsWithChildren;
useSelect
, useGlobalSelect
커스텀훅 구현useSelect
useSelect
커스텀훅은 옵션들의 상태값에 따라 렌더링 될 수 있도록 하는 역할을 합니다.
옵션 배열에서 첫 번째 옵션을 초기값으로 설정하며, handleSelect
함수를 통해 옵션 선택 시 상태를 업데이트하는 역할을 수행합니다.
const { selectedOption, handleSelect } = useSelect(filterOptions[0]);
import theme from '@/assets/theme';
import { Select, Icon, List } from '@/components/common';
import useSelect from '@/components/common/Select/hooks/useSelect';
const filterOptions = [
{
value: 'all',
text: '전체',
action: () => console.log('All clicked'),
},
{
value: 'age',
text: '나이',
action: () => console.log('Age clicked'),
},
{
value: 'area',
text: '지역',
action: () => console.log('Area clicked'),
},
];
const triggerStyle = { minWidth: '80px', fontSize: '16px', fontWeight: '700', color: theme.palettes.blue };
export default function RecruitmentFilter() {
const { selectedOption, handleSelect } = useSelect(filterOptions[0]);
return (
<Select.Root>
<Select.Trigger icon={<Icon.Arrow.DownBlue />} css={triggerStyle}>
{selectedOption.text}
</Select.Trigger>
<Select.Content>
<List
items={filterOptions}
renderItem={(option) => (
<Select.Option key={option.value} value={option.value} onClick={() => handleSelect(option)}>
{option.text}
</Select.Option>
)}
/>
</Select.Content>
</Select.Root>
);
}
useGlobalSelect
useSelect
와 유사하나, 선택한 옵션을 로컬 스토리지(localStorage
)에 저장하여 페이지를 이동해도 선택 상태를 유지할 수 있습니다.
const { selectedOption, handleSelect } = useGlobalSelect(languageOptions[0]);
import theme from '@/assets/theme';
import { Select, Icon, List } from '@/components/common';
import useGlobalSelect from '@/components/common/Select/hooks/useGlobalSelect';
const languageOptions = [
{
value: 'korean',
text: '한국어',
action: () => console.log('한국어'),
},
{
value: 'vietnamese',
text: '베트남어',
action: () => console.log('베트남어'),
},
];
export default function LanguageFilter() {
const { selectedOption, handleSelect } = useGlobalSelect(languageOptions[0]);
return (
<Select.Root>
<Select.Trigger icon={<Icon.Arrow.DownBlue />} css={triggerStyle}>
{selectedOption.text}
</Select.Trigger>
<Select.Content>
<List
items={languageOptions}
renderItem={(option) => (
<Select.Option key={option.value} value={option.value} onClick={() => handleSelect(option)}>
{option.text}
</Select.Option>
)}
/>
</Select.Content>
</Select.Root>
);
}