Skip to main content

LoadingSpinner

Infinite loading spinner.

github
View source code

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 { LoadingSpinner } from '@uhg-abyss/web/ui/LoadingSpinner';

Overview​

The LoadingSpinner visually communicates that an operation such as data fetching, file downloading, or form submission is in progress, all without disrupting the user's current focus. The prop isLoading controls the visibility of the spinner, allowing it to be shown or hidden based on the loading state of your application; by default, this is set to false.

It requires the ariaLoadingLabel prop to describe what is happening while the spinner is active, for example, "Submitting form", "Downloading files", "Content is loading", etc. Be as descriptive as possible.

<LoadingSpinner ariaLoadingLabel="Downloading" isLoading={isLoading} />

Size and variant​

The LoadingSpinner component comes in three sizes:

  • xs: Compact size designed specifically for use within buttons
  • lg: Standard size for general use (default)
  • xl: Larger size for greater visibility

The component offers two styling variants:

  • primary: Default styling for light backgrounds
  • alt: Alternative styling optimized for dark backgrounds

Label​

Use the optional prop label to provide an additional description for your spinner. The label prop should be an object with:

  • heading - required, a short title or heading for the spinner
  • headingLevel - optional, a number from 0 to 5 indicating the heading level (default is 3). You can read more about heading levels in our Heading component.
  • bodyText - optional, a longer description or body text that provides more context about the loading state

For spinners with a size of xs, text labels will not be displayed regardless of the provided label values.

Important

The ariaLoadingLabel prop should match the heading value in the label prop to ensure accessibility compliance.

Color​

Use the optional color prop to change the color of the spinner.

Button​

The Button component has LoadingSpinner integration. See the Button documentation to learn more.

Content wrapping and overflow​

Use the optional width prop to set a fixed width for the spinner. This is useful when you want to ensure that the spinner does not exceed a certain size, especially in responsive designs. By default, the spinner has a width of fit-content, meaning it will adjust its size based on the content and available space.

LoadingSpinner Props​

Name
Type
DefaultRequiredA11yDescription
ariaLoadingLabel
string
The text that describes what is happening while the LoadingSpinner is active
className
string | undefined
CSS class name to apply to each element within the component
color
string | undefined
The color of LoadingSpinner component
css
CSSProperties | Partial<Record<"abyss-loading-spinner" | "abyss-loading-spinner-label.heading" | "abyss-loading-spinner-track" | "abyss-loading-spinner-heading" | ... 4 more ... | "abyss-loading-spinner-body-text", CSSProperties>> | undefined
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 | undefined
Suffix used to create a unique ID used for automated testing
See Component Testing for more information
disableDefaultProviderProps
boolean | undefined
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.
hiddenFrom
Breakpoint | undefined
When defined, the component is hidden once the screen width reaches the specified breakpoint.
isLoading
boolean | undefined
false
If true , the spinner is loading
label
{ heading: string; headingLevel?: 1 | 2 | 3 | 4 | 5 | 6 | undefined; bodyText?: string | undefined; } | undefined
The label for the LoadingSpinner component.
Accepts an object with a heading, a headingLevel and a corresponding optional bodyText.
The headingLevel is defaulted to 3.
Note: If bodyText is provided, a heading must also be provided.
size
"xs" | "lg" | "xl" | undefined
'lg'
The size of LoadingSpinner component
slotProps
Partial<Record<ToSlotKey<{ container: LeafSlotDef<"div", undefined>; root: LeafSlotDef<"div", undefined>; spinner: LeafSlotDef<"svg", "loading-spinner">; ... 5 more ...; bodyText: LeafSlotDef<...>; }, "loading-spinner">, SlotPropsLeafValue>> | undefined
variant
"alt" | "primary" | undefined
'primary'
The variant of LoadingSpinner component
visibleFrom
Breakpoint | undefined
When defined, the component is hidden until the screen width reaches the specified breakpoint.
width
string | number | undefined
'fit-content'
The width of the LoadingSpinner component

LoadingSpinner Classes​

Class NameDescription
.abyss-loading-spinnerLoadingSpinner spinner element
.abyss-loading-spinner-barLoadingSpinner bar element
.abyss-loading-spinner-body-textLoadingSpinner body text element
.abyss-loading-spinner-containerLoadingSpinner container element
.abyss-loading-spinner-headingLoadingSpinner heading element
.abyss-loading-spinner-label.headingLoadingSpinner heading element. Prefer using `loading-spinner-heading`.
.abyss-loading-spinner-rootLoadingSpinner root element
.abyss-loading-spinner-text-containerLoadingSpinner text container element
.abyss-loading-spinner-trackLoadingSpinner track element

Following the requirements of WAI-ARIA, LoadingSpinner follows the requirements of 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 user's context (i.e., take focus).

LoadingSpinner 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.

Adheres to the Status messages WAI-ARIA design patternopens in a new window.

** Screen reader behavior when used within a button: JAWS suppresses announcement of button when aria-busy="true" **

  • For most screen readers (NVDA, VoiceOver-Mac), the use of aria-busy="true" includes this state in the announcement of the button.
  • JAWS' implementation is to suppress announcement of the button until aria-busy="false" (or removed).
  • This is a known "feature" documented here (since May 16, 2018): Short note on being busy - TPGiopens in a new window.

Reduced Motion​

For users who have prefers-reduced-motion set to reduced, the animation of the spinner is disabled.

Component Tokens​

Tip

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

LoadingSpinner Tokens​

Token NameValue
loading-spinner.color.surface.bar.default
#002677
loading-spinner.color.surface.bar.alt
#FFFFFF
loading-spinner.color.surface.track.default
#002677
loading-spinner.color.surface.track.alt
#F3F3F3
loading-spinner.color.text.heading.default
#002677
loading-spinner.color.text.heading.alt
#FFFFFF
loading-spinner.color.text.paragraph.default
#4B4D4F
loading-spinner.color.text.paragraph.alt
#FFFFFF
loading-spinner.sizing.all.spinner.xs
20px
loading-spinner.sizing.all.spinner.lg
40px
loading-spinner.sizing.all.spinner.xl
80px
loading-spinner.spacing.gap.vertical.container
24px
loading-spinner.spacing.gap.vertical.text-container
4px
Table of Contents