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.

1import {2  Select,3  SelectContent,4  SelectControl,

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/react
npm install @sprawlify/primitives @sprawlify/react
yarn add @sprawlify/primitives @sprawlify/react
bun add @sprawlify/primitives @sprawlify/react

Add the following files to your project:

select.tsx
1"use client";23import * as React from "react";4import { cn } from "@/lib/utils";5import { sprawlify } from "@sprawlify/react";6import { Portal } from "@sprawlify/react/portal";7import { Select as SelectPrimitive } from "@sprawlify/react/select";8import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";910const Select = SelectPrimitive.Root;1112const SelectControl = React.forwardRef<13  HTMLDivElement,14  React.ComponentProps<typeof SelectPrimitive.Control>15>(({ className, children, ...props }, ref) => (16  <SelectPrimitive.Control17    ref={ref}18    data-slot="select-control"19    className={cn("relative flex w-full items-center", className)}20    {...props}21  >22    {children}23  </SelectPrimitive.Control>24));25SelectControl.displayName = "SelectControl";2627const SelectTrigger = React.forwardRef<28  HTMLButtonElement,29  React.ComponentProps<typeof SelectPrimitive.Trigger>30>(({ className, children, ...props }, ref) => (31  <SelectPrimitive.Trigger32    ref={ref}33    data-slot="select-trigger"34    className={cn(35      "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",36      "data-placeholder-shown:text-muted-foreground",37      "hover:border-ring/50",38      "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/20",39      "data-disabled:cursor-not-allowed data-disabled:opacity-50",40      "data-invalid:border-destructive data-invalid:focus-visible:ring-destructive/20",41      className,42    )}43    {...props}44  >45    {children}46  </SelectPrimitive.Trigger>47));48SelectTrigger.displayName = "SelectTrigger";4950const SelectIndicatorGroup = React.forwardRef<51  HTMLDivElement,52  React.ComponentProps<typeof sprawlify.div>53>(({ className, children, ...props }, ref) => (54  <sprawlify.div55    ref={ref}56    data-slot="select-indicator-group"57    className={cn(58      "pointer-events-none absolute inset-y-0 right-0 flex items-center gap-1 px-2.5",59      className,60    )}61    {...props}62  >63    {children}64  </sprawlify.div>65));66SelectIndicatorGroup.displayName = "SelectIndicatorGroup";6768const SelectIndicator = React.forwardRef<69  HTMLDivElement,70  React.ComponentProps<typeof SelectPrimitive.Indicator>71>(({ className, children, ...props }, ref) => (72  <SelectPrimitive.Indicator73    ref={ref}74    data-slot="select-indicator"75    className={cn(76      "pointer-events-none absolute inset-y-0 right-0 flex items-center px-2.5 text-muted-foreground/60 [&_svg]:size-4",77      className,78    )}79    {...props}80  >81    {children ?? <ChevronsUpDownIcon />}82  </SelectPrimitive.Indicator>83));84SelectIndicator.displayName = "SelectIndicator";8586const SelectValue = React.forwardRef<87  HTMLSpanElement,88  React.ComponentProps<typeof SelectPrimitive.ValueText>89>(({ className, ...props }, ref) => (90  <SelectPrimitive.ValueText91    ref={ref}92    data-slot="select-value"93    className={cn("line-clamp-1 flex-1 text-left", className)}94    {...props}95  />96));97SelectValue.displayName = "SelectValue";9899const SelectPositioner = React.forwardRef<100  HTMLDivElement,101  React.ComponentProps<typeof SelectPrimitive.Positioner>102>(({ className, ...props }, ref) => (103  <SelectPrimitive.Positioner104    ref={ref}105    data-slot="select-positioner"106    className={cn("outline-none", className)}107    {...props}108  />109));110SelectPositioner.displayName = "SelectPositioner";111112const SelectContent = React.forwardRef<113  HTMLDivElement,114  React.ComponentProps<typeof SelectPrimitive.Content>115>(({ className, children, ...props }, ref) => (116  <Portal>117    <SelectPrimitive.Positioner data-slot="select-positioner" className="outline-none">118      <SelectPrimitive.Content119        ref={ref}120        data-slot="select-content"121        className={cn(122          "z-50 flex flex-col gap-0.5 rounded-lg border bg-popover p-1 text-popover-foreground shadow-lg outline-none",123          "min-w-(--reference-width)",124          "max-h-[min(var(--available-height,300px),300px)] overflow-y-auto",125          "origin-(--transform-origin)",126          "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-[98%]",127          "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[98%]",128          className,129        )}130        {...props}131      >132        {children}133      </SelectPrimitive.Content>134    </SelectPrimitive.Positioner>135  </Portal>136));137SelectContent.displayName = "SelectContent";138139const SelectHiddenSelect = SelectPrimitive.HiddenSelect;140141const SelectItem = React.forwardRef<142  HTMLDivElement,143  React.ComponentProps<typeof SelectPrimitive.Item>144>(({ className, children, ...props }, ref) => (145  <SelectPrimitive.Item146    ref={ref}147    data-slot="select-item"148    className={cn(149      "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",150      "data-highlighted:bg-accent data-highlighted:text-accent-foreground",151      "data-[state=checked]:font-medium",152      "data-disabled:pointer-events-none data-disabled:opacity-50",153      className,154    )}155    {...props}156  >157    {children}158  </SelectPrimitive.Item>159));160SelectItem.displayName = "SelectItem";161162const SelectItemText = SelectPrimitive.ItemText;163164const SelectItemIndicator = React.forwardRef<165  HTMLDivElement,166  React.ComponentProps<typeof SelectPrimitive.ItemIndicator>167>(({ className, children, ...props }, ref) => (168  <SelectPrimitive.ItemIndicator169    ref={ref}170    data-slot="select-item-indicator"171    className={cn("absolute right-2 flex size-4 items-center justify-center", className)}172    {...props}173  >174    {children ?? <CheckIcon />}175  </SelectPrimitive.ItemIndicator>176));177SelectItemIndicator.displayName = "SelectItemIndicator";178179const SelectItemGroup = React.forwardRef<180  HTMLDivElement,181  React.ComponentProps<typeof SelectPrimitive.ItemGroup>182>(({ className, ...props }, ref) => (183  <SelectPrimitive.ItemGroup184    ref={ref}185    data-slot="select-item-group"186    className={cn("flex flex-col", className)}187    {...props}188  />189));190SelectItemGroup.displayName = "SelectItemGroup";191192const SelectItemGroupLabel = React.forwardRef<193  HTMLDivElement,194  React.ComponentProps<typeof SelectPrimitive.ItemGroupLabel>195>(({ className, ...props }, ref) => (196  <SelectPrimitive.ItemGroupLabel197    ref={ref}198    data-slot="select-item-group-label"199    className={cn(200      "px-2 py-1.5 text-xs font-semibold tracking-wide text-muted-foreground",201      className,202    )}203    {...props}204  />205));206SelectItemGroupLabel.displayName = "SelectItemGroupLabel";207208const SelectLabel = React.forwardRef<209  HTMLLabelElement,210  React.ComponentProps<typeof SelectPrimitive.Label>211>(({ className, ...props }, ref) => (212  <SelectPrimitive.Label213    ref={ref}214    data-slot="select-label"215    className={cn(216      "text-sm leading-none font-medium select-none data-disabled:opacity-50",217      className,218    )}219    {...props}220  />221));222SelectLabel.displayName = "SelectLabel";223224const SelectSeparator = React.forwardRef<225  HTMLDivElement,226  React.ComponentProps<typeof sprawlify.div>227>(({ className, ...props }, ref) => (228  <sprawlify.div229    ref={ref}230    data-slot="select-separator"231    className={cn("-mx-1 my-1 h-px bg-border", className)}232    {...props}233  />234));235SelectSeparator.displayName = "SelectSeparator";236237const SelectContext = SelectPrimitive.Context;238const SelectRootProvider = SelectPrimitive.RootProvider;239240export {241  Select,242  SelectControl,243  SelectTrigger,244  SelectIndicator,245  SelectValue,246  SelectPositioner,247  SelectContent,248  SelectHiddenSelect,249  SelectItem,250  SelectItemText,251  SelectItemIndicator,252  SelectItemGroup,253  SelectItemGroupLabel,254  SelectLabel,255  SelectSeparator,256  SelectIndicatorGroup,257  SelectContext,258  SelectRootProvider,259};260

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({
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.

1import {2  Select,3  SelectContent,4  SelectControl,

Groups

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

1import {2  Select,3  SelectContent,4  SelectControl,

Invalid

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

1import { Field, FieldError, FieldLabel } from "@/components/ui/field";2import {3  Select,4  SelectContent,

Scrollable

1import {2  Select,3  SelectContent,4  SelectControl,

On This Page

InstallationUsageExamplesDisabledGroupsInvalidScrollable

Get PRO

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