Skip to main content
Urbicon UI

Select

Form-focused select dropdown with label, validation, keyboard navigation, grouped options, and form integration.

Playground

Variant
Tier Style variant (tailwind-variants)
<script lang="ts">
  import { Select } from '@urbicon-ui/blocks';

  const options = [
    { label: 'Svelte', value: 'svelte' },
    { label: 'React', value: 'react' },
    { label: 'Vue', value: 'vue' },
    { label: 'Angular', value: 'angular' }
  ];
</script>

<Select
  {options}
  clearable
  label="Framework"
  placeholder="Choose a framework"
/>

01 Examples

Grouped options

Use the groups prop to organize long option lists under section labels — typical for timezones, countries by region, or categorized data.
<Select label="Timezone" groups={timezoneGroups} placeholder="Select timezone" />

Per-option disabled

Disable individual options while the rest of the list stays selectable. Keyboard navigation skips disabled options.
<Select
  label="Plan"
  options={[
    { label: 'Free', value: 'free' },
    { label: 'Starter', value: 'starter' },
    { label: 'Pro', value: 'pro' },
    { label: 'Enterprise (Contact us)', value: 'enterprise', disabled: true }
  ]}
  placeholder="Choose a plan"
/>

Helper & error

Helper and error text follow the same form-field contract as Input — error overrides helper when both are set.
Choose your preferred language
<Select
  label="Language"
  options={countries}
  helper="Choose your preferred language"
  placeholder="Select..."
/>
<Select
  label="Department"
  options={countries}
  error="Please select a department"
  placeholder="Select..."
/>

Form Integration

Select with hidden input for native form submission.

Form value: editor

<div class="border-border-subtle bg-surface-elevated w-full space-y-4 rounded-2xl border p-5">
  <Select
    label="User Role"
    name="role"
    bind:value={selectedRole}
    options={[
      { label: 'Viewer', value: 'viewer' },
      { label: 'Editor', value: 'editor' },
      { label: 'Admin', value: 'admin' }
    ]}
  />
  <p class="text-text-tertiary text-xs">
    Form value: <code class="text-text-primary">{selectedRole ?? 'null'}</code>
  </p>
</div>

02 Customization

Pill Trigger via slotClasses

Select spans two surfaces — the field (trigger, triggerText, placeholder, chevron, clear) and the floating list (listbox, option, group, groupLabel). Here the trigger becomes a pill and the listbox gets a matching radius with a stronger shadow; keyboard navigation and the form contract are untouched.
<Select
  label="Sort by"
  options={[
    { label: 'Newest first', value: 'newest' },
    { label: 'Price ascending', value: 'price-asc' },
    { label: 'Price descending', value: 'price-desc' }
  ]}
  value="newest"
  slotClasses={{
    trigger: 'rounded-full',
    listbox: 'rounded-xl shadow-[var(--blocks-shadow-lg)]',
    option: 'rounded-lg'
  }}
/>

unstyled strips every slot's default classes while the combobox ARIA wiring, keyboard navigation, and hidden form input keep working — rebuild both surfaces through slotClasses. A field treatment your forms share (with Input and Combobox) belongs in BlocksProvider presets (presets.Select) rather than per-instance overrides — see Customization.

03 Accessibility

ARIA Combobox

The trigger uses role="combobox" with aria-expanded, aria-haspopup="listbox", and aria-controls. Options use role="option" with aria-selected. Label, error, and helper text are linked via aria-labelledby and aria-describedby.

Keyboard

Enter / Space / Arrow Down opens the dropdown. Arrow Up/Down navigates options. Home/End jump to first/last. Escape closes and returns focus.

Form Submission

When the name prop is set, a hidden <input> element carries the selected value for native form submission without JavaScript.

04 API Reference

39 props
39 props
Prop
Type
Default
Description

05 Types

Local type definitions used by this component.

13 types
Name
Kind
Category
Used by
Description

06 Installation

Import

import { Select } from '@urbicon-ui/blocks';