{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "steps",
  "title": "Steps",
  "description": "Where someone is in a fixed sequence. Each status has a shape and a spoken label.",
  "registryDependencies": [
    "https://creance.pages.dev/r/creance-base.json"
  ],
  "files": [
    {
      "path": "steps/Steps.css",
      "content": "/* The wrapper is the container, so a horizontal list can stack when it runs out of room. */\n.cr-steps {\n  container-type: inline-size;\n  color: var(--cr-color-text-default);\n  font-family: var(--cr-font-family-sans);\n}\n\n.cr-steps__list {\n  display: flex;\n  align-items: flex-start;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n\n/* A step is its marker with the line running on to the next marker, then its text beneath. */\n.cr-steps__step {\n  display: flex;\n  flex: 1 1 0;\n  flex-direction: column;\n  gap: var(--cr-space-2);\n  min-width: 0;\n}\n\n.cr-steps__step:last-child {\n  flex: none;\n}\n\n.cr-steps__rail {\n  display: flex;\n  align-items: center;\n  gap: var(--cr-space-3);\n  padding-inline-end: var(--cr-space-3);\n}\n\n.cr-steps__marker {\n  display: grid;\n  place-items: center;\n  flex: none;\n  width: 28px;\n  height: 28px;\n  border-radius: var(--cr-radius-full);\n  background: var(--cr-color-bg-subtle);\n  color: var(--cr-color-text-muted);\n  font-size: var(--cr-font-size-sm);\n  font-weight: var(--cr-font-weight-bold);\n}\n\n.cr-steps__line {\n  flex: 1;\n  height: 2px;\n  border-radius: 2px;\n  background: var(--cr-color-border-strong);\n}\n\n.cr-steps__step:last-child .cr-steps__line {\n  display: none;\n}\n\n.cr-steps__text {\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n  padding-inline-end: var(--cr-space-4);\n}\n\n.cr-steps__title {\n  color: var(--cr-color-text-muted);\n  font-size: var(--cr-font-size-md);\n  font-weight: var(--cr-font-weight-semibold);\n}\n\n.cr-steps__description {\n  color: var(--cr-color-text-muted);\n  font-size: var(--cr-font-size-sm);\n}\n\n.cr-steps__step[data-status='done'] .cr-steps__marker {\n  background: var(--cr-color-ink-bg);\n  color: var(--cr-color-ink-fg);\n}\n\n.cr-steps__step[data-status='done'] .cr-steps__line {\n  background: var(--cr-color-ink-bg);\n}\n\n.cr-steps__step[data-status='current'] .cr-steps__marker {\n  background: var(--cr-color-bg-raised);\n  box-shadow: 0 0 0 2px var(--cr-color-ink-bg);\n  color: var(--cr-color-text-default);\n}\n\n.cr-steps__step[data-status='done'] .cr-steps__title,\n.cr-steps__step[data-status='current'] .cr-steps__title {\n  color: var(--cr-color-text-default);\n}\n\n.cr-steps__step[data-status='error'] .cr-steps__marker {\n  background: var(--cr-color-status-failed-bg);\n  box-shadow: 0 0 0 1.5px var(--cr-color-danger-text);\n  color: var(--cr-color-danger-text);\n}\n\n.cr-steps__step[data-status='error'] .cr-steps__title {\n  color: var(--cr-color-danger-text);\n}\n\n/* Vertical: the marker and line form a column beside the text. */\n.cr-steps[data-orientation='vertical'] .cr-steps__list {\n  flex-direction: column;\n}\n\n.cr-steps[data-orientation='vertical'] .cr-steps__step {\n  flex: none;\n  flex-direction: row;\n  gap: var(--cr-space-3);\n}\n\n.cr-steps[data-orientation='vertical'] .cr-steps__rail {\n  flex-direction: column;\n  gap: 6px;\n  padding: 0;\n}\n\n.cr-steps[data-orientation='vertical'] .cr-steps__line {\n  width: 2px;\n  min-height: 20px;\n  height: auto;\n  margin-bottom: 6px;\n}\n\n.cr-steps[data-orientation='vertical'] .cr-steps__text {\n  padding: 3px 0 var(--cr-space-4);\n}\n\n.cr-steps[data-orientation='vertical'] .cr-steps__step:last-child .cr-steps__text {\n  padding-bottom: 0;\n}\n\n@container (max-width: 480px) {\n  .cr-steps[data-orientation='horizontal'] .cr-steps__list {\n    flex-direction: column;\n  }\n\n  .cr-steps[data-orientation='horizontal'] .cr-steps__step {\n    flex: none;\n    flex-direction: row;\n    gap: var(--cr-space-3);\n  }\n\n  .cr-steps[data-orientation='horizontal'] .cr-steps__rail {\n    flex-direction: column;\n    gap: 6px;\n    padding: 0;\n  }\n\n  .cr-steps[data-orientation='horizontal'] .cr-steps__line {\n    width: 2px;\n    min-height: 20px;\n    height: auto;\n    margin-bottom: 6px;\n  }\n\n  .cr-steps[data-orientation='horizontal'] .cr-steps__text {\n    padding: 3px 0 var(--cr-space-4);\n  }\n}\n",
      "type": "registry:file",
      "target": "@components/creance/steps/Steps.css"
    },
    {
      "path": "steps/Steps.tsx",
      "content": "import type { ReactNode } from 'react';\nimport { cx } from '@/lib/creance/cx';\nimport { CheckIcon, CrossIcon } from '@/lib/creance/icons';\nimport { VisuallyHidden } from '@/lib/creance/VisuallyHidden';\nimport './Steps.css';\n\nexport type StepStatus = 'done' | 'current' | 'upcoming' | 'error';\n\nexport interface StepItem {\n  title: ReactNode;\n  description?: ReactNode;\n  /** Overrides the status worked out from `current`. Use `error` for a step that failed. */\n  status?: StepStatus;\n}\n\nexport interface StepsProps {\n  steps: StepItem[];\n  /** Index of the step in progress. Earlier steps are done, later ones are upcoming. Pass `steps.length` when all are done. Default 0. */\n  current?: number;\n  /** A narrow horizontal list stacks vertically by itself. */\n  orientation?: 'horizontal' | 'vertical';\n  /** Accessible name of the list. Default \"Progress\". */\n  label?: string;\n  /** What screen readers hear for each status. */\n  statusLabels?: Partial<Record<StepStatus, string>>;\n  className?: string;\n}\n\nconst defaults: Record<StepStatus, string> = { done: 'Done', current: 'Current step', upcoming: 'Not started', error: 'Failed' };\n\n/** Where someone is in a fixed sequence. Each status has a shape and a spoken label, not only a colour. */\nexport function Steps({ steps, current = 0, orientation = 'horizontal', label = 'Progress', statusLabels, className }: StepsProps) {\n  const names = { ...defaults, ...statusLabels };\n  return (\n    <div className={cx('cr-steps', className)} data-orientation={orientation}>\n      <ol className=\"cr-steps__list\" aria-label={label}>\n        {steps.map((step, i) => {\n          const status = step.status ?? (i < current ? 'done' : i === current ? 'current' : 'upcoming');\n          return (\n            <li key={i} className=\"cr-steps__step\" data-status={status} aria-current={status === 'current' ? 'step' : undefined}>\n              <span className=\"cr-steps__rail\">\n                <span className=\"cr-steps__marker\" aria-hidden=\"true\">\n                  {status === 'done' ? <CheckIcon /> : status === 'error' ? <CrossIcon /> : i + 1}\n                </span>\n                <span className=\"cr-steps__line\" aria-hidden=\"true\" />\n              </span>\n              <span className=\"cr-steps__text\">\n                <span className=\"cr-steps__title\">\n                  {step.title}\n                  <VisuallyHidden>, {names[status]}</VisuallyHidden>\n                </span>\n                {step.description && <span className=\"cr-steps__description\">{step.description}</span>}\n              </span>\n            </li>\n          );\n        })}\n      </ol>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/creance/steps/Steps.tsx"
    }
  ],
  "categories": [
    "molecule",
    "navigation"
  ],
  "type": "registry:ui"
}