{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "grid-bar-chart",
  "description": "Bar chart where each bar is composed of stacked 10x10px squares",
  "dependencies": [
    "recharts"
  ],
  "registryDependencies": [
    "@evilcharts/recharts-chart"
  ],
  "files": [
    {
      "path": "src/registry/blocks/recharts/b-grid-bar-chart.tsx",
      "content": "\"use client\";\n\nimport { type ChartConfig, ChartContainer } from \"@/registry/ui/recharts-chart\";\nimport { Bar, BarChart, XAxis } from \"recharts\";\nconst SQUARE_SIZE = 10;\nconst GAP = 2;\nconst CELL_SIZE = SQUARE_SIZE + GAP;\n\nconst chartData = [\n  { month: \"January\", desktop: 186 },\n  { month: \"February\", desktop: 305 },\n  { month: \"March\", desktop: 237 },\n  { month: \"April\", desktop: 273 },\n  { month: \"May\", desktop: 209 },\n  { month: \"June\", desktop: 346 },\n  { month: \"July\", desktop: 181 },\n  { month: \"August\", desktop: 392 },\n  { month: \"September\", desktop: 298 },\n  { month: \"October\", desktop: 215 },\n  { month: \"November\", desktop: 327 },\n  { month: \"December\", desktop: 162 },\n];\n\nconst chartConfig = {\n  desktop: {\n    label: \"Desktop\",\n    colors: {\n      light: [\"#18181b\"],\n      dark: [\"#fafafa\"],\n    },\n  },\n} satisfies ChartConfig;\n\ninterface GridBarProps {\n  x?: number;\n  y?: number;\n  width?: number;\n  height?: number;\n  fill?: string;\n}\n\n// Renders ghost squares filling the entire column height — used as the Bar background.\n// recharts passes y = chart top, height = full chart area height, so y + height = the\n// shared bottom baseline, which perfectly aligns with the data squares in GridBarShape.\nconst GridBarBackground = (props: GridBarProps) => {\n  const { fill, x, y, width, height } = props;\n\n  const xPos = Number(x ?? 0);\n  const yPos = Number(y ?? 0);\n  const realWidth = Number(width ?? 0);\n  const realHeight = Number(height ?? 0);\n\n  if (realHeight <= 0) return null;\n\n  const numSquares = Math.floor(realHeight / CELL_SIZE);\n  const squareSize = Math.min(SQUARE_SIZE, Math.max(2, realWidth - 2));\n  const squareX = xPos + Math.floor((realWidth - squareSize) / 2);\n  const bottomY = yPos + realHeight;\n\n  return (\n    <>\n      {Array.from({ length: numSquares }, (_, i) => {\n        const squareY = bottomY - (i + 1) * CELL_SIZE + GAP;\n        return (\n          <rect\n            className=\"dark:opacity-[0.1]\"\n            key={i}\n            x={squareX}\n            y={squareY}\n            width={squareSize}\n            height={squareSize}\n            fill={fill}\n          />\n        );\n      })}\n    </>\n  );\n};\n\nconst GridBarShape = (props: GridBarProps) => {\n  const { fill, x, y, width, height } = props;\n\n  const xPos = Number(x ?? 0);\n  const yPos = Number(y ?? 0);\n  const realWidth = Number(width ?? 0);\n  const realHeight = Number(height ?? 0);\n\n  if (realHeight <= 0) return null;\n\n  const numSquares = Math.max(1, Math.floor(realHeight / CELL_SIZE));\n  const squareSize = Math.min(SQUARE_SIZE, Math.max(2, realWidth - 2));\n  const squareX = xPos + Math.floor((realWidth - squareSize) / 2);\n  const bottomY = yPos + realHeight;\n\n  return (\n    <>\n      {Array.from({ length: numSquares }, (_, i) => {\n        const squareY = bottomY - (i + 1) * CELL_SIZE + GAP;\n        return (\n          <rect\n            key={i}\n            x={squareX}\n            y={squareY}\n            width={squareSize}\n            height={squareSize}\n            fill={fill}\n          />\n        );\n      })}\n    </>\n  );\n};\n\nexport function EvilGridBarChart() {\n  const total = chartData.reduce((sum, item) => sum + item.desktop, 0);\n  const maxData = chartData.reduce(\n    (max, item, index) =>\n      item.desktop > max.value ? { index, month: item.month, value: item.desktop } : max,\n    { index: 0, month: chartData[0].month, value: chartData[0].desktop },\n  );\n\n  return (\n    <div className=\"flex h-full flex-col p-4\">\n      <div className=\"flex flex-row justify-between\">\n        <div className=\"flex flex-row\">\n          <div className=\"flex flex-col gap-2\">\n            <span className=\"text-muted-foreground font-mono text-xs\">{\"[Σ] Total\"}</span>\n            <span className=\"text-primary font-mono text-3xl tracking-tighter\">\n              {total.toLocaleString()}\n            </span>\n          </div>\n          <hr className=\"mx-4 h-full border-l border-dashed\" />\n          <div className=\"flex flex-col gap-2\">\n            <span className=\"text-muted-foreground font-mono text-xs\">{\"[⬆] Peak\"}</span>\n            <span className=\"text-primary font-mono text-3xl tracking-tighter\">\n              {maxData.month.slice(0, 3)}\n            </span>\n          </div>\n        </div>\n        <div className=\"flex flex-col justify-end gap-1\">\n          <span className=\"text-muted-foreground font-mono text-[10px]\">\n            {\"// CELL: \"}\n            <span className=\"text-primary\">10x10px</span>\n          </span>\n          <span className=\"text-muted-foreground font-mono text-[10px]\">\n            {\"// TYPE: \"}\n            <span className=\"text-primary\">GRID</span>\n          </span>\n        </div>\n      </div>\n      <hr className=\"my-4 border-t border-dashed\" />\n      <ChartContainer config={chartConfig}>\n        <BarChart accessibilityLayer data={chartData}>\n          <XAxis\n            dataKey=\"month\"\n            tickLine={false}\n            tickMargin={10}\n            axisLine={false}\n            tickFormatter={(value: string) => value.slice(0, 3)}\n          />\n          {Object.keys(chartConfig).map((key) => (\n            <Bar\n              key={key}\n              dataKey={key}\n              fill={`var(--color-${key}-0)`}\n              background={GridBarBackground}\n              shape={GridBarShape}\n              activeBar={GridBarShape}\n            />\n          ))}\n        </BarChart>\n      </ChartContainer>\n    </div>\n  );\n}\n",
      "type": "registry:block",
      "target": "components/evilcharts/blocks/grid-bar-chart.tsx"
    }
  ],
  "type": "registry:block"
}