Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/reference/generated/label.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "Label",
"props": {
"nativeLabel": {
"type": "boolean",
"default": "true",
"description": "Whether the component renders a native `<label>` element when replacing it via the `render` prop.\nSet to `false` if the rendered element is not a label (e.g. `<div>`).\n\nThis is useful to avoid inheriting label behaviors on `<button>` controls (such as `<Select.Trigger>` and `<Combobox.Trigger>`), including avoiding `:hover` on the button when hovering the label, and preventing clicks on the label from firing on the button.",
"detailedType": "boolean | undefined"
},
"className": {
"type": "string | ((state: Label.State) => string | undefined)",
"description": "CSS class applied to the element, or a function that\nreturns a class based on the component’s state.",
"detailedType": "| string\n| ((state: Label.State) => string | undefined)"
},
"style": {
"type": "CSSProperties | ((state: Label.State) => CSSProperties | undefined)",
"detailedType": "| React.CSSProperties\n| ((state: Label.State) => CSSProperties | undefined)\n| undefined"
},
"render": {
"type": "ReactElement | ((props: HTMLProps, state: Label.State) => ReactElement)",
"description": "Allows you to replace the component’s HTML element\nwith a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render.",
"detailedType": "| ReactElement\n| ((props: HTMLProps, state: Label.State) => ReactElement)"
}
},
"dataAttributes": {},
"cssVariables": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DemoAutocompleteHero } from './demos/hero';

- **Avoid when selection state is needed**: Use [Combobox](/react/components/combobox) instead of Autocomplete if the selection should be remembered and the input value cannot be custom. Unlike Combobox, Autocomplete's input can contain free-form text, as its suggestions only _optionally_ autocomplete the text.
- **Can be used for filterable command pickers**: The input can be used as a filter for command items that perform an action when clicked when rendered inside the popup.
- **Form controls must have an accessible name**: It can be created using a `<label>` element or the `Field` component. See the [forms guide](/react/handbook/forms).
- **Form controls must have an accessible name**: It can be created using a `<label>` element, the [Label](/react/components/label) component, or the `Field` component. See the [forms guide](/react/handbook/forms).

## Anatomy

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { CheckboxGroup } from '@base-ui/react/checkbox-group';
import { Label } from '@base-ui/react/label';
import styles from './index.module.css';

export default function ExampleCheckboxGroup() {
Expand All @@ -16,32 +17,32 @@ export default function ExampleCheckboxGroup() {
Apples
</div>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root name="apple" value="fuji-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Fuji
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root name="apple" value="gala-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Gala
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root name="apple" value="granny-smith-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Granny Smith
</label>
</Label>
</CheckboxGroup>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { CheckboxGroup } from '@base-ui/react/checkbox-group';
import { Label } from '@base-ui/react/label';

export default function ExampleCheckboxGroup() {
const id = React.useId();
Expand All @@ -15,7 +16,7 @@ export default function ExampleCheckboxGroup() {
Apples
</div>

<label className="flex items-center gap-2">
<Label className="flex items-center gap-2">
<Checkbox.Root
name="apple"
value="fuji-apple"
Expand All @@ -26,9 +27,9 @@ export default function ExampleCheckboxGroup() {
</Checkbox.Indicator>
</Checkbox.Root>
Fuji
</label>
</Label>

<label className="flex items-center gap-2">
<Label className="flex items-center gap-2">
<Checkbox.Root
name="apple"
value="gala-apple"
Expand All @@ -39,9 +40,9 @@ export default function ExampleCheckboxGroup() {
</Checkbox.Indicator>
</Checkbox.Root>
Gala
</label>
</Label>

<label className="flex items-center gap-2">
<Label className="flex items-center gap-2">
<Checkbox.Root
name="apple"
value="granny-smith-apple"
Expand All @@ -52,7 +53,7 @@ export default function ExampleCheckboxGroup() {
</Checkbox.Indicator>
</Checkbox.Root>
Granny Smith
</label>
</Label>
</CheckboxGroup>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { CheckboxGroup } from '@base-ui/react/checkbox-group';
import { Label } from '@base-ui/react/label';
import styles from './index.module.css';

const mainPermissions = ['view-dashboard', 'manage-users', 'access-reports'];
Expand All @@ -28,7 +29,7 @@ export default function PermissionsForm() {
className={styles.CheckboxGroup}
style={{ marginLeft: '1rem' }}
>
<label className={styles.Item} id={id} style={{ marginLeft: '-1rem' }}>
<Label className={styles.Item} id={id} style={{ marginLeft: '-1rem' }}>
<Checkbox.Root
className={styles.Checkbox}
parent
Expand All @@ -51,25 +52,25 @@ export default function PermissionsForm() {
/>
</Checkbox.Root>
User Permissions
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="view-dashboard" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
View Dashboard
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="access-reports" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Access Reports
</label>
</Label>

<CheckboxGroup
aria-labelledby="manage-users-caption"
Expand All @@ -86,7 +87,7 @@ export default function PermissionsForm() {
allValues={userManagementPermissions}
style={{ marginLeft: '1rem' }}
>
<label className={styles.Item} id="manage-users-caption" style={{ marginLeft: '-1rem' }}>
<Label className={styles.Item} id="manage-users-caption" style={{ marginLeft: '-1rem' }}>
<Checkbox.Root className={styles.Checkbox} parent>
<Checkbox.Indicator
className={styles.Indicator}
Expand All @@ -102,43 +103,43 @@ export default function PermissionsForm() {
/>
</Checkbox.Root>
Manage Users
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="create-user" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Create User
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="edit-user" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Edit User
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="delete-user" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Delete User
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="assign-roles" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Assign Roles
</label>
</Label>
</CheckboxGroup>
</CheckboxGroup>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { CheckboxGroup } from '@base-ui/react/checkbox-group';
import { Label } from '@base-ui/react/label';
import styles from './index.module.css';

const fruits = ['fuji-apple', 'gala-apple', 'granny-smith-apple'];
Expand All @@ -19,7 +20,7 @@ export default function ExampleCheckboxGroup() {
className={styles.CheckboxGroup}
style={{ marginLeft: '1rem' }}
>
<label className={styles.Item} id={id} style={{ marginLeft: '-1rem' }}>
<Label className={styles.Item} id={id} style={{ marginLeft: '-1rem' }}>
<Checkbox.Root className={styles.Checkbox} parent>
<Checkbox.Indicator
className={styles.Indicator}
Expand All @@ -35,34 +36,34 @@ export default function ExampleCheckboxGroup() {
/>
</Checkbox.Root>
Apples
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="fuji-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Fuji
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="gala-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Gala
</label>
</Label>

<label className={styles.Item}>
<Label className={styles.Item}>
<Checkbox.Root value="granny-smith-apple" className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Granny Smith
</label>
</Label>
</CheckboxGroup>
);
}
Expand Down
12 changes: 6 additions & 6 deletions docs/src/app/(docs)/react/components/checkbox-group/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { DemoCheckboxGroupHero } from './demos/hero';

## Usage guidelines

- **Form controls must have an accessible name**: It can be created using `<label>` elements, or the `Field` and `Fieldset` components. See [Labeling a checkbox group](#labeling-a-checkbox-group) and the [forms guide](/react/handbook/forms).
- **Form controls must have an accessible name**: It can be created using native label elements, the [Label](/react/components/label) component, or the `Field` and `Fieldset` components. See [Labeling a checkbox group](#labeling-a-checkbox-group) and the [forms guide](/react/handbook/forms).

## Anatomy

Expand All @@ -38,16 +38,16 @@ A visible label for the group is created by specifying `aria-labelledby` on `<Ch
<CheckboxGroup aria-labelledby="protocols-label">{/* ... */}</CheckboxGroup>
```

For individual checkboxes, use an enclosing `<label>` element that wraps each `<Checkbox.Root>`. An enclosing label is announced to screen readers when focus is on the control, and ensures that clicking on any gaps between the label and checkbox still toggles it.
For individual checkboxes, use the [Label](/react/components/label) component. It supports the same enclosing labeling pattern as a native label element, so clicking on any gaps between the label text and checkbox still toggles it.

```tsx title="Using an enclosing label to label a checkbox" {1,4}
<label>
```tsx title="Using Label to label a checkbox" {1,4}
<Label>
<Checkbox.Root value="http" />
HTTP
</label>
</Label>
```

The [Field](/react/components/field) and [Fieldset](/react/components/fieldset) components eliminate the need to track `id` or `aria-labelledby` associations manually. They support both enclosing and sibling labeling patterns, along with a UX improvement to prevent double clicks from selecting the label text.
The [Field](/react/components/field) and [Fieldset](/react/components/fieldset) components are alternatives that add validation and group labeling support.

1. **Group label**: Since the group contains multiple controls, it can be labeled as a fieldset. Use [Fieldset](/react/components/fieldset) by replacing the `<Fieldset.Root>` element with `<CheckboxGroup>` via the `render` prop. `<Fieldset.Legend>` provides the visible label for the group.
2. **Individual label**: Place each individual checkbox in `<Field.Item>`, then label it using an enclosing `<Field.Label>`. Enclosing labels ensure that clicking on any gaps between the label and checkbox still toggles it.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { Label } from '@base-ui/react/label';
import styles from './index.module.css';

export default function ExampleCheckbox() {
return (
<label className={styles.Label}>
<Label className={styles.Label}>
<Checkbox.Root defaultChecked className={styles.Checkbox}>
<Checkbox.Indicator className={styles.Indicator}>
<CheckIcon className={styles.Icon} />
</Checkbox.Indicator>
</Checkbox.Root>
Enable notifications
</label>
</Label>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from 'react';
import { Checkbox } from '@base-ui/react/checkbox';
import { Label } from '@base-ui/react/label';

export default function ExampleCheckbox() {
return (
<label className="flex items-center gap-2 text-base text-gray-900">
<Label className="flex items-center gap-2 text-base text-gray-900">
<Checkbox.Root
defaultChecked
className="flex size-5 items-center justify-center rounded-xs focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-800 data-[checked]:bg-gray-900 data-[unchecked]:border data-[unchecked]:border-gray-300"
Expand All @@ -13,7 +14,7 @@ export default function ExampleCheckbox() {
</Checkbox.Indicator>
</Checkbox.Root>
Enable notifications
</label>
</Label>
);
}

Expand Down
Loading
Loading