{
 "id": "progress-steps",
 "name": "Progress with steps",
 "purpose": "Progress for a long task: a bar with a percentage, the time left, each step done, now and next, and a way to keep working while it runs.",
 "use_when": [
  "for long tasks (imports, exports, uploads, migrations) that take more than a few seconds",
  "a task takes longer than about 10 seconds",
  "the task has steps the person would recognise"
 ],
 "avoid_when": [
  "waits of a few seconds: use inline-spinner",
  "unknown length with no steps: say what is happening and show an indeterminate bar"
 ],
 "type": "states",
 "style": "quiet",
 "width": "medium",
 "tags": {
  "audience": "work",
  "industries": [
   "any"
  ],
  "keywords": [
   "progress",
   "steps",
   "import",
   "long task",
   "background"
  ]
 },
 "root": ".odl-progress-steps",
 "parts": [
  {
   "name": "title",
   "selector": ".odl-progress-steps [data-od-slot=\"title\"]",
   "what": "the heading: what happened, in plain words, as in “Importing 4,812 contacts”",
   "slot": "text"
  },
  {
   "name": "progress",
   "selector": ".odl-progress-steps [data-od-measure=\"progress\"]",
   "what": "how far the task has got, 0 to 1",
   "slot": "number"
  },
  {
   "name": "left",
   "selector": ".odl-progress-steps [data-od-slot=\"left\"]",
   "what": "time left and what the person can do meanwhile, as in “About 2 minutes left. You can close this page; w”",
   "slot": "text"
  },
  {
   "name": "steps",
   "selector": ".odl-progress-steps [data-od-list=\"steps\"]",
   "what": "the steps, one item each",
   "slot": "list"
  },
  {
   "name": "steps.state",
   "selector": ".odl-progress-steps [data-od-list=\"steps\"] [data-od-var=\"state\"]",
   "what": "done, now or next",
   "slot": "text"
  },
  {
   "name": "steps.label",
   "selector": ".odl-progress-steps [data-od-list=\"steps\"] [data-od-slot=\"label\"]",
   "what": "the visible label, as in “Upload file”",
   "slot": "text"
  },
  {
   "name": "cancel",
   "selector": ".odl-progress-steps [data-od-action=\"cancel\"]",
   "what": "the Cancel import action",
   "slot": "action"
  },
  {
   "name": "background",
   "selector": ".odl-progress-steps [data-od-action=\"background\"]",
   "what": "the Keep working action",
   "slot": "action"
  }
 ],
 "data": {
  "type": "object",
  "properties": {
   "title": {
    "type": "string",
    "maxLength": 32,
    "part": "title"
   },
   "progress": {
    "type": "number",
    "minimum": 0,
    "maximum": 1,
    "part": "progress"
   },
   "left": {
    "type": "string",
    "maxLength": 96,
    "part": "left"
   },
   "steps": {
    "type": "array",
    "minItems": 1,
    "maxItems": 8,
    "items": {
     "type": "object",
     "properties": {
      "state": {
       "enum": [
        "done",
        "next",
        "now"
       ],
       "part": "steps.state"
      },
      "label": {
       "type": "string",
       "maxLength": 24,
       "part": "steps.label"
      }
     },
     "required": [
      "state",
      "label"
     ]
    },
    "part": "steps"
   }
  },
  "required": [
   "title",
   "progress",
   "left",
   "steps"
  ]
 },
 "states": {
  "shown": [
   "step done",
   "current step",
   "next step",
   "in progress",
   "hover",
   "focus"
  ],
  "edge": {
   "empty": {
    "status": "handled",
    "evidence": "data-od-list",
    "how": "the Smart UI renderer puts one plain 'Nothing to show yet.' line in an empty list"
   },
   "loading": {
    "status": "shown",
    "how": "This part is the long-wait state: a bar, a percentage and the steps.",
    "evidence": "role=\"progressbar\""
   },
   "error": {
    "status": "not_built",
    "how": "A failed step should turn its dot to the danger colour, say what failed and offer Retry from that step; not drawn here."
   },
   "disabled": {
    "status": "not_built",
    "how": "No control here is ever disabled; each one always does something."
   },
   "overflow": {
    "status": "handled",
    "how": "Buttons stack under 26rem.",
    "evidence": "column-reverse"
   },
   "long_text": {
    "status": "handled",
    "how": "Titles balance and body text wraps at word boundaries inside a capped measure.",
    "evidence": "text-wrap"
   },
   "missing_image": {
    "status": "none",
    "how": "the part has no photo"
   }
  }
 },
 "tokens": [
  "--ds-border-width-default",
  "--ds-border-width-emphasis",
  "--ds-color-bg-accent-bold",
  "--ds-color-bg-action-primary",
  "--ds-color-bg-action-primary-hover",
  "--ds-color-bg-action-primary-pressed",
  "--ds-color-bg-neutral-subtle",
  "--ds-color-bg-success-bold",
  "--ds-color-border-accent",
  "--ds-color-border-default",
  "--ds-color-border-focus",
  "--ds-color-border-subtle",
  "--ds-color-surface-raised",
  "--ds-color-text-link",
  "--ds-color-text-on-action",
  "--ds-color-text-on-success",
  "--ds-color-text-primary",
  "--ds-color-text-secondary",
  "--ds-focus-ring-offset",
  "--ds-focus-ring-width",
  "--ds-font-weight-heading",
  "--ds-font-weight-label",
  "--ds-icon-stroke-lg",
  "--ds-icon-stroke-md",
  "--ds-motion-duration-medium",
  "--ds-motion-duration-short",
  "--ds-motion-easing-standard",
  "--ds-opacity-disabled-container",
  "--ds-radius-container",
  "--ds-radius-control",
  "--ds-radius-full",
  "--ds-size-control-md",
  "--ds-size-icon-md",
  "--ds-size-icon-sm",
  "--ds-size-target-min",
  "--ds-space-8",
  "--ds-space-inline-md",
  "--ds-space-inline-sm",
  "--ds-space-inset-lg",
  "--ds-space-inset-md",
  "--ds-space-inset-sm",
  "--ds-space-inset-xl",
  "--ds-space-stack-lg",
  "--ds-space-stack-md",
  "--ds-space-stack-xl",
  "--ds-space-stack-xs",
  "--ds-text-body-md",
  "--ds-text-body-sm",
  "--ds-text-label-lg",
  "--ds-text-numeric-md",
  "--ds-text-title-md"
 ],
 "a11y": {
  "summary": "The bar is a progressbar with a value and a text value; steps are an ordered list with the current one marked aria-current; a polite status line names the current step; update it when the step changes, not on every percent.",
  "roles": [
   "list",
   "progressbar",
   "region",
   "status"
  ],
  "keyboard": [
   "Tab reaches Cancel import, then Keep working"
  ],
  "controls": {
   "button": 2,
   "input": 0,
   "link": 0,
   "select": 0,
   "textarea": 0,
   "summary": 0
  },
  "focus_visible": true,
  "reduced_motion": true,
  "min_target": true
 },
 "files": {
  "html": "components/progress-steps/component.html",
  "bytes": 8996,
  "script": false
 },
 "source": null,
 "photos": 0,
 "urls": {
  "html": "https://opendesigner.dev/library/progress-steps.html",
  "json": "https://opendesigner.dev/library/progress-steps.json",
  "page": "https://opendesigner.dev/library/progress-steps/"
 },
 "get": {
  "curl": "curl -fsSLo progress-steps.html https://opendesigner.dev/library/progress-steps.html",
  "opendesigner": "python3 path/to/skills/opendesigner/scripts/library.py add progress-steps --from https://opendesigner.dev",
  "prompt": "Add the OpenDesigner component progress-steps to this project: https://opendesigner.dev/library/progress-steps.html. Keep its markup and states; map its --ds-* variables to my tokens."
 }
}
