{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "progress-stepped",
  "title": "Stepped progress",
  "description": "Styled progress: the Stepped set. 5 decorative progress variations (StepsProgress, DotsStepProgress, NumberedProgress, CheckStepProgress, PillStepProgress) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2",
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/progress-stepped.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { Check } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Stepped progress family: value 0-100 maps to roughly 5 discrete steps; the completed ones fill with a token. Colour comes ONLY from tokens. framer-motion settles the completed steps into place softly; they appear instantly under reduced-motion. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst track: Record<StyledSize, string> = {\n  sm: \"h-1\",\n  md: \"h-1.5\",\n  lg: \"h-2.5\",\n  xl: \"h-3.5\",\n}\n\nconst node: Record<StyledSize, string> = {\n  sm: \"size-4 text-[9px]\",\n  md: \"size-5 text-[10px]\",\n  lg: \"size-6 text-xs\",\n  xl: \"size-7 text-sm\",\n}\n\nconst STEPS = 5\n\ntype Props = React.ComponentProps<\"div\"> & { size?: StyledSize; value?: number; label?: string }\n\nfunction clamp(v: number) {\n  return Math.max(0, Math.min(100, v))\n}\n\nfunction stepsDone(v: number) {\n  return Math.round((clamp(v) / 100) * STEPS)\n}\n\nfunction useFill() {\n  const reduce = useReducedMotion()\n  return {\n    initial: reduce ? false : ({ scale: 0.5, opacity: 0 } as const),\n    transition: (i: number) => (reduce ? undefined : { duration: 0.35, ease: \"easeOut\" as const, delay: i * 0.06 }),\n  }\n}\n\n/* Steps: baglayicilarla ayrilmis 5 bar segmenti; tamamlananlar token dolu. */\nexport function StepsProgress({ className, size = \"md\", value = 60, label = \"Progress\", ...props }: Props) {\n  const v = clamp(value)\n  const filled = stepsDone(v)\n  const { initial, transition } = useFill()\n  return (\n    <div\n      data-slot=\"styled-progress\"\n      role=\"progressbar\"\n      aria-valuenow={v}\n      aria-valuemin={0}\n      aria-valuemax={100}\n      aria-label={label}\n      className={cn(\"flex w-56 max-w-full items-center gap-1.5\", track[size], className)}\n      {...props}\n    >\n      {Array.from({ length: STEPS }).map((_, i) => (\n        <span key={i} className=\"relative h-full flex-1 overflow-hidden rounded-full bg-secondary\">\n          {i < filled && (\n            <motion.span\n              className=\"absolute inset-0 rounded-full bg-primary\"\n              initial={initial}\n              animate={{ scale: 1, opacity: 1 }}\n              transition={transition(i)}\n            />\n          )}\n        </span>\n      ))}\n    </div>\n  )\n}\n\n/* DotsStep: cizgilerle birlesmis noktalar; tamamlanan nokta ve baglantilar dolu. */\nexport function DotsStepProgress({ className, size = \"md\", value = 60, label = \"Progress\", ...props }: Props) {\n  const v = clamp(value)\n  const filled = stepsDone(v)\n  const { initial, transition } = useFill()\n  return (\n    <div\n      data-slot=\"styled-progress\"\n      role=\"progressbar\"\n      aria-valuenow={v}\n      aria-valuemin={0}\n      aria-valuemax={100}\n      aria-label={label}\n      className={cn(\"flex w-56 max-w-full items-center\", className)}\n      {...props}\n    >\n      {Array.from({ length: STEPS }).map((_, i) => (\n        <React.Fragment key={i}>\n          <motion.span\n            className={cn(\"size-2.5 shrink-0 rounded-full\", i < filled ? \"bg-primary\" : \"bg-secondary\")}\n            initial={i < filled ? initial : false}\n            animate={{ scale: 1, opacity: 1 }}\n            transition={i < filled ? transition(i) : undefined}\n          />\n          {i < STEPS - 1 && (\n            <span\n              className={cn(\"h-0.5 flex-1 rounded-full\", i < filled - 1 ? \"bg-primary\" : \"bg-secondary\")}\n            />\n          )}\n        </React.Fragment>\n      ))}\n    </div>\n  )\n}\n\n/* Numbered: 1..5 numarali adim daireleri; tamamlananlar token dolu. */\nexport function NumberedProgress({ className, size = \"md\", value = 60, label = \"Progress\", ...props }: Props) {\n  const v = clamp(value)\n  const filled = stepsDone(v)\n  const { initial, transition } = useFill()\n  return (\n    <div\n      data-slot=\"styled-progress\"\n      role=\"progressbar\"\n      aria-valuenow={v}\n      aria-valuemin={0}\n      aria-valuemax={100}\n      aria-label={label}\n      className={cn(\"flex w-56 max-w-full items-center\", className)}\n      {...props}\n    >\n      {Array.from({ length: STEPS }).map((_, i) => {\n        const done = i < filled\n        return (\n          <React.Fragment key={i}>\n            <motion.span\n              className={cn(\n                \"flex shrink-0 items-center justify-center rounded-full font-medium tabular-nums\",\n                node[size],\n                done ? \"bg-primary text-primary-foreground\" : \"bg-secondary text-muted-foreground\"\n              )}\n              initial={done ? initial : false}\n              animate={{ scale: 1, opacity: 1 }}\n              transition={done ? transition(i) : undefined}\n            >\n              {i + 1}\n            </motion.span>\n            {i < STEPS - 1 && (\n              <span className={cn(\"h-0.5 flex-1 rounded-full\", i < filled - 1 ? \"bg-primary\" : \"bg-secondary\")} />\n            )}\n          </React.Fragment>\n        )\n      })}\n    </div>\n  )\n}\n\n/* CheckStep: completed steps show a check. */\nexport function CheckStepProgress({ className, size = \"md\", value = 60, label = \"Progress\", ...props }: Props) {\n  const v = clamp(value)\n  const filled = stepsDone(v)\n  const { initial, transition } = useFill()\n  return (\n    <div\n      data-slot=\"styled-progress\"\n      role=\"progressbar\"\n      aria-valuenow={v}\n      aria-valuemin={0}\n      aria-valuemax={100}\n      aria-label={label}\n      className={cn(\"flex w-56 max-w-full items-center\", className)}\n      {...props}\n    >\n      {Array.from({ length: STEPS }).map((_, i) => {\n        const done = i < filled\n        return (\n          <React.Fragment key={i}>\n            <motion.span\n              className={cn(\n                \"flex shrink-0 items-center justify-center rounded-full [&>svg]:size-3\",\n                node[size],\n                done ? \"bg-primary text-primary-foreground\" : \"bg-secondary text-muted-foreground\"\n              )}\n              initial={done ? initial : false}\n              animate={{ scale: 1, opacity: 1 }}\n              transition={done ? transition(i) : undefined}\n            >\n              {done ? <Check aria-hidden=\"true\" /> : <span className=\"size-1.5 rounded-full bg-current opacity-60\" />}\n            </motion.span>\n            {i < STEPS - 1 && (\n              <span className={cn(\"h-0.5 flex-1 rounded-full\", i < filled - 1 ? \"bg-primary\" : \"bg-secondary\")} />\n            )}\n          </React.Fragment>\n        )\n      })}\n    </div>\n  )\n}\n\n/* PillStep: hap (pill) segmentler; tamamlananlar token dolu. */\nexport function PillStepProgress({ className, size = \"md\", value = 60, label = \"Progress\", ...props }: Props) {\n  const v = clamp(value)\n  const filled = stepsDone(v)\n  const { initial, transition } = useFill()\n  return (\n    <div\n      data-slot=\"styled-progress\"\n      role=\"progressbar\"\n      aria-valuenow={v}\n      aria-valuemin={0}\n      aria-valuemax={100}\n      aria-label={label}\n      className={cn(\"flex w-56 max-w-full items-center gap-1\", track[size], className)}\n      {...props}\n    >\n      {Array.from({ length: STEPS }).map((_, i) => (\n        <span\n          key={i}\n          className=\"relative h-full flex-1 overflow-hidden rounded-full bg-secondary ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-foreground)_10%,transparent)]\"\n        >\n          {i < filled && (\n            <motion.span\n              className=\"absolute inset-0 rounded-full bg-primary\"\n              initial={initial}\n              animate={{ scale: 1, opacity: 1 }}\n              transition={transition(i)}\n            />\n          )}\n        </span>\n      ))}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/progress-stepped.tsx"
    }
  ],
  "categories": [
    "styled",
    "progress"
  ],
  "type": "registry:component"
}