Skip to content

Commit e5f9b41

Browse files
committed
Refactor: Select 코드 개선
1 parent af032c5 commit e5f9b41

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

src/components/Select.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
useRef,
55
ReactNode,
66
SelectHTMLAttributes,
7+
useMemo,
78
} from "react";
89

910
import { DropdownDown, DropdownUp } from "@/assets/icon";
@@ -32,7 +33,6 @@ interface SelectProps
3233
placeholder?: string;
3334
size?: keyof typeof sizeMap;
3435
fullWidth?: boolean;
35-
width?: number | string;
3636
className?: string;
3737
wrapperClassName?: string;
3838
}
@@ -68,18 +68,19 @@ function Select({
6868
placeholder = "선택",
6969
size = "lg",
7070
fullWidth,
71-
width,
7271
className,
7372
wrapperClassName,
7473
...rest
7574
}: SelectProps) {
7675
const [open, setOpen] = useState(false);
7776
const [buttonWidth, setButtonWidth] = useState<number>(0);
7877

79-
const wrapperRef = useRef<HTMLDivElement>(null);
78+
const wrapperRef = useRef<HTMLUListElement>(null);
8079
const buttonRef = useRef<HTMLButtonElement>(null);
8180

82-
const selectedOption = options.find((option) => option.value === value);
81+
const selectedOption = useMemo(() => {
82+
return options.find((option) => option.value === value);
83+
}, [options, value]);
8384

8485
const wrapperClassNames = cn(
8586
"relative",
@@ -90,18 +91,19 @@ function Select({
9091
);
9192

9293
const buttonClassNames = cn(
93-
"flex items-center justify-between rounded-[0.375rem]",
94+
"flex items-center justify-between rounded-[0.375rem] cursor-pointer",
9495
{
9596
"w-full": fullWidth,
96-
"bg-white placeholder:text-gray-40 border border-gray-30": size === "lg",
97+
"bg-white border border-gray-30": size === "lg",
9798
"bg-gray-10 font-bold": size === "sm",
9899
},
100+
value ? "text-black" : "text-gray-40",
99101
sizeMap[size],
100102
className,
101103
);
102104

103105
const listClassNames = cn(
104-
"absolute top-full left-0 mt-1 border rounded-[0.375rem] bg-white border-gray-30 shadow-lg z-10 max-h-48 overflow-y-auto",
106+
"absolute top-full left-0 mt-1 border rounded-[0.375rem] bg-white border-gray-30 text-black shadow-lg z-10 max-h-48 overflow-y-auto",
105107
);
106108

107109
const handleSelect = (selectedValue: string) => {
@@ -112,9 +114,10 @@ function Select({
112114
// 드롭다운 외부 클릭 시 닫기
113115
useEffect(() => {
114116
const handleClickOutside = (event: MouseEvent) => {
117+
const target = event.target as Node;
115118
if (
116-
wrapperRef.current &&
117-
!wrapperRef.current.contains(event.target as Node)
119+
!buttonRef.current?.contains(target) &&
120+
!wrapperRef.current?.contains(target)
118121
) {
119122
setOpen(false);
120123
}
@@ -136,19 +139,16 @@ function Select({
136139

137140
return (
138141
<Field id={id} label={label}>
139-
<div className={wrapperClassNames} ref={wrapperRef}>
142+
<div className={wrapperClassNames}>
140143
<button
141144
id={id}
142145
type="button"
143146
ref={buttonRef}
144147
onClick={() => setOpen((prev) => !prev)}
145148
className={buttonClassNames}
146-
style={width ? { width } : undefined}
147149
{...rest}
148150
>
149-
<span className={cn(value ? "" : "text-gray-40")}>
150-
{selectedOption?.label || placeholder}
151-
</span>
151+
{selectedOption?.label || placeholder}
152152
{open ? (
153153
<DropdownUp className="ml-2" />
154154
) : (
@@ -158,9 +158,10 @@ function Select({
158158

159159
{open && (
160160
<ul
161+
ref={wrapperRef}
161162
className={listClassNames}
162163
style={{
163-
width: width || buttonWidth,
164+
width: buttonWidth,
164165
}}
165166
>
166167
{options.map((option) => (
@@ -171,7 +172,7 @@ function Select({
171172
<button
172173
type="button"
173174
className={cn(
174-
"w-full text-center hover:bg-gray-10",
175+
"w-full text-center hover:bg-gray-10 cursor-pointer",
175176
size === "sm"
176177
? "px-3 py-2 text-sm"
177178
: "px-5 py-3 text-[1rem]",

0 commit comments

Comments
 (0)