Button
A labelled control for actions in an interface.
Button triggers an action, such as saving a form, opening a dialog, or deleting an item. Use
Link when the interaction takes someone to another URL or route.
Best practices
| Guidance | Practices |
|---|---|
| Do | Use Button for an action, such as saving, submitting, or opening a dialog. |
| Do | Use Link with an href when the interaction navigates to another URL or route. |
| Don't | Navigate from a Button. It loses native link semantics and browser link behaviours. |
Size
medium is the default size. Use small in dense toolbars, tables, and other compact interfaces.
Keep related controls at the same size.
Appearance
button is the default appearance. It has control sizing, truncates its label, and supports content
slots. Set appearance="text" when an action should use text-link presentation. Text Buttons wrap
and do not support a size, block layout, or content slots.
Tone
neutral is the default tone for ordinary actions. Set tone="critical" for destructive actions.
Prominence
standard is the default. Choose low for quiet secondary actions and high for the primary
action in a group. For ordinary actions, high prominence uses the theme’s primary accent treatment.
Presentation reference
Block layout
Set isBlock when the button should fill the inline size of its container. A typical case is a
primary action at the end of a narrow form or panel.
Content slots
Use startContent or endContent for non-interactive adornments beside the label, such as an icon,
badge, count, or keyboard hint. Nested interactive controls are unsupported. Button sizes nested
icons for you, so an Icon needs no size prop. Pass one only to override it. Use
IconButton only when the icon is familiar without a text label.
Pending and Actions
onPress handles the interaction. pressAction performs the resulting operation. When both are
set, onPress runs first, then pressAction.
Prefer a native form Action when the operation is a form submission. Pass the form’s pending state
to Button. This example uses React’s
useActionState.
Use pressAction for Button-owned operations that are not form submissions. Combining pressAction
with type="submit" is usually the wrong pattern, because both paths may run.
pressAction creates pending state automatically. Explicit isPending shows a spinner immediately.
An Action-owned spinner waits briefly so a fast Action never flashes one.
Set isPending for externally owned pending state, such as a parent mutation or router transition.
Pending buttons stay focusable and ignore further presses.
Unexpected failures from pressAction use React’s normal Action and Error Boundary behaviour.
Handle expected domain errors inside the Action.
Disabled
Set isDisabled only when the action is unavailable. Disabled buttons cannot receive focus or
respond to presses.
Accessibility
The visible label provides the accessible name, so most buttons do not need aria-label. Write a
label that describes the action, such as “Save changes” or “Delete account”, rather than a vague
label such as “OK”.
The spinner is hidden from assistive technology. Pending state is announced through the button’s pending semantics, so the label does not need to change while pending.
API
ButtonProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.
Prop
Type