{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "progress",
  "type": "registry:component",
  "title": "Progress",
  "description": "Shows completion for a known process. 4px bar; the label carries the percentage.",
  "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/progress.tsx",
      "content": "import * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n  value: number;\n  max?: number;\n  /** Label above the bar; it names the bar. The percentage lives here, never inside the bar. */\n  label?: React.ReactNode;\n}\n\nconst styles = stylex.create({\n  head: {\n    display: \"flex\",\n    justifyContent: \"space-between\",\n    fontSize: \"0.75rem\",\n    fontWeight: 500,\n    color: vlak.gray,\n    letterSpacing: \"-0.01em\",\n    marginBottom: \"0.4375rem\",\n  },\n  bar: {\n    height: \"0.25rem\",\n    backgroundColor: vlak.dividerSubtle,\n    borderRadius: 2,\n    overflow: \"hidden\",\n  },\n  fill: {\n    display: \"block\",\n    height: \"100%\",\n    backgroundColor: vlak.ink,\n    borderRadius: 2,\n  },\n});\n\nexport const Progress = React.forwardRef<HTMLDivElement, ProgressProps>(function Progress({\n  value,\n  max = 100,\n  label,\n  className,\n  style,\n  \"aria-label\": ariaLabel,\n  \"aria-labelledby\": ariaLabelledBy,\n  ...props\n}, ref) {\n  const labelId = React.useId();\n  const now = Math.min(max, Math.max(0, value));\n  const pct = Math.min(100, Math.max(0, max === 0 ? 0 : (value / max) * 100));\n  const head = rs([\"rs-progress-head\"], styles.head);\n  const bar = rs([\"rs-progress\"], styles.bar);\n  const fill = rs([\"rs-progress-fill\"], styles.fill);\n  const labelledBy = ariaLabelledBy ?? (ariaLabel == null && label != null ? labelId : undefined);\n  return (\n    <div ref={ref} {...props} className={className} style={style}>\n      {label != null && (\n        <div className={head.className} style={head.style}>\n          <span id={labelId}>{label}</span>\n          <span>{Math.round(pct)}%</span>\n        </div>\n      )}\n      <div\n        className={bar.className}\n        style={bar.style}\n        role=\"progressbar\"\n        aria-label={ariaLabel}\n        aria-labelledby={labelledBy}\n        aria-valuemin={0}\n        aria-valuemax={max}\n        aria-valuenow={now}\n        aria-valuetext={`${Math.round(pct)}%`}\n      >\n        <span className={fill.className} style={{ ...fill.style, width: `${pct}%` }} />\n      </div>\n    </div>\n  );\n});\n",
      "type": "registry:component",
      "target": "components/vlak/progress.tsx"
    },
    {
      "path": "vlak/styles/progress.css",
      "content": "/* ── progress: generated from packages/react/src/components/progress.tsx ── */\n.rs-progress-head{display:flex;justify-content:space-between;font-size:0.75rem;font-weight:500;color:var(--text-secondary);letter-spacing:-0.01em;margin-bottom:0.4375rem}\n.rs-progress{height:0.25rem;background-color:var(--divider-subtle);border-radius:2px;overflow:hidden}\n.rs-progress-fill{display:block;height:100%;background-color:var(--text);border-radius:2px}\n",
      "type": "registry:file",
      "target": "styles/vlak/progress.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "feedback",
      "classes": [
        "rs-progress",
        "rs-progress-head",
        "rs-progress-fill"
      ],
      "snippet": "<div class=\"rs-progress-head\"><span id=\"upload-label\">Uploading</span><span>40%</span></div><div class=\"rs-progress\" role=\"progressbar\" aria-labelledby=\"upload-label\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"40\"><span class=\"rs-progress-fill\" style=\"width:40%\"></span></div>",
      "cssOnly": false,
      "registryDependencies": [
        "vlak-lib"
      ],
      "aliases": [
        "Progress",
        "Progress bar",
        "Meter"
      ],
      "example": "import { Progress } from \"@noorddev/vlak-react\";\n\n<Progress label=\"Uploading\" value={40} />\n<Progress value={3} max={5} aria-label=\"Steps done\" />",
      "usage": {
        "use": [
          "Determinate progress with a known total.",
          "label to show the name and the percentage above the bar."
        ],
        "avoid": [
          "Unknown duration; use Spinner.",
          "Static ratios like storage used; a number reads better."
        ]
      },
      "a11y": [
        "Renders role=\"progressbar\" with aria-valuemin, aria-valuemax, aria-valuenow, and aria-valuetext as a percentage.",
        "label names the bar through aria-labelledby; without one, pass aria-label."
      ]
    }
  }
}
