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: "function" | "article" | "code" | "details" | "html" | "iframe" | "input" | "label" | "link" | "map" | "menu" | "output" | "search" | "script" | "select" | "style" | "table" | ... 3567 more ... | "zoom_out_map"; position: "leading" | ... 1 more ... | "icon-only"; variant?: "filled" | ... 1 more ... | undefin...
        --
        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