Button
The <Button>
component is a crucial components of any user interface, allowing users to initiate actions such as submitting forms, adding items to a cart, or opening dialogs. The label on a button indicates the action that will be taken when the user presses it.
Different types of buttons, such as primary and secondary, help guide users by visually prioritizing actions. Primary buttons are typically used for the most important actions, while secondary buttons provide less critical options.
Anatomy
A button consists of a pressable area, often containing a textual label or icon, which users can press or activate using the Space or Enter keys.

Appearance
The appearance of a component can be customized using the variant
and size
props. These props adjust the visual style and dimensions of the component, available values are based on the active theme.
Property | Type | Description |
---|---|---|
variant | primary | secondary | destructive | ghost | text | The available variants of this component. |
size | default | small | large | icon | The available sizes of this component. |
The core theme does not include a "secondary" button. In the demo above, this variant will default to a regular button without any additional styling.
Usage
Buttons have a wide range of applications. Their most common usage is to submit forms, but they are also used for other actions like opening a <Menu>
or <Dialog>
.
It is essential that the label and context around the button clearly set expectations for what will happen when the user interacts with it. In user interfaces, buttons guide interactions, providing clear call-to-action elements that help users navigate and complete tasks.
Write button text that is clear, starts with a verb, and helps users confidently take action.
Visual hierarchy
This primary button should represent the most crucial action within that section. Having multiple primary buttons in one section can create confusion and visual clutter, as they compete for the user's attention and detract from the clarity of the intended action.

Use one primary button per page or section to highlight the most important action

Don't include multiple primary buttons in the same section to prevent confusion and visual clutter.
Icons and labels
Icons can reinforce text labels, but they can also cause confusion if they don't clearly match the related text. Buttons should always have a label unless they use an icon that is universally understood and accessible.
Accompany labels with icons only when they have a strong association with the text, never use icon purely for decoration.
Icon-only buttons should only be used when the icon is universally recognized and its function is clear without additional text, like a pencil for editing. These buttons are particularly useful in compact spaces or mobile interfaces where screen real estate is limited.
For icon-only buttons, ensure you set an aria-label
or aria-labelledby
attribute to provide context and maintain accessibility.

Use icons in buttons to provide additional clarity when the icon is highly relevant to the action.

Icons should not be used for decoration.
Avoid disabled buttons
A disabled button can't be actioned. Keep buttons active and use validation and error messages to guide users on what needs to be done to proceed.
Disabled buttons are problematic as they offer no feedback on why an action is unavailable, are often hard to see due to low contrast, and are inaccessible to keyboard users who cannot focus on them.

Use validation and error messages to guide users on the necessary steps.

Don't disable form submission buttons, as this doesn't clearly guide users on how to proceed.
In general, it's best to avoid using disabled buttons. However, if they are necessary, take steps to make them more inclusive. Ensure users don't get stuck by providing additional information. Place a message near the disabled button that explains why it is unavailable and what actions are needed to enable it.
Never put tooltips on disabled buttons
Tooltips aren't accessible on all devices or by some assistive technologies, and they should never be used on non-interactive elements. For more information see the tooltip page.
Loading state
The <Button>
component includes a loading
property that can be used to display loading behavior. This visually indicates the progress of system operations, such as downloading, uploading, or processing tasks. The loading spinner always shows an indeterminate progress to signify that the duration of the operation is unknown.
This functionality is especially useful when performing actions like submitting a form or saving changes in your application that require time to complete a request. While the button is in the loading state, it becomes disabled, preventing further interaction until the operation is completed.
The button's label should clearly describe the action being performed, providing context for the current state of the process, like also mentioned in Icons and labels.
When the loading state is activated, the label becomes hidden. To ensure accessibility, we provide the loading state with an aria-label
and aria-busy
.
The loading
property must be added manually to a Button, and is intended for processes that typically last more than 1 second.
Full-width
Full-width buttons are especially useful for emphasizing primary actions like submitting a form or completing a purchase, as they attract attention and create a strong visual hierarchy. They also enhance usability on mobile devices or in narrow layouts by providing a larger, easier-to-tap target.
Button or link
If the user interacts with the element and it results in navigation to another page without submitting a form, use an anchor element (<Link>
). For all other interactions that perform actions on the same page, use a button (<Button>
).
Understanding this distinction is crucial: anchors handle navigation, while buttons handle page-specific actions. Misusing them can cause accessibility and usability issues, as anchors support tab-opening and navigation, while buttons do not.
To visually imitate a button element that navigates (e.g., a "Cancel" action that redirects users to the previous page), use the <Link>
component with the corresponding variant
, usually secondary
. This way, the action is clear and prominent while keeping its navigation function.
Use buttons to trigger an event or an action.
Don't use buttons for navigation purposes.
Press Event
The <Button>
component supports user interactions via mouse, keyboard, and touch, handled through the onPress
prop. This prop is similar to the standard onClick
event but is normalized for all interaction methods. Additionally, onPressStart
, onPressEnd
, and onPressChange
events are fired during user interaction.
Each handler receives a PressEvent
, providing details about the target and the type of event that triggered the interaction, like the pointer (mouse, keyboard or touch) that was used.
Props
aria-controls?
string;
aria-current?
boolean | "true" | "false" | "page" | "step" | "location" | "date" | "time";
aria-describedby?
string;
aria-details?
string;
aria-expanded?
boolean | "true" | "false";
aria-haspopup?
boolean | "true" | "false" | "menu" | "listbox" | "tree" | "grid" | "dialog";
aria-label?
string;
aria-labelledby?
string;
aria-pressed?
boolean | "true" | "false" | "mixed";
autoFocus?
boolean;
children?
ReactNode;
className?
string;
disabled?
boolean;
"false"
excludeFromTabOrder?
boolean;
form?
string;
<form>
element to associate the button with.
The value of this attribute must be the id of a <form>
in the same document.formAction?
string;
formEncType?
string;
formMethod?
string;
formNoValidate?
boolean;
formTarget?
string;
fullWidth?
boolean;
"false"
id?
string;
loading?
boolean;
name?
string;
onBlur?
(e: FocusEvent<Element, Element>) => void;
onClick?
(e: MouseEvent<FocusableElement, MouseEvent>) => void;
onPress
instead. onClick
is an alias for onPress
provided for compatibility with other libraries. onPress
provides
additional event details for non-mouse interactions.onFocus?
(e: FocusEvent<Element, Element>) => void;
onFocusChange?
(isFocused: boolean) => void;
onHoverChange?
(isHovering: boolean) => void;
onHoverEnd?
(e: HoverEvent) => void;
onHoverStart?
(e: HoverEvent) => void;
onKeyDown?
(e: KeyboardEvent) => void;
onKeyUp?
(e: KeyboardEvent) => void;
onPress?
(e: PressEvent) => void;
onPressChange?
(isPressed: boolean) => void;
onPressEnd?
(e: PressEvent) => void;
onPressStart?
(e: PressEvent) => void;
onPressUp?
(e: PressEvent) => void;
preventFocusOnPress?
boolean;
ref?
Ref<HTMLButtonElement>;
ref.current
to null
(or call the ref with null
if you passed a callback ref).
@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}slot?
string | null;
null
value indicates that the local props completely override all props received from a parent.type?
"button" | "submit" | "reset";
'button'
value?
string;
Alternative components
- Link: A component to navigate to another page.