orn-ui
Atom

Spinner

Requires <UIProvider> — Getting Started →

Installation

Install just this component (copies the source into your project, no npm dependency)

npx orn-ui add spinner

Or install the whole package and import it

pnpm add orn-ui
import { Spinner } from 'orn-ui/spinner';
Depends on:core (theme + icons)

Usage

  • variant — `native` is the system indicator and the right default. `dots` and `ring` look identical on iOS and Android when that matters.
  • fullscreen — `true` takes the whole area; set it to `false` for an inline spinner inside a row or a card.
  • text — A short line under the indicator. Use it when the wait is long enough to need explaining.
  • indicator — Your own node, when the brand asks for something the three variants do not cover.
Demo clip not recorded yet — see MEDIA.md

Variants

Default — a status message under the spinner

<Spinner text="Loading invoices..." fullscreen={false} />

Custom look — dots and ring, identical on iOS and Android

<VariantRow>
  <Spinner variant="dots" text="Fetching..." fullscreen={false} />
  <Spinner variant="ring" text="Syncing..." fullscreen={false} />
</VariantRow>

Sizes — small for inline use, large for a loading screen

<VariantRow>
  <Spinner variant="ring" size="small" fullscreen={false} />
  <Spinner variant="ring" size="large" fullscreen={false} />
</VariantRow>

Custom color — matches your brand accent

<VariantRow>
  <Spinner variant="dots" color="#00cae1" fullscreen={false} />
  <Spinner variant="ring" color="#ff3b30" fullscreen={false} />
</VariantRow>

Your own indicator — e.g. an avatar while a photo uploads

<Spinner
  fullscreen={false}
  text="Uploading..."
  indicator={
    <Avatar size={48} backgroundColor="#004cef20">
      <Icon name="plus" size={24} color="#004cef" />
    </Avatar>
  }
/>

No text — just the wait, next to a button or inline in a row

<View style={{ alignItems: 'center' }}>
  <Spinner variant="ring" fullscreen={false} />
</View>
Full demo source
const variants: VariantDef[] = [
  {
    label: 'Default — a status message under the spinner',
    content: <Spinner text="Loading invoices..." fullscreen={false} />,
  },
  {
    label: 'Custom look — dots and ring, identical on iOS and Android',
    content: (
      <VariantRow>
        <Spinner variant="dots" text="Fetching..." fullscreen={false} />
        <Spinner variant="ring" text="Syncing..." fullscreen={false} />
      </VariantRow>
    ),
  },
  {
    label: 'Sizes — small for inline use, large for a loading screen',
    content: (
      <VariantRow>
        <Spinner variant="ring" size="small" fullscreen={false} />
        <Spinner variant="ring" size="large" fullscreen={false} />
      </VariantRow>
    ),
  },
  {
    label: 'Custom color — matches your brand accent',
    content: (
      <VariantRow>
        <Spinner variant="dots" color="#00cae1" fullscreen={false} />
        <Spinner variant="ring" color="#ff3b30" fullscreen={false} />
      </VariantRow>
    ),
  },
  {
    label: 'Your own indicator — e.g. an avatar while a photo uploads',
    content: (
      <Spinner
        fullscreen={false}
        text="Uploading..."
        indicator={
          <Avatar size={48} backgroundColor="#004cef20">
            <Icon name="plus" size={24} color="#004cef" />
          </Avatar>
        }
      />
    ),
  },
  {
    label: 'No text — just the wait, next to a button or inline in a row',
    content: (
      <View style={{ alignItems: 'center' }}>
        <Spinner variant="ring" fullscreen={false} />
      </View>
    ),
  },
];
return <VariantList variants={variants} />;

Props

Also accepts testID, forwarded to the root node. It exists for end-to-end tests (Maestro drives the app by the accessibility tree) and has no effect on how the component looks or behaves.

NameTypeDefaultDescription
size?'small' | 'large'large
color?string
text?string
fullscreen?booleantrueWhen false, doesn't take up flex:1 (useful inline, inside a button/row).
variant?'native' | 'dots' | 'ring'native'native' uses the system ActivityIndicator; 'dots' and 'ring' are custom indicators, identical on iOS and Android.
indicator?ReactNodeFully custom indicator. Wins over `variant`.