Skip to content

Commit 1ecd7cd

Browse files
mirkaciampo
authored andcommitted
UI: Recommend Checkbox family components (WordPress#83771)
* UI: Recommend Checkbox family components * Add Checkbox recommendation changelog entries * Add CheckboxControl migration guide * Remove legacy checkbox heading guidance * Document checkbox group migration * Remove redundant checkbox lint examples * Docs: Clarify CheckboxControl form value migration Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: ciampo <mciampini@git.wordpress.org>
1 parent 2a6e465 commit 1ecd7cd

14 files changed

Lines changed: 254 additions & 32 deletions

File tree

‎packages/components/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
### Enhancements
1313

14+
- `CheckboxControl`: Mark as not recommended for use in a WordPress environment, in favour of `CheckboxControl` from `@wordpress/ui` ([#83771](https://github.com/WordPress/gutenberg/pull/83771)).
1415
- `RadioControl`: Match the `@wordpress/ui` Radio colors ([#83270](https://github.com/WordPress/gutenberg/pull/83270)).
1516
- `CheckboxControl`: Keep the default checkbox at 16px on narrow screens while retaining a 24px click target ([#83612](https://github.com/WordPress/gutenberg/pull/83612)).
1617
- `FormToggle`: Match the `@wordpress/ui` `Switch` track, thumb, and border colors across unchecked, checked, hover, and disabled states ([#83773](https://github.com/WordPress/gutenberg/pull/83773)).

‎packages/components/src/checkbox-control/stories/index.story.tsx‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { VStack } from '../../v-stack';
77
import { HStack } from '../../h-stack';
88

99
const meta: Meta< typeof CheckboxControl > = {
10-
tags: [ 'manifest' ],
1110
component: CheckboxControl,
1211
title: 'Components/@wordpress-components/Selection & Input/Common/CheckboxControl',
1312
id: 'components-checkboxcontrol',
@@ -27,9 +26,9 @@ const meta: Meta< typeof CheckboxControl > = {
2726
},
2827
docs: { canvas: { sourceState: 'shown' } },
2928
componentStatus: {
30-
status: 'recommended',
29+
status: 'not-recommended',
3130
whereUsed: 'global',
32-
notes: 'Will be superseded by [`CheckboxControl`](?path=/docs/design-system-components-form-checkboxcontrol--docs) in `@wordpress/ui`, but continue using for now.',
31+
notes: 'Use [`CheckboxControl`](?path=/docs/design-system-components-form-checkboxcontrol--docs) from `@wordpress/ui` instead. See the [migration guide](?path=/docs/components-checkboxcontrol--migration-guide).',
3332
},
3433
},
3534
};
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { Markdown, Meta } from '@storybook/addon-docs/blocks';
2+
import * as CheckboxControlStories from './index.story';
3+
4+
<Meta of={ CheckboxControlStories } name="Migration Guide" />
5+
6+
# CheckboxControl migration guide
7+
8+
Migrate from [`CheckboxControl`](?path=/docs/components-checkboxcontrol--docs) in `@wordpress/components` to [`CheckboxControl`](?path=/docs/design-system-components-form-checkboxcontrol--docs) in `@wordpress/ui`.
9+
10+
## Basic migration
11+
12+
Update the import and replace the callback and help props:
13+
14+
```jsx
15+
// Before
16+
import { CheckboxControl } from '@wordpress/components';
17+
18+
<CheckboxControl
19+
label="Is author"
20+
checked={ isChecked }
21+
onChange={ setChecked }
22+
help="Give this user author permissions."
23+
/>;
24+
25+
// After
26+
import { CheckboxControl } from '@wordpress/ui';
27+
28+
<CheckboxControl
29+
label="Is author"
30+
checked={ isChecked }
31+
onCheckedChange={ setChecked }
32+
description="Give this user author permissions."
33+
/>;
34+
```
35+
36+
## Prop mapping
37+
38+
<Markdown>{ `
39+
| \`@wordpress/components\` | \`@wordpress/ui\` | Notes |
40+
| --- | --- | --- |
41+
| \`onChange\` | \`onCheckedChange\` | Receives the next checked state as a boolean. |
42+
| \`help\` | \`description\` | Use plain text only. |
43+
| \`help\` with links or other markup | \`details\` | Use when the help text needs semantic content. |
44+
| \`checked\` | \`checked\` | Continue passing the state for a controlled checkbox. |
45+
` }</Markdown>
46+
47+
## Form values
48+
49+
When a checked checkbox has a `name` but no `value`, the legacy component submits `"1"` with the form, while the new component submits `"on"`, the native default for checkboxes. If your form handler expects the legacy value, pass `value="1"` to the new component:
50+
51+
```jsx
52+
<CheckboxControl
53+
name="isAuthor"
54+
value="1"
55+
label="Is author"
56+
checked={ isChecked }
57+
onCheckedChange={ setChecked }
58+
/>
59+
```
60+
61+
If the legacy component already has a custom `value`, keep that value instead.
62+
63+
## Labels
64+
65+
The new `CheckboxControl` requires a `label` prop with a plain `string` value. The legacy component treats `label` as optional. Give every checkbox a descriptive label, even when the text is already visible elsewhere:
66+
67+
```jsx
68+
<CheckboxControl
69+
label="Receive notifications"
70+
hideLabelFromVision
71+
checked={ isChecked }
72+
onCheckedChange={ setChecked }
73+
/>
74+
```
75+
76+
For a custom label layout, compose the [`Checkbox`](?path=/docs/design-system-components-form-primitives-checkbox--docs) and [`Field`](?path=/docs/design-system-components-form-primitives-field--docs) primitives.
77+
78+
## Checkbox groups
79+
80+
If a legacy checkbox uses `indeterminate` to show that only some items are selected, move the selected items into a `CheckboxGroup` instead of calculating the parent checkbox state yourself. Pass the child values to `allValues` and mark the select-all checkbox with `parent`. The group updates the parent checkbox when children change and selects or clears all children when the parent is clicked.
81+
82+
```jsx
83+
import { useState } from '@wordpress/element';
84+
import { CheckboxControl, CheckboxGroup } from '@wordpress/ui';
85+
86+
function FruitCheckboxes() {
87+
const [ selectedFruits, setSelectedFruits ] = useState( [ 'apple' ] );
88+
89+
return (
90+
<CheckboxGroup
91+
value={ selectedFruits }
92+
onValueChange={ setSelectedFruits }
93+
allValues={ [ 'apple', 'orange' ] }
94+
aria-label="Fruit"
95+
>
96+
<CheckboxControl parent value="fruit" label="Select all fruit" />
97+
<CheckboxGroup.NestedItems>
98+
<CheckboxControl value="apple" label="Apple" />
99+
<CheckboxControl value="orange" label="Orange" />
100+
</CheckboxGroup.NestedItems>
101+
</CheckboxGroup>
102+
);
103+
}
104+
```
105+
106+
See the [Checkbox Groups stories](?path=/docs/design-system-components-form-checkbox-groups--docs) for other grouping patterns.

‎packages/eslint-plugin/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
### Enhancements
1010

11+
- `use-recommended-components`: Recommend `Checkbox`, `CheckboxControl`, and `CheckboxGroup` from `@wordpress/ui`, and flag `CheckboxControl` from `@wordpress/components` ([#83771](https://github.com/WordPress/gutenberg/pull/83771)).
1112
- `use-recommended-components`: Update the "Use with caution" entry from `LinkButton` to `ButtonLink` to match the renamed `@wordpress/ui` component ([#83789](https://github.com/WordPress/gutenberg/pull/83789)).
1213
- Update `use-recommended-components` rule to prefer `Badge` from `@wordpress/ui` over the private `@wordpress/components` `Badge`. ([#82379](https://github.com/WordPress/gutenberg/pull/82379))
1314

‎packages/eslint-plugin/docs/rules/use-recommended-components.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ The rule checks named imports and direct destructuring from `unlock( privateApis
66

77
## Migration guides
88

9+
- `CheckboxControl` — [`CheckboxControl` migration guide][checkboxcontrol-migration-guide]
910
- `__experimentalInputControl` — [`InputControl` migration guide][inputcontrol-migration-guide]
1011
- `TextControl` — [`InputControl` migration guide][inputcontrol-migration-guide]
1112
- `TextareaControl` — [`TextareaControl` migration guide][textareacontrol-migration-guide]
1213

14+
[checkboxcontrol-migration-guide]: https://wordpress.github.io/gutenberg/?path=/docs/components-checkboxcontrol--migration-guide
1315
[inputcontrol-migration-guide]: https://wordpress.github.io/gutenberg/?path=/docs/components-inputcontrol--migration-guide
1416
[textareacontrol-migration-guide]: https://wordpress.github.io/gutenberg/?path=/docs/components-textareacontrol--migration-guide
1517

‎packages/eslint-plugin/rules/use-recommended-components.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const ALLOWLIST = {
2323
'Badge',
2424
'Calendar',
2525
'Card',
26+
'Checkbox',
27+
'CheckboxControl',
28+
'CheckboxGroup',
2629
'Collapsible',
2730
'CollapsibleCard',
2831
'ControlWithError',
@@ -60,8 +63,6 @@ const ALLOWLIST = {
6063
'Breadcrumb',
6164
'Button',
6265
'ButtonLink',
63-
'Checkbox',
64-
'CheckboxGroup',
6566
'Combobox',
6667
'Dialog',
6768
'Drawer',
@@ -121,6 +122,8 @@ const DENYLIST = {
121122
CardHeader:
122123
'Use `Card.Header` (and optionally `Card.Title`) from `@wordpress/ui` instead.',
123124
CardMedia: 'Use `Card.FullBleed` from `@wordpress/ui` instead.',
125+
CheckboxControl:
126+
'Use `CheckboxControl` from `@wordpress/ui` instead. See migration guide in the lint rule documentation.',
124127
Flex: 'For use cases not covered by `Stack` from `@wordpress/ui`, write your own CSS instead.',
125128
FlexBlock:
126129
'For use cases not covered by `Stack` from `@wordpress/ui`, write your own CSS instead.',

‎packages/ui/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
### Enhancements
1818

19+
- `Checkbox`, `CheckboxControl`, `CheckboxGroup`: Mark as recommended for use in a WordPress environment ([#83771](https://github.com/WordPress/gutenberg/pull/83771)).
1920
- `Spinner`: Show a trackless half-circle like the `Button` loading indicator, with a `color` prop that accepts any CSS color value and defaults to weak neutral foreground. Keep the arc visible in forced-colors mode ([#83775](https://github.com/WordPress/gutenberg/pull/83775)).
2021
- Native text inputs and textareas use at least 16px below 600px to avoid iOS Safari zoom. Prefix and suffix text on `Input` match that size. Select and combobox trigger text stay at the `md` font size. ([#82764](https://github.com/WordPress/gutenberg/pull/82764))
2122
- `Menu`: Add development-only checks against nesting `Group` and `RadioGroup` within each other, and document how to label radio groups ([#83792](https://github.com/WordPress/gutenberg/pull/83792)).

‎packages/ui/src/form/checkbox-control/stories/index.story.tsx‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@ import {
66
} from '../../stories/shared';
77

88
const meta: Meta< typeof CheckboxControl > = {
9+
tags: [ 'manifest' ],
910
title: 'Components/@wordpress-ui/Form/CheckboxControl',
1011
id: 'design-system-components-form-checkboxcontrol',
1112
component: CheckboxControl,
1213
argTypes: {
1314
checked: { control: false },
1415
onCheckedChange: { action: 'onCheckedChange' },
1516
},
17+
parameters: {
18+
componentStatus: {
19+
status: 'recommended',
20+
whereUsed: 'global',
21+
},
22+
},
1623
};
1724
export default meta;
1825

‎packages/ui/src/form/primitives/checkbox-group/stories/index.story.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Checkbox } from '../../checkbox';
44
import { CheckboxGroup } from '../';
55

66
const meta: Meta< typeof CheckboxGroup > = {
7+
tags: [ 'manifest' ],
78
title: 'Components/@wordpress-ui/Form/Primitives/CheckboxGroup',
89
id: 'design-system-components-form-primitives-checkboxgroup',
910
component: CheckboxGroup,
@@ -15,9 +16,8 @@ const meta: Meta< typeof CheckboxGroup > = {
1516
},
1617
parameters: {
1718
componentStatus: {
18-
status: 'use-with-caution',
19+
status: 'recommended',
1920
whereUsed: 'global',
20-
notes: 'Not yet recommended for use alongside components from `@wordpress/components`, pending review of style consistency with `@wordpress/components` and component set completeness. See [WordPress/gutenberg#76135](https://github.com/WordPress/gutenberg/issues/76135).',
2121
},
2222
},
2323
};

‎packages/ui/src/form/primitives/checkbox-group/types.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ComponentProps } from '../../../utils/types';
33
import type { Stack } from '../../../stack';
44

55
export type CheckboxGroupProps = ComponentProps< typeof _CheckboxGroup > & {
6+
/** The checkboxes and optional nested items in the group. */
67
children?: React.ReactNode;
78
};
89

0 commit comments

Comments
 (0)