{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "progress",
  "title": "Progress",
  "author": "Tori Bryan",
  "description": "Shows how far a task has got, or that it's under way.",
  "dependencies": [
    "@base-ui/react",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/progress.tsx",
      "content": "\"use client\"\n\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst progressVariants = cva(\"\", {\n  variants: {\n    type: {\n      bar: \"flex w-full flex-wrap gap-3\",\n      // A ring in the current text color, so it takes the color of the\n      // button or row it sits in.\n      circle: \"inline-flex shrink-0 align-middle\",\n    },\n    size: {\n      xs: \"\",\n      sm: \"\",\n      default: \"\",\n      lg: \"\",\n    },\n  },\n  compoundVariants: [\n    { type: \"circle\", size: \"xs\", className: \"size-3\" },\n    { type: \"circle\", size: \"sm\", className: \"size-4\" },\n    { type: \"circle\", size: \"default\", className: \"size-5\" },\n    { type: \"circle\", size: \"lg\", className: \"size-6\" },\n  ],\n  defaultVariants: {\n    type: \"bar\",\n    size: \"default\",\n  },\n})\n\n// Radius 9 in a 24-unit box leaves room for the stroke at every size.\nconst RING = 2 * Math.PI * 9\n\n/*\n * A bar's children sit above the track, so a ProgressLabel and a\n * ProgressValue placed inside line up on one row over it. A circle has no\n * room for them: name it with aria-label.\n */\nfunction Progress({\n  className,\n  children,\n  type = \"bar\",\n  size = \"default\",\n  value,\n  min = 0,\n  max = 100,\n  ...props\n}: ProgressPrimitive.Root.Props &\n  VariantProps<typeof progressVariants> & {\n    /** `bar` across its container, or `circle`, a ring that fits in a button or beside text. */\n    type?: \"bar\" | \"circle\"\n    /** The circle's size: 12, 16, 20 or 24 pixels. A bar ignores it. */\n    size?: \"xs\" | \"sm\" | \"default\" | \"lg\"\n  }) {\n  return (\n    <ProgressPrimitive.Root\n      data-slot=\"progress\"\n      data-type={type}\n      value={value}\n      min={min}\n      max={max}\n      className={cn(progressVariants({ type, size }), className)}\n      {...props}\n    >\n      {type === \"circle\" ? (\n        <ProgressCircle\n          share={\n            value === null || value === undefined\n              ? null\n              : (value - min) / (max - min || 1)\n          }\n        />\n      ) : (\n        <>\n          {children}\n          <ProgressTrack>\n            <ProgressIndicator />\n          </ProgressTrack>\n        </>\n      )}\n    </ProgressPrimitive.Root>\n  )\n}\n\nfunction ProgressCircle({ share }: { share: number | null }) {\n  const length = share === null ? 0.25 : Math.min(1, Math.max(0, share))\n  return (\n    <svg\n      data-slot=\"progress-circle\"\n      aria-hidden=\"true\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      className={cn(\n        \"size-full\",\n        // With no value, a quarter arc turns. Under reduced motion it holds\n        // still, and the ring still says something is under way.\n        share === null && \"animate-spin motion-reduce:animate-none\"\n      )}\n    >\n      <circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"9\"\n        strokeWidth=\"3\"\n        className=\"stroke-current opacity-20\"\n      />\n      <circle\n        data-slot=\"progress-circle-indicator\"\n        cx=\"12\"\n        cy=\"12\"\n        r=\"9\"\n        strokeWidth=\"3\"\n        strokeLinecap=\"round\"\n        strokeDasharray={`${length * RING} ${RING}`}\n        transform=\"rotate(-90 12 12)\"\n        className=\"stroke-current transition-[stroke-dasharray] duration-300 motion-reduce:transition-none\"\n      />\n    </svg>\n  )\n}\n\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\n  return (\n    <ProgressPrimitive.Track\n      data-slot=\"progress-track\"\n      className={cn(\n        \"relative flex h-1.5 w-full items-center overflow-x-hidden rounded-full bg-input\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ProgressIndicator({\n  className,\n  ...props\n}: ProgressPrimitive.Indicator.Props) {\n  return (\n    <ProgressPrimitive.Indicator\n      data-slot=\"progress-indicator\"\n      className={cn(\n        // With no value Base UI sets no width, so an indeterminate bar\n        // would look empty. It gets a sweeping segment instead, or under\n        // reduced motion a full bar in the muted text color.\n        \"h-full rounded-full bg-primary transition-all data-indeterminate:w-1/3 data-indeterminate:animate-progress-indeterminate motion-reduce:transition-none motion-reduce:data-indeterminate:w-full motion-reduce:data-indeterminate:animate-none motion-reduce:data-indeterminate:bg-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\n  return (\n    <ProgressPrimitive.Label\n      data-slot=\"progress-label\"\n      className={cn(\"text-sm font-medium\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\n  return (\n    <ProgressPrimitive.Value\n      data-slot=\"progress-value\"\n      className={cn(\n        \"ml-auto font-mono text-sm text-muted-foreground tabular-nums\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Progress,\n  progressVariants,\n  ProgressTrack,\n  ProgressIndicator,\n  ProgressLabel,\n  ProgressValue,\n}\n",
      "type": "registry:ui"
    }
  ],
  "cssVars": {
    "theme": {
      "animate-progress-indeterminate": "progress-indeterminate 1.4s ease-in-out infinite"
    }
  },
  "css": {
    "@keyframes progress-indeterminate": {
      "from": {
        "transform": "translateX(-100%)"
      },
      "to": {
        "transform": "translateX(300%)"
      }
    }
  },
  "meta": {
    "tier": "base-components",
    "group": "Feedback",
    "docs": "https://fibo.toribryan.com/?path=/docs/base-components-feedback-progress--docs"
  },
  "docs": "Docs and live examples: https://fibo.toribryan.com/?path=/docs/base-components-feedback-progress--docs",
  "categories": [
    "base-components",
    "feedback"
  ],
  "type": "registry:ui"
}