@tensor_1/react 2.19.2 → 2.21.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 (70) hide show
  1. package/README.md +14 -0
  2. package/dist/{ChartCore-Do6gRBN3.d.cts → ChartCore-DzWe10bN.d.cts} +16 -1
  3. package/dist/chart-preset.cjs +25 -13
  4. package/dist/chart-preset.d.cts +2 -2
  5. package/dist/chart-preset.d.ts +1 -1
  6. package/dist/chart-preset.js +2 -1
  7. package/dist/chart.cjs +25 -13
  8. package/dist/chart.d.cts +2 -2
  9. package/dist/chart.d.ts +1 -1
  10. package/dist/chart.js +2 -1
  11. package/dist/components/AppShell.d.ts +5 -1
  12. package/dist/components/AppShell.js +4 -2
  13. package/dist/components/Avatar.d.ts +3 -1
  14. package/dist/components/Avatar.js +2 -2
  15. package/dist/components/BrandProfiles.d.ts +29 -2
  16. package/dist/components/BrandProfiles.js +45 -20
  17. package/dist/components/BuilderCanvas.d.ts +27 -2
  18. package/dist/components/BuilderCanvas.js +45 -22
  19. package/dist/components/Chart.d.ts +1 -1
  20. package/dist/components/Chart.js +2 -1
  21. package/dist/components/ChartCore.d.ts +17 -2
  22. package/dist/components/ChartCore.js +24 -13
  23. package/dist/components/ColorPicker.d.ts +24 -2
  24. package/dist/components/ColorPicker.js +38 -20
  25. package/dist/components/CommandPalette.d.ts +3 -1
  26. package/dist/components/CommandPalette.js +2 -2
  27. package/dist/components/CopyButton.d.ts +25 -0
  28. package/dist/components/CopyButton.js +52 -0
  29. package/dist/components/DateRangePicker.d.ts +21 -2
  30. package/dist/components/DateRangePicker.js +26 -6
  31. package/dist/components/DetailPage.d.ts +22 -3
  32. package/dist/components/DetailPage.js +33 -3
  33. package/dist/components/DiffViewer.d.ts +34 -3
  34. package/dist/components/DiffViewer.js +60 -40
  35. package/dist/components/Drawer.d.ts +3 -1
  36. package/dist/components/Drawer.js +2 -2
  37. package/dist/components/Inbox.d.ts +3 -1
  38. package/dist/components/Inbox.js +2 -2
  39. package/dist/components/MatchReview.d.ts +49 -2
  40. package/dist/components/MatchReview.js +72 -30
  41. package/dist/components/Meter.d.ts +3 -1
  42. package/dist/components/Meter.js +3 -2
  43. package/dist/components/Pagination.d.ts +10 -2
  44. package/dist/components/Pagination.js +11 -4
  45. package/dist/components/Peek.d.ts +7 -1
  46. package/dist/components/Peek.js +4 -4
  47. package/dist/components/RelationshipGraph.js +6 -2
  48. package/dist/components/RuleBuilder.d.ts +42 -2
  49. package/dist/components/RuleBuilder.js +71 -37
  50. package/dist/components/SchedulingCalendar.d.ts +25 -2
  51. package/dist/components/SchedulingCalendar.js +38 -15
  52. package/dist/components/Stat.d.ts +24 -3
  53. package/dist/components/Stat.js +51 -10
  54. package/dist/components/Table.d.ts +11 -3
  55. package/dist/components/Table.js +5 -8
  56. package/dist/components/Tabs.d.ts +14 -1
  57. package/dist/components/Tabs.js +88 -19
  58. package/dist/components/Toast.d.ts +6 -2
  59. package/dist/components/Toast.js +4 -4
  60. package/dist/components/Tree.d.ts +9 -1
  61. package/dist/components/Tree.js +55 -8
  62. package/dist/copy-model.d.ts +12 -0
  63. package/dist/copy-model.js +12 -0
  64. package/dist/fill-label.d.ts +7 -0
  65. package/dist/fill-label.js +9 -0
  66. package/dist/index.cjs +1480 -1004
  67. package/dist/index.d.cts +387 -30
  68. package/dist/index.d.ts +11 -10
  69. package/dist/index.js +20 -9
  70. package/package.json +1 -1
package/README.md CHANGED
@@ -191,4 +191,18 @@ Radial mode still shortens long labels to fit its ring, but every node carries i
191
191
  <TabPanel value="history" keepMounted>{history}</TabPanel>
192
192
  ```
193
193
 
194
+ ### Scrolling tabs, toned stat tiles and copying
195
+
196
+ - **`Tabs overflow="scroll"`** keeps a long tab row on one line that scrolls sideways. The selected tab is always scrolled into view, and edge buttons appear only on the side that has hidden tabs. The buttons are pointer-only: keyboard users move with Arrow, Home and End. Combine it with `TabPanel keepMounted` on a record page with many sections.
197
+ - **`Stat tone`** (`warning`, `danger`) draws a toned outline and value; the label stays muted, so the tone never replaces words. `size="compact"` fits dense fact bands.
198
+ - **`Stat onActivate`** makes the whole tile a button that opens an editor (`aria-haspopup="dialog"`). Pass `activateLabel` (e.g. "change") so the name reads "Priority: P1, change", and `expanded` while the editor is open. The ref points at the button, for anchoring a popover.
199
+ - **`CopyButton`** copies `value`. Name it for what it copies (`label="Copy email"`), pass `copiedLabel`, and pass `failedLabel` so a refused copy is explained rather than silent.
200
+
201
+ ```tsx
202
+ <Tabs value={tab} onChange={setTab} overflow="scroll">{tabs}</Tabs>
203
+ <Stat label={t('sla')} value={remaining} tone={breached ? 'danger' : 'neutral'} size="compact" />
204
+ <Stat ref={anchor} label={t('priority')} value="P1" onActivate={openEditor} activateLabel={t('change')} expanded={open} size="compact" />
205
+ <CopyButton value={email} label={t('copyEmail')} copiedLabel={t('copied')} failedLabel={t('copyFailed')} />
206
+ ```
207
+
194
208
  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)**.
@@ -6,6 +6,19 @@ declare function uixChartPalette(): string[];
6
6
  interface ChartTableRow {
7
7
  [key: string]: string | number;
8
8
  }
9
+ /**
10
+ * Every word the chart renders itself (TENSOR RX-125, UIX-04 / UIX-05). The
11
+ * loading text used to live in CSS `content:`, where nothing could translate it.
12
+ */
13
+ interface ChartLabels {
14
+ /** Shown (and announced inside the busy region) while `loading`. */
15
+ loading: ReactNode;
16
+ /** Accessible name when neither `ariaLabel` nor `title` is given. */
17
+ chart: string;
18
+ /** Appended to the chart's name for its data-table alternative. */
19
+ dataTableSuffix: string;
20
+ }
21
+ declare const DEFAULT_CHART_LABELS: ChartLabels;
9
22
  interface ChartProps {
10
23
  option: EChartsOption;
11
24
  title?: string;
@@ -22,6 +35,8 @@ interface ChartProps {
22
35
  footer?: ReactNode;
23
36
  loading?: boolean;
24
37
  empty?: ReactNode;
38
+ /** Translatable words; English defaults in {@link DEFAULT_CHART_LABELS}. */
39
+ labels?: Partial<ChartLabels>;
25
40
  }
26
41
  interface ChartMetricProps extends HTMLAttributes<HTMLDivElement> {
27
42
  value: ReactNode;
@@ -41,4 +56,4 @@ interface ChartLegendItemProps extends HTMLAttributes<HTMLLIElement> {
41
56
  }
42
57
  declare function ChartLegendItem({ label, color, swatch, className, style, ...props }: ChartLegendItemProps): react.JSX.Element;
43
58
 
44
- export { type ChartProps as C, ChartLegend as a, ChartLegendItem as b, type ChartLegendItemProps as c, type ChartLegendProps as d, ChartMetric as e, type ChartMetricProps as f, type ChartTableRow as g, uixChartPalette as u };
59
+ export { type ChartProps as C, DEFAULT_CHART_LABELS as D, type ChartLabels as a, ChartLegend as b, ChartLegendItem as c, type ChartLegendItemProps as d, type ChartLegendProps as e, ChartMetric as f, type ChartMetricProps as g, type ChartTableRow as h, uixChartPalette as u };
@@ -35,6 +35,7 @@ __export(chart_preset_exports, {
35
35
  ChartLegend: () => ChartLegend,
36
36
  ChartLegendItem: () => ChartLegendItem,
37
37
  ChartMetric: () => ChartMetric,
38
+ DEFAULT_CHART_LABELS: () => DEFAULT_CHART_LABELS,
38
39
  uixChartPalette: () => uixChartPalette
39
40
  });
40
41
  module.exports = __toCommonJS(chart_preset_exports);
@@ -66,6 +67,11 @@ function motionSafe(option) {
66
67
  }
67
68
  return option;
68
69
  }
70
+ var DEFAULT_CHART_LABELS = {
71
+ loading: "Loading chart\u2026",
72
+ chart: "Chart",
73
+ dataTableSuffix: "data table"
74
+ };
69
75
  function ChartCore({
70
76
  engine,
71
77
  option,
@@ -82,8 +88,10 @@ function ChartCore({
82
88
  headerAction,
83
89
  footer,
84
90
  loading = false,
85
- empty
91
+ empty,
92
+ labels: labelOverrides
86
93
  }) {
94
+ const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
87
95
  const containerRef = (0, import_react.useRef)(null);
88
96
  const chartRef = (0, import_react.useRef)(null);
89
97
  const appliedOptionRef = (0, import_react.useRef)(null);
@@ -138,7 +146,7 @@ function ChartCore({
138
146
  appliedOptionRef.current = option;
139
147
  }, [option]);
140
148
  const heightValue = typeof height === "number" ? `${height}px` : height;
141
- const effectiveAriaLabel = ariaLabel ?? title ?? "Chart";
149
+ const effectiveAriaLabel = ariaLabel ?? title ?? labels.chart;
142
150
  const hasTable = Boolean(tableData?.length && tableHeaders?.length);
143
151
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cx("uix-chart", className), style, children: [
144
152
  title != null || subtitle != null || header != null || headerAction != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "uix-chart__header", children: [
@@ -149,17 +157,20 @@ function ChartCore({
149
157
  ] }),
150
158
  headerAction
151
159
  ] }) : null,
152
- hasEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-empty": true, children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-loading": loading || void 0, "aria-busy": loading || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
153
- "div",
154
- {
155
- ref: containerRef,
156
- style: { height: heightValue },
157
- role: "img",
158
- "aria-label": effectiveAriaLabel,
159
- "aria-describedby": hasTable ? tableId : void 0
160
- }
161
- ) }),
162
- hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "uix-visually-hidden", "aria-label": `${effectiveAriaLabel} \u2014 data table`, children: [
160
+ hasEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-empty": true, children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "uix-chart__plot", "data-loading": loading || void 0, "aria-busy": loading || void 0, children: [
161
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "uix-chart__loading", children: labels.loading }) : null,
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
163
+ "div",
164
+ {
165
+ ref: containerRef,
166
+ style: { height: heightValue },
167
+ role: "img",
168
+ "aria-label": effectiveAriaLabel,
169
+ "aria-describedby": hasTable ? tableId : void 0
170
+ }
171
+ )
172
+ ] }),
173
+ hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "uix-visually-hidden", "aria-label": `${effectiveAriaLabel} \u2014 ${labels.dataTableSuffix}`, children: [
163
174
  /* @__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)) }) }),
164
175
  /* @__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)) })
165
176
  ] }) : null,
@@ -208,5 +219,6 @@ function Chart(props) {
208
219
  ChartLegend,
209
220
  ChartLegendItem,
210
221
  ChartMetric,
222
+ DEFAULT_CHART_LABELS,
211
223
  uixChartPalette
212
224
  });
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { C as ChartProps } from './ChartCore-Do6gRBN3.cjs';
3
- export { a as ChartLegend, b as ChartLegendItem, c as ChartLegendItemProps, d as ChartLegendProps, e as ChartMetric, f as ChartMetricProps, g as ChartTableRow, u as uixChartPalette } from './ChartCore-Do6gRBN3.cjs';
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';
4
4
  import 'echarts';
5
5
 
6
6
  /** Lean SVG adapter: line, bar, pie, dataset, grid, legend, title, and tooltip. */
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ChartProps } from './components/ChartCore.js';
3
- export { ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartTableRow, uixChartPalette } from './components/ChartCore.js';
3
+ export { ChartLabels, ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartTableRow, DEFAULT_CHART_LABELS, uixChartPalette } from './components/ChartCore.js';
4
4
  import 'echarts';
5
5
 
6
6
  /** Lean SVG adapter: line, bar, pie, dataset, grid, legend, title, and tooltip. */
@@ -28,11 +28,12 @@ const presetEngine = echarts;
28
28
  function Chart(props) {
29
29
  return /* @__PURE__ */ jsx(ChartCore, { ...props, engine: presetEngine });
30
30
  }
31
- import { ChartLegend, ChartLegendItem, ChartMetric, uixChartPalette } from "./components/ChartCore.js";
31
+ import { ChartLegend, ChartLegendItem, ChartMetric, DEFAULT_CHART_LABELS, uixChartPalette } from "./components/ChartCore.js";
32
32
  export {
33
33
  Chart,
34
34
  ChartLegend,
35
35
  ChartLegendItem,
36
36
  ChartMetric,
37
+ DEFAULT_CHART_LABELS,
37
38
  uixChartPalette
38
39
  };
package/dist/chart.cjs CHANGED
@@ -34,6 +34,7 @@ __export(chart_exports, {
34
34
  ChartLegend: () => ChartLegend,
35
35
  ChartLegendItem: () => ChartLegendItem,
36
36
  ChartMetric: () => ChartMetric,
37
+ DEFAULT_CHART_LABELS: () => DEFAULT_CHART_LABELS,
37
38
  uixChartPalette: () => uixChartPalette
38
39
  });
39
40
  module.exports = __toCommonJS(chart_exports);
@@ -64,6 +65,11 @@ function motionSafe(option) {
64
65
  }
65
66
  return option;
66
67
  }
68
+ var DEFAULT_CHART_LABELS = {
69
+ loading: "Loading chart\u2026",
70
+ chart: "Chart",
71
+ dataTableSuffix: "data table"
72
+ };
67
73
  function ChartCore({
68
74
  engine,
69
75
  option,
@@ -80,8 +86,10 @@ function ChartCore({
80
86
  headerAction,
81
87
  footer,
82
88
  loading = false,
83
- empty
89
+ empty,
90
+ labels: labelOverrides
84
91
  }) {
92
+ const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
85
93
  const containerRef = (0, import_react.useRef)(null);
86
94
  const chartRef = (0, import_react.useRef)(null);
87
95
  const appliedOptionRef = (0, import_react.useRef)(null);
@@ -136,7 +144,7 @@ function ChartCore({
136
144
  appliedOptionRef.current = option;
137
145
  }, [option]);
138
146
  const heightValue = typeof height === "number" ? `${height}px` : height;
139
- const effectiveAriaLabel = ariaLabel ?? title ?? "Chart";
147
+ const effectiveAriaLabel = ariaLabel ?? title ?? labels.chart;
140
148
  const hasTable = Boolean(tableData?.length && tableHeaders?.length);
141
149
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cx("uix-chart", className), style, children: [
142
150
  title != null || subtitle != null || header != null || headerAction != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "uix-chart__header", children: [
@@ -147,17 +155,20 @@ function ChartCore({
147
155
  ] }),
148
156
  headerAction
149
157
  ] }) : null,
150
- hasEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-empty": true, children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-loading": loading || void 0, "aria-busy": loading || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
151
- "div",
152
- {
153
- ref: containerRef,
154
- style: { height: heightValue },
155
- role: "img",
156
- "aria-label": effectiveAriaLabel,
157
- "aria-describedby": hasTable ? tableId : void 0
158
- }
159
- ) }),
160
- hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "uix-visually-hidden", "aria-label": `${effectiveAriaLabel} \u2014 data table`, children: [
158
+ hasEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "uix-chart__plot", "data-empty": true, children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "uix-chart__plot", "data-loading": loading || void 0, "aria-busy": loading || void 0, children: [
159
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "uix-chart__loading", children: labels.loading }) : null,
160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
+ "div",
162
+ {
163
+ ref: containerRef,
164
+ style: { height: heightValue },
165
+ role: "img",
166
+ "aria-label": effectiveAriaLabel,
167
+ "aria-describedby": hasTable ? tableId : void 0
168
+ }
169
+ )
170
+ ] }),
171
+ hasTable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { id: tableId, className: "uix-visually-hidden", "aria-label": `${effectiveAriaLabel} \u2014 ${labels.dataTableSuffix}`, children: [
161
172
  /* @__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)) }) }),
162
173
  /* @__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)) })
163
174
  ] }) : null,
@@ -193,5 +204,6 @@ function Chart(props) {
193
204
  ChartLegend,
194
205
  ChartLegendItem,
195
206
  ChartMetric,
207
+ DEFAULT_CHART_LABELS,
196
208
  uixChartPalette
197
209
  });
package/dist/chart.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { C as ChartProps } from './ChartCore-Do6gRBN3.cjs';
3
- export { a as ChartLegend, b as ChartLegendItem, c as ChartLegendItemProps, d as ChartLegendProps, e as ChartMetric, f as ChartMetricProps, g as ChartTableRow, u as uixChartPalette } from './ChartCore-Do6gRBN3.cjs';
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';
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,4 @@
1
1
  export { Chart } from './components/Chart.js';
2
- export { ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartProps, ChartTableRow, uixChartPalette } from './components/ChartCore.js';
2
+ export { ChartLabels, ChartLegend, ChartLegendItem, ChartLegendItemProps, ChartLegendProps, ChartMetric, ChartMetricProps, ChartProps, ChartTableRow, DEFAULT_CHART_LABELS, uixChartPalette } from './components/ChartCore.js';
3
3
  import 'react';
4
4
  import 'echarts';
package/dist/chart.js CHANGED
@@ -1,8 +1,9 @@
1
- import { Chart, ChartLegend, ChartLegendItem, ChartMetric, uixChartPalette } from "./components/Chart.js";
1
+ import { Chart, ChartLegend, ChartLegendItem, ChartMetric, DEFAULT_CHART_LABELS, uixChartPalette } from "./components/Chart.js";
2
2
  export {
3
3
  Chart,
4
4
  ChartLegend,
5
5
  ChartLegendItem,
6
6
  ChartMetric,
7
+ DEFAULT_CHART_LABELS,
7
8
  uixChartPalette
8
9
  };
@@ -22,7 +22,11 @@ interface AppShellProps extends HTMLAttributes<HTMLDivElement> {
22
22
  sidebar?: ReactNode;
23
23
  topbar?: ReactNode;
24
24
  children?: ReactNode;
25
+ /** TENSOR RX-125 (UIX-04): translatable; English default. */
26
+ skipToContentLabel?: ReactNode;
27
+ /** TENSOR RX-125 (UIX-04): translatable; English default. */
28
+ exitFocusLabel?: ReactNode;
25
29
  }
26
- declare function AppShell({ nav, collapsed, focus, onExitFocus, mainBleed, mainId, sidebar, topbar, children, className, ...props }: AppShellProps): react.JSX.Element;
30
+ declare function AppShell({ nav, collapsed, focus, onExitFocus, mainBleed, mainId, sidebar, topbar, children, skipToContentLabel, exitFocusLabel, className, ...props }: AppShellProps): react.JSX.Element;
27
31
 
28
32
  export { AppShell, type AppShellProps, type ShellNav };
@@ -12,6 +12,8 @@ function AppShell({
12
12
  sidebar,
13
13
  topbar,
14
14
  children,
15
+ skipToContentLabel = "Skip to content",
16
+ exitFocusLabel = "Esc \xB7 Exit focus",
15
17
  className,
16
18
  ...props
17
19
  }) {
@@ -33,11 +35,11 @@ function AppShell({
33
35
  "data-focus": focus || void 0,
34
36
  ...props,
35
37
  children: [
36
- /* @__PURE__ */ jsx("a", { className: "uix-skiplink", href: `#${mainId}`, children: "Skip to content" }),
38
+ /* @__PURE__ */ jsx("a", { className: "uix-skiplink", href: `#${mainId}`, children: skipToContentLabel }),
37
39
  sidebar && /* @__PURE__ */ jsx("div", { className: "uix-shell__sidebar", children: sidebar }),
38
40
  topbar && /* @__PURE__ */ jsx("div", { className: "uix-shell__topbar", children: topbar }),
39
41
  /* @__PURE__ */ jsx("main", { id: mainId, tabIndex: -1, className: cx("uix-shell__main", mainBleed && "uix-shell__main--bleed"), children }),
40
- focus && onExitFocus && /* @__PURE__ */ jsx("div", { className: "uix-shell__focus-exit", children: /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: onExitFocus, children: "Esc \xB7 Exit focus" }) })
42
+ focus && onExitFocus && /* @__PURE__ */ jsx("div", { className: "uix-shell__focus-exit", children: /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: onExitFocus, children: exitFocusLabel }) })
41
43
  ]
42
44
  }
43
45
  );
@@ -2,6 +2,8 @@ import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
5
+ /** TENSOR RX-125 (UIX-04): translatable; English default. */
6
+ onlineLabel?: string;
5
7
  size?: 'sm' | 'md' | 'lg';
6
8
  src?: string;
7
9
  alt?: string;
@@ -11,7 +13,7 @@ interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
11
13
  status?: boolean;
12
14
  }
13
15
  /** Avatar over `.uix-avatar`. Renders an image when `src` is set, else children (initials). */
14
- declare function Avatar({ size, src, alt, children, status, className, ...props }: AvatarProps): react.JSX.Element;
16
+ declare function Avatar({ size, src, alt, children, status, onlineLabel, className, ...props }: AvatarProps): react.JSX.Element;
15
17
  interface AvatarGroupProps extends HTMLAttributes<HTMLSpanElement> {
16
18
  children?: ReactNode;
17
19
  }
@@ -1,10 +1,10 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cx } from "../cx.js";
3
- function Avatar({ size = "md", src, alt, children, status, className, ...props }) {
3
+ function Avatar({ size = "md", src, alt, children, status, onlineLabel = "online", className, ...props }) {
4
4
  return /* @__PURE__ */ jsxs("span", { className: cx("uix-avatar", size !== "md" && `uix-avatar--${size}`, className), ...props, children: [
5
5
  src ? /* @__PURE__ */ jsx("img", { src, alt: alt ?? "" }) : children,
6
6
  status && /* @__PURE__ */ jsx("span", { className: "uix-avatar__status", "aria-hidden": "true" }),
7
- status && /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: "online" })
7
+ status && /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: onlineLabel })
8
8
  ] });
9
9
  }
10
10
  function AvatarGroup({ children, className, ...props }) {
@@ -26,6 +26,32 @@ interface AppliedBrandProfileSnapshot {
26
26
  /** Apply only the existing UIx brand/font slots and readable logo metadata. */
27
27
  declare function applyBrandProfile(profile: BrandProfile, target?: HTMLElement | null): AppliedBrandProfileSnapshot | undefined;
28
28
  declare function restoreBrandProfile(snapshot: AppliedBrandProfileSnapshot, target?: HTMLElement | null): void;
29
+ /**
30
+ * Every word the brand-profile editor renders (TENSOR RX-125, UIX-12). `{name}` is the
31
+ * profile's name. The preview copy is sample content and may be replaced too.
32
+ */
33
+ interface BrandProfileEditorLabels {
34
+ region: string;
35
+ profile: string;
36
+ name: string;
37
+ brand: string;
38
+ brandColor: string;
39
+ onBrand: string;
40
+ onBrandColor: string;
41
+ bodyFont: string;
42
+ headingFont: string;
43
+ logoFile: string;
44
+ apply: string;
45
+ applied: string;
46
+ preview: string;
47
+ logoPlaceholder: string;
48
+ previewTitleFallback: string;
49
+ previewHeading: string;
50
+ previewBody: string;
51
+ previewPrimary: string;
52
+ previewLink: string;
53
+ }
54
+ declare const DEFAULT_BRAND_PROFILE_EDITOR_LABELS: BrandProfileEditorLabels;
29
55
  interface BrandProfileEditorProps {
30
56
  value: BrandProfile;
31
57
  onChange: (profile: BrandProfile) => void;
@@ -36,10 +62,11 @@ interface BrandProfileEditorProps {
36
62
  onLogoFile?: (file: File) => void;
37
63
  colorPresets?: string[];
38
64
  className?: string;
65
+ labels?: Partial<BrandProfileEditorLabels>;
39
66
  }
40
67
  /** Small controlled editor composition for serializable UIx brand profiles. */
41
- declare function BrandProfileEditor({ value, onChange, profiles, onSelectProfile, onApply, applyTarget, onLogoFile, colorPresets, className, }: BrandProfileEditorProps): react.JSX.Element;
68
+ declare function BrandProfileEditor({ value, onChange, profiles, onSelectProfile, onApply, applyTarget, onLogoFile, colorPresets, className, labels: labelOverrides, }: BrandProfileEditorProps): react.JSX.Element;
42
69
  /** Canonical Phase 46.9 export; equivalent to BrandProfileEditor. */
43
70
  declare const BrandProfiles: typeof BrandProfileEditor;
44
71
 
45
- export { type AppliedBrandProfileSnapshot, type BrandProfile, BrandProfileEditor, type BrandProfileEditorProps, type BrandProfileLogo, type BrandProfileTypography, BrandProfiles, applyBrandProfile, restoreBrandProfile };
72
+ export { type AppliedBrandProfileSnapshot, type BrandProfile, BrandProfileEditor, type BrandProfileEditorLabels, type BrandProfileEditorProps, type BrandProfileLogo, type BrandProfileTypography, BrandProfiles, DEFAULT_BRAND_PROFILE_EDITOR_LABELS, applyBrandProfile, restoreBrandProfile };
@@ -4,6 +4,7 @@ import { useState } from "react";
4
4
  import { cx } from "../cx.js";
5
5
  import { normalizeHex } from "../color-model.js";
6
6
  import { ColorPicker } from "./ColorPicker.js";
7
+ import { fillLabel } from "../fill-label.js";
7
8
  const PROFILE_PROPERTIES = {
8
9
  brand: "--uix-brand",
9
10
  brandForeground: "--uix-brand-fg",
@@ -61,6 +62,27 @@ function restoreBrandProfile(snapshot, target) {
61
62
  if (snapshot.logoAlt) element.dataset.uixBrandLogoAlt = snapshot.logoAlt;
62
63
  else delete element.dataset.uixBrandLogoAlt;
63
64
  }
65
+ const DEFAULT_BRAND_PROFILE_EDITOR_LABELS = {
66
+ region: "Brand profile editor",
67
+ profile: "Profile",
68
+ name: "Name",
69
+ brand: "Brand",
70
+ brandColor: "Brand color",
71
+ onBrand: "On brand",
72
+ onBrandColor: "Brand foreground color",
73
+ bodyFont: "Body font",
74
+ headingFont: "Heading font",
75
+ logoFile: "Logo file",
76
+ apply: "Apply profile",
77
+ applied: "{name} applied.",
78
+ preview: "Live preview of {name}",
79
+ logoPlaceholder: "Logo",
80
+ previewTitleFallback: "Brand preview",
81
+ previewHeading: "Readable, serializable branding",
82
+ previewBody: "Accent, links, rings, and muted states continue through the existing UIx token chain.",
83
+ previewPrimary: "Primary action",
84
+ previewLink: "Preview link"
85
+ };
64
86
  function BrandProfileEditor({
65
87
  value,
66
88
  onChange,
@@ -70,14 +92,16 @@ function BrandProfileEditor({
70
92
  applyTarget,
71
93
  onLogoFile,
72
94
  colorPresets = EMPTY_COLORS,
73
- className
95
+ className,
96
+ labels: labelOverrides
74
97
  }) {
98
+ const labels = { ...DEFAULT_BRAND_PROFILE_EDITOR_LABELS, ...labelOverrides };
75
99
  const [announcement, setAnnouncement] = useState("");
76
100
  const update = (patch) => onChange({ ...value, ...patch });
77
101
  const apply = () => {
78
102
  if (applyTarget !== null) applyBrandProfile(value, applyTarget);
79
103
  onApply?.(value);
80
- setAnnouncement(`${value.name} applied.`);
104
+ setAnnouncement(fillLabel(labels.applied, { name: value.name }));
81
105
  };
82
106
  const onFile = (event) => {
83
107
  const file = event.currentTarget.files?.[0];
@@ -89,54 +113,54 @@ function BrandProfileEditor({
89
113
  ...value.typography?.sans ? { "--uix-font-sans": value.typography.sans } : {},
90
114
  ...value.typography?.heading ? { "--uix-font-heading": value.typography.heading } : {}
91
115
  };
92
- return /* @__PURE__ */ jsxs("section", { className: cx("uix-brand-profiles", className), "aria-label": "Brand profile editor", children: [
116
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-brand-profiles", className), "aria-label": labels.region, children: [
93
117
  /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__form", children: [
94
118
  profiles.length > 0 && /* @__PURE__ */ jsxs("label", { className: "uix-field__label", children: [
95
- "Profile",
119
+ labels.profile,
96
120
  /* @__PURE__ */ jsx("select", { className: "uix-select", value: value.id, onChange: (event) => {
97
121
  const selected = profiles.find((profile) => profile.id === event.currentTarget.value);
98
122
  if (selected) onSelectProfile?.(selected);
99
123
  }, children: profiles.map((profile) => /* @__PURE__ */ jsx("option", { value: profile.id, children: profile.name }, profile.id)) })
100
124
  ] }),
101
125
  /* @__PURE__ */ jsxs("label", { className: "uix-field__label", children: [
102
- "Name",
126
+ labels.name,
103
127
  /* @__PURE__ */ jsx("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
104
128
  ] }),
105
129
  /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__colors", children: [
106
130
  /* @__PURE__ */ jsxs("label", { children: [
107
- "Brand",
108
- /* @__PURE__ */ jsx(ColorPicker, { label: "Brand color", value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
131
+ labels.brand,
132
+ /* @__PURE__ */ jsx(ColorPicker, { label: labels.brandColor, value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
109
133
  ] }),
110
134
  /* @__PURE__ */ jsxs("label", { children: [
111
- "On brand",
112
- /* @__PURE__ */ jsx(ColorPicker, { label: "Brand foreground color", value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
135
+ labels.onBrand,
136
+ /* @__PURE__ */ jsx(ColorPicker, { label: labels.onBrandColor, value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
113
137
  ] })
114
138
  ] }),
115
139
  /* @__PURE__ */ jsxs("label", { className: "uix-field__label", children: [
116
- "Body font",
140
+ labels.bodyFont,
117
141
  /* @__PURE__ */ jsx("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
118
142
  ] }),
119
143
  /* @__PURE__ */ jsxs("label", { className: "uix-field__label", children: [
120
- "Heading font",
144
+ labels.headingFont,
121
145
  /* @__PURE__ */ jsx("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
122
146
  ] }),
123
147
  /* @__PURE__ */ jsxs("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
124
- "Logo file",
148
+ labels.logoFile,
125
149
  /* @__PURE__ */ jsx("input", { type: "file", accept: "image/*", onChange: onFile })
126
150
  ] }),
127
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: "Apply profile" }),
151
+ /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: labels.apply }),
128
152
  /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
129
153
  ] }),
130
- /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": `Live preview of ${value.name}`, children: [
154
+ /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": fillLabel(labels.preview, { name: value.name }), children: [
131
155
  /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__preview-header", children: [
132
- value.logo ? /* @__PURE__ */ jsx("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ jsx("span", { className: "uix-brand-profiles__logo-placeholder", children: "Logo" }),
133
- /* @__PURE__ */ jsx("strong", { children: value.name || "Brand preview" })
156
+ value.logo ? /* @__PURE__ */ jsx("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ jsx("span", { className: "uix-brand-profiles__logo-placeholder", children: labels.logoPlaceholder }),
157
+ /* @__PURE__ */ jsx("strong", { children: value.name || labels.previewTitleFallback })
134
158
  ] }),
135
159
  /* @__PURE__ */ jsxs("div", { className: "uix-brand-profiles__preview-body", children: [
136
- /* @__PURE__ */ jsx("h3", { children: "Readable, serializable branding" }),
137
- /* @__PURE__ */ jsx("p", { children: "Accent, links, rings, and muted states continue through the existing UIx token chain." }),
138
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--primary", children: "Primary action" }),
139
- /* @__PURE__ */ jsx("a", { href: "#brand-profile-preview", children: "Preview link" })
160
+ /* @__PURE__ */ jsx("h3", { children: labels.previewHeading }),
161
+ /* @__PURE__ */ jsx("p", { children: labels.previewBody }),
162
+ /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--primary", children: labels.previewPrimary }),
163
+ /* @__PURE__ */ jsx("a", { href: "#brand-profile-preview", children: labels.previewLink })
140
164
  ] })
141
165
  ] })
142
166
  ] });
@@ -145,6 +169,7 @@ const BrandProfiles = BrandProfileEditor;
145
169
  export {
146
170
  BrandProfileEditor,
147
171
  BrandProfiles,
172
+ DEFAULT_BRAND_PROFILE_EDITOR_LABELS,
148
173
  applyBrandProfile,
149
174
  restoreBrandProfile
150
175
  };
@@ -14,6 +14,30 @@ interface BuilderPaletteItem {
14
14
  description?: string;
15
15
  create: () => BuilderCanvasItem;
16
16
  }
17
+ /** Every word the builder renders (TENSOR RX-125, UIX-12). `{label}` is the item's label. */
18
+ interface BuilderCanvasLabels {
19
+ region: string;
20
+ palette: string;
21
+ paletteHeading: string;
22
+ paletteEmpty: string;
23
+ add: string;
24
+ addFirst: string;
25
+ canvasHeading: string;
26
+ loading: string;
27
+ retry: string;
28
+ moveUp: string;
29
+ moveUpNamed: string;
30
+ moveDown: string;
31
+ moveDownNamed: string;
32
+ remove: string;
33
+ removeNamed: string;
34
+ properties: string;
35
+ propertiesHeading: string;
36
+ propertiesEmpty: string;
37
+ type: string;
38
+ label: string;
39
+ }
40
+ declare const DEFAULT_BUILDER_CANVAS_LABELS: BuilderCanvasLabels;
17
41
  interface BuilderCanvasProps {
18
42
  items: BuilderCanvasItem[];
19
43
  onItemsChange: (items: BuilderCanvasItem[]) => void;
@@ -27,8 +51,9 @@ interface BuilderCanvasProps {
27
51
  onRetry?: () => void;
28
52
  emptyMessage?: string;
29
53
  className?: string;
54
+ labels?: Partial<BuilderCanvasLabels>;
30
55
  }
31
56
  /** Palette + sortable canvas + property panel scaffold. Owns interaction, never persistence. */
32
- declare function BuilderCanvas({ items, onItemsChange, palette, selectedId: controlledSelectedId, onSelect, renderItem, renderProperties, loading, error, onRetry, emptyMessage, className, }: BuilderCanvasProps): react.JSX.Element;
57
+ declare function BuilderCanvas({ items, onItemsChange, palette, selectedId: controlledSelectedId, onSelect, renderItem, renderProperties, loading, error, onRetry, emptyMessage, className, labels: labelOverrides, }: BuilderCanvasProps): react.JSX.Element;
33
58
 
34
- export { BuilderCanvas, type BuilderCanvasItem, type BuilderCanvasProps, type BuilderPaletteItem };
59
+ export { BuilderCanvas, type BuilderCanvasItem, type BuilderCanvasLabels, type BuilderCanvasProps, type BuilderPaletteItem, DEFAULT_BUILDER_CANVAS_LABELS };