feat(multi-select): make MultiSelect slottable (#1183)

This commit is contained in:
metonym 2022-03-19 09:15:58 -07:00 committed by GitHub
commit 1017e80198
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 17 deletions

View file

@ -2456,15 +2456,17 @@ export interface MultiSelectItem {
### Slots ### Slots
None. | Slot name | Default | Props | Fallback |
| :-------- | :------ | :----------------------------------------------------- | :-------------------------------- |
| -- | Yes | <code>{ item: MultiSelectItem; index: number } </code> | <code>{itemToString(item)}</code> |
### Events ### Events
| Event name | Type | Detail | | Event name | Type | Detail |
| :--------- | :--------- | :------------------------------------------------------------------------------------------------------------- | | :--------- | :--------- | :------------------------------------------------------------------------------------------------------------- |
| blur | dispatched | <code>FocusEvent &#124; CustomEvent<FocusEvent></code> |
| select | dispatched | <code>{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }</code> | | select | dispatched | <code>{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }</code> |
| clear | dispatched | <code>null</code> | | clear | dispatched | <code>null</code> |
| blur | dispatched | <code>FocusEvent &#124; CustomEvent<FocusEvent></code> |
| keydown | forwarded | -- | | keydown | forwarded | -- |
| keyup | forwarded | -- | | keyup | forwarded | -- |
| focus | forwarded | -- | | focus | forwarded | -- |

View file

@ -6935,19 +6935,26 @@
} }
], ],
"moduleExports": [], "moduleExports": [],
"slots": [], "slots": [
"events": [
{ {
"type": "dispatched", "name": "__default__",
"name": "blur", "default": true,
"detail": "FocusEvent | CustomEvent<FocusEvent>" "fallback": "{itemToString(item)}",
}, "slot_props": "{ item: MultiSelectItem; index: number }"
}
],
"events": [
{ {
"type": "dispatched", "type": "dispatched",
"name": "select", "name": "select",
"detail": "{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }" "detail": "{ selectedIds: MultiSelectItemId[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }"
}, },
{ "type": "dispatched", "name": "clear", "detail": "null" }, { "type": "dispatched", "name": "clear", "detail": "null" },
{
"type": "dispatched",
"name": "blur",
"detail": "FocusEvent | CustomEvent<FocusEvent>"
},
{ "type": "forwarded", "name": "keydown", "element": "input" }, { "type": "forwarded", "name": "keydown", "element": "input" },
{ "type": "forwarded", "name": "keyup", "element": "input" }, { "type": "forwarded", "name": "keyup", "element": "input" },
{ "type": "forwarded", "name": "focus", "element": "input" } { "type": "forwarded", "name": "focus", "element": "input" }

View file

@ -13,6 +13,12 @@ By default, items will be ordered alphabetically based on the `item.text` value.
{id: "2", text: "Fax"}]}" {id: "2", text: "Fax"}]}"
/> />
### Custom slot
Override the default slot to customize the display of each item. Access the item and index through the `let:` directive.
<FileSource src="/framed/MultiSelect/MultiSelectSlot" />
### No alphabetical ordering ### No alphabetical ordering
To prevent alphabetical item ordering, pass an empty function to the `sortItem` prop. To prevent alphabetical item ordering, pass an empty function to the `sortItem` prop.

View file

@ -0,0 +1,33 @@
<script>
import { MultiSelect } from "carbon-components-svelte";
</script>
<MultiSelect
titleText="Contact"
label="Select contact methods..."
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
let:item
let:index
>
<div>
<strong>{item.text}</strong>
</div>
<div>
id: {item.id} - index:
{index}
</div>
</MultiSelect>
<style>
:global(.bx--list-box__menu-item, .bx--list-box__menu-item__option) {
height: auto;
}
:global(.bx--checkbox-label-text) {
display: block;
}
</style>

View file

@ -1,14 +1,12 @@
<script> <script>
/**
* @event {FocusEvent | CustomEvent<FocusEvent>} blur
*/
/** /**
* @typedef {any} MultiSelectItemId * @typedef {any} MultiSelectItemId
* @typedef {string} MultiSelectItemText * @typedef {string} MultiSelectItemText
* @typedef {{ id: MultiSelectItemId; text: MultiSelectItemText; }} MultiSelectItem * @typedef {{ id: MultiSelectItemId; text: MultiSelectItemText; }} 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
* @slot {{ item: MultiSelectItem; index: number }}
*/ */
/** /**
@ -487,7 +485,6 @@
> >
<Checkbox <Checkbox
name="{item.id}" name="{item.id}"
labelText="{itemToString(item)}"
title="{useTitleInItem ? itemToString(item) : undefined}" title="{useTitleInItem ? itemToString(item) : undefined}"
{...itemToInput(item)} {...itemToInput(item)}
readonly readonly
@ -498,7 +495,11 @@
on:blur="{() => { on:blur="{() => {
if (i === filteredItems.length - 1) open = false; if (i === filteredItems.length - 1) open = false;
}}" }}"
/> >
<slot slot="labelText" item="{item}" index="{i}">
{itemToString(item)}
</slot>
</Checkbox>
</ListBoxMenuItem> </ListBoxMenuItem>
{/each} {/each}
</ListBoxMenu> </ListBoxMenu>

View file

@ -20,7 +20,12 @@
on:blur="{(e) => { on:blur="{(e) => {
e.detail; // number | FocusEvent e.detail; // number | FocusEvent
}}" }}"
/> let:item
let:index
>
{item.id}
{index}
</MultiSelect>
<MultiSelect <MultiSelect
titleText="Contact" titleText="Contact"

View file

@ -228,16 +228,16 @@ export interface MultiSelectProps
export default class MultiSelect extends SvelteComponentTyped< export default class MultiSelect extends SvelteComponentTyped<
MultiSelectProps, MultiSelectProps,
{ {
blur: FocusEvent | CustomEvent<FocusEvent>;
select: CustomEvent<{ select: CustomEvent<{
selectedIds: MultiSelectItemId[]; selectedIds: MultiSelectItemId[];
selected: MultiSelectItem[]; selected: MultiSelectItem[];
unselected: MultiSelectItem[]; unselected: MultiSelectItem[];
}>; }>;
clear: CustomEvent<null>; clear: CustomEvent<null>;
blur: FocusEvent | CustomEvent<FocusEvent>;
keydown: WindowEventMap["keydown"]; keydown: WindowEventMap["keydown"];
keyup: WindowEventMap["keyup"]; keyup: WindowEventMap["keyup"];
focus: WindowEventMap["focus"]; focus: WindowEventMap["focus"];
}, },
{} { default: { item: MultiSelectItem; index: number } }
> {} > {}