mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
feat: support item.disabled
key for Dropdown
, MultiSelect
, ComboBox
(#1328)
Closes #1326 * feat: support item.disabled key for `Dropdown`, `MultiSelect`, `ComboBox` * Run "yarn build:docs" * test: assert disabled property * docs: add "Disabled items" examples
This commit is contained in:
parent
22f93ee675
commit
f25a10c9c4
16 changed files with 150 additions and 19 deletions
|
@ -646,6 +646,7 @@ export type ComboBoxItemId = any;
|
||||||
export interface ComboBoxItem {
|
export interface ComboBoxItem {
|
||||||
id: ComboBoxItemId;
|
id: ComboBoxItemId;
|
||||||
text: string;
|
text: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1140,6 +1141,7 @@ export type DropdownItemText = string;
|
||||||
export interface DropdownItem {
|
export interface DropdownItem {
|
||||||
id: DropdownItemId;
|
id: DropdownItemId;
|
||||||
text: DropdownItemText;
|
text: DropdownItemText;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -2085,6 +2087,7 @@ None.
|
||||||
| :---------- | :------- | :--------------- | :------- | -------------------- | ------------------ | --------------------------------------------- |
|
| :---------- | :------- | :--------------- | :------- | -------------------- | ------------------ | --------------------------------------------- |
|
||||||
| active | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the active state |
|
| active | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the active state |
|
||||||
| highlighted | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the highlighted state |
|
| highlighted | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the highlighted state |
|
||||||
|
| disabled | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the menu item |
|
||||||
|
|
||||||
### Slots
|
### Slots
|
||||||
|
|
||||||
|
@ -2327,6 +2330,7 @@ export type MultiSelectItemText = string;
|
||||||
export interface MultiSelectItem {
|
export interface MultiSelectItem {
|
||||||
id: MultiSelectItemId;
|
id: MultiSelectItemId;
|
||||||
text: MultiSelectItemText;
|
text: MultiSelectItemText;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1769,9 +1769,9 @@
|
||||||
"ts": "type ComboBoxItemId = any"
|
"ts": "type ComboBoxItemId = any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "{ id: ComboBoxItemId; text: string; }",
|
"type": "{ id: ComboBoxItemId; text: string; disabled?: boolean; }",
|
||||||
"name": "ComboBoxItem",
|
"name": "ComboBoxItem",
|
||||||
"ts": "interface ComboBoxItem { id: ComboBoxItemId; text: string; }"
|
"ts": "interface ComboBoxItem { id: ComboBoxItemId; text: string; disabled?: boolean; }"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rest_props": { "type": "Element", "name": "input" }
|
"rest_props": { "type": "Element", "name": "input" }
|
||||||
|
@ -3493,9 +3493,9 @@
|
||||||
"ts": "type DropdownItemText = string"
|
"ts": "type DropdownItemText = string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "{ id: DropdownItemId; text: DropdownItemText; }",
|
"type": "{ id: DropdownItemId; text: DropdownItemText; disabled?: boolean; }",
|
||||||
"name": "DropdownItem",
|
"name": "DropdownItem",
|
||||||
"ts": "interface DropdownItem { id: DropdownItemId; text: DropdownItemText; }"
|
"ts": "interface DropdownItem { id: DropdownItemId; text: DropdownItemText; disabled?: boolean; }"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rest_props": { "type": "Element", "name": "div" }
|
"rest_props": { "type": "Element", "name": "div" }
|
||||||
|
@ -6063,6 +6063,18 @@
|
||||||
"isRequired": false,
|
"isRequired": false,
|
||||||
"constant": false,
|
"constant": false,
|
||||||
"reactive": false
|
"reactive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disabled",
|
||||||
|
"kind": "let",
|
||||||
|
"description": "Set to `true` to disable the menu item",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": "false",
|
||||||
|
"isFunction": false,
|
||||||
|
"isFunctionDeclaration": false,
|
||||||
|
"isRequired": false,
|
||||||
|
"constant": false,
|
||||||
|
"reactive": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"moduleExports": [],
|
"moduleExports": [],
|
||||||
|
@ -7296,9 +7308,9 @@
|
||||||
"ts": "type MultiSelectItemText = string"
|
"ts": "type MultiSelectItemText = string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "{ id: MultiSelectItemId; text: MultiSelectItemText; }",
|
"type": "{ id: MultiSelectItemId; text: MultiSelectItemText; disabled?: boolean; }",
|
||||||
"name": "MultiSelectItem",
|
"name": "MultiSelectItem",
|
||||||
"ts": "interface MultiSelectItem { id: MultiSelectItemId; text: MultiSelectItemText; }"
|
"ts": "interface MultiSelectItem { id: MultiSelectItemId; text: MultiSelectItemText; disabled?: boolean; }"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rest_props": { "type": "Element", "name": "input" }
|
"rest_props": { "type": "Element", "name": "input" }
|
||||||
|
|
|
@ -112,11 +112,25 @@ items={[
|
||||||
{id: "2", text: "Fax"}
|
{id: "2", text: "Fax"}
|
||||||
]} />
|
]} />
|
||||||
|
|
||||||
### Disabled
|
### Disabled state
|
||||||
|
|
||||||
<ComboBox disabled titleText="Contact" placeholder="Select contact method"
|
<ComboBox disabled titleText="Contact" placeholder="Select contact method"
|
||||||
items={[
|
items={[
|
||||||
{id: "0", text: "Slack"},
|
{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}
|
{id: "2", text: "Fax"}
|
||||||
]} />
|
]} />
|
||||||
|
|
||||||
|
### Disabled items
|
||||||
|
|
||||||
|
Use the `disabled` property in the `items` prop to disable specific items.
|
||||||
|
|
||||||
|
<ComboBox
|
||||||
|
titleText="Contact"
|
||||||
|
placeholder="Select contact method"
|
||||||
|
items={[
|
||||||
|
{ id: "0", text: "Slack" },
|
||||||
|
{ id: "1", text: "Email", disabled: true },
|
||||||
|
{ id: "2", text: "Fax" },
|
||||||
|
]}
|
||||||
|
/>
|
|
@ -95,6 +95,20 @@ Set `direction` to `"top"` for the dropdown menu to appear above the input.
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
|
### Disabled items
|
||||||
|
|
||||||
|
Use the `disabled` property in the `items` prop to disable specific items.
|
||||||
|
|
||||||
|
<Dropdown
|
||||||
|
selectedId="0"
|
||||||
|
titleText="Contact"
|
||||||
|
items={[
|
||||||
|
{ id: "0", text: "Slack" },
|
||||||
|
{ id: "1", text: "Email", disabled: true },
|
||||||
|
{ id: "2", text: "Fax" },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
### Skeleton
|
### Skeleton
|
||||||
|
|
||||||
<DropdownSkeleton />
|
<DropdownSkeleton />
|
|
@ -145,4 +145,18 @@ Set `direction` to `"top"` for the dropdown menu to appear above the input.
|
||||||
items="{[{id: "0", text: "Slack"},
|
items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}"
|
{id: "2", text: "Fax"}]}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
### Disabled items
|
||||||
|
|
||||||
|
Use the `disabled` property in the `items` prop to disable specific items.
|
||||||
|
|
||||||
|
<MultiSelect
|
||||||
|
titleText="Contact"
|
||||||
|
label="Select contact methods..."
|
||||||
|
items={[
|
||||||
|
{ id: "0", text: "Slack" },
|
||||||
|
{ id: "1", text: "Email", disabled: true },
|
||||||
|
{ id: "2", text: "Fax" },
|
||||||
|
]}
|
||||||
|
/>
|
|
@ -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;
|
||||||
}}"
|
}}"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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; }}
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +121,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,11 +262,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;
|
||||||
}}"
|
}}"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}}"
|
}}"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
const items: ComboBoxItem[] = [
|
const items: ComboBoxItem[] = [
|
||||||
{ id: 0, text: "Slack" },
|
{ id: 0, text: "Slack" },
|
||||||
{ id: "1", text: "Email" },
|
{ id: "1", text: "Email" },
|
||||||
{ id: "2", text: "Fax" },
|
{ id: "2", text: "Fax", disabled: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
let ref: ComboBox;
|
let ref: ComboBox;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
items="{[
|
items="{[
|
||||||
{ id: 0, text: 'Slack' },
|
{ id: 0, text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
{ id: '2', text: 'Fax' },
|
{ id: '2', text: 'Fax', disabled: true },
|
||||||
]}"
|
]}"
|
||||||
on:select="{(e) => {
|
on:select="{(e) => {
|
||||||
console.log(e.detail.selectedId);
|
console.log(e.detail.selectedId);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
items="{[
|
items="{[
|
||||||
{ id: 0, text: 'Slack' },
|
{ id: 0, text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
{ id: '2', text: 'Fax' },
|
{ id: '2', text: 'Fax', disabled: true },
|
||||||
]}"
|
]}"
|
||||||
on:select="{(e) => {
|
on:select="{(e) => {
|
||||||
console.log(e.detail.selectedIds);
|
console.log(e.detail.selectedIds);
|
||||||
|
|
1
types/ComboBox/ComboBox.svelte.d.ts
vendored
1
types/ComboBox/ComboBox.svelte.d.ts
vendored
|
@ -6,6 +6,7 @@ export type ComboBoxItemId = any;
|
||||||
export interface ComboBoxItem {
|
export interface ComboBoxItem {
|
||||||
id: ComboBoxItemId;
|
id: ComboBoxItemId;
|
||||||
text: string;
|
text: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComboBoxProps
|
export interface ComboBoxProps
|
||||||
|
|
1
types/Dropdown/Dropdown.svelte.d.ts
vendored
1
types/Dropdown/Dropdown.svelte.d.ts
vendored
|
@ -8,6 +8,7 @@ export type DropdownItemText = string;
|
||||||
export interface DropdownItem {
|
export interface DropdownItem {
|
||||||
id: DropdownItemId;
|
id: DropdownItemId;
|
||||||
text: DropdownItemText;
|
text: DropdownItemText;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DropdownProps
|
export interface DropdownProps
|
||||||
|
|
6
types/ListBox/ListBoxMenuItem.svelte.d.ts
vendored
6
types/ListBox/ListBoxMenuItem.svelte.d.ts
vendored
|
@ -14,6 +14,12 @@ export interface ListBoxMenuItemProps
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
highlighted?: boolean;
|
highlighted?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to `true` to disable the menu item
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ListBoxMenuItem extends SvelteComponentTyped<
|
export default class ListBoxMenuItem extends SvelteComponentTyped<
|
||||||
|
|
1
types/MultiSelect/MultiSelect.svelte.d.ts
vendored
1
types/MultiSelect/MultiSelect.svelte.d.ts
vendored
|
@ -8,6 +8,7 @@ export type MultiSelectItemText = string;
|
||||||
export interface MultiSelectItem {
|
export interface MultiSelectItem {
|
||||||
id: MultiSelectItemId;
|
id: MultiSelectItemId;
|
||||||
text: MultiSelectItemText;
|
text: MultiSelectItemText;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MultiSelectProps
|
export interface MultiSelectProps
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue