- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<Listbox class="w-full max-w-md" {collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function Default() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
return (
<Listbox className="w-full max-w-md" collection={collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
Groups
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
Fruits
Vegetables
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple', type: 'Fruits' },
{ label: 'Banana', value: 'banana', type: 'Fruits' },
{ label: 'Orange', value: 'orange', type: 'Fruits' },
{ label: 'Carrot', value: 'carrot', type: 'Vegetables' },
{ label: 'Broccoli', value: 'broccoli', type: 'Vegetables' },
{ label: 'Spinach', value: 'spinach', type: 'Vegetables' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
groupBy: (item) => item.type,
});
</script>
<Listbox class="w-full max-w-md" {collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.group() as [type, items] (type)}
<Listbox.ItemGroup>
<Listbox.ItemGroupLabel>{type}</Listbox.ItemGroupLabel>
{#each items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.ItemGroup>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
Fruits
Vegetables
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple', type: 'Fruits' },
{ label: 'Banana', value: 'banana', type: 'Fruits' },
{ label: 'Orange', value: 'orange', type: 'Fruits' },
{ label: 'Carrot', value: 'carrot', type: 'Vegetables' },
{ label: 'Broccoli', value: 'broccoli', type: 'Vegetables' },
{ label: 'Spinach', value: 'spinach', type: 'Vegetables' },
];
export default function Group() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
groupBy: (item) => item.type,
});
return (
<Listbox className="w-full max-w-md" collection={collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.group().map(([type, items]) => (
<Listbox.ItemGroup key={type}>
<Listbox.ItemGroupLabel>{type}</Listbox.ItemGroupLabel>
{items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.ItemGroup>
))}
</Listbox.Content>
</Listbox>
);
}
Multiple
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<Listbox class="w-full max-w-md" {collection} selectionMode="multiple">
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function Multiple() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
return (
<Listbox className="w-full max-w-md" collection={collection} selectionMode="multiple">
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
Disabled
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<Listbox class="w-full max-w-md" {collection} disabled={true}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function Disabled() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
return (
<Listbox className="w-full max-w-md" collection={collection} disabled={true}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
Disabled Item
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
isItemDisabled: (item) => item.value === 'banana',
});
</script>
<Listbox class="w-full max-w-md" {collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function DisabledItem() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
isItemDisabled: (item) => item.value === 'banana',
});
return (
<Listbox className="w-full max-w-md" collection={collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
Search
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
let query = $state('');
const collection = $derived(
useListCollection({
items: data.filter((item) => item.label.toLowerCase().includes(query.toLowerCase())),
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
}),
);
</script>
<Listbox class="w-full max-w-md" {collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Input placeholder="Type to search..." value={query} onchange={(e) => (query = e.currentTarget.value)} />
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
import { useMemo, useState } from 'react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function Search() {
const [query, setQuery] = useState('');
const collection = useMemo(() => {
const items = data.filter((item) => item.label.toLowerCase().includes(query.toLowerCase()));
return useListCollection({ items });
}, [query]);
return (
<Listbox className="w-full max-w-md" collection={collection}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Input placeholder="Type to search..." value={query} onChange={(e) => setQuery(e.currentTarget.value)} />
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
Direction
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
<script lang="ts">
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-svelte';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<Listbox class="w-full max-w-md" {collection} dir="rtl">
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{#each collection.items as item (item.value)}
<Listbox.Item {item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
{/each}
</Listbox.Content>
</Listbox>
- Apple
- Banana
- Orange
- Carrot
- Broccoli
- Spinach
import { Listbox, useListCollection } from '@skeletonlabs/skeleton-react';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli' },
{ label: 'Spinach', value: 'spinach' },
];
export default function Dir() {
const collection = useListCollection({
items: data,
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
return (
<Listbox className="w-full max-w-md" collection={collection} dir="rtl">
<Listbox.Label>Label</Listbox.Label>
<Listbox.Content>
{collection.items.map((item) => (
<Listbox.Item key={item.value} item={item}>
<Listbox.ItemText>{item.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox>
);
}
API Reference
Root
| Property | Default | Type |
|---|---|---|
orientation | "vertical" | "horizontal" | "vertical" | undefinedThe orientation of the listbox. |
collection | - | ListCollection<any> | GridCollection<any>The item collection |
ids | - | Partial<{ root: string; content: string; label: string; item: (id: string | number) => string; itemGroup: (id: string | number) => string; itemGroupLabel: (id: string | number) => string; }> | undefined The ids of the elements in the listbox. Useful for composition. |
disabled | - | boolean | undefinedWhether the listbox is disabled |
disallowSelectAll | - | boolean | undefinedWhether to disallow selecting all items when `meta+a` is pressed |
onHighlightChange | - | ((details: HighlightChangeDetails<any>) => void) | undefinedThe callback fired when the highlighted item changes. |
onValueChange | - | ((details: ValueChangeDetails<any>) => void) | undefinedThe callback fired when the selected item changes. |
value | - | string[] | undefinedThe controlled keys of the selected items |
defaultValue | [] | string[] | undefinedThe initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. |
highlightedValue | - | string | null | undefinedThe controlled key of the highlighted item |
defaultHighlightedValue | - | string | null | undefinedThe initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. |
loopFocus | false | boolean | undefinedWhether to loop the keyboard navigation through the options |
selectionMode | "single" | SelectionMode | undefinedHow multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. |
scrollToIndexFn | - | ((details: ScrollToIndexDetails) => void) | undefinedFunction to scroll to a specific index |
selectOnHighlight | - | boolean | undefinedWhether to select the item when it is highlighted |
deselectable | - | boolean | undefinedWhether to disallow empty selection |
typeahead | - | boolean | undefinedWhether to enable typeahead on the listbox |
onSelect | - | ((details: SelectionDetails) => void) | undefinedFunction called when an item is selected |
dir | "ltr" | "ltr" | "rtl" | undefinedThe document's text/writing direction. |
getRootNode | - | (() => ShadowRoot | Node | Document) | undefinedA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootProvider
| Property | Default | Type |
|---|---|---|
value | - | ListboxApi<PropTypes, any> |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootContext
| Property | Default | Type |
|---|---|---|
children | - | (listbox: ListboxApi<PropTypes, any>) => ReactNode |
Label
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"label">) => Element) | undefinedRender the element yourself |
Input
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"input">) => Element) | undefinedRender the element yourself |
Content
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"ul">) => Element) | undefinedRender the element yourself |
ItemGroup
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
ItemGroupLabel
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
Item
| Property | Default | Type |
|---|---|---|
item | - | anyThe item to render |
highlightOnHover | - | boolean | undefinedWhether to highlight the item on hover |
element | - | ((attributes: HTMLAttributes<"li">) => Element) | undefinedRender the element yourself |
ItemText
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"span">) => Element) | undefinedRender the element yourself |
ItemIndicator
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"span">) => Element) | undefinedRender the element yourself |