{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stepper",
  "type": "registry:component",
  "title": "Stepper",
  "description": "Shows progress through ordered steps. 1px connectors; done fills with ink, active is outlined.",
  "registryDependencies": [
    "https://vlak.dev/r/vlak-base.json",
    "https://vlak.dev/r/inter.json",
    "https://vlak.dev/r/vlak-lib.json"
  ],
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "devDependencies": [
    "@stylexjs/babel-plugin"
  ],
  "docs": "Vlak leaves are StyleX. Compile them with @stylexjs/babel-plugin (Vite: @stylexjs/unplugin, Next: @stylexjs/nextjs-plugin). If you would rather not run a compiler, import @noorddev/vlak-react instead: it ships precompiled with one stylesheet.",
  "files": [
    {
      "path": "vlak/stepper.tsx",
      "content": "import * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak, mq } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\n\nexport interface Step {\n  name: React.ReactNode;\n  sub?: React.ReactNode;\n}\n\nexport interface StepperProps extends React.HTMLAttributes<HTMLDivElement> {\n  steps: Step[];\n  /** 0-based index of the active step; everything before it is done. */\n  current: number;\n}\n\nconst styles = stylex.create({\n  steps: {\n    display: \"flex\",\n    alignItems: \"flex-start\",\n    width: \"100%\",\n    maxWidth: \"100%\",\n    gap: 0,\n  },\n  step: {\n    position: \"relative\",\n    display: \"flex\",\n    flexDirection: \"column\",\n    alignItems: \"flex-start\",\n    gap: {\n      default: \"0.1875rem\",\n      [mq.phone]: \"0.375rem\",\n    },\n    flexGrow: 1,\n    flexShrink: 1,\n    flexBasis: 0,\n    minWidth: 0,\n  },\n  dot: {\n    boxSizing: \"border-box\",\n    width: {\n      default: \"1.5rem\",\n      [mq.phone]: vlak.hit,\n    },\n    height: {\n      default: \"1.5rem\",\n      [mq.phone]: vlak.hit,\n    },\n    borderRadius: \"50%\",\n    borderWidth: 1.5,\n    borderStyle: \"solid\",\n    borderColor: vlak.divider,\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    fontSize: {\n      default: \"0.6875rem\",\n      [mq.phone]: \"0.9375rem\",\n    },\n    fontWeight: 600,\n    color: vlak.gray,\n    marginBottom: {\n      default: \"0.375rem\",\n      [mq.phone]: \"0.5rem\",\n    },\n    backgroundColor: vlak.paper,\n    position: \"relative\",\n    zIndex: 1,\n  },\n  done: {\n    backgroundColor: vlak.ink,\n    borderColor: vlak.ink,\n    color: vlak.paper,\n  },\n  active: {\n    borderColor: vlak.ink,\n    color: vlak.ink,\n  },\n  name: {\n    fontSize: {\n      default: \"0.8125rem\",\n      [mq.phone]: vlak.controlFs,\n    },\n    fontWeight: 600,\n    letterSpacing: \"-0.01em\",\n    color: vlak.ink,\n    lineHeight: 1.2,\n  },\n  sub: {\n    fontSize: {\n      default: \"0.6875rem\",\n      [mq.phone]: \"0.8125rem\",\n    },\n    fontWeight: 500,\n    color: vlak.gray,\n    letterSpacing: \"-0.01em\",\n  },\n  line: {\n    position: \"absolute\",\n    top: {\n      default: \"0.71875rem\",\n      [mq.phone]: `calc(${vlak.hit} / 2)`,\n    },\n    insetInlineStart: {\n      default: \"1.5rem\",\n      [mq.phone]: vlak.hit,\n    },\n    insetInlineEnd: 0,\n    height: vlak.hairline,\n    backgroundColor: vlak.divider,\n    margin: 0,\n    minWidth: 0,\n    zIndex: 0,\n  },\n});\n\nexport const Stepper = React.forwardRef<HTMLDivElement, StepperProps>(function Stepper(\n  { steps, current, className, style, ...props },\n  ref,\n) {\n  const root = rs([\"rs-steps\", className], styles.steps);\n  return (\n    <div ref={ref} {...props} className={root.className} style={{ ...root.style, ...style }}>\n      {steps.map((step, index) => {\n        const row = rs([\"rs-step\"], styles.step);\n        const dot = rs(\n          [\"rs-step-dot\", index < current && \"rs-step-done\", index === current && \"rs-step-active\"],\n          styles.dot,\n          index < current && styles.done,\n          index === current && styles.active,\n        );\n        const line = rs([\"rs-step-line\"], styles.line);\n        const name = rs([\"rs-step-name\"], styles.name);\n        const sub = rs([\"rs-step-sub\"], styles.sub);\n        return (\n          <div key={index} className={row.className} style={row.style} aria-current={index === current ? \"step\" : undefined}>\n            <span className={dot.className} style={dot.style}>\n              {index + 1}\n            </span>\n            {index < steps.length - 1 && <span className={line.className} style={line.style} aria-hidden=\"true\" />}\n            <span className={name.className} style={name.style}>\n              {step.name}\n            </span>\n            {step.sub != null && (\n              <span className={sub.className} style={sub.style}>\n                {step.sub}\n              </span>\n            )}\n          </div>\n        );\n      })}\n    </div>\n  );\n});\n",
      "type": "registry:component",
      "target": "components/vlak/stepper.tsx"
    },
    {
      "path": "vlak/styles/stepper.css",
      "content": "/* ── stepper: generated from packages/react/src/components/stepper.tsx ── */\n.rs-steps{display:flex;align-items:flex-start;width:100%;max-width:100%;gap:0}\n.rs-step{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:0.1875rem;flex-grow:1;flex-shrink:1;flex-basis:0;min-width:0}\n@media (max-width: 640px){.rs-step{gap:0.375rem}}\n.rs-step-dot{box-sizing:border-box;width:1.5rem;height:1.5rem;border-radius:50%;border-width:1.5px;border-style:solid;border-color:var(--divider);display:flex;align-items:center;justify-content:center;font-size:0.6875rem;font-weight:600;color:var(--text-secondary);margin-bottom:0.375rem;background-color:var(--bg);position:relative;z-index:1}\n@media (max-width: 640px){.rs-step-dot{width:var(--hit);height:var(--hit);font-size:0.9375rem;margin-bottom:0.5rem}}\n.rs-step-done{background-color:var(--text);border-color:var(--text);color:var(--bg)}\n.rs-step-active{border-color:var(--text);color:var(--text)}\n.rs-step-name{font-size:0.8125rem;font-weight:600;letter-spacing:-0.01em;color:var(--text);line-height:1.2}\n@media (max-width: 640px){.rs-step-name{font-size:var(--control-fs)}}\n.rs-step-sub{font-size:0.6875rem;font-weight:500;color:var(--text-secondary);letter-spacing:-0.01em}\n@media (max-width: 640px){.rs-step-sub{font-size:0.8125rem}}\n.rs-step-line{position:absolute;top:0.71875rem;inset-inline-start:1.5rem;inset-inline-end:0;height:1px;background-color:var(--divider);margin:0;min-width:0;z-index:0}\n@media (max-width: 640px){.rs-step-line{top:calc(var(--hit) / 2);inset-inline-start:var(--hit)}}\n",
      "type": "registry:file",
      "target": "styles/vlak/stepper.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "navigation",
      "classes": [
        "rs-steps",
        "rs-step",
        "rs-step-dot",
        "rs-step-done",
        "rs-step-active",
        "rs-step-name",
        "rs-step-sub",
        "rs-step-line"
      ],
      "snippet": "<div class=\"rs-steps\"><div class=\"rs-step\"><span class=\"rs-step-dot rs-step-done\">1</span><span class=\"rs-step-line\"></span><span class=\"rs-step-name\">Brief</span></div><div class=\"rs-step\"><span class=\"rs-step-dot rs-step-active\">2</span><span class=\"rs-step-name\">Design</span></div></div>",
      "cssOnly": false,
      "registryDependencies": [
        "vlak-lib"
      ],
      "aliases": [
        "Stepper",
        "Steps",
        "Progress steps",
        "Wizard"
      ],
      "example": "import { Stepper } from \"@noorddev/vlak-react\";\n\n<Stepper steps={[{ name: \"Brief\" }, { name: \"Design\", sub: \"In review\" }, { name: \"Build\" }]} current={1} />",
      "usage": {
        "use": [
          "A fixed sequence of three to six steps where the user should see what is done and what is next.",
          "sub for a short status under a step."
        ],
        "avoid": [
          "Steps the user can jump between; use Tabs.",
          "Progress of one task; use Progress."
        ]
      },
      "a11y": [
        "The active step carries aria-current=\"step\"; connector lines are aria-hidden.",
        "The dots are numbered text, so the order reads without color."
      ]
    }
  }
}
