{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "echarts-legend",
  "registryDependencies": [
    "@evilcharts/echarts-chart"
  ],
  "files": [
    {
      "path": "src/registry/ui/echarts-legend.tsx",
      "content": "\"use client\";\n\nimport { getColorsCount, indicatorBackground, type ChartConfig } from \"@/registry/ui/echarts-chart\";\nimport type { CSSProperties } from \"react\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legend overlay (React) — replicates ChartLegendContent + its 7 indicators.\n// The legend is HTML inside `[data-chart={id}]`, so it uses the injected\n// `--color-*` vars directly. Shared by every ECharts chart.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type LegendVariant =\n  | \"square\"\n  | \"circle\"\n  | \"circle-outline\"\n  | \"rounded-square\"\n  | \"rounded-square-outline\"\n  | \"vertical-bar\"\n  | \"horizontal-bar\";\n\nexport function legendFillStyle(key: string, colorsCount: number): CSSProperties {\n  if (colorsCount <= 1) return { backgroundColor: `var(--color-${key}-0)` };\n  return { background: indicatorBackground(key, colorsCount) };\n}\n\n// Punches out the centre with a mask-composite so only the \"border\" shows —\n// works with gradients and border-radius, unlike plain border-color.\nexport function legendOutlineStyle(key: string, colorsCount: number): CSSProperties {\n  const mask: CSSProperties = {\n    WebkitMask: \"linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)\",\n    WebkitMaskComposite: \"xor\",\n    mask: \"linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)\",\n    maskComposite: \"exclude\",\n  };\n  return { ...legendFillStyle(key, colorsCount), ...mask };\n}\n\nexport function LegendIndicator({\n  variant,\n  dataKey,\n  colorsCount,\n}: {\n  variant: LegendVariant;\n  dataKey: string;\n  colorsCount: number;\n}) {\n  const fill = legendFillStyle(dataKey, colorsCount);\n  const outline = legendOutlineStyle(dataKey, colorsCount);\n\n  switch (variant) {\n    case \"square\":\n      return <div className=\"h-2 w-2 shrink-0\" style={fill} />;\n    case \"circle\":\n      return <div className=\"h-2 w-2 shrink-0 rounded-full\" style={fill} />;\n    case \"circle-outline\":\n      return <div className=\"h-2.5 w-2.5 shrink-0 rounded-full p-[1.5px]\" style={outline} />;\n    case \"vertical-bar\":\n      return <div className=\"h-3 w-1 shrink-0 rounded-[2px]\" style={fill} />;\n    case \"horizontal-bar\":\n      return <div className=\"h-1 w-3 shrink-0 rounded-[2px]\" style={fill} />;\n    case \"rounded-square-outline\":\n      return <div className=\"h-2.5 w-2.5 shrink-0 rounded-[3px] p-[1.5px]\" style={outline} />;\n    case \"rounded-square\":\n    default:\n      return <div className=\"h-2 w-2 shrink-0 rounded-[2px]\" style={fill} />;\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// LegendOverlay — the positioned HTML legend row. The chart computes the\n// absolute-positioned `style` (it owns the brush/verticalAlign layout math) and\n// passes it in; this renders the entries, their indicators, and the\n// selection/hover dim. `verticalAlign` is carried on the props for parity with\n// the chart's LegendSlot even though positioning arrives fully via `style`.\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype LegendOverlayProps = {\n  seriesKeys: string[];\n  config: ChartConfig;\n  variant: LegendVariant;\n  align: \"left\" | \"center\" | \"right\";\n  verticalAlign: \"top\" | \"middle\" | \"bottom\";\n  selectedKey: string | null;\n  hoveredKey: string | null;\n  isClickable: boolean;\n  onToggle: (key: string) => void;\n  style: CSSProperties;\n};\n\nexport function LegendOverlay({\n  seriesKeys,\n  config,\n  variant,\n  align,\n  selectedKey,\n  hoveredKey,\n  isClickable,\n  onToggle,\n  style,\n}: LegendOverlayProps) {\n  const legendJustify =\n    align === \"left\" ? \"justify-start\" : align === \"center\" ? \"justify-center\" : \"justify-end\";\n\n  return (\n    <div style={style} className={`flex items-center gap-4 select-none ${legendJustify}`}>\n      {seriesKeys.map((key) => {\n        const item = config[key];\n        const colorsCount = item ? getColorsCount(item) : 1;\n        const isSelected =\n          (selectedKey === null || selectedKey === key) &&\n          (hoveredKey === null || hoveredKey === key);\n        return (\n          // No entrance here — the Recharts legend appears instantly, and a\n          // fade-in reads as disconnected from the canvas draw-in.\n          <div\n            key={key}\n            className={`flex items-center gap-1.5 transition-opacity ${\n              !isSelected ? \"opacity-30\" : \"\"\n            } ${isClickable ? \"cursor-pointer\" : \"\"}`}\n            onClick={() => {\n              if (isClickable) onToggle(key);\n            }}\n          >\n            <LegendIndicator variant={variant} dataKey={key} colorsCount={colorsCount} />\n            {item?.label}\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/evilcharts/ui/echarts-legend.tsx"
    }
  ],
  "type": "registry:component"
}