forked from woowacourse-teams/2024-code-zap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDropdown.tsx
75 lines (70 loc) · 1.91 KB
/
Dropdown.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { chevron } from '@/assets/images';
import * as S from './Dropdown.style';
interface Props<T> {
dropdownRef: React.MutableRefObject<HTMLDivElement | null>;
isOpen: boolean;
toggleDropdown: () => void;
options: T[];
getOptionLabel: (option: T) => string;
currentValue: T;
handleCurrentValue: (value: T) => void;
replaceChildrenWhenIsOpen?: React.ReactNode;
}
const Dropdown = <T,>({
dropdownRef,
isOpen,
toggleDropdown,
options,
getOptionLabel,
currentValue,
handleCurrentValue,
replaceChildrenWhenIsOpen,
}: Props<T>) => (
<S.DropdownContainer ref={dropdownRef}>
<S.Wrapper>
{isOpen ? (
replaceChildrenWhenIsOpen || (
<SelectedButton
isOpen={isOpen}
toggleDropdown={toggleDropdown}
getOptionLabel={getOptionLabel}
currentValue={currentValue}
/>
)
) : (
<SelectedButton
isOpen={isOpen}
toggleDropdown={toggleDropdown}
getOptionLabel={getOptionLabel}
currentValue={currentValue}
/>
)}
</S.Wrapper>
{isOpen && (
<S.OptionList>
{options?.map((option, idx) => (
<S.Option key={idx} onClick={() => handleCurrentValue(option)}>
{getOptionLabel(option)}
</S.Option>
))}
</S.OptionList>
)}
</S.DropdownContainer>
);
export default Dropdown;
type SelectedButtonProps<T> = Pick<Props<T>, 'toggleDropdown' | 'getOptionLabel' | 'currentValue' | 'isOpen'>;
const SelectedButton = <T,>({ toggleDropdown, getOptionLabel, currentValue, isOpen }: SelectedButtonProps<T>) => (
<S.SelectedButton onClick={toggleDropdown}>
{getOptionLabel(currentValue)}
<img
src={chevron}
width={24}
height={24}
alt=''
css={{
transition: 'transform 0.3s ease',
transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
}}
/>
</S.SelectedButton>
);