# Spinner

The platform's activity indicator in the theme accent, for a wait without a known end.

![The platform's activity indicator in the theme accent: sm and default are the small one, lg the large.](https://ui.terratcg.app/previews/spinner/sizes/ios-light.png)

```tsx
import { Spinner } from "@terratcg/ui";
import { View } from "react-native";

export default function SpinnerSizes() {
  return (
    <View style={{ flexDirection: "row", alignItems: "center", gap: 24 }}>
      <Spinner size="sm" />
      <Spinner />
      <Spinner size="lg" />
    </View>
  );
}
```

## Import

```tsx
import { Spinner } from "@terratcg/ui";
```

## Usage

```tsx
{loading ? <Spinner /> : <PhotoList />}
```

A Spinner is React Native's `ActivityIndicator` coloured with the theme accent. For a busy key, set `loading` on the Button instead: it holds its width and shows its own Spinner.

## Examples

### With a label

Beside text, the label says what is loading, and the spinner takes the same words for screen readers.

![Beside text, the label says what is loading, and the spinner takes the same words for screen readers.](https://ui.terratcg.app/previews/spinner/with-label/ios-light.png)

```tsx
import { Spinner, Text } from "@terratcg/ui";
import { View } from "react-native";

export default function SpinnerWithLabel() {
  return (
    <View style={{ flexDirection: "row", alignItems: "center", gap: 10 }}>
      <Spinner accessibilityLabel="Syncing your library" />
      <Text tone="secondary">Syncing your library</Text>
    </View>
  );
}
```

## Props

### SpinnerProps

| Prop    | Type                        | Description                                                                                      |
| ------- | --------------------------- | ------------------------------------------------------------------------------------------------ |
| `size?` | `"default" \| "lg" \| "sm"` | "sm" and "default" draw the platform's small indicator, "lg" its large one. Default: `"default"` |

Spinner also accepts React Native's `ActivityIndicator` props except `size`, such as `animating`, `color` and `hidesWhenStopped`. `color` replaces the accent.

## Accessibility

- **Role:** `progressbar`, with the label from `ThemeProvider`'s `labels.loading` ("Loading" by default, see [Labels](/docs/theme-provider#labels)) unless you pass your own `accessibilityLabel`. Say what is loading: "Syncing your library".
- **One per wait:** a screen that is loading shows one Spinner, so it is announced once.

## Platform differences

- **iOS:** the system activity indicator. `sm` and `default` are the small one, `lg` the large one.
- **Android:** the Material circular indicator, at the same two sizes.
- **Web:** react-native-web draws its own indicator for these docs, but the web is not a supported target.

## Rules

- Use a Spinner for a wait without a known end. When you know how far along the work is, show Progress.
- Don't use a Spinner as a page's placeholder: show Skeleton shapes for content that is on its way.
- Keep the accent: pass `color` only on a surface where the accent doesn't read.
