import * as Ariakit from '@ariakit/react'; import { IOption } from '@websolutespa/bom-core'; import { FocusEvent, useEffect, useState } from 'react'; import { useVariants } from '../../variants'; import { innerToOuterValue, outerToInnerSingleValue, outerToInnerValue } from '../utils/utils'; import { ComboboxContext } from './combobox.context'; import { comboboxVariants, IComboboxVariants } from './combobox.variants'; type Props = { name?: string; label?: string; value?: string | IOption | null; defaultValue?: string | null; selectedValue?: string | IOption | string[] | IOption[] | null; defaultSelectedValue?: string | IOption | string[] | IOption[] | null; options?: IOption[]; multiple?: boolean; variant?: keyof typeof comboboxVariants | (string & {}); variants?: IComboboxVariants; onFocus?: (event: FocusEvent) => void; onBlur?: (event: FocusEvent) => void; onChange?: (value: string | IOption | string[] | IOption[] | null) => void; }; export type ComboboxProps = Omit & Props; export function Combobox({ name, label: outerLabel, value: outerValue, defaultValue: outerDefaultValue, selectedValue: outerSelectedValue, defaultSelectedValue: outerDefaultSelectedValue, options, multiple, variant = 'default', variants, onBlur, onFocus, onChange, children, ...props }: ComboboxProps) { const value = outerToInnerSingleValue(outerValue); const defaultValue = outerToInnerSingleValue(outerDefaultValue) || ''; const [innerValue, setInnerValue] = useState(value || defaultValue); const selectedValue = outerToInnerValue(outerSelectedValue); const defaultSelectedValue = outerToInnerValue(outerDefaultSelectedValue) || (multiple ? [] : ''); const [innerSelectedValue, setInnerSelectedValue] = useState(); // console.log('value', value, 'defaultValue', defaultValue); useEffect(() => { const value = outerToInnerSingleValue(outerValue); if (innerValue !== value) { setInnerValue(value); } }, [innerValue, outerValue]); useEffect(() => { const selectedValue = outerToInnerValue(outerSelectedValue); if (innerSelectedValue !== selectedValue) { // const value = Array.isArray(selectedValue) ? selectedValue[0] : selectedValue; // setInnerValue(value); setInnerSelectedValue(selectedValue); if (selectedValue) { setInnerValue(Array.isArray(selectedValue) ? selectedValue[0] : selectedValue); } else { setInnerValue(''); } // console.log('Combobox', innerSelectedValue, selectedValue); } }, [innerSelectedValue, outerSelectedValue]); const onBlur_ = (event: FocusEvent) => { /* if (selectedValue) { setInnerValue(Array.isArray(selectedValue) ? selectedValue[0] : selectedValue); } */ onBlur && onBlur(event); }; const onFocus_ = (event: FocusEvent) => { // console.log('onFocus_', selectedValue); /* if (selectedValue) { setInnerValue(''); } */ onFocus && onFocus(event); }; const onSetValue = (value: string) => { if (innerValue !== value) { setInnerValue(value); } }; const onSetSelectedValue = (value: string | string[]) => { if (innerSelectedValue !== value) { setInnerSelectedValue(value); const outerSelectedValue = innerToOuterValue(value, options); onChange && onChange(outerSelectedValue); } }; const globalVariants = useVariants('combobox', comboboxVariants); variants = variants || globalVariants; return ( {children} ); }