mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
@ -1192,9 +1192,9 @@ None.
|
|||
|
||||
### Events
|
||||
|
||||
| Event name | Type | Detail |
|
||||
| :--------- | :--------- | :--------------------------------------------------------------------------------------------- |
|
||||
| select | dispatched | <code>{ selectedId: DropdownItemId, selectedIndex: number, selectedItem: DropdownItem }</code> |
|
||||
| Event name | Type | Detail |
|
||||
| :--------- | :--------- | :---------------------------------------------------------------------- |
|
||||
| select | dispatched | <code>{ selectedId: DropdownItemId, selectedItem: DropdownItem }</code> |
|
||||
|
||||
## `DropdownSkeleton`
|
||||
|
||||
|
|
|
@ -3008,11 +3008,10 @@
|
|||
"reactive": false
|
||||
},
|
||||
{
|
||||
"name": "selectedIndex",
|
||||
"name": "selectedId",
|
||||
"kind": "let",
|
||||
"description": "Specify the selected item index",
|
||||
"type": "number",
|
||||
"value": "-1",
|
||||
"description": "Specify the selected item id",
|
||||
"type": "DropdownItemId",
|
||||
"isFunction": false,
|
||||
"isFunctionDeclaration": false,
|
||||
"constant": false,
|
||||
|
@ -3229,7 +3228,7 @@
|
|||
{
|
||||
"type": "dispatched",
|
||||
"name": "select",
|
||||
"detail": "{ selectedId: DropdownItemId, selectedIndex: number, selectedItem: DropdownItem }"
|
||||
"detail": "{ selectedId: DropdownItemId, selectedItem: DropdownItem }"
|
||||
}
|
||||
],
|
||||
"typedefs": [
|
||||
|
|
|
@ -9,13 +9,13 @@ components: ["Dropdown", "DropdownSkeleton"]
|
|||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
|
@ -25,7 +25,7 @@ Use the `itemToString` prop to format the display of individual items.
|
|||
|
||||
<Dropdown itemToString={item => {
|
||||
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: "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.
|
||||
|
||||
<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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
### 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: "2", text: "Fax"}]}" />
|
||||
|
||||
|
|
|
@ -7,28 +7,29 @@
|
|||
{ id: "2", text: "Fax" },
|
||||
];
|
||||
|
||||
let dropdown1_selectedIndex = 0;
|
||||
let dropdown2_selectedIndex = 1;
|
||||
let dropdown1_selectedId = "0";
|
||||
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);
|
||||
$: secondary = formatSelected(dropdown2_selectedIndex);
|
||||
$: primary = formatSelected(dropdown1_selectedId);
|
||||
$: secondary = formatSelected(dropdown2_selectedId);
|
||||
</script>
|
||||
|
||||
<Dropdown
|
||||
titleText="Primary contact"
|
||||
bind:selectedIndex="{dropdown1_selectedIndex}"
|
||||
bind:selectedId="{dropdown1_selectedId}"
|
||||
items="{items}"
|
||||
/>
|
||||
|
||||
<div>Primary: {primary}</div>
|
||||
|
||||
<Dropdown
|
||||
invalid="{dropdown1_selectedIndex === dropdown2_selectedIndex}"
|
||||
invalid="{dropdown1_selectedId === dropdown2_selectedId}"
|
||||
invalidText="Secondary contact method must be different from the primary contact"
|
||||
titleText="Secondary contact"
|
||||
bind:selectedIndex="{dropdown2_selectedIndex}"
|
||||
bind:selectedId="{dropdown2_selectedId}"
|
||||
items="{items}"
|
||||
/>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @typedef {string} DropdownItemId
|
||||
* @typedef {string} DropdownItemText
|
||||
* @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;
|
||||
|
||||
/** 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
|
||||
|
@ -108,7 +111,6 @@
|
|||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let selectedId = undefined;
|
||||
let highlightedIndex = -1;
|
||||
|
||||
function change(dir) {
|
||||
|
@ -123,12 +125,11 @@
|
|||
highlightedIndex = index;
|
||||
}
|
||||
|
||||
$: if (selectedIndex > -1) {
|
||||
dispatch("select", { selectedId, selectedIndex, selectedItem });
|
||||
$: if (selectedId !== undefined) {
|
||||
dispatch("select", { selectedId, selectedItem });
|
||||
}
|
||||
$: inline = type === "inline";
|
||||
$: selectedItem = items[selectedIndex];
|
||||
$: selectedId = items[selectedIndex] ? items[selectedIndex].id : undefined;
|
||||
$: selectedItem = items.find((item) => item.id === selectedId);
|
||||
$: if (!open) {
|
||||
highlightedIndex = -1;
|
||||
}
|
||||
|
@ -206,8 +207,11 @@
|
|||
}
|
||||
if (key === 'Enter') {
|
||||
open = !open;
|
||||
if (highlightedIndex > -1 && highlightedIndex !== selectedIndex) {
|
||||
selectedIndex = highlightedIndex;
|
||||
if (
|
||||
highlightedIndex > -1 &&
|
||||
items[highlightedIndex].id !== selectedId
|
||||
) {
|
||||
selectedId = items[highlightedIndex].id;
|
||||
open = false;
|
||||
}
|
||||
} else if (key === 'Tab') {
|
||||
|
@ -233,11 +237,10 @@
|
|||
{#each items as item, i (item.id)}
|
||||
<ListBoxMenuItem
|
||||
id="{item.id}"
|
||||
active="{selectedIndex === i || selectedId === item.id}"
|
||||
highlighted="{highlightedIndex === i || selectedIndex === i}"
|
||||
active="{selectedId === item.id}"
|
||||
highlighted="{highlightedIndex === i || selectedId === item.id}"
|
||||
on:click="{() => {
|
||||
selectedId = item.id;
|
||||
selectedIndex = i;
|
||||
ref.focus();
|
||||
}}"
|
||||
on:mouseenter="{() => {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<Dropdown
|
||||
direction="top"
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -18,7 +18,7 @@
|
|||
return item.text + ' (' + item.id + ')';
|
||||
}}"
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -29,7 +29,7 @@
|
|||
<Dropdown
|
||||
light
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -40,7 +40,7 @@
|
|||
<Dropdown
|
||||
type="inline"
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -51,7 +51,7 @@
|
|||
<Dropdown
|
||||
size="xl"
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -62,7 +62,7 @@
|
|||
<Dropdown
|
||||
size="sm"
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ id: '1', text: 'Email' },
|
||||
|
@ -73,7 +73,7 @@
|
|||
<Dropdown
|
||||
disabled
|
||||
titleText="Contact"
|
||||
selectedIndex="{0}"
|
||||
selectedId="0"
|
||||
items="{[
|
||||
{ id: '0', text: 'Slack' },
|
||||
{ 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;
|
||||
|
||||
/**
|
||||
* Specify the selected item index
|
||||
* @default -1
|
||||
* Specify the selected item id
|
||||
*/
|
||||
selectedIndex?: number;
|
||||
selectedId?: DropdownItemId;
|
||||
|
||||
/**
|
||||
* Specify the type of dropdown
|
||||
|
@ -146,7 +145,6 @@ export default class Dropdown extends SvelteComponentTyped<
|
|||
{
|
||||
select: CustomEvent<{
|
||||
selectedId: DropdownItemId;
|
||||
selectedIndex: number;
|
||||
selectedItem: DropdownItem;
|
||||
}>;
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue