Skip to content
GitHub

Select

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

import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select";
const items = [
{ label: "Select a fruit", value: null },
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Blueberry", value: "blueberry" },
{ label: "Grapes", value: "grapes" },
]
export default function SelectDemo() {
return (
<Select items={items}>
<SelectTrigger className="w-full max-w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
{items.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
);
}
pnpm dlx shadcn@latest add pxl-ui/registry/select
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select"
const items = [
{ label: "Light", value: "light" },
{ label: "Dark", value: "dark" },
{ label: "System", value: "system" },
]
<Select items={items}>
<SelectTrigger className="w-45">
<SelectValue placeholder="Theme" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{items.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>

Use the following composition to build a Select:

Select
├── SelectTrigger
│ └── SelectValue
└── SelectContent
├── SelectGroup
│ ├── SelectLabel
│ ├── SelectItem
│ └── SelectItem
├── SelectSeparator
└── SelectGroup
├── SelectLabel
├── SelectItem
└── SelectItem

Use alignItemWithTrigger on SelectContent to control whether the selected item aligns with the trigger. When true (default), the popup positions so the selected item appears over the trigger. When false, the popup aligns to the trigger edge.

Toggle to align the item with the trigger.

"use client";
import * as React from "react";
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/components/ui/pxl/field";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select";
import { Switch } from "@/components/ui/pxl/switch";
const items = [
{ label: "Select a fruit", value: null },
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Blueberry", value: "blueberry" },
{ label: "Grapes", value: "grapes" },
{ label: "Pineapple", value: "pineapple" },
];
export default function SelectAlignItemExample() {
const [alignItemWithTrigger, setAlignItemWithTrigger] = React.useState(true);
return (
<FieldGroup className="w-full max-w-xs">
<Field orientation="horizontal">
<FieldContent>
<FieldLabel htmlFor="align-item">Align Item</FieldLabel>
<FieldDescription>
Toggle to align the item with the trigger.
</FieldDescription>
</FieldContent>
<Switch
id="align-item"
checked={alignItemWithTrigger}
onCheckedChange={setAlignItemWithTrigger}
/>
</Field>
<Field>
<Select items={items} defaultValue="banana">
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent alignItemWithTrigger={alignItemWithTrigger}>
<SelectGroup>
{items.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
</FieldGroup>
);
}

Use SelectGroup, SelectLabel, and SelectSeparator to organize items.

import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select"
export default function SelectGroupsExample() {
const fruits = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Blueberry", value: "blueberry" },
]
const vegetables = [
{ label: "Carrot", value: "carrot" },
{ label: "Broccoli", value: "broccoli" },
{ label: "Spinach", value: "spinach" },
]
const allItems = [
{ label: "Select a fruit", value: null },
...fruits,
...vegetables,
]
return (
<Select items={allItems}>
<SelectTrigger className="w-full max-w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
{fruits.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
{vegetables.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
)
}

A select with many items that scrolls.

import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select"
const northAmerica = [
{ label: "Eastern Standard Time", value: "est" },
{ label: "Central Standard Time", value: "cst" },
{ label: "Mountain Standard Time", value: "mst" },
{ label: "Pacific Standard Time", value: "pst" },
{ label: "Alaska Standard Time", value: "akst" },
{ label: "Hawaii Standard Time", value: "hst" },
]
const europeAfrica = [
{ label: "Greenwich Mean Time", value: "gmt" },
{ label: "Central European Time", value: "cet" },
{ label: "Eastern European Time", value: "eet" },
{ label: "Western European Summer Time", value: "west" },
{ label: "Central Africa Time", value: "cat" },
{ label: "East Africa Time", value: "eat" },
]
const asia = [
{ label: "Moscow Time", value: "msk" },
{ label: "India Standard Time", value: "ist" },
{ label: "China Standard Time", value: "cst_china" },
{ label: "Japan Standard Time", value: "jst" },
{ label: "Korea Standard Time", value: "kst" },
{ label: "Indonesia Central Standard Time", value: "ist_indonesia" },
]
const australiaPacific = [
{ label: "Australian Western Standard Time", value: "awst" },
{ label: "Australian Central Standard Time", value: "acst" },
{ label: "Australian Eastern Standard Time", value: "aest" },
{ label: "New Zealand Standard Time", value: "nzst" },
{ label: "Fiji Time", value: "fjt" },
]
const southAmerica = [
{ label: "Argentina Time", value: "art" },
{ label: "Bolivia Time", value: "bot" },
{ label: "Brasilia Time", value: "brt" },
{ label: "Chile Standard Time", value: "clt" },
]
const items = [
{ label: "Select a timezone", value: null },
...northAmerica,
...europeAfrica,
...asia,
...australiaPacific,
...southAmerica,
]
export default function SelectScrollableExample() {
return (
<Select items={items}>
<SelectTrigger className="w-full max-w-64">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>North America</SelectLabel>
{northAmerica.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
<SelectGroup>
<SelectLabel>Europe & Africa</SelectLabel>
{europeAfrica.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
<SelectGroup>
<SelectLabel>Asia</SelectLabel>
{asia.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
<SelectGroup>
<SelectLabel>Australia & Pacific</SelectLabel>
{australiaPacific.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
<SelectGroup>
<SelectLabel>South America</SelectLabel>
{southAmerica.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
)
}

A select with icons.

import { CountryFlag } from "@/components/ui/pxl/country-flag";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/pxl/select";
const items = [
{ label: "Español", iso31661: "ES", value: "es" },
{ label: "Português", iso31661: "PT", value: "pt" },
{ label: "Français", iso31661: "FR", value: "fr" },
{ label: "Italiano", iso31661: "IT", value: "it" },
{ label: "Deutsch", iso31661: "DE", value: "de" },
{ label: "English", iso31661: "GB", value: "gb" },
{ label: "Русский", iso31661: "RU", value: "ru" },
{ label: "हिन्दी", iso31661: "IN", value: "hi" },
{ label: "বাংলা", iso31661: "BD", value: "bn" },
{ label: "العربية", iso31661: "SA", value: "ar" },
{ label: "日本語", iso31661: "JP", value: "jp" },
{ label: "한국어", iso31661: "KR", value: "kr" },
];
export default function SelectIconsExample() {
return (
<Select items={items} defaultValue="es">
<SelectTrigger className="w-full max-w-48">
<SelectValue className="text-start uppercase gap-2!">
{(value) => {
const match = items.find((item) => item.value === value);
return match ? (
<>
<CountryFlag className="w-8! h-5!" code={match.iso31661} />
{match.label}
</>
) : value;
}}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Language</SelectLabel>
{items.map((item) => (
<SelectItem className="uppercase" key={item.value} value={item.value}>
<CountryFlag className="w-8! h-5!" code={item.iso31661} />
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
);
}

Add the data-invalid attribute to the Field component and the aria-invalid attribute to the SelectTrigger component to show an error state.

<Field data-invalid>
<FieldLabel>Fruit</FieldLabel>
<SelectTrigger aria-invalid>
<SelectValue />
</SelectTrigger>
</Field>

See the Base UI Select documentation.