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
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
value | string[] | - | 当前选中值(受控) |
defaultValue | string[] | - | 默认选中值(非受控) |
onChange | (value: string[]) => void | - | 选中值变化时的回调 |
isDisabled | boolean | false | 是否禁用 |
isRequired | boolean | false | 是否必填 |
isReadOnly | boolean | false | 是否只读 |
isInvalid | boolean | false | 是否处于无效状态 |
name | string | - | 提交 HTML 表单时复选框组的名称 |
children | React.ReactNode | (values: CheckboxGroupRenderProps) => React.ReactNode | - | 内容或 render prop |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxGroupRenderProps> | - | 使用自定义 render 函数覆盖默认 DOM 元素 |
Render Props
使用 render prop 模式时,提供以下值:
| Prop | 类型 | 描述 |
|---|---|---|
value | string[] | 当前选中值 |
isDisabled | boolean | 是否禁用 |
isReadOnly | boolean | 是否只读 |
isInvalid | boolean | 是否处于无效状态 |
isRequired | boolean | 是否必填 |