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 selectnpx sprawlify@latest add selectyarn sprawlify@latest add selectbunx --bun sprawlify@latest add select
Install the following dependencies:
pnpm add @sprawlify/primitives @sprawlify/sveltenpm install @sprawlify/primitives @sprawlify/svelteyarn add @sprawlify/primitives @sprawlify/sveltebun add @sprawlify/primitives @sprawlify/svelte
Add the following files to your project:
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";161<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>
311<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>
181<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>
201<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>
261<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>
191<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>
181<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>
231<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>
131<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>
241<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/>
191<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>
151<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>
281<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/>
161<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>
13Update 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,
Get PRO
Need premium blocks and templates? Upgrade to PRO and get access.