Listbox

A list of options that can be selected by the user.

	<script lang="ts">
  import { Listbox } from "bits-ui";
  import Check from "phosphor-svelte/lib/Check";
  import Palette from "phosphor-svelte/lib/Palette";
  import CaretUpDown from "phosphor-svelte/lib/CaretUpDown";
 
  const themes = [
    { value: "light-monochrome", label: "Light Monochrome" },
    { value: "dark-green", label: "Dark Green" },
    { value: "svelte-orange", label: "Svelte Orange" },
    { value: "punk-pink", label: "Punk Pink" },
    { value: "ocean-blue", label: "Ocean Blue" },
    { value: "sunset-red", label: "Sunset Red" },
    { value: "forest-green", label: "Forest Green" },
    { value: "lavender-purple", label: "Lavender Purple" },
    { value: "mustard-yellow", label: "Mustard Yellow" },
    { value: "slate-gray", label: "Slate Gray" },
    { value: "neon-green", label: "Neon Green" },
    { value: "coral-reef", label: "Coral Reef" },
    { value: "midnight-blue", label: "Midnight Blue" },
    { value: "crimson-red", label: "Crimson Red" },
    { value: "mint-green", label: "Mint Green" },
    { value: "pastel-pink", label: "Pastel Pink" },
    { value: "golden-yellow", label: "Golden Yellow" },
    { value: "deep-purple", label: "Deep Purple" },
    { value: "turquoise-blue", label: "Turquoise Blue" },
    { value: "burnt-orange", label: "Burnt Orange" }
  ];
 
  let value = $state<string>("");
  const selectedLabel = $derived(
    value
      ? themes.find((theme) => theme.value === value)?.label
      : "Select a theme"
  );
</script>
 
<Listbox.Root type="single" bind:value>
  <Listbox.Trigger
    class="inline-flex h-input w-[296px] select-none items-center rounded-9px border border-border-input bg-background px-[11px] text-sm transition-colors placeholder:text-foreground-alt/50"
    aria-label="Select a theme"
  >
    <Palette class="mr-[9px] size-6 text-muted-foreground" />
    {selectedLabel}
    <CaretUpDown class="ml-auto size-6 text-muted-foreground" />
  </Listbox.Trigger>
  <Listbox.Portal>
    <Listbox.Content
      class="max-h-96 w-[var(--bits-listbox-trigger-width)] min-w-[var(--bits-listbox-trigger-width)] overflow-y-auto rounded-xl border border-muted bg-background px-1 py-3 shadow-popover outline-none"
      sideOffset={10}
    >
      {#each themes as theme, i (i + theme.value)}
        <Listbox.Item
          class="flex h-10 w-full select-none items-center rounded-button py-3 pl-5 pr-1.5 text-sm capitalize outline-none duration-75 data-[highlighted]:bg-muted"
          value={theme.value}
          label={theme.label}
        >
          {#snippet children({ selected })}
            {theme.label}
            {#if selected}
              <div class="ml-auto">
                <Check />
              </div>
            {/if}
          {/snippet}
        </Listbox.Item>
      {/each}
    </Listbox.Content>
  </Listbox.Portal>
</Listbox.Root>

Structure

	<script lang="ts">
	import { Listbox } from "bits-ui";
</script>
 
<Listbox.Root>
	<Listbox.Label />
	<Listbox.Content>
		<Listbox.Group>
			<Listbox.GroupLabel />
			<Listbox.Item />
		</Listbox.Group>
	</Listbox.Content>
</Listbox.Root>