Select
A dropdown menu for choosing one option from a list..
select-demo.tsx
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
const items = [
{
label: "Select a fruit",
value: null,
},
{
label: "Apple",
value: "apple",
},
{
label: "Banana",
value: "banana",
},
{
label: "Cherry",
value: "cherry",
},
]
export function SelectDemo() {
return (
<div className="w-80">
<Select items={items}>
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
{items.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)
}
Installation
npx shadcn@latest add @9ui/select
Usage
Imports
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
Anatomy
<Select>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectGroupLabel />
<SelectItem />
</SelectGroup>
</SelectContent>
</Select>
Examples
Custom value
select-with-custom-value.tsx
import { useState } from "react"
import Image from "next/image"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
const users = {
"karen-smith": {
name: "Karen Smith",
image: "/memoji-1.png",
},
"chris-williams": {
name: "Chris Williams",
image: "/memoji-3.png",
},
"melissa-johnson": {
name: "Melissa Johnson",
image: "/memoji-2.png",
},
"frank-lee": {
name: "Frank Lee",
image: "/memoji-4.png",
},
}
export function SelectWithCustomValue() {
const [selected, setSelected] = useState<keyof typeof users | null>(null)
return (
<div className="w-80">
<Select
value={selected}
onValueChange={(value) => setSelected(value as keyof typeof users)}
>
<SelectTrigger className="w-full">
<SelectValue>
{() =>
selected ? (
<div className="flex items-center gap-2">
<Image
src={users[selected].image}
alt={users[selected].name}
width={16}
height={16}
/>
{users[selected].name}
</div>
) : (
"Assign to"
)
}
</SelectValue>
</SelectTrigger>
<SelectContent>
{Object.entries(users).map(([id, user]) => (
<SelectItem key={id} value={id}>
<div className="flex items-center gap-2">
<Image
src={user.image}
alt={user.name}
width={16}
height={16}
/>
{user.name}
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)
}
With groups
select-with-groups.tsx
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
const items = [
{
label: "Select an option",
value: null,
},
{
label: "Apple",
value: "apple",
},
{
label: "Banana",
value: "banana",
},
{
label: "Cherry",
value: "cherry",
},
{
label: "Carrot",
value: "carrot",
},
{
label: "Potato",
value: "potato",
},
{
label: "Tomato",
value: "tomato",
},
]
export function SelectWithGroups() {
return (
<div className="w-80">
<Select items={items}>
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="cherry">Cherry</SelectItem>
</SelectGroup>
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
<SelectItem value="carrot">Carrot</SelectItem>
<SelectItem value="potato">Potato</SelectItem>
<SelectItem value="tomato">Tomato</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
)
}
Multiple
select-multiple.tsx
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
const languages = {
javascript: "JavaScript",
typescript: "TypeScript",
python: "Python",
java: "Java",
csharp: "C#",
php: "PHP",
cpp: "C++",
rust: "Rust",
go: "Go",
swift: "Swift",
}
type Language = keyof typeof languages
const values = Object.keys(languages) as Language[]
function renderValue(value: Language[]) {
if (value.length === 0) {
return "Select languages..."
}
const firstLanguage = languages[value[0]]
const additionalLanguages =
value.length > 1 ? ` (+${value.length - 1} more)` : ""
return firstLanguage + additionalLanguages
}
export function SelectMultiple() {
return (
<div className="w-80">
<Select multiple>
<SelectTrigger className="w-full">
<SelectValue>{renderValue}</SelectValue>
</SelectTrigger>
<SelectContent>
{values.map((value) => (
<SelectItem key={value} value={value}>
{languages[value]}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)
}