跳到内容

复选框

用于同意复选框、多选筛选器和批量行选择的二进制切换开关——采用新粗野主义风格的边框与阴影处理效果。

"use client"

import { Checkbox } from "@/components/ui/checkbox"

复选框是处理二元选择的标准控件——选中、未选中,或者用不确定态表示部分选中。它基于 Base UI Checkbox 基元构建,并按新粗野主义的配方设计:粗边框、硬阴影、加粗字体。

适合以下场景:

  • 条款与同意——注册和结算流程里那个「我已阅读并同意」的勾选框,随表单一起提交。
  • 多选筛选——侧边栏里的分类、标签或价格区间,任意组合都成立。
  • 表格批量选择——每行一个复选框,表头再放一个带不确定态的全选框。

安装

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
npx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/checkbox.json

安装以下依赖:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

将以下代码复制并粘贴到您的项目中。

components/ui/checkbox.tsx
"use client"

import * as React from "react"
import { CheckIcon } from "lucide-react"
import { Checkbox as CheckboxPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Checkbox({
  className,
  ...props
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
  return (
    <CheckboxPrimitive.Root
      data-slot="checkbox"
      className={cn(
        "peer relative flex size-5 shrink-0 items-center justify-center rounded border-2 bg-input shadow-sm transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-checked:border-border data-checked:bg-primary data-checked:text-primary-foreground",
        className
      )}
      {...props}
    >
      <CheckboxPrimitive.Indicator
        data-slot="checkbox-indicator"
        className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
      >
        <CheckIcon />
      </CheckboxPrimitive.Indicator>
    </CheckboxPrimitive.Root>
  )
}

export { Checkbox }

更新导入路径以匹配您的项目结构。

用法

import { Checkbox } from "@/components/ui/checkbox"
<Checkbox />

选中状态

非受控复选框使用 defaultChecked,需要控制状态时则使用 checkedonCheckedChange

import * as React from "react"
 
export function Example() {
  const [checked, setChecked] = React.useState(false)
 
  return <Checkbox checked={checked} onCheckedChange={setChecked} />
}

无效状态

在复选框上设置 aria-invalid,并在字段包装器上设置 data-invalid, 以显示无效状态的样式。

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

示例

基础

将复选框与 FieldFieldLabel 搭配使用,以获得恰当的布局和标注。

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

说明

辅助文本使用 FieldContentFieldDescription

import { Checkbox } from "@/components/ui/checkbox"
import {
  Field,

禁用

使用 disabled 属性来阻止交互,并在 <Field> 组件上添加 data-disabled 属性以应用禁用样式。

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

分组

使用多个字段来创建复选框列表。

import { Checkbox } from "@/components/ui/checkbox"
import {
  Field,

表格

"use client"

import * as React from "react"

RTL

若要在 Neobrutalism 中启用 RTL 支持,请参阅 RTL 配置指南

"use client"

import * as React from "react"

无障碍

复选框遵循 WAI-ARIA Checkbox 模式:基元渲染一个带 aria-checkedrole="checkbox" 元素(不确定态对应 "mixed"),并同步一个隐藏的原生 input,让取值能随表单一起提交。

键盘交互:

按键操作
Tab / Shift + Tab把焦点移到复选框上或移开
Space切换选中状态(不确定态 → 选中)

Enter 不会切换复选框——这是 ARIA 模式的规定,不是缺陷。

API 参考

更多信息请参阅 Base UI 文档。