diff --git a/src/create-select.tsx b/src/create-select.tsx index 447b3ca..5ab7ba1 100644 --- a/src/create-select.tsx +++ b/src/create-select.tsx @@ -20,6 +20,7 @@ interface CreateSelectProps { multiple?: boolean; disabled?: boolean; optionToValue?: (option: CreateSelectOption) => CreateSelectSingleValue; + isOptionSelected?: (option: CreateSelectOption) => boolean; isOptionDisabled?: (option: CreateSelectOption) => boolean; onChange?: (value: CreateSelectValue) => void; onInput?: (inputValue: string) => void; @@ -33,6 +34,7 @@ const createSelect = (props: CreateSelectProps) => { optionToValue: (option: CreateSelectOption): CreateSelectSingleValue => option, isOptionDisabled: (option: CreateSelectOption) => false, + isOptionSelected: (option: CreateSelectOption) => false, }, props, ); @@ -40,7 +42,7 @@ const createSelect = (props: CreateSelectProps) => { const parseValue = (value: CreateSelectValue) => { if (config.multiple && Array.isArray(value)) { return value; - } else if (!config.multiple && !Array.isArray(value)) { + } else if (!config.multiple) { return value !== null ? [value] : []; } else { throw new Error( @@ -60,7 +62,7 @@ const createSelect = (props: CreateSelectProps) => { const clearValue = () => _setValue([]); const hasValue = () => !!(config.multiple ? value().length : value()); - createEffect(on(_value, () => config.onChange?.(value()), { defer: true })); + // createEffect(on(_value, () => config.onChange?.(value()), { defer: true })); const [inputValue, setInputValue] = createSignal(""); const clearInputValue = () => setInputValue(""); @@ -98,10 +100,12 @@ const createSelect = (props: CreateSelectProps) => { const value = config.optionToValue(option); if (config.multiple) { - setValue([..._value(), value]); + setValue([..._value(), option]); + props.onChange?.(_value().map(config.optionToValue)); } else { - setValue(value); + setValue(option); setIsActive(false); + props.onChange?.(value); } setIsOpen(false); }; @@ -134,6 +138,14 @@ const createSelect = (props: CreateSelectProps) => { const focusPreviousOption = () => focusOption("previous"); const focusNextOption = () => focusOption("next"); + const addSelectedOption = (option: CreateSelectOption) => { + if (config.multiple) { + _setValue([..._value(), option]); + } else { + _setValue(parseValue(option)); + } + } + createEffect( on( options, @@ -279,6 +291,8 @@ const createSelect = (props: CreateSelectProps) => { pickOption, isOptionFocused, isOptionDisabled: config.isOptionDisabled, + isOptionSelected: config.isOptionSelected, + addSelectedOption, onFocusIn, onFocusOut, onMouseDown, diff --git a/src/select.tsx b/src/select.tsx index 1aabb8d..467ae04 100644 --- a/src/select.tsx +++ b/src/select.tsx @@ -11,6 +11,7 @@ import { useContext, JSXElement, Ref, + onMount, } from "solid-js"; import { createSelect, @@ -65,6 +66,7 @@ const Select: Component = (props) => { "options", "optionToValue", "isOptionDisabled", + "isOptionSelected", "multiple", "disabled", "onInput", @@ -130,6 +132,14 @@ type ControlProps = Omit; const Control: Component = (props) => { const select = useSelect(); + createEffect(on(select.options, () => { + select.options().forEach((option: any) => { + if (select.isOptionSelected(option)) { + select.addSelectedOption(option); + } + }); + })); + const removeValue = (index: number) => { const value = select.value(); select.setValue([...value.slice(0, index), ...value.slice(index + 1)]); @@ -252,6 +262,14 @@ type ListProps = Pick< const List: Component = (props) => { const select = useSelect(); + const addSelectedOption = (option: CreateSelectOption) => { + if (select.multiple) { + select.setValue([...select.value(), option]); + } else { + select.setValue(option); + } + } + return (
@@ -295,11 +313,13 @@ const Option: ParentComponent = (props) => { } }); }; + return (
select.pickOption(props.option)} >