mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
feat(Dropdown): selectedIndex -> selectedId (#1004)
* feat(breaking): selectedIndex -> selectedId in Dropdown * feat: omit `selectedIndex` from the `select` event
This commit is contained in:
parent
37f10ad1a2
commit
e11a893bee
7 changed files with 53 additions and 52 deletions
|
@ -1166,7 +1166,7 @@ export interface DropdownItem {
|
||||||
| ref | <code>let</code> | Yes | <code>null | HTMLButtonElement</code> | <code>null</code> | Obtain a reference to the button HTML element |
|
| ref | <code>let</code> | Yes | <code>null | HTMLButtonElement</code> | <code>null</code> | Obtain a reference to the button HTML element |
|
||||||
| inline | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to use the inline variant |
|
| inline | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to use the inline variant |
|
||||||
| open | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to open the dropdown |
|
| open | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to open the dropdown |
|
||||||
| selectedIndex | <code>let</code> | Yes | <code>number</code> | <code>-1</code> | Specify the selected item index |
|
| selectedId | <code>let</code> | Yes | <code>DropdownItemId</code> | -- | Specify the selected item id |
|
||||||
| items | <code>let</code> | No | <code>DropdownItem[]</code> | <code>[]</code> | Set the dropdown items |
|
| items | <code>let</code> | No | <code>DropdownItem[]</code> | <code>[]</code> | Set the dropdown items |
|
||||||
| itemToString | <code>let</code> | No | <code>(item: DropdownItem) => string</code> | <code>(item) => item.text || item.id</code> | Override the display of a dropdown item |
|
| itemToString | <code>let</code> | No | <code>(item: DropdownItem) => string</code> | <code>(item) => item.text || item.id</code> | Override the display of a dropdown item |
|
||||||
| type | <code>let</code> | No | <code>"default" | "inline"</code> | <code>"default"</code> | Specify the type of dropdown |
|
| type | <code>let</code> | No | <code>"default" | "inline"</code> | <code>"default"</code> | Specify the type of dropdown |
|
||||||
|
@ -1192,9 +1192,9 @@ None.
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
| Event name | Type | Detail |
|
| Event name | Type | Detail |
|
||||||
| :--------- | :--------- | :--------------------------------------------------------------------------------------------- |
|
| :--------- | :--------- | :---------------------------------------------------------------------- |
|
||||||
| select | dispatched | <code>{ selectedId: DropdownItemId, selectedIndex: number, selectedItem: DropdownItem }</code> |
|
| select | dispatched | <code>{ selectedId: DropdownItemId, selectedItem: DropdownItem }</code> |
|
||||||
|
|
||||||
## `DropdownSkeleton`
|
## `DropdownSkeleton`
|
||||||
|
|
||||||
|
|
|
@ -3008,11 +3008,10 @@
|
||||||
"reactive": false
|
"reactive": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "selectedIndex",
|
"name": "selectedId",
|
||||||
"kind": "let",
|
"kind": "let",
|
||||||
"description": "Specify the selected item index",
|
"description": "Specify the selected item id",
|
||||||
"type": "number",
|
"type": "DropdownItemId",
|
||||||
"value": "-1",
|
|
||||||
"isFunction": false,
|
"isFunction": false,
|
||||||
"isFunctionDeclaration": false,
|
"isFunctionDeclaration": false,
|
||||||
"constant": false,
|
"constant": false,
|
||||||
|
@ -3229,7 +3228,7 @@
|
||||||
{
|
{
|
||||||
"type": "dispatched",
|
"type": "dispatched",
|
||||||
"name": "select",
|
"name": "select",
|
||||||
"detail": "{ selectedId: DropdownItemId, selectedIndex: number, selectedItem: DropdownItem }"
|
"detail": "{ selectedId: DropdownItemId, selectedItem: DropdownItem }"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"typedefs": [
|
"typedefs": [
|
||||||
|
|
|
@ -9,13 +9,13 @@ components: ["Dropdown", "DropdownSkeleton"]
|
||||||
|
|
||||||
### Default
|
### Default
|
||||||
|
|
||||||
<Dropdown titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Hidden label
|
### Hidden label
|
||||||
|
|
||||||
<Dropdown hideLabel titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown hideLabel titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ Use the `itemToString` prop to format the display of individual items.
|
||||||
|
|
||||||
<Dropdown itemToString={item => {
|
<Dropdown itemToString={item => {
|
||||||
return item.text + ' (' + item.id +')'
|
return item.text + ' (' + item.id +')'
|
||||||
}} titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
}} titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
|
@ -37,49 +37,49 @@ Use the `itemToString` prop to format the display of individual items.
|
||||||
|
|
||||||
Set `direction` to `"top"` for the dropdown menu to appear above the input.
|
Set `direction` to `"top"` for the dropdown menu to appear above the input.
|
||||||
|
|
||||||
<Dropdown direction="top" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown direction="top" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Light variant
|
### Light variant
|
||||||
|
|
||||||
<Dropdown light titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown light titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Inline variant
|
### Inline variant
|
||||||
|
|
||||||
<Dropdown type="inline" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown type="inline" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Extra-large size
|
### Extra-large size
|
||||||
|
|
||||||
<Dropdown size="xl" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown size="xl" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Small size
|
### Small size
|
||||||
|
|
||||||
<Dropdown size="sm" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown size="sm" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Invalid state
|
### Invalid state
|
||||||
|
|
||||||
<Dropdown invalid invalidText="Secondary contact method must be different from the primary contact" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown invalid invalidText="Secondary contact method must be different from the primary contact" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Warning state
|
### Warning state
|
||||||
|
|
||||||
<Dropdown warn warnText="This contact method is not associated with your account" titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown warn warnText="This contact method is not associated with your account" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
### Disabled state
|
### Disabled state
|
||||||
|
|
||||||
<Dropdown disabled titleText="Contact" selectedIndex={0} items="{[{id: "0", text: "Slack"},
|
<Dropdown disabled titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
|
||||||
{id: "1", text: "Email"},
|
{id: "1", text: "Email"},
|
||||||
{id: "2", text: "Fax"}]}" />
|
{id: "2", text: "Fax"}]}" />
|
||||||
|
|
||||||
|
|
|
@ -7,28 +7,29 @@
|
||||||
{ id: "2", text: "Fax" },
|
{ id: "2", text: "Fax" },
|
||||||
];
|
];
|
||||||
|
|
||||||
let dropdown1_selectedIndex = 0;
|
let dropdown1_selectedId = "0";
|
||||||
let dropdown2_selectedIndex = 1;
|
let dropdown2_selectedId = "1";
|
||||||
|
|
||||||
const formatSelected = (i) => (items[i] ? items[i].text : "N/A");
|
const formatSelected = (id) =>
|
||||||
|
items.find((item) => item.id === id)?.text ?? "N/A";
|
||||||
|
|
||||||
$: primary = formatSelected(dropdown1_selectedIndex);
|
$: primary = formatSelected(dropdown1_selectedId);
|
||||||
$: secondary = formatSelected(dropdown2_selectedIndex);
|
$: secondary = formatSelected(dropdown2_selectedId);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Dropdown
|
<Dropdown
|
||||||
titleText="Primary contact"
|
titleText="Primary contact"
|
||||||
bind:selectedIndex="{dropdown1_selectedIndex}"
|
bind:selectedId="{dropdown1_selectedId}"
|
||||||
items="{items}"
|
items="{items}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>Primary: {primary}</div>
|
<div>Primary: {primary}</div>
|
||||||
|
|
||||||
<Dropdown
|
<Dropdown
|
||||||
invalid="{dropdown1_selectedIndex === dropdown2_selectedIndex}"
|
invalid="{dropdown1_selectedId === dropdown2_selectedId}"
|
||||||
invalidText="Secondary contact method must be different from the primary contact"
|
invalidText="Secondary contact method must be different from the primary contact"
|
||||||
titleText="Secondary contact"
|
titleText="Secondary contact"
|
||||||
bind:selectedIndex="{dropdown2_selectedIndex}"
|
bind:selectedId="{dropdown2_selectedId}"
|
||||||
items="{items}"
|
items="{items}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* @typedef {string} DropdownItemId
|
* @typedef {string} DropdownItemId
|
||||||
* @typedef {string} DropdownItemText
|
* @typedef {string} DropdownItemText
|
||||||
* @typedef {{ id: DropdownItemId; text: DropdownItemText; }} DropdownItem
|
* @typedef {{ id: DropdownItemId; text: DropdownItemText; }} DropdownItem
|
||||||
* @event {{ selectedId: DropdownItemId, selectedIndex: number, selectedItem: DropdownItem }} select
|
* @event {{ selectedId: DropdownItemId, selectedItem: DropdownItem }} select
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,8 +18,11 @@
|
||||||
*/
|
*/
|
||||||
export let itemToString = (item) => item.text || item.id;
|
export let itemToString = (item) => item.text || item.id;
|
||||||
|
|
||||||
/** Specify the selected item index */
|
/**
|
||||||
export let selectedIndex = -1;
|
* Specify the selected item id
|
||||||
|
* @type {DropdownItemId}
|
||||||
|
*/
|
||||||
|
export let selectedId = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the type of dropdown
|
* Specify the type of dropdown
|
||||||
|
@ -108,7 +111,6 @@
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
let selectedId = undefined;
|
|
||||||
let highlightedIndex = -1;
|
let highlightedIndex = -1;
|
||||||
|
|
||||||
function change(dir) {
|
function change(dir) {
|
||||||
|
@ -123,12 +125,11 @@
|
||||||
highlightedIndex = index;
|
highlightedIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (selectedIndex > -1) {
|
$: if (selectedId !== undefined) {
|
||||||
dispatch("select", { selectedId, selectedIndex, selectedItem });
|
dispatch("select", { selectedId, selectedItem });
|
||||||
}
|
}
|
||||||
$: inline = type === "inline";
|
$: inline = type === "inline";
|
||||||
$: selectedItem = items[selectedIndex];
|
$: selectedItem = items.find((item) => item.id === selectedId);
|
||||||
$: selectedId = items[selectedIndex] ? items[selectedIndex].id : undefined;
|
|
||||||
$: if (!open) {
|
$: if (!open) {
|
||||||
highlightedIndex = -1;
|
highlightedIndex = -1;
|
||||||
}
|
}
|
||||||
|
@ -206,8 +207,11 @@
|
||||||
}
|
}
|
||||||
if (key === 'Enter') {
|
if (key === 'Enter') {
|
||||||
open = !open;
|
open = !open;
|
||||||
if (highlightedIndex > -1 && highlightedIndex !== selectedIndex) {
|
if (
|
||||||
selectedIndex = highlightedIndex;
|
highlightedIndex > -1 &&
|
||||||
|
items[highlightedIndex].id !== selectedId
|
||||||
|
) {
|
||||||
|
selectedId = items[highlightedIndex].id;
|
||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
} else if (key === 'Tab') {
|
} else if (key === 'Tab') {
|
||||||
|
@ -233,11 +237,10 @@
|
||||||
{#each items as item, i (item.id)}
|
{#each items as item, i (item.id)}
|
||||||
<ListBoxMenuItem
|
<ListBoxMenuItem
|
||||||
id="{item.id}"
|
id="{item.id}"
|
||||||
active="{selectedIndex === i || selectedId === item.id}"
|
active="{selectedId === item.id}"
|
||||||
highlighted="{highlightedIndex === i || selectedIndex === i}"
|
highlighted="{highlightedIndex === i || selectedId === item.id}"
|
||||||
on:click="{() => {
|
on:click="{() => {
|
||||||
selectedId = item.id;
|
selectedId = item.id;
|
||||||
selectedIndex = i;
|
|
||||||
ref.focus();
|
ref.focus();
|
||||||
}}"
|
}}"
|
||||||
on:mouseenter="{() => {
|
on:mouseenter="{() => {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
direction="top"
|
direction="top"
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
return item.text + ' (' + item.id + ')';
|
return item.text + ' (' + item.id + ')';
|
||||||
}}"
|
}}"
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
light
|
light
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
type="inline"
|
type="inline"
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
size="xl"
|
size="xl"
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
size="sm"
|
size="sm"
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
<Dropdown
|
<Dropdown
|
||||||
disabled
|
disabled
|
||||||
titleText="Contact"
|
titleText="Contact"
|
||||||
selectedIndex="{0}"
|
selectedId="0"
|
||||||
items="{[
|
items="{[
|
||||||
{ id: '0', text: 'Slack' },
|
{ id: '0', text: 'Slack' },
|
||||||
{ id: '1', text: 'Email' },
|
{ id: '1', text: 'Email' },
|
||||||
|
|
6
types/Dropdown/Dropdown.svelte.d.ts
vendored
6
types/Dropdown/Dropdown.svelte.d.ts
vendored
|
@ -25,10 +25,9 @@ export interface DropdownProps
|
||||||
itemToString?: (item: DropdownItem) => string;
|
itemToString?: (item: DropdownItem) => string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the selected item index
|
* Specify the selected item id
|
||||||
* @default -1
|
|
||||||
*/
|
*/
|
||||||
selectedIndex?: number;
|
selectedId?: DropdownItemId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the type of dropdown
|
* Specify the type of dropdown
|
||||||
|
@ -146,7 +145,6 @@ export default class Dropdown extends SvelteComponentTyped<
|
||||||
{
|
{
|
||||||
select: CustomEvent<{
|
select: CustomEvent<{
|
||||||
selectedId: DropdownItemId;
|
selectedId: DropdownItemId;
|
||||||
selectedIndex: number;
|
|
||||||
selectedItem: DropdownItem;
|
selectedItem: DropdownItem;
|
||||||
}>;
|
}>;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue