章节
组件
如需带样式的 select 组件,请参阅 Select 组件。
import {
NativeSelect,
NativeSelectOption,原生选择器是浏览器自带 <select> 元素 上的一层薄样式——没有基元、没有 portal、没有 JavaScript。收起态控件套上新粗野主义配方——粗边框、硬阴影、加粗字体——展开后的列表仍由操作系统选择器呈现。
适合以下场景:
- 国家/地区、时区与货币选择——选项很长时,系统渲染比任何自定义弹出层都快。
- 移动端为主的表单——iOS 与 Android 会换成原生滚轮选择器,小屏上优于自定义下拉。
- 普通表单提交——它是真正的
<select name="…">,取值随表单提交,水合前也能用。
安装#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/native-select.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/native-select.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/native-select.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/native-select.json
将以下代码复制并粘贴到您的项目中。
import * as React from "react"
import { ChevronDownIcon } from "lucide-react"
import { cn } from "@/lib/utils"
type NativeSelectProps = Omit<React.ComponentProps<"select">, "size"> & {
size?: "sm" | "default"
}
function NativeSelect({
className,
size = "default",
...props
}: NativeSelectProps) {
return (
<div
className={cn(
"group/native-select relative w-fit has-[select:disabled]:opacity-50",
className
)}
data-slot="native-select-wrapper"
data-size={size}
>
<select
data-slot="native-select"
data-size={size}
className="h-8 w-full min-w-0 appearance-none rounded border-2 bg-input py-2 pr-8 pl-3 text-sm shadow-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive data-[size=sm]:h-7 data-[size=sm]:rounded data-[size=sm]:py-0.5"
{...props}
/>
<ChevronDownIcon
className="pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none"
aria-hidden="true"
data-slot="native-select-icon"
/>
</div>
)
}
function NativeSelectOption({
className,
...props
}: React.ComponentProps<"option">) {
return (
<option
data-slot="native-select-option"
className={cn("bg-[Canvas] text-[CanvasText]", className)}
{...props}
/>
)
}
function NativeSelectOptGroup({
className,
...props
}: React.ComponentProps<"optgroup">) {
return (
<optgroup
data-slot="native-select-optgroup"
className={cn("bg-[Canvas] text-[CanvasText]", className)}
{...props}
/>
)
}
export { NativeSelect, NativeSelectOptGroup, NativeSelectOption }
更新导入路径以匹配您的项目结构。
用法#
import {
NativeSelect,
NativeSelectOptGroup,
NativeSelectOption,
} from "@/components/ui/native-select"<NativeSelect>
<NativeSelectOption value="">Select a fruit</NativeSelectOption>
<NativeSelectOption value="apple">Apple</NativeSelectOption>
<NativeSelectOption value="banana">Banana</NativeSelectOption>
<NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
<NativeSelectOption value="pineapple">Pineapple</NativeSelectOption>
</NativeSelect>组合#
简单#
将选项直接放在 NativeSelect 之下(不使用 NativeSelectOptGroup)。
NativeSelect
├── NativeSelectOption
├── NativeSelectOption
├── NativeSelectOption
└── NativeSelectOption带分组#
使用 NativeSelectOptGroup 将选项按类别组织。
NativeSelect
├── NativeSelectOptGroup
│ ├── NativeSelectOption
│ └── NativeSelectOption
└── NativeSelectOptGroup
├── NativeSelectOption
└── NativeSelectOption示例#
分组#
使用 NativeSelectOptGroup 将选项按类别组织。
import {
NativeSelect,
NativeSelectOptGroup,禁用#
在 NativeSelect 组件上添加 disabled 属性以禁用该选择框。
import {
NativeSelect,
NativeSelectOption,无效#
使用 aria-invalid 显示校验错误,并在 Field 组件上添加 data-invalid 属性以设置样式。
import {
NativeSelect,
NativeSelectOption,Native Select vs Select#
- 若需要原生浏览器行为、更佳的性能或针对移动端优化的下拉框,请使用
NativeSelect。 - 若需要自定义样式、动画或复杂的交互,请使用
Select。
RTL#
若要在 Neobrutalism 中启用 RTL 支持,请参阅 RTL 配置指南。
"use client"
import * as React from "react"无障碍#
这就是平台自己的 <select>,浏览器已向辅助技术暴露——WAI-ARIA 仅选择 Combobox 模式 正是为了模拟它。无需 ARIA 接线;只需通过 <Label htmlFor> 或 aria-label 给它可访问名称。
键盘行为由浏览器提供,跨操作系统与浏览器会略有差异。常见按键如下:
| 按键 | 操作 |
|---|---|
Space / Alt + ArrowDown | 打开选项列表 |
ArrowDown / ArrowUp | 高亮下一项 / 上一项 |
Home / End | 跳到第一项 / 最后一项 |
Enter | 确认高亮项并关闭列表 |
Escape | 关闭列表且不改变取值 |
| 可打印字符 | 键入即定位——跳到下一个匹配所输内容的选项 |
API 参考#
NativeSelect#
包裹原生 HTML select 元素的主选择组件。
<NativeSelect>
<NativeSelectOption value="option1">Option 1</NativeSelectOption>
<NativeSelectOption value="option2">Option 2</NativeSelectOption>
</NativeSelect>NativeSelectOption#
表示选择框中的单个选项。
| Prop | Type | Default |
|---|---|---|
value | string | |
disabled | boolean | false |
NativeSelectOptGroup#
将相关选项组合在一起,使结构更清晰。
| Prop | Type | Default |
|---|---|---|
label | string | |
disabled | boolean | false |
<NativeSelectOptGroup label="Fruits">
<NativeSelectOption value="apple">Apple</NativeSelectOption>
<NativeSelectOption value="banana">Banana</NativeSelectOption>
</NativeSelectOptGroup>