Skip to content
Lenso UI

CheckboxGroup 复选框组

用于管理多个复选框选择的复选框组组件

用法

import { CheckboxGroup, Checkbox, Label, Description } from '@lenso/ui';

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

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useId } from "react";import * as stylex from "@stylexjs/stylex";
const interests = [  { value: "coding", label: "Coding", description: "Love building software" },  { value: "design", label: "Design", description: "Enjoy creating beautiful interfaces" },  { value: "writing", label: "Writing", description: "Passionate about content creation" },];export function Basic() {  const id = useId();  return (    <TextField name="interests">      <CheckboxGroup aria-labelledby={`${id}-label`} aria-describedby={`${id}-help`}>        <span id={`${id}-label`} {...stylex.props(labelStyles.label)}>          Select your interests        </span>        <span id={`${id}-help`} {...stylex.props(descriptionStyles.description)}>          Choose all that apply        </span>        {interests.map((interest) => (          <Checkbox            key={interest.value}            value={interest.value}            aria-label={interest.label}            aria-describedby={`${id}-${interest.value}`}          >            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              {interest.label}            </Checkbox.Content>            <span              id={`${id}-${interest.value}`}              {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}            >              {interest.description}            </span>          </Checkbox>        ))}      </CheckboxGroup>    </TextField>  );}

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

组件结构

import {CheckboxGroup, Checkbox, Label, Description, FieldError} from '@lenso/ui';
export default () => (  <CheckboxGroup name="interests">    <Label />    <Description /> {/* 可选 */}    <Checkbox value="option1">      <Checkbox.Content>        <Checkbox.Control>          <Checkbox.Indicator />        </Checkbox.Control>        Label {/* 纯文本 — 可点击标签 */}      </Checkbox.Content>      <Description /> {/* 可选 — 单个 Checkbox 的帮助文本 */}    </Checkbox>    <FieldError /> {/* 可选 */}  </CheckboxGroup>);

示例

表面样式

在 Surface 组件内使用时,请使用 variant="secondary" 以应用适合 Surface 背景的低强调变体。

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

"use client";/** Adapted from HeroUI v3.2.6. SPDX-License-Identifier: Apache-2.0 */import { Checkbox, CheckboxGroup, Surface, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useId } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  surface: { width: "100%", borderRadius: "1.5rem", padding: "1.5rem" },});export function OnSurface() {  const labelId = useId();  return (    <Surface xstyle={styles.surface}>      <TextField name="interests">        <CheckboxGroup          variant="secondary"          aria-labelledby={labelId}          aria-describedby={`${labelId}-help`}        >          <span id={labelId} {...stylex.props(labelStyles.label)}>            Select your interests          </span>          <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>            Choose all that apply          </span>          <Checkbox value="coding" aria-label="Coding" aria-describedby={`${labelId}-coding`}>            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Coding            </Checkbox.Content>            <span              id={`${labelId}-coding`}              {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}            >              Love building software            </span>          </Checkbox>          <Checkbox value="design" aria-label="Design" aria-describedby={`${labelId}-design`}>            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Design            </Checkbox.Content>            <span              id={`${labelId}-design`}              {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}            >              Enjoy creating beautiful interfaces            </span>          </Checkbox>          <Checkbox value="writing" aria-label="Writing" aria-describedby={`${labelId}-writing`}>            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Writing            </Checkbox.Content>            <span              id={`${labelId}-writing`}              {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}            >              Passionate about content creation            </span>          </Checkbox>        </CheckboxGroup>      </TextField>    </Surface>  );}

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, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useId } from "react";import * as stylex from "@stylexjs/stylex";export function Disabled() {  const labelId = useId();  return (    <TextField name="disabled-features">      <CheckboxGroup disabled aria-labelledby={labelId} aria-describedby={`${labelId}-help`}>        <span id={labelId} {...stylex.props(labelStyles.label)}>          Features        </span>        <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>          Feature selection is temporarily disabled        </span>        <Checkbox value="feature1" aria-label="Feature 1" aria-describedby={`${labelId}-feature1`}>          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Feature 1          </Checkbox.Content>          <span            id={`${labelId}-feature1`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            This feature is coming soon          </span>        </Checkbox>        <Checkbox value="feature2" aria-label="Feature 2" aria-describedby={`${labelId}-feature2`}>          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Feature 2          </Checkbox.Content>          <span            id={`${labelId}-feature2`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            This feature is coming soon          </span>        </Checkbox>      </CheckboxGroup>    </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, CheckboxGroup } from "@lenso/ui";import { useState } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  children: { marginInlineStart: "1.5rem", display: "flex", flexDirection: "column", gap: ".5rem" },});export function Indeterminate() {  const [selected, setSelected] = useState(["coding"]);  const allOptions = ["coding", "design", "writing"];  return (    <div>      <Checkbox        indeterminate={selected.length > 0 && selected.length < allOptions.length}        checked={selected.length === allOptions.length}        name="select-all"        onCheckedChange={(checked) => setSelected(checked ? allOptions : [])}      >        <Checkbox.Content>          <Checkbox.Control>            <Checkbox.Indicator />          </Checkbox.Control>          Select all        </Checkbox.Content>      </Checkbox>      <div {...stylex.props(styles.children)}>        <CheckboxGroup value={selected} onValueChange={setSelected}>          <Checkbox value="coding">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Coding            </Checkbox.Content>          </Checkbox>          <Checkbox value="design">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Design            </Checkbox.Content>          </Checkbox>          <Checkbox value="writing">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Writing            </Checkbox.Content>          </Checkbox>        </CheckboxGroup>      </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, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { useId, useState } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  root: { minWidth: "320px" },  summary: { marginBlock: "1rem", fontSize: ".875rem", color: "var(--muted)" },});export function Controlled() {  const labelId = useId();  const [selected, setSelected] = useState(["coding", "design"]);  return (    <TextField name="skills">      <CheckboxGroup        aria-labelledby={labelId}        xstyle={styles.root}        value={selected}        onValueChange={setSelected}      >        <span id={labelId} {...stylex.props(labelStyles.label)}>          Your skills        </span>        <Checkbox value="coding">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Coding          </Checkbox.Content>        </Checkbox>        <Checkbox value="design">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Design          </Checkbox.Content>        </Checkbox>        <Checkbox value="writing">          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Writing          </Checkbox.Content>        </Checkbox>        <p {...stylex.props(styles.summary)}>Selected: {selected.join(", ") || "None"}</p>      </CheckboxGroup>    </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, CheckboxGroup, FieldError, Form, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { useId } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  form: { display: "flex", flexDirection: "column", gap: "1rem", paddingInline: "1rem" },});export function Validation() {  const labelId = useId();  return (    <Form      xstyle={styles.form}      onSubmit={(e) => {        e.preventDefault();        const values = new FormData(e.currentTarget).getAll("preferences");        alert(`Selected preferences: ${values.join(", ")}`);      }}    >      <TextField        name="preferences"        validate={(value) =>          Array.isArray(value) && value.length > 0            ? null            : "Please select at least one notification method."        }      >        <CheckboxGroup aria-labelledby={labelId}>          <span id={labelId} {...stylex.props(labelStyles.label)}>            Preferences          </span>          <Checkbox value="email">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Email notifications            </Checkbox.Content>          </Checkbox>          <Checkbox value="sms">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              SMS notifications            </Checkbox.Content>          </Checkbox>          <Checkbox value="push">            <Checkbox.Content>              <Checkbox.Control>                <Checkbox.Indicator />              </Checkbox.Control>              Push notifications            </Checkbox.Content>          </Checkbox>        </CheckboxGroup>        <FieldError>Please select at least one notification method.</FieldError>      </TextField>      <Button type="submit">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 { Bell, Comment, Envelope } from "@gravity-ui/icons";import { Checkbox, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { useId } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  wrapper: {    display: "flex",    width: "100%",    flexDirection: "column",    alignItems: "center",    gap: "2.5rem",    paddingInline: "1rem",    paddingBlock: "2rem",  },  section: {    display: "flex",    width: "100%",    minWidth: "320px",    flexDirection: "column",    gap: "1rem",  },  items: { display: "flex", flexDirection: "column", gap: ".5rem" },  content: {    position: "relative",    display: "flex",    width: "100%",    flexDirection: "row",    alignItems: "flex-start",    justifyContent: "flex-start",    gap: "1rem",    borderRadius: "1.5rem",    backgroundColor: {      default: "var(--surface)",      ":is([data-checked] *)": "color-mix(in oklab, var(--accent) 10%, transparent)",    },    paddingInline: "1.25rem",    paddingBlock: "1rem",    transition: {      default: "background-color 150ms ease",      "@media (prefers-reduced-motion: reduce)": "none",    },  },  control: {    position: "absolute",    insetInlineEnd: "1rem",    top: ".75rem",    width: "1.25rem",    height: "1.25rem",    borderRadius: "9999px",    "::before": { borderRadius: "9999px" },  },  icon: { width: "1.25rem", height: "1.25rem", color: "var(--accent-soft-foreground)" },  copy: { display: "flex", flexDirection: "column", gap: ".25rem" },});export function FeaturesAndAddOns() {  const labelId = useId();  const addOns = [    {      description: "Receive updates via email",      icon: Envelope,      title: "Email Notifications",      value: "email",    },    {      description: "Get instant SMS notifications",      icon: Comment,      title: "SMS Alerts",      value: "sms",    },    {      description: "Browser and mobile push alerts",      icon: Bell,      title: "Push Notifications",      value: "push",    },  ];  return (    <div {...stylex.props(styles.wrapper)}>      <section {...stylex.props(styles.section)}>        <TextField name="notification-preferences">          <CheckboxGroup aria-labelledby={labelId} aria-describedby={`${labelId}-help`}>            <span id={labelId} {...stylex.props(labelStyles.label)}>              Notification preferences            </span>            <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>              Choose how you want to receive updates            </span>            <div {...stylex.props(styles.items)}>              {addOns.map((addon) => (                <Checkbox                  key={addon.value}                  value={addon.value}                  variant="secondary"                  aria-label={addon.title}                  aria-describedby={`${labelId}-${addon.value}`}                >                  <Checkbox.Content xstyle={styles.content}>                    <Checkbox.Control xstyle={styles.control}>                      <Checkbox.Indicator />                    </Checkbox.Control>                    <addon.icon {...stylex.props(styles.icon)} aria-hidden="true" />                    <div {...stylex.props(styles.copy)}>                      <span>{addon.title}</span>                      <span                        id={`${labelId}-${addon.value}`}                        {...stylex.props(descriptionStyles.description)}                      >                        {addon.description}                      </span>                    </div>                  </Checkbox.Content>                </Checkbox>              ))}            </div>          </CheckboxGroup>        </TextField>      </section>    </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, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useId } from "react";import * as stylex from "@stylexjs/stylex";export function WithCustomIndicator() {  const labelId = useId();  return (    <TextField name="features">      <CheckboxGroup aria-labelledby={labelId} aria-describedby={`${labelId}-help`}>        <span id={labelId} {...stylex.props(labelStyles.label)}>          Features        </span>        <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>          Select the features you want        </span>        <Checkbox          value="notifications"          aria-label="Email notifications"          aria-describedby={`${labelId}-notifications`}        >          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator                render={(props, { checked }) => (                  <span {...props}>                    {checked ? (                      <svg                        aria-hidden="true"                        fill="none"                        stroke="currentColor"                        strokeLinecap="round"                        strokeWidth={2}                        viewBox="0 0 24 24"                      >                        <path d="M6 18L18 6M6 6l12 12" />                      </svg>                    ) : null}                  </span>                )}              />            </Checkbox.Control>            Email notifications          </Checkbox.Content>          <span            id={`${labelId}-notifications`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            Receive updates via email          </span>        </Checkbox>        <Checkbox          value="newsletter"          aria-label="Newsletter"          aria-describedby={`${labelId}-newsletter`}        >          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator                render={(props, { checked }) => (                  <span {...props}>                    {checked ? (                      <svg                        aria-hidden="true"                        fill="none"                        stroke="currentColor"                        strokeLinecap="round"                        strokeWidth={2}                        viewBox="0 0 24 24"                      >                        <path d="M6 18L18 6M6 6l12 12" />                      </svg>                    ) : null}                  </span>                )}              />            </Checkbox.Control>            Newsletter          </Checkbox.Content>          <span            id={`${labelId}-newsletter`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            Get weekly newsletters          </span>        </Checkbox>      </CheckboxGroup>    </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, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { checkboxSupportingStyles } from "@lenso/tokens/checkbox";import { useId } from "react";import * as stylex from "@stylexjs/stylex";export function RenderFunction() {  const labelId = useId();  return (    <TextField name="interests">      <CheckboxGroup        aria-labelledby={labelId}        aria-describedby={`${labelId}-help`}        render={(props) => <div {...props} data-custom="foo" />}      >        <span id={labelId} {...stylex.props(labelStyles.label)}>          Select your interests        </span>        <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>          Choose all that apply        </span>        <Checkbox value="coding" aria-label="Coding" aria-describedby={`${labelId}-coding`}>          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Coding          </Checkbox.Content>          <span            id={`${labelId}-coding`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            Love building software          </span>        </Checkbox>        <Checkbox value="design" aria-label="Design" aria-describedby={`${labelId}-design`}>          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Design          </Checkbox.Content>          <span            id={`${labelId}-design`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            Enjoy creating beautiful interfaces          </span>        </Checkbox>        <Checkbox value="writing" aria-label="Writing" aria-describedby={`${labelId}-writing`}>          <Checkbox.Content>            <Checkbox.Control>              <Checkbox.Indicator />            </Checkbox.Control>            Writing          </Checkbox.Content>          <span            id={`${labelId}-writing`}            {...stylex.props(descriptionStyles.description, checkboxSupportingStyles.direct)}          >            Passionate about content creation          </span>        </Checkbox>      </CheckboxGroup>    </TextField>  );}

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, CheckboxGroup, TextField } from "@lenso/ui";import { labelStyles } from "@lenso/tokens/label";import { descriptionStyles } from "@lenso/tokens/description";import { useId } from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({  root: { gap: ".75rem" },  item: { marginTop: 0 },  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)" },});const channels = [  { label: "Email", value: "email" },  { label: "SMS", value: "sms" },  { label: "Push", value: "push" },] as const;export function CustomStyles() {  const labelId = useId();  return (    <TextField name="notification-channels">      <CheckboxGroup        aria-labelledby={labelId}        aria-describedby={`${labelId}-help`}        xstyle={styles.root}        defaultValue={["email"]}      >        <span id={labelId} {...stylex.props(labelStyles.label)}>          Notification channels        </span>        <span id={`${labelId}-help`} {...stylex.props(descriptionStyles.description)}>          Choose how we should reach you for account updates.        </span>        {channels.map(({ label, value }) => (          <Checkbox key={value} value={value} xstyle={styles.item}>            <Checkbox.Content>              <Checkbox.Control xstyle={styles.control}>                <Checkbox.Indicator xstyle={styles.indicator} />              </Checkbox.Control>              {label}            </Checkbox.Content>          </Checkbox>        ))}      </CheckboxGroup>    </TextField>  );}

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

全局 CSS

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

@layer components {  .checkbox-group {    @apply flex flex-col gap-2;  }}

样式参考

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

CSS 类

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

基础类 [!toc]

  • .checkbox-group - 复选框组根容器

API 参考

CheckboxGroup

继承自 React Aria CheckboxGroup。

Prop类型默认值描述
valuestring[]-当前选中值(受控)
defaultValuestring[]-默认选中值(非受控)
onChange(value: string[]) => void-选中值变化时的回调
isDisabledbooleanfalse是否禁用
isRequiredbooleanfalse是否必填
isReadOnlybooleanfalse是否只读
isInvalidbooleanfalse是否处于无效状态
namestring-提交 HTML 表单时复选框组的名称
childrenReact.ReactNode | (values: CheckboxGroupRenderProps) => React.ReactNode-内容或 render prop
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxGroupRenderProps>-使用自定义 render 函数覆盖默认 DOM 元素

Render Props

使用 render prop 模式时,提供以下值:

Prop类型描述
valuestring[]当前选中值
isDisabledboolean是否禁用
isReadOnlyboolean是否只读
isInvalidboolean是否处于无效状态
isRequiredboolean是否必填

相关组件