{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "charts",
  "type": "registry:ui",
  "title": "Charts",
  "description": "A charts component",
  "dependencies": [
    "solid-js",
    "chart.js",
    "@solid-primitives/refs"
  ],
  "files": [
    {
      "path": "src/registry/ui/charts.tsx",
      "content": "import type { Component } from \"solid-js\"\nimport { createEffect, createSignal, mergeProps, on, onCleanup, onMount } from \"solid-js\"\nimport { unwrap } from \"solid-js/store\"\n\nimport type { Ref } from \"@solid-primitives/refs\"\nimport { mergeRefs } from \"@solid-primitives/refs\"\nimport type {\n  ChartComponent,\n  ChartData,\n  ChartItem,\n  ChartOptions,\n  Plugin as ChartPlugin,\n  ChartType,\n  ChartTypeRegistry,\n  TooltipModel\n} from \"chart.js\"\nimport {\n  ArcElement,\n  BarController,\n  BarElement,\n  BubbleController,\n  CategoryScale,\n  Chart,\n  Colors,\n  DoughnutController,\n  Filler,\n  Legend,\n  LinearScale,\n  LineController,\n  LineElement,\n  PieController,\n  PointElement,\n  PolarAreaController,\n  RadarController,\n  RadialLinearScale,\n  ScatterController,\n  Tooltip\n} from \"chart.js\"\n\ntype TypedChartProps = {\n  data: ChartData\n  options?: ChartOptions\n  plugins?: ChartPlugin[]\n  ref?: Ref<HTMLCanvasElement | null>\n  width?: number | undefined\n  height?: number | undefined\n}\n\ntype ChartProps = TypedChartProps & {\n  type: ChartType\n}\n\ntype ChartContext = {\n  chart: Chart\n  tooltip: TooltipModel<keyof ChartTypeRegistry>\n}\n\nconst BaseChart: Component<ChartProps> = (rawProps) => {\n  const [canvasRef, setCanvasRef] = createSignal<HTMLCanvasElement | null>()\n  const [chart, setChart] = createSignal<Chart>()\n\n  const props = mergeProps(\n    {\n      width: 512,\n      height: 512,\n      options: { responsive: true } as ChartOptions,\n      plugins: [] as ChartPlugin[]\n    },\n    rawProps\n  )\n\n  const init = () => {\n    const ctx = canvasRef()?.getContext(\"2d\") as ChartItem\n    const config = unwrap(props)\n    const chart = new Chart(ctx, {\n      type: config.type,\n      data: config.data,\n      options: config.options,\n      plugins: config.plugins\n    })\n    setChart(chart)\n  }\n\n  onMount(() => init())\n\n  createEffect(\n    on(\n      () => props.data,\n      () => {\n        chart()!.data = props.data\n        chart()!.update()\n      },\n      { defer: true }\n    )\n  )\n\n  createEffect(\n    on(\n      () => props.options,\n      () => {\n        chart()!.options = props.options\n        chart()!.update()\n      },\n      { defer: true }\n    )\n  )\n\n  createEffect(\n    on(\n      [() => props.width, () => props.height],\n      () => {\n        chart()!.resize(props.width, props.height)\n      },\n      { defer: true }\n    )\n  )\n\n  createEffect(\n    on(\n      () => props.type,\n      () => {\n        const dimensions = [chart()!.width, chart()!.height]\n        chart()!.destroy()\n        init()\n        chart()!.resize(...dimensions)\n      },\n      { defer: true }\n    )\n  )\n\n  onCleanup(() => {\n    chart()?.destroy()\n    mergeRefs(props.ref, null)\n  })\n\n  Chart.register(Colors, Filler, Legend, Tooltip)\n  return (\n    <canvas\n      ref={mergeRefs(props.ref, (el) => setCanvasRef(el))}\n      height={props.height}\n      width={props.width}\n    />\n  )\n}\n\nfunction showTooltip(context: ChartContext) {\n  let el = document.getElementById(\"chartjs-tooltip\")\n  if (!el) {\n    el = document.createElement(\"div\")\n    el.id = \"chartjs-tooltip\"\n    document.body.appendChild(el)\n  }\n\n  const model = context.tooltip\n  if (model.opacity === 0 || !model.body) {\n    el.style.opacity = \"0\"\n    return\n  }\n\n  el.className = `p-2 bg-card text-card-foreground rounded-lg border shadow-sm text-sm ${\n    model.yAlign ?? `no-transform`\n  }`\n\n  let content = \"\"\n\n  model.title.forEach((title) => {\n    content += `<h3 class=\"font-semibold leading-none tracking-tight\">${title}</h3>`\n  })\n\n  content += `<div class=\"mt-1 text-muted-foreground\">`\n  const body = model.body.flatMap((body) => body.lines)\n  body.forEach((line, i) => {\n    const colors = model.labelColors[i]\n    content += `\n        <div class=\"flex items-center\">\n          <span class=\"inline-block h-2 w-2 mr-1 rounded-full border\" style=\"background: ${colors.backgroundColor}; border-color: ${colors.borderColor}\"></span>\n          ${line}\n        </div>`\n  })\n  content += `</div>`\n\n  el.innerHTML = content\n\n  const pos = context.chart.canvas.getBoundingClientRect()\n  el.style.opacity = \"1\"\n  el.style.position = \"absolute\"\n  el.style.left = `${pos.left + window.scrollX + model.caretX}px`\n  el.style.top = `${pos.top + window.scrollY + model.caretY}px`\n  el.style.pointerEvents = \"none\"\n}\n\nfunction createTypedChart(\n  type: ChartType,\n  components: ChartComponent[]\n): Component<TypedChartProps> {\n  const chartsWithScales: ChartType[] = [\"bar\", \"line\", \"scatter\"]\n  const chartsWithLegends: ChartType[] = [\"bar\", \"line\"]\n\n  const options: ChartOptions = {\n    responsive: true,\n    maintainAspectRatio: false,\n    scales: chartsWithScales.includes(type)\n      ? {\n          x: {\n            border: { display: false },\n            grid: { display: false }\n          },\n          y: {\n            border: {\n              dash: [3],\n              dashOffset: 3,\n              display: false\n            },\n            grid: {\n              color: \"hsla(240, 3.8%, 46.1%, 0.4)\"\n            }\n          }\n        }\n      : {},\n    plugins: {\n      legend: chartsWithLegends.includes(type)\n        ? {\n            display: true,\n            align: \"end\",\n            labels: {\n              usePointStyle: true,\n              boxWidth: 6,\n              boxHeight: 6,\n              color: \"hsl(240, 3.8%, 46.1%)\",\n              font: { size: 14 }\n            }\n          }\n        : { display: false },\n      tooltip: {\n        enabled: false,\n        external: (context) => showTooltip(context)\n      }\n    }\n  }\n\n  Chart.register(...components)\n  return (props) => <BaseChart type={type} options={options} {...props} />\n}\n\nconst BarChart = /* #__PURE__ */ createTypedChart(\"bar\", [\n  BarController,\n  BarElement,\n  CategoryScale,\n  LinearScale\n])\nconst BubbleChart = /* #__PURE__ */ createTypedChart(\"bubble\", [\n  BubbleController,\n  PointElement,\n  LinearScale\n])\nconst DonutChart = /* #__PURE__ */ createTypedChart(\"doughnut\", [DoughnutController, ArcElement])\nconst LineChart = /* #__PURE__ */ createTypedChart(\"line\", [\n  LineController,\n  LineElement,\n  PointElement,\n  CategoryScale,\n  LinearScale\n])\nconst PieChart = /* #__PURE__ */ createTypedChart(\"pie\", [PieController, ArcElement])\nconst PolarAreaChart = /* #__PURE__ */ createTypedChart(\"polarArea\", [\n  PolarAreaController,\n  ArcElement,\n  RadialLinearScale\n])\nconst RadarChart = /* #__PURE__ */ createTypedChart(\"radar\", [\n  RadarController,\n  LineElement,\n  PointElement,\n  RadialLinearScale\n])\nconst ScatterChart = /* #__PURE__ */ createTypedChart(\"scatter\", [\n  ScatterController,\n  PointElement,\n  LinearScale\n])\n\nexport {\n  BaseChart as Chart,\n  BarChart,\n  BubbleChart,\n  DonutChart,\n  LineChart,\n  PieChart,\n  PolarAreaChart,\n  RadarChart,\n  ScatterChart\n}\n",
      "type": "registry:ui"
    }
  ]
}