---
title: Actions
description: Buttons, menu buttons and segmented controls, on native buttons and radio inputs.
---

## Button

<Demo id="button">
  <gw-button>Reboot</gw-button>
  <gw-button variant="neutral" appearance="filled">Plan boot</gw-button>
  <gw-button variant="neutral" appearance="plain">Cancel</gw-button>
  <gw-button disabled>Unavailable</gw-button>
</Demo>

`variant` picks the color and `appearance` how it's applied, from most to least important: accent (a solid fill, the default), filled (a soft tint), outlined (a stroke) or plain (text only). Every button is a pill. The six colors match the alert colors.

<Demo id="button-appearance" layout="stack">
  <gw-row>
    <gw-button variant="brand" appearance="accent">Brand</gw-button>
    <gw-button variant="neutral" appearance="accent">Neutral</gw-button>
    <gw-button variant="info" appearance="accent">Info</gw-button>
    <gw-button variant="success" appearance="accent">Success</gw-button>
    <gw-button variant="warning" appearance="accent">Warning</gw-button>
    <gw-button variant="danger" appearance="accent">Danger</gw-button>
  </gw-row>
  <gw-row>
    <gw-button variant="brand" appearance="filled">Brand</gw-button>
    <gw-button variant="neutral" appearance="filled">Neutral</gw-button>
    <gw-button variant="info" appearance="filled">Info</gw-button>
    <gw-button variant="success" appearance="filled">Success</gw-button>
    <gw-button variant="warning" appearance="filled">Warning</gw-button>
    <gw-button variant="danger" appearance="filled">Danger</gw-button>
  </gw-row>
  <gw-row>
    <gw-button variant="brand" appearance="outlined">Brand</gw-button>
    <gw-button variant="neutral" appearance="outlined">Neutral</gw-button>
    <gw-button variant="info" appearance="outlined">Info</gw-button>
    <gw-button variant="success" appearance="outlined">Success</gw-button>
    <gw-button variant="warning" appearance="outlined">Warning</gw-button>
    <gw-button variant="danger" appearance="outlined">Danger</gw-button>
  </gw-row>
  <gw-row>
    <gw-button variant="brand" appearance="plain">Brand</gw-button>
    <gw-button variant="neutral" appearance="plain">Neutral</gw-button>
    <gw-button variant="info" appearance="plain">Info</gw-button>
    <gw-button variant="success" appearance="plain">Success</gw-button>
    <gw-button variant="warning" appearance="plain">Warning</gw-button>
    <gw-button variant="danger" appearance="plain">Danger</gw-button>
  </gw-row>
</Demo>

A screen pairs them by importance: one accent button for the main action, with quieter ones beside it.

<Demo id="button-pairs">
  <gw-button variant="neutral" appearance="plain">Cancel</gw-button>
  <gw-button variant="danger">Remove backup</gw-button>
  <gw-button variant="info" appearance="outlined">Check for updates</gw-button>
  <gw-button variant="success" appearance="filled">Mark resolved</gw-button>
</Demo>

Icons are first class: most buttons have one, with text beside it. Set `icon` to SVG path data, such as one of `@mdi/js`'s. Where space is short, `labels="hide"` shows only the icon, and `labels="auto"` does so on narrow screens. The text stays as the button's accessible name and its tooltip.

<Demo id="button-icons">
  <gw-button icon="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z">Restart</gw-button>
  <gw-button variant="neutral" appearance="filled" icon="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z">Export</gw-button>
  <gw-button variant="danger" appearance="outlined" icon="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z">Remove</gw-button>
  <gw-button variant="neutral" appearance="plain" labels="hide" icon="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z">Settings</gw-button>
  <gw-button appearance="filled" labels="auto" icon="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z">Add device</gw-button>
</Demo>

Sizes scale everything together, from `xs` to `xl`, and `--gw-button-scale` sets any size in between or beyond:

<Demo id="button-sizes">
  <gw-button size="xs">Extra small</gw-button>
  <gw-button size="small" variant="neutral" appearance="filled">
    <svg slot="icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" /></svg>
    Export
  </gw-button>
  <gw-button>Medium</gw-button>
  <gw-button size="large" appearance="outlined" href="#button">Open as a link</gw-button>
  <gw-button size="xl">Extra large</gw-button>
  <gw-button style="--gw-button-scale: 2" appearance="filled">Scale 2</gw-button>
</Demo>

| Attribute | Values |
| --- | --- |
| `variant` | `brand` (default), `neutral`, `info`, `success`, `warning` or `danger` |
| `appearance` | `accent` (default), `filled`, `outlined` or `plain` |
| `size` | `xs`, `small`, `medium` (default), `large` or `xl`; or set `--gw-button-scale` |
| `type` | `button` (default), `submit` or `reset` |
| `href` | Renders a link that looks the same |
| `icon` | SVG path data for an icon before the text |
| `labels` | `show` (default), `hide` for the icon only, or `auto` to hide the text on narrow screens |
| `label` | An accessible name, when the text doesn't say enough |
| `disabled` | Disables it |

It renders a native `<button>`, or an `<a>` with `href`. Put an icon in the `icon` slot. Style the inner element with `::part(button)`.

## Menu button

<Demo id="menu-button">
  <gw-menu-button label="Power" items='[{"value":"sleep","label":"Sleep"},{"value":"restart","label":"Restart","description":"Back in about a minute"},{"value":"shutdown","label":"Shut down"}]'></gw-menu-button>
</Demo>

The menu opens on the Popover API, in the top layer, and closes on Esc or a click outside. Arrow keys, Home and End move between items and actions. Choosing one fires `select` with its `value`, closes the menu and puts focus back on the button.

Set `items` to `[{ "value", "label", "description", "icon", "disabled" }]`, as JSON or as a property. They render inside the component, so a page's own button styles can't reach them.

Contextual actions, such as "Add", go in `actions`, in the same shape. They stay below the items as the list scrolls, rather than sitting at the end of it, so they're found straight away, and there can be several. With no items, the menu says so (`empty`) above them.

<Demo id="menu-actions">
  <gw-menu-button label="Backup" items='[{"value":"daily","label":"Daily, 03:00"},{"value":"weekly","label":"Weekly, Sunday"},{"value":"before-update","label":"Before each update"}]' actions='[{"value":"add","label":"Add a schedule"},{"value":"import","label":"Import from a file"}]'></gw-menu-button>
  <gw-menu-button label="Tags" empty="No tags yet" actions='[{"value":"add-tag","label":"Add a tag"}]'></gw-menu-button>
</Demo>

## Segmented control

<Demo id="segmented">
  <gw-segmented label="View" value="dashboard" options='[{"value":"dashboard","label":"Dashboard"},{"value":"json","label":"JSON"},{"value":"history","label":"History"}]'></gw-segmented>
</Demo>

| Attribute | Values |
| --- | --- |
| `label` | Names the group for assistive technology |
| `value` | The picked option |
| `options` | JSON: `[{ "value", "label" }]`, or set the property |
| `name` | The form field name; one is made up if left out |

It's a `<fieldset>` of native radio buttons, so arrow keys move the choice and a form submits it. It fires `change`.

Options can carry an icon as path data. `labels="auto"` shows the text on wide screens and only the icons on narrow ones, `hide` always shows icons only, and either way the text stays as the tooltip and the accessible name:

<Demo id="segmented-icons">
  <gw-segmented label="Mode" labels="auto" value="dark" options='[{"value":"light","label":"Light","icon":"M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.65,5.15 12.84,5 12,5C11.16,5 10.35,5.15 9.61,5.42L12,2M3.34,7L7.5,6.65C6.9,7.16 6.36,7.78 5.94,8.5C5.5,9.24 5.25,10 5.11,10.79L3.34,7M3.36,17L5.12,13.23C5.26,14 5.53,14.78 5.95,15.5C6.37,16.24 6.91,16.86 7.5,17.37L3.36,17M20.65,7L18.88,10.79C18.74,10 18.47,9.23 18.05,8.5C17.63,7.78 17.1,7.15 16.5,6.64L20.65,7M20.64,17L16.5,17.36C17.09,16.85 17.62,16.22 18.04,15.5C18.46,14.77 18.73,14 18.87,13.21L20.64,17M12,22L9.59,18.56C10.33,18.83 11.14,19 12,19C12.82,19 13.63,18.83 14.37,18.56L12,22Z"},{"value":"dark","label":"Dark","icon":"M2 12A10 10 0 0 0 15 21.54A10 10 0 0 1 15 2.46A10 10 0 0 0 2 12Z"},{"value":"darker","label":"Darker","icon":"M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z"}]'></gw-segmented>
  <gw-segmented label="Mode, icons only" labels="hide" value="light" options='[{"value":"light","label":"Light","icon":"M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.65,5.15 12.84,5 12,5C11.16,5 10.35,5.15 9.61,5.42L12,2M3.34,7L7.5,6.65C6.9,7.16 6.36,7.78 5.94,8.5C5.5,9.24 5.25,10 5.11,10.79L3.34,7M3.36,17L5.12,13.23C5.26,14 5.53,14.78 5.95,15.5C6.37,16.24 6.91,16.86 7.5,17.37L3.36,17M20.65,7L18.88,10.79C18.74,10 18.47,9.23 18.05,8.5C17.63,7.78 17.1,7.15 16.5,6.64L20.65,7M20.64,17L16.5,17.36C17.09,16.85 17.62,16.22 18.04,15.5C18.46,14.77 18.73,14 18.87,13.21L20.64,17M12,22L9.59,18.56C10.33,18.83 11.14,19 12,19C12.82,19 13.63,18.83 14.37,18.56L12,22Z"},{"value":"dark","label":"Dark","icon":"M2 12A10 10 0 0 0 15 21.54A10 10 0 0 1 15 2.46A10 10 0 0 0 2 12Z"},{"value":"darker","label":"Darker","icon":"M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z"}]'></gw-segmented>
</Demo>

## References

- Home Assistant: [Button](https://contributors.home-assistant.io/design/components/button/), [Dropdown](https://contributors.home-assistant.io/design/components/dropdown/) · Code: [button](https://github.com/home-assistant/frontend/blob/dev/src/components/ha-button.ts), [dropdown](https://github.com/home-assistant/frontend/blob/dev/src/components/ha-dropdown.ts), [toggle group](https://github.com/home-assistant/frontend/blob/dev/src/components/ha-button-toggle-group.ts)
- Web Awesome: [Button](https://webawesome.com/docs/components/button), [Dropdown](https://webawesome.com/docs/components/dropdown), [Radio group](https://webawesome.com/docs/components/radio-group) · Code: [button](https://github.com/shoelace-style/webawesome/tree/next/packages/webawesome/src/components/button), [dropdown](https://github.com/shoelace-style/webawesome/tree/next/packages/webawesome/src/components/dropdown), [radio group](https://github.com/shoelace-style/webawesome/tree/next/packages/webawesome/src/components/radio-group)
- Primer: [Button](https://primer.style/product/components/button/), [Action menu](https://primer.style/product/components/action-menu/), [Segmented control](https://primer.style/product/components/segmented-control/) · Code: [Button](https://github.com/primer/react/tree/main/packages/react/src/Button), [ActionMenu](https://github.com/primer/react/tree/main/packages/react/src/ActionMenu), [SegmentedControl](https://github.com/primer/react/tree/main/packages/react/src/SegmentedControl)
