diff --git a/src/ComboBox/ComboBox.svelte b/src/ComboBox/ComboBox.svelte index 40399deb..f7267f70 100644 --- a/src/ComboBox/ComboBox.svelte +++ b/src/ComboBox/ComboBox.svelte @@ -108,18 +108,19 @@ const dispatch = createEventDispatcher(); let selectedId = undefined; - let inputValue = ""; + let inputValue = value; let highlightedIndex = -1; + let selectedItem; + function change(dir) { let index = highlightedIndex + dir; - + let _items = !filteredItems?.length ? items : filteredItems; if (index < 0) { - index = items.length - 1; - } else if (index >= items.length) { + index = _items.length - 1; + } else if (index >= _items.length) { index = 0; } - highlightedIndex = index; } @@ -130,38 +131,51 @@ export function clear() { selectedIndex = -1; highlightedIndex = -1; + highlightedId = undefined; + selectedItem = undefined; open = false; inputValue = ""; ref?.focus(); } + let prevInputValue; afterUpdate(() => { if (open) { ref.focus(); filteredItems = items.filter((item) => shouldFilterItem(item, value)); } else { highlightedIndex = -1; - + filteredItems = []; if (!selectedItem) { selectedId = undefined; selectedIndex = -1; + } else { + // programmatically set selectedIndex + inputValue = selectedItem.text; } } }); - $: if (selectedIndex > -1) { - selectedId = items[selectedIndex].id; + let prevSelectedIndex; + $: if (selectedIndex > -1 && prevSelectedIndex !== selectedIndex) { + prevSelectedIndex = selectedIndex; + if (filteredItems?.length === 1 && open) { + selectedId = filteredItems[0].id; + selectedItem = filteredItems[0]; + highlightedIndex = -1; + highlightedId = undefined; + } else { + selectedId = items[selectedIndex].id; + selectedItem = items[selectedIndex]; + } dispatch("select", { selectedId, selectedIndex, selectedItem }); } + $: ariaLabel = $$props["aria-label"] || "Choose an item"; $: menuId = `menu-${id}`; $: comboId = `combo-${id}`; - $: highlightedId = items[highlightedIndex] - ? items[highlightedIndex].id - : undefined; + $: highlightedId = items[highlightedIndex] ? items[highlightedIndex].id : 0; $: filteredItems = items.filter((item) => shouldFilterItem(item, value)); - $: selectedItem = items[selectedIndex]; - $: inputValue = selectedItem ? selectedItem.text : ""; $: value = inputValue; @@ -245,15 +259,24 @@ if (highlightedIndex > -1 && highlightedIndex !== selectedIndex) { selectedIndex = highlightedIndex; open = false; - + highlightedIndex = -1; if (filteredItems[selectedIndex]) { inputValue = filteredItems[selectedIndex].text; + selectedItem = filteredItems[selectedIndex]; + selectedId = filteredItems[selectedIndex].id; } - } - - if (highlightedIndex < 0 && selectedIndex > -1) { + selectedIndex = items.findIndex((item) => item.id === selectedId); + } else { + selectedIndex = 0; + open = false; + highlightedIndex = -1; if (filteredItems[selectedIndex]) { inputValue = filteredItems[selectedIndex].text; + selectedItem = filteredItems[selectedIndex]; + selectedId = filteredItems[selectedIndex].id; + selectedIndex = items.findIndex( + (item) => item.id === selectedId + ); } } } else if (key === 'Tab') { @@ -270,12 +293,6 @@ on:focus on:blur on:blur="{({ relatedTarget }) => { - if (inputValue.length === 0 && selectedIndex > -1) { - if (filteredItems[selectedIndex]) { - inputValue = filteredItems[selectedIndex].text; - } - } - if (!open || !relatedTarget) return; if ( relatedTarget &&