({
checkboxes = false,
clearable = true,
disabled = false,
error = false,
multiple = false,
options,
size = 'medium',
value,
label,
placeholder,
onChange,
onClear,
onDropdownClose,
onDropdownOpen,
buttonClassName,
containerClassName,
dropdownClassName,
dropdownPortalContainerId,
...rest
}: SelectProps)
| 112 | } |
| 113 | |
| 114 | export function Select({ |
| 115 | checkboxes = false, |
| 116 | clearable = true, |
| 117 | disabled = false, |
| 118 | error = false, |
| 119 | multiple = false, |
| 120 | options, |
| 121 | size = 'medium', |
| 122 | value, |
| 123 | label, |
| 124 | placeholder, |
| 125 | onChange, |
| 126 | onClear, |
| 127 | onDropdownClose, |
| 128 | onDropdownOpen, |
| 129 | buttonClassName, |
| 130 | containerClassName, |
| 131 | dropdownClassName, |
| 132 | dropdownPortalContainerId, |
| 133 | ...rest |
| 134 | }: SelectProps) { |
| 135 | const buttonId = useId(); |
| 136 | const labelId = useId(); |
| 137 | const buttonRef = useRef<HTMLButtonElement>(null); |
| 138 | const dropdownRef = useRef<HTMLUListElement>(null); |
| 139 | const [focusedOption, setFocusedOption] = useState<SelectOptionValue | null>(null); |
| 140 | const [isOpened, setIsOpened] = useState(false); |
| 141 | const [isSelected, setIsSelected] = useState<SelectOptionValue[]>( |
| 142 | options.filter(o => (Array.isArray(value) ? value.includes(o.value) : o.value === value)).map(o => o.value) |
| 143 | ); |
| 144 | const [showDropdown, setShowDropdown] = useState(false); |
| 145 | const [dropdownPosition, setDropdownPosition] = useState<Pick<CSSProperties, 'top' | 'left' | 'width'>>({ |
| 146 | top: 0, |
| 147 | left: 0, |
| 148 | width: 0, |
| 149 | }); |
| 150 | |
| 151 | useEffect(() => { |
| 152 | if (isOpened) { |
| 153 | setShowDropdown(true); |
| 154 | } |
| 155 | }, [isOpened]); |
| 156 | |
| 157 | useEffect(() => { |
| 158 | if (!showDropdown) { |
| 159 | const timer = setTimeout(() => { |
| 160 | setIsOpened(false); |
| 161 | }, 300); |
| 162 | |
| 163 | return () => { |
| 164 | clearTimeout(timer); |
| 165 | }; |
| 166 | } |
| 167 | }, [showDropdown]); |
| 168 | |
| 169 | useLayoutEffect(() => { |
| 170 | const updateDropdownPosition = () => { |
| 171 | if (isOpened && buttonRef.current) { |
nothing calls this directly
no test coverage detected