{
  "name": "Stepper",
  "source": "src/components/Stepper.tsx",
  "propsType": "StepperProps",
  "description": "Stepper — where the user is in a task that has an order.\n\nWHY NOT TABS\n\nThe `tablist` role announces peers that can be visited in any order, which is\nthe opposite of a wizard. This is an ordered list: the steps are a sequence,\nand `ol` says so. Nothing here is a tab, and arrow keys do nothing.\n\nPOSITION AND STATUS ARE TEXT, NOT ONLY DRAWING\n\nEvery step renders \"Step 2 of 5\" and its status as visually hidden text. The\nnumber in the circle is for the eye; a screen reader cannot be relied on to\nannounce list position, and a coloured ring carries nothing in forced-colours\nmode. The complete and error glyphs also differ in SHAPE — a check and an\nexclamation — so the states survive greyscale, which WCAG 1.4.1 requires.\n\nONLY VISITED STEPS ARE LINKS\n\n`href` / `onPress` are honoured on `complete` and `error` steps that are not\ncurrent. An `incomplete` step renders as text even when given one, because\njumping forward past unanswered steps is exactly what a wizard exists to\nprevent — and a link that is there but should not be followed is worse than\nno link. The current step is text for the same reason Breadcrumb's is: a link\nto where you already are is a dead control.\n\nIT DOES NOT ANNOUNCE STEP CHANGES\n\nThe Wizard pattern moves focus to the new step's heading, which announces it.\nA live region here as well would say the same thing twice, on every step.",
  "import": "import { Stepper } from 'ionbase-ui';",
  "status": "stable",
  "summary": "Where the user is in a task that has an order. An ordered list of steps, each stating its position and status in text.",
  "useWhen": [
    "a Wizard — later steps depend on earlier answers and the user needs to see what is left",
    "a multi-page flow such as checkout or onboarding, where the steps are fixed and known in advance"
  ],
  "useInstead": [
    {
      "when": "the sections can be visited in any order",
      "use": "Tabs",
      "why": "tabs promise peers; a stepper promises a sequence, and using one for the other misleads in both directions"
    },
    {
      "when": "the progress is a quantity with no named stages — an upload, an import",
      "use": "ProgressBar",
      "why": "a stepper with no meaningful step names is a progress bar drawn in circles"
    },
    {
      "when": "the steps are an agent's actions rather than the user's",
      "use": "AgentActivity",
      "why": "the user is not moving through those steps; they are supervising them"
    }
  ],
  "variants": {
    "orientation": {
      "horizontal": {
        "use": "the default — a header above the step's form. Below 40rem it keeps only the current label visible"
      },
      "vertical": {
        "use": "a side rail beside the form, or when step names or descriptions are long"
      }
    }
  },
  "slots": {
    "children": {
      "accepts": "StepperStep",
      "note": "first step first, and exactly one with isCurrent"
    }
  },
  "a11y": {
    "requires": [
      "`label` naming the task when a page carries more than one stepper — it defaults to \"Progress\""
    ],
    "guarantees": [
      "every step renders \"Step N of M\" and its status as visually hidden text, derived from the children rather than passed in",
      "the current step carries aria-current=\"step\"",
      "connectors are CSS and never enter the accessibility tree"
    ],
    "notes": [
      "it does not announce step changes. The Wizard pattern moves focus to the new step's heading, which announces it; a live region here would say it twice"
    ]
  },
  "antiPatterns": [
    {
      "dont": "<Tabs> as a wizard's step indicator",
      "do": "<Stepper>",
      "why": "the tablist role announces peers that can be visited in any order, which is the opposite of a wizard"
    },
    {
      "dont": "more than about seven steps",
      "why": "a stepper that has to scroll or wrap no longer shows what is left, which is the only thing it is for — group the steps instead"
    }
  ],
  "stylesheet": "src/styles/stepper.css",
  "tokens": [
    "--border-default",
    "--border-error",
    "--border-focus",
    "--border-primary",
    "--border-strong",
    "--border-width-thick",
    "--border-width-thicker",
    "--font-family-sans",
    "--font-weight-medium",
    "--font-weight-semibold",
    "--icon-error",
    "--icon-primary",
    "--icon-size-lg",
    "--icon-size-sm",
    "--ion-duration-base",
    "--ion-ease-out",
    "--radius-full",
    "--radius-xs",
    "--spacing-16",
    "--spacing-2",
    "--spacing-24",
    "--spacing-4",
    "--spacing-8",
    "--surface-error",
    "--surface-primary",
    "--text-default",
    "--text-error",
    "--text-on-color",
    "--text-secondary",
    "--text-tertiary",
    "--type-body-sm",
    "--type-body-sm-line-height",
    "--type-caption",
    "--type-caption-line-height"
  ],
  "props": {
    "label": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Names the list. Defaults to \"Progress\"; give it the task's name when a page\ncarries more than one — \"Checkout progress\"."
    },
    "orientation": {
      "type": "StepperOrientation | undefined",
      "required": false,
      "origin": "own",
      "description": "`horizontal` for a page-width header above the form, `vertical` for a side\nrail. Below 40rem a horizontal stepper hides every label but the current\none, so it does not need a second variant for mobile.",
      "values": [
        "vertical",
        "horizontal"
      ]
    },
    "children": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own",
      "description": "`StepperStep` elements, first step first."
    },
    "labels": {
      "type": "StepperLabels | undefined",
      "required": false,
      "origin": "own",
      "description": "Every string the steps read out, for translation. English by default.\nGiven once here rather than on each step."
    }
  },
  "propCounts": {
    "own": 4,
    "aria": 0,
    "dom": 277,
    "other": 0
  }
}
