"use client"; /* eslint-disable complexity, sonarjs/cognitive-complexity, react/no-object-type-as-default-prop, react/no-danger, react-dom/no-dangerously-set-innerhtml, unicorn/no-negated-condition */ import * as React from "react"; import type { DefaultLegendContentProps, DefaultTooltipContentProps, LegendPayload, ResponsiveContainerProps, TooltipValueType, } from "recharts"; import * as RechartsPrimitive from "recharts"; import {cn} from "@/lib/utilities"; import styles from "./chart.module.css"; const THEMES = {light: "", dark: ".dark"} as const; /** * Describes per-series chart metadata used by legend and tooltip renderers. */ type ChartConfigItem = { /** * Label rendered by shared legends and tooltips for the series. * @default undefined */ label?: React.ReactNode; /** * Optional icon rendered in legends and tooltips instead of the color swatch. * @default undefined */ icon?: React.ComponentType; /** * Unit suffix appended to rendered values when the payload does not provide one. * @default undefined */ unit?: string; /** * Shared numeric formatter used by helper content renderers when no Recharts tooltip formatter is supplied. * @default undefined */ formatter?: (value: number) => string; /** * Recharts stack identifier that consuming chart primitives can read from config. * @default undefined */ stackId?: string; }; export type ChartConfig = Record< string, ChartConfigItem & ({color?: string; theme?: never} | {color?: never; theme: Record}) >; interface ChartContextProps { config: ChartConfig; } const ChartContext = React.createContext(null); function useChart(): ChartContextProps { const context = React.useContext(ChartContext); if (!context) { throw new Error("useChart must be used within a "); } return context; } interface ChartContainerProps extends Omit, "children" | "className" | "id">, Pick< ResponsiveContainerProps, | "initialDimension" | "aspect" | "debounce" | "minHeight" | "minWidth" | "maxHeight" | "height" | "width" | "onResize" | "children" | "className" | "id" > { /** * Series configuration used to resolve labels, icons, and colors. * @default undefined */ config: ChartConfig; /** * Inline styles applied to the inner `ResponsiveContainer`. * @default undefined */ innerResponsiveContainerStyle?: React.ComponentProps["style"]; } /** * Provides responsive chart layout and series config context for Recharts content. * * @remarks * - Renders a wrapping `
` element * - Built on `recharts` `ResponsiveContainer` * - Injects CSS variables so legends and tooltips can share theme-aware colors * * @example * ```tsx * * ... * * ``` * * @see {@link https://recharts.org/en-US/api/ResponsiveContainer | Recharts ResponsiveContainer Docs} */ const ChartContainer = React.forwardRef( ( { id, config, initialDimension = {width: 320, height: 200}, className, children, innerResponsiveContainerStyle, aspect, debounce, height, maxHeight, minHeight, minWidth, onResize, width, ...props }, ref, ) => { const uniqueId = React.useId(); const chartId = `chart-${id ?? uniqueId.replaceAll(":", "")}`; return (
{children}
); }, ); /** * Emits theme-aware CSS variables for configured chart series colors. * * @remarks * - Renders a `