From 47382962ebcf6d29b9ef59b6e0ffa8f9d2ca5dac Mon Sep 17 00:00:00 2001 From: dominikg Date: Wed, 9 Mar 2022 14:02:40 +0100 Subject: [PATCH] feat(MultiSelect): Expose highlightedId and improve highlight handling for filterable --- COMPONENT_INDEX.md | 1 + docs/src/COMPONENT_API.json | 11 ++++++ src/MultiSelect/MultiSelect.svelte | 44 +++++++++++------------ types/MultiSelect/MultiSelect.svelte.d.ts | 6 ++++ 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index 12257e16..9eab4f45 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -2422,6 +2422,7 @@ export interface MultiSelectItem { | Prop name | Kind | Reactive | Type | Default value | Description | | :---------------- | :--------------- | :------- | :--------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | +| highlightedId | let | Yes | null | string | null | Id of the highlighted ListBoxMenuItem | | selectionRef | let | Yes | null | HTMLDivElement | null | Obtain a reference to the selection element | | fieldRef | let | Yes | null | HTMLDivElement | null | Obtain a reference to the field box element | | multiSelectRef | let | Yes | null | HTMLDivElement | null | Obtain a reference to the outer div element | diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index ec4b8462..3035988a 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -6804,6 +6804,17 @@ "isFunctionDeclaration": false, "constant": false, "reactive": true + }, + { + "name": "highlightedId", + "kind": "let", + "description": "Id of the highlighted ListBoxMenuItem", + "type": "null | string", + "value": "null", + "isFunction": false, + "isFunctionDeclaration": false, + "constant": false, + "reactive": true } ], "slots": [], diff --git a/src/MultiSelect/MultiSelect.svelte b/src/MultiSelect/MultiSelect.svelte index fbcae562..a9ab55bb 100644 --- a/src/MultiSelect/MultiSelect.svelte +++ b/src/MultiSelect/MultiSelect.svelte @@ -156,6 +156,12 @@ */ export let selectionRef = null; + /** + * Id of the highlighted ListBoxMenuItem + * @type {null | string} + */ + export let highlightedId = null; + import { afterUpdate, createEventDispatcher, setContext } from "svelte"; import WarningFilled16 from "../icons/WarningFilled16.svelte"; import WarningAltFilled16 from "../icons/WarningAltFilled16.svelte"; @@ -191,10 +197,10 @@ function change(direction) { let index = highlightedIndex + direction; - + const length = filterable ? filteredItems.length : items.length; if (index < 0) { - index = items.length - 1; - } else if (index >= items.length) { + index = length - 1; + } else if (index >= length) { index = 0; } @@ -245,9 +251,10 @@ $: checked = sortedItems.filter(({ checked }) => checked); $: unchecked = sortedItems.filter(({ checked }) => !checked); $: filteredItems = sortedItems.filter((item) => filterItem(item, value)); - $: highlightedId = sortedItems[highlightedIndex] - ? sortedItems[highlightedIndex].id - : undefined; + $: highlightedId = + highlightedIndex > -1 + ? (filterable ? filteredItems : sortedItems)[highlightedIndex]?.id ?? null + : null; $: value = inputValue; @@ -394,23 +401,14 @@ on:keydown on:keydown|stopPropagation="{({ key }) => { if (key === 'Enter') { - if (highlightedIndex > -1) { - if (filterable) { - const filteredItemId = filteredItems[highlightedIndex].id; - const filteredItemIndex = sortedItems - .map((item) => item.id) - .indexOf(filteredItemId); - - sortedItems = sortedItems.map((item, i) => { - if (i !== filteredItemIndex) return item; - return { ...item, checked: !item.checked }; - }); - } else { - sortedItems = sortedItems.map((item, i) => { - if (i !== highlightedIndex) return item; - return { ...item, checked: !item.checked }; - }); - } + if (highlightedId) { + const filteredItemIndex = sortedItems.findIndex( + (item) => item.id === highlightedId + ); + sortedItems = sortedItems.map((item, i) => { + if (i !== filteredItemIndex) return item; + return { ...item, checked: !item.checked }; + }); } } else if (key === 'Tab') { open = false; diff --git a/types/MultiSelect/MultiSelect.svelte.d.ts b/types/MultiSelect/MultiSelect.svelte.d.ts index fee3cc7d..ff9f86e9 100644 --- a/types/MultiSelect/MultiSelect.svelte.d.ts +++ b/types/MultiSelect/MultiSelect.svelte.d.ts @@ -217,6 +217,12 @@ export interface MultiSelectProps * @default null */ selectionRef?: null | HTMLDivElement; + + /** + * Id of the highlighted ListBoxMenuItem + * @default null + */ + highlightedId?: null | string; } export default class MultiSelect extends SvelteComponentTyped<