Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CheckboxGroup and RadioGroup components #830

Merged
merged 32 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
885dd26
add CheckboxGroup, RadioGroup, and InputGroup components
joshfarrant Nov 21, 2024
09ba756
add changeset
joshfarrant Nov 25, 2024
50b888c
update snapshots
joshfarrant Nov 25, 2024
c3f881d
improve changeset
joshfarrant Nov 25, 2024
b71c4c2
remove unused InputGroup test file
joshfarrant Nov 25, 2024
e43f7fb
fixed broken animation
joshfarrant Nov 25, 2024
aca86dc
github-actions[bot] Regenerated snapshots
joshfarrant Nov 25, 2024
790fa13
rename InputGroup to ControlGroup
joshfarrant Nov 25, 2024
526ae02
reset snapshots
joshfarrant Nov 26, 2024
a9aca70
reduce Caption and Validation font-size to 100
joshfarrant Nov 26, 2024
52cc180
rename CSS declaration file
joshfarrant Nov 26, 2024
810a183
github-actions[bot] Regenerated snapshots
joshfarrant Nov 26, 2024
d65b102
add documentation for CheckboxGroup and RadioGroup components
joshfarrant Nov 27, 2024
4b9b5f4
reduce font-weight on FormControl labels within a ControlGroup
joshfarrant Nov 27, 2024
78366b2
github-actions[bot] Regenerated snapshots
joshfarrant Nov 27, 2024
7bd4fea
update changeset
joshfarrant Nov 27, 2024
0fd5510
update changeset semver bump
joshfarrant Nov 27, 2024
df783b5
various docs updates based on PR feedback
joshfarrant Nov 27, 2024
fa4729d
leverage Text component
joshfarrant Nov 27, 2024
17aefc5
split stories up into multiple fies
joshfarrant Nov 27, 2024
8405890
remove regex
joshfarrant Nov 27, 2024
3bbaec1
updated docs to align with prc
joshfarrant Nov 27, 2024
d3ab439
fix tabs in React docs
joshfarrant Nov 27, 2024
1aa22e8
fix case
joshfarrant Nov 27, 2024
8e91013
stop forwarding unused prop to Radio
joshfarrant Nov 27, 2024
fc5f393
correct casing
joshfarrant Dec 2, 2024
160275a
modify styles to avoid :global selector
joshfarrant Dec 3, 2024
c3dc707
update animation easing
joshfarrant Dec 3, 2024
e6096f8
update links in docs
joshfarrant Dec 3, 2024
7c3b183
update changeset
joshfarrant Dec 3, 2024
e6f5a23
github-actions[bot] Regenerated snapshots
joshfarrant Dec 3, 2024
b535c93
remove nested describe
joshfarrant Dec 3, 2024
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
5 changes: 5 additions & 0 deletions .changeset/popular-seas-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react-brand': minor
---

Added new `CheckboxGroup` and `RadioGroup` components to group `Checkbox` and `Radio` components respectively.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions apps/docs/content/components/CheckboxGroup/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Checkbox group
description: Checkbox group renders a set of checkboxes.
---

import ComponentLayout from '../../../src/layouts/component-layout'
export default ComponentLayout

import anatomy from './images/anatomy.png'

## Usage

Use checkbox group to allow users to select multiple items from a list of individual items, or to mark one individual item as selected.

### Best practices

- Put checkboxes in a logical order
- If users are only allowed to select a single option, consider using a [radio group](/components/RadioGroup) instead
- 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

## Anatomy

<img src={anatomy} alt="Anatomy diagram" />

**Label:** A title that labels the group of options and helps users understand the relationship between the options in the group.

**Required indicator:** Indicates that a selection is required.

**Caption:** May be used to provide additional context about the checkbox group when the label alone is not sufficient

**Options:** A list of options represented using [checkboxes](/components/Checkbox).

**Validation message:** A message explaining why the selection failed validation. See the [form pattern documentation](/ui-patterns/forms/overview#validation) for more information on form validation patterns.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved

## Accessibility

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](/ui-patterns/saving) for more information.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved

## Related components

- [Checkbox](/components/Checkbox): Used to render an individual checkbox control.
- [FormControl](/components/FormControl): Used to group individual controls with an associated label.
- [RadioGroup](/components/RadioGroup): Similar to `CheckboxGroup`, but used for organizing radio controls.
188 changes: 188 additions & 0 deletions apps/docs/content/components/CheckboxGroup/react.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
title: Checkbox group
description: Checkbox group renders a set of checkboxes.
source: https://github.com/primer/brand/blob/main/packages/react/src/forms/CheckboxGroup/CheckboxGroup.tsx
figma: 'https://www.figma.com/design/BJ95AjraesmRCWsKA013GS/Primer-Brand?node-id=10467-3273&t=GA5GtEqPtQ9yeRaN-4'
storybook: '/brand/storybook/?path=/story/components-forms-checkboxgroup--playground'
---

import ComponentLayout from '../../../src/layouts/component-layout'
export default ComponentLayout

import {Label} from '@primer/react'
import {PropTableValues} from '../../../src/components'

joshfarrant marked this conversation as resolved.
Show resolved Hide resolved
```js
import {CheckboxGroup} from '@primer/react-brand'
```

## Examples

### Default

`CheckboxGroup` creates a semantic container for multiple related checkboxes.

```jsx live
<CheckboxGroup>
<CheckboxGroup.Label>Choose your favorite features</CheckboxGroup.Label>
<FormControl>
<FormControl.Label>Actions notifications</FormControl.Label>
<Checkbox value="actions" />
</FormControl>
<FormControl>
<FormControl.Label>Packages</FormControl.Label>
<Checkbox value="packages" />
</FormControl>
<FormControl>
<FormControl.Label>Codespaces</FormControl.Label>
<Checkbox value="codespaces" />
</FormControl>
</CheckboxGroup>
```

### With caption

Use `CheckboxGroup.Caption` to provide additional context for the group.

```jsx live
<CheckboxGroup>
<CheckboxGroup.Label>Notification preferences</CheckboxGroup.Label>
<CheckboxGroup.Caption>
Select how you'd like to be notified
</CheckboxGroup.Caption>
<FormControl>
<FormControl.Label>Email notifications</FormControl.Label>
<Checkbox value="email" />
</FormControl>
<FormControl>
<FormControl.Label>Browser notifications</FormControl.Label>
<Checkbox value="browser" />
</FormControl>
<FormControl>
<FormControl.Label>Mobile notifications</FormControl.Label>
<Checkbox value="mobile" />
</FormControl>
</CheckboxGroup>
```

### With validation

`CheckboxGroup.Validation` can display success or error states with appropriate icons.

```jsx live
<Stack direction="vertical" gap="spacious">
<CheckboxGroup>
<CheckboxGroup.Label>Valid selection</CheckboxGroup.Label>
<FormControl>
<FormControl.Label>Option one</FormControl.Label>
<Checkbox value="one" />
</FormControl>
<FormControl>
<FormControl.Label>Option two</FormControl.Label>
<Checkbox value="two" />
</FormControl>
<CheckboxGroup.Validation variant="success">
Great choice!
</CheckboxGroup.Validation>
</CheckboxGroup>

<CheckboxGroup>
<CheckboxGroup.Label>Invalid selection</CheckboxGroup.Label>
<FormControl>
<FormControl.Label>Option one</FormControl.Label>
<Checkbox value="one" />
</FormControl>
<FormControl>
<FormControl.Label>Option two</FormControl.Label>
<Checkbox value="two" />
</FormControl>
<CheckboxGroup.Validation variant="error">
Please select at least one option
</CheckboxGroup.Validation>
</CheckboxGroup>
</Stack>
```

### Visually hidden label

When context is clear, labels can be visually hidden while remaining accessible to screen readers.

```jsx live
<CheckboxGroup>
<CheckboxGroup.Label visuallyHidden>Filter options</CheckboxGroup.Label>
<Stack direction="vertical" gap="regular">
<FormControl>
<FormControl.Label>Show all</FormControl.Label>
<Checkbox value="all" />
</FormControl>
<FormControl>
<FormControl.Label>Show active only</FormControl.Label>
<Checkbox value="active" />
</FormControl>
</Stack>
</CheckboxGroup>
```

### Inline

When space is limited, checkboxes can be arranged horizontally using the [Stack](/components/Stack) component.

```jsx live
<CheckboxGroup>
<CheckboxGroup.Label visuallyHidden>Filter options</CheckboxGroup.Label>
<CheckboxGroup.Caption>
Some inline checkboxes with a visually hidden label
</CheckboxGroup.Caption>
<Stack direction="horizontal" gap="normal" padding="none">
<FormControl>
<FormControl.Label>Choice one</FormControl.Label>
<Checkbox value="one" />
</FormControl>
<FormControl>
<FormControl.Label>Choice two</FormControl.Label>
<Checkbox value="two" />
</FormControl>
<FormControl>
<FormControl.Label>Choice three</FormControl.Label>
<Checkbox value="three" />
</FormControl>
</Stack>
</CheckboxGroup>
```

## Component props

### CheckboxGroup <Label>Required</Label>

| Name | Type | Default | Description |
| :--------- | :--------------------- | :-----: | :--------------------------------------------------------------- |
| `children` | `React.ReactElement[]` | | CheckboxGroup components and FormControl components |
| `id` | `string` | | Sets a custom id. If not provided, a unique id will be generated |

`CheckboxGroup` extends the HTML `fieldset` element and supports all `fieldset` props.

### CheckboxGroup.Label <Label>Required</Label>

| Name | Type | Default | Description |
| :--------------- | :-------- | :-----: | :-------------------------------------- |
| `children` | `string` | | Label text |
| `visuallyHidden` | `boolean` | `false` | Hide label visually but keep accessible |

`CheckboxGroup.Label` extends the HTML `legend` element and supports all `legend` props.

### CheckboxGroup.Caption

| Name | Type | Default | Description |
| :--------- | :------- | :-----: | :----------- |
| `children` | `string` | | Caption text |

`CheckboxGroup.Caption` extends the `span` element and supports all `span` props.

### CheckboxGroup.Validation

| Name | Type | Default | Description |
| :--------- | :--------------------------------------------------------------- | :-----: | :--------------------------------- |
| `children` | `string` | | Validation message |
| `variant` | <PropTableValues values={['error', 'success' ]} addLineBreaks /> | | Sets the validation state and icon |

`CheckboxGroup.Validation` extends the `span` element and supports all `span` props.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions apps/docs/content/components/RadioGroup/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Radio group
description: Radio group is used to render a short list of mutually exclusive options.
---

import ComponentLayout from '../../../src/layouts/component-layout'

import anatomy from './images/anatomy.png'
export default ComponentLayout

## Usage

Use radio group to allow users to select a single option from a short list of related options.

### Orientation

A vertical orientation makes options easier to visually scan. A horizontal orientation is not yet supported.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved

### Anatomy

<img src={anatomy} alt="Anatomy diagram" />

**Label:** A title that labels the group of options and helps users understand the relationship between the options in the group

**Required indicator:** Indicates that a selection is required

**Caption:** May be used to provide additional context about the radio group when the label alone is not sufficient

**Options:** A list of mutually exclusive options represented using [radio buttons](/components/Radio)

**Validation message:** A message explaining why the selection failed validation. See the [form pattern documentation](/ui-patterns/forms/overview#validation) for more information on form validation patterns.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved

### Best practices

- Put radio buttons in a logical order
- 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)
- Radio buttons cannot be unchecked, so only use a radio group when a selection is required. Consider the following alternatives:
- use a radio group, but with one option that equates to "none of these options"
- use a [checkbox group](/components/CheckboxGroup) that fails validation if more than one option is selected
- If there is an option that's the most likely option to be checked, that option should be checked by default

## Accessibility

- 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](/ui-patterns/saving) for more information.
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved
- Radio groups must be labeled. The label may be visually hidden, but visible labels are preferred.

## Related components

- [FormControl](/components/FormControl): Used to group form controls with labels
- [Radio](/components/Radio): Individual radio button control
- [CheckboxGroup](/components/CheckboxGroup): For allowing multiple selections
- [SegmentedControl](/components/SegmentedControl): For immediate selection outside forms
joshfarrant marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading