{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "category-distribution-chart",
  "title": "Category Distribution Chart",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-angular/components/charts/category-distribution-chart/category-distribution-chart.component.ts",
      "content": "import { Component, Input, ChangeDetectionStrategy } from '@angular/core'\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\nconst DEFAULT_COLORS = ['var(--chart-1)', 'var(--chart-2)', 'var(--chart-3)', 'var(--chart-4)', 'var(--chart-5)']\n\n/**\n * Angular port of the UIPKGE CategoryDistributionChart. Dependency-free like React/Vue:\n * a KPI headline plus a stacked share bar and a value legend. Shares auto-normalise.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-category-distribution-chart, [ui-category-distribution-chart]',\n  standalone: true,\n  host: {\n    '[attr.data-slot]': '\"category-distribution-chart\"',\n    '[attr.data-uipkge]': '\"\"',\n    '[attr.role]': '\"img\"',\n    '[attr.aria-label]': 'ariaLabel || \"Chart\"',\n    '[class]': 'hostClass',\n    '[style.height]': 'heightStyle',\n  },\n  template: `\n    <div class=\"flex items-baseline gap-2\">\n      <span class=\"text-foreground text-3xl font-bold tabular-nums\">{{ primaryValue }}</span>\n      @if (trend) {\n        <span class=\"text-xs font-semibold tabular-nums\" [style.color]=\"trendColor\">{{ trendSign }}{{ trend.value }}</span>\n      }\n      @if (primaryLabel) {\n        <span class=\"text-muted-foreground text-xs\">{{ primaryLabel }}</span>\n      }\n    </div>\n    <div class=\"mt-3 flex h-3 w-full overflow-hidden rounded-full\" role=\"presentation\">\n      @for (s of slices; track s.label) {\n        <div class=\"h-full\" [style.width.%]=\"s.share\" [style.background]=\"s.color\" [title]=\"s.label + ' — ' + s.rounded + '%'\"></div>\n      }\n    </div>\n    @if (showLegend) {\n      <ul class=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-1.5 text-xs\">\n        @for (s of slices; track s.label) {\n          <li class=\"flex min-w-0 items-center gap-2\">\n            <span class=\"size-2.5 shrink-0 rounded-[3px]\" [style.background]=\"s.color\"></span>\n            <span class=\"text-foreground truncate font-medium\">{{ s.label }}</span>\n            <span class=\"text-muted-foreground ml-auto shrink-0 tabular-nums\">{{ s.displayValue }}</span>\n          </li>\n        }\n      </ul>\n    }\n  `,\n})\nexport class UiCategoryDistributionChartComponent {\n  @Input() primaryValue!: string | number\n  @Input() primaryLabel?: string\n  @Input() trend?: { value: string; direction: 'up' | 'down' }\n  @Input() categories: DistributionSlice[] = []\n  @Input() height: number | string = 220\n  @Input() showLegend = true\n  @Input() colors: string[] = DEFAULT_COLORS\n  /** Accessible name announced for the chart image. Defaults to \"Chart\". */\n  @Input() ariaLabel?: string\n  @Input('class') className?: string\n\n  get hostClass(): string {\n    return cn('flex w-full flex-col justify-center', this.className)\n  }\n\n  get heightStyle(): string {\n    return /^\\d+$/.test(String(this.height)) ? `${this.height}px` : String(this.height)\n  }\n\n  get total(): number {\n    return this.categories.reduce((s, c) => s + c.percentage, 0) || 1\n  }\n\n  get slices(): (DistributionSlice & { share: number; rounded: number; displayValue: string | number })[] {\n    return this.categories.map((c, i) => {\n      const share = (c.percentage / this.total) * 100\n      return {\n        ...c,\n        color: c.color ?? this.colors[i % this.colors.length],\n        share,\n        rounded: Math.round(share),\n        displayValue: c.value ?? `${Math.round(share)}%`,\n      }\n    })\n  }\n\n  get trendColor(): string {\n    return this.trend?.direction === 'up' ? 'var(--chart-2)' : 'var(--destructive)'\n  }\n\n  get trendSign(): string {\n    return this.trend?.direction === 'up' ? '+' : '−'\n  }\n}\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/charts/category-distribution-chart/category-distribution-chart.component.ts"
    },
    {
      "path": "packages/registry-angular/components/charts/category-distribution-chart/index.ts",
      "content": "export { UiCategoryDistributionChartComponent } from './category-distribution-chart.component'\n",
      "type": "registry:ui",
      "target": "~/src/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"
  ]
}