{
  "generatedFrom": "progress.contract.json",
  "component": "Progress",
  "slug": "progress",
  "group": "Feedback",
  "tier": "leaf-lit",
  "summary": "A determinate progress indicator — completion, upload, a quiz timer — as a line, segmented steps, or a circle.",
  "install": {
    "package": "@ahaslides-product/design",
    "registry": "https://npm.pkg.github.com",
    "scope": "@ahaslides-product",
    "auth": "Published to GitHub Packages — needs a GitHub token with read:packages. Configure the @ahaslides-product scope in .npmrc before installing.",
    "npmrc": "@ahaslides-product:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}   # a GitHub token with read:packages",
    "command": "npm i @ahaslides-product/design",
    "tokenLayer": "import '@ahaslides-product/design/tokens.css';",
    "import": "import '@ahaslides-product/design/aha-progress';",
    "element": "aha-progress",
    "registers": "aha-progress"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/progress/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/progress/progress.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/progress.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/progress.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-progress> is a standard custom element that renders on open — React/Vue are thin adapters over the same element. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "via": "web-component",
      "ref": "aha-progress"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-progress"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-progress",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "percent",
      "type": "number",
      "default": "0",
      "desc": "Completion 0–100; clamped and drives the fill"
    },
    {
      "name": "type",
      "type": "'line' | 'circle'",
      "default": "line",
      "desc": "Shape: horizontal bar or SVG ring"
    },
    {
      "name": "steps",
      "type": "number",
      "default": "0",
      "desc": "Split a line into N discrete segments (line type only)"
    },
    {
      "name": "size",
      "type": "'default' | 'small'",
      "default": "default",
      "desc": "Compact Mini variant (thinner bar / smaller ring)"
    },
    {
      "name": "status",
      "type": "default | active | success | warning | exception",
      "default": "default",
      "desc": "Fill colour (exception aliases error)"
    },
    {
      "name": "show-info",
      "type": "boolean",
      "default": "true",
      "desc": "Show the trailing percent/glyph label (set 'false' to hide)"
    }
  ],
  "tokens": [
    "color-primary",
    "color-success",
    "color-warning",
    "color-error",
    "gray-30",
    "radius-pill",
    "text-secondary",
    "text-positive",
    "text-negative"
  ],
  "spec": [
    {
      "label": "Track",
      "value": "line height 8 (small 6) · radius pill · #F1F1F1"
    },
    {
      "label": "Fill",
      "value": "default primary #6A1EBB · width (line) or stroke-dashoffset (circle) = percent"
    },
    {
      "label": "Type",
      "value": "line (default) · circle (SVG ring, box 96 / small 40)"
    },
    {
      "label": "Steps",
      "value": "steps=N → N equal segments, first round(percent) filled"
    },
    {
      "label": "Status",
      "value": "active primary · success #16C49A · warning #FF7747 · exception #F5222D"
    },
    {
      "label": "Motion",
      "value": "width / stroke-dashoffset animate on --aha-motion-slow / --aha-ease-out"
    },
    {
      "label": "Info",
      "value": "percent label (✓/✕ glyph at success/exception); hide with show-info=false"
    },
    {
      "label": "A11y",
      "value": "role=progressbar · aria-valuemin 0 / valuemax 100 / valuenow synced to percent"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Progress",
        "when": "a determinate task with a known percentage (upload, steps, a timer)"
      },
      {
        "what": "Spin",
        "when": "an indeterminate wait with no measurable percentage"
      },
      {
        "what": "Skeleton",
        "when": "content is loading and you want to hold its layout"
      }
    ],
    "note": "Use Progress only when you can measure completion. A line for inline flow, steps for a discrete multi-stage task, a circle for a compact score dial. Let the fill colour carry success/exception, not a separate label. For an indeterminate wait use Spin.",
    "dsv3": "COVERED — enumerated from the DS V3 Progress component-set taxonomy: Progress line (Bare · Status Success/Exception), Progress-Line-Mini (small size · Success/Exception), Progress-Circle + Progress-Circle-Mini (Status Normal/Success/Exception), Progress-Step (Default/Small). i.e. the family carries type (line · circle), size (default · Mini/small), steps, and status (normal/success/exception; antd adds active/warning). No measured px cell exists; sizes/colours derived from the token layer (fill color-primary + status color-success/warning/error, track gray-30, radius-pill) and antd Progress conventions (8px line, trailing percent). A deliberate, documented extension."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "audience"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-progress> is the SAME shared custom element React and Vue consume — here in its\n     native form. Theming comes only from the --aha-* tokens in tokens.css.\n     type: line (default) | circle · size: default | small · steps: N (segmented line) ·\n     status: default | active | success | warning | exception · show-info=\"false\" hides the label. -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css\">\n<script type=\"module\">\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/icons.js';       // <aha-icon> for the status glyph\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-progress.js'; // registers <aha-progress>\n</script>\n\n<div style=\"display:flex; flex-direction:column; gap:16px; max-width:320px\">\n  <aha-progress percent=\"30\"></aha-progress>\n  <aha-progress percent=\"70\" status=\"warning\"></aha-progress>\n  <aha-progress percent=\"100\" status=\"success\"></aha-progress>\n  <aha-progress size=\"small\" percent=\"50\"></aha-progress>\n  <aha-progress steps=\"5\" percent=\"60\"></aha-progress>\n  <aha-progress type=\"circle\" percent=\"75\"></aha-progress>\n</div>\n",
    "react": "import '@ahaslides-product/design/aha-progress';   // registers <aha-progress>\nimport '@ahaslides-product/design/icons';          // registers <aha-icon> for the status glyph\n\n// Attributes only — no events — so React 18/19 can render the element directly.\nfunction AhaProgress({ percent, status, type, size, steps }) {\n  return <aha-progress percent={percent} status={status} type={type} size={size} steps={steps} />;\n}\n\n// usage\n<AhaProgress percent={uploaded} status={failed ? 'exception' : 'default'} />\n<AhaProgress type=\"circle\" percent={score} status=\"success\" />\n<AhaProgress steps={5} percent={stepPct} size=\"small\" />\n",
    "vue": "// main.ts — register the elements + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-progress';\nimport '@ahaslides-product/design/icons';   // <aha-icon> for the status glyph\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref } from 'vue';\nconst uploaded = ref(70);\nconst score = ref(75);\n</script>\n\n<template>\n  <aha-progress :percent=\"uploaded\" status=\"success\" />\n  <aha-progress type=\"circle\" :percent=\"score\" />\n  <aha-progress :steps=\"5\" :percent=\"uploaded\" size=\"small\" />\n</template>\n"
  }
}
