Examples
Basic selection
A compact trigger opens a positioned list of predefined values.
Basic Select with a placeholder-capable value
"use client";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
export function Example() {
return (
<Select defaultValue="activity">
<SelectTrigger aria-label="Sort projects"><SelectValue placeholder="Sort projects" /></SelectTrigger>
<SelectContent>
<SelectItem value="activity">Recent activity</SelectItem>
<SelectItem value="name">Name</SelectItem>
<SelectItem value="owner">Owner</SelectItem>
</SelectContent>
</Select>
);
}
Density
Use sm, md, or lg so the trigger matches the surrounding form rhythm.
Select trigger small, default, and large sizes
"use client";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
function SortSelect({ size, label }: { size: "sm" | "md" | "lg"; label: string }) {
return (
<Select defaultValue="activity">
<SelectTrigger size={size} aria-label={label}><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="activity">Recent activity</SelectItem>
<SelectItem value="name">Name</SelectItem>
<SelectItem value="owner">Owner</SelectItem>
</SelectContent>
</Select>
);
}
export function Example() {
return (
<div className="grid max-w-xs gap-3">
<SortSelect size="sm" label="Sort projects, small" />
<SortSelect size="md" label="Sort projects, default" />
<SortSelect size="lg" label="Sort projects, large" />
</div>
);
}
Controlled value
Use controlled state when a selected value drives surrounding feature behavior.
Controlled Select preview
"use client";
import { useState } from "react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
export function Example() {
const [value, setValue] = useState("activity");
return (
<Select value={value} onValueChange={setValue}>
<SelectTrigger aria-label="Project status"><SelectValue placeholder="Choose a status" /></SelectTrigger>
<SelectContent>
<SelectItem value="activity">Recent activity</SelectItem>
<SelectItem value="name">Name</SelectItem>
<SelectItem value="owner">Owner</SelectItem>
</SelectContent>
</Select>
);
}Grouped options
Group related choices and keep a disabled option understandable.
Select groups, labels, separator, and disabled item
"use client";
import { Select, SelectContent, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
export function Example() {
return (
<Select defaultValue="designer">
<SelectTrigger aria-label="Role"><SelectValue placeholder="Choose a role" /></SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectGroupLabel>Product</SelectGroupLabel>
<SelectItem value="designer">Designer</SelectItem>
<SelectItem value="researcher">Researcher</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectGroupLabel>Operations</SelectGroupLabel>
<SelectItem value="admin">Administrator</SelectItem>
<SelectItem value="billing" disabled>Billing (contact owner)</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
);
}
Multiple selection
Use Base UI multiple mode when the form needs more than one value.
Select with multiple values
"use client";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
export function Example() {
return (
<Select multiple defaultValue={["email", "push"]}>
<SelectTrigger aria-label="Notification channels"><SelectValue placeholder="Choose channels" /></SelectTrigger>
<SelectContent>
<SelectItem value="email">Email</SelectItem>
<SelectItem value="push">Push</SelectItem>
<SelectItem value="sms">SMS</SelectItem>
</SelectContent>
</Select>
);
}
Placeholder, disabled, and long list
The trigger and popup remain usable at narrow widths and with many options.
Select placeholder, disabled trigger, and scrollable list
"use client";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
const months = Array.from({ length: 14 }, (_, index) => `2026-${String(index + 1).padStart(2, "0")}`);
export function Example() {
return (
<div className="grid gap-3">
<Select>
<SelectTrigger aria-label="Choose a month"><SelectValue placeholder="Choose a month" /></SelectTrigger>
<SelectContent>{months.map((month) => <SelectItem key={month} value={month}>{month}</SelectItem>)}</SelectContent>
</Select>
<Select disabled defaultValue="locked">
<SelectTrigger aria-label="Locked value"><SelectValue /></SelectTrigger>
<SelectContent><SelectItem value="locked">Locked by policy</SelectItem></SelectContent>
</Select>
</div>
);
}
When to use
Use Select when the options are predefined and the list is too long or secondary to keep visible. Use RadioGroup for a small peer set, and use a Combobox pattern when searching the list is required.
Usage
"use client";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@phuctech/ui/components/select";
export function Example() {
return (
<Select defaultValue="activity">
<SelectTrigger aria-label="Sort projects"><SelectValue placeholder="Sort projects" /></SelectTrigger>
<SelectContent>
<SelectItem value="activity">Recent activity</SelectItem>
<SelectItem value="name">Name</SelectItem>
<SelectItem value="owner">Owner</SelectItem>
</SelectContent>
</Select>
);
}
The wrapper exposes Base UI's positioned popup and supports the same render-based composition model as the rest of the library. Pair the trigger with a Field label when it is part of a form.
States
API
Tokens
Accessibility
- Open the list with Enter, Space, or Arrow keys and move with the arrow keys.
- Escape closes the popup and returns focus to the trigger.
- Use a visible label or an explicit
aria-label; placeholder text alone is not a label.
Related
- Field connects Select to labels and errors.
- RadioGroup keeps a short set of peer options visible.
- DropdownMenu is for actions rather than form values.