# Loading Spinner (/components/feedback/loading-spinner)



`LoadingSpinner` shows that work is in progress. Use it on its own for a small loading region. Wrap
final content to replace it in place.

apps/docs/src/examples/loading-spinner/basic.tsx

```tsx
import { LoadingSpinner } from '@luke-ui/react/loading-spinner';

export default () => {
	return <LoadingSpinner aria-label="Loading" />;
};
```

## Size [#size]

`medium` is the default. Set `size` to match the surrounding control or content.

apps/docs/src/examples/loading-spinner/sizes.tsx

```tsx
import { LoadingSpinner } from '@luke-ui/react/loading-spinner';
import { Comparison, ComparisonItem } from '#docs/comparison';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="X-small">
				<LoadingSpinner aria-label="Loading" size="xsmall" />
			</ComparisonItem>
			<ComparisonItem label="Small">
				<LoadingSpinner aria-label="Loading" size="small" />
			</ComparisonItem>
			<ComparisonItem label="Medium">
				<LoadingSpinner aria-label="Loading" size="medium" />
			</ComparisonItem>
			<ComparisonItem label="Large">
				<LoadingSpinner aria-label="Loading" size="large" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## With content [#with-content]

Pass final content with `isLoading` to replace it in place. While loading, the spinner keeps the
content's dimensions and disables interactive descendants. Set `isLoading` to `false` to reveal the
content.

apps/docs/src/examples/loading-spinner/children.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Button } from '@luke-ui/react/button';
import { Checkbox } from '@luke-ui/react/checkbox';
import { LoadingSpinner } from '@luke-ui/react/loading-spinner';
import { useState } from 'react';

export default () => {
	const [isLoading, setIsLoading] = useState(true);

	return (
		<Box alignItems="flex-start" display="flex" flexDirection="column" gap="sp16">
			<LoadingSpinner aria-label="Saving changes" isLoading={isLoading}>
				<Button>Save changes</Button>
			</LoadingSpinner>
			<Checkbox isSelected={isLoading} onChange={setIsLoading}>
				Loading
			</Checkbox>
		</Box>
	);
};
```

## Colour [#colour]

Omit `color` to inherit the surrounding text colour. Set it only when the spinner needs to match
nearby semantic content.

apps/docs/src/examples/loading-spinner/colors.tsx

```tsx
import { LoadingSpinner } from '@luke-ui/react/loading-spinner';
import { Comparison, ComparisonItem } from '#docs/comparison';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Inherited">
				<LoadingSpinner aria-label="Loading" />
			</ComparisonItem>
			<ComparisonItem label="Primary">
				<LoadingSpinner aria-label="Loading" color="primary" />
			</ComparisonItem>
			<ComparisonItem label="Secondary">
				<LoadingSpinner aria-label="Loading" color="secondary" />
			</ComparisonItem>
			<ComparisonItem label="Accent">
				<LoadingSpinner aria-label="Loading" color="accent" />
			</ComparisonItem>
			<ComparisonItem label="Info">
				<LoadingSpinner aria-label="Loading" color="info" />
			</ComparisonItem>
			<ComparisonItem label="Success">
				<LoadingSpinner aria-label="Loading" color="success" />
			</ComparisonItem>
			<ComparisonItem label="Warning">
				<LoadingSpinner aria-label="Loading" color="warning" />
			</ComparisonItem>
			<ComparisonItem label="Danger">
				<LoadingSpinner aria-label="Loading" color="danger" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## Accessibility [#accessibility]

The spinner is a polite status region. Its accessible name defaults to `loading`. Provide an
`aria-label` that names the work, such as `Loading profile`. While loading, the spinner hides
wrapped children from assistive technology and blocks focus and activation.

For a standard loading control, prefer [`Button`](/components/actions/button) `pressAction` or
`isPending`. Pending keeps the control focusable. Do not swap that behaviour for `isDisabled` with a
hand-rolled spinner.

## API [#api]

<ComponentPropsTable
  id="type-table-loading-spinner.tsx-LoadingSpinnerProps"
  type="{
  &#x22;id&#x22;: &#x22;loading-spinner.tsx-LoadingSpinnerProps&#x22;,
  &#x22;name&#x22;: &#x22;LoadingSpinnerProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for `LoadingSpinner`.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;aria-label&#x22;,
      &#x22;description&#x22;: &#x22;Accessible name for the loading status region.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'loading'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;children&#x22;,
      &#x22;description&#x22;: &#x22;Content to show once loading finishes. While loading, the spinner replaces it in place.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;ReactNode&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;ReactNode&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isLoading&#x22;,
      &#x22;description&#x22;: &#x22;Whether the spinner is shown in place of `children`.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;true&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;color&#x22;,
      &#x22;description&#x22;: &#x22;Sets a semantic content color. Omit to inherit the surrounding content color.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;accent\&#x22; | \&#x22;info\&#x22; | \&#x22;success\&#x22; | \&#x22;warning\&#x22; | \&#x22;danger\&#x22; | \&#x22;primary\&#x22; | \&#x22;secondary\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;size&#x22;,
      &#x22;description&#x22;: &#x22;Sets the spinner size.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'medium'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;small\&#x22; | \&#x22;medium\&#x22; | \&#x22;large\&#x22; | \&#x22;xsmall\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;deprecated&#x22;: false,
      &#x22;description&#x22;: &#x22;`LoadingSpinnerProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.&#x22;,
      &#x22;name&#x22;: &#x22;__nativePropsForwarding&#x22;,
      &#x22;required&#x22;: true,
      &#x22;simplifiedType&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;&#x22;
    }
  ]
}"
/>
