From d52a34da35131f44a9426c1e214561ac28be4514 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Wed, 28 Feb 2024 21:18:29 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20controlled=20and=20uncont?= =?UTF-8?q?roller=20console=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Select/Select.theme.ts | 4 +-- .../src/components/shared/Select/Select.tsx | 34 +++++-------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/packages/frontend/src/components/shared/Select/Select.theme.ts b/packages/frontend/src/components/shared/Select/Select.theme.ts index 43d4b0f4..fed6531e 100644 --- a/packages/frontend/src/components/shared/Select/Select.theme.ts +++ b/packages/frontend/src/components/shared/Select/Select.theme.ts @@ -85,7 +85,7 @@ export const selectTheme = tv({ size: { md: { container: ['min-h-11'], - inputWrapper: ['min-h-11', 'text-sm', 'pl-4', 'pr-4', 'py-1'], + inputWrapper: ['min-h-11', 'text-sm', 'pl-4', 'pr-4'], icon: ['h-[18px]', 'w-[18px]'], helperText: 'text-sm', helperIcon: ['h-5', 'w-5'], @@ -93,7 +93,7 @@ export const selectTheme = tv({ }, sm: { container: ['min-h-8'], - inputWrapper: ['min-h-8', 'text-xs', 'pl-3', 'pr-3', 'py-0.5'], + inputWrapper: ['min-h-8', 'text-xs', 'pl-3', 'pr-3'], icon: ['h-4', 'w-4'], helperText: 'text-xs', helperIcon: ['h-4', 'w-4'], diff --git a/packages/frontend/src/components/shared/Select/Select.tsx b/packages/frontend/src/components/shared/Select/Select.tsx index 963cc0bb..8c7e9149 100644 --- a/packages/frontend/src/components/shared/Select/Select.tsx +++ b/packages/frontend/src/components/shared/Select/Select.tsx @@ -3,7 +3,6 @@ import React, { useState, ComponentPropsWithoutRef, useMemo, - useCallback, MouseEvent, useRef, useEffect, @@ -135,7 +134,9 @@ export const Select = ({ const theme = selectTheme({ size, error, variant, orientation }); const [inputValue, setInputValue] = useState(''); - const [selectedItem, setSelectedItem] = useState(null); + const [selectedItem, setSelectedItem] = useState( + (value as SelectOption) || null, + ); const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>( 'bottom', @@ -166,22 +167,6 @@ export const Select = ({ } }, [dropdownOpen]); // Re-calculate whenever the dropdown is opened - useEffect(() => { - // If multiple selection is enabled, ensure the internal state is an array - if (multiple) { - if (Array.isArray(value)) { - // Directly use the provided array - setSelectedItems(value); - } else { - // Reset or set to empty array if the value is not an array - setSelectedItems([]); - } - } else { - // For single selection, directly set the selected item - setSelectedItem(value as SelectOption); - } - }, [value, multiple]); - const handleSelectedItemChange = (selectedItem: SelectOption | null) => { setSelectedItem(selectedItem); setInputValue(selectedItem ? selectedItem.label : ''); @@ -194,9 +179,10 @@ export const Select = ({ addSelectedItem, removeSelectedItem, selectedItems, - setSelectedItems, + // setSelectedItems, reset, } = useMultipleSelection({ + selectedItems: multiple ? (value as SelectOption[]) : [], onSelectedItemsChange: multiple ? undefined : ({ selectedItems }) => { @@ -234,6 +220,7 @@ export const Select = ({ openMenu, } = useCombobox({ items: filteredItems, + selectedItem: multiple ? null : (value as SelectOption) || null, // @ts-expect-error – there are two params but we don't need the second one isItemDisabled: (item) => item.disabled, onInputValueChange: ({ inputValue = '' }) => setInputValue(inputValue), @@ -265,16 +252,12 @@ export const Select = ({ setInputValue(''); } }, - selectedItem: multiple ? null : selectedItem, // TODO: Make the input value empty when the dropdown is open, has a value, it is not multiple, and searchable itemToString: (item) => (item && !multiple ? item.label : ''), }); - const isSelected = useCallback( - (item: SelectOption) => - multiple ? selectedItems.includes(item) : selectedItem === item, - [selectedItems, selectedItem, multiple], - ); + const isSelected = (item: SelectOption) => + multiple ? selectedItems.includes(item) : selectedItem === item; const handleClear = (e: MouseEvent) => { e.stopPropagation(); @@ -336,6 +319,7 @@ export const Select = ({ const isMultipleHasValue = multiple && selectedItems.length > 0; const isMultipleHasValueButNotSearchable = multiple && !searchable && selectedItems.length > 0; + const displayPlaceholder = useMemo(() => { if (hideValues && isMultipleHasValue) { return `${selectedItems.length} selected`;