feat(multi-select): expose highlightedId and fix highlighting for filterable variant (#1153)

This commit is contained in:
Dominik G 2022-03-12 22:49:10 +01:00 committed by GitHub
commit 9215e3b106
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 23 deletions

View file

@ -2422,6 +2422,7 @@ export interface MultiSelectItem {
| Prop name | Kind | Reactive | Type | Default value | Description |
| :---------------- | :--------------- | :------- | :--------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| highlightedId | <code>let</code> | Yes | <code>null &#124; MultiSelectItemId</code> | <code>null</code> | Id of the highlighted ListBoxMenuItem |
| selectionRef | <code>let</code> | Yes | <code>null &#124; HTMLDivElement</code> | <code>null</code> | Obtain a reference to the selection element |
| fieldRef | <code>let</code> | Yes | <code>null &#124; HTMLDivElement</code> | <code>null</code> | Obtain a reference to the field box element |
| multiSelectRef | <code>let</code> | Yes | <code>null &#124; HTMLDivElement</code> | <code>null</code> | Obtain a reference to the outer div element |

View file

@ -6804,6 +6804,17 @@
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "highlightedId",
"kind": "let",
"description": "Id of the highlighted ListBoxMenuItem",
"type": "null | MultiSelectItemId",
"value": "null",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
}
],
"slots": [],

View file

@ -156,6 +156,12 @@
*/
export let selectionRef = null;
/**
* Id of the highlighted ListBoxMenuItem
* @type {null | MultiSelectItemId}
*/
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;
</script>
@ -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;

View file

@ -217,6 +217,12 @@ export interface MultiSelectProps
* @default null
*/
selectionRef?: null | HTMLDivElement;
/**
* Id of the highlighted ListBoxMenuItem
* @default null
*/
highlightedId?: null | MultiSelectItemId;
}
export default class MultiSelect extends SvelteComponentTyped<