Presets

Blocks

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.

Upgrade
JoinLogin
Presets
Monochrome
Overview
  • Introduction
  • Components
  • Installation
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • CalendarNEW
  • Card
  • CarouselNEW
  • Checkbox
  • Collapsible
  • Dialog
  • Dropdown Menu
  • Empty
  • Field
  • Input
  • Input Group
  • Item
  • Kbd
  • Label
  • Native Select
  • Scroll Area
  • SelectNEW
  • Separator
  • SwitchNEW
  • Table
  • Tabs
  • Textarea
  • TooltipNEW

Select

PreviousNext

Displays a list of options for the user to pick from—triggered by a button.

1<script lang="ts">
2import {
3  Select,
4  SelectContent,

Installation

pnpm dlx sprawlify@latest add select
npx sprawlify@latest add select
yarn sprawlify@latest add select
bunx --bun sprawlify@latest add select

Install the following dependencies:

pnpm add @sprawlify/primitives @sprawlify/svelte
npm install @sprawlify/primitives @sprawlify/svelte
yarn add @sprawlify/primitives @sprawlify/svelte
bun add @sprawlify/primitives @sprawlify/svelte

Add the following files to your project:

select/index.ts
1export { SelectRoot as Select } from "@sprawlify/svelte/select";2export { default as SelectControl } from "./select-control.svelte";3export { default as SelectTrigger } from "./select-trigger.svelte";4export { default as SelectIndicatorGroup } from "./select-indicator-group.svelte";5export { default as SelectIndicator } from "./select-indicator.svelte";6export { default as SelectValue } from "./select-value.svelte";7export { default as SelectContent } from "./select-content.svelte";8export { default as SelectItem } from "./select-item.svelte";9export { default as SelectItemText } from "./select-item-text.svelte";10export { default as SelectItemIndicator } from "./select-item-indicator.svelte";11export { default as SelectItemGroup } from "./select-item-group.svelte";12export { default as SelectItemGroupLabel } from "./select-item-group-label.svelte";13export { default as SelectLabel } from "./select-label.svelte";14export { default as SelectSeparator } from "./select-separator.svelte";15export { SelectHiddenSelect, SelectContext, SelectRootProvider } from "@sprawlify/svelte/select";16
select/select-content.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { Portal } from "@sprawlify/svelte/portal"
4import { cn } from "@/lib/utils"
5import type { ComponentProps } from "svelte"
6
7interface Props extends ComponentProps<typeof SelectPrimitive.Content> {}
8
9let { class: className, children, ...rest }: Props = $props()
10</script>
11
12<Portal>
13  <SelectPrimitive.Positioner data-slot="select-positioner" class="outline-none">
14    <SelectPrimitive.Content
15      data-slot="select-content"
16      class={cn(
17        "z-50 flex flex-col gap-0.5 rounded-lg border bg-popover p-1 text-popover-foreground shadow-lg outline-none",
18        "min-w-(--reference-width)",
19        "max-h-[min(var(--available-height,300px),300px)] overflow-y-auto",
20        "origin-(--transform-origin)",
21        "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-[98%]",
22        "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[98%]",
23        className,
24      )}
25      {...rest}
26    >
27      {@render children?.()}
28    </SelectPrimitive.Content>
29  </SelectPrimitive.Positioner>
30</Portal>
31
select/select-control.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.Control> {}
7
8let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.Control
12  data-slot="select-control"
13  class={cn("relative flex w-full items-center", className)}
14  {...rest}
15>
16  {@render children?.()}
17</SelectPrimitive.Control>
18
select/select-indicator-group.svelte
1<script lang="ts">
2import { cn } from "@/lib/utils"
3import type { HTMLAttributes } from "svelte/elements"
4
5interface Props extends HTMLAttributes<HTMLDivElement> {}
6
7let { class: className, children, ...rest }: Props = $props()
8</script>
9
10<div
11  data-slot="select-indicator-group"
12  class={cn(
13    "pointer-events-none absolute inset-y-0 right-0 flex items-center gap-1 px-2.5",
14    className,
15  )}
16  {...rest}
17>
18  {@render children?.()}
19</div>
20
select/select-indicator.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { ChevronsUpDown } from "lucide-svelte"
4import { cn } from "@/lib/utils"
5import type { ComponentProps } from "svelte"
6
7interface Props extends ComponentProps<typeof SelectPrimitive.Indicator> {}
8
9let { class: className, children, ...rest }: Props = $props()
10</script>
11
12<SelectPrimitive.Indicator
13  data-slot="select-indicator"
14  class={cn(
15    "pointer-events-none absolute inset-y-0 right-0 flex items-center px-2.5 text-muted-foreground/60 [&_svg]:size-4",
16    className,
17  )}
18  {...rest}
19>
20  {#if children}
21    {@render children()}
22  {:else}
23    <ChevronsUpDown />
24  {/if}
25</SelectPrimitive.Indicator>
26
select/select-item-group-label.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.ItemGroupLabel> {}
7
8let { class: className, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.ItemGroupLabel
12  data-slot="select-item-group-label"
13  class={cn(
14    "px-2 py-1.5 text-xs font-semibold tracking-wide text-muted-foreground",
15    className,
16  )}
17  {...rest}
18></SelectPrimitive.ItemGroupLabel>
19
select/select-item-group.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.ItemGroup> {}
7
8let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.ItemGroup
12  data-slot="select-item-group"
13  class={cn("flex flex-col", className)}
14  {...rest}
15>
16  {@render children?.()}
17</SelectPrimitive.ItemGroup>
18
select/select-item-indicator.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { Check } from "lucide-svelte"
4import { cn } from "@/lib/utils"
5import type { ComponentProps } from "svelte"
6
7interface Props extends ComponentProps<typeof SelectPrimitive.ItemIndicator> {}
8
9let { class: className, children, ...rest }: Props = $props()
10</script>
11
12<SelectPrimitive.ItemIndicator
13  data-slot="select-item-indicator"
14  class={cn("absolute right-2 flex size-4 items-center justify-center", className)}
15  {...rest}
16>
17  {#if children}
18    {@render children()}
19  {:else}
20    <Check />
21  {/if}
22</SelectPrimitive.ItemIndicator>
23
select/select-item-text.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import type { ComponentProps } from "svelte"
4
5interface Props extends ComponentProps<typeof SelectPrimitive.ItemText> {}
6
7let { children, ...rest }: Props = $props()
8</script>
9
10<SelectPrimitive.ItemText data-slot="select-item-text" {...rest}>
11  {@render children?.()}
12</SelectPrimitive.ItemText>
13
select/select-item.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.Item> {}
7
8let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.Item
12  data-slot="select-item"
13  class={cn(
14    "relative flex w-full cursor-default items-center gap-2 rounded-md px-2 py-1.5 pr-8 text-sm outline-none select-none",
15    "data-highlighted:bg-accent data-highlighted:text-accent-foreground",
16    "data-[state=checked]:font-medium",
17    "data-disabled:pointer-events-none data-disabled:opacity-50",
18    className,
19  )}
20  {...rest}
21>
22  {@render children?.()}
23</SelectPrimitive.Item>
24
select/select-label.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.Label> {}
7
8let { class: className, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.Label
12  data-slot="select-label"
13  class={cn(
14    "text-sm leading-none font-medium select-none data-disabled:opacity-50",
15    className,
16  )}
17  {...rest}
18/>
19
select/select-separator.svelte
1<script lang="ts">
2import { cn } from "@/lib/utils"
3import type { HTMLAttributes } from "svelte/elements"
4
5interface Props extends HTMLAttributes<HTMLDivElement> {}
6
7let { class: className, ...rest }: Props = $props()
8</script>
9
10<div
11  data-slot="select-separator"
12  class={cn("-mx-1 my-1 h-px bg-border", className)}
13  {...rest}
14></div>
15
select/select-trigger.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.Trigger> {}
7
8let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.Trigger
12  data-slot="select-trigger"
13  class={cn(
14    "flex h-9 w-full items-center gap-2 rounded-md border border-input bg-input/30 py-2 pr-10 pl-3 text-sm shadow-xs transition-[border-color,box-shadow] duration-150 ease-in-out outline-none",
15    "data-placeholder-shown:text-muted-foreground",
16    "hover:border-ring/50",
17    "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/20",
18    "data-disabled:cursor-not-allowed data-disabled:opacity-50",
19    "data-invalid:border-destructive data-invalid:focus-visible:ring-destructive/20",
20    className,
21  )}
22  {...rest}
23>
24  <div class="flex gap-2">
25    {@render children?.()}
26  </div>
27</SelectPrimitive.Trigger>
28
select/select-value.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import { cn } from "@/lib/utils"
4import type { ComponentProps } from "svelte"
5
6interface Props extends ComponentProps<typeof SelectPrimitive.ValueText> {}
7
8let { class: className, ...rest }: Props = $props()
9</script>
10
11<SelectPrimitive.ValueText
12  data-slot="select-value"
13  class={cn("line-clamp-1 flex-1 text-left", className)}
14  {...rest}
15/>
16
select/select.svelte
1<script lang="ts">
2import { Select as SelectPrimitive } from "@sprawlify/svelte/select"
3import type { ComponentProps } from "svelte"
4
5interface Props extends ComponentProps<typeof SelectPrimitive.Root> {}
6
7let { children, ...rest }: Props = $props()
8</script>
9
10<SelectPrimitive.Root data-slot="select" {...rest}>
11  {@render children?.()}
12</SelectPrimitive.Root>
13

Update the import paths to match your project setup.

Usage

1import {
2  Select,
3  SelectClearTrigger,
4  SelectContent,
5  SelectControl,
6  SelectHiddenSelect,
7  SelectIndicator,
8  SelectIndicatorGroup,
9  SelectItem,
10  SelectItemGroup,
11  SelectItemGroupLabel,
12  SelectItemIndicator,
13  SelectItemText,
14  SelectTrigger,
15  SelectValue,
16} from "@/components/ui/select"
1const collection = createListCollection<CollectionItem>({
2  items: [
3    { label: "Item 1", value: "item-1" },
4    { label: "Item 2", value: "item-2" },
5    { label: "Item 3", value: "item-3" },
6    { label: "Item 4", value: "item-4" },
7    { label: "Item 5", value: "item-5" },
8  ],
9})
10
11<Select collection={collection}>
12  <SelectHiddenSelect />
13  <SelectControl>
14    <SelectTrigger>
15      <SelectValue placeholder="Select an item" />
16    </SelectTrigger>
17    <SelectIndicatorGroup>
18      <SelectIndicator />
19    </SelectIndicatorGroup>
20  </SelectControl>
21  <SelectContent>
22    <SelectItemGroup>
23      <SelectItemGroupLabel>Fruits</SelectItemGroupLabel>
24      {collection.items.map((item) => (
25        <SelectItem key={item.value} item={item}>
26          <SelectItemText>{item.label}</SelectItemText>
27            <SelectItemIndicator />
28          </SelectItem>
29      ))}
30    </SelectItemGroup>
31  </SelectContent>
32</Select>

Examples

Disabled

Add the disabled prop to the Select component to disable the select.

1<script lang="ts">
2import {
3  Select,
4  SelectContent,

Groups

Use the groupBy option in createListCollection to organize items into groups.

1<script lang="ts">
2import {
3  Select,
4  SelectContent,

Invalid

Use aria-invalid to show validation errors and the data-invalid attribute to the Field component for styling.

1<script lang="ts">
2import { Field, FieldError, FieldLabel } from "@/components/ui/field"
3import {
4  Select,

Scrollable

1<script lang="ts">
2import {
3  Select,
4  SelectContent,

On This Page

InstallationUsageExamplesDisabledGroupsInvalidScrollable

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.