Skip to content

Commit 1f9eb72

Browse files
authored
Add CheckboxGroup and RadioGroup components (#830)
* add CheckboxGroup, RadioGroup, and InputGroup components * add changeset * update snapshots * improve changeset * remove unused InputGroup test file * fixed broken animation * github-actions[bot] Regenerated snapshots * rename InputGroup to ControlGroup * reset snapshots * reduce Caption and Validation font-size to 100 * rename CSS declaration file * github-actions[bot] Regenerated snapshots * add documentation for CheckboxGroup and RadioGroup components * reduce font-weight on FormControl labels within a ControlGroup * github-actions[bot] Regenerated snapshots * update changeset * update changeset semver bump * various docs updates based on PR feedback * leverage Text component * split stories up into multiple fies * remove regex * updated docs to align with prc * fix tabs in React docs * fix case * stop forwarding unused prop to Radio * correct casing * modify styles to avoid :global selector * update animation easing * update links in docs * update changeset * github-actions[bot] Regenerated snapshots * remove nested describe --------- Co-authored-by: joshfarrant <[email protected]>
1 parent c008e13 commit 1f9eb72

30 files changed

+1366
-1
lines changed

.changeset/popular-seas-yawn.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
'@primer/react-brand': minor
3+
---
4+
5+
New `CheckboxGroup` and `RadioGroup` components to group `Checkbox` and `Radio` components are now available.
6+
7+
`CheckboxGroup`
8+
9+
```jsx
10+
<CheckboxGroup>
11+
<CheckboxGroup.Label>Choose your favorite features</CheckboxGroup.Label>
12+
<FormControl>
13+
<FormControl.Label>Actions notifications</FormControl.Label>
14+
<Checkbox value="actions" />
15+
</FormControl>
16+
<FormControl>
17+
<FormControl.Label>Packages</FormControl.Label>
18+
<Checkbox value="packages" />
19+
</FormControl>
20+
<FormControl>
21+
<FormControl.Label>Codespaces</FormControl.Label>
22+
<Checkbox value="codespaces" />
23+
</FormControl>
24+
</CheckboxGroup>
25+
```
26+
27+
🔗 [Read the documentation for more `CheckboxGroup` examples](https://primer.style/brand/components/RadioGroup/react)
28+
29+
`RadioGroup`:
30+
31+
```jsx
32+
<RadioGroup>
33+
<RadioGroup.Label>Choose your primary workspace</RadioGroup.Label>
34+
<FormControl>
35+
<FormControl.Label>Codespaces</FormControl.Label>
36+
<Radio name="workspace" value="codespaces" />
37+
</FormControl>
38+
<FormControl>
39+
<FormControl.Label>Local environment</FormControl.Label>
40+
<Radio name="workspace" value="local" />
41+
</FormControl>
42+
<FormControl>
43+
<FormControl.Label>Pen and paper</FormControl.Label>
44+
<Radio name="workspace" value="remote" />
45+
</FormControl>
46+
</RadioGroup>
47+
```
48+
49+
🔗 [Read the documentation for more `RadioGroup` examples](https://primer.style/brand/components/RadioGroup/react)
Loading
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: Checkbox group
3+
description: Checkbox group renders a set of checkboxes.
4+
---
5+
6+
import ComponentLayout from '../../../src/layouts/component-layout'
7+
export default ComponentLayout
8+
9+
import anatomy from './images/anatomy.png'
10+
11+
## Usage
12+
13+
Use checkbox group to allow users to select multiple items from a list of individual items, or to mark one individual item as selected.
14+
15+
### Best practices
16+
17+
- Put checkboxes in a logical order
18+
- If users are only allowed to select a single option, consider using a [radio group](/components/RadioGroup) instead
19+
- Each checkbox's state should be independent from other checkboxes in the group. For example: checking one checkbox should not check or disable any other checkboxes
20+
21+
## Anatomy
22+
23+
<img src={anatomy} alt="Anatomy diagram" />
24+
25+
**Label:** A title that labels the group of options and helps users understand the relationship between the options in the group.
26+
27+
**Required indicator:** Indicates that a selection is required.
28+
29+
**Caption:** May be used to provide additional context about the checkbox group when the label alone is not sufficient
30+
31+
**Options:** A list of options represented using [checkboxes](/components/Checkbox).
32+
33+
**Validation message:** A message explaining why the selection failed validation. See the [form pattern documentation](https://primer.style/ui-patterns/forms/overview#validation-message) for more information on form validation patterns.
34+
35+
## Accessibility
36+
37+
Once a user checks an option from a checkbox group, the result should not be saved or applied until the user has explicitly submitted their input using a "save" or "submit" button. See the [saving pattern guidelines](https://primer.style/ui-patterns/saving) for more information.
38+
39+
## Related components
40+
41+
- [Checkbox](/components/Checkbox): Used to render an individual checkbox control.
42+
- [FormControl](/components/FormControl): Used to group individual controls with an associated label.
43+
- [RadioGroup](/components/RadioGroup): Similar to `CheckboxGroup`, but used for organizing radio controls.
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
title: Checkbox group
3+
description: Checkbox group renders a set of checkboxes.
4+
source: https://github.com/primer/brand/blob/main/packages/react/src/forms/CheckboxGroup/CheckboxGroup.tsx
5+
figma: 'https://www.figma.com/design/BJ95AjraesmRCWsKA013GS/Primer-Brand?node-id=10467-3273&t=GA5GtEqPtQ9yeRaN-4'
6+
storybook: '/brand/storybook/?path=/story/components-forms-checkboxgroup--playground'
7+
---
8+
9+
import ComponentLayout from '../../../src/layouts/component-layout'
10+
export default ComponentLayout
11+
12+
import {Label} from '@primer/react'
13+
import {PropTableValues} from '../../../src/components'
14+
15+
```js
16+
import {CheckboxGroup} from '@primer/react-brand'
17+
```
18+
19+
## Examples
20+
21+
### Default
22+
23+
`CheckboxGroup` creates a semantic container for multiple related checkboxes.
24+
25+
```jsx live
26+
<CheckboxGroup>
27+
<CheckboxGroup.Label>Choose your favorite features</CheckboxGroup.Label>
28+
<FormControl>
29+
<FormControl.Label>Actions notifications</FormControl.Label>
30+
<Checkbox value="actions" />
31+
</FormControl>
32+
<FormControl>
33+
<FormControl.Label>Packages</FormControl.Label>
34+
<Checkbox value="packages" />
35+
</FormControl>
36+
<FormControl>
37+
<FormControl.Label>Codespaces</FormControl.Label>
38+
<Checkbox value="codespaces" />
39+
</FormControl>
40+
</CheckboxGroup>
41+
```
42+
43+
### With caption
44+
45+
Use `CheckboxGroup.Caption` to provide additional context for the group.
46+
47+
```jsx live
48+
<CheckboxGroup>
49+
<CheckboxGroup.Label>Notification preferences</CheckboxGroup.Label>
50+
<CheckboxGroup.Caption>
51+
Select how you'd like to be notified
52+
</CheckboxGroup.Caption>
53+
<FormControl>
54+
<FormControl.Label>Email notifications</FormControl.Label>
55+
<Checkbox value="email" />
56+
</FormControl>
57+
<FormControl>
58+
<FormControl.Label>Browser notifications</FormControl.Label>
59+
<Checkbox value="browser" />
60+
</FormControl>
61+
<FormControl>
62+
<FormControl.Label>Mobile notifications</FormControl.Label>
63+
<Checkbox value="mobile" />
64+
</FormControl>
65+
</CheckboxGroup>
66+
```
67+
68+
### With validation
69+
70+
`CheckboxGroup.Validation` can display success or error states with appropriate icons.
71+
72+
```jsx live
73+
<Stack direction="vertical" gap="spacious">
74+
<CheckboxGroup>
75+
<CheckboxGroup.Label>Valid selection</CheckboxGroup.Label>
76+
<FormControl>
77+
<FormControl.Label>Option one</FormControl.Label>
78+
<Checkbox value="one" />
79+
</FormControl>
80+
<FormControl>
81+
<FormControl.Label>Option two</FormControl.Label>
82+
<Checkbox value="two" />
83+
</FormControl>
84+
<CheckboxGroup.Validation variant="success">
85+
Great choice!
86+
</CheckboxGroup.Validation>
87+
</CheckboxGroup>
88+
89+
<CheckboxGroup>
90+
<CheckboxGroup.Label>Invalid selection</CheckboxGroup.Label>
91+
<FormControl>
92+
<FormControl.Label>Option one</FormControl.Label>
93+
<Checkbox value="one" />
94+
</FormControl>
95+
<FormControl>
96+
<FormControl.Label>Option two</FormControl.Label>
97+
<Checkbox value="two" />
98+
</FormControl>
99+
<CheckboxGroup.Validation variant="error">
100+
Please select at least one option
101+
</CheckboxGroup.Validation>
102+
</CheckboxGroup>
103+
</Stack>
104+
```
105+
106+
### Visually hidden label
107+
108+
When context is clear, labels can be visually hidden while remaining accessible to screen readers.
109+
110+
```jsx live
111+
<CheckboxGroup>
112+
<CheckboxGroup.Label visuallyHidden>Filter options</CheckboxGroup.Label>
113+
<Stack direction="vertical" gap="regular">
114+
<FormControl>
115+
<FormControl.Label>Show all</FormControl.Label>
116+
<Checkbox value="all" />
117+
</FormControl>
118+
<FormControl>
119+
<FormControl.Label>Show active only</FormControl.Label>
120+
<Checkbox value="active" />
121+
</FormControl>
122+
</Stack>
123+
</CheckboxGroup>
124+
```
125+
126+
### Inline
127+
128+
When space is limited, checkboxes can be arranged horizontally using the [Stack](/components/Stack) component.
129+
130+
```jsx live
131+
<CheckboxGroup>
132+
<CheckboxGroup.Label visuallyHidden>Filter options</CheckboxGroup.Label>
133+
<CheckboxGroup.Caption>
134+
Some inline checkboxes with a visually hidden label
135+
</CheckboxGroup.Caption>
136+
<Stack direction="horizontal" gap="normal" padding="none">
137+
<FormControl>
138+
<FormControl.Label>Choice one</FormControl.Label>
139+
<Checkbox value="one" />
140+
</FormControl>
141+
<FormControl>
142+
<FormControl.Label>Choice two</FormControl.Label>
143+
<Checkbox value="two" />
144+
</FormControl>
145+
<FormControl>
146+
<FormControl.Label>Choice three</FormControl.Label>
147+
<Checkbox value="three" />
148+
</FormControl>
149+
</Stack>
150+
</CheckboxGroup>
151+
```
152+
153+
## Component props
154+
155+
### CheckboxGroup <Label>Required</Label>
156+
157+
| Name | Type | Default | Description |
158+
| :--------- | :--------------------- | :-----: | :--------------------------------------------------------------- |
159+
| `children` | `React.ReactElement[]` | | CheckboxGroup components and FormControl components |
160+
| `id` | `string` | | Sets a custom id. If not provided, a unique id will be generated |
161+
162+
`CheckboxGroup` extends the HTML `fieldset` element and supports all `fieldset` props.
163+
164+
### CheckboxGroup.Label <Label>Required</Label>
165+
166+
| Name | Type | Default | Description |
167+
| :--------------- | :-------- | :-----: | :-------------------------------------- |
168+
| `children` | `string` | | Label text |
169+
| `visuallyHidden` | `boolean` | `false` | Hide label visually but keep accessible |
170+
171+
`CheckboxGroup.Label` extends the HTML `legend` element and supports all `legend` props.
172+
173+
### CheckboxGroup.Caption
174+
175+
| Name | Type | Default | Description |
176+
| :--------- | :------- | :-----: | :----------- |
177+
| `children` | `string` | | Caption text |
178+
179+
`CheckboxGroup.Caption` extends the `span` element and supports all `span` props.
180+
181+
### CheckboxGroup.Validation
182+
183+
| Name | Type | Default | Description |
184+
| :--------- | :--------------------------------------------------------------- | :-----: | :--------------------------------- |
185+
| `children` | `string` | | Validation message |
186+
| `variant` | <PropTableValues values={['error', 'success' ]} addLineBreaks /> | | Sets the validation state and icon |
187+
188+
`CheckboxGroup.Validation` extends the `span` element and supports all `span` props.
Loading
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Radio group
3+
description: Radio group is used to render a short list of mutually exclusive options.
4+
---
5+
6+
import ComponentLayout from '../../../src/layouts/component-layout'
7+
8+
import anatomy from './images/anatomy.png'
9+
export default ComponentLayout
10+
11+
## Usage
12+
13+
Use radio group to allow users to select a single option from a short list of related options.
14+
15+
### Orientation
16+
17+
A vertical orientation makes options easier to visually scan.
18+
19+
### Anatomy
20+
21+
<img src={anatomy} alt="Anatomy diagram" />
22+
23+
**Label:** A title that labels the group of options and helps users understand the relationship between the options in the group
24+
25+
**Required indicator:** Indicates that a selection is required
26+
27+
**Caption:** May be used to provide additional context about the radio group when the label alone is not sufficient
28+
29+
**Options:** A list of mutually exclusive options represented using [radio buttons](/components/Radio)
30+
31+
**Validation message:** A message explaining why the selection failed validation. See the [form pattern documentation](https://primer.style/ui-patterns/forms/overview#validation-message) for more information on form validation patterns.
32+
33+
### Best practices
34+
35+
- Put radio buttons in a logical order
36+
- Only use a radio group for a short list of options: aim for 6 or less options. For longer sets of options, consider using a [select](/components/Select) or an [action menu](/components/ActionMenu)
37+
- Radio buttons cannot be unchecked, so only use a radio group when a selection is required. Consider the following alternatives:
38+
- use a radio group, but with one option that equates to "none of these options"
39+
- use a [checkbox group](/components/CheckboxGroup) that fails validation if more than one option is selected
40+
- If there is an option that's the most likely option to be checked, that option should be checked by default
41+
42+
## Accessibility
43+
44+
- Once a user checks an option from a radio group, the result should not be saved or applied until the user has explicitly submitted their input using a "save" or "submit" button. A radio group is a single tab stop, and the options can be navigated using the arrow keys: this means assistive technologies like a screen reader cannot "read" an option without selecting it. See the [saving pattern guidelines](https://primer.style/ui-patterns/saving) for more information.
45+
- Radio groups must be labeled. The label may be visually hidden, but visible labels are preferred.
46+
47+
## Related components
48+
49+
- [FormControl](/components/FormControl): Used to group form controls with labels
50+
- [Radio](/components/Radio): Individual radio button control
51+
- [CheckboxGroup](/components/CheckboxGroup): For allowing multiple selections

0 commit comments

Comments
 (0)