Skip to content
CodeAtlas UI

Inputs

Select

Dropdown selector built on Bits UI with keyboard navigation and a glass content panel.

<script>
  import { Select } from "@codeatlasdev/ui";
  let value = $state("br");
</script>

<Select label="Country" options={[{ value: "br", label: "Brazil" }]} bind:value />

For long lists that need filtering, use Combobox. Without a label the trigger is named by its placeholder. Text inside inputs stays at 16px or more on touch screens, so iOS Safari never zooms on focus.

Basic

Controlled select with a pre-selected value.

Selected: svelte

Code
svelte
<script lang="ts">
  import { Select } from '@codeatlasdev/ui';

  let framework = $state('svelte');

  const frameworks = [
    { value: 'svelte', label: 'Svelte 5' },
    { value: 'react', label: 'React 19' },
    { value: 'vue', label: 'Vue 3' },
    { value: 'solid', label: 'SolidJS' },
    { value: 'astro', label: 'Astro' },
  ];
</script>

<div class="col">
  <Select label="Framework" options={frameworks} bind:value={framework} />
  <p class="out">Selected: <strong>{framework}</strong></p>
</div>

<style>
  .col {
    display: flex;
    flex-direction: column;
    gap: var(--ca-space-3);
    width: 100%;
    max-width: 320px;
  }

  .out {
    margin: 0;
    font-size: var(--ca-font-size-body2);
    color: var(--ca-text-secondary);
  }

  .out strong {
    color: var(--ca-brand-text);
    font-family: var(--ca-font-mono);
  }
</style>

Placeholder

No initial value: the placeholder shows until the user picks an option.

Code
svelte
<script lang="ts">
  import { Select } from '@codeatlasdev/ui';

  let country = $state('');

  const countries = [
    { value: 'br', label: 'Brazil' },
    { value: 'us', label: 'United States' },
    { value: 'de', label: 'Germany' },
    { value: 'jp', label: 'Japan' },
    { value: 'au', label: 'Australia' },
  ];
</script>

<div class="col">
  <Select label="Country" placeholder="Choose a country…" options={countries} bind:value={country} />
</div>

<style>
  .col {
    width: 100%;
    max-width: 320px;
  }
</style>

States

Disabled options, description, error and a disabled select.

Enterprise is disabled.

Code
svelte
<script lang="ts">
  import { Select } from '@codeatlasdev/ui';

  let size = $state('md');
  let plan = $state('free');

  const sizes = [
    { value: 'sm', label: 'Small' },
    { value: 'md', label: 'Medium' },
    { value: 'lg', label: 'Large' },
  ];

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

<div class="col">
  <Select label="Plan" description="Enterprise is disabled." options={plans} bind:value={plan} />
  <Select label="Region" options={sizes} error="Pick a region to continue." />
  <Select label="Size" options={sizes} bind:value={size} disabled />
</div>

<style>
  .col {
    display: flex;
    flex-direction: column;
    gap: var(--ca-space-4);
    width: 100%;
    max-width: 320px;
  }
</style>

Props

PropTypeDefaultDescription
valuestring–Bindable selected value.
optionsArray<{ value: string; label: string; disabled?: boolean }>–Option items.
placeholderstring'Select…' (localized)Text shown when no value is selected. The default comes from the active i18n catalog.
labelstring–Visible label above the trigger.
descriptionstring–Hint shown below the trigger.
errorstring–Error message. Puts the select in the error state.
requiredbooleanfalseMarks the field as required.
disabledbooleanfalseDisables the entire select.
size'sm' | 'md''md'Trigger height.
classstring–Extra classes on the root.
onchange(value: string) => void–Called when the selection changes.