From 9b142a2b32da7d5de929429acd1a6ebc31c693f0 Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 22 Jan 2026 16:07:39 +0530 Subject: [PATCH 1/6] add data-crayon-chart attribute in all the charts, this enables custom renderer when exporting to a specific format --- js/packages/react-ui/package.json | 2 +- .../components/Charts/AreaChart/AreaChart.tsx | 16 ++- .../components/Charts/BarChart/BarChart.tsx | 16 ++- .../react-ui/src/components/Charts/Charts.tsx | 114 +++++++++++------- .../HorizontalBarChart/HorizontalBarChart.tsx | 25 +++- .../components/Charts/LineChart/LineChart.tsx | 21 +++- .../components/Charts/PieChart/PieChart.tsx | 18 ++- .../Charts/RadarChart/RadarChart.tsx | 18 ++- .../Charts/RadialChart/RadialChart.tsx | 12 +- .../Charts/ScatterChart/ScatterChart.tsx | 18 ++- .../SingleStackedBarChart.tsx | 18 +++ .../src/components/Charts/hooks/index.ts | 1 + .../Charts/hooks/useExportChartData.ts | 78 ++++++++++++ js/packages/react-ui/src/index.ts | 1 + 14 files changed, 297 insertions(+), 61 deletions(-) create mode 100644 js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts diff --git a/js/packages/react-ui/package.json b/js/packages/react-ui/package.json index 4945f4682..2d45b7be7 100644 --- a/js/packages/react-ui/package.json +++ b/js/packages/react-ui/package.json @@ -2,7 +2,7 @@ "type": "module", "name": "@crayonai/react-ui", "license": "MIT", - "version": "0.9.14", + "version": "0.9.15", "description": "Component library for Generative UI SDK", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx b/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx index d1c78b8b3..6581d372e 100644 --- a/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx +++ b/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx @@ -5,7 +5,7 @@ import { usePrintContext } from "../../../context/PrintContext"; import { useId } from "../../../polyfills"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useMaxLabelHeight, useTransformedKeys, useYAxisLabelWidth } from "../hooks"; +import { useExportChartData, useMaxLabelHeight, useTransformedKeys, useYAxisLabelWidth } from "../hooks"; import { ActiveDot, cartesianGrid, @@ -182,7 +182,7 @@ const AreaChartComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -229,6 +229,17 @@ const AreaChartComponent = ({ return getLegendItems(dataKeys, colors, icons); }, [dataKeys, colors, icons]); + const exportData = useExportChartData({ + type: "area", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + }); + const id = useId(); const gradientID = useMemo(() => `area-chart-gradient-${id}`, [id]); @@ -304,6 +315,7 @@ const AreaChartComponent = ({ >
({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -253,6 +253,17 @@ const BarChartComponent = ({ return getLegendItems(dataKeys, colors, icons); }, [dataKeys, colors, icons]); + const exportData = useExportChartData({ + type: "bar", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + }); + const id = useId(); const yAxis = useMemo(() => { @@ -428,6 +439,7 @@ const BarChartComponent = ({ >
; - } + color?: never; + theme: Record< + keyof typeof THEMES, + | string + | { + color: string; + secondaryColor?: string; + } + >; + } ); }; +/** + * Data structure for chart export (e.g., to PPTX) + */ +export type ExportChartData = { + type: "line" | "bar" | "area" | "pie" | "radar" | "scatter"; + data: { + name: string; + labels?: string[]; + values?: number[]; + x?: number[]; + y?: number[]; + }[]; + options?: { + chartColors?: string[]; + showLegend?: boolean; + legendPos?: "b" | "t" | "l" | "r"; + title?: string; + showTitle?: boolean; + catAxisTitle?: string; + showCatAxisTitle?: boolean; + valAxisTitle?: string; + showValAxisTitle?: boolean; + lineSize?: number; + barDir?: "bar" | "col"; + barGrouping?: "stacked" | "clustered" | "percent" | "standard"; + }; +}; + /** * Context props for chart configuration */ @@ -83,27 +111,27 @@ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { ([theme, prefix]) => ` ${prefix} [data-chart=${id}] { ${colorConfig - .map(([_, itemConfig]) => { - const transformedKey = itemConfig.transformed; - const themeValue = itemConfig.theme?.[theme as keyof typeof itemConfig.theme]; - const color = - typeof themeValue === "string" ? themeValue : themeValue?.color || itemConfig.color; - const secondaryColor = - typeof themeValue === "object" - ? themeValue?.secondaryColor - : "secondaryColor" in itemConfig - ? itemConfig.secondaryColor - : undefined; - - return [ - color ? ` --color-${transformedKey}: ${color};` : null, - secondaryColor ? ` --color-${transformedKey}-secondary: ${secondaryColor};` : null, - ] - .filter(Boolean) - .join("\n"); - }) - .filter(Boolean) - .join("\n")} + .map(([_, itemConfig]) => { + const transformedKey = itemConfig.transformed; + const themeValue = itemConfig.theme?.[theme as keyof typeof itemConfig.theme]; + const color = + typeof themeValue === "string" ? themeValue : themeValue?.color || itemConfig.color; + const secondaryColor = + typeof themeValue === "object" + ? themeValue?.secondaryColor + : "secondaryColor" in itemConfig + ? itemConfig.secondaryColor + : undefined; + + return [ + color ? ` --color-${transformedKey}: ${color};` : null, + secondaryColor ? ` --color-${transformedKey}-secondary: ${secondaryColor};` : null, + ] + .filter(Boolean) + .join("\n"); + }) + .filter(Boolean) + .join("\n")} } `, ) @@ -177,14 +205,14 @@ const ChartTooltip = RechartsPrimitive.Tooltip; const ChartTooltipContent = forwardRef< HTMLDivElement, React.ComponentProps & - React.ComponentProps<"div"> & { - hideLabel?: boolean; - hideIndicator?: boolean; - indicator?: "line" | "dot" | "dashed"; - nameKey?: string; - labelKey?: string; - showPercentage?: boolean; - } + React.ComponentProps<"div"> & { + hideLabel?: boolean; + hideIndicator?: boolean; + indicator?: "line" | "dot" | "dashed"; + nameKey?: string; + labelKey?: string; + showPercentage?: boolean; + } >( ( { @@ -328,10 +356,10 @@ const ChartLegend = RechartsPrimitive.Legend; const ChartLegendContent = forwardRef< HTMLDivElement, React.ComponentProps<"div"> & - Pick & { - hideIcon?: boolean; - nameKey?: string; - } + Pick & { + hideIcon?: boolean; + nameKey?: string; + } >(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => { const { config } = useChart(); diff --git a/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx b/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx index 1cfcf1e2a..96a30a6ab 100644 --- a/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx @@ -6,7 +6,7 @@ import { useId } from "../../../polyfills"; import { useTheme } from "../../ThemeProvider"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useTransformedKeys } from "../hooks"; +import { useExportChartData, useTransformedKeys } from "../hooks"; import { useHorizontalBarLabelHeight } from "../hooks/useMaxLabelHeight"; import { CustomTooltipContent, @@ -197,7 +197,7 @@ const HorizontalBarChartComponent = ({ useEffect(() => { // Set up ResizeObserver if height or width is not provided if (!chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -245,6 +245,20 @@ const HorizontalBarChartComponent = ({ return getLegendItems(dataKeys, colors, icons); }, [dataKeys, colors, icons]); + const exportData = useExportChartData({ + type: "bar", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + extraOptions: { + barDir: "bar", + }, + }); + const id = useId(); const xAxis = useMemo(() => { @@ -337,7 +351,7 @@ const HorizontalBarChartComponent = ({ [dataKeys, colors], ); - const setLabelWidth = useCallback(() => {}, []); + const setLabelWidth = useCallback(() => { }, []); return ( @@ -347,7 +361,10 @@ const HorizontalBarChartComponent = ({ data={sideBarTooltipData} setData={setSideBarTooltipData} > -
+
({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -228,6 +228,20 @@ export const LineChart = ({ return getLegendItems(dataKeys, colors, icons); }, [dataKeys, colors, icons]); + const exportData = useExportChartData({ + type: "line", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + extraOptions: { + lineSize: strokeWidth, + }, + }); + const id = useId(); const onLineClick = useCallback( @@ -314,6 +328,7 @@ export const LineChart = ({ >
({ dataLength: sortedProcessedData.length, }); + const exportData = useExportChartData({ + type: "pie", + data: sortedProcessedData, + categoryKey: categoryKey as string, + dataKeys: [dataKey as string], + colors, + legend, + }); + // Memoize expensive data transformations and configurations const transformedData = useMemo( () => transformDataWithPercentages(sortedProcessedData as T, dataKey), @@ -445,7 +454,12 @@ const PieChartComponent = ({ }, [width, height]); return ( -
+
diff --git a/js/packages/react-ui/src/components/Charts/RadarChart/RadarChart.tsx b/js/packages/react-ui/src/components/Charts/RadarChart/RadarChart.tsx index a418534c8..6f8579bfb 100644 --- a/js/packages/react-ui/src/components/Charts/RadarChart/RadarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/RadarChart/RadarChart.tsx @@ -10,7 +10,7 @@ import { import { usePrintContext } from "../../../context/PrintContext"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useTransformedKeys } from "../hooks/useTransformKey"; +import { useExportChartData, useTransformedKeys } from "../hooks"; import { ActiveDot, CustomTooltipContent, DefaultLegend } from "../shared"; import { LegendItem } from "../types"; import { useChartPalette } from "../utils/PalletUtils"; @@ -77,6 +77,15 @@ const RadarChartComponent = ({ return getLegendItems(dataKeys, colors, icons); }, [dataKeys, colors, icons]); + const exportData = useExportChartData({ + type: "radar", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + }); + const [isLegendExpanded, setIsLegendExpanded] = useState(false); const wrapperRef = useRef(null); const [wrapperRect, setWrapperRect] = useState({ width: 0, height: 0 }); @@ -195,7 +204,12 @@ const RadarChartComponent = ({ data={undefined} setData={() => {}} > -
+
diff --git a/js/packages/react-ui/src/components/Charts/RadialChart/RadialChart.tsx b/js/packages/react-ui/src/components/Charts/RadialChart/RadialChart.tsx index c12ec93d2..930490e04 100644 --- a/js/packages/react-ui/src/components/Charts/RadialChart/RadialChart.tsx +++ b/js/packages/react-ui/src/components/Charts/RadialChart/RadialChart.tsx @@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Cell, PolarGrid, RadialBar, RadialBarChart, ResponsiveContainer } from "recharts"; import { usePrintContext } from "../../../context/PrintContext"; import { ChartContainer, ChartTooltip, ChartTooltipContent } from "../Charts"; -import { useTransformedKeys } from "../hooks"; +import { useExportChartData, useTransformedKeys } from "../hooks"; import { DefaultLegend } from "../shared/DefaultLegend/DefaultLegend"; import { StackedLegend } from "../shared/StackedLegend/StackedLegend"; import { LegendItem } from "../types/Legend"; @@ -150,6 +150,15 @@ export const RadialChart = ({ dataLength: sortedProcessedData.length, }); + const exportData = useExportChartData({ + type: "pie", + data: sortedProcessedData, + categoryKey: categoryKey as string, + dataKeys: [dataKey as string], + colors, + legend, + }); + // Memoize expensive data transformations and configurations const transformedData = useMemo( () => transformRadialDataWithPercentages(sortedProcessedData as T, dataKey, colors), @@ -332,6 +341,7 @@ export const RadialChart = ({ className={wrapperClassName} style={wrapperStyle} aria-description="radial-chart-wrapper" + data-crayon-chart={exportData} >
diff --git a/js/packages/react-ui/src/components/Charts/ScatterChart/ScatterChart.tsx b/js/packages/react-ui/src/components/Charts/ScatterChart/ScatterChart.tsx index 027b957d4..9c78aa8c9 100644 --- a/js/packages/react-ui/src/components/Charts/ScatterChart/ScatterChart.tsx +++ b/js/packages/react-ui/src/components/Charts/ScatterChart/ScatterChart.tsx @@ -5,7 +5,7 @@ import { usePrintContext } from "../../../context/PrintContext"; import { useId } from "../../../polyfills"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useYAxisLabelWidth } from "../hooks"; +import { useExportChartData, useYAxisLabelWidth } from "../hooks"; import { CustomTooltipContent, DefaultLegend, @@ -189,6 +189,21 @@ export const ScatterChart = ({ return getLegendItems(datasets, colors); }, [datasets, colors]); + const exportData = useExportChartData({ + type: "scatter", + data, + colors, + legend, + xAxisLabel, + yAxisLabel, + customDataTransform: () => + data.map((dataset) => ({ + name: dataset.name, + x: dataset.data.map((p) => p[xAxisDataKey] as number), + y: dataset.data.map((p) => p[yAxisDataKey] as number), + })), + }); + const id = useId(); const xAxis = useMemo(() => { @@ -299,6 +314,7 @@ export const ScatterChart = ({ >
({ [segments, colors], ); + const printContext = usePrintContext(); + + const exportData = useExportChartData({ + type: "bar", + data, + categoryKey: categoryKey as string, + dataKeys: [dataKey as string], + colors, + legend, + extraOptions: { + barDir: "bar", + barGrouping: "stacked", + }, + }); + // Handle legend item hover with tooltip positioning const handleLegendItemHover = useCallback( (hoverIndex: number | null) => { @@ -142,6 +159,7 @@ export const SingleStackedBar = ({ "crayon-single-stacked-bar-chart-container-gap": legend && legendVariant === "default", })} style={style} + data-crayon-chart={exportData} >
{segments.map((segment, index) => { diff --git a/js/packages/react-ui/src/components/Charts/hooks/index.ts b/js/packages/react-ui/src/components/Charts/hooks/index.ts index ad182fdf0..e465f700c 100644 --- a/js/packages/react-ui/src/components/Charts/hooks/index.ts +++ b/js/packages/react-ui/src/components/Charts/hooks/index.ts @@ -1,5 +1,6 @@ export * from "./useAutoAngleCalculation"; export * from "./useCanvasContextForLabelSize"; +export * from "./useExportChartData"; export * from "./useMaxLabelHeight"; export * from "./useMaxLabelWidth"; export * from "./useTransformKey"; diff --git a/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts b/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts new file mode 100644 index 000000000..1440135c0 --- /dev/null +++ b/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts @@ -0,0 +1,78 @@ +import { useMemo } from "react"; +import { usePrintContext } from "../../../context/PrintContext"; +import { ExportChartData } from "../Charts"; + +export interface UseExportChartDataProps { + type: ExportChartData["type"]; + data: any[]; + categoryKey?: string; + dataKeys?: string[]; + colors: string[]; + legend?: boolean; + xAxisLabel?: React.ReactNode; + yAxisLabel?: React.ReactNode; + extraOptions?: Omit< + NonNullable, + "chartColors" | "showLegend" | "catAxisTitle" | "valAxisTitle" + >; + // For specialized charts like scatter + customDataTransform?: () => ExportChartData["data"]; +} + +export const useExportChartData = ({ + type, + data, + categoryKey, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + extraOptions, + customDataTransform, +}: UseExportChartDataProps): string | undefined => { + const printContext = usePrintContext(); + + return useMemo(() => { + if (!printContext) { + return undefined; + } + + const chartData = customDataTransform + ? customDataTransform() + : (dataKeys || []).map((key) => ({ + name: key, + labels: data.map((item) => (categoryKey ? String(item[categoryKey]) : "")), + values: data.map((item) => Number(item[key])), + })); + + const exportData: ExportChartData = { + type, + data: chartData, + options: { + chartColors: colors, + showLegend: legend, + catAxisTitle: typeof xAxisLabel === "string" ? xAxisLabel : undefined, + showCatAxisTitle: typeof xAxisLabel === "string", + valAxisTitle: typeof yAxisLabel === "string" ? yAxisLabel : undefined, + showValAxisTitle: typeof yAxisLabel === "string", + ...extraOptions, + }, + }; + + return JSON.stringify(exportData); + }, [ + type, + data, + dataKeys, + categoryKey, + colors, + legend, + xAxisLabel, + yAxisLabel, + extraOptions, + customDataTransform, + printContext, + ]); +}; + diff --git a/js/packages/react-ui/src/index.ts b/js/packages/react-ui/src/index.ts index c854d5a2a..e39a5070e 100644 --- a/js/packages/react-ui/src/index.ts +++ b/js/packages/react-ui/src/index.ts @@ -11,6 +11,7 @@ export * from "./components/CheckBoxGroup"; export * from "./components/CheckBoxItem"; export * from "./components/CodeBlock"; export * as CopilotShell from "./components/CopilotShell"; +export type { ExportChartData } from "./components/Charts/Charts"; export * from "./components/CrayonChat"; export * from "./components/DatePicker"; export * from "./components/FollowUpBlock"; From 8d6d2c3b2950a9d947fab121fa01f2977cfe1897 Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 22 Jan 2026 16:12:22 +0530 Subject: [PATCH 2/6] fmt --- .../components/Charts/AreaChart/AreaChart.tsx | 9 +- .../components/Charts/BarChart/BarChart.tsx | 9 +- .../react-ui/src/components/Charts/Charts.tsx | 86 +++++++++---------- .../HorizontalBarChart/HorizontalBarChart.tsx | 4 +- .../components/Charts/LineChart/LineChart.tsx | 11 ++- .../Charts/hooks/useExportChartData.ts | 1 - js/packages/react-ui/src/index.ts | 2 +- 7 files changed, 68 insertions(+), 54 deletions(-) diff --git a/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx b/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx index 6581d372e..e690de3dd 100644 --- a/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx +++ b/js/packages/react-ui/src/components/Charts/AreaChart/AreaChart.tsx @@ -5,7 +5,12 @@ import { usePrintContext } from "../../../context/PrintContext"; import { useId } from "../../../polyfills"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useExportChartData, useMaxLabelHeight, useTransformedKeys, useYAxisLabelWidth } from "../hooks"; +import { + useExportChartData, + useMaxLabelHeight, + useTransformedKeys, + useYAxisLabelWidth, +} from "../hooks"; import { ActiveDot, cartesianGrid, @@ -182,7 +187,7 @@ const AreaChartComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { diff --git a/js/packages/react-ui/src/components/Charts/BarChart/BarChart.tsx b/js/packages/react-ui/src/components/Charts/BarChart/BarChart.tsx index 280603f48..e8d069dee 100644 --- a/js/packages/react-ui/src/components/Charts/BarChart/BarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/BarChart/BarChart.tsx @@ -6,7 +6,12 @@ import { useId } from "../../../polyfills"; import { useTheme } from "../../ThemeProvider"; import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useExportChartData, useMaxLabelHeight, useTransformedKeys, useYAxisLabelWidth } from "../hooks"; +import { + useExportChartData, + useMaxLabelHeight, + useTransformedKeys, + useYAxisLabelWidth, +} from "../hooks"; import { cartesianGrid, CustomTooltipContent, @@ -206,7 +211,7 @@ const BarChartComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { diff --git a/js/packages/react-ui/src/components/Charts/Charts.tsx b/js/packages/react-ui/src/components/Charts/Charts.tsx index 3f377f2d3..44424d449 100644 --- a/js/packages/react-ui/src/components/Charts/Charts.tsx +++ b/js/packages/react-ui/src/components/Charts/Charts.tsx @@ -28,16 +28,16 @@ export type ChartConfig = { } & ( | { color?: string; secondaryColor?: string; theme?: never } | { - color?: never; - theme: Record< - keyof typeof THEMES, - | string - | { - color: string; - secondaryColor?: string; - } - >; - } + color?: never; + theme: Record< + keyof typeof THEMES, + | string + | { + color: string; + secondaryColor?: string; + } + >; + } ); }; @@ -111,27 +111,27 @@ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { ([theme, prefix]) => ` ${prefix} [data-chart=${id}] { ${colorConfig - .map(([_, itemConfig]) => { - const transformedKey = itemConfig.transformed; - const themeValue = itemConfig.theme?.[theme as keyof typeof itemConfig.theme]; - const color = - typeof themeValue === "string" ? themeValue : themeValue?.color || itemConfig.color; - const secondaryColor = - typeof themeValue === "object" - ? themeValue?.secondaryColor - : "secondaryColor" in itemConfig - ? itemConfig.secondaryColor - : undefined; - - return [ - color ? ` --color-${transformedKey}: ${color};` : null, - secondaryColor ? ` --color-${transformedKey}-secondary: ${secondaryColor};` : null, - ] - .filter(Boolean) - .join("\n"); - }) - .filter(Boolean) - .join("\n")} + .map(([_, itemConfig]) => { + const transformedKey = itemConfig.transformed; + const themeValue = itemConfig.theme?.[theme as keyof typeof itemConfig.theme]; + const color = + typeof themeValue === "string" ? themeValue : themeValue?.color || itemConfig.color; + const secondaryColor = + typeof themeValue === "object" + ? themeValue?.secondaryColor + : "secondaryColor" in itemConfig + ? itemConfig.secondaryColor + : undefined; + + return [ + color ? ` --color-${transformedKey}: ${color};` : null, + secondaryColor ? ` --color-${transformedKey}-secondary: ${secondaryColor};` : null, + ] + .filter(Boolean) + .join("\n"); + }) + .filter(Boolean) + .join("\n")} } `, ) @@ -205,14 +205,14 @@ const ChartTooltip = RechartsPrimitive.Tooltip; const ChartTooltipContent = forwardRef< HTMLDivElement, React.ComponentProps & - React.ComponentProps<"div"> & { - hideLabel?: boolean; - hideIndicator?: boolean; - indicator?: "line" | "dot" | "dashed"; - nameKey?: string; - labelKey?: string; - showPercentage?: boolean; - } + React.ComponentProps<"div"> & { + hideLabel?: boolean; + hideIndicator?: boolean; + indicator?: "line" | "dot" | "dashed"; + nameKey?: string; + labelKey?: string; + showPercentage?: boolean; + } >( ( { @@ -356,10 +356,10 @@ const ChartLegend = RechartsPrimitive.Legend; const ChartLegendContent = forwardRef< HTMLDivElement, React.ComponentProps<"div"> & - Pick & { - hideIcon?: boolean; - nameKey?: string; - } + Pick & { + hideIcon?: boolean; + nameKey?: string; + } >(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => { const { config } = useChart(); diff --git a/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx b/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx index 96a30a6ab..09ab59f33 100644 --- a/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/HorizontalBarChart/HorizontalBarChart.tsx @@ -197,7 +197,7 @@ const HorizontalBarChartComponent = ({ useEffect(() => { // Set up ResizeObserver if height or width is not provided if (!chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { @@ -351,7 +351,7 @@ const HorizontalBarChartComponent = ({ [dataKeys, colors], ); - const setLabelWidth = useCallback(() => { }, []); + const setLabelWidth = useCallback(() => {}, []); return ( diff --git a/js/packages/react-ui/src/components/Charts/LineChart/LineChart.tsx b/js/packages/react-ui/src/components/Charts/LineChart/LineChart.tsx index e4e54fca2..aa87a198e 100644 --- a/js/packages/react-ui/src/components/Charts/LineChart/LineChart.tsx +++ b/js/packages/react-ui/src/components/Charts/LineChart/LineChart.tsx @@ -3,9 +3,14 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react" import { Line, LineChart as RechartsLineChart, XAxis, YAxis } from "recharts"; import { usePrintContext } from "../../../context/PrintContext"; import { useId } from "../../../polyfills"; -import { ChartConfig, ChartContainer, ChartTooltip, ExportChartData } from "../Charts"; +import { ChartConfig, ChartContainer, ChartTooltip } from "../Charts"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; -import { useExportChartData, useMaxLabelHeight, useTransformedKeys, useYAxisLabelWidth } from "../hooks"; +import { + useExportChartData, + useMaxLabelHeight, + useTransformedKeys, + useYAxisLabelWidth, +} from "../hooks"; import { ActiveDot, cartesianGrid, @@ -182,7 +187,7 @@ export const LineChart = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { diff --git a/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts b/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts index 1440135c0..c86ba39e8 100644 --- a/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts +++ b/js/packages/react-ui/src/components/Charts/hooks/useExportChartData.ts @@ -75,4 +75,3 @@ export const useExportChartData = ({ printContext, ]); }; - diff --git a/js/packages/react-ui/src/index.ts b/js/packages/react-ui/src/index.ts index e39a5070e..8249cab49 100644 --- a/js/packages/react-ui/src/index.ts +++ b/js/packages/react-ui/src/index.ts @@ -7,11 +7,11 @@ export * from "./components/Card"; export * from "./components/CardHeader"; export * from "./components/Carousel"; export * from "./components/Charts"; +export type { ExportChartData } from "./components/Charts/Charts"; export * from "./components/CheckBoxGroup"; export * from "./components/CheckBoxItem"; export * from "./components/CodeBlock"; export * as CopilotShell from "./components/CopilotShell"; -export type { ExportChartData } from "./components/Charts/Charts"; export * from "./components/CrayonChat"; export * from "./components/DatePicker"; export * from "./components/FollowUpBlock"; From 41711c30fa9f4a32192d8f9d31a1af861c7baab8 Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 22 Jan 2026 16:40:47 +0530 Subject: [PATCH 3/6] add changes in condensed variants --- .../AreaChartCondensed/AreaChartCondensed.tsx | 17 +++++++++++++++-- .../BarChartCondensed/BarChartCondensed.tsx | 15 ++++++++++++++- .../LineChartCondensed/LineChartCondensed.tsx | 18 +++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx b/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx index b7d95b9bc..c26dac2db 100644 --- a/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx +++ b/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx @@ -9,6 +9,7 @@ import { DEFAULT_X_AXIS_HEIGHT, X_AXIS_PADDING } from "../constants"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; import { useAutoAngleCalculation, + useExportChartData, useMaxLabelWidth, useTransformedKeys, useYAxisLabelWidth, @@ -134,6 +135,17 @@ const AreaChartCondensedComponent = ({ }, [dataKeys, icons, colors, transformedKeys]); const id = useId(); + + const exportData = useExportChartData({ + type: "area", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + }); const gradientID = useMemo(() => `area-chart-condensed-gradient-${id}`, [id]); const chartMargin = useMemo( @@ -181,7 +193,7 @@ const AreaChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -279,6 +291,7 @@ const AreaChartCondensedComponent = ({ >
({ activeDot={} dot={false} isAnimationActive={isAnimationActive} - // strokeWidth={2} + // strokeWidth={2} /> ); })} diff --git a/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx b/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx index d8ca9aaf3..d34ea8d94 100644 --- a/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx +++ b/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx @@ -10,6 +10,7 @@ import { DEFAULT_X_AXIS_HEIGHT, X_AXIS_PADDING } from "../constants"; import { SideBarChartData, SideBarTooltipProvider } from "../context/SideBarTooltipContext"; import { useAutoAngleCalculation, + useExportChartData, useMaxLabelWidth, useTransformedKeys, useYAxisLabelWidth, @@ -140,6 +141,17 @@ const BarChartCondensedComponent = ({ const id = useId(); + const exportData = useExportChartData({ + type: "bar", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + }); + const chartMargin = useMemo( () => ({ top: 10, @@ -221,7 +233,7 @@ const BarChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -378,6 +390,7 @@ const BarChartCondensedComponent = ({ >
({ const id = useId(); + const exportData = useExportChartData({ + type: "line", + data, + categoryKey: categoryKey as string, + dataKeys, + colors, + legend, + xAxisLabel, + yAxisLabel, + extraOptions: { + lineSize: strokeWidth, + }, + }); + const chartMargin = useMemo( () => ({ top: 10, @@ -181,7 +196,7 @@ const LineChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => {}; + return () => { }; } const resizeObserver = new ResizeObserver((entries) => { @@ -279,6 +294,7 @@ const LineChartCondensedComponent = ({ >
Date: Thu, 22 Jan 2026 16:41:33 +0530 Subject: [PATCH 4/6] fmt --- .../Charts/AreaChartCondensed/AreaChartCondensed.tsx | 4 ++-- .../components/Charts/BarChartCondensed/BarChartCondensed.tsx | 2 +- .../Charts/LineChartCondensed/LineChartCondensed.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx b/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx index c26dac2db..54b3b253f 100644 --- a/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx +++ b/js/packages/react-ui/src/components/Charts/AreaChartCondensed/AreaChartCondensed.tsx @@ -193,7 +193,7 @@ const AreaChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { @@ -377,7 +377,7 @@ const AreaChartCondensedComponent = ({ activeDot={} dot={false} isAnimationActive={isAnimationActive} - // strokeWidth={2} + // strokeWidth={2} /> ); })} diff --git a/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx b/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx index d34ea8d94..8ece25982 100644 --- a/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx +++ b/js/packages/react-ui/src/components/Charts/BarChartCondensed/BarChartCondensed.tsx @@ -233,7 +233,7 @@ const BarChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { diff --git a/js/packages/react-ui/src/components/Charts/LineChartCondensed/LineChartCondensed.tsx b/js/packages/react-ui/src/components/Charts/LineChartCondensed/LineChartCondensed.tsx index f47505ebb..8ee1fe9e5 100644 --- a/js/packages/react-ui/src/components/Charts/LineChartCondensed/LineChartCondensed.tsx +++ b/js/packages/react-ui/src/components/Charts/LineChartCondensed/LineChartCondensed.tsx @@ -196,7 +196,7 @@ const LineChartCondensedComponent = ({ useEffect(() => { // Only set up ResizeObserver if width is not provided if (width || !containerRef.current || !chartContainerRef.current) { - return () => { }; + return () => {}; } const resizeObserver = new ResizeObserver((entries) => { From 303951143f75496fea945a5e4fde72696f5b7b4d Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 22 Jan 2026 16:42:42 +0530 Subject: [PATCH 5/6] lint fix --- .../Charts/SingleStackedBarChart/SingleStackedBarChart.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx b/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx index 2fd3d9b56..7e6155f0e 100644 --- a/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx @@ -103,8 +103,6 @@ export const SingleStackedBar = ({ [segments, colors], ); - const printContext = usePrintContext(); - const exportData = useExportChartData({ type: "bar", data, From 57bdfac8ab5b7a777939c0dc4d0c202e2beb1adc Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 22 Jan 2026 16:44:12 +0530 Subject: [PATCH 6/6] disable animation in single stacked bar chart --- .../Charts/SingleStackedBarChart/SingleStackedBarChart.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx b/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx index 7e6155f0e..8ba8ae81f 100644 --- a/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx +++ b/js/packages/react-ui/src/components/Charts/SingleStackedBarChart/SingleStackedBarChart.tsx @@ -103,6 +103,9 @@ export const SingleStackedBar = ({ [segments, colors], ); + const printContext = usePrintContext(); + animated = printContext ? false : animated; + const exportData = useExportChartData({ type: "bar", data,