diff --git a/ui/src/components/core/combobox/combobox.tsx b/ui/src/components/core/combobox/combobox.tsx index fa74939..4b51a55 100644 --- a/ui/src/components/core/combobox/combobox.tsx +++ b/ui/src/components/core/combobox/combobox.tsx @@ -156,141 +156,136 @@ export type ComboboxProps = { error?: boolean; }; -export const Combobox = forwardRef( - ({ - items, - selectedValue = { value: '', label: '' }, - withAutocomplete = false, - leftIcon = 'search', - onChange, - onBlur, - error = false, - }) => { - const [filteredItems, setFilteredItems] = useState([]); - const [autocompleteItems, setAutocompleteItems] = useState( - [] - ); +export const Combobox: React.FC = ({ + items, + selectedValue = { value: '', label: '' }, + withAutocomplete = false, + leftIcon = 'search', + onChange, + onBlur, + error = false, +}) => { + const [filteredItems, setFilteredItems] = useState([]); + const [autocompleteItems, setAutocompleteItems] = useState( + [] + ); - useEffect(() => { - // If the selected value doesn't exist in the list of items, we add it - if ( - items.filter((item) => item === selectedValue).length === 0 && - selectedValue.value !== undefined && - autocompleteItems.length === 0 && - withAutocomplete - ) { - setAutocompleteItems([selectedValue]); - } - }, [autocompleteItems.length, items, selectedValue, withAutocomplete]); + useEffect(() => { + // If the selected value doesn't exist in the list of items, we add it + if ( + items.filter((item) => item === selectedValue).length === 0 && + selectedValue.value !== undefined && + autocompleteItems.length === 0 && + withAutocomplete + ) { + setAutocompleteItems([selectedValue]); + } + }, [autocompleteItems.length, items, selectedValue, withAutocomplete]); - useEffect(() => { + useEffect(() => { + setFilteredItems(items); + }, [items]); + + const buttonRef = useRef(null); + + const handleSearch = useDebounce((searchValue: string) => { + if (searchValue === '') { setFilteredItems(items); - }, [items]); - const buttonRef = useRef(null); - - const handleSearch = useDebounce((searchValue: string) => { - if (searchValue === '') { - setFilteredItems(items); - - if (withAutocomplete) { - setAutocompleteItems([]); - handleComboboxChange({} as ComboboxItem); - } - } else { - const filteredValues = items.filter((item) => - cleanString(item.label).startsWith(cleanString(searchValue)) - ); - - if (withAutocomplete && filteredValues.length === 0) { - // If the search value doesn't exist in the list of items, we add it - setAutocompleteItems([{ value: searchValue, label: searchValue }]); - } - setFilteredItems(filteredValues); - } - }, 200); - - const handleInputChange = ( - event: React.ChangeEvent - ): void => { - event.stopPropagation(); - handleSearch(event.target.value); - }; - - const handleInputClick = (): void => { - buttonRef.current?.click(); - }; - - const handleComboboxChange = (optionSelected: ComboboxItem): void => { - onChange(optionSelected); - }; - - const handleLeaveTransition = (): void => { - setFilteredItems(items); - if (selectedValue.value === undefined && withAutocomplete) { + if (withAutocomplete) { setAutocompleteItems([]); handleComboboxChange({} as ComboboxItem); } - }; + } else { + const filteredValues = items.filter((item) => + cleanString(item.label).startsWith(cleanString(searchValue)) + ); - return ( - - {({ open }) => ( -
- - + if (withAutocomplete && filteredValues.length === 0) { + // If the search value doesn't exist in the list of items, we add it + setAutocompleteItems([{ value: searchValue, label: searchValue }]); + } + setFilteredItems(filteredValues); + } + }, 200); - - - {[...autocompleteItems, ...filteredItems].length === 0 || - filteredItems === undefined ? ( - - ) : ( - <> - {autocompleteItems.length > 0 && Create new} - {autocompleteItems.map( - (autocompleteOption: ComboboxItem) => ( - - ) - )} - {autocompleteItems.length > 0 && - filteredItems.length > 0 && ( - - )} - {filteredItems.map((option: ComboboxItem) => ( - - ))} - - )} - - -
- )} -
- ); - } -); + const handleInputChange = ( + event: React.ChangeEvent + ): void => { + event.stopPropagation(); + handleSearch(event.target.value); + }; + + const handleInputClick = (): void => { + buttonRef.current?.click(); + }; + + const handleComboboxChange = (optionSelected: ComboboxItem): void => { + onChange(optionSelected); + }; + + const handleLeaveTransition = (): void => { + setFilteredItems(items); + if (selectedValue.value === undefined && withAutocomplete) { + setAutocompleteItems([]); + handleComboboxChange({} as ComboboxItem); + } + }; + + return ( + + {({ open }) => ( +
+ + + + + + {[...autocompleteItems, ...filteredItems].length === 0 || + filteredItems === undefined ? ( + + ) : ( + <> + {autocompleteItems.length > 0 && Create new} + {autocompleteItems.map((autocompleteOption: ComboboxItem) => ( + + ))} + {autocompleteItems.length > 0 && filteredItems.length > 0 && ( + + )} + {filteredItems.map((option: ComboboxItem) => ( + + ))} + + )} + + +
+ )} +
+ ); +}; Combobox.displayName = 'Combobox'; diff --git a/ui/src/components/form/form.tsx b/ui/src/components/form/form.tsx index 6e1e706..1089f65 100644 --- a/ui/src/components/form/form.tsx +++ b/ui/src/components/form/form.tsx @@ -134,48 +134,45 @@ export abstract class Form { } ); - static readonly Combobox = forwardRef( - (props, ref) => { - const { - id, - validators, - value: [value, setValue], - validationEnabled: [validationEnabled, setValidationEnabled], - } = useFormFieldContext(); + static readonly Combobox: React.FC = (props) => { + const { + id, + validators, + value: [value, setValue], + validationEnabled: [validationEnabled, setValidationEnabled], + } = useFormFieldContext(); - const comboboxValue = useMemo(() => { - // if it's with autocomplete maybe won't be on the items list - const item = props.items.find((item) => item.label === value); - if (props.withAutocomplete && !item && value !== '') { - //return the selected value if the item doesn't exist - return { label: value, value: value }; - } - return item; - }, [props.items, props.withAutocomplete, value]); + const comboboxValue = useMemo(() => { + // if it's with autocomplete maybe won't be on the items list + const item = props.items.find((item) => item.label === value); + if (props.withAutocomplete && !item && value !== '') { + //return the selected value if the item doesn't exist + return { label: value, value: value }; + } + return item; + }, [props.items, props.withAutocomplete, value]); - const isValid = useFormFieldValidatorValue(id, validators, value); + const isValid = useFormFieldValidatorValue(id, validators, value); - const handleComboboxChange = (option: ComboboxItem): void => { - if (props.onChange) props.onChange(option); - setValue(option.label); - }; + const handleComboboxChange = (option: ComboboxItem): void => { + if (props.onChange) props.onChange(option); + setValue(option.label); + }; - const handleComboboxBlur = (): void => { - setValidationEnabled(true); - }; + const handleComboboxBlur = (): void => { + setValidationEnabled(true); + }; - return ( - - ); - } - ); + return ( + + ); + }; static readonly ColorPicker: React.FC = ({ logo,