{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "category-bar",
  "type": "registry:ui",
  "title": "Category Bar",
  "description": "Segmented progress bar with per-segment colors and optional labels. Useful for resource breakdowns.",
  "dependencies": [
    "@saasflare/ui",
    "motion"
  ],
  "files": [
    {
      "path": "components/ui/category-bar.tsx",
      "type": "registry:ui",
      "content": "// @draft\n\"use client\"\n\n/**\n * @fileoverview Saasflare CategoryBar — segmented progress bar.\n * @author Saasflare™\n *\n * One horizontal bar split into adjacent colored segments — useful for\n * resource breakdowns (disk usage by category, traffic by source, budget\n * allocation). Each segment can carry a value, color, and label;\n * percentages auto-normalize to fill the bar.\n *\n * @module packages/ui/components/ui/category-bar\n * @package ui\n * @layer core\n *\n * @example\n * <CategoryBar\n *   segments={[\n *     { value: 30, color: \"var(--chart-1)\", label: \"Images\" },\n *     { value: 20, color: \"var(--chart-2)\", label: \"Docs\"   },\n *     { value: 50, color: \"var(--chart-3)\", label: \"Other\"  },\n *   ]}\n *   showLabels\n * />\n */\n\nimport { m } from \"motion/react\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\nimport { useSaasflareMotion, springGentle } from \"@saasflare/ui\"\n\n/** A single segment of the bar. */\nexport interface CategoryBarSegment {\n    /** Numeric value driving the segment width (auto-normalized). */\n    value: number\n    /** Any CSS color. Falls back to a derived primary tint. */\n    color?: string\n    /** Optional label shown below the segment when `showLabels` is true. */\n    label?: string\n}\n\n/** Props for the CategoryBar component. */\nexport interface CategoryBarProps extends SaasflareComponentProps {\n    /** Segments to render, left-to-right. */\n    segments: CategoryBarSegment[]\n    /** Bar height in pixels. Default: `8`. */\n    height?: number\n    /** Render labels + percentages under each segment. */\n    showLabels?: boolean\n    /** Formats the percentage text. Default: `\"NN%\"`. */\n    valueFormatter?: (percent: number) => string\n    /** Additional class names. */\n    className?: string\n    /** Accessible label for the bar group. */\n    \"aria-label\"?: string\n}\n\n/** Fallback palette — derived from the design-system chart tokens. */\nconst FALLBACK_COLORS = [\n    \"var(--chart-1)\",\n    \"var(--chart-2)\",\n    \"var(--chart-3)\",\n    \"var(--chart-4)\",\n    \"var(--chart-5)\",\n]\n\n/**\n * Segmented progress bar with optional labels.\n *\n * @component\n * @layer core\n */\nexport function CategoryBar({\n    segments,\n    height = 8,\n    showLabels = false,\n    valueFormatter,\n    className,\n    surface,\n    radius,\n    animated,\n    iconWeight,\n    \"aria-label\": ariaLabel,\n}: CategoryBarProps) {\n    const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n    const motion = useSaasflareMotion(sf.animated, springGentle)\n\n    const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0)\n    if (total === 0 || segments.length === 0) return null\n\n    const formatter =\n        valueFormatter ?? ((p: number) => `${p.toFixed(p < 10 ? 1 : 0)}%`)\n\n    return (\n        <div\n            data-slot=\"category-bar\"\n            data-surface={sf.surface}\n            data-radius={sf.radius}\n            data-animated={String(sf.animated)}\n            role=\"group\"\n            aria-label={ariaLabel ?? \"Category breakdown\"}\n            className={cn(\"w-full\", className)}\n        >\n            <div\n                data-slot=\"category-bar-track\"\n                className=\"flex w-full overflow-hidden rounded-full bg-primary/10\"\n                style={{ height }}\n            >\n                {segments.map((seg, i) => {\n                    const pct = (Math.max(0, seg.value) / total) * 100\n                    return (\n                        <m.div\n                            key={i}\n                            data-slot=\"category-bar-segment\"\n                            title={\n                                seg.label\n                                    ? `${seg.label}: ${formatter(pct)}`\n                                    : formatter(pct)\n                            }\n                            initial={motion.disabled ? false : { width: 0 }}\n                            animate={{ width: `${pct}%` }}\n                            transition={motion.transition}\n                            className=\"h-full\"\n                            style={{\n                                backgroundColor:\n                                    seg.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n                            }}\n                        />\n                    )\n                })}\n            </div>\n            {showLabels && (\n                <div\n                    data-slot=\"category-bar-labels\"\n                    className=\"mt-2 flex w-full text-xs text-muted-foreground\"\n                >\n                    {segments.map((seg, i) => {\n                        const pct = (Math.max(0, seg.value) / total) * 100\n                        return (\n                            <div\n                                key={i}\n                                data-slot=\"category-bar-label\"\n                                style={{ width: `${pct}%` }}\n                                className=\"flex min-w-0 items-center gap-1.5 truncate px-1\"\n                            >\n                                <span\n                                    aria-hidden=\"true\"\n                                    className=\"size-2 shrink-0 rounded-full\"\n                                    style={{\n                                        backgroundColor:\n                                            seg.color ??\n                                            FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n                                    }}\n                                />\n                                <span className=\"truncate\">\n                                    {seg.label ? `${seg.label} ` : \"\"}\n                                    <span className=\"text-foreground font-medium tabular-nums\">\n                                        {formatter(pct)}\n                                    </span>\n                                </span>\n                            </div>\n                        )\n                    })}\n                </div>\n            )}\n        </div>\n    )\n}\n",
      "target": "components/ui/category-bar.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/category-bar.json"
  }
}
