zzzUI

Select

触发器与 Input 同为凹槽外观。列表从触发器下方展开,为直角方框,外围双层描边,呈浮起效果;高亮的一行以强调色填充。

安装

terminal
# once per project: where @zzzui items come frompnpm dlx shadcn@latest registry add @zzzui=https://zzzui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zzzui/select

示例

基础

select-basic.tsx
import {  Select,  SelectContent,  SelectItem,  SelectTrigger,  SelectValue,} from "@/components/zero/select";const districts = {  harbor: "Harbor",  market: "Old market",  rail: "Rail yards",  canal: "Canal side",};export default function SelectBasic() {  return (    <Select items={districts}>      <SelectTrigger className="max-w-64" aria-label="District">        <SelectValue placeholder="Pick a district" />      </SelectTrigger>      <SelectContent>        {Object.entries(districts).map(([value, label]) => (          <SelectItem key={value} value={value}>            {label}          </SelectItem>        ))}      </SelectContent>    </Select>  );}

分组、分隔线与禁用项

select-groups.tsx
import {  Select,  SelectContent,  SelectGroup,  SelectItem,  SelectLabel,  SelectSeparator,  SelectTrigger,  SelectValue,} from "@/components/zero/select";const districts = {  harbor: "Harbor",  canal: "Canal side",  market: "Old market",  rail: "Rail yards",  tower: "Tower row",};export default function SelectGroups() {  return (    <Select items={districts} defaultValue="market">      <SelectTrigger className="max-w-64" aria-label="District">        <SelectValue />      </SelectTrigger>      <SelectContent>        <SelectGroup>          <SelectLabel>Waterfront</SelectLabel>          <SelectItem value="harbor">Harbor</SelectItem>          <SelectItem value="canal">Canal side</SelectItem>        </SelectGroup>        <SelectSeparator />        <SelectGroup>          <SelectLabel>Inland</SelectLabel>          <SelectItem value="market">Old market</SelectItem>          <SelectItem value="rail">Rail yards</SelectItem>          <SelectItem value="tower" disabled>            Tower row          </SelectItem>        </SelectGroup>      </SelectContent>    </Select>  );}

置于 Field 中

No crew is free at night this week.
select-field.tsx
import { Field, FieldError, FieldLabel } from "@/components/zero/field";import {  Select,  SelectContent,  SelectItem,  SelectTrigger,  SelectValue,} from "@/components/zero/select";const shifts = { dawn: "Dawn", day: "Day", night: "Night" };export default function SelectField() {  return (    <Field invalid className="w-full max-w-64">      <FieldLabel>Shift</FieldLabel>      <Select items={shifts} defaultValue="night">        <SelectTrigger>          <SelectValue />        </SelectTrigger>        <SelectContent>          {Object.entries(shifts).map(([value, label]) => (            <SelectItem key={value} value={value}>              {label}            </SelectItem>          ))}        </SelectContent>      </Select>      <FieldError match>No crew is free at night this week.</FieldError>    </Field>  );}

行为

弹出层在 240 ms 内从触发器展开,在 140 ms 内收起。弹出层总是出现在触发器下方(空间不足时在上方),不会让已选项与触发器重叠对齐。因此列表较长时,在弹出层内部滚动。

向 Select 传入 items(值到标签的映射),这样即使列表从未打开,触发器也能显示已选项的标签。

属性

Select

属性类型默认值说明
itemsRecord<string, ReactNode>—按值索引的标签,供触发器显示。

另可传入 Base UI Select.Root 的全部属性。

SelectTrigger

属性类型默认值说明
size"sm" | "md" | "lg""md"高 32、40 或 52 px。
cut"end" | "start" | "both" | "none""end"凹槽的斜切位置:末端、起始端、两端或不斜切。

另可传入 Base UI Select.Trigger 的全部属性。

SelectValue

属性类型默认值说明
placeholderReactNode—尚未选择时显示,灰色斜体。

另可传入 Base UI Select.Value 的全部属性。

SelectContent

属性类型默认值说明
side"bottom" | "top" | "left" | "right""bottom"弹出层相对触发器的展开方向。
align"start" | "center" | "end""start"与触发器的对齐方式。

另可传入 Base UI Select.Popup 的全部属性。

SelectItem

另可传入 Base UI Select.Item 的全部属性。

SelectGroup, SelectLabel, SelectSeparator

另可传入 Base UI Select.Group 的全部属性。