Skip to content
Lenso UI

Checkbox 复选框

复选框允许用户从列表中选择多项,或标记单个项目为选中状态

用法

import { Checkbox } from '@lenso/ui';

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";
export function Basic() {  return (    <Checkbox name="basic-terms">      <Checkbox.Content>        <Checkbox.Control>          <Checkbox.Indicator />        </Checkbox.Control>        Accept terms and conditions      </Checkbox.Content>    </Checkbox>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

组件结构

import { Checkbox, Description, FieldError } from '@lenso/ui';
export default () => (  <Checkbox>    <Checkbox.Content>      <Checkbox.Control>        <Checkbox.Indicator />      </Checkbox.Control>      Label {/* 纯文本 — 可点击标签与无障碍名称 */}    </Checkbox.Content>    <Description /> {/* 可选 — 字段级帮助文本 */}    <FieldError /> {/* 可选 — 校验消息 */}  </Checkbox>);

示例

变体

Checkbox 组件支持两种视觉变体:

  • primary(默认)- 标准样式与默认背景,适用于大多数场景
  • secondary - 低强调变体,适用于 Surface 组件内

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, Description, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  root: { display: "flex", flexDirection: "column", gap: "1rem" },  section: { display: "flex", flexDirection: "column", gap: ".5rem" },  heading: { fontSize: ".875rem", fontWeight: 500, color: "var(--muted)" },});export function Variants() {  return (    <div {...stylex.props(styles.root)}>      <div {...stylex.props(styles.section)}>        <p {...stylex.props(styles.heading)}>Primary variant</p>        <TextField>          <Checkbox id="primary" name="primary" variant="primary">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Primary checkbox            </Checkbox.Content>            <Description xstyle={checkboxSupportingStyles.direct}>              Standard styling with default background            </Description>          </Checkbox>        </TextField>      </div>      <div {...stylex.props(styles.section)}>        <p {...stylex.props(styles.heading)}>Secondary variant</p>        <TextField>          <Checkbox id="secondary" name="secondary" variant="secondary">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Secondary checkbox            </Checkbox.Content>            <Description xstyle={checkboxSupportingStyles.direct}>              Lower emphasis variant for use in surfaces            </Description>          </Checkbox>        </TextField>      </div>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

全圆角

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  root: { display: "flex", flexDirection: "column", gap: "1.5rem" },  section: { display: "flex", flexDirection: "column", gap: ".75rem" },  label: { color: "var(--muted)" },  smallIndicator: { "--checkbox-checkmark-size": ".5rem" },  extraLargeIndicator: { "--checkbox-checkmark-size": "1rem" },  small: {    width: ".75rem",    height: ".75rem",    borderRadius: "9999px",    "::before": { borderRadius: "9999px" },  },  medium: {    width: "1rem",    height: "1rem",    borderRadius: "9999px",    "::before": { borderRadius: "9999px" },  },  large: {    width: "1.25rem",    height: "1.25rem",    borderRadius: "9999px",    "::before": { borderRadius: "9999px" },  },  extraLarge: {    width: "1.5rem",    height: "1.5rem",    borderRadius: "9999px",    "::before": { borderRadius: "9999px" },  },});export function FullRounded() {  return (    <div {...stylex.props(styles.root)}>      <div {...stylex.props(styles.section)}>        <span {...stylex.props(labelStyles.label, styles.label)}>Rounded checkboxes</span>        <Checkbox name="small-rounded">          <Checkbox.Content>            <Checkbox.Control xstyle={styles.small}>              <Checkbox.Indicator xstyle={styles.smallIndicator} />            </Checkbox.Control>            Small size          </Checkbox.Content>        </Checkbox>      </div>      <div {...stylex.props(styles.section)}>        <Checkbox name="default-rounded">          <Checkbox.Content>            <Checkbox.Control xstyle={styles.medium}>              <Checkbox.Indicator />            </Checkbox.Control>            Default size          </Checkbox.Content>        </Checkbox>      </div>      <div {...stylex.props(styles.section)}>        <Checkbox name="large-rounded">          <Checkbox.Content>            <Checkbox.Control xstyle={styles.large}>              <Checkbox.Indicator />            </Checkbox.Control>            Large size          </Checkbox.Content>        </Checkbox>      </div>      <div {...stylex.props(styles.section)}>        <Checkbox name="xl-rounded">          <Checkbox.Content>            <Checkbox.Control xstyle={styles.extraLarge}>              <Checkbox.Indicator xstyle={styles.extraLargeIndicator} />            </Checkbox.Control>            Extra large size          </Checkbox.Content>        </Checkbox>      </div>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

禁用

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, Description, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";export function Disabled() {  return (    <TextField>      <Checkbox disabled id="feature" aria-describedby="feature-help">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          Premium Feature        </Checkbox.Content>        <Description id="feature-help" xstyle={checkboxSupportingStyles.direct}>          This feature is coming soon        </Description>      </Checkbox>    </TextField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

外部标签

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", alignItems: "center", gap: ".75rem" } });export function ExternalLabel() {  return (    <div {...stylex.props(styles.root)}>      <Checkbox id="label-marketing">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>        </Checkbox.Content>      </Checkbox>      <label {...stylex.props(labelStyles.label)} htmlFor="label-marketing">        Send me marketing emails      </label>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

带描述

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, Description, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";export function WithDescription() {  return (    <TextField>      <Checkbox name="description-notifications" aria-describedby="description-notifications-help">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          Email notifications        </Checkbox.Content>        <Description id="description-notifications-help" xstyle={checkboxSupportingStyles.direct}>          Get notified when someone mentions you in a comment        </Description>      </Checkbox>    </TextField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

默认选中

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";export function DefaultSelected() {  return (    <Checkbox defaultChecked id="default-notifications">      <Checkbox.Content>        <Checkbox.Control>          <Checkbox.Indicator />        </Checkbox.Control>        Enable email notifications      </Checkbox.Content>    </Checkbox>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

无效状态

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, FieldError, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";export function Invalid() {  return (    <TextField invalid>      <Checkbox required name="agreement">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          I agree to the terms        </Checkbox.Content>        <FieldError          match          xstyle={[checkboxSupportingStyles.direct, checkboxSupportingStyles.error]}        >          You must accept the terms to continue        </FieldError>      </Checkbox>    </TextField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

受控组件

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";import { useState } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  root: { display: "flex", flexDirection: "column", gap: ".75rem" },  status: { fontSize: ".875rem", color: "var(--muted)" },  strong: { fontWeight: 500 },});export function Controlled() {  const [isSelected, setIsSelected] = useState(true);  return (    <div {...stylex.props(styles.root)}>      <Checkbox id="email-notifications" checked={isSelected} onCheckedChange={setIsSelected}>        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          Email notifications        </Checkbox.Content>      </Checkbox>      <p {...stylex.props(styles.status)}>        Status: <span {...stylex.props(styles.strong)}>{isSelected ? "Enabled" : "Disabled"}</span>      </p>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

半选状态

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, Description, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useState } from "react";export function Indeterminate() {  const [isIndeterminate, setIsIndeterminate] = useState(true);  const [isSelected, setIsSelected] = useState(false);  return (    <TextField>      <Checkbox        id="select-all"        indeterminate={isIndeterminate}        checked={isSelected}        onCheckedChange={(selected) => {          setIsSelected(selected);          setIsIndeterminate(false);        }}      >        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          Select all        </Checkbox.Content>        <Description xstyle={checkboxSupportingStyles.direct}>          Shows indeterminate state (dash icon)        </Description>      </Checkbox>    </TextField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

表单集成

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Button, Checkbox } from "@lenso/ui";import type { FormEvent } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  form: { display: "flex", flexDirection: "column", gap: "1rem" },  items: { display: "flex", flexDirection: "column", gap: ".75rem" },  submit: { marginTop: "1rem" },});export function Form() {  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {    e.preventDefault();    const formData = new FormData(e.currentTarget);    alert(      `Form submitted with:\n${Array.from(formData.entries())        .map(([key, value]) => `${key}: ${value}`)        .join("\n")}`,    );  };  return (    <form {...stylex.props(styles.form)} onSubmit={handleSubmit}>      <div {...stylex.props(styles.items)}>        <Checkbox name="notifications" value="on">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Enable notifications          </Checkbox.Content>        </Checkbox>        <Checkbox defaultChecked name="newsletter" value="on">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Subscribe to newsletter          </Checkbox.Content>        </Checkbox>        <Checkbox name="marketing" value="on">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Receive marketing updates          </Checkbox.Content>        </Checkbox>      </div>      <Button xstyle={styles.submit} size="sm" type="submit" variant="primary">        Submit      </Button>    </form>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

渲染属性

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, Description, TextField } from "@lenso/ui";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";export function RenderProps() {  return (    <TextField>      <Checkbox        id="render-props-terms"        render={(props, { checked }) => (          <span {...props}>            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              {checked ? "Terms accepted" : "Accept terms"}            </Checkbox.Content>            <Description xstyle={checkboxSupportingStyles.direct}>              {checked ? "Thank you for accepting" : "Please read and accept the terms"}            </Description>          </span>        )}      />    </TextField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

渲染函数

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";export function RenderFunction() {  return (    <Checkbox render={(props) => <div {...props} data-custom="bar" />}>      <Checkbox.Content>        <Checkbox.Control>          <Checkbox.Indicator />        </Checkbox.Control>        Accept terms and conditions      </Checkbox.Content>    </Checkbox>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

自定义指示器

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", gap: "1rem" } });export function CustomIndicator() {  return (    <div {...stylex.props(styles.root)}>      <Checkbox defaultChecked name="heart">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator              render={(props, { checked }) => (                <span {...props}>                  {checked ? (                    <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24">                      <path d="M12.62 20.81c-.34.12-.9.12-1.24 0C8.48 19.82 2 15.69 2 8.69 2 5.6 4.49 3.1 7.56 3.1c1.82 0 3.43.88 4.44 2.24a5.53 5.53 0 0 1 4.44-2.24C19.51 3.1 22 5.6 22 8.69c0 7-6.48 11.13-9.38 12.12Z" />                    </svg>                  ) : null}                </span>              )}            />          </Checkbox.Control>          Heart        </Checkbox.Content>      </Checkbox>      <Checkbox defaultChecked name="plus">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator              render={(props, { checked }) => (                <span {...props}>                  {checked ? (                    <svg aria-hidden="true" fill="none" viewBox="0 0 24 24">                      <path                        d="M6 12H18"                        stroke="currentColor"                        strokeLinecap="round"                        strokeLinejoin="round"                        strokeWidth="3"                      />                      <path                        d="M12 18V6"                        stroke="currentColor"                        strokeLinecap="round"                        strokeLinejoin="round"                        strokeWidth="3"                      />                    </svg>                  ) : null}                </span>              )}            />          </Checkbox.Control>          Plus        </Checkbox.Content>      </Checkbox>      <Checkbox indeterminate name="indeterminate">        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator              render={(props, { indeterminate }) => (                <span {...props}>                  {indeterminate ? (                    <svg                      aria-hidden="true"                      stroke="currentColor"                      strokeWidth={3}                      viewBox="0 0 24 24"                    >                      <line x1="21" x2="3" y1="12" y2="12" />                    </svg>                  ) : null}                </span>              )}            />          </Checkbox.Control>          Indeterminate        </Checkbox.Content>      </Checkbox>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

自定义样式

Tailwind CSS

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  control: {    backgroundColor: "var(--success-soft)",    "::before": {      backgroundColor: {        default: "var(--success)",        ":is([data-slot='checkbox']:hover *)": "var(--success)",        ":is([data-slot='checkbox'][data-invalid] *)": "var(--success)",      },    },  },  indicator: { color: "var(--success-foreground)" },});export function CustomStyles() {  return (    <Checkbox id="custom">      <Checkbox.Content>        <Checkbox.Control xstyle={styles.control}>          <Checkbox.Indicator xstyle={styles.indicator} />        </Checkbox.Control>        Custom styled checkbox      </Checkbox.Content>    </Checkbox>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

全局 CSS

可使用 @layer components 指令自定义 Checkbox 组件类。 了解更多。

@layer components {  .checkbox {    @apply inline-flex gap-3 items-center;  }
  .checkbox__control {    @apply size-5 border-2 border-gray-400 rounded data-[selected=true]:bg-blue-500 data-[selected=true]:border-blue-500;
    /* Animated background indicator */    &::before {      @apply bg-accent pointer-events-none absolute inset-0 z-0 origin-center scale-50 rounded-md opacity-0 content-[''];
      transition:        scale 200ms linear,        opacity 200ms linear,        background-color 200ms ease-out;    }
    /* Show indicator when selected */    &[data-selected="true"]::before {      @apply scale-100 opacity-100;    }  }
  .checkbox__indicator {    @apply text-white;  }
  .checkbox__content {    @apply items-center gap-3;  }}

样式参考

HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。

CSS 类

Checkbox 组件使用以下 CSS 类(查看源码样式):

基础类 [!toc]

  • .checkbox - 基础复选框容器(字段)
  • .checkbox__content - 包裹控件与标签文本的可点击 label
  • .checkbox__control - 复选框控件框
  • .checkbox__indicator - 复选框勾选指示器

交互状态

复选框同时支持 CSS 伪类与 data 属性:

  • Selected:[data-selected="true"] 或 [aria-checked="true"](显示勾选与背景色变化)
  • Indeterminate:[data-indeterminate="true"](显示不确定状态的短横线)
  • Invalid:[data-invalid="true"] 或 [aria-invalid="true"](显示 danger 色错误状态)
  • Hover:Checkbox.Control(按钮)上的 :hover 或 [data-hovered="true"]
  • Focus:按钮上的 :focus-visible 或 [data-focus-visible="true"](控件上显示焦点环)
  • Disabled:字段上的 [data-disabled="true"](降低透明度,包括帮助文本)
  • Pressed::active 或 [data-pressed="true"]

API 参考

Checkbox

继承自 React Aria CheckboxField。

Prop类型默认值描述
isSelectedbooleanfalse是否选中
defaultSelectedbooleanfalse默认是否选中(非受控)
isIndeterminatebooleanfalse是否处于不确定状态
isDisabledbooleanfalse是否禁用
isInvalidbooleanfalse是否无效
isReadOnlybooleanfalse是否只读
isRequiredbooleanfalse是否必须选中
validate(value: boolean) => ValidationError | true | null | undefined-自定义验证函数
validationBehavior'native' | 'aria''native'使用原生 HTML 表单验证还是 ARIA
variant"primary" | "secondary""primary"视觉变体。primary 为默认带阴影样式;secondary 为低强调无阴影,适用于 Surface 内
namestring-提交 HTML 表单时 input 元素的名称
valuestring-提交 HTML 表单时 input 元素的值
onChange(isSelected: boolean) => void-值变化时的回调
childrenReact.ReactNode | (values: CheckboxFieldRenderProps) => React.ReactNode-内容或字段 render prop
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxFieldRenderProps>-使用自定义 render 函数覆盖默认 DOM 元素

Checkbox.Content

可点击的 <label>,包裹控件与标签文本。将 Checkbox.Control 与 Label 放在其中;Description/FieldError 作为 Checkbox.Content 的兄弟节点。无标签的复选框可省略 Label,并在 Checkbox 上传递 aria-label。

Prop类型默认值描述
childrenReact.ReactNode | (values: CheckboxButtonRenderProps) => React.ReactNode-按钮内容(控件 + 标签)或按钮 render prop
classNamestring | (values: CheckboxButtonRenderProps) => string-应用于可点击 label 的类

CheckboxFieldRenderProps

在根 Checkbox 上使用 render prop 时,提供以下字段级值:

Prop类型描述
isSelectedboolean是否当前选中
isIndeterminateboolean是否处于不确定状态
isDisabledboolean是否禁用
isReadOnlyboolean是否只读
isInvalidboolean是否无效
isRequiredboolean是否必填

CheckboxButtonRenderProps

Checkbox.Control 与 Checkbox.Indicator 使用按钮级 render props(isHovered、isPressed、isFocusVisible 等)。将函数作为 Checkbox.Control 子节点或传给 Checkbox.Indicator 以访问它们。

相关组件