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 buttonslg: Standard size for general use (default)xl: Larger size for greater visibility
The component offers two styling variants:
primary: Default styling for light backgroundsalt: 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 spinnerheadingLevel- 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.
Note: 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 | Default | Required | Description |
|---|---|---|---|---|
ariaLoadingLabel | string | - | The text that describes what is happening while the LoadingSpinner is active | |
className | string | - | - | CSS class name to apply to each element within the component |
color | string | - | - | The color of LoadingSpinner component |
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 |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
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. |
isLoading | boolean | false | - | If true , the spinner is loading |
label | { heading: string; headingLevel?: 1 | 2 | 3 | 4 | 5 | 6 | undefined; bodyText?: string | 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" | 'lg' | - | The size of LoadingSpinner component |
variant | "primary" | "alt" | 'primary' | - | The variant of LoadingSpinner component |
width | string | number | 'fit-content' | - | The width of the LoadingSpinner component |
Below are the link(s) to the relevant GitHub type files:
LoadingSpinner Classes
| Class Name | Description |
|---|---|
| .abyss-loading-spinner-container | LoadingSpinner container element |
| .abyss-loading-spinner-root | LoadingSpinner root element |
| .abyss-loading-spinner | LoadingSpinner spinner element |
| .abyss-loading-spinner-track | LoadingSpinner track element |
| .abyss-loading-spinner-bar | LoadingSpinner bar element |
| .abyss-loading-spinner-text-container | LoadingSpinner text container element |
| .abyss-loading-spinner-heading | LoadingSpinner heading element |
| .abyss-loading-spinner-label.heading | LoadingSpinner heading element. Prefer using `loading-spinner-heading`. |
| .abyss-loading-spinner-body-text | LoadingSpinner body text 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 pattern.
** 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 - TPGi.
Reduced Motion
For users who have prefers-reduced-motion set to reduced, the animation of the spinner is disabled.
Component Tokens
Note: Click on the token row to copy the token to your clipboard.
LoadingSpinner Tokens
| Token Name | Value | |
|---|---|---|
| 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 |