# Spinner

The indeterminate busy indicator — an arc that turns, announcing itself politely.

```slint
import { Spinner } from "@glint/components/spinner.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Spinner {
                size: 16px;
            }

            Spinner {
                size: 24px;
                tint: Tokens.color-primary;
            }

            Spinner {
                size: 32px;
                tint: Tokens.color-foreground;
                thickness: 3px;
            }
        }
    }
}
```

## Usage

```slint
import { Spinner } from "@glint/components/spinner.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component AppWindow inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        Spinner {
            size: 20px;
        }
    }
}
```

`Spinner` displays a continuously rotating indeterminate loading indicator.

## Examples

### Sizing and thickness

Scale `size` and customize `thickness` to fit compact button contexts or large centered loading screens.

```slint
import { Spinner } from "@glint/components/spinner.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Spinner {
                size: 14px;
            }

            Spinner {
                size: 20px;
            }

            Spinner {
                size: 28px;
                thickness: 2.5px;
            }

            Spinner {
                size: 40px;
                thickness: 4px;
            }
        }
    }
}
```

### Color tints

Customize `tint` with semantic tokens.

```slint
import { Spinner } from "@glint/components/spinner.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Spinner {
                size: 24px;
                tint: Tokens.color-muted-foreground;
            }

            Spinner {
                size: 24px;
                tint: Tokens.color-primary;
            }

            Spinner {
                size: 24px;
                tint: Tokens.color-destructive;
            }
        }
    }
}
```

## API Reference

### Properties

| Property    | Type          | Default                         | Description                                                                                                                                   |
| ----------- | ------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `size`      | `in length`   | `16px`                          | Side length of the square arc.                                                                                                                |
| `tint`      | `in color`    | `Tokens.color-muted-foreground` | Arc color; defaults to the muted foreground token.                                                                                            |
| `thickness` | `in length`   | `root.size / 8`                 | Arc stroke thickness. Proportional by default, so a spinner scaled up for a card does not end up drawing a hairline: 2px at the default size. |
| `period`    | `in duration` | `1s`                            | Time for one full turn.                                                                                                                       |
| `rotation`  | `out angle`   | no default                      | The arc's current rotation. Public so a host can drive matching motion from the same phase — and so a test can watch the arc actually move.   |

## Accessibility

- **Progress indicator role.** Spinner announces as `accessible-role: progress-indicator`.
- **Polite live region.** Configured with `accessible-live-region: AccessibleLiveness.polite` and defaults to the accessible label `"Loading"`.
