Skip to main content

Button

Used to trigger an action or event, such as submitting a form, opening a dialog, cancelling an action, or performing a delete operation.

Submit feedback
github

Migration Information

For teams migrating from the V1 to V2 component, please refer to the migration guide for changes to the component.
Component Guide
import { Button } from '@uhg-abyss/web/ui/Button';
<Button>Click Here!</Button>

Size

Use the size prop to change the size of the button. The default is set to 'md'. The size prop can take in the Abyss standardized 'sm', 'md', and 'lg'.

Button colors and variants

Button provides distinct visual styles through separate color and variant props:

  • Use the variant prop to specify the button style category: filled, outline, or text.
  • Use the color prop to indicate color and purpose: brand (primary actions), neutral (secondary actions), destructive (dangerous actions), or inverse (on dark backgrounds).

By default, brand color and filled variant are enabled.

Icons

To insert an IconSymbol into the Button, use the icon props. This prop accepts an object of the following type:

{
icon: string;
position: 'leading' | 'trailing' | 'icon-only';
variant?: 'filled' | 'outlined';
}
  • icon: The name of the icon to display.
  • position: The position of the icon relative to the button text.
  • variant: The variant of the icon.

Icon-only

Buttons can also be created without any text by providing an icon with position 'icon-only'. This button can be used with any of the available variants.

Note: The child text of the button will be visually hidden, but will remain accessible for screen readers.

Using the useForm hook lets the DOM handle form data.

useState

Using the useState hook gets values from the component state.

Href

If the href prop is present, the button will render as an HTML anchor (<a>) and navigate to the given href when clicked. For an accessible and user-friendly site, it is recommended to use buttons only for executing actions and using Links instead for navigating to other pages.

Additionally, you can set the openNewWindow prop to true if you want the link to open in a new window. Note: The icon prop will be overridden with a trailing icon indicating the link opens in a new window.

Disabled

Use the isDisabled prop to disable the button.

Note: It is recommended that screen readers be provided a reason for a button being in a disabled state. For example, if a form submit button is disabled because all fields must have valid inputs before the user is allowed to submit the form, it is helpful to convey this information so the user understands why the button is disabled. As shown in the example below, this can be achieved using the aria-describedby attribute and the VisuallyHidden component to point to off-screen content that conveys the reason for the disabled state.

Loading

Note: isDisabled takes precedence over isLoading. If both props are passed, the button will be disabled and the loading spinner will not be shown.

A UI concept which merges the loading spinner indicator into the action that invokes it. Primarily intended for use with forms where it gives users immediate feedback upon pressing submit.

The use of the ariaLoadingLabel prop is highly encouraged for accessibility standards. Be as descriptive as possible when coming up with a description. Common labels are 'Submitting Form', 'Downloading Files', 'Content is loading', etc.

When button is passed the ariaLoadingLabel prop, it also takes in the isLoading attribute to dynamically toggle the Loading Spinner to populate after the text within button.

<Button isLoading={true} ariaLoadingLabel="Downloading Files">
Submit
</Button>

With this feature, the accessibility of spinner changes so when being read by a screen reader, the live region of the button will be read. Visit the LoadingSpinner documentation to learn more about this accessibility feature.

Button Props

NameTypeDefaultRequiredDescription
ariaLoadingLabel
string
--
Screen reader text describing the loading state of the Button; only used if isLoading is true
children
React.ReactNode
--
The contents of the button component
className
string
--
CSS class name to apply to each element within the component
color
"brand" | "neutral" | "inverse" | "destructive"
'brand'
-
The color of the Button
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
href
string
--
The href to navigate to
icon
{ icon: string; position: "leading" | "trailing" | "icon-only"; variant?: "filled" | "outlined" | undefined; }
--
The IconSymbol to insert into the Button
isActive
boolean
--
If true, the Link is considered the active route
isDisabled
boolean
false
-
If true, the Button is disabled
isLoading
boolean
false
-
If true, the Button will be in a loading state; ariaLoadingLabel is required when using this prop
isStandardAnchor
boolean
false
-
If true, ignore router and external Link checks
onClick
(event: React.MouseEvent<HTMLElement, MouseEvent>) => void
--
Callback function executed when the Button is clicked
openNewWindow
boolean
false
-
If true, the Link opens in a new window. By default, external links will open in a new window.
routerComponent
React.ComponentType<any>
--
Custom router component to use for client-side navigation
(e.g., Next.js Link, Gatsby Link, etc.)
size
"sm" | "$sm" | "md" | "$md" | "lg" | "$lg"
'md'
-
The size of the Button
variant
"text" | "filled" | "outline"
'filled'
-
The variant of the Button

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

Button Classes

Class NameDescription
.abyss-button-rootButton root element
.abyss-button-content-containerContent container element
.abyss-button-leading-iconIconSymbol placed before the button content
.abyss-button-new-window-iconIcon for new window anchor buttons
.abyss-button-trailing-iconIconSymbol placed after the button content
.abyss-button-icon-only-iconIconSymbol placed as the button content (icon-only position)
.abyss-button-loading-spinnerLoadingSpinner placed inside the button when `isLoading` is true
.abyss-button-activeButton root element when active

A button is a widget that enables users to trigger an action or event, such as submitting a form, opening a dialog, canceling an action, or performing a delete operation. A common convention for informing users that a button launches a dialog is to append "…" (ellipsis) to the button label, e.g., "Save as…".

Adheres to the Button WAI-ARIA design pattern.

<Button>Click Here!</Button>

Keyboard Interactions

KeyDescription
SpaceActivates the button
EnterActivates the button

Disabled Accessibility Guidance

It is recommended that a screen reader be provided with a reason for a button being in a disabled state. For example if a form submit button is disabled because all fields must have valid inputs before the user is allowed to submit the form, it can be helpful to convey this information, so the user understands why the button is disabled. Target the disabled button state with the prop isDisabled, and use the aria-describedby attribute and the VisuallyHidden component to point to off-screen content that conveys the reason for the disabled state.

Loading State Button

For a loading state, button pulls in the Loading Spinner component and renders a status message to convey the action of loading without taking focus.

Loading Spinner is programmed through the ariaLoadingLabel property, and has been tested using a screen reader to present a status message to assistive technology without receiving focus.

Following the requirements of WAI-ARIA, Loading Spinner follows the requirements 4.1.3: Status Messages. Status messages are defined by WCAG as messages that provide information on the success or results of a user action, but do not change the users context (i.e. take focus).

The Toggle Loading button below can be used to toggle the loading state of the Submit button for screen readers.

Triggering Elements

Use the aria-haspopup attribute on buttons or other triggering elements that open content like dialogs, listboxes, trees, menus, grids, etc. Use a corresponding value that indicates what kind of popup will be displayed when the trigger element is activated. In turn, the element that pops up must be of the role indicated. For example, use aria-haspopup="dialog" on buttons that open modal dialogs. Be sure to include role="dialog" on the containing element of the dialog itself, too.

See the docs on aria-haspopup for more details.

Component Tokens

Note: Click on the token row to copy the token to your clipboard.

Button Tokens

Token NameValue
button.color.text.label.filled-brand
#FFFFFF
button.color.text.label.filled-disabled
#7D7F81
button.color.text.label.filled-neutral
#FFFFFF
button.color.text.label.filled-destructive
#FFFFFF
button.color.text.label.filled-inverse
#323334
button.color.text.label.outline-brand
#002677
button.color.text.label.outline-disabled
#7D7F81
button.color.text.label.outline-neutral
#323334
button.color.text.label.outline-destructive
#990000
button.color.text.label.outline-inverse.rest
#FFFFFF
button.color.text.label.outline-inverse.hover
#F3F3F3
button.color.text.label.outline-inverse.active
#E5E5E6
button.color.text.label.text-brand.rest
#196ECF
button.color.text.label.text-brand.hover
#004BA0
button.color.text.label.text-brand.active
#002677
button.color.text.label.text-disabled
#7D7F81
button.color.text.label.text-neutral.rest
#323334
button.color.text.label.text-neutral.hover
#222324
button.color.text.label.text-neutral.active
#000000
button.color.text.label.text-destructive.rest
#990000
button.color.text.label.text-destructive.hover
#B20000
button.color.text.label.text-destructive.active
#890000
button.color.text.label.text-inverse.rest
#FFFFFF
button.color.text.label.text-inverse.hover
#F3F3F3
button.color.text.label.text-inverse.active
#E5E5E6
button.color.surface.container.filled-brand.rest
#002677
button.color.surface.container.filled-brand.hover
#004BA0
button.color.surface.container.filled-brand.active
#00184D
button.color.surface.container.filled-neutral.rest
#323334
button.color.surface.container.filled-neutral.hover
#222324
button.color.surface.container.filled-neutral.active
#000000
button.color.surface.container.filled-destructive.rest
#990000
button.color.surface.container.filled-destructive.hover
#B20000
button.color.surface.container.filled-destructive.active
#990000
button.color.surface.container.filled-inverse.rest
#FFFFFF
button.color.surface.container.filled-inverse.hover
#F3F3F3
button.color.surface.container.filled-inverse.active
#E5E5E6
button.color.surface.container.outline-brand.rest
#FFFFFF
button.color.surface.container.outline-brand.hover
#EDF3FB
button.color.surface.container.outline-brand.active
#E3EEFA
button.color.surface.container.outline-neutral.rest
#FFFFFF
button.color.surface.container.outline-neutral.hover
#FAF8F2
button.color.surface.container.outline-neutral.active
#F5F3ED
button.color.surface.container.outline-destructive.rest
#FFFFFF
button.color.surface.container.outline-destructive.hover
#FCF0F0
button.color.surface.container.outline-destructive.active
#F9D1D1
button.color.surface.container.filled-disabled
#F3F3F3
button.color.surface.container.outline-disabled
#F3F3F3
button.color.surface.loading-spinner.text-brand
#196ECF
button.color.surface.loading-spinner.outline-neutral
#4B4D4F
button.color.surface.loading-spinner.text-neutral
#4B4D4F
button.color.surface.loading-spinner.outline-destructive
#990000
button.color.surface.loading-spinner.text-destructive
#990000
button.color.surface.loading-spinner.filled-inverse
#4B4D4F
button.color.border.outline-brand
#002677
button.color.border.outline-disabled
#7D7F81
button.color.border.outline-neutral
#323334
button.color.border.outline-destructive
#990000
button.color.border.outline-inverse.rest
#FFFFFF
button.color.border.outline-inverse.hover
#F3F3F3
button.color.border.outline-inverse.active
#E5E5E6
button.color.icon.filled-brand
#FFFFFF
button.color.icon.filled-disabled
#7D7F81
button.color.icon.filled-neutral
#FFFFFF
button.color.icon.filled-destructive
#FFFFFF
button.color.icon.filled-inverse
#323334
button.color.icon.outline-brand
#002677
button.color.icon.outline-disabled
#7D7F81
button.color.icon.outline-neutral
#323334
button.color.icon.outline-destructive
#990000
button.color.icon.outline-inverse.rest
#FFFFFF
button.color.icon.outline-inverse.hover
#F3F3F3
button.color.icon.outline-inverse.active
#E5E5E6
button.color.icon.text-brand.rest
#196ECF
button.color.icon.text-brand.hover
#004BA0
button.color.icon.text-brand.active
#002677
button.color.icon.text-disabled
#7D7F81
button.color.icon.text-neutral.rest
#323334
button.color.icon.text-neutral.hover
#222324
button.color.icon.text-neutral.active
#000000
button.color.icon.text-destructive.rest
#990000
button.color.icon.text-destructive.hover
#B20000
button.color.icon.text-destructive.active
#890000
button.color.icon.text-inverse.rest
#FFFFFF
button.color.icon.text-inverse.hover
#F3F3F3
button.color.icon.text-inverse.active
#E5E5E6
button.border-radius.all.container
500px
button.border-width.all.container
1px
button.sizing.all.icon
16px
button.sizing.all.icon-only.container.sm
32px
button.sizing.all.icon-only.container.md
40px
button.sizing.all.icon-only.container.lg
48px
button.sizing.all.icon-only.icon
24px
button.sizing.height.min.container.sm
32px
button.sizing.height.min.container.md
40px
button.sizing.height.min.container.lg
48px
button.spacing.gap.horizontal.container
8px
button.spacing.padding.horizontal.container.sm
16px
button.spacing.padding.horizontal.container.md
24px
button.spacing.padding.horizontal.container.lg
24px
button.spacing.padding.vertical.container.sm
4px
button.spacing.padding.vertical.container.md
8px
button.spacing.padding.vertical.container.lg
12px
Table of Contents