@tensor_1/react 2.31.0 → 2.32.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.
Files changed (114) hide show
  1. package/README.md +350 -0
  2. package/dist/attachment-labels.d.ts +16 -0
  3. package/dist/attachment-labels.js +9 -0
  4. package/dist/calendar-model.d.ts +141 -1
  5. package/dist/calendar-model.js +200 -11
  6. package/dist/chart-preset.cjs +127 -7
  7. package/dist/chart-preset.d.cts +2 -2
  8. package/dist/chart-preset.d.ts +1 -0
  9. package/dist/chart-preset.js +6 -1
  10. package/dist/chart-theme-Cl0IrkKQ.d.cts +112 -0
  11. package/dist/chart-theme.d.ts +51 -0
  12. package/dist/chart-theme.js +99 -0
  13. package/dist/chart.cjs +127 -7
  14. package/dist/chart.d.cts +2 -2
  15. package/dist/chart.d.ts +1 -0
  16. package/dist/chart.js +6 -2
  17. package/dist/components/Alert.d.ts +17 -1
  18. package/dist/components/Alert.js +9 -4
  19. package/dist/components/AlertDismiss.d.ts +14 -0
  20. package/dist/components/AlertDismiss.js +11 -0
  21. package/dist/components/Attachment.d.ts +15 -12
  22. package/dist/components/Attachment.js +17 -17
  23. package/dist/components/AttachmentParts.d.ts +24 -0
  24. package/dist/components/AttachmentParts.js +20 -0
  25. package/dist/components/Chart.d.ts +1 -0
  26. package/dist/components/Chart.js +6 -1
  27. package/dist/components/ChartCore.d.ts +6 -1
  28. package/dist/components/ChartCore.js +23 -5
  29. package/dist/components/Chip.d.ts +17 -2
  30. package/dist/components/Chip.js +35 -11
  31. package/dist/components/ChipRemove.d.ts +17 -0
  32. package/dist/components/ChipRemove.js +13 -0
  33. package/dist/components/CollapsibleParts.d.ts +29 -0
  34. package/dist/components/CollapsibleParts.js +20 -0
  35. package/dist/components/CollapsibleSection.d.ts +30 -3
  36. package/dist/components/CollapsibleSection.js +7 -11
  37. package/dist/components/CollapsibleSectionState.d.ts +1 -1
  38. package/dist/components/CollapsibleSectionState.js +54 -27
  39. package/dist/components/DashboardGrid.d.ts +60 -0
  40. package/dist/components/DashboardGrid.js +40 -0
  41. package/dist/components/DateRangePicker.d.ts +7 -1
  42. package/dist/components/DateRangePicker.js +5 -1
  43. package/dist/components/DescriptionList.d.ts +12 -1
  44. package/dist/components/DescriptionList.js +5 -5
  45. package/dist/components/Dialogs.d.ts +24 -3
  46. package/dist/components/Dialogs.js +74 -16
  47. package/dist/components/FileUpload.d.ts +10 -2
  48. package/dist/components/FileUpload.js +10 -4
  49. package/dist/components/FilterEditor.d.ts +4 -0
  50. package/dist/components/FilterEditor.js +13 -2
  51. package/dist/components/Heartbeat.d.ts +31 -0
  52. package/dist/components/Heartbeat.js +28 -0
  53. package/dist/components/Menu.d.ts +53 -5
  54. package/dist/components/Menu.js +104 -4
  55. package/dist/components/Meter.d.ts +7 -3
  56. package/dist/components/Meter.js +2 -1
  57. package/dist/components/Popover.d.ts +21 -2
  58. package/dist/components/Popover.js +94 -17
  59. package/dist/components/Prose.d.ts +6 -2
  60. package/dist/components/Prose.js +1 -1
  61. package/dist/components/RuleBuilder.d.ts +52 -4
  62. package/dist/components/RuleBuilder.js +109 -24
  63. package/dist/components/SchedulingCalendar.d.ts +142 -11
  64. package/dist/components/SchedulingCalendar.js +234 -57
  65. package/dist/components/SchedulingTimeline.d.ts +1 -0
  66. package/dist/components/Segmented.d.ts +17 -3
  67. package/dist/components/Segmented.js +59 -5
  68. package/dist/components/Select.d.ts +66 -2
  69. package/dist/components/Select.js +800 -10
  70. package/dist/components/Spinner.d.ts +2 -1
  71. package/dist/components/Spinner.js +1 -1
  72. package/dist/components/StatusPill.d.ts +8 -2
  73. package/dist/components/StatusPill.js +2 -2
  74. package/dist/components/Steps.d.ts +28 -4
  75. package/dist/components/Steps.js +46 -16
  76. package/dist/components/TableControls.js +4 -3
  77. package/dist/components/Tabs.d.ts +7 -2
  78. package/dist/components/Tabs.js +14 -1
  79. package/dist/components/TextDiff.d.ts +49 -0
  80. package/dist/components/TextDiff.js +124 -0
  81. package/dist/{emoji-image-6mPZ15Zy.d.cts → emoji-image-DjCKpdwE.d.cts} +1 -1
  82. package/dist/emoji.cjs +169 -27
  83. package/dist/emoji.d.cts +3 -3
  84. package/dist/file-model.d.ts +22 -3
  85. package/dist/file-model.js +6 -4
  86. package/dist/filter-model.d.ts +26 -2
  87. package/dist/filter-model.js +13 -1
  88. package/dist/hooks/useAnchoredPosition.d.ts +24 -1
  89. package/dist/hooks/useAnchoredPosition.js +58 -8
  90. package/dist/hooks/useVirtualRows.d.ts +17 -2
  91. package/dist/hooks/useVirtualRows.js +6 -5
  92. package/dist/icons/Icon.d.ts +14 -14
  93. package/dist/index.cjs +4179 -1678
  94. package/dist/index.d.cts +1706 -660
  95. package/dist/index.d.ts +16 -9
  96. package/dist/index.js +53 -4
  97. package/dist/labels-context.d.ts +28 -0
  98. package/dist/{overlay-position-Cjv5E7mn.d.cts → overlay-position-2Afke51l.d.cts} +20 -0
  99. package/dist/overlay-position.d.ts +20 -0
  100. package/dist/overlay-position.js +17 -2
  101. package/dist/rich-text.cjs +169 -27
  102. package/dist/rich-text.d.cts +3 -3
  103. package/dist/rule-builder-model.d.ts +34 -2
  104. package/dist/rule-builder-model.js +48 -12
  105. package/dist/scheduling-calendar-model.d.ts +66 -0
  106. package/dist/scheduling-calendar-model.js +82 -0
  107. package/dist/select-model.d.ts +80 -0
  108. package/dist/select-model.js +109 -0
  109. package/dist/table-engine.d.ts +7 -0
  110. package/dist/table-engine.js +2 -1
  111. package/dist/text-diff-model.d.ts +71 -0
  112. package/dist/text-diff-model.js +261 -0
  113. package/package.json +1 -1
  114. package/dist/ChartCore-DzWe10bN.d.cts +0 -59
@@ -0,0 +1,99 @@
1
+ function reader(source) {
2
+ if (typeof source === "function") return source;
3
+ if (typeof getComputedStyle === "undefined" || typeof document === "undefined") return () => "";
4
+ const style = getComputedStyle(source ?? document.documentElement);
5
+ return (token) => style.getPropertyValue(token).trim();
6
+ }
7
+ function uixChartTokens(source) {
8
+ const read = reader(source);
9
+ const t = (name) => read(`--uix-${name}`);
10
+ const unquote = (font) => font.replace(/"/g, "");
11
+ return {
12
+ palette: [1, 2, 3, 4, 5, 6, 7, 8].map((i) => t(`chart-${i}`)),
13
+ neutral: t("chart-neutral"),
14
+ grid: t("chart-grid"),
15
+ axis: t("chart-axis"),
16
+ reference: t("chart-reference"),
17
+ zoneWarning: t("chart-zone-warning"),
18
+ zoneDanger: t("chart-zone-danger"),
19
+ forecastBand: t("chart-forecast-band"),
20
+ event: t("chart-event"),
21
+ partial: t("chart-partial"),
22
+ comparison: t("chart-comparison"),
23
+ surface: t("surface"),
24
+ text: t("text"),
25
+ textMuted: t("text-muted"),
26
+ border: t("border-strong"),
27
+ fontSans: unquote(t("font-sans")),
28
+ fontMono: unquote(t("font-mono"))
29
+ };
30
+ }
31
+ function uixChartTheme(source) {
32
+ const k = uixChartTokens(source);
33
+ const read = reader(source);
34
+ const axis = {
35
+ axisLine: { lineStyle: { color: k.axis } },
36
+ axisTick: { show: false },
37
+ axisLabel: { color: k.textMuted, fontFamily: k.fontMono, fontSize: 11 },
38
+ splitLine: { lineStyle: { color: k.grid, type: "solid", width: 1 } }
39
+ };
40
+ return {
41
+ color: k.palette,
42
+ backgroundColor: "transparent",
43
+ textStyle: { color: k.textMuted, fontFamily: k.fontSans, fontSize: 12 },
44
+ title: { textStyle: { color: k.text, fontFamily: k.fontSans }, subtextStyle: { color: k.textMuted, fontFamily: k.fontSans } },
45
+ legend: { textStyle: { color: k.textMuted, fontFamily: k.fontSans, fontSize: 12 }, icon: "roundRect", itemWidth: 10, itemHeight: 6, itemGap: 12 },
46
+ tooltip: {
47
+ backgroundColor: k.surface,
48
+ borderColor: k.border,
49
+ borderWidth: 1,
50
+ padding: [8, 10],
51
+ textStyle: { color: k.text, fontFamily: k.fontSans, fontSize: 12 },
52
+ extraCssText: `border-radius:${read("--uix-radius-sm")};box-shadow:${read("--uix-shadow-popover")}`,
53
+ axisPointer: { lineStyle: { color: k.reference, width: 1 }, crossStyle: { color: k.reference }, shadowStyle: { color: k.forecastBand } }
54
+ },
55
+ xAxis: axis,
56
+ yAxis: axis
57
+ };
58
+ }
59
+ function uixChartAreaGradient(color) {
60
+ const alpha = (opacity) => {
61
+ const hex = color.replace("#", "");
62
+ if (!/^[0-9a-f]{6}$/i.test(hex)) return color;
63
+ const [r, g, b] = hex.match(/.{2}/g).map((channel) => Number.parseInt(channel, 16));
64
+ return `rgba(${r},${g},${b},${opacity})`;
65
+ };
66
+ return {
67
+ type: "linear",
68
+ x: 0,
69
+ y: 0,
70
+ x2: 0,
71
+ y2: 1,
72
+ colorStops: [{ offset: 0, color: alpha(0.28) }, { offset: 0.72, color: alpha(0.06) }, { offset: 1, color: alpha(0) }]
73
+ };
74
+ }
75
+ const isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
76
+ function deepMerge(base, over) {
77
+ if (over === void 0) return base;
78
+ if (!isPlainObject(base) || !isPlainObject(over)) return over;
79
+ const out = { ...base };
80
+ for (const key of Object.keys(over)) out[key] = deepMerge(base[key], over[key]);
81
+ return out;
82
+ }
83
+ const STYLED_ONLY = ["xAxis", "yAxis", "legend", "title"];
84
+ function mergeChartTheme(theme, option) {
85
+ const merged = deepMerge(theme, option);
86
+ const source = option;
87
+ const base = theme;
88
+ for (const key of STYLED_ONLY) {
89
+ if (Array.isArray(source[key])) merged[key] = source[key].map((axis) => deepMerge(base[key], axis));
90
+ else if (!(key in source)) delete merged[key];
91
+ }
92
+ return merged;
93
+ }
94
+ export {
95
+ mergeChartTheme,
96
+ uixChartAreaGradient,
97
+ uixChartTheme,
98
+ uixChartTokens
99
+ };
package/dist/chart.cjs CHANGED
@@ -35,7 +35,11 @@ __export(chart_exports, {
35
35
  ChartLegendItem: () => ChartLegendItem,
36
36
  ChartMetric: () => ChartMetric,
37
37
  DEFAULT_CHART_LABELS: () => DEFAULT_CHART_LABELS,
38
- uixChartPalette: () => uixChartPalette
38
+ mergeChartTheme: () => mergeChartTheme,
39
+ uixChartAreaGradient: () => uixChartAreaGradient,
40
+ uixChartPalette: () => uixChartPalette,
41
+ uixChartTheme: () => uixChartTheme,
42
+ uixChartTokens: () => uixChartTokens
39
43
  });
40
44
  module.exports = __toCommonJS(chart_exports);
41
45
 
@@ -50,6 +54,101 @@ function cx(...args) {
50
54
  return args.filter(Boolean).join(" ");
51
55
  }
52
56
 
57
+ // src/chart-theme.ts
58
+ function reader(source) {
59
+ if (typeof source === "function") return source;
60
+ if (typeof getComputedStyle === "undefined" || typeof document === "undefined") return () => "";
61
+ const style = getComputedStyle(source ?? document.documentElement);
62
+ return (token) => style.getPropertyValue(token).trim();
63
+ }
64
+ function uixChartTokens(source) {
65
+ const read = reader(source);
66
+ const t = (name) => read(`--uix-${name}`);
67
+ const unquote = (font) => font.replace(/"/g, "");
68
+ return {
69
+ palette: [1, 2, 3, 4, 5, 6, 7, 8].map((i) => t(`chart-${i}`)),
70
+ neutral: t("chart-neutral"),
71
+ grid: t("chart-grid"),
72
+ axis: t("chart-axis"),
73
+ reference: t("chart-reference"),
74
+ zoneWarning: t("chart-zone-warning"),
75
+ zoneDanger: t("chart-zone-danger"),
76
+ forecastBand: t("chart-forecast-band"),
77
+ event: t("chart-event"),
78
+ partial: t("chart-partial"),
79
+ comparison: t("chart-comparison"),
80
+ surface: t("surface"),
81
+ text: t("text"),
82
+ textMuted: t("text-muted"),
83
+ border: t("border-strong"),
84
+ fontSans: unquote(t("font-sans")),
85
+ fontMono: unquote(t("font-mono"))
86
+ };
87
+ }
88
+ function uixChartTheme(source) {
89
+ const k = uixChartTokens(source);
90
+ const read = reader(source);
91
+ const axis = {
92
+ axisLine: { lineStyle: { color: k.axis } },
93
+ axisTick: { show: false },
94
+ axisLabel: { color: k.textMuted, fontFamily: k.fontMono, fontSize: 11 },
95
+ splitLine: { lineStyle: { color: k.grid, type: "solid", width: 1 } }
96
+ };
97
+ return {
98
+ color: k.palette,
99
+ backgroundColor: "transparent",
100
+ textStyle: { color: k.textMuted, fontFamily: k.fontSans, fontSize: 12 },
101
+ title: { textStyle: { color: k.text, fontFamily: k.fontSans }, subtextStyle: { color: k.textMuted, fontFamily: k.fontSans } },
102
+ legend: { textStyle: { color: k.textMuted, fontFamily: k.fontSans, fontSize: 12 }, icon: "roundRect", itemWidth: 10, itemHeight: 6, itemGap: 12 },
103
+ tooltip: {
104
+ backgroundColor: k.surface,
105
+ borderColor: k.border,
106
+ borderWidth: 1,
107
+ padding: [8, 10],
108
+ textStyle: { color: k.text, fontFamily: k.fontSans, fontSize: 12 },
109
+ extraCssText: `border-radius:${read("--uix-radius-sm")};box-shadow:${read("--uix-shadow-popover")}`,
110
+ axisPointer: { lineStyle: { color: k.reference, width: 1 }, crossStyle: { color: k.reference }, shadowStyle: { color: k.forecastBand } }
111
+ },
112
+ xAxis: axis,
113
+ yAxis: axis
114
+ };
115
+ }
116
+ function uixChartAreaGradient(color) {
117
+ const alpha = (opacity) => {
118
+ const hex = color.replace("#", "");
119
+ if (!/^[0-9a-f]{6}$/i.test(hex)) return color;
120
+ const [r, g, b] = hex.match(/.{2}/g).map((channel) => Number.parseInt(channel, 16));
121
+ return `rgba(${r},${g},${b},${opacity})`;
122
+ };
123
+ return {
124
+ type: "linear",
125
+ x: 0,
126
+ y: 0,
127
+ x2: 0,
128
+ y2: 1,
129
+ colorStops: [{ offset: 0, color: alpha(0.28) }, { offset: 0.72, color: alpha(0.06) }, { offset: 1, color: alpha(0) }]
130
+ };
131
+ }
132
+ var isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
133
+ function deepMerge(base, over) {
134
+ if (over === void 0) return base;
135
+ if (!isPlainObject(base) || !isPlainObject(over)) return over;
136
+ const out = { ...base };
137
+ for (const key of Object.keys(over)) out[key] = deepMerge(base[key], over[key]);
138
+ return out;
139
+ }
140
+ var STYLED_ONLY = ["xAxis", "yAxis", "legend", "title"];
141
+ function mergeChartTheme(theme, option) {
142
+ const merged = deepMerge(theme, option);
143
+ const source = option;
144
+ const base = theme;
145
+ for (const key of STYLED_ONLY) {
146
+ if (Array.isArray(source[key])) merged[key] = source[key].map((axis) => deepMerge(base[key], axis));
147
+ else if (!(key in source)) delete merged[key];
148
+ }
149
+ return merged;
150
+ }
151
+
53
152
  // src/components/ChartCore.tsx
54
153
  var import_jsx_runtime = require("react/jsx-runtime");
55
154
  function readToken(name) {
@@ -59,6 +158,9 @@ function readToken(name) {
59
158
  function uixChartPalette() {
60
159
  return [1, 2, 3, 4, 5, 6, 7, 8].map((i) => readToken(`--uix-chart-${i}`));
61
160
  }
161
+ function themed(option, theme, element) {
162
+ return theme === "none" ? option : mergeChartTheme(uixChartTheme(element), option);
163
+ }
62
164
  function motionSafe(option) {
63
165
  if (typeof matchMedia !== "undefined" && matchMedia("(prefers-reduced-motion: reduce)").matches) {
64
166
  return { ...option, animation: false };
@@ -87,7 +189,8 @@ function ChartCore({
87
189
  footer,
88
190
  loading = false,
89
191
  empty,
90
- labels: labelOverrides
192
+ labels: labelOverrides,
193
+ theme = "uix"
91
194
  }) {
92
195
  const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
93
196
  const containerRef = (0, import_react.useRef)(null);
@@ -99,7 +202,9 @@ function ChartCore({
99
202
  const hasEmpty = empty != null;
100
203
  const hasTextAlternative = Boolean(ariaLabel || title || tableData?.length);
101
204
  const hasTextAlternativeRef = (0, import_react.useRef)(hasTextAlternative);
205
+ const themeRef = (0, import_react.useRef)(theme);
102
206
  latestOptionRef.current = option;
207
+ themeRef.current = theme;
103
208
  onReadyRef.current = onReady;
104
209
  hasTextAlternativeRef.current = hasTextAlternative;
105
210
  (0, import_react.useEffect)(() => {
@@ -107,9 +212,17 @@ function ChartCore({
107
212
  if (!element) return;
108
213
  const chart = engine.init(element, null, { renderer: "svg" });
109
214
  chartRef.current = chart;
110
- chart.setOption(motionSafe(latestOptionRef.current));
215
+ chart.setOption(motionSafe(themed(latestOptionRef.current, themeRef.current, element)));
111
216
  appliedOptionRef.current = latestOptionRef.current;
112
217
  onReadyRef.current?.(chart);
218
+ const retheme = () => {
219
+ if (themeRef.current === "none") return;
220
+ chart.setOption(motionSafe(themed(latestOptionRef.current, themeRef.current, element)));
221
+ };
222
+ const themeObserver = typeof MutationObserver === "undefined" ? null : new MutationObserver(retheme);
223
+ themeObserver?.observe(document.documentElement, { attributes: true, attributeFilter: ["class", "data-theme"] });
224
+ const scheme = typeof matchMedia === "undefined" ? null : matchMedia("(prefers-color-scheme: dark)");
225
+ scheme?.addEventListener?.("change", retheme);
113
226
  if (!hasTextAlternativeRef.current) {
114
227
  console.warn("[uix] Chart has no text alternative \u2014 provide ariaLabel, title, or tableData.");
115
228
  }
@@ -131,6 +244,8 @@ function ChartCore({
131
244
  observer.observe(element);
132
245
  return () => {
133
246
  observer.disconnect();
247
+ themeObserver?.disconnect();
248
+ scheme?.removeEventListener?.("change", retheme);
134
249
  if (frame) cancelAnimationFrame(frame);
135
250
  chart.dispose();
136
251
  chartRef.current = null;
@@ -139,10 +254,11 @@ function ChartCore({
139
254
  }, [engine, hasEmpty]);
140
255
  (0, import_react.useEffect)(() => {
141
256
  const chart = chartRef.current;
142
- if (!chart || appliedOptionRef.current === option) return;
143
- chart.setOption(motionSafe(option), { notMerge: false });
257
+ const element = containerRef.current;
258
+ if (!chart || !element || appliedOptionRef.current === option) return;
259
+ chart.setOption(motionSafe(themed(option, theme, element)), { notMerge: false });
144
260
  appliedOptionRef.current = option;
145
- }, [option]);
261
+ }, [option, theme]);
146
262
  const heightValue = typeof height === "number" ? `${height}px` : height;
147
263
  const effectiveAriaLabel = ariaLabel ?? title ?? labels.chart;
148
264
  const hasTable = Boolean(tableData?.length && tableHeaders?.length);
@@ -205,5 +321,9 @@ function Chart(props) {
205
321
  ChartLegendItem,
206
322
  ChartMetric,
207
323
  DEFAULT_CHART_LABELS,
208
- uixChartPalette
324
+ mergeChartTheme,
325
+ uixChartAreaGradient,
326
+ uixChartPalette,
327
+ uixChartTheme,
328
+ uixChartTokens
209
329
  });
package/dist/chart.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { C as ChartProps } from './ChartCore-DzWe10bN.cjs';
3
- export { a as ChartLabels, b as ChartLegend, c as ChartLegendItem, d as ChartLegendItemProps, e as ChartLegendProps, f as ChartMetric, g as ChartMetricProps, h as ChartTableRow, D as DEFAULT_CHART_LABELS, u as uixChartPalette } from './ChartCore-DzWe10bN.cjs';
2
+ import { C as ChartProps } from './chart-theme-Cl0IrkKQ.cjs';
3
+ export { a as ChartLabels, b as ChartLegend, c as ChartLegendItem, d as ChartLegendItemProps, e as ChartLegendProps, f as ChartMetric, g as ChartMetricProps, h as ChartTableRow, i as ChartTokenSource, D as DEFAULT_CHART_LABELS, U as UixChartTokens, m as mergeChartTheme, u as uixChartAreaGradient, j as uixChartPalette, k as uixChartTheme, l as uixChartTokens } from './chart-theme-Cl0IrkKQ.cjs';
4
4
  import 'echarts';
5
5
 
6
6
  /** Full-compatibility adapter. Use `@tensor_1/react/chart/preset` for the lean preset. */
package/dist/chart.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Chart } from './components/Chart.js';
2
2
  export { ChartLabels, ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartProps, ChartTableRow, DEFAULT_CHART_LABELS, uixChartPalette } from './components/ChartCore.js';
3
+ export { ChartTokenSource, UixChartTokens, mergeChartTheme, uixChartAreaGradient, uixChartTheme, uixChartTokens } from './chart-theme.js';
3
4
  import 'react';
4
5
  import 'echarts';
package/dist/chart.js CHANGED
@@ -1,9 +1,13 @@
1
- import { Chart, ChartLegend, ChartLegendItem, ChartMetric, DEFAULT_CHART_LABELS, uixChartPalette } from "./components/Chart.js";
1
+ import { Chart, ChartLegend, ChartLegendItem, ChartMetric, DEFAULT_CHART_LABELS, mergeChartTheme, uixChartAreaGradient, uixChartPalette, uixChartTheme, uixChartTokens } from "./components/Chart.js";
2
2
  export {
3
3
  Chart,
4
4
  ChartLegend,
5
5
  ChartLegendItem,
6
6
  ChartMetric,
7
7
  DEFAULT_CHART_LABELS,
8
- uixChartPalette
8
+ mergeChartTheme,
9
+ uixChartAreaGradient,
10
+ uixChartPalette,
11
+ uixChartTheme,
12
+ uixChartTokens
9
13
  };
@@ -7,7 +7,23 @@ interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
7
7
  title?: ReactNode;
8
8
  icon?: ReactNode;
9
9
  children?: ReactNode;
10
+ /**
11
+ * A trailing slot for what the alert offers to do: a `Button`, a link (HAR-1614). It keeps
12
+ * its place at the end while the text beside it wraps.
13
+ */
14
+ actions?: ReactNode;
15
+ /**
16
+ * Adds a × at the end. The alert does not hide itself: stop rendering it in the handler, and
17
+ * move focus somewhere sensible if the alert held it.
18
+ */
19
+ onDismiss?: () => void;
20
+ /** Accessible name of the ×. Default: `UixLabelsProvider` `alert.dismiss`, then "Dismiss". */
21
+ dismissLabel?: string;
10
22
  }
11
- declare function Alert({ tone, title, icon, children, className, ...props }: AlertProps): react.JSX.Element;
23
+ /**
24
+ * Inline banner over `.uix-alert`. The ref is the alert element, so a form can move focus to
25
+ * its error message (give it `tabIndex={-1}`).
26
+ */
27
+ declare const Alert: react.ForwardRefExoticComponent<AlertProps & react.RefAttributes<HTMLDivElement>>;
12
28
 
13
29
  export { Alert, type AlertProps, type AlertTone };
@@ -1,22 +1,27 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
2
3
  import { cx } from "../cx.js";
3
- function Alert({ tone, title, icon, children, className, ...props }) {
4
+ import { AlertDismissButton } from "./AlertDismiss.js";
5
+ const Alert = forwardRef(function Alert2({ tone, title, icon, children, actions, onDismiss, dismissLabel, className, ...props }, ref) {
4
6
  return /* @__PURE__ */ jsxs(
5
7
  "div",
6
8
  {
9
+ ref,
7
10
  className: cx("uix-alert", tone && tone !== "neutral" && `uix-alert--${tone}`, className),
8
11
  role: tone === "danger" || tone === "warning" ? "alert" : "status",
9
12
  ...props,
10
13
  children: [
11
14
  icon && /* @__PURE__ */ jsx("div", { className: "uix-alert__icon", children: icon }),
12
- /* @__PURE__ */ jsxs("div", { children: [
15
+ /* @__PURE__ */ jsxs("div", { className: "uix-alert__content", children: [
13
16
  title && /* @__PURE__ */ jsx("div", { className: "uix-alert__title", children: title }),
14
17
  children && /* @__PURE__ */ jsx("div", { className: "uix-alert__body", children })
15
- ] })
18
+ ] }),
19
+ actions != null && /* @__PURE__ */ jsx("div", { className: "uix-alert__actions", children: actions }),
20
+ onDismiss && /* @__PURE__ */ jsx(AlertDismissButton, { label: dismissLabel, onDismiss })
16
21
  ]
17
22
  }
18
23
  );
19
- }
24
+ });
20
25
  export {
21
26
  Alert
22
27
  };
@@ -0,0 +1,14 @@
1
+ import * as react from 'react';
2
+
3
+ interface AlertDismissButtonProps {
4
+ /** The alert's `dismissLabel`, when one was passed. */
5
+ label?: string;
6
+ onDismiss: () => void;
7
+ }
8
+ /**
9
+ * The × of a dismissible `Alert`. Internal. Its own client component so its name can come from
10
+ * `UixLabelsProvider` (`alert.dismiss`) while `Alert` itself stays server-renderable (HAR-1614).
11
+ */
12
+ declare function AlertDismissButton({ label, onDismiss }: AlertDismissButtonProps): react.JSX.Element;
13
+
14
+ export { AlertDismissButton };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { XIcon } from "../icons/components.js";
4
+ import { useUixLabels } from "../labels-context.js";
5
+ function AlertDismissButton({ label, onDismiss }) {
6
+ const provided = useUixLabels().alert?.dismiss;
7
+ return /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--xs uix-btn--icon uix-alert__dismiss", "aria-label": label ?? provided ?? "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ jsx(XIcon, { size: "sm" }) });
8
+ }
9
+ export {
10
+ AlertDismissButton
11
+ };
@@ -1,16 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { LiHTMLAttributes, ReactNode, HTMLAttributes } from 'react';
3
+ import { FileSizeFormatter } from '../file-model.js';
3
4
  import { UixRenderLink } from '../link.js';
5
+ import { AttachmentLabels } from '../attachment-labels.js';
6
+ export { DEFAULT_ATTACHMENT_LABELS } from '../attachment-labels.js';
4
7
 
5
- interface AttachmentLabels {
6
- /** Remove button. `{name}`. */
7
- remove: string;
8
- /** Download link name when `download` is set. `{name}`. */
9
- download: string;
10
- loading: string;
11
- forbidden: string;
12
- }
13
- declare const DEFAULT_ATTACHMENT_LABELS: AttachmentLabels;
14
8
  interface AttachmentProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'children'> {
15
9
  /** File name as the user should read it (decrypted, if the product stores it encrypted). */
16
10
  name: string;
@@ -37,13 +31,22 @@ interface AttachmentProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'childre
37
31
  /** Extra actions at the end of the row. */
38
32
  actions?: ReactNode;
39
33
  locale?: string;
34
+ /** Count sizes in 1024s (1 MB = 1,048,576 bytes) instead of 1000s. Default `1000`. */
35
+ sizeBase?: 1000 | 1024;
36
+ /** The product's own size formatter; it replaces `formatFileSize` (and `sizeBase`). */
37
+ formatSize?: FileSizeFormatter;
38
+ /**
39
+ * Words for this row. Each one defaults to `UixLabelsProvider` `attachment`, then to English,
40
+ * so one provider translates every row below it (HAR-1630).
41
+ */
40
42
  labels?: Partial<AttachmentLabels>;
41
43
  }
42
44
  /**
43
45
  * One file row (HAR-985; TENSOR C15/B12 `attachments-panel-view.tsx`, MEDx S19/S52): glyph or
44
- * thumbnail, the name as a link, size and meta, a state slot, and remove. Server-renderable.
46
+ * thumbnail, the name as a link, size and meta, a state slot, and remove. Server-renderable:
47
+ * the words that come from `UixLabelsProvider` are rendered by small client parts.
45
48
  */
46
- declare function Attachment({ name, size, type, href, download, renderLink, meta, state, thumbnail, onRemove, status, error, actions, locale, labels: labelOverrides, className, ...props }: AttachmentProps): react.JSX.Element;
49
+ declare function Attachment({ name, size, type, href, download, renderLink, meta, state, thumbnail, onRemove, status, error, actions, locale, sizeBase, formatSize, labels, className, ...props }: AttachmentProps): react.JSX.Element;
47
50
  interface AttachmentListProps extends HTMLAttributes<HTMLUListElement> {
48
51
  /** Names the list, e.g. "Attachments (3)". */
49
52
  label?: string;
@@ -52,4 +55,4 @@ interface AttachmentListProps extends HTMLAttributes<HTMLUListElement> {
52
55
  /** A list of `Attachment` rows. */
53
56
  declare function AttachmentList({ label, className, children, ...props }: AttachmentListProps): react.JSX.Element;
54
57
 
55
- export { Attachment, type AttachmentLabels, AttachmentList, type AttachmentListProps, type AttachmentProps, DEFAULT_ATTACHMENT_LABELS };
58
+ export { Attachment, AttachmentLabels, AttachmentList, type AttachmentListProps, type AttachmentProps };
@@ -1,16 +1,10 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cx } from "../cx.js";
3
- import { fillLabel } from "../fill-label.js";
4
3
  import { formatFileSize } from "../file-model.js";
5
4
  import { renderUixLink } from "../link.js";
6
- import { Button } from "./Button.js";
5
+ import { DEFAULT_ATTACHMENT_LABELS } from "../attachment-labels.js";
6
+ import { AttachmentRemoveButton, AttachmentText } from "./AttachmentParts.js";
7
7
  import { FileIcon } from "./FileIcon.js";
8
- const DEFAULT_ATTACHMENT_LABELS = {
9
- remove: "Remove {name}",
10
- download: "Download {name}",
11
- loading: "Loading\u2026",
12
- forbidden: "You do not have access to this file."
13
- };
14
8
  function Attachment({
15
9
  name,
16
10
  size,
@@ -26,17 +20,23 @@ function Attachment({
26
20
  error,
27
21
  actions,
28
22
  locale,
29
- labels: labelOverrides,
23
+ sizeBase,
24
+ formatSize,
25
+ labels,
30
26
  className,
31
27
  ...props
32
28
  }) {
33
- const labels = { ...DEFAULT_ATTACHMENT_LABELS, ...labelOverrides };
34
29
  const linked = href != null && status !== "loading" && status !== "forbidden";
35
30
  const nameNode = linked ? renderUixLink(renderLink, {
36
31
  href,
37
32
  className: "uix-attachment__name",
38
- children: name,
39
- ...download ? { download: typeof download === "string" ? download : "", "aria-label": fillLabel(labels.download, { name }) } : {}
33
+ // A download link is named "Download {name}": the visible name, plus the translated
34
+ // sentence for assistive technology in place of it.
35
+ children: download ? /* @__PURE__ */ jsxs(Fragment, { children: [
36
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: name }),
37
+ /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: /* @__PURE__ */ jsx(AttachmentText, { label: "download", override: labels?.download, name }) })
38
+ ] }) : name,
39
+ ...download ? { download: typeof download === "string" ? download : "" } : {}
40
40
  }) : /* @__PURE__ */ jsx("span", { className: "uix-attachment__name", children: name });
41
41
  return /* @__PURE__ */ jsxs("li", { className: cx("uix-attachment", className), "data-status": status === "ready" ? void 0 : status, "aria-busy": status === "loading" || void 0, ...props, children: [
42
42
  /* @__PURE__ */ jsx("span", { className: "uix-attachment__icon", "aria-hidden": "true", children: thumbnail ?? /* @__PURE__ */ jsx(FileIcon, { name, type }) }),
@@ -46,16 +46,16 @@ function Attachment({
46
46
  state != null && /* @__PURE__ */ jsx("span", { className: "uix-attachment__state", children: state })
47
47
  ] }),
48
48
  /* @__PURE__ */ jsxs("span", { className: "uix-attachment__meta", children: [
49
- size !== void 0 && /* @__PURE__ */ jsx("span", { className: "uix-attachment__size", children: formatFileSize(size, locale) }),
49
+ size !== void 0 && /* @__PURE__ */ jsx("span", { className: "uix-attachment__size", children: formatSize ? formatSize(size, locale) : formatFileSize(size, locale, { base: sizeBase }) }),
50
50
  meta != null && /* @__PURE__ */ jsx("span", { children: meta }),
51
- status === "loading" && /* @__PURE__ */ jsx("span", { children: labels.loading }),
52
- status === "forbidden" && /* @__PURE__ */ jsx("span", { children: labels.forbidden })
51
+ status === "loading" && /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(AttachmentText, { label: "loading", override: labels?.loading, name }) }),
52
+ status === "forbidden" && /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(AttachmentText, { label: "forbidden", override: labels?.forbidden, name }) })
53
53
  ] }),
54
54
  status === "error" && error != null && /* @__PURE__ */ jsx("span", { className: "uix-attachment__error", role: "alert", children: error })
55
55
  ] }),
56
56
  (actions != null || onRemove) && /* @__PURE__ */ jsxs("span", { className: "uix-attachment__actions", children: [
57
57
  actions,
58
- onRemove && /* @__PURE__ */ jsx(Button, { type: "button", size: "xs", variant: "ghost", icon: true, "aria-label": fillLabel(labels.remove, { name }), onClick: onRemove, children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14" }) }) })
58
+ onRemove && /* @__PURE__ */ jsx(AttachmentRemoveButton, { override: labels?.remove, name, onRemove })
59
59
  ] })
60
60
  ] });
61
61
  }
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { AttachmentLabels } from '../attachment-labels.js';
3
+
4
+ interface AttachmentTextProps {
5
+ label: keyof AttachmentLabels;
6
+ /** The row's own `labels[label]`, when it was passed. */
7
+ override?: string;
8
+ name: string;
9
+ }
10
+ /**
11
+ * One translated string of an `Attachment` row. Internal. `Attachment` is server-renderable
12
+ * and so cannot read `UixLabelsProvider` itself; these small client parts do it for it
13
+ * (HAR-1630).
14
+ */
15
+ declare function AttachmentText({ label, override, name }: AttachmentTextProps): react.JSX.Element;
16
+ interface AttachmentRemoveButtonProps {
17
+ override?: string;
18
+ name: string;
19
+ onRemove: () => void;
20
+ }
21
+ /** The remove button of an `Attachment` row. Internal. */
22
+ declare function AttachmentRemoveButton({ override, name, onRemove }: AttachmentRemoveButtonProps): react.JSX.Element;
23
+
24
+ export { AttachmentRemoveButton, AttachmentText };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { Fragment, jsx } from "react/jsx-runtime";
3
+ import { fillLabel } from "../fill-label.js";
4
+ import { useUixLabels } from "../labels-context.js";
5
+ import { DEFAULT_ATTACHMENT_LABELS } from "../attachment-labels.js";
6
+ import { Button } from "./Button.js";
7
+ function useAttachmentLabel(key, override) {
8
+ const provided = useUixLabels().attachment?.[key];
9
+ return override ?? provided ?? DEFAULT_ATTACHMENT_LABELS[key];
10
+ }
11
+ function AttachmentText({ label, override, name }) {
12
+ return /* @__PURE__ */ jsx(Fragment, { children: fillLabel(useAttachmentLabel(label, override), { name }) });
13
+ }
14
+ function AttachmentRemoveButton({ override, name, onRemove }) {
15
+ return /* @__PURE__ */ jsx(Button, { type: "button", size: "xs", variant: "ghost", icon: true, "aria-label": fillLabel(useAttachmentLabel("remove", override), { name }), onClick: onRemove, children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14" }) }) });
16
+ }
17
+ export {
18
+ AttachmentRemoveButton,
19
+ AttachmentText
20
+ };
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ChartProps } from './ChartCore.js';
3
3
  export { ChartLabels, ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartTableRow, DEFAULT_CHART_LABELS, uixChartPalette } from './ChartCore.js';
4
+ export { ChartTokenSource, UixChartTokens, mergeChartTheme, uixChartAreaGradient, uixChartTheme, uixChartTokens } from '../chart-theme.js';
4
5
  import 'echarts';
5
6
 
6
7
  /** Full-compatibility adapter. Use `@tensor_1/react/chart/preset` for the lean preset. */
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
3
3
  import * as echarts from "echarts";
4
4
  import { ChartCore } from "./ChartCore.js";
5
5
  import { ChartLegend, ChartLegendItem, ChartMetric, DEFAULT_CHART_LABELS, uixChartPalette } from "./ChartCore.js";
6
+ import { mergeChartTheme, uixChartAreaGradient, uixChartTheme, uixChartTokens } from "../chart-theme.js";
6
7
  function Chart(props) {
7
8
  return /* @__PURE__ */ jsx(ChartCore, { ...props, engine: echarts });
8
9
  }
@@ -12,5 +13,9 @@ export {
12
13
  ChartLegendItem,
13
14
  ChartMetric,
14
15
  DEFAULT_CHART_LABELS,
15
- uixChartPalette
16
+ mergeChartTheme,
17
+ uixChartAreaGradient,
18
+ uixChartPalette,
19
+ uixChartTheme,
20
+ uixChartTokens
16
21
  };
@@ -42,12 +42,17 @@ interface ChartProps {
42
42
  empty?: ReactNode;
43
43
  /** Translatable words; English defaults in {@link DEFAULT_CHART_LABELS}. */
44
44
  labels?: Partial<ChartLabels>;
45
+ /**
46
+ * `'uix'` (default) merges {@link uixChartTheme} under `option` — token palette, fonts, a solid hairline
47
+ * grid and the UIx tooltip — and re-applies it when the page theme changes. `'none'` renders `option` as is.
48
+ */
49
+ theme?: 'uix' | 'none';
45
50
  }
46
51
  interface ChartCoreProps extends ChartProps {
47
52
  engine: ChartEngine;
48
53
  }
49
54
  /** Shared chart lifecycle. Runtime adapters only choose the ECharts build. */
50
- declare function ChartCore({ engine, option, title, subtitle, height, className, style, ariaLabel, tableData, tableHeaders, onReady, header, headerAction, footer, loading, empty, labels: labelOverrides, }: ChartCoreProps): react.JSX.Element;
55
+ declare function ChartCore({ engine, option, title, subtitle, height, className, style, ariaLabel, tableData, tableHeaders, onReady, header, headerAction, footer, loading, empty, labels: labelOverrides, theme, }: ChartCoreProps): react.JSX.Element;
51
56
  interface ChartMetricProps extends HTMLAttributes<HTMLDivElement> {
52
57
  value: ReactNode;
53
58
  label?: ReactNode;