# Loader

**`sonic-loader`** shows a loading animation, either in the content flow or as a viewport overlay. With no `mode`, it is `fixed` (centered overlay); use `mode="inline"` inside content areas. For [Fetch](/core/components/functional/fetch) and [List](/core/components/functional/list), set their `loader` attribute instead of adding the tag yourself.

## Mode

`inline` renders an ellipsis animation in the document flow. `fixed` (default) covers the viewport with a centered animation; toggle it with the checkbox below.

<sonic-code>
  <template>
    <sonic-loader mode="inline"></sonic-loader>
  </template>
</sonic-code>

<docs-lit-demo for="docs-toggle-loader-demo"></docs-lit-demo>

## Alignment and color

`align` only affects `mode="inline"`: `left` · `center` (default) · `right`. Dots use `--sc-primary`; set `currentColor` to follow the host `color`.

<sonic-code>
  <template>
    <div class="grid gap-4">
      <sonic-loader mode="inline" currentColor style="color: purple;"></sonic-loader>
      <sonic-loader mode="inline" align="left"></sonic-loader>
      <sonic-loader mode="inline" align="center"></sonic-loader>
      <sonic-loader mode="inline" align="right"></sonic-loader>
    </div>
  </template>
</sonic-code>

## Delay

A `fixed` loader waits 0.5 s before fading in, so short requests show nothing. `inline` loaders appear at once. Set `noDelay` (or pass `noDelay: true` to `Loader.show()`) to show a `fixed` loader immediately.

<sonic-code>
  <template>
    <sonic-loader mode="inline" noDelay></sonic-loader>
  </template>
</sonic-code>

## Accessibility

The animation is `aria-hidden` by default so screen readers are not flooded on every request. Set `announce` when the loader appears after a user action: the host gets `role="status"`, `aria-live="polite"` and a localized "Loading" label. For a busy button, use the `loading` attribute of `sonic-button` instead.

<sonic-code>
  <template>
    <div class="flex flex-wrap items-center gap-4">
      <sonic-loader mode="inline" announce></sonic-loader>
      <sonic-button loading>Confirm check-in</sonic-button>
    </div>
  </template>
</sonic-code>

## Show and hide programmatically

`Loader.show()` mounts one shared instance; `Loader.hide()` is reference-counted, so call it once per `show()`. **Without `container`, the loader goes to the theme pop container and `mode` is forced to `fixed`.**

<sonic-code language="javascript">
  <template>
import { Loader } from "@supersoniks/concorde/ui/loader";

Loader.show({ announce: true });
// …
Loader.hide();

// Inline loader inside a given element
Loader.show({ mode: "inline", container: document.querySelector("#results") });
  </template>
</sonic-code>

## API reference

| Attribute | Values | Description |
|----------|---------|-------------|
| `mode` | `inline` · `fixed` (default `fixed`) | In-flow ellipsis or viewport-centered overlay |
| `noDelay` | boolean | Skips the 0.5 s fade-in delay of `fixed` |
| `announce` | boolean | Adds `role="status"`, `aria-live="polite"` and a localized label |
| `align` | `left` · `center` · `right` (default `center`) | Horizontal alignment, `mode="inline"` only |
| `currentColor` | boolean | Dots use `currentColor` instead of `--sc-primary` |

No slots.

| Static method | Description |
|--------|-------------|
| `Loader.show(conf?)` | Mounts the shared instance. `conf`: `mode` · `noDelay` · `announce` · `container` |
| `Loader.hide()` | Decrements the show counter; removes the instance when it reaches zero |
