# spin

> Continuous 360° rotation for a busy indicator's glyph, resolved entirely to `@keyframes` so it runs from server-rendered markup.

```ts
import { spin } from "@sdxc/ui/animations";
```

Continuous 360° rotation for a busy indicator's glyph, resolved entirely to
`@keyframes` so it runs from server-rendered markup. Under
`prefers-reduced-motion: reduce`, a gentle opacity breathe carries it.

## Signature

```ts
spin<Node extends Element = Element>(options?: Spin.Options): Mixin<Node>
```

Returns: A `@sdxc/u` mixin ready for a spinner's host element.

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `options?` | `Spin.Options` | Timing and gating for the loop. |

## Examples

```tsx
<Spinner mix={[spin()]} aria-label={t("status.loading")} />
```

## Used with it

The events, constants and types its module publishes, each imported from `@sdxc/ui/animations` too.

### Spin.Options

Tuning for a spin loop: timing and the platform state it runs under.

#### Members

| Member | Type | Description |
| --- | --- | --- |
| `duration?` | `string` | Length of one full rotation, as a CSS time. Defaults to DEFAULT_SPIN_DURATION. |
| `easing?` | `string` | CSS easing function driving the rotation. Defaults to DEFAULT_SPIN_EASING. |
| `when?` | `string` | Selector fragment, relative to the host (e.g. `[aria-busy="true"]`), that gates the loop. Left unset, the loop runs as soon as it is mixed in, matching a spinner that is mounted only while busy. |
