Skip to content

Commit

Permalink
Adds guidelines about inactive buttons (#627)
Browse files Browse the repository at this point in the history
* adds guidelines about inactive buttons

* adds link to internal a11y guidance

* add guidance about informing users about the cause of a button being inactive

* updates inactive button guidance per a11y feedback
  • Loading branch information
mperrotti authored Nov 13, 2023
1 parent 39d3eb3 commit 20316c9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 39 deletions.
2 changes: 1 addition & 1 deletion content/components/action-menu.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ Here is an overview of [action list](/components/action-menu) items that are com
<img
width="960"
alt="Three examples: 1. An action menu that works just fine; 2. An action menu with some items disabled; 3. An action menu with all items disabled"
src="https://github.com/primer/design/assets/2313998/69e24a92-e5b7-42d9-857c-63d58cfda026"
src="https://github.com/primer/design/assets/2313998/c49774be-9bf3-4e93-8537-5810d3f5579a"
/>

If items in a menu have been affected by a system error such as an outage, they may be put into an inactive state with a message in each item explaining why it's disabled.
Expand Down
64 changes: 63 additions & 1 deletion content/components/button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Buttons allow users to initiate an action or command when clicked or tapped. The
</Box>
</Box>

### Color
### Variants

<Box
mb={3}
Expand Down Expand Up @@ -234,6 +234,62 @@ Buttons allow users to initiate an action or command when clicked or tapped. The
</Box>
</Box>

### Inactive

<Box
mb={3}
display="flex"
alignItems="flex-start"
justifyContent="space-between"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 3}}
>

<img
width="456"
alt="An button that looks like a disabled primary button, but it has a focus state"
src="https://github.com/primer/design/assets/2313998/167f846f-0a86-4f04-bac3-4af9843e8933"
/>

<div>

An inactive button has styles that make the button appear "muted". The style is the same for all button variants.

An inactive button an accessible alternative to a disabled button. They're intended to be used for buttons that are non-functional, but cannot be removed from the page.

Unlike a disabled button, an inactive button can respond to user input. For example, if a button shows a tooltip when hovered or focused, or a dialog when clicked.

If you need to use an inactive button, it's best to have something else on the page that informs users about the issue that broke the button's normal functionality. For example, showing a [global banner](/ui-patterns/degraded-experiences#global-system-notification) for service outages.

</div>

</Box>

<Box
display="flex"
alignItems="flex-start"
justifyContent="space-between"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 3}}
>

<CustomVideoPlayer
width="456"
loop
src="https://github.com/primer/design/assets/2313998/b74267b7-3c7b-4343-88f8-fdfe6d076e31"
/>

<Box sx={{flexBasis: 0, flexGrow: 1}}>

There are two recommended ways an inactive button should respond to user input:

1. **Show a dialog on click:** When a user tries to activate an inactive the button, open a [dialog](/components/dialog) that explains why the action cannot be completed and give them a path forward if possible. It is required to provide some kind of feedback when a user clicks a button.
2. **Show a tooltip on hover or focus:** Before a user tries to activate a non-functional control, a [tooltip](/components/tooltip) with additional context may be displayed on hover or focus. It is *not* required to respond to hover and focus.

</Box>

</Box>

## Best practices

### Primary and outline button usage
Expand Down Expand Up @@ -349,6 +405,12 @@ Limit primary button usage. Only use one primary button on the page, whenever po

## Accessibility

### Do not disable buttons

There are rare cases where it's ok to disable a button, but it should generally be avoided. Disabling a button makes it invisible to assistive technologies such as screen readers.

For more information on disabled controls, see GitHub's [link and button a11y guidance](https://accessibility-playbook.github.com/link-and-button-guidance#disabling-links-and-buttons) (GitHub staff only).

### Descriptive buttons

Labeling buttons properly lets users know what will happen when they activate the control, lessens errors, and increases confidence.
Expand Down
40 changes: 4 additions & 36 deletions content/ui-patterns/degraded-experiences.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ Common types of page navigation include [underline nav](/components/underline-na

<img
width="960"
alt="Decision tree for how to handle a non-functional button. Could removing the button be disorienting? If no, don't render the button. If yes: does it respond to a hover or click? If yes, use an inert button. If no, use a disabled button."
src="https://github.com/primer/design/assets/2313998/4f93c6ef-0f0f-427b-b81c-2fdac957c9b3"
alt="Decision tree for how to handle a non-functional button. Could removing the button be disorienting? If no, don't render the button. If yes: does it respond to a hover or click? If yes, use an inactive button. If no, use a disabled button."
src="https://github.com/primer/react/assets/2313998/89a15946-ecc8-498b-a9e1-4802c3bc49b1"
/>

#### Removing a non-functional button
Expand Down Expand Up @@ -303,41 +303,9 @@ Default to removing non-functional buttons from the UI. Don't remove buttons tha

#### Indicating a button is non-functional without disabling it

<Box
mb={3}
display="flex"
alignItems="flex-start"
justifyContent="space-between"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 3}}
>

<div>

If a button is too critical to be omitted and responds to user input by showing more info about why it's non-functional, use an inert button. An inert button has the same styles as a disabled button, but it still reponds to user input.

An inert button is the accessible option because buttons may not be disabled if they respond to user input. For example, if a button shows a tooltip when hovered or focused, or a dialog when clicked.
If a button is too critical to be omitted and responds to user input by showing more info about why it's non-functional, use an inactive button.

</div>

<img
width="456"
alt="A default button and an inert button"
src="https://github.com/primer/design/assets/2313998/fd1a7c99-b8c3-43fd-9f74-ae509e9efa31"
/>

</Box>

There are two recommended ways an inert button should respond to user input:

1. **Show a dialog on click:** When a user tries to activate an inert the button, open a [dialog](/components/dialog) that explains why the action cannot be completed and give them a path forward if possible. It is required to provide some kind of feedback when a user clicks a button.
2. **Show a tooltip on hover or focus:** Before a user tries to activate a non-functional control, a [tooltip](/components/tooltip) with additional context may be displayed on hover or focus. It is *not* required to respond to hover and focus.

<CustomVideoPlayer
width="960"
loop
src="https://github.com/primer/design/assets/2313998/f7837087-a6ff-4572-9ef6-d5dfad158b88"
/>
For more information, see the the [inactive button guidelines](/components/button#inactive)

### Handling action lists and menus with non-functional items

Expand Down
2 changes: 1 addition & 1 deletion content/ui-patterns/loading.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ If non-sequential groups of navigation links are in a loading state, preserve th
src="https://github.com/primer/design/assets/2313998/3ab14657-8ab3-45e4-b47a-ef9eee76da4b"
/>

If some links in the right side sheet cannot be loaded, default to showing each [nav list](components/nav-list) item in an inert state. The users should still be able to hover, click, and focus inert items, but they don't link to anywhere. Optionally, a tooltip may be displayed explaining that the navigation item is unavailable. An error banner is not necessary for this case.
If some links in the right side sheet cannot be loaded, default to showing each [nav list](components/nav-list) item in an inactive state. The users should still be able to hover, click, and focus inactive items, but they don't link to anywhere. Optionally, a tooltip may be displayed explaining that the navigation item is unavailable. An error banner is not necessary for this case.

<Box
mb={3}
Expand Down

0 comments on commit 20316c9

Please sign in to comment.