# LoadingOverlay

> Covers a region or the whole screen with a spinner while work is in progress.

Category: Feedback · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/loading-overlay

LoadingOverlay keeps layout stable while content refreshes, and prevents interaction with stale data. The covered content is marked aria-busy and made inert so it cannot be clicked or focused. Prefer Skeleton for first loads and a Button’s loading state for single actions; use the overlay when a whole panel is temporarily unusable.

## Import

```tsx
import { LoadingOverlay } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Covering a panel

```tsx
import * as React from 'react';
import { Button, LoadingOverlay } from '@bindshq/stance-react';

const panel: React.CSSProperties = {
  display: 'grid',
  gap: 8,
  width: 320,
  padding: 20,
  border: '1px solid var(--st-color-border-default)',
  borderRadius: 12,
  background: 'var(--st-color-bg-surface)',
};

export function Basic() {
  const [busy, setBusy] = React.useState(true);
  return (
    <div style={{ display: 'grid', gap: 12, justifyItems: 'center' }}>
      <LoadingOverlay visible={busy} message="Refreshing usage…" style={{ borderRadius: 12 }}>
        <div style={panel}>
          <strong>Seat usage</strong>
          <span>48 of 50 seats used</span>
          <Button size="sm" variant="outline">
            Manage seats
          </Button>
        </div>
      </LoadingOverlay>
      <Button size="sm" variant="secondary" onClick={() => setBusy((b) => !b)}>
        {busy ? 'Finish loading' : 'Start loading'}
      </Button>
    </div>
  );
}
```

### Solid backdrop

Hide content entirely when partial data would mislead.

```tsx
import * as React from 'react';
import { LoadingOverlay } from '@bindshq/stance-react';

const panel: React.CSSProperties = {
  display: 'grid',
  gap: 8,
  width: 320,
  padding: 20,
  border: '1px solid var(--st-color-border-default)',
  borderRadius: 12,
  background: 'var(--st-color-bg-surface)',
};

export function Solid() {
  return (
    <LoadingOverlay visible backdrop="solid" message="Loading report…" style={{ borderRadius: 12 }}>
      <div style={panel}>
        <strong>Deployment report</strong>
        <span>128 mailboxes</span>
      </div>
    </LoadingOverlay>
  );
}
```

### Full screen

For app-wide transitions such as switching organisation.

```tsx
import * as React from 'react';
import { Button, LoadingOverlay } from '@bindshq/stance-react';

export function FullScreen() {
  const [busy, setBusy] = React.useState(false);
  return (
    <>
      <Button
        onClick={() => {
          setBusy(true);
          setTimeout(() => setBusy(false), 1500);
        }}
      >
        Switch organisation
      </Button>
      <LoadingOverlay visible={busy} fullScreen message="Switching to Binds Ltd…" />
    </>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| LoadingOverlay | `visible` (required) | `boolean` | None | Show the overlay. |
| LoadingOverlay | `message` | `ReactNode` | `'Loading…'` | Shown under the spinner and announced politely. |
| LoadingOverlay | `backdrop` | `'subtle' \| 'solid'` | `'subtle'` | Subtle keeps content faintly visible. |
| LoadingOverlay | `fullScreen` | `boolean` | `false` | Cover the viewport (rendered in a portal). |
| LoadingOverlay | `children` | `ReactNode` | None | Content to cover; made inert and aria-busy while visible. |

## Accessibility

- The wrapper has aria-busy="true" while visible and the content is inert (not focusable or clickable).
- The message is in a role="status" region so screen readers hear it once.
- The spinner slows instead of stopping under prefers-reduced-motion.

## Guidelines

**Do**

- Write a specific message: “Deploying signatures…”.
- Return focus to a sensible place when loading finishes.

**Don’t**

- Cover the screen for background refreshes; update in place instead.

## Related

- https://stanceui.com/components/spinner
- https://stanceui.com/components/skeleton
- https://stanceui.com/components/progress
