Installation

Barrel

import { Select } from 'kumo-svelte';

Granular

import { Select } from 'kumo-svelte/components/select';

Usage

<script lang="ts">  import { Select } from 'kumo-svelte';  let value = $state('apple');</script><Select  label="Favorite Fruit"  bind:value  items={{ apple: 'Apple', banana: 'Banana', cherry: 'Cherry' }}/>

Examples

Basic

A select with a visible label. When you provide the label prop, the select automatically renders inside a Field wrapper with the label displayed above it.

Sizes

Use the size prop to match Input sizing (xs, sm, base, lg).

Without Visible Label

When a visible label isn't needed (e.g., in compact UIs or when context is clear), use aria-label for accessibility.

With Description and Error

Select integrates with the Field wrapper to show description text and validation errors.

Placeholder

Use the placeholder prop to show text when no value is selected. When using renderValue to customize the display of selected values, the placeholder is shown instead of calling renderValue when the value is null.

<script lang="ts">  import { Select } from 'kumo-svelte';  type User = { id: string; name: string };  const users: User[] = [    { id: 'visal', name: 'Visal' },    { id: 'alice', name: 'Alice' }  ];  let user = $state('');</script><Select  placeholder="Select a user..."  bind:value={user}  items={Object.fromEntries(users.map((user) => [user.id, user.name]))}/>

Label with Tooltip

Add a tooltip icon next to the label for additional context using labelTooltip.

Custom Rendering

Use renderValue to customize how the selected value appears in the trigger button. This is useful when working with complex object data structures instead of simple string values.

The renderValue function is only called when a value is selected. Use placeholder to define what to show when no value is selected.

<script lang="ts">  import { Select } from 'kumo-svelte';  const languages = [    { value: 'en', label: 'English', emoji: 'GB' },    { value: 'fr', label: 'French', emoji: 'FR' },    { value: 'de', label: 'German', emoji: 'DE' }  ];  let value = $state('en');</script><Select  class="w-[200px]"  placeholder="Select a language..."  bind:value  items={languages.map((language) => ({    value: language.value,    label: `${language.emoji} ${language.label}`  }))}/>

Loading

A select component with loading state. The loading state is passed to the component via the loading prop.

Multiple Selection

Enable multiple selection with the multiple prop. The value becomes an array of selected items. Use placeholder for the empty state and renderValue to customize how selections are displayed.

<script lang="ts">  import { Select } from 'kumo-svelte';  let selectedColumns = $state(['name', 'email']);</script><Select  multiple  placeholder="Select columns..."  bind:value={selectedColumns}  renderValue={(columns) => columns.join(", ")}  items={{ name: "Name", email: "Email" }}/>

More Example

Disabled Options

Options can be disabled with the disabled prop. Disabled options are greyed out and cannot be selected.

Disabled Items (via items prop)

The items object-map prop accepts descriptor objects with disabled alongside plain string values.

Grouped Options

Use Select.Group, Select.GroupLabel, and Select.Separator to organize options under labeled headers with visual dividers.

Groups with Disabled Options

Combine groups, separators, and disabled options with info tooltips to clearly separate available and unavailable choices.

Long List (Scrolling Test)

A select component with many options to test popup scrolling behavior. The popup should scroll smoothly without bounce/overscroll issues.

API Reference

Select

PropTypeDefaultDescription
class string-Additional classes merged onto the root element.
size 'xs' | 'sm' | 'base' | 'lg'"base"Size preset.
label string | Snippet-Visible label content.
hideLabel booleanfalsehideLabel prop.
placeholder string"Select..."Placeholder text.
loading booleanfalseLoading state.
disabled booleanfalseDisables the component.
required booleanfalseMarks the field as required.
labelTooltip string | Snippet-Optional help content for the label.
value Value-Controlled value.
children Snippet-Child snippet rendered by the component.
description string | Snippet-Supporting description text.
error FieldError-Validation error message or matcher.
defaultValue Value-Initial uncontrolled value.
renderValue (value: Value) => unknown-Custom selected-value renderer.
items Record<string, SelectItemValue> | { label: Snippet | string; value: Value }[]-Items rendered by the component.
options Option[][]Options rendered by the component.
multiple booleanfalseEnables multiple selection.
name string-Form field name.
container HTMLElement | string-Container element for the portal.

Select.Option

PropTypeDefaultDescription
size 'xs' | 'sm' | 'base' | 'lg'"base"Size preset.
label string | Snippet-Visible label content.
hideLabel booleanfalsehideLabel prop.
placeholder string"Select..."Placeholder text.
loading booleanfalseLoading state.
disabled booleanfalseDisables the component.
required booleanfalseMarks the field as required.
labelTooltip string | Snippet-Optional help content for the label.
value Value-Controlled value.
description string | Snippet-Supporting description text.
error FieldError-Validation error message or matcher.
defaultValue Value-Initial uncontrolled value.
renderValue (value: Value) => unknown-Custom selected-value renderer.
items Record<string, SelectItemValue> | { label: Snippet | string; value: Value }[]-Items rendered by the component.
options Option[][]Options rendered by the component.
multiple booleanfalseEnables multiple selection.
name string-Form field name.
container HTMLElement | string-Container element for the portal.

Select.Group

Groups related options together with an accessible role="group". Use with Select.GroupLabel to provide a visible heading.

Select.GroupLabel

A visible heading for a Select.Group. Automatically associated with its parent group for accessibility.

Select.Separator

A visual divider line between option groups. Renders with role="separator".