@trackunit/react-chart-components 2.6.38 → 2.6.39
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/index.cjs.js +47 -15
- package/index.esm.js +48 -16
- package/migrations/entry.js.map +1 -0
- package/package.json +1 -1
- package/src/LegendItem/LegendItem.d.ts +56 -4
- package/src/LegendItem/LegendItem.variants.d.ts +3 -3
package/index.cjs.js
CHANGED
|
@@ -249,7 +249,14 @@ const cvaLegendItem = cssClassVarianceUtilities.cvaMerge([
|
|
|
249
249
|
},
|
|
250
250
|
isClickable: {
|
|
251
251
|
false: "cursor-default",
|
|
252
|
-
true:
|
|
252
|
+
true: [
|
|
253
|
+
"cursor-pointer",
|
|
254
|
+
"rounded-sm",
|
|
255
|
+
"focus-visible:outline-none",
|
|
256
|
+
"focus-visible:ring-2",
|
|
257
|
+
"focus-visible:ring-primary-500",
|
|
258
|
+
"focus-visible:ring-offset-2",
|
|
259
|
+
],
|
|
253
260
|
},
|
|
254
261
|
},
|
|
255
262
|
defaultVariants: {
|
|
@@ -258,27 +265,52 @@ const cvaLegendItem = cssClassVarianceUtilities.cvaMerge([
|
|
|
258
265
|
isClickable: false,
|
|
259
266
|
},
|
|
260
267
|
});
|
|
261
|
-
const cvaLegendItemIndicator = cssClassVarianceUtilities.cvaMerge(["w-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
false: "",
|
|
265
|
-
true: "",
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
defaultVariants: {
|
|
269
|
-
selected: false,
|
|
270
|
-
},
|
|
271
|
-
});
|
|
268
|
+
const cvaLegendItemIndicator = cssClassVarianceUtilities.cvaMerge(["w-2.5", "mr-1", "h-2.5", "rounded-[50%]", "flex-none"]);
|
|
269
|
+
const cvaLegendItemLineSwatch = cssClassVarianceUtilities.cvaMerge(["relative", "mr-1", "h-3", "w-5", "flex-none", "overflow-hidden"]);
|
|
270
|
+
const cvaLegendItemLineSvg = cssClassVarianceUtilities.cvaMerge(["h-full", "w-full"]);
|
|
272
271
|
|
|
272
|
+
const LINE_SWATCH_WIDTH = 20;
|
|
273
|
+
const LINE_SWATCH_HEIGHT = 12;
|
|
274
|
+
const LINE_SWATCH_MID_Y = 6;
|
|
275
|
+
const LINE_STROKE_WIDTH = 2;
|
|
276
|
+
const LINE_DASH_ARRAY = "3 2";
|
|
277
|
+
const EMPTY_CIRCLE_RADIUS = 3;
|
|
278
|
+
const LegendItemSwatch = ({ color, dataTestId, indicator, symbol }) => {
|
|
279
|
+
switch (indicator) {
|
|
280
|
+
case "fill":
|
|
281
|
+
return (jsxRuntime.jsx("div", { className: cvaLegendItemIndicator(), "data-testid": dataTestId ? `${dataTestId}-indicator` : null, style: { backgroundColor: color } }));
|
|
282
|
+
case "solid line":
|
|
283
|
+
case "dashed line":
|
|
284
|
+
return (jsxRuntime.jsx("div", { className: cvaLegendItemLineSwatch(), "data-testid": dataTestId ? `${dataTestId}-indicator` : null, children: jsxRuntime.jsxs("svg", { "aria-hidden": "true", className: cvaLegendItemLineSvg(), viewBox: `0 0 ${LINE_SWATCH_WIDTH} ${LINE_SWATCH_HEIGHT}`, children: [jsxRuntime.jsx("line", { "data-testid": dataTestId ? `${dataTestId}-indicator-line` : null, stroke: color, strokeDasharray: indicator === "dashed line" ? LINE_DASH_ARRAY : undefined, strokeWidth: LINE_STROKE_WIDTH, x1: 0, x2: LINE_SWATCH_WIDTH, y1: LINE_SWATCH_MID_Y, y2: LINE_SWATCH_MID_Y }), indicator === "solid line" && symbol === "emptyCircle" ? (jsxRuntime.jsx("circle", { cx: LINE_SWATCH_WIDTH / 2, cy: LINE_SWATCH_MID_Y, "data-testid": dataTestId ? `${dataTestId}-indicator-symbol` : null, fill: "white", r: EMPTY_CIRCLE_RADIUS, stroke: color, strokeWidth: LINE_STROKE_WIDTH })) : null] }) }));
|
|
285
|
+
default:
|
|
286
|
+
return sharedUtils.exhaustiveCheck(indicator);
|
|
287
|
+
}
|
|
288
|
+
};
|
|
273
289
|
/**
|
|
274
|
-
* The LegendItem component is
|
|
290
|
+
* The LegendItem component is the standard chart legend row: a swatch, a label, and an optional count.
|
|
291
|
+
*
|
|
292
|
+
* ### When to use
|
|
293
|
+
* - Fill for field/sector bars and donut slices
|
|
294
|
+
* - Solid line with a hollow circle when individual data points are part of the reading
|
|
295
|
+
* - Dashed line with no symbol for averages, targets, and comparisons
|
|
275
296
|
*
|
|
276
297
|
* @param {LegendItem} props - The props for the LegendItem component
|
|
277
298
|
* @returns {ReactElement} LegendItem component
|
|
278
299
|
*/
|
|
279
|
-
const LegendItem = ({ className, style, count, label, disabled = false, selected = false, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit = undefined, hideValue = false, }) => {
|
|
300
|
+
const LegendItem = ({ className, style, count, label, disabled = false, selected = false, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit = undefined, hideValue = false, ...indicatorProps }) => {
|
|
280
301
|
const handleOnClick = onClick && !disabled ? e => onClick(e) : undefined;
|
|
281
|
-
|
|
302
|
+
const handleOnKeyDown = handleOnClick
|
|
303
|
+
? event => {
|
|
304
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
305
|
+
event.preventDefault();
|
|
306
|
+
event.currentTarget.click();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
: undefined;
|
|
310
|
+
const indicator = indicatorProps.indicator ?? "fill";
|
|
311
|
+
const symbol = indicatorProps.indicator === "solid line" ? (indicatorProps.symbol ?? "emptyCircle") : "none";
|
|
312
|
+
const isSwitch = handleOnClick !== undefined;
|
|
313
|
+
return (jsxRuntime.jsxs("div", { "aria-checked": isSwitch ? selected : undefined, className: cvaLegendItem({ disabled, selected, isClickable: isSwitch, className }), "data-testid": dataTestId, onClick: handleOnClick, onKeyDown: handleOnKeyDown, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, role: isSwitch ? "switch" : undefined, style: style, tabIndex: isSwitch ? 0 : undefined, children: [jsxRuntime.jsx(LegendItemSwatch, { color: color, dataTestId: dataTestId, indicator: indicator, symbol: symbol }), jsxRuntime.jsxs("p", { className: "truncate text-xs", children: [label, "\u00A0"] }), hideValue ? null : jsxRuntime.jsx("p", { className: "text-xs", children: `(${count ?? 0}${unit ?? ""})` })] }));
|
|
282
314
|
};
|
|
283
315
|
|
|
284
316
|
/**
|
package/index.esm.js
CHANGED
|
@@ -5,7 +5,7 @@ import { useLocale, useDateAndTime } from '@trackunit/react-date-and-time-hooks'
|
|
|
5
5
|
import { DEFAULT_CHART_COLORS, CHART_STATUS_COLORS, fontFamily, DEFAULT_CHART_OTHER } from '@trackunit/ui-design-tokens';
|
|
6
6
|
import { useRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
7
|
import { Spinner, Text, useMergeRefs } from '@trackunit/react-components';
|
|
8
|
-
import { objectKeys } from '@trackunit/shared-utils';
|
|
8
|
+
import { objectKeys, exhaustiveCheck } from '@trackunit/shared-utils';
|
|
9
9
|
import * as echarts from 'echarts';
|
|
10
10
|
|
|
11
11
|
function isECElementEvent(value) {
|
|
@@ -228,7 +228,14 @@ const cvaLegendItem = cvaMerge([
|
|
|
228
228
|
},
|
|
229
229
|
isClickable: {
|
|
230
230
|
false: "cursor-default",
|
|
231
|
-
true:
|
|
231
|
+
true: [
|
|
232
|
+
"cursor-pointer",
|
|
233
|
+
"rounded-sm",
|
|
234
|
+
"focus-visible:outline-none",
|
|
235
|
+
"focus-visible:ring-2",
|
|
236
|
+
"focus-visible:ring-primary-500",
|
|
237
|
+
"focus-visible:ring-offset-2",
|
|
238
|
+
],
|
|
232
239
|
},
|
|
233
240
|
},
|
|
234
241
|
defaultVariants: {
|
|
@@ -237,27 +244,52 @@ const cvaLegendItem = cvaMerge([
|
|
|
237
244
|
isClickable: false,
|
|
238
245
|
},
|
|
239
246
|
});
|
|
240
|
-
const cvaLegendItemIndicator = cvaMerge(["w-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
false: "",
|
|
244
|
-
true: "",
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
defaultVariants: {
|
|
248
|
-
selected: false,
|
|
249
|
-
},
|
|
250
|
-
});
|
|
247
|
+
const cvaLegendItemIndicator = cvaMerge(["w-2.5", "mr-1", "h-2.5", "rounded-[50%]", "flex-none"]);
|
|
248
|
+
const cvaLegendItemLineSwatch = cvaMerge(["relative", "mr-1", "h-3", "w-5", "flex-none", "overflow-hidden"]);
|
|
249
|
+
const cvaLegendItemLineSvg = cvaMerge(["h-full", "w-full"]);
|
|
251
250
|
|
|
251
|
+
const LINE_SWATCH_WIDTH = 20;
|
|
252
|
+
const LINE_SWATCH_HEIGHT = 12;
|
|
253
|
+
const LINE_SWATCH_MID_Y = 6;
|
|
254
|
+
const LINE_STROKE_WIDTH = 2;
|
|
255
|
+
const LINE_DASH_ARRAY = "3 2";
|
|
256
|
+
const EMPTY_CIRCLE_RADIUS = 3;
|
|
257
|
+
const LegendItemSwatch = ({ color, dataTestId, indicator, symbol }) => {
|
|
258
|
+
switch (indicator) {
|
|
259
|
+
case "fill":
|
|
260
|
+
return (jsx("div", { className: cvaLegendItemIndicator(), "data-testid": dataTestId ? `${dataTestId}-indicator` : null, style: { backgroundColor: color } }));
|
|
261
|
+
case "solid line":
|
|
262
|
+
case "dashed line":
|
|
263
|
+
return (jsx("div", { className: cvaLegendItemLineSwatch(), "data-testid": dataTestId ? `${dataTestId}-indicator` : null, children: jsxs("svg", { "aria-hidden": "true", className: cvaLegendItemLineSvg(), viewBox: `0 0 ${LINE_SWATCH_WIDTH} ${LINE_SWATCH_HEIGHT}`, children: [jsx("line", { "data-testid": dataTestId ? `${dataTestId}-indicator-line` : null, stroke: color, strokeDasharray: indicator === "dashed line" ? LINE_DASH_ARRAY : undefined, strokeWidth: LINE_STROKE_WIDTH, x1: 0, x2: LINE_SWATCH_WIDTH, y1: LINE_SWATCH_MID_Y, y2: LINE_SWATCH_MID_Y }), indicator === "solid line" && symbol === "emptyCircle" ? (jsx("circle", { cx: LINE_SWATCH_WIDTH / 2, cy: LINE_SWATCH_MID_Y, "data-testid": dataTestId ? `${dataTestId}-indicator-symbol` : null, fill: "white", r: EMPTY_CIRCLE_RADIUS, stroke: color, strokeWidth: LINE_STROKE_WIDTH })) : null] }) }));
|
|
264
|
+
default:
|
|
265
|
+
return exhaustiveCheck(indicator);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
252
268
|
/**
|
|
253
|
-
* The LegendItem component is
|
|
269
|
+
* The LegendItem component is the standard chart legend row: a swatch, a label, and an optional count.
|
|
270
|
+
*
|
|
271
|
+
* ### When to use
|
|
272
|
+
* - Fill for field/sector bars and donut slices
|
|
273
|
+
* - Solid line with a hollow circle when individual data points are part of the reading
|
|
274
|
+
* - Dashed line with no symbol for averages, targets, and comparisons
|
|
254
275
|
*
|
|
255
276
|
* @param {LegendItem} props - The props for the LegendItem component
|
|
256
277
|
* @returns {ReactElement} LegendItem component
|
|
257
278
|
*/
|
|
258
|
-
const LegendItem = ({ className, style, count, label, disabled = false, selected = false, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit = undefined, hideValue = false, }) => {
|
|
279
|
+
const LegendItem = ({ className, style, count, label, disabled = false, selected = false, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit = undefined, hideValue = false, ...indicatorProps }) => {
|
|
259
280
|
const handleOnClick = onClick && !disabled ? e => onClick(e) : undefined;
|
|
260
|
-
|
|
281
|
+
const handleOnKeyDown = handleOnClick
|
|
282
|
+
? event => {
|
|
283
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
284
|
+
event.preventDefault();
|
|
285
|
+
event.currentTarget.click();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
: undefined;
|
|
289
|
+
const indicator = indicatorProps.indicator ?? "fill";
|
|
290
|
+
const symbol = indicatorProps.indicator === "solid line" ? (indicatorProps.symbol ?? "emptyCircle") : "none";
|
|
291
|
+
const isSwitch = handleOnClick !== undefined;
|
|
292
|
+
return (jsxs("div", { "aria-checked": isSwitch ? selected : undefined, className: cvaLegendItem({ disabled, selected, isClickable: isSwitch, className }), "data-testid": dataTestId, onClick: handleOnClick, onKeyDown: handleOnKeyDown, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, role: isSwitch ? "switch" : undefined, style: style, tabIndex: isSwitch ? 0 : undefined, children: [jsx(LegendItemSwatch, { color: color, dataTestId: dataTestId, indicator: indicator, symbol: symbol }), jsxs("p", { className: "truncate text-xs", children: [label, "\u00A0"] }), hideValue ? null : jsx("p", { className: "text-xs", children: `(${count ?? 0}${unit ?? ""})` })] }));
|
|
261
293
|
};
|
|
262
294
|
|
|
263
295
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/chart-components/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["// Migration entry point for @nx/js:tsc build target.\n// Migrations are registered in ../migrations.json and resolved by NX at runtime.\nexport {};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { Refable, type Styleable } from "@trackunit/react-components";
|
|
2
|
-
import { MouseEventHandler } from "react";
|
|
3
|
-
|
|
2
|
+
import { MouseEventHandler, ReactElement } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Shape of the colour indicator. `fill` is a solid circle for a block of colour. `solid line` is a
|
|
5
|
+
* horizontal rule with an optional hollow-circle marker. `dashed line` is a reference series and
|
|
6
|
+
* never has a marker.
|
|
7
|
+
*/
|
|
8
|
+
export type LegendItemIndicator = "fill" | "solid line" | "dashed line";
|
|
9
|
+
/**
|
|
10
|
+
* Marker on a solid-line indicator. `emptyCircle` is the default hollow circle. Pass `none` only when
|
|
11
|
+
* the reader should follow the trend rather than each sample. Dashed lines cannot take a symbol.
|
|
12
|
+
*/
|
|
13
|
+
export type LegendItemSymbol = "none" | "emptyCircle";
|
|
14
|
+
interface LegendItemBaseProps extends Refable<HTMLDivElement>, Styleable {
|
|
4
15
|
label: string;
|
|
5
16
|
count?: number;
|
|
6
17
|
selected?: boolean;
|
|
@@ -14,10 +25,51 @@ export interface LegendItemProps extends Refable<HTMLDivElement>, Styleable {
|
|
|
14
25
|
unit?: "%";
|
|
15
26
|
hideValue?: boolean;
|
|
16
27
|
}
|
|
28
|
+
interface LegendItemFillProps extends LegendItemBaseProps {
|
|
29
|
+
/**
|
|
30
|
+
* Filled colour block for field/sector bars and donut slices. This is the default indicator.
|
|
31
|
+
*
|
|
32
|
+
* @category primary
|
|
33
|
+
*/
|
|
34
|
+
indicator?: "fill";
|
|
35
|
+
}
|
|
36
|
+
interface LegendItemSolidLineProps extends LegendItemBaseProps {
|
|
37
|
+
/**
|
|
38
|
+
* Solid line for a series whose individual data points are part of the reading, such as a
|
|
39
|
+
* cumulative series. Defaults to a hollow circle marker.
|
|
40
|
+
*
|
|
41
|
+
* @category primary
|
|
42
|
+
*/
|
|
43
|
+
indicator: "solid line";
|
|
44
|
+
/**
|
|
45
|
+
* Marker on a solid line. Defaults to a hollow circle. Pass `none` only when the reader should
|
|
46
|
+
* follow the trend rather than each sample. Do not use a solid line with `symbol="none"` for
|
|
47
|
+
* averages, targets, or comparisons — those use `indicator="dashed line"`.
|
|
48
|
+
*
|
|
49
|
+
* @category primary
|
|
50
|
+
*/
|
|
51
|
+
symbol?: LegendItemSymbol;
|
|
52
|
+
}
|
|
53
|
+
interface LegendItemDashedLineProps extends LegendItemBaseProps {
|
|
54
|
+
/**
|
|
55
|
+
* Dashed line for a reference or secondary series (average, target, comparison). Dashed lines
|
|
56
|
+
* never have a symbol.
|
|
57
|
+
*
|
|
58
|
+
* @category primary
|
|
59
|
+
*/
|
|
60
|
+
indicator: "dashed line";
|
|
61
|
+
}
|
|
62
|
+
export type LegendItemProps = LegendItemFillProps | LegendItemSolidLineProps | LegendItemDashedLineProps;
|
|
17
63
|
/**
|
|
18
|
-
* The LegendItem component is
|
|
64
|
+
* The LegendItem component is the standard chart legend row: a swatch, a label, and an optional count.
|
|
65
|
+
*
|
|
66
|
+
* ### When to use
|
|
67
|
+
* - Fill for field/sector bars and donut slices
|
|
68
|
+
* - Solid line with a hollow circle when individual data points are part of the reading
|
|
69
|
+
* - Dashed line with no symbol for averages, targets, and comparisons
|
|
19
70
|
*
|
|
20
71
|
* @param {LegendItem} props - The props for the LegendItem component
|
|
21
72
|
* @returns {ReactElement} LegendItem component
|
|
22
73
|
*/
|
|
23
|
-
export declare const LegendItem: ({ className, style, count, label, disabled, selected, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit, hideValue, }: LegendItemProps) =>
|
|
74
|
+
export declare const LegendItem: ({ className, style, count, label, disabled, selected, onClick, color, "data-testid": dataTestId, onMouseEnter, onMouseLeave, unit, hideValue, ...indicatorProps }: LegendItemProps) => ReactElement;
|
|
75
|
+
export {};
|
|
@@ -3,6 +3,6 @@ export declare const cvaLegendItem: (props?: ({
|
|
|
3
3
|
disabled?: boolean | null | undefined;
|
|
4
4
|
isClickable?: boolean | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
-
export declare const cvaLegendItemIndicator: (props?: (
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export declare const cvaLegendItemIndicator: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
7
|
+
export declare const cvaLegendItemLineSwatch: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
8
|
+
export declare const cvaLegendItemLineSvg: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|