Skip to content

Button

Button is an interactive UI element for users to trigger a response.
Figma logo

Buttons come in three primary variants: primary, secondary, and tertiary.

  • Each page should contain only one primary CTA
  • Secondary buttons are the default as they are more common
  • Tertiary buttons do not contain a visible outline, but a background appears on hover; they provide the user with a larger tap target than buttons styled as links

Buttons come in three sizes: small, medium, and large.

Buttons come in three themes: primary (kale), error, and neutral. The neutral theme can be used when you need to provide a more subtle call to action.

Buttons can visually represent themselves as a link. This visual representation is used when the action needs to be in line with other text.

This visual variant does not impact the HTML structure; assistive technologies will still recognize it as a button. Use the Link component if you are navigating to a new URL.

Tertiary buttons are not outlined and can be aligned to text above and below.

Disabled states are available but are strongly discouraged. Learn about alternative approaches to disabling buttons.

The loading prop can be used to display the button in a loading state. See SubmitButton for a more realistic implementation.

Icons can be added using the before and after props.

React props
NameTypeDefaultDescription
after  
ReactNode
-Content shown after children.
before  
ReactNode
-Content shown before the children.
children  
ReactNode
-The content of the Link.
color  
errorprimary
primaryBackground and foreground colors.
edge  
endstart
-Aligns the visual edge of a button along a specified side. For example, edge="start" aligns the text of a tertiary button to align with content above and below on the left side.
getLoadingText  
(() => string)
-Determines the screen reader accessible text to be displayed when the button is in the loading state.
loading  
boolean
-If true, a loading indicator will be shown. See SubmitButton for a ready-made component.
size  
smallmediumlarge
largeThe size of the button when variant is set to "primary" or "secondary".
variant  
linkprimarysecondarytertiary
secondaryDetermines the shape of the element (button or text link).
  • Consider using the getLoadingText prop to update the button text for screen readers when the button is in a loading state.
  • Avoid using the disabled attribute as this is confusing to users whether or not they are using assistive technologies.
  • Our color palette was chosen to meet our standards for color contrast ratio.

The following testing snippet(s) offer suggestions for testing the component using React Testing LibraryExternal link with occasional help from JestExternal link.

render(<Button>Save</Button>);
const button = screen.getByRole('button', {
name: 'Save',
});
expect(button).not.toBeDisabled();
userEvent.click(button);
// Testing loading
const onClick = jest.fn();
render(
<Button loading onClick={onClick}>
Save
</Button>,
);
const button = screen.getByRole('button', {
name: /Save/,
});
userEvent.click(button);
expect(button).toBeDisabled();
expect(onClick).not.toHaveBeenCalled();
expect(button).toHaveTextContent('Loading…');