"use client"; import * as React from "react"; import * as RechartsPrimitive from "recharts"; import { cn } from "../../utils.js"; import "./chart.css"; export type ChartConfig = { [k in string]: { label?: React.ReactNode; icon?: React.ComponentType; } & ( | { color?: string; theme?: never } | { color?: never; theme: Record } ); }; type ChartContextProps = { config: ChartConfig; }; const ChartContext = React.createContext(null); function useChart() { const context = React.useContext(ChartContext); if (!context) { throw new Error("useChart must be used within a "); } return context; } function escapeCssIdentifier(str: string): string { return str.replace(/[^a-zA-Z0-9_-]/g, ""); } function sanitizeCssValue(str: string): string { return str.replace(/[;{}\n\r\\]/g, "").trim(); } /** * Injects CSS variables for chart colors per chart instance. * Emits separate correctly themed, per-instance .cfui-chart selectors * and escapes instance IDs and config keys. */ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { const colorConfig = Object.entries(config).filter( ([, itemConfig]) => itemConfig.theme || itemConfig.color ); if (!colorConfig.length) { return null; } const escapedId = escapeCssIdentifier(id); const getVariablesForTheme = (theme: "light" | "dark") => { return colorConfig .map(([key, itemConfig]) => { const rawColor = itemConfig.theme?.[theme] || itemConfig.color; if (!rawColor) return null; const escapedKey = escapeCssIdentifier(key); const safeColor = sanitizeCssValue(rawColor); if (!escapedKey || !safeColor) return null; return ` --color-${escapedKey}: ${safeColor};`; }) .filter(Boolean) .join("\n"); }; const lightVariables = getVariablesForTheme("light"); const darkVariables = getVariablesForTheme("dark"); const css = ` .cfui-chart[data-chart="${escapedId}"] { ${lightVariables} } .dark .cfui-chart[data-chart="${escapedId}"], [data-cfui-theme="dark"] .cfui-chart[data-chart="${escapedId}"], .dark.cfui-chart[data-chart="${escapedId}"], [data-cfui-theme="dark"].cfui-chart[data-chart="${escapedId}"] { ${darkVariables} } `; return (