Forms

Select

A dropdown select with icons, avatars, grouped items, descriptions, and custom rendering. Built on bits-ui with full keyboard navigation.

Playground

Experiment with different props in real-time.

Basic Usage

Pass items and use bind:value.

<script lang="ts">
  import { Select } from 'sv5ui';

  let value = $state('');

  const countries = [
    { value: 'us', label: 'United States' },
    { value: 'ca', label: 'Canada' },
    { value: 'mx', label: 'Mexico' },
    { value: 'br', label: 'Brazil' },
    { value: 'ar', label: 'Argentina' }
  ];
</script>

<Select items={countries} bind:value placeholder="Select a country" />

Variants

5 trigger visual styles.

<Select items={frameworks} variant="outline" placeholder="Outline" />
<Select items={frameworks} variant="none" placeholder="None" />
<Select items={frameworks} variant="soft" placeholder="Soft" />
<Select items={frameworks} variant="subtle" placeholder="Subtle" />
<Select items={frameworks} variant="ghost" placeholder="Ghost" />

Sizes

5 sizes.

<Select items={frameworks} size="xs" placeholder="Extra Small" />
<Select items={frameworks} size="sm" placeholder="Small" />
<Select items={frameworks} size="md" placeholder="Medium" />
<Select items={frameworks} size="lg" placeholder="Large" />
<Select items={frameworks} size="xl" placeholder="Extra Large" />

Colors

Color schemes visible with highlight.

<Select items={frameworks} color="primary" placeholder="Primary" />
<Select items={frameworks} color="secondary" placeholder="Secondary" />
<Select items={frameworks} color="success" placeholder="Success" />
<Select items={frameworks} color="warning" placeholder="Warning" />
<Select items={frameworks} color="error" placeholder="Error" />
<Select items={frameworks} color="info" placeholder="Info" />

With Icons

Add icons to items and the trigger.

<script lang="ts">
  const browsers = [
    { value: 'chrome', label: 'Chrome', icon: 'logos:chrome' },
    { value: 'firefox', label: 'Firefox', icon: 'logos:firefox' },
    { value: 'safari', label: 'Safari', icon: 'logos:safari' },
    { value: 'edge', label: 'Edge', icon: 'logos:microsoft-edge' }
  ];
</script>

<Select items={browsers} placeholder="Choose a browser" icon="lucide:globe" />

With Descriptions

Add secondary text to items.

<script lang="ts">
  const roles = [
    { value: 'admin', label: 'Admin', description: 'Full access to all resources' },
    { value: 'editor', label: 'Editor', description: 'Can edit and publish content' },
    { value: 'viewer', label: 'Viewer', description: 'Read-only access' }
  ];
</script>

<Select items={roles} placeholder="Assign a role" />

Grouped Items

Use type: 'label' and type: 'separator'.

<script lang="ts">
  const items = [
    { type: 'label', label: 'Frontend' },
    { value: 'react', label: 'React' },
    { value: 'vue', label: 'Vue' },
    { value: 'svelte', label: 'Svelte' },
    { type: 'separator' },
    { type: 'label', label: 'Backend' },
    { value: 'node', label: 'Node.js' },
    { value: 'python', label: 'Python' },
    { value: 'go', label: 'Go' }
  ];
</script>

<Select items={items} placeholder="Pick a technology" />

With Avatar

Display avatars alongside items.

<script lang="ts">
  const members = [
    { value: 'alice', label: 'Alice Martin', avatar: { src: 'https://i.pravatar.cc/40?u=alice', alt: 'Alice' } },
    { value: 'bob', label: 'Bob Wilson', avatar: { src: 'https://i.pravatar.cc/40?u=bob', alt: 'Bob' } },
    { value: 'carol', label: 'Carol Lee', avatar: { src: 'https://i.pravatar.cc/40?u=carol', alt: 'Carol' } }
  ];
</script>

<Select items={members} placeholder="Assign to member" />

Disabled

Disable the select or individual items.

<script lang="ts">
  const plans = [
    { value: 'free', label: 'Free' },
    { value: 'pro', label: 'Pro' },
    { value: 'enterprise', label: 'Enterprise', disabled: true }
  ];
</script>

<Select items={plans} placeholder="Select a plan" />
<Select items={plans} placeholder="Disabled select" disabled />

UI Slots

Use the ui prop to override classes on internal elements.

SlotDescription
rootOutermost container wrapper
baseTrigger button element
leadingLeading content wrapper
leadingIconLeading icon element
leadingAvatarLeading avatar element
trailingTrailing content wrapper
trailingIconTrailing icon (chevron)
valueSelected value text
placeholderPlaceholder text
contentDropdown content panel
viewportScrollable viewport
groupOption group wrapper
groupLabelGroup label text
itemIndividual option
itemIconIcon in option
itemAvatarAvatar in option
itemLabelLabel text in option
itemDescriptionDescription in option
itemIndicatorSelected checkmark
separatorSeparator between groups
<Select
  items={countries}
  placeholder="Custom styled"
  ui={{
    base: 'rounded-full shadow-lg',
    content: 'rounded-xl',
    item: 'rounded-lg'
  }}
/>

Snippets

SnippetDescription
leadingSlotCustom content before selected value
trailingSlotCustom content after selected value
itemCustom option rendering (receives item, index, selected)
itemLeadingCustom option leading (receives item, index, selected)
itemLabelCustom option label (receives item, index, selected)
itemTrailingCustom option trailing (receives item, index, selected)
contentCustom dropdown content (receives open)

Props

PropTypeDefault
itemsSelectItemType[][]
valuestring-
defaultValuestring-
openbooleanfalse
placeholderstring-
variant'outline' | 'soft' | 'subtle' | 'ghost' | 'none''outline'
colorColorType'primary'
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
highlightbooleanfalse
loadingbooleanfalse
disabledbooleanfalse
iconstring-
leadingIconstring-
trailingIconstring'lucide:chevron-down'
selectedIconstring'lucide:check'
avatarAvatarProps-
requiredbooleanfalse
namestring-
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-

Item Props

Use type: 'label' for group headings and type: 'separator' for dividers.

PropTypeDefault
valuestring-
labelstring-
descriptionstring-
iconstring-
avatarAvatarProps-
disabledbooleanfalse