🐛 fix: controlled and uncontroller console error

This commit is contained in:
Wahyu Kurniawan 2024-02-28 21:18:29 +07:00
parent eb4ccfbc9c
commit d52a34da35
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
2 changed files with 11 additions and 27 deletions

View File

@ -85,7 +85,7 @@ export const selectTheme = tv({
size: { size: {
md: { md: {
container: ['min-h-11'], 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]'], icon: ['h-[18px]', 'w-[18px]'],
helperText: 'text-sm', helperText: 'text-sm',
helperIcon: ['h-5', 'w-5'], helperIcon: ['h-5', 'w-5'],
@ -93,7 +93,7 @@ export const selectTheme = tv({
}, },
sm: { sm: {
container: ['min-h-8'], 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'], icon: ['h-4', 'w-4'],
helperText: 'text-xs', helperText: 'text-xs',
helperIcon: ['h-4', 'w-4'], helperIcon: ['h-4', 'w-4'],

View File

@ -3,7 +3,6 @@ import React, {
useState, useState,
ComponentPropsWithoutRef, ComponentPropsWithoutRef,
useMemo, useMemo,
useCallback,
MouseEvent, MouseEvent,
useRef, useRef,
useEffect, useEffect,
@ -135,7 +134,9 @@ export const Select = ({
const theme = selectTheme({ size, error, variant, orientation }); const theme = selectTheme({ size, error, variant, orientation });
const [inputValue, setInputValue] = useState(''); const [inputValue, setInputValue] = useState('');
const [selectedItem, setSelectedItem] = useState<SelectOption | null>(null); const [selectedItem, setSelectedItem] = useState<SelectOption | null>(
(value as SelectOption) || null,
);
const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(false);
const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>( const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>(
'bottom', 'bottom',
@ -166,22 +167,6 @@ export const Select = ({
} }
}, [dropdownOpen]); // Re-calculate whenever the dropdown is opened }, [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) => { const handleSelectedItemChange = (selectedItem: SelectOption | null) => {
setSelectedItem(selectedItem); setSelectedItem(selectedItem);
setInputValue(selectedItem ? selectedItem.label : ''); setInputValue(selectedItem ? selectedItem.label : '');
@ -194,9 +179,10 @@ export const Select = ({
addSelectedItem, addSelectedItem,
removeSelectedItem, removeSelectedItem,
selectedItems, selectedItems,
setSelectedItems, // setSelectedItems,
reset, reset,
} = useMultipleSelection<SelectOption>({ } = useMultipleSelection<SelectOption>({
selectedItems: multiple ? (value as SelectOption[]) : [],
onSelectedItemsChange: multiple onSelectedItemsChange: multiple
? undefined ? undefined
: ({ selectedItems }) => { : ({ selectedItems }) => {
@ -234,6 +220,7 @@ export const Select = ({
openMenu, openMenu,
} = useCombobox({ } = useCombobox({
items: filteredItems, items: filteredItems,
selectedItem: multiple ? null : (value as SelectOption) || null,
// @ts-expect-error there are two params but we don't need the second one // @ts-expect-error there are two params but we don't need the second one
isItemDisabled: (item) => item.disabled, isItemDisabled: (item) => item.disabled,
onInputValueChange: ({ inputValue = '' }) => setInputValue(inputValue), onInputValueChange: ({ inputValue = '' }) => setInputValue(inputValue),
@ -265,16 +252,12 @@ export const Select = ({
setInputValue(''); 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 // 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 : ''), itemToString: (item) => (item && !multiple ? item.label : ''),
}); });
const isSelected = useCallback( const isSelected = (item: SelectOption) =>
(item: SelectOption) => multiple ? selectedItems.includes(item) : selectedItem === item;
multiple ? selectedItems.includes(item) : selectedItem === item,
[selectedItems, selectedItem, multiple],
);
const handleClear = (e: MouseEvent<SVGSVGElement, globalThis.MouseEvent>) => { const handleClear = (e: MouseEvent<SVGSVGElement, globalThis.MouseEvent>) => {
e.stopPropagation(); e.stopPropagation();
@ -336,6 +319,7 @@ export const Select = ({
const isMultipleHasValue = multiple && selectedItems.length > 0; const isMultipleHasValue = multiple && selectedItems.length > 0;
const isMultipleHasValueButNotSearchable = const isMultipleHasValueButNotSearchable =
multiple && !searchable && selectedItems.length > 0; multiple && !searchable && selectedItems.length > 0;
const displayPlaceholder = useMemo(() => { const displayPlaceholder = useMemo(() => {
if (hideValues && isMultipleHasValue) { if (hideValues && isMultipleHasValue) {
return `${selectedItems.length} selected`; return `${selectedItems.length} selected`;