feat: support item.disabled key for Dropdown, MultiSelect, ComboBox

Closes #1326
This commit is contained in:
Eric Liu 2022-06-01 19:09:47 -07:00
commit 460ad3240a
4 changed files with 71 additions and 7 deletions

View file

@ -1,7 +1,7 @@
<script> <script>
/** /**
* @typedef {any} ComboBoxItemId * @typedef {any} ComboBoxItemId
* @typedef {{ id: ComboBoxItemId; text: string; }} ComboBoxItem * @typedef {{ id: ComboBoxItemId; text: string; disabled?: boolean; }} ComboBoxItem
* @event {{ selectedId: ComboBoxItemId; selectedItem: ComboBoxItem }} select * @event {{ selectedId: ComboBoxItemId; selectedItem: ComboBoxItem }} select
* @slot {{ item: ComboBoxItem; index: number }} * @slot {{ item: ComboBoxItem; index: number }}
*/ */
@ -133,6 +133,20 @@
} else if (index >= _items.length) { } else if (index >= _items.length) {
index = 0; index = 0;
} }
let disabled = items[index].disabled;
while (disabled) {
index = index + dir;
if (index < 0) {
index = items.length - 1;
} else if (index >= items.length) {
index = 0;
}
disabled = items[index].disabled;
}
highlightedIndex = index; highlightedIndex = index;
} }
@ -360,7 +374,12 @@
id="{item.id}" id="{item.id}"
active="{selectedId === item.id}" active="{selectedId === item.id}"
highlighted="{highlightedIndex === i}" highlighted="{highlightedIndex === i}"
on:click="{() => { disabled="{item.disabled}"
on:click="{(e) => {
if (item.disabled) {
e.stopPropagation();
return;
}
selectedId = item.id; selectedId = item.id;
open = false; open = false;
@ -369,6 +388,7 @@
} }
}}" }}"
on:mouseenter="{() => { on:mouseenter="{() => {
if (item.disabled) return;
highlightedIndex = i; highlightedIndex = i;
}}" }}"
> >

View file

@ -2,7 +2,7 @@
/** /**
* @typedef {any} DropdownItemId * @typedef {any} DropdownItemId
* @typedef {string} DropdownItemText * @typedef {string} DropdownItemText
* @typedef {{ id: DropdownItemId; text: DropdownItemText; }} DropdownItem * @typedef {{ id: DropdownItemId; text: DropdownItemText; disabled?: boolean; }} DropdownItem
* @event {{ selectedId: DropdownItemId, selectedItem: DropdownItem }} select * @event {{ selectedId: DropdownItemId, selectedItem: DropdownItem }} select
* @slot {{ item: DropdownItem; index: number; }} * @slot {{ item: DropdownItem; index: number; }}
*/ */
@ -124,6 +124,20 @@
index = 0; index = 0;
} }
let disabled = items[index].disabled;
while (disabled) {
index = index + dir;
if (index < 0) {
index = items.length - 1;
} else if (index >= items.length) {
index = 0;
}
disabled = items[index].disabled;
}
highlightedIndex = index; highlightedIndex = index;
} }
@ -251,11 +265,17 @@
id="{item.id}" id="{item.id}"
active="{selectedId === item.id}" active="{selectedId === item.id}"
highlighted="{highlightedIndex === i || selectedId === item.id}" highlighted="{highlightedIndex === i || selectedId === item.id}"
on:click="{() => { disabled="{item.disabled}"
on:click="{(e) => {
if (item.disabled) {
e.stopPropagation();
return;
}
selectedId = item.id; selectedId = item.id;
ref.focus(); ref.focus();
}}" }}"
on:mouseenter="{() => { on:mouseenter="{() => {
if (item.disabled) return;
highlightedIndex = i; highlightedIndex = i;
}}" }}"
> >

View file

@ -5,6 +5,9 @@
/** Set to `true` to enable the highlighted state */ /** Set to `true` to enable the highlighted state */
export let highlighted = false; export let highlighted = false;
/** Set to `true` to disable the menu item */
export let disabled = false;
let ref = null; let ref = null;
$: isTruncated = ref?.offsetWidth < ref?.scrollWidth; $: isTruncated = ref?.offsetWidth < ref?.scrollWidth;
@ -17,6 +20,7 @@
class:bx--list-box__menu-item--active="{active}" class:bx--list-box__menu-item--active="{active}"
class:bx--list-box__menu-item--highlighted="{highlighted}" class:bx--list-box__menu-item--highlighted="{highlighted}"
aria-selected="{active}" aria-selected="{active}"
disabled="{disabled ? true : undefined}"
{...$$restProps} {...$$restProps}
on:click on:click
on:mouseenter on:mouseenter

View file

@ -2,7 +2,7 @@
/** /**
* @typedef {any} MultiSelectItemId * @typedef {any} MultiSelectItemId
* @typedef {string} MultiSelectItemText * @typedef {string} MultiSelectItemText
* @typedef {{ id: MultiSelectItemId; text: MultiSelectItemText; }} MultiSelectItem * @typedef {{ id: MultiSelectItemId; text: MultiSelectItemText; disabled?: boolean; }} MultiSelectItem
* @event {{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }} select * @event {{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }} select
* @event {null} clear * @event {null} clear
* @event {FocusEvent | CustomEvent<FocusEvent>} blur * @event {FocusEvent | CustomEvent<FocusEvent>} blur
@ -210,6 +210,20 @@
index = 0; index = 0;
} }
let disabled = items[index].disabled;
while (disabled) {
index = index + direction;
if (index < 0) {
index = items.length - 1;
} else if (index >= items.length) {
index = 0;
}
disabled = items[index].disabled;
}
highlightedIndex = index; highlightedIndex = index;
} }
@ -481,13 +495,19 @@
aria-selected="{item.checked}" aria-selected="{item.checked}"
active="{item.checked}" active="{item.checked}"
highlighted="{highlightedIndex === i}" highlighted="{highlightedIndex === i}"
on:click="{() => { disabled="{item.disabled}"
on:click="{(e) => {
if (item.disabled) {
e.stopPropagation();
return;
}
sortedItems = sortedItems.map((_) => sortedItems = sortedItems.map((_) =>
_.id === item.id ? { ..._, checked: !_.checked } : _ _.id === item.id ? { ..._, checked: !_.checked } : _
); );
fieldRef.focus(); fieldRef.focus();
}}" }}"
on:mouseenter="{() => { on:mouseenter="{() => {
if (item.disabled) return;
highlightedIndex = i; highlightedIndex = i;
}}" }}"
> >
@ -499,7 +519,7 @@
tabindex="-1" tabindex="-1"
id="checkbox-{item.id}" id="checkbox-{item.id}"
checked="{item.checked}" checked="{item.checked}"
disabled="{disabled}" disabled="{item.disabled}"
on:blur="{() => { on:blur="{() => {
if (i === filteredItems.length - 1) open = false; if (i === filteredItems.length - 1) open = false;
}}" }}"