All components (204)
Button
Actions · Button · .amset-button
What it is and when to use it
The usual button: it does something on the same screen (save, send, delete, open a dialog).
When to use it
- For an action. If what it does is take you to another page, it is a
ButtonLink: it opens in another tab and the screen reader says "link". - Only one
solidbutton per screen or per dialog: it is the main action. The rest,outline,softorghost. tone="error"for what deletes or cancels an account, better inside aConfirmAction.startIconandendIconto accompany the text;fullWidthto make it take the full width;shape="pill"for rounded corners.
When not to
- Icon only:
IconButton, which forces you to give it a name. - Several actions that weigh the same:
SplitButtonorActionMenu.
Keyboard: it is a native <button>: Tab reaches it; Enter and Space press it. With disabled it leaves the Tab order. With loading it stays focusable (it carries aria-disabled, not disabled), stops responding to clicks and announces the sending; with loadingText the sending text replaces the content, with no spinner.
Accessibility: the name is the text. Icons are decorative: they never carry information that is not in the text.
Fine-tuning: CSS variables --amset-button-*.
What it looks like
Last change 2 min ago.
<Button variant="solid" tone="accent" startIcon={<SaveIcon />} loading={guardando} loadingLabel="Saving" onPress={guardar}>
Guardar cambios
</Button>
<Button variant="outline" startIcon={<PlusIcon />}>New order</Button>
<Button variant="outline" endIcon={<DownloadIcon />}>Export</Button>
<Button variant="soft" tone="error" startIcon={<TrashIcon />}>Delete</Button>
<Button variant="ghost">Cancel</Button>
<Button variant="solid" disabled>Unavailable</Button>
<Button variant="solid" size="sm" shape="pill">Small and round</Button>
<ToggleButton label="Favourite" icon={<StarIcon />} defaultSelected variant="outline" />
<TextButton onPress={deshacer}>Undo</TextButton>Props
Import it with import { Button } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
childrenrequired | ReactNode | — |
className | string | — |
disabled | boolean | Out of play: it cannot be pressed, cannot be focused and is not in the tab order. |
endIcon | ReactNode | Icon after the text (an arrow, a menu chevron). |
excludeFromTabOrder | boolean | Out of the tab order but pressable. For a button that duplicates something already in it: the one that opens the list of a search field, which does nothing the down arrow does not. |
fullWidth | boolean | Takes up the whole available width. On mobile this is usually what you want. |
loading | boolean | Submitting state. The button stays focusable (`aria-disabled`), stops responding to presses and announces the change to the screen reader. It does not change width: the spinner goes over the text, not beside it. |
loadingLabel | string | What is announced while the sending lasts. |
loadingText | string | The text shown INSTEAD of the content while sending: "Saving…". No spinner on top: the text is the notice, and it is announced when it changes. It is what a front end did by swapping its `children` by hand. The button changes width if the new text is a different size. |
onClick | MouseEventHandler<HTMLButtonElement> | — |
onPress | PressHandler | — |
shape | "default" | "pill" | The shape: `default` (the default) or `pill`, with fully rounded corners. Inside a `ButtonGroup` only the outer corners of the group are rounded. For the round icon-only button, `IconButton`. |
size | "sm" | "md" | "lg" | — |
startIcon | ReactNode | Icon before the text. Decorative: the text is what counts. |
style | CSSProperties | Inline style. The stable look goes in the `--amset-button-*` CSS variables, which is what is maintained; this is for what is only known at run time: a colour chosen by whoever uses the application, a calculated position, a height that depends on the content. It used to be forbidden and had to be opened: a real front end used it on 40 buttons to calculate their halo from an arbitrary colour (AMS-735), and without it the only way out was to write CSS by hand against our classes. |
tone | "neutral" | "accent" | "secondary" | "tertiary" | "info" | "success" | "warning" | "error" | What it means. Without it, a solid or soft button is `accent` (the main action) and an outline or ghost one is `neutral`. `error` is the one for deleting or cancelling an account. |
variant | "solid" | "soft" | "outline" | "ghost" | How it is drawn: `solid`, `soft`, `outline` (default) or `ghost`. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-button-color | var(--amset-ink) |
--amset-button-ink | var(--amset-surface) |
--amset-button-soft | var(--amset-divider) |
--amset-button-text | var(--amset-ink) |
--amset-button-text-active | var(--amset-button-text) |
--amset-button-border | var(--amset-border-bold) |
--amset-button-height | var(--amset-height-control) |
--amset-button-padding | var(--amset-space-3) |
--amset-button-font | var(--amset-text-base) |
--amset-button-icon | 1rem |
--amset-button-radius | var(--amset-radius) |
--amset-button-weight | var(--amset-weight-bold) |
--amset-button-family | var(--amset-font) |
--amset-button-transform | none |
--amset-button-spacing | normal |
--amset-button-line | 1 |
--amset-button-gap | var(--amset-space-2) |
--amset-button-shadow | none |
--amset-button-background | transparent |
--amset-button-background-hover | var(--amset-button-background) |
--amset-button-background-active | var(--amset-button-background) |
How to change it
.amset-button {
--amset-button-color: ...;
--amset-button-ink: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
