@classic-homes/charts-react 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @classic-homes/charts-react
2
+
3
+ React ECharts components for the Classic Theme design system. Charts pick up the Classic light and dark themes from `@classic-homes/charts-core`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @classic-homes/charts-react echarts react react-dom
9
+ ```
10
+
11
+ Peer dependencies: `echarts@^5.5.0`, `react@^18 || ^19`, `react-dom@^18 || ^19`.
12
+
13
+ ## Quick Start
14
+
15
+ ```tsx
16
+ import { LineChart } from '@classic-homes/charts-react';
17
+
18
+ const data = {
19
+ categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
20
+ series: [
21
+ { name: '2024', data: [120, 132, 101, 134, 90, 230] },
22
+ { name: '2025', data: [220, 182, 191, 234, 290, 330] },
23
+ ],
24
+ };
25
+
26
+ export function RevenueChart() {
27
+ return <LineChart data={data} />;
28
+ }
29
+ ```
30
+
31
+ ## Exports
32
+
33
+ - **Core charts**: `LineChart`, `BarChart`, `PieChart`, `AreaChart`, `ScatterChart`, `DonutChart`
34
+ - **Extended charts**: `RadarChart`, `FunnelChart`, `GaugeChart`, `HeatmapChart`, `TreemapChart`, `CandlestickChart`, `SankeyChart`
35
+ - **Base components**: `ChartContainer`, `ChartSkeleton`, `ChartError`, `ChartEmpty`, `ChartLegend`
36
+ - **Hooks**: `useChart`, `useChartTheme`, `useChartResize`, `useReducedMotion`, `registerClassicThemes`, `useChartLegend`
37
+ - **Utilities**: `cn`
38
+ - **Types**: component props (`LineChartComponentProps`, ...) and the chart data and event types re-exported from `@classic-homes/charts-core`
39
+
40
+ Chart data and option types come from `@classic-homes/charts-core/types`.
41
+
42
+ ```tsx
43
+ import type { LineChartData } from '@classic-homes/charts-core/types';
44
+ ```
package/dist/index.cjs CHANGED
@@ -201,6 +201,30 @@ ChartEmpty.displayName = "ChartEmpty";
201
201
 
202
202
  // src/components/base/ChartContainer.tsx
203
203
  var import_jsx_runtime4 = require("react/jsx-runtime");
204
+ var CHART_ONLY_PROPS = [
205
+ "minHeight",
206
+ "maxHeight",
207
+ "rowHeight",
208
+ "showLegend",
209
+ "showGrid",
210
+ "valueFormat",
211
+ "locale",
212
+ "onReady",
213
+ "events",
214
+ "showDataTable",
215
+ "exportable",
216
+ "patterns",
217
+ "referenceLines",
218
+ "referenceBands",
219
+ "dataZoom",
220
+ "connectNulls",
221
+ "zoomStart"
222
+ ];
223
+ function domProps(props) {
224
+ const rest = { ...props };
225
+ for (const key of CHART_ONLY_PROPS) delete rest[key];
226
+ return rest;
227
+ }
204
228
  var ChartContainer = React4.forwardRef(
205
229
  ({
206
230
  title,
@@ -246,7 +270,7 @@ var ChartContainer = React4.forwardRef(
246
270
  "aria-describedby": description ? descriptionId : void 0,
247
271
  "data-testid": "chart-container",
248
272
  className: legend ? "min-h-0 min-w-0 flex-1" : cn("rounded-lg border border-border bg-card", wrapperClassName),
249
- ...props,
273
+ ...domProps(props),
250
274
  children: [
251
275
  description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { id: descriptionId, className: "sr-only", children: description }),
252
276
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("h-full w-full", className), style: { height: heightStyle }, children })
@@ -832,6 +856,8 @@ var BarChart = React7.forwardRef(
832
856
  const categoryAxis = {
833
857
  type: "category",
834
858
  data: data.categories,
859
+ // Horizontal bars list the first category at the top
860
+ inverse: isHorizontal,
835
861
  axisTick: {
836
862
  alignWithLabel: true
837
863
  }
@@ -1827,6 +1853,7 @@ var RadarChart = React12.forwardRef(
1827
1853
  renderLegend,
1828
1854
  onLegendChange,
1829
1855
  option: optionOverride,
1856
+ onClick,
1830
1857
  class: className,
1831
1858
  ...props
1832
1859
  }, ref) => {
@@ -1904,12 +1931,27 @@ var RadarChart = React12.forwardRef(
1904
1931
  customLegend,
1905
1932
  optionOverride
1906
1933
  ]);
1934
+ const latest = useLatestRef({ onClick });
1907
1935
  const { containerRef } = useChart({
1908
1936
  option,
1909
1937
  theme,
1910
1938
  animation,
1911
1939
  onReady: (chart) => {
1912
1940
  legend.attach(chart);
1941
+ chart.on("click", (params) => {
1942
+ const { onClick: onClick2 } = latest.current;
1943
+ if (!onClick2) return;
1944
+ onClick2({
1945
+ type: params.type || "click",
1946
+ componentType: params.componentType || "series",
1947
+ seriesIndex: params.seriesIndex,
1948
+ seriesName: params.seriesName || "",
1949
+ dataIndex: params.dataIndex ?? 0,
1950
+ name: params.name || "",
1951
+ value: params.value,
1952
+ color: params.color
1953
+ });
1954
+ });
1913
1955
  }
1914
1956
  });
1915
1957
  const accessibilityDescription = description || (!isEmpty ? `${title}. Radar chart with ${indicators.length} dimensions comparing ${data.series.length} series.` : void 0);
@@ -2144,6 +2186,7 @@ var GaugeChart = React14.forwardRef(
2144
2186
  tooltipFormatter,
2145
2187
  tooltipValueFormatter,
2146
2188
  option: optionOverride,
2189
+ onClick,
2147
2190
  class: className,
2148
2191
  ...props
2149
2192
  }, ref) => {
@@ -2250,10 +2293,27 @@ var GaugeChart = React14.forwardRef(
2250
2293
  tooltipValueFormatter,
2251
2294
  optionOverride
2252
2295
  ]);
2296
+ const latest = useLatestRef({ onClick });
2253
2297
  const { containerRef } = useChart({
2254
2298
  option,
2255
2299
  theme: currentTheme === import_charts_core12.THEME_DARK ? "dark" : "light",
2256
- animation
2300
+ animation,
2301
+ onReady: (chart) => {
2302
+ chart.on("click", (params) => {
2303
+ const { onClick: onClick2 } = latest.current;
2304
+ if (!onClick2) return;
2305
+ onClick2({
2306
+ type: params.type || "click",
2307
+ componentType: params.componentType || "series",
2308
+ seriesIndex: params.seriesIndex,
2309
+ seriesName: params.seriesName || "",
2310
+ dataIndex: params.dataIndex ?? 0,
2311
+ name: params.name || "",
2312
+ value: params.value,
2313
+ color: params.color
2314
+ });
2315
+ });
2316
+ }
2257
2317
  });
2258
2318
  const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
2259
2319
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
package/dist/index.js CHANGED
@@ -141,6 +141,30 @@ ChartEmpty.displayName = "ChartEmpty";
141
141
 
142
142
  // src/components/base/ChartContainer.tsx
143
143
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
144
+ var CHART_ONLY_PROPS = [
145
+ "minHeight",
146
+ "maxHeight",
147
+ "rowHeight",
148
+ "showLegend",
149
+ "showGrid",
150
+ "valueFormat",
151
+ "locale",
152
+ "onReady",
153
+ "events",
154
+ "showDataTable",
155
+ "exportable",
156
+ "patterns",
157
+ "referenceLines",
158
+ "referenceBands",
159
+ "dataZoom",
160
+ "connectNulls",
161
+ "zoomStart"
162
+ ];
163
+ function domProps(props) {
164
+ const rest = { ...props };
165
+ for (const key of CHART_ONLY_PROPS) delete rest[key];
166
+ return rest;
167
+ }
144
168
  var ChartContainer = React4.forwardRef(
145
169
  ({
146
170
  title,
@@ -186,7 +210,7 @@ var ChartContainer = React4.forwardRef(
186
210
  "aria-describedby": description ? descriptionId : void 0,
187
211
  "data-testid": "chart-container",
188
212
  className: legend ? "min-h-0 min-w-0 flex-1" : cn("rounded-lg border border-border bg-card", wrapperClassName),
189
- ...props,
213
+ ...domProps(props),
190
214
  children: [
191
215
  description && /* @__PURE__ */ jsx4("span", { id: descriptionId, className: "sr-only", children: description }),
192
216
  /* @__PURE__ */ jsx4("div", { className: cn("h-full w-full", className), style: { height: heightStyle }, children })
@@ -808,6 +832,8 @@ var BarChart = React7.forwardRef(
808
832
  const categoryAxis = {
809
833
  type: "category",
810
834
  data: data.categories,
835
+ // Horizontal bars list the first category at the top
836
+ inverse: isHorizontal,
811
837
  axisTick: {
812
838
  alignWithLabel: true
813
839
  }
@@ -1877,6 +1903,7 @@ var RadarChart = React12.forwardRef(
1877
1903
  renderLegend,
1878
1904
  onLegendChange,
1879
1905
  option: optionOverride,
1906
+ onClick,
1880
1907
  class: className,
1881
1908
  ...props
1882
1909
  }, ref) => {
@@ -1954,12 +1981,27 @@ var RadarChart = React12.forwardRef(
1954
1981
  customLegend,
1955
1982
  optionOverride
1956
1983
  ]);
1984
+ const latest = useLatestRef({ onClick });
1957
1985
  const { containerRef } = useChart({
1958
1986
  option,
1959
1987
  theme,
1960
1988
  animation,
1961
1989
  onReady: (chart) => {
1962
1990
  legend.attach(chart);
1991
+ chart.on("click", (params) => {
1992
+ const { onClick: onClick2 } = latest.current;
1993
+ if (!onClick2) return;
1994
+ onClick2({
1995
+ type: params.type || "click",
1996
+ componentType: params.componentType || "series",
1997
+ seriesIndex: params.seriesIndex,
1998
+ seriesName: params.seriesName || "",
1999
+ dataIndex: params.dataIndex ?? 0,
2000
+ name: params.name || "",
2001
+ value: params.value,
2002
+ color: params.color
2003
+ });
2004
+ });
1963
2005
  }
1964
2006
  });
1965
2007
  const accessibilityDescription = description || (!isEmpty ? `${title}. Radar chart with ${indicators.length} dimensions comparing ${data.series.length} series.` : void 0);
@@ -2209,6 +2251,7 @@ var GaugeChart = React14.forwardRef(
2209
2251
  tooltipFormatter,
2210
2252
  tooltipValueFormatter,
2211
2253
  option: optionOverride,
2254
+ onClick,
2212
2255
  class: className,
2213
2256
  ...props
2214
2257
  }, ref) => {
@@ -2315,10 +2358,27 @@ var GaugeChart = React14.forwardRef(
2315
2358
  tooltipValueFormatter,
2316
2359
  optionOverride
2317
2360
  ]);
2361
+ const latest = useLatestRef({ onClick });
2318
2362
  const { containerRef } = useChart({
2319
2363
  option,
2320
2364
  theme: currentTheme === THEME_DARK5 ? "dark" : "light",
2321
- animation
2365
+ animation,
2366
+ onReady: (chart) => {
2367
+ chart.on("click", (params) => {
2368
+ const { onClick: onClick2 } = latest.current;
2369
+ if (!onClick2) return;
2370
+ onClick2({
2371
+ type: params.type || "click",
2372
+ componentType: params.componentType || "series",
2373
+ seriesIndex: params.seriesIndex,
2374
+ seriesName: params.seriesName || "",
2375
+ dataIndex: params.dataIndex ?? 0,
2376
+ name: params.name || "",
2377
+ value: params.value,
2378
+ color: params.color
2379
+ });
2380
+ });
2381
+ }
2322
2382
  });
2323
2383
  const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
2324
2384
  return /* @__PURE__ */ jsx14(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/charts-react",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "React ECharts components for Classic Theme",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -30,7 +30,6 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@classic-homes/charts-core": "*",
33
- "@classic-homes/theme-tokens": "*",
34
33
  "clsx": "^2.1.0",
35
34
  "tailwind-merge": "^2.2.0"
36
35
  },