{
  "name": "Spinner",
  "type": "component",
  "description": "Loading indicator, indeterminate or determinate, in five sizes.",
  "export": "@gtmi/strix-react/atoms/spinner",
  "path": "@gtmi/strix-react/atoms/spinner",
  "figma": {
    "file": "zT3vGm4QlFEI2Jp9nxyFKI",
    "fileName": "Demo components library",
    "nodes": [
      {
        "node": "22:3828",
        "name": ".icon",
        "section": "Atoms"
      }
    ],
    "note": "Ports `.icon`s Loading ring only — an 86px arc, which is Spinner at xl (84px). The other three .icon types (Success/Alert/Fail) are shield glyphs Strix already ships, not this component."
  },
  "props": [
    {
      "name": "variant",
      "type": "indeterminate | determinate",
      "default": "indeterminate",
      "description": "indeterminate spins a quarter arc; determinate fills the ring to `value` and becomes a progressbar."
    },
    {
      "name": "size",
      "type": "xs | sm | md | lg | xl",
      "default": "md",
      "description": "From md up the layout stacks so a label fits under the ring; at lg and xl the percentage is centered inside it."
    },
    {
      "name": "value",
      "type": "number",
      "description": "Progress 0-100, clamped. Only meaningful when determinate."
    },
    {
      "name": "label",
      "type": "string",
      "description": "Caption under an indeterminate spinner."
    },
    {
      "name": "disabled",
      "type": "boolean",
      "default": "false",
      "description": "Forces the value to 0, stops the animation, and paints the disabled colors."
    },
    {
      "name": "onComplete",
      "type": "() => void",
      "description": "Fires exactly once, on the transition into >= 100. Never fires while disabled, and never for a spinner that mounts already complete."
    },
    {
      "name": "aria-label",
      "type": "string",
      "default": "Loading",
      "description": "Accessible name."
    },
    {
      "name": "className",
      "type": "string",
      "description": "Merged through cn()."
    }
  ],
  "ai_tags": ["spinner", "loading", "progress", "primitive"],
  "since": "0.2.0",
  "tokens_used": [
    "--color-icon-accent-muted",
    "--color-icon-accent-subtle",
    "--color-icon-disabled",
    "--color-text-primary",
    "--color-text-disabled-on-surface",
    "--spacing-gap-100",
    "--spacing-gap-150"
  ],
  "notes": "role is status when indeterminate and progressbar when determinate, with the value semantics present only in the second case. The visible percentage is aria-hidden and a polite live region carries the announcement, so the number is not read twice. onComplete is held in a ref, so passing a fresh closure each render does not re-fire it. Honors prefers-reduced-motion for both the spin and the fill transition. Adds ref forwarding, which upstream did not have."
}
