# Spinner

A turning icon that shows that something is working and the wait has no known length.

- **Import:** `import { Spinner } from "@booleanpress/ui/spinner"`
- **Page:** <https://ui.booleanpress.com/components/spinner> · @booleanpress/ui 0.1.0

## Usage

A spinner is an icon: 16 px, in the current text colour, turning. Size and colour it with classes.

```tsx
import { Button } from "@booleanpress/ui/button"
import { Spinner } from "@booleanpress/ui/spinner"

export function Sending() {
  return (
    <Button disabled>
      <Spinner />
      Sending
    </Button>
  )
}
```

Its accessible name comes from the provider's `loading` string ("Loading" in English), so a translated product needs no change in the component. Pass `aria-label` to say more: "Sending the test email". When a nearby text already says what is happening, as in the button above, the spinner's own name is read as well; to avoid repeating it, pass `aria-hidden` or `aria-label=""` for that use.

Use a spinner for a wait of unknown length, a progress bar for one you can measure, and a skeleton while a whole block loads.

## Examples

### Basic

The default 16 px spinner.

```tsx
import { Spinner } from "@booleanpress/ui/spinner"

export default function SpinnerBasic() {
  return <Spinner />
}
```

### Sizes

Any `size-*` class sets the size; the colour follows `text-*`.

```tsx
import { Spinner } from "@booleanpress/ui/spinner"

export default function SpinnerSizes() {
  return (
    <div className="flex items-center gap-4">
      <Spinner className="size-3" />
      <Spinner />
      <Spinner className="size-6" />
      <Spinner className="size-8 text-muted-foreground" />
    </div>
  )
}
```

### In a button

A spinner before the label of a disabled button.

```tsx
import { Button } from "@booleanpress/ui/button"
import { Spinner } from "@booleanpress/ui/spinner"

export default function SpinnerInButton() {
  return (
    <Button disabled>
      <Spinner />
      Sending
    </Button>
  )
}
```

### Inline

A spinner beside a line of status text.

```tsx
import { Spinner } from "@booleanpress/ui/spinner"

export default function SpinnerInline() {
  return (
    <p className="flex items-center gap-2 text-sm text-muted-foreground">
      <Spinner />
      Checking the connection…
    </p>
  )
}
```

## Accessibility

**Semantics.** An `svg` with `role="status"` and `aria-label` from `strings.loading`, so it is a polite live region with a name.

**Labels.** The provider's `loading` string. Override per use with `aria-label`.

**Focus.** A spinner takes no focus and has no keyboard behaviour, so it has no keyboard rows.

**Known limits.**

- A `role="status"` that is already on the page when it loads is not announced. Add the spinner when the wait starts, or put the message in a live region that exists already.
- The turn is `animate-spin`. `theme.css` ends it under `prefers-reduced-motion`, so the icon then stands still: keep a text beside it that says the wait is on.

### Keyboard

| Key | Behaviour |
| --- | --- |

## API

### Spinner

Renders a `svg` and passes it every other prop.

Every part takes `className`, merged with its defaults by `cn()`, and `ref`, which reaches the element it renders.

**Provider strings:** `loading` (`BooleanUIProvider`'s `strings`).

## Theming
