<!-- https://svgrid.com/docs/help/ui-components/sv-loading-overlay/ - SvGrid documentation as markdown. Index of every page: https://svgrid.com/llms.txt -->

# SvLoadingOverlay

A cover-a-container loading scrim: a translucent overlay with a centred spinner
that sits on top of any positioned parent while its content loads or saves.

`SvLoadingOverlay` fills its nearest positioned ancestor (`position: absolute;
inset: 0`) with a scrim + [SvSpinner](https://svgrid.com/docs/help/ui-components/sv-spinner/) and an optional label. Drop
it inside a `position: relative` wrapper so the content stays visible (optionally
blurred) underneath while an async action is in flight - a save, a fetch, a
recalculation.

Related: [SvSpinner](https://svgrid.com/docs/help/ui-components/sv-spinner/) · [SvSkeleton](https://svgrid.com/docs/help/ui-components/sv-skeleton/) · [SvResult](https://svgrid.com/docs/help/ui-components/sv-result/)

## Installation

Add it with the CLI - this drops a ready-to-edit `SvLoadingOverlay` starter into your app:

<div data-docs-add="add loading-overlay"></div>

Prefer to see it first? `npx @svgrid/ui try loading-overlay` opens it in a throwaway sandbox - no project needed.

Or install the package and import it directly. `SvLoadingOverlay` ships free in
`@svgrid/grid` (dependency-free):

<div data-docs-install="@svgrid/grid"></div>

```ts
import { SvLoadingOverlay } from '@svgrid/grid'
```

## Example

> Live demo: Layout & feedback primitives - https://svgrid.com/demos/409-layout-feedback/

```svelte
<script lang="ts">
  import { SvLoadingOverlay } from '@svgrid/grid'
  let loading = $state(false)
</script>

<div style="position: relative">
  <SvLoadingOverlay visible={loading} label="Saving…" />
  <!-- panel content -->
</div>
```

The wrapper **must** be positioned (`relative` / `absolute`) - the overlay pins
itself to that box with `inset: 0`.

## Props

| Prop          | Type                              | Default | Description                                                          |
| ------------- | --------------------------------- | ------- | -------------------------------------------------------------------- |
| `visible`     | `boolean`                         | `false` | Show the overlay. Nothing renders when `false`.                      |
| `label`       | `string`                          | -       | Text under the spinner and the overlay's accessible name.           |
| `spinnerSize` | `sm` \| `md` \| `lg` \| `number`  | `lg`    | Size passed through to the inner [SvSpinner](https://svgrid.com/docs/help/ui-components/sv-spinner/).         |
| `blur`        | `boolean`                         | `false` | Blur the content behind the scrim.                                   |
| `children`    | `Snippet`                         | -       | Custom overlay content in place of the default spinner + label.      |

## Accessibility

- The overlay is `role="status"` with `aria-live="polite"` and an `aria-label`
  (falls back to `"Loading"`), so its appearance is announced without stealing
  focus.
- It does not trap focus. If the underlying content must be non-interactive while
  loading, disable those controls or set `inert` on the wrapper yourself.

## Over live content

The overlay covers its children rather than replacing them, so the layout does
not jump when loading ends. `blur` is what stops the content behind reading as
still-interactive.

```svelte
<script lang="ts">
  import { SvLoadingOverlay, SvGrid, SvButton, type GridColumns } from '@svgrid/grid'

  type Person = { name: string; city: string }

  const people: Person[] = [
    { name: 'Ada Lovelace', city: 'London' },
    { name: 'Grace Hopper', city: 'New York' },
    { name: 'Linus Torvalds', city: 'Portland' },
  ]

  const columns: GridColumns<Person> = [
    { field: 'name', header: 'Name', width: 180 },
    { field: 'city', header: 'City', width: 140 },
  ]

  let busy = $state(false)

  function refresh() {
    busy = true
    setTimeout(() => (busy = false), 1200)
  }
</script>

<SvButton onclick={refresh}>Refresh</SvButton>

<SvLoadingOverlay visible={busy} label="Fetching rows..." blur>
  <SvGrid data={people} {columns} />
</SvLoadingOverlay>
```

## See also

- [SvSpinner](https://svgrid.com/docs/help/ui-components/sv-spinner/) - the inline indicator used inside this overlay.
- [SvSkeleton](https://svgrid.com/docs/help/ui-components/sv-skeleton/) - placeholder shapes for first-load content.
- [SvResult](https://svgrid.com/docs/help/ui-components/sv-result/) - the terminal state once the async action finishes.

---

SvGrid is the Svelte 5 data grid (`npm install @svgrid/grid`, MIT). This page: https://svgrid.com/docs/help/ui-components/sv-loading-overlay/ . All docs: https://svgrid.com/llms.txt
