Hacktron Design System

Spinner

A spinning indicator for a short wait of unknown length.

<template>  <Spinner /></template>

Props

Name Type Default
size'sm' | 'md' | 'lg'md
iconstringi-lucide-loader-2
colorstringtext-primary

Guidelines

Do

  • Use <Spinner /> for short, indeterminate waits (auth callbacks, waiting on an OAuth redirect) where you have no progress percentage to show.
  • Center it in the space it's replacing so layout doesn't jump when content arrives.
  • Use size="sm" when composing it inline next to text (e.g. in a Button or Badge) - the default md is sized for a full-page or full-panel wait.
  • Set color to match whatever it's composed inside (e.g. color="text-text-inverse" in a Primary button, color="text-text-secondary" in a Default badge) - the default text-primary is only right for a standalone wait on a plain background.
  • Reach for icon only for a deliberate, one-off exception (e.g. matching a specific third-party brand mark inline) - leave it at the default everywhere else.

Don't

  • Don't use it for waits longer than a few seconds - prefer Skeleton that mirrors the shape of the content being loaded, so the page doesn't feel stuck.
  • Don't build your own spin animation from scratch (a raw <UIcon animate-spin>) for loading states - this is the one loading indicator in the system; a second, hand-rolled one reads as inconsistent, not intentional.
  • Don't leave color at its default when composing Spinner inside a colored background - text-primary is the same token some backgrounds (e.g. a Primary button) already use, so the icon can end up invisible instead of just off-color.

Examples

Size

The three size steps - sm, md, and lg.

<template>  <Spinner size="sm" />  <Spinner size="md" />  <Spinner size="lg" /></template>

Custom icon

A different spin glyph for a deliberate, one-off exception.

<template>  <Spinner icon="i-lucide-refresh-cw" /></template>

Button

Composed inside a disabled button during a pending action.

<template>  <Button variant="primary" disabled>    <template #leftIcon>      <Spinner size="sm" color="text-text-inverse" />    </template>    Please wait  </Button></template>

Badge

Composed inside a badge to show a syncing or loading state.

Syncing
<template>  <Badge variant="default">    <template #leftIcon>      <Spinner size="sm" color="text-text-secondary" />    </template>    Syncing  </Badge></template>