{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "steps",
  "type": "registry:ui",
  "title": "Steps",
  "description": "Horizontal or vertical step indicator showing progress through a multi-stage flow or wizard.",
  "dependencies": [
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/steps.tsx",
      "type": "registry:ui",
      "content": "\"use client\"\n\n/**\n * @fileoverview Numbered step indicator with connector lines.\n * @author Saasflare™\n * A horizontal or vertical step sequence showing progress through stages.\n * Pure visual — no form/wizard logic.\n * @module packages/ui/components/ui/steps\n * @package ui\n *\n * @component\n * @example\n * import { Steps, Step } from '@saasflare/ui';\n * <Steps current={1}>\n *   <Step title=\"Sign Up\" />\n *   <Step title=\"Configure\" />\n *   <Step title=\"Deploy\" />\n * </Steps>\n */\n\nimport { Children, isValidElement, type ReactNode, type ReactElement } from \"react\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\nimport { CheckIcon } from \"@saasflare/ui\"\n\n/** Props for the Steps container. */\nexport interface StepsProps extends SaasflareComponentProps {\n  /** Step children. */\n  children: ReactNode\n  /** Index of the current active step (0-based). Default: `0` */\n  current?: number\n  /** Layout direction. Default: `\"horizontal\"` */\n  direction?: \"horizontal\" | \"vertical\"\n  /** Additional class names. */\n  className?: string\n}\n\n/** Props for an individual Step. */\nexport interface StepProps {\n  /** Step title text. */\n  title: string\n  /** Optional description below the title. */\n  description?: string\n  /** Optional icon to replace the step number. */\n  icon?: ReactNode\n  /**\n   * Marks the step as skippable. Purely cosmetic here — renders a small\n   * \"Optional\" sub-label beneath the title. Consumed by `Stepper` to infer its\n   * `optional` step indices. Default: `false`\n   */\n  optional?: boolean\n  /** Additional class names. */\n  className?: string\n}\n\n/**\n * Step sequence indicator with numbered circles and connector lines.\n *\n * @component\n * @package ui\n */\nexport function Steps({\n  children,\n  current = 0,\n  direction = \"horizontal\",\n  className,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n}: StepsProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  const items = Children.toArray(children).filter(\n    (c): c is ReactElement<StepProps> => isValidElement(c) && c.type === Step,\n  )\n\n  return (\n    <div\n      className={cn(\n        \"flex\",\n        direction === \"horizontal\" ? \"flex-row items-start\" : \"flex-col\",\n        className,\n      )}\n      data-slot=\"steps\"\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      role=\"list\"\n    >\n      {items.map((child, i) => {\n        const status = i < current ? \"completed\" : i === current ? \"active\" : \"pending\"\n        const isLast = i === items.length - 1\n\n        return (\n          <div\n            key={i}\n            className={cn(\n              \"flex\",\n              direction === \"horizontal\"\n                ? \"flex-1 flex-col items-center\"\n                : \"flex-row gap-4\",\n            )}\n            role=\"listitem\"\n            aria-current={status === \"active\" ? \"step\" : undefined}\n          >\n            <div className={cn(\n              \"flex items-center\",\n              direction === \"horizontal\" ? \"w-full\" : \"flex-col\",\n            )}>\n              {/* Circle */}\n              <div\n                className={cn(\n                  \"flex size-9 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold transition-colors\",\n                  status === \"completed\" && \"border-primary bg-primary text-primary-foreground\",\n                  status === \"active\" && \"border-primary bg-background text-primary\",\n                  status === \"pending\" && \"border-muted-foreground/30 bg-background text-muted-foreground\",\n                )}\n              >\n                {status === \"completed\" ? (\n                  <CheckIcon className=\"size-4\" weight={sf.iconWeight} aria-hidden=\"true\" />\n                ) : (\n                  child.props.icon ?? i + 1\n                )}\n              </div>\n\n              {/* Connector line */}\n              {!isLast && (\n                <div\n                  className={cn(\n                    direction === \"horizontal\"\n                      ? \"h-0.5 flex-1\"\n                      : \"w-0.5 min-h-8 flex-1\",\n                    status === \"completed\" ? \"bg-primary\" : \"bg-border\",\n                  )}\n                />\n              )}\n            </div>\n\n            {/* Text */}\n            <div className={cn(\n              direction === \"horizontal\" ? \"mt-2 text-center\" : \"pb-8\",\n            )}>\n              <p className={cn(\n                \"text-sm font-medium\",\n                status === \"pending\" && \"text-muted-foreground\",\n              )}>\n                {child.props.title}\n              </p>\n              {child.props.description && (\n                <p className=\"mt-0.5 text-xs text-muted-foreground\">\n                  {child.props.description}\n                </p>\n              )}\n              {child.props.optional && (\n                <p className=\"mt-0.5 text-xs text-muted-foreground/70 italic\">\n                  Optional\n                </p>\n              )}\n            </div>\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n\n/**\n * Individual step within a Steps container.\n * This component is a data carrier — it renders nothing on its own.\n *\n * @component\n * @package ui\n */\nexport function Step(_props: StepProps) {\n  return null\n}\n",
      "target": "components/ui/steps.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/steps.json"
  }
}
