Progress button
A button that shows its action is running, and then whether it worked.
A progress button is a button for actions that take a moment and finish in place: saving a setting, running a test, calling an action. While the action runs, it shows a spinner. When it is done, it briefly shows a check mark on a green button, or an alert icon on a red one. After two seconds, it returns to normal.
Use a progress button for:
- An action that takes a moment, where the result has nowhere else to show up, like Test connection or Restart
Don't use a progress button for:
- An action that opens a dialog or moves to another page. A regular button is enough.
- Showing an error people need to read. The red flash says that it failed, not why. Show the error as well, for example in an alert.
A progress button is a regular button with one extra layer:
- Button: the regular button, with its container, optional icon, and label
- Spinner: replaces the label while the action runs
- Result icon: on top of the button after the action, a check mark for success or an alert icon for an error
The progress button comes in the same appearances, variants, and sizes as a regular button, so it fits in next to one. During progress and while showing the result, it switches to the accent appearance.
- Resting: looks and behaves like a regular button with the same appearance, variant, and size.
- Progress: the button switches to the accent appearance and shows a spinner instead of its label. It ignores pointer input, so people can't start the action twice.
- Success: the button turns to the success variant, and a white check mark covers the faded label, for two seconds.
- Error: the button turns to the danger variant, and a white alert icon covers the faded label, for two seconds.
- Disabled: like a disabled regular button.
The success and error states can only be triggered from code, so they are not shown here.
The hover, focus, and pressed states are those of the button.
The sizes, spacing, and colors are those of the button. On top of that:
| Property | Value | Token |
|---|---|---|
| Appearance during progress and result | Accent | None |
| Variant on success | Success | --ha-color-fill-success-loud-resting |
| Variant on error | Danger | --ha-color-fill-danger-loud-resting |
| Result icon color | White | --white-color |
| Result icon size | 24px | None |
| Icon size in extra small and small | 16px | --mdc-icon-size |
| Result duration | 2 seconds | None |
- Keep labels short, and say what happens: Save, Restart, Test connection. See UI text.
- When the action can fail with an error people need to read, show that error as well, for example in an alert.
| Key | Action |
|---|---|
| Tab | Moves focus to the button, and away from it. A disabled button is skipped. |
| Enter or Space | Selects the button. Does nothing while it shows progress. |
The same as the button: 40px high at the default size.
The button is announced with its label, also while the result shows. During progress it is announced as busy. The success and error states only change the look: nothing is announced, so show an error people need to know about as text too.
- The role is
button, from the<ha-button>inside. - While the result icon shows, the label is faded out instead of hidden, so the button keeps its accessible name.
- During progress, the inner button has
aria-busy="true".
- Button: the regular button this one wraps
- Spinner: progress on its own
- Alert: showing an error people need to read
The element is <ha-progress-button>. It wraps <ha-button>. Set progress while the action runs, then call actionSuccess() or actionError() when it is done:
<ha-progress-button>Restart</ha-progress-button>private async _restart(ev) {
const button = ev.currentTarget;
button.progress = true;
try {
await doTheThing();
button.actionSuccess();
} catch (err) {
button.actionError();
} finally {
button.progress = false;
}
}While progress is set, the button ignores pointer input, so people can't start the action twice.
progress: shows the spinner. Reflected as an attribute.disabled: disables the button.appearance:accent(default),filled,outlined, orplain.variant:brand(default),neutral,success,warning, ordanger.size:xs,s,m(default),l, orxl.label: the label, used when the default slot is empty.
These can only be set as properties:
iconPath: SVG path data for an icon before the label.
- Default: the label.
actionSuccess(): shows the success state for two seconds.actionError(): shows the error state for two seconds.