{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "category-distribution-chart",
  "title": "Category Distribution Chart",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-vue/components/charts/category-distribution-chart/CategoryDistributionChart.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nexport interface DistributionSlice {\n  label: string\n  /** Share of the whole; auto-normalised when the sum is not 100. */\n  percentage: number\n  value?: string | number\n  color?: string\n}\n\ninterface Props {\n  primaryValue: string | number\n  primaryLabel?: string\n  trend?: { value: string; direction: 'up' | 'down' }\n  categories: DistributionSlice[]\n  height?: number | string\n  showLegend?: boolean\n  colors?: string[]\n  class?: HTMLAttributes['class']\n  /** Accessible name announced for the chart image. Defaults to \"Chart\". */\n  ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  height: 220,\n  showLegend: true,\n  colors: () => ['var(--chart-1)', 'var(--chart-2)', 'var(--chart-3)', 'var(--chart-4)', 'var(--chart-5)'],\n})\n\nconst heightStyle = computed(() => (/^\\d+$/.test(String(props.height)) ? `${props.height}px` : String(props.height)))\nconst total = computed(() => props.categories.reduce((s, c) => s + c.percentage, 0) || 1)\nconst slices = computed(() =>\n  props.categories.map((c, i) => ({\n    ...c,\n    share: (c.percentage / total.value) * 100,\n    color: c.color ?? props.colors[i % props.colors.length]!,\n  })),\n)\n</script>\n\n<template>\n  <div\n    data-slot=\"category-distribution-chart\"\n    :style=\"{ height: heightStyle }\"\n    :class=\"cn('flex w-full flex-col justify-center', props.class)\"\n  >\n    <div class=\"flex items-baseline gap-2\">\n      <span class=\"text-foreground text-3xl font-bold tabular-nums\">{{ primaryValue }}</span>\n      <span\n        v-if=\"trend\"\n        class=\"text-xs font-semibold tabular-nums\"\n        :style=\"{ color: trend.direction === 'up' ? 'var(--chart-2)' : 'var(--destructive)' }\"\n      >\n        {{ trend.direction === 'up' ? '+' : '−' }}{{ trend.value }}\n      </span>\n      <span v-if=\"primaryLabel\" class=\"text-muted-foreground text-xs\">{{ primaryLabel }}</span>\n    </div>\n    <div class=\"mt-3 flex h-3 w-full overflow-hidden rounded-full\" role=\"presentation\">\n      <div\n        v-for=\"s in slices\"\n        :key=\"s.label\"\n        class=\"h-full\"\n        :style=\"{ width: `${s.share}%`, background: s.color }\"\n        :title=\"`${s.label} — ${Math.round(s.share)}%`\"\n      />\n    </div>\n    <ul v-if=\"showLegend\" class=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-1.5 text-xs\">\n      <li v-for=\"s in slices\" :key=\"s.label\" class=\"flex min-w-0 items-center gap-2\">\n        <span class=\"size-2.5 shrink-0 rounded-[3px]\" :style=\"{ background: s.color }\" />\n        <span class=\"text-foreground truncate font-medium\">{{ s.label }}</span>\n        <span class=\"text-muted-foreground ml-auto shrink-0 tabular-nums\">{{\n          s.value ?? `${Math.round(s.share)}%`\n        }}</span>\n      </li>\n    </ul>\n  </div>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/charts/category-distribution-chart/CategoryDistributionChart.vue"
    },
    {
      "path": "packages/registry-vue/components/charts/category-distribution-chart/index.ts",
      "content": "export { default as CategoryDistributionChart } from './CategoryDistributionChart.vue'\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/charts/category-distribution-chart/index.ts"
    }
  ],
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Category distribution as dependency-free markup. Primary KPI with trend pill, proportional stacked bar, and legend. Shares auto-normalise. Picks up chart tokens via CSS variables.",
  "categories": [
    "chart"
  ]
}