fix(combobox): filtered ComboBox handling with keyboard (#926)

* fix(combobox): filtered ComboBox handling with keyboard

* fix: dispatching filteredItems

* fix: default value settings (init) on inputValue

* fix: multiple event dispatch, and item selection bug

* fix(ComboBox): programmatically setting selectedIndex has no effect

* fix(ComboBox): selectedIndex prog. setting on filtered items

* fix(ComboBox): removed unnecessary blur code fragment, fix mouse selection after keyboard editing
This commit is contained in:
István Pató 2022-01-10 23:45:37 +01:00 committed by GitHub
commit a2a5159a59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

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