{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "step-indicator",
  "title": "Step Indicator",
  "description": "Current, complete, optional, blocked, and error steps with explicit status text.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "https://uaiblocks.dev/r/uai-theme.json",
    "https://uaiblocks.dev/r/uai-utils.json"
  ],
  "files": [
    {
      "path": "src/registry/uai/components/step-indicator.tsx",
      "content": "\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { type ComponentProps, createContext, useContext } from \"react\";\nimport { cn } from \"@/lib/uai-utils\";\n\nexport const STEP_INDICATOR_VARIANTS = [\"horizontal\", \"vertical\", \"compact\"] as const;\nexport type StepIndicatorVariant = (typeof STEP_INDICATOR_VARIANTS)[number];\nexport type StepIndicatorStatus = \"upcoming\" | \"current\" | \"complete\" | \"blocked\" | \"error\";\nconst Context = createContext<StepIndicatorVariant | null>(null);\n\nconst stepIndicatorVariants = cva(\n  \"m-0 flex list-none flex-wrap p-0 text-[13px]/[18px] text-foreground\",\n  {\n    variants: {\n      variant: {\n        horizontal: \"flex-row gap-2.5\",\n        vertical: \"flex-col gap-0.5\",\n        compact: \"flex-row gap-1\",\n      },\n    },\n  },\n);\n\nconst dotTone: Record<StepIndicatorStatus, string> = {\n  complete: \"bg-foreground\",\n  current: \"bg-primary\",\n  error: \"bg-destructive\",\n  blocked: \"bg-border-strong\",\n  upcoming: \"bg-border\",\n};\n// Complete steps keep the neutral track; the `before:` fill grows over it.\nconst verticalTone: Record<StepIndicatorStatus, string> = {\n  complete: \"shadow-[inset_2px_0_0_var(--border)]\",\n  current: \"shadow-[inset_2px_0_0_var(--primary)]\",\n  error: \"shadow-[inset_2px_0_0_var(--destructive)]\",\n  blocked: \"shadow-[inset_2px_0_0_var(--border-strong)]\",\n  upcoming: \"shadow-[inset_2px_0_0_var(--border)]\",\n};\nconst horizontalTone: Record<StepIndicatorStatus, string> = {\n  complete: \"shadow-[inset_0_3px_0_var(--border)]\",\n  current: \"shadow-[inset_0_3px_0_var(--primary)]\",\n  error: \"shadow-[inset_0_3px_0_var(--destructive)]\",\n  blocked: \"shadow-[inset_0_3px_0_var(--border-strong)]\",\n  upcoming: \"shadow-[inset_0_3px_0_var(--border)]\",\n};\n\nexport function StepIndicator({\n  variant = \"horizontal\",\n  className,\n  ...props\n}: ComponentProps<\"ol\"> & { variant?: StepIndicatorVariant }) {\n  return (\n    <Context.Provider value={variant}>\n      <ol\n        aria-label=\"Form progress\"\n        data-slot=\"step-indicator\"\n        className={cn(stepIndicatorVariants({ variant }), className)}\n        {...props}\n        data-variant={variant}\n      />\n    </Context.Provider>\n  );\n}\nexport function StepIndicatorStep({\n  status = \"upcoming\",\n  optional = false,\n  children,\n  className,\n  ...props\n}: ComponentProps<\"li\"> & { status?: StepIndicatorStatus; optional?: boolean }) {\n  const variant = useContext(Context);\n  if (!variant) throw new Error(\"StepIndicatorStep must be used within StepIndicator\");\n  const active = status === \"current\";\n  const muted = status === \"upcoming\" || status === \"blocked\";\n  const label = (\n    <span\n      className={cn(\n        \"text-[11.5px]/4\",\n        status === \"error\"\n          ? \"text-destructive-ink\"\n          : active\n            ? \"text-primary-ink\"\n            : \"text-subtle-foreground\",\n        variant === \"compact\" && \"sr-only\",\n      )}\n    >\n      {status.charAt(0).toUpperCase() + status.slice(1)}\n      {optional ? \" · Optional\" : \"\"}\n    </span>\n  );\n  if (variant === \"compact\")\n    return (\n      <li\n        data-slot=\"step-indicator-step\"\n        className={cn(\n          \"relative inline-flex h-7 min-w-0 items-center gap-1.5 rounded-full pr-3 pl-2.5 text-[12.5px] transition-[background-color,color] duration-120 ease-[ease-out] motion-reduce:transition-none\",\n          active ? \"bg-accent\" : \"bg-transparent\",\n          muted ? \"text-subtle-foreground\" : \"text-foreground\",\n          className,\n        )}\n        {...props}\n        aria-current={active ? \"step\" : undefined}\n        data-status={status}\n      >\n        <span\n          aria-hidden=\"true\"\n          className={cn(\n            \"size-1.5 shrink-0 rounded-full transition-colors duration-200 ease-out motion-reduce:transition-none\",\n            dotTone[status],\n          )}\n        />\n        {children}\n        {label}\n      </li>\n    );\n  return (\n    <li\n      data-slot=\"step-indicator-step\"\n      className={cn(\n        \"relative grid min-w-0 content-start gap-1 [transition:box-shadow_240ms_var(--ease-out-quint),color_120ms_ease-out] before:pointer-events-none before:absolute before:bg-foreground before:transition-[scale] before:duration-300 before:ease-out-quint before:content-[''] motion-reduce:transition-none motion-reduce:before:transition-none\",\n        muted ? \"text-muted-foreground\" : \"text-foreground\",\n        variant === \"vertical\"\n          ? cn(\n              \"rounded-none pt-2 pr-0 pb-2.5 pl-3.5 before:inset-y-0 before:left-0 before:w-0.5 before:origin-top before:scale-y-0 data-[status=complete]:before:scale-y-100\",\n              verticalTone[status],\n            )\n          : cn(\n              \"flex-[1_1_110px] rounded-t-[2px] pt-3 before:inset-x-0 before:top-0 before:h-[3px] before:origin-left before:scale-x-0 before:rounded-t-[2px] data-[status=complete]:before:scale-x-100\",\n              horizontalTone[status],\n            ),\n        className,\n      )}\n      {...props}\n      aria-current={active ? \"step\" : undefined}\n      data-status={status}\n    >\n      {children}\n      {label}\n    </li>\n  );\n}\nexport function StepIndicatorTitle({ className, ...props }: ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"step-indicator-title\"\n      className={cn(\"font-medium wrap-anywhere\", className)}\n      {...props}\n    />\n  );\n}\nexport function StepIndicatorDescription({ className, ...props }: ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"step-indicator-description\"\n      className={cn(\"m-0 text-xs/4 text-muted-foreground\", className)}\n      {...props}\n    />\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/uai/step-indicator.tsx"
    }
  ],
  "categories": [
    "forms"
  ],
  "type": "registry:ui"
}