@tensor_1/react 2.11.0 → 2.13.0
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 +26 -1
- package/dist/ChartCore-Bt1C84ty.d.cts +22 -0
- package/dist/calendar-model.d.ts +31 -0
- package/dist/calendar-model.js +89 -0
- package/dist/chart-preset.cjs +168 -0
- package/dist/chart-preset.d.cts +9 -0
- package/dist/chart-preset.d.ts +9 -0
- package/dist/chart-preset.js +35 -0
- package/dist/chart.cjs +58 -32
- package/dist/chart.d.cts +6 -21
- package/dist/chart.d.ts +2 -1
- package/dist/color-model.d.ts +20 -0
- package/dist/color-model.js +74 -0
- package/dist/components/BrandProfiles.d.ts +45 -0
- package/dist/components/BrandProfiles.js +150 -0
- package/dist/components/BuilderCanvas.d.ts +34 -0
- package/dist/components/BuilderCanvas.js +117 -0
- package/dist/components/Chart.d.ts +6 -21
- package/dist/components/Chart.js +5 -76
- package/dist/components/ChartCore.d.ts +33 -0
- package/dist/components/ChartCore.js +100 -0
- package/dist/components/ColorPicker.d.ts +17 -0
- package/dist/components/ColorPicker.js +158 -0
- package/dist/components/DateRangePicker.d.ts +23 -0
- package/dist/components/DateRangePicker.js +123 -0
- package/dist/components/DiffViewer.d.ts +18 -0
- package/dist/components/DiffViewer.js +93 -0
- package/dist/components/Inbox.js +0 -1
- package/dist/components/LicensePositionBar.d.ts +17 -0
- package/dist/components/LicensePositionBar.js +50 -0
- package/dist/components/MatchReview.d.ts +39 -0
- package/dist/components/MatchReview.js +120 -0
- package/dist/components/Meter.js +0 -1
- package/dist/components/MetricInput.d.ts +23 -0
- package/dist/components/MetricInput.js +92 -0
- package/dist/components/NavFavourites.js +35 -108
- package/dist/components/RelationshipGraph.d.ts +30 -0
- package/dist/components/RelationshipGraph.js +138 -0
- package/dist/components/RuleBuilder.d.ts +45 -0
- package/dist/components/RuleBuilder.js +163 -0
- package/dist/components/SchedulingCalendar.d.ts +42 -0
- package/dist/components/SchedulingCalendar.js +124 -0
- package/dist/components/Segmented.js +3 -2
- package/dist/components/Table.d.ts +1 -1
- package/dist/components/Table.js +4 -3
- package/dist/components/Tabs.js +3 -2
- package/dist/diff-model.d.ts +23 -0
- package/dist/diff-model.js +50 -0
- package/dist/hooks/useTable.js +11 -7
- package/dist/hooks/useVirtualRows.d.ts +27 -0
- package/dist/hooks/useVirtualRows.js +50 -0
- package/dist/index.cjs +1930 -194
- package/dist/index.d.cts +464 -2
- package/dist/index.d.ts +19 -0
- package/dist/index.js +93 -1
- package/dist/json-value.d.ts +10 -0
- package/dist/json-value.js +19 -0
- package/dist/metric-model.d.ts +9 -0
- package/dist/metric-model.js +25 -0
- package/dist/relationship-graph-model.d.ts +31 -0
- package/dist/relationship-graph-model.js +68 -0
- package/dist/rule-builder-model.d.ts +41 -0
- package/dist/rule-builder-model.js +101 -0
- package/dist/table-engine.js +8 -6
- package/package.json +16 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Thin React wrappers over the UIx v2 CSS component library — every component is
|
|
|
7
7
|
```sh
|
|
8
8
|
npm i @tensor_1/react @tensor_1/tokens
|
|
9
9
|
```
|
|
10
|
-
Peer deps: `react` / `react-dom` (`^18` or `^19`).
|
|
10
|
+
Peer deps: `react` / `react-dom` (`^18` or `^19`). Install `echarts` only when using a chart entry.
|
|
11
11
|
|
|
12
12
|
## Use
|
|
13
13
|
|
|
@@ -31,4 +31,29 @@ Charts (ECharts) live behind a separate entry so they stay out of the main bundl
|
|
|
31
31
|
import { Chart } from "@tensor_1/react/chart";
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
For common line, bar, and pie charts, the tree-shaken preset avoids shipping the complete ECharts build:
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { Chart } from "@tensor_1/react/chart/preset";
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Large fixed-height tables can use `useVirtualRows(rows, { rowHeight })`; attach its `containerRef` to
|
|
41
|
+
`TableWrap` and render the returned row window between spacer rows.
|
|
42
|
+
|
|
43
|
+
## UIX-V3 capability components
|
|
44
|
+
|
|
45
|
+
Phase 46.9 adds eleven controlled, domain-neutral components:
|
|
46
|
+
|
|
47
|
+
- Authoring: `RuleBuilder` and `BuilderCanvas`.
|
|
48
|
+
- Time: `SchedulingCalendar` and `DateRangePicker`.
|
|
49
|
+
- Relationships and review: `RelationshipGraph` and `MatchReview`.
|
|
50
|
+
- Configuration: `MetricInput`, `LicensePositionBar`, `BrandProfiles` (also
|
|
51
|
+
`BrandProfileEditor`), `DiffViewer`, and `ColorPicker`.
|
|
52
|
+
|
|
53
|
+
Their serializable helpers are exported from the main entry as well: immutable
|
|
54
|
+
rule-tree operations, calendar/time-zone helpers, bounded graph layout and
|
|
55
|
+
traversal, three-way JSON diffing, metric parsing/stepping, color conversion and
|
|
56
|
+
contrast checks, plus brand-profile apply/restore helpers. No graph or date
|
|
57
|
+
runtime dependency is required.
|
|
58
|
+
|
|
34
59
|
Ships **ESM + CJS + types**, with per-file `"use client"` so it's safe under React Server Components. Part of the **[UIx v2 styleguide](https://github.com/COx-ORG-H/UIx)**.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { EChartsOption, ECharts } from 'echarts';
|
|
3
|
+
|
|
4
|
+
declare function uixChartPalette(): string[];
|
|
5
|
+
interface ChartTableRow {
|
|
6
|
+
[key: string]: string | number;
|
|
7
|
+
}
|
|
8
|
+
interface ChartProps {
|
|
9
|
+
option: EChartsOption;
|
|
10
|
+
title?: string;
|
|
11
|
+
subtitle?: string;
|
|
12
|
+
height?: string | number;
|
|
13
|
+
className?: string;
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
tableData?: ChartTableRow[];
|
|
17
|
+
tableHeaders?: string[];
|
|
18
|
+
onReady?: (chart: ECharts) => void;
|
|
19
|
+
header?: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { type ChartProps as C, type ChartTableRow as a, uixChartPalette as u };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface CalendarDay {
|
|
2
|
+
date: string;
|
|
3
|
+
day: number;
|
|
4
|
+
inMonth: boolean;
|
|
5
|
+
weekday: number;
|
|
6
|
+
}
|
|
7
|
+
interface DateRangeValue {
|
|
8
|
+
start?: string;
|
|
9
|
+
end?: string;
|
|
10
|
+
}
|
|
11
|
+
interface ZonedDateSpan {
|
|
12
|
+
start: string;
|
|
13
|
+
end: string;
|
|
14
|
+
}
|
|
15
|
+
declare function toDateKey(date: Date): string;
|
|
16
|
+
declare function addCalendarDays(value: string, amount: number): string;
|
|
17
|
+
declare function addCalendarMonths(value: string, amount: number): string;
|
|
18
|
+
declare function startOfMonth(value: string): string;
|
|
19
|
+
declare function buildMonthGrid(month: string, weekStartsOn?: 0 | 1): CalendarDay[];
|
|
20
|
+
declare function zonedDateKey(instant: string | Date, timeZone: string): string;
|
|
21
|
+
declare function zonedDateSpan(start: string, end: string, timeZone: string): ZonedDateSpan;
|
|
22
|
+
declare function enumerateDateSpan(span: ZonedDateSpan, limit?: number): string[];
|
|
23
|
+
declare function selectRangeDate(current: DateRangeValue, date: string): DateRangeValue;
|
|
24
|
+
declare function isDateInRange(date: string, value: DateRangeValue): boolean;
|
|
25
|
+
declare function isDateUnavailable(date: string, options: {
|
|
26
|
+
min?: string;
|
|
27
|
+
max?: string;
|
|
28
|
+
isDisabled?: (date: string) => boolean;
|
|
29
|
+
}): boolean;
|
|
30
|
+
|
|
31
|
+
export { type CalendarDay, type DateRangeValue, type ZonedDateSpan, addCalendarDays, addCalendarMonths, buildMonthGrid, enumerateDateSpan, isDateInRange, isDateUnavailable, selectRangeDate, startOfMonth, toDateKey, zonedDateKey, zonedDateSpan };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
function fromDateKey(value) {
|
|
2
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
3
|
+
if (!match) throw new TypeError(`Invalid ISO date: ${value}`);
|
|
4
|
+
return new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
|
|
5
|
+
}
|
|
6
|
+
function toDateKey(date) {
|
|
7
|
+
return `${date.getUTCFullYear().toString().padStart(4, "0")}-${(date.getUTCMonth() + 1).toString().padStart(2, "0")}-${date.getUTCDate().toString().padStart(2, "0")}`;
|
|
8
|
+
}
|
|
9
|
+
function addCalendarDays(value, amount) {
|
|
10
|
+
const date = fromDateKey(value);
|
|
11
|
+
date.setUTCDate(date.getUTCDate() + amount);
|
|
12
|
+
return toDateKey(date);
|
|
13
|
+
}
|
|
14
|
+
function addCalendarMonths(value, amount) {
|
|
15
|
+
const date = fromDateKey(value);
|
|
16
|
+
const day = date.getUTCDate();
|
|
17
|
+
date.setUTCDate(1);
|
|
18
|
+
date.setUTCMonth(date.getUTCMonth() + amount);
|
|
19
|
+
const last = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)).getUTCDate();
|
|
20
|
+
date.setUTCDate(Math.min(day, last));
|
|
21
|
+
return toDateKey(date);
|
|
22
|
+
}
|
|
23
|
+
function startOfMonth(value) {
|
|
24
|
+
return `${value.slice(0, 7)}-01`;
|
|
25
|
+
}
|
|
26
|
+
function buildMonthGrid(month, weekStartsOn = 1) {
|
|
27
|
+
const first = fromDateKey(startOfMonth(month));
|
|
28
|
+
const offset = (first.getUTCDay() - weekStartsOn + 7) % 7;
|
|
29
|
+
const start = addCalendarDays(toDateKey(first), -offset);
|
|
30
|
+
return Array.from({ length: 42 }, (_, index) => {
|
|
31
|
+
const date = addCalendarDays(start, index);
|
|
32
|
+
const parsed = fromDateKey(date);
|
|
33
|
+
return {
|
|
34
|
+
date,
|
|
35
|
+
day: parsed.getUTCDate(),
|
|
36
|
+
inMonth: date.slice(0, 7) === month.slice(0, 7),
|
|
37
|
+
weekday: parsed.getUTCDay()
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function zonedDateKey(instant, timeZone) {
|
|
42
|
+
const date = instant instanceof Date ? instant : new Date(instant);
|
|
43
|
+
if (Number.isNaN(date.getTime())) throw new TypeError(`Invalid instant: ${String(instant)}`);
|
|
44
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
45
|
+
timeZone,
|
|
46
|
+
year: "numeric",
|
|
47
|
+
month: "2-digit",
|
|
48
|
+
day: "2-digit"
|
|
49
|
+
}).formatToParts(date);
|
|
50
|
+
const get = (type) => parts.find((part) => part.type === type)?.value ?? "";
|
|
51
|
+
return `${get("year")}-${get("month")}-${get("day")}`;
|
|
52
|
+
}
|
|
53
|
+
function zonedDateSpan(start, end, timeZone) {
|
|
54
|
+
const startKey = zonedDateKey(start, timeZone);
|
|
55
|
+
const endKey = zonedDateKey(end, timeZone);
|
|
56
|
+
return startKey <= endKey ? { start: startKey, end: endKey } : { start: endKey, end: startKey };
|
|
57
|
+
}
|
|
58
|
+
function enumerateDateSpan(span, limit = 370) {
|
|
59
|
+
const dates = [];
|
|
60
|
+
let current = span.start;
|
|
61
|
+
while (current <= span.end && dates.length < limit) {
|
|
62
|
+
dates.push(current);
|
|
63
|
+
current = addCalendarDays(current, 1);
|
|
64
|
+
}
|
|
65
|
+
return dates;
|
|
66
|
+
}
|
|
67
|
+
function selectRangeDate(current, date) {
|
|
68
|
+
if (!current.start || current.end) return { start: date };
|
|
69
|
+
return date < current.start ? { start: date, end: current.start } : { start: current.start, end: date };
|
|
70
|
+
}
|
|
71
|
+
function isDateInRange(date, value) {
|
|
72
|
+
return !!value.start && !!value.end && date >= value.start && date <= value.end;
|
|
73
|
+
}
|
|
74
|
+
function isDateUnavailable(date, options) {
|
|
75
|
+
return !!options.min && date < options.min || !!options.max && date > options.max || !!options.isDisabled?.(date);
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
addCalendarDays,
|
|
79
|
+
addCalendarMonths,
|
|
80
|
+
buildMonthGrid,
|
|
81
|
+
enumerateDateSpan,
|
|
82
|
+
isDateInRange,
|
|
83
|
+
isDateUnavailable,
|
|
84
|
+
selectRangeDate,
|
|
85
|
+
startOfMonth,
|
|
86
|
+
toDateKey,
|
|
87
|
+
zonedDateKey,
|
|
88
|
+
zonedDateSpan
|
|
89
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/chart-preset.tsx
|
|
32
|
+
var chart_preset_exports = {};
|
|
33
|
+
__export(chart_preset_exports, {
|
|
34
|
+
Chart: () => Chart,
|
|
35
|
+
uixChartPalette: () => uixChartPalette
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(chart_preset_exports);
|
|
38
|
+
var echarts = __toESM(require("echarts/core"), 1);
|
|
39
|
+
var import_charts = require("echarts/charts");
|
|
40
|
+
var import_components = require("echarts/components");
|
|
41
|
+
var import_renderers = require("echarts/renderers");
|
|
42
|
+
|
|
43
|
+
// src/components/ChartCore.tsx
|
|
44
|
+
var import_react = require("react");
|
|
45
|
+
|
|
46
|
+
// src/cx.ts
|
|
47
|
+
function cx(...args) {
|
|
48
|
+
return args.filter(Boolean).join(" ");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/components/ChartCore.tsx
|
|
52
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
|
+
function readToken(name) {
|
|
54
|
+
if (typeof getComputedStyle === "undefined") return "";
|
|
55
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
56
|
+
}
|
|
57
|
+
function uixChartPalette() {
|
|
58
|
+
return [1, 2, 3, 4, 5, 6, 7, 8].map((i) => readToken(`--uix-chart-${i}`));
|
|
59
|
+
}
|
|
60
|
+
function ChartCore({
|
|
61
|
+
engine,
|
|
62
|
+
option,
|
|
63
|
+
title,
|
|
64
|
+
subtitle,
|
|
65
|
+
height = 280,
|
|
66
|
+
className,
|
|
67
|
+
style,
|
|
68
|
+
ariaLabel,
|
|
69
|
+
tableData,
|
|
70
|
+
tableHeaders,
|
|
71
|
+
onReady,
|
|
72
|
+
header
|
|
73
|
+
}) {
|
|
74
|
+
const containerRef = (0, import_react.useRef)(null);
|
|
75
|
+
const chartRef = (0, import_react.useRef)(null);
|
|
76
|
+
const appliedOptionRef = (0, import_react.useRef)(null);
|
|
77
|
+
const latestOptionRef = (0, import_react.useRef)(option);
|
|
78
|
+
const onReadyRef = (0, import_react.useRef)(onReady);
|
|
79
|
+
const tableId = (0, import_react.useId)();
|
|
80
|
+
latestOptionRef.current = option;
|
|
81
|
+
onReadyRef.current = onReady;
|
|
82
|
+
(0, import_react.useEffect)(() => {
|
|
83
|
+
const element = containerRef.current;
|
|
84
|
+
if (!element) return;
|
|
85
|
+
const chart = engine.init(element, null, { renderer: "svg" });
|
|
86
|
+
chartRef.current = chart;
|
|
87
|
+
chart.setOption(latestOptionRef.current);
|
|
88
|
+
appliedOptionRef.current = latestOptionRef.current;
|
|
89
|
+
onReadyRef.current?.(chart);
|
|
90
|
+
let frame = 0;
|
|
91
|
+
let width = element.clientWidth;
|
|
92
|
+
let height2 = element.clientHeight;
|
|
93
|
+
const observer = new ResizeObserver(() => {
|
|
94
|
+
const nextWidth = element.clientWidth;
|
|
95
|
+
const nextHeight = element.clientHeight;
|
|
96
|
+
if (nextWidth === width && nextHeight === height2) return;
|
|
97
|
+
width = nextWidth;
|
|
98
|
+
height2 = nextHeight;
|
|
99
|
+
if (frame) return;
|
|
100
|
+
frame = requestAnimationFrame(() => {
|
|
101
|
+
frame = 0;
|
|
102
|
+
chart.resize();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
observer.observe(element);
|
|
106
|
+
return () => {
|
|
107
|
+
observer.disconnect();
|
|
108
|
+
if (frame) cancelAnimationFrame(frame);
|
|
109
|
+
chart.dispose();
|
|
110
|
+
chartRef.current = null;
|
|
111
|
+
appliedOptionRef.current = null;
|
|
112
|
+
};
|
|
113
|
+
}, [engine]);
|
|
114
|
+
(0, import_react.useEffect)(() => {
|
|
115
|
+
const chart = chartRef.current;
|
|
116
|
+
if (!chart || appliedOptionRef.current === option) return;
|
|
117
|
+
chart.setOption(option, { notMerge: false });
|
|
118
|
+
appliedOptionRef.current = option;
|
|
119
|
+
}, [option]);
|
|
120
|
+
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
121
|
+
const effectiveAriaLabel = ariaLabel ?? title ?? "Chart";
|
|
122
|
+
const hasTable = Boolean(tableData?.length && tableHeaders?.length);
|
|
123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cx("uix-chart", className), style, children: [
|
|
124
|
+
title != null || subtitle != null || header != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
125
|
+
header,
|
|
126
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__title", children: title }) : null,
|
|
127
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__subtitle", children: subtitle }) : null
|
|
128
|
+
] }) : null,
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
ref: containerRef,
|
|
133
|
+
style: { height: heightValue },
|
|
134
|
+
role: "img",
|
|
135
|
+
"aria-label": effectiveAriaLabel,
|
|
136
|
+
"aria-describedby": hasTable ? tableId : void 0
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "sr-only", "aria-label": `${effectiveAriaLabel} \u2014 data table`, children: [
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: label }, label)) }) }),
|
|
141
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: tableData.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: row[label] }, label)) }, index)) })
|
|
142
|
+
] }) : null
|
|
143
|
+
] });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/chart-preset.tsx
|
|
147
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
148
|
+
echarts.use([
|
|
149
|
+
import_charts.BarChart,
|
|
150
|
+
import_charts.LineChart,
|
|
151
|
+
import_charts.PieChart,
|
|
152
|
+
import_components.DatasetComponent,
|
|
153
|
+
import_components.GridComponent,
|
|
154
|
+
import_components.LegendComponent,
|
|
155
|
+
import_components.TitleComponent,
|
|
156
|
+
import_components.TooltipComponent,
|
|
157
|
+
import_components.TransformComponent,
|
|
158
|
+
import_renderers.SVGRenderer
|
|
159
|
+
]);
|
|
160
|
+
var presetEngine = echarts;
|
|
161
|
+
function Chart(props) {
|
|
162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartCore, { ...props, engine: presetEngine });
|
|
163
|
+
}
|
|
164
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
165
|
+
0 && (module.exports = {
|
|
166
|
+
Chart,
|
|
167
|
+
uixChartPalette
|
|
168
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { C as ChartProps } from './ChartCore-Bt1C84ty.cjs';
|
|
3
|
+
export { a as ChartTableRow, u as uixChartPalette } from './ChartCore-Bt1C84ty.cjs';
|
|
4
|
+
import 'echarts';
|
|
5
|
+
|
|
6
|
+
/** Lean SVG adapter: line, bar, pie, dataset, grid, legend, title, and tooltip. */
|
|
7
|
+
declare function Chart(props: ChartProps): react.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { Chart, ChartProps };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ChartProps } from './components/ChartCore.js';
|
|
3
|
+
export { ChartTableRow, uixChartPalette } from './components/ChartCore.js';
|
|
4
|
+
import 'echarts';
|
|
5
|
+
|
|
6
|
+
/** Lean SVG adapter: line, bar, pie, dataset, grid, legend, title, and tooltip. */
|
|
7
|
+
declare function Chart(props: ChartProps): react.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { Chart, ChartProps };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as echarts from "echarts/core";
|
|
4
|
+
import { BarChart, LineChart, PieChart } from "echarts/charts";
|
|
5
|
+
import {
|
|
6
|
+
DatasetComponent,
|
|
7
|
+
GridComponent,
|
|
8
|
+
LegendComponent,
|
|
9
|
+
TitleComponent,
|
|
10
|
+
TooltipComponent,
|
|
11
|
+
TransformComponent
|
|
12
|
+
} from "echarts/components";
|
|
13
|
+
import { SVGRenderer } from "echarts/renderers";
|
|
14
|
+
import { ChartCore } from "./components/ChartCore.js";
|
|
15
|
+
echarts.use([
|
|
16
|
+
BarChart,
|
|
17
|
+
LineChart,
|
|
18
|
+
PieChart,
|
|
19
|
+
DatasetComponent,
|
|
20
|
+
GridComponent,
|
|
21
|
+
LegendComponent,
|
|
22
|
+
TitleComponent,
|
|
23
|
+
TooltipComponent,
|
|
24
|
+
TransformComponent,
|
|
25
|
+
SVGRenderer
|
|
26
|
+
]);
|
|
27
|
+
const presetEngine = echarts;
|
|
28
|
+
function Chart(props) {
|
|
29
|
+
return /* @__PURE__ */ jsx(ChartCore, { ...props, engine: presetEngine });
|
|
30
|
+
}
|
|
31
|
+
import { uixChartPalette } from "./components/ChartCore.js";
|
|
32
|
+
export {
|
|
33
|
+
Chart,
|
|
34
|
+
uixChartPalette
|
|
35
|
+
};
|
package/dist/chart.cjs
CHANGED
|
@@ -36,15 +36,17 @@ __export(chart_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(chart_exports);
|
|
37
37
|
|
|
38
38
|
// src/components/Chart.tsx
|
|
39
|
-
var import_react = require("react");
|
|
40
39
|
var echarts = __toESM(require("echarts"), 1);
|
|
41
40
|
|
|
41
|
+
// src/components/ChartCore.tsx
|
|
42
|
+
var import_react = require("react");
|
|
43
|
+
|
|
42
44
|
// src/cx.ts
|
|
43
45
|
function cx(...args) {
|
|
44
46
|
return args.filter(Boolean).join(" ");
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
// src/components/
|
|
49
|
+
// src/components/ChartCore.tsx
|
|
48
50
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
49
51
|
function readToken(name) {
|
|
50
52
|
if (typeof getComputedStyle === "undefined") return "";
|
|
@@ -53,7 +55,8 @@ function readToken(name) {
|
|
|
53
55
|
function uixChartPalette() {
|
|
54
56
|
return [1, 2, 3, 4, 5, 6, 7, 8].map((i) => readToken(`--uix-chart-${i}`));
|
|
55
57
|
}
|
|
56
|
-
function
|
|
58
|
+
function ChartCore({
|
|
59
|
+
engine,
|
|
57
60
|
option,
|
|
58
61
|
title,
|
|
59
62
|
subtitle,
|
|
@@ -68,58 +71,81 @@ function Chart({
|
|
|
68
71
|
}) {
|
|
69
72
|
const containerRef = (0, import_react.useRef)(null);
|
|
70
73
|
const chartRef = (0, import_react.useRef)(null);
|
|
74
|
+
const appliedOptionRef = (0, import_react.useRef)(null);
|
|
75
|
+
const latestOptionRef = (0, import_react.useRef)(option);
|
|
76
|
+
const onReadyRef = (0, import_react.useRef)(onReady);
|
|
71
77
|
const tableId = (0, import_react.useId)();
|
|
78
|
+
latestOptionRef.current = option;
|
|
79
|
+
onReadyRef.current = onReady;
|
|
72
80
|
(0, import_react.useEffect)(() => {
|
|
73
|
-
const
|
|
74
|
-
if (!
|
|
75
|
-
const chart =
|
|
81
|
+
const element = containerRef.current;
|
|
82
|
+
if (!element) return;
|
|
83
|
+
const chart = engine.init(element, null, { renderer: "svg" });
|
|
76
84
|
chartRef.current = chart;
|
|
77
|
-
chart.setOption(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
chart.setOption(latestOptionRef.current);
|
|
86
|
+
appliedOptionRef.current = latestOptionRef.current;
|
|
87
|
+
onReadyRef.current?.(chart);
|
|
88
|
+
let frame = 0;
|
|
89
|
+
let width = element.clientWidth;
|
|
90
|
+
let height2 = element.clientHeight;
|
|
91
|
+
const observer = new ResizeObserver(() => {
|
|
92
|
+
const nextWidth = element.clientWidth;
|
|
93
|
+
const nextHeight = element.clientHeight;
|
|
94
|
+
if (nextWidth === width && nextHeight === height2) return;
|
|
95
|
+
width = nextWidth;
|
|
96
|
+
height2 = nextHeight;
|
|
97
|
+
if (frame) return;
|
|
98
|
+
frame = requestAnimationFrame(() => {
|
|
99
|
+
frame = 0;
|
|
100
|
+
chart.resize();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
observer.observe(element);
|
|
81
104
|
return () => {
|
|
82
|
-
|
|
105
|
+
observer.disconnect();
|
|
106
|
+
if (frame) cancelAnimationFrame(frame);
|
|
83
107
|
chart.dispose();
|
|
84
108
|
chartRef.current = null;
|
|
109
|
+
appliedOptionRef.current = null;
|
|
85
110
|
};
|
|
86
|
-
}, []);
|
|
111
|
+
}, [engine]);
|
|
87
112
|
(0, import_react.useEffect)(() => {
|
|
88
|
-
chartRef.current
|
|
113
|
+
const chart = chartRef.current;
|
|
114
|
+
if (!chart || appliedOptionRef.current === option) return;
|
|
115
|
+
chart.setOption(option, { notMerge: false });
|
|
116
|
+
appliedOptionRef.current = option;
|
|
89
117
|
}, [option]);
|
|
90
|
-
const
|
|
118
|
+
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
91
119
|
const effectiveAriaLabel = ariaLabel ?? title ?? "Chart";
|
|
92
|
-
const hasTable = tableData
|
|
120
|
+
const hasTable = Boolean(tableData?.length && tableHeaders?.length);
|
|
93
121
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cx("uix-chart", className), style, children: [
|
|
94
|
-
|
|
122
|
+
title != null || subtitle != null || header != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
95
123
|
header,
|
|
96
|
-
title
|
|
97
|
-
subtitle
|
|
98
|
-
] }),
|
|
124
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__title", children: title }) : null,
|
|
125
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__subtitle", children: subtitle }) : null
|
|
126
|
+
] }) : null,
|
|
99
127
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
100
128
|
"div",
|
|
101
129
|
{
|
|
102
130
|
ref: containerRef,
|
|
103
|
-
style: { height:
|
|
131
|
+
style: { height: heightValue },
|
|
104
132
|
role: "img",
|
|
105
133
|
"aria-label": effectiveAriaLabel,
|
|
106
134
|
"aria-describedby": hasTable ? tableId : void 0
|
|
107
135
|
}
|
|
108
136
|
),
|
|
109
|
-
hasTable
|
|
110
|
-
"
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
className: "sr-only",
|
|
114
|
-
"aria-label": `${effectiveAriaLabel} \u2014 data table`,
|
|
115
|
-
children: [
|
|
116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((h) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: h }, h)) }) }),
|
|
117
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: tableData.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((h) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: row[h] }, h)) }, i)) })
|
|
118
|
-
]
|
|
119
|
-
}
|
|
120
|
-
)
|
|
137
|
+
hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "sr-only", "aria-label": `${effectiveAriaLabel} \u2014 data table`, children: [
|
|
138
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: label }, label)) }) }),
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: tableData.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: tableHeaders.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: row[label] }, label)) }, index)) })
|
|
140
|
+
] }) : null
|
|
121
141
|
] });
|
|
122
142
|
}
|
|
143
|
+
|
|
144
|
+
// src/components/Chart.tsx
|
|
145
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
146
|
+
function Chart(props) {
|
|
147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartCore, { ...props, engine: echarts });
|
|
148
|
+
}
|
|
123
149
|
// Annotate the CommonJS export names for ESM import in node:
|
|
124
150
|
0 && (module.exports = {
|
|
125
151
|
Chart,
|
package/dist/chart.d.cts
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { C as ChartProps } from './ChartCore-Bt1C84ty.cjs';
|
|
3
|
+
export { a as ChartTableRow, u as uixChartPalette } from './ChartCore-Bt1C84ty.cjs';
|
|
4
|
+
import 'echarts';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[key: string]: string | number;
|
|
8
|
-
}
|
|
9
|
-
interface ChartProps {
|
|
10
|
-
option: EChartsOption;
|
|
11
|
-
title?: string;
|
|
12
|
-
subtitle?: string;
|
|
13
|
-
height?: string | number;
|
|
14
|
-
className?: string;
|
|
15
|
-
style?: CSSProperties;
|
|
16
|
-
ariaLabel?: string;
|
|
17
|
-
tableData?: ChartTableRow[];
|
|
18
|
-
tableHeaders?: string[];
|
|
19
|
-
onReady?: (chart: ECharts) => void;
|
|
20
|
-
header?: ReactNode;
|
|
21
|
-
}
|
|
22
|
-
declare function Chart({ option, title, subtitle, height, className, style, ariaLabel, tableData, tableHeaders, onReady, header, }: ChartProps): react.JSX.Element;
|
|
6
|
+
/** Full-compatibility adapter. Use `@tensor_1/react/chart/preset` for the lean preset. */
|
|
7
|
+
declare function Chart(props: ChartProps): react.JSX.Element;
|
|
23
8
|
|
|
24
|
-
export { Chart,
|
|
9
|
+
export { Chart, ChartProps };
|
package/dist/chart.d.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface RgbColor {
|
|
2
|
+
r: number;
|
|
3
|
+
g: number;
|
|
4
|
+
b: number;
|
|
5
|
+
}
|
|
6
|
+
interface HsvColor {
|
|
7
|
+
h: number;
|
|
8
|
+
s: number;
|
|
9
|
+
v: number;
|
|
10
|
+
}
|
|
11
|
+
declare function normalizeHex(value: string): string | undefined;
|
|
12
|
+
declare function hexToRgb(value: string): RgbColor | undefined;
|
|
13
|
+
declare function rgbToHex({ r, g, b }: RgbColor): string;
|
|
14
|
+
declare function rgbToHsv({ r, g, b }: RgbColor): HsvColor;
|
|
15
|
+
declare function hsvToRgb({ h, s, v }: HsvColor): RgbColor;
|
|
16
|
+
declare function hsvToHex(value: HsvColor): string;
|
|
17
|
+
declare function contrastRatio(background: string, foreground: string): number | undefined;
|
|
18
|
+
declare function meetsContrast(background: string, foreground: string, minimum?: number): boolean;
|
|
19
|
+
|
|
20
|
+
export { type HsvColor, type RgbColor, contrastRatio, hexToRgb, hsvToHex, hsvToRgb, meetsContrast, normalizeHex, rgbToHex, rgbToHsv };
|