@dlh.io/bideux 0.1.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 (90) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +90 -0
  3. package/dist/all.d.ts +14 -0
  4. package/dist/all.js +15 -0
  5. package/dist/all.js.map +1 -0
  6. package/dist/chunk-62IQGXLW.js +11470 -0
  7. package/dist/chunk-62IQGXLW.js.map +1 -0
  8. package/dist/chunk-75CRTQK7.js +315 -0
  9. package/dist/chunk-75CRTQK7.js.map +1 -0
  10. package/dist/chunk-FVO6E22Z.js +225 -0
  11. package/dist/chunk-FVO6E22Z.js.map +1 -0
  12. package/dist/chunk-GRITOB4M.js +337 -0
  13. package/dist/chunk-GRITOB4M.js.map +1 -0
  14. package/dist/chunk-HPFHIZWO.js +40 -0
  15. package/dist/chunk-HPFHIZWO.js.map +1 -0
  16. package/dist/chunk-IMNUQGHE.js +2864 -0
  17. package/dist/chunk-IMNUQGHE.js.map +1 -0
  18. package/dist/chunk-LHD445PJ.js +571 -0
  19. package/dist/chunk-LHD445PJ.js.map +1 -0
  20. package/dist/chunk-LPLBBHOW.js +386 -0
  21. package/dist/chunk-LPLBBHOW.js.map +1 -0
  22. package/dist/chunk-NGM5R3LW.js +881 -0
  23. package/dist/chunk-NGM5R3LW.js.map +1 -0
  24. package/dist/chunk-OMPR32AR.js +1320 -0
  25. package/dist/chunk-OMPR32AR.js.map +1 -0
  26. package/dist/chunk-QDQ5VVTC.js +255 -0
  27. package/dist/chunk-QDQ5VVTC.js.map +1 -0
  28. package/dist/chunk-RRWZKNDZ.js +1004 -0
  29. package/dist/chunk-RRWZKNDZ.js.map +1 -0
  30. package/dist/chunk-SRWIBMEB.js +178 -0
  31. package/dist/chunk-SRWIBMEB.js.map +1 -0
  32. package/dist/element/chunk-AOKCBPMV.js +1646 -0
  33. package/dist/element/chunk-AOKCBPMV.js.map +1 -0
  34. package/dist/element/chunk-B67SYRQP.js +281 -0
  35. package/dist/element/chunk-B67SYRQP.js.map +1 -0
  36. package/dist/element/chunk-FNRVFA2C.js +55 -0
  37. package/dist/element/chunk-FNRVFA2C.js.map +1 -0
  38. package/dist/element/chunk-G3C722QP.js +4707 -0
  39. package/dist/element/chunk-G3C722QP.js.map +1 -0
  40. package/dist/element/chunk-H5IFOSQP.js +346 -0
  41. package/dist/element/chunk-H5IFOSQP.js.map +1 -0
  42. package/dist/element/chunk-LXR3CLCN.js +30 -0
  43. package/dist/element/chunk-LXR3CLCN.js.map +1 -0
  44. package/dist/element/chunk-TFV4CJR4.js +183 -0
  45. package/dist/element/chunk-TFV4CJR4.js.map +1 -0
  46. package/dist/element/chunk-TXSK3CIN.js +859 -0
  47. package/dist/element/chunk-TXSK3CIN.js.map +1 -0
  48. package/dist/element/chunk-WDTTBY3S.js +45 -0
  49. package/dist/element/chunk-WDTTBY3S.js.map +1 -0
  50. package/dist/element/chunk-ZI3RYCAR.js +233 -0
  51. package/dist/element/chunk-ZI3RYCAR.js.map +1 -0
  52. package/dist/element/element.d.ts +3044 -0
  53. package/dist/element/element.js +146554 -0
  54. package/dist/element/element.js.map +1 -0
  55. package/dist/element/revo-grid.entry-7FHEBN3O.js +4817 -0
  56. package/dist/element/revo-grid.entry-7FHEBN3O.js.map +1 -0
  57. package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js +1328 -0
  58. package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js.map +1 -0
  59. package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js +494 -0
  60. package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js.map +1 -0
  61. package/dist/element/revogr-data_4.entry-2UBOKTFN.js +1041 -0
  62. package/dist/element/revogr-data_4.entry-2UBOKTFN.js.map +1 -0
  63. package/dist/element/revogr-filter-panel.entry-B24PLQU4.js +552 -0
  64. package/dist/element/revogr-filter-panel.entry-B24PLQU4.js.map +1 -0
  65. package/dist/index.d.ts +1041 -0
  66. package/dist/index.js +10 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/react.d.ts +1915 -0
  69. package/dist/react.js +14 -0
  70. package/dist/react.js.map +1 -0
  71. package/dist/renderers/echarts.d.ts +44 -0
  72. package/dist/renderers/echarts.js +6 -0
  73. package/dist/renderers/echarts.js.map +1 -0
  74. package/dist/renderers/index.d.ts +48 -0
  75. package/dist/renderers/index.js +12 -0
  76. package/dist/renderers/index.js.map +1 -0
  77. package/dist/renderers/revogrid.d.ts +76 -0
  78. package/dist/renderers/revogrid.js +6 -0
  79. package/dist/renderers/revogrid.js.map +1 -0
  80. package/dist/renderers/tabulator.d.ts +37 -0
  81. package/dist/renderers/tabulator.js +6 -0
  82. package/dist/renderers/tabulator.js.map +1 -0
  83. package/dist/result-table-CPls-277.d.ts +1885 -0
  84. package/dist/schema/dashboard.schema.json +4374 -0
  85. package/dist/schema/semantic-model.schema.json +1200 -0
  86. package/dist/schema/widget.schema.json +1793 -0
  87. package/dist/styles.css +156 -0
  88. package/dist/theme.css +1789 -0
  89. package/dist/types-CHFSsU_X.d.ts +1007 -0
  90. package/package.json +119 -0
@@ -0,0 +1,315 @@
1
+ // ../dashboard-core/src/interactions.ts
2
+ function getClickInteraction(widget) {
3
+ return widget.spec.interactions?.[0];
4
+ }
5
+ function findEventRow(rows, mappings, name, seriesName) {
6
+ const categoryField = mappings?.category ?? "category";
7
+ const seriesField = mappings?.series;
8
+ if (!rows.length) return void 0;
9
+ if (name !== void 0 && name !== null && name !== "") {
10
+ for (const row of rows) {
11
+ const categoryMatch = String(row[categoryField] ?? "") === String(name);
12
+ const seriesMatch = !seriesField || seriesName === void 0 || seriesName === null || String(row[seriesField] ?? "") === String(seriesName);
13
+ if (categoryMatch && seriesMatch) {
14
+ return row;
15
+ }
16
+ }
17
+ }
18
+ if (seriesField && seriesName !== void 0 && seriesName !== null) {
19
+ for (const row of rows) {
20
+ if (String(row[seriesField] ?? "") === String(seriesName)) {
21
+ return row;
22
+ }
23
+ }
24
+ }
25
+ return rows[0];
26
+ }
27
+ function resolveInteractionValue(mapping, context, currentFilters) {
28
+ const source = mapping.source ?? { kind: "event" };
29
+ if (source.kind === "literal") {
30
+ return source.value;
31
+ }
32
+ if (source.kind === "filter") {
33
+ return source.field ? currentFilters[source.field] : void 0;
34
+ }
35
+ if (source.field) {
36
+ return context.data?.[source.field];
37
+ }
38
+ return context.value;
39
+ }
40
+ function resolveInteractionValues(interaction, context, currentFilters) {
41
+ const values = {};
42
+ for (const mapping of interaction.variable_mappings ?? []) {
43
+ values[mapping.target] = resolveInteractionValue(
44
+ mapping,
45
+ context,
46
+ currentFilters
47
+ );
48
+ }
49
+ return values;
50
+ }
51
+ function isUrlInteraction(interaction) {
52
+ return interaction.target_type === "url" || /^https?:\/\//i.test(interaction.target) || interaction.target.startsWith("/");
53
+ }
54
+ function encodeDrillStack(stack) {
55
+ return encodeURIComponent(JSON.stringify(stack));
56
+ }
57
+ function decodeDrillStack(raw) {
58
+ if (!raw) return [];
59
+ try {
60
+ const parsed = JSON.parse(decodeURIComponent(raw));
61
+ if (Array.isArray(parsed)) return parsed;
62
+ } catch {
63
+ }
64
+ return [];
65
+ }
66
+ function buildDrillUrl(targetDashboardId, targetFilters, currentStack, options) {
67
+ const stack = options?.currentDashboard ? [...currentStack, options.currentDashboard] : currentStack;
68
+ const params = [
69
+ `filters=${encodeURIComponent(JSON.stringify(targetFilters))}`
70
+ ];
71
+ if (stack.length > 0) {
72
+ params.push(`drill_stack=${encodeURIComponent(encodeDrillStack(stack))}`);
73
+ }
74
+ if (options?.detail) {
75
+ params.push("detail=1");
76
+ }
77
+ return `/dashboards/custom/${targetDashboardId}?${params.join("&")}`;
78
+ }
79
+
80
+ // ../dashboard-renderers/src/records.ts
81
+ function isRecord(value) {
82
+ return typeof value === "object" && value !== null && !Array.isArray(value);
83
+ }
84
+ function record(value) {
85
+ return isRecord(value) ? value : {};
86
+ }
87
+ function stringValue(value) {
88
+ return typeof value === "string" ? value : void 0;
89
+ }
90
+ function numberValue(value) {
91
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
92
+ }
93
+ function displayBlock(widget, component) {
94
+ return record(record(widget.spec.display)[component]);
95
+ }
96
+
97
+ // ../dashboard-renderers/src/theme.ts
98
+ var DEFAULT_WIDGET_DEFAULTS = {
99
+ global: {
100
+ borderRadius: "0.75rem",
101
+ border: true,
102
+ shadow: true
103
+ }
104
+ };
105
+ var THEME_KEYS = [
106
+ "padding",
107
+ "margin",
108
+ "borderRadius",
109
+ "background",
110
+ "border",
111
+ "shadow"
112
+ ];
113
+ function isDefined(value) {
114
+ return value !== void 0 && value !== null && value !== "";
115
+ }
116
+ function firstDefined(...values) {
117
+ return values.find(isDefined);
118
+ }
119
+ function addBaseline(value, baseline) {
120
+ if (value === void 0 || typeof value === "boolean") return baseline;
121
+ if (typeof value === "number") return baseline + value;
122
+ const trimmed = value.trim();
123
+ if (trimmed === "") return baseline;
124
+ if (/^-?\d+(?:\.\d+)?$/u.test(trimmed)) {
125
+ return `calc(${baseline}px + ${trimmed}px)`;
126
+ }
127
+ return `calc(${baseline}px + ${trimmed})`;
128
+ }
129
+ function resolveTheme(widget, component, widgetDefaults = {}) {
130
+ const display = record(widget.spec.display);
131
+ const componentDisplay = record(display[component]);
132
+ const defaults = DEFAULT_WIDGET_DEFAULTS[component];
133
+ const defaultGlobal = DEFAULT_WIDGET_DEFAULTS.global;
134
+ const overrideComponent = widgetDefaults[component];
135
+ const overrideGlobal = widgetDefaults.global;
136
+ const theme = {};
137
+ for (const key of THEME_KEYS) {
138
+ const resolved = firstDefined(
139
+ componentDisplay[key],
140
+ display[key],
141
+ overrideComponent?.[key],
142
+ overrideGlobal?.[key],
143
+ defaults?.[key],
144
+ defaultGlobal?.[key]
145
+ );
146
+ if (key === "padding" || key === "margin") {
147
+ theme[key] = addBaseline(resolved, key === "padding" ? 12 : 0);
148
+ continue;
149
+ }
150
+ if (key === "borderRadius") {
151
+ if (typeof resolved === "string" || typeof resolved === "number") {
152
+ theme.borderRadius = resolved;
153
+ }
154
+ continue;
155
+ }
156
+ if (key === "background") {
157
+ if (typeof resolved === "string") theme.background = resolved;
158
+ continue;
159
+ }
160
+ if ((key === "border" || key === "shadow") && (typeof resolved === "string" || typeof resolved === "boolean")) {
161
+ theme[key] = resolved;
162
+ }
163
+ }
164
+ return theme;
165
+ }
166
+ function widgetThemeStyle(theme) {
167
+ const style = {};
168
+ if (theme.padding !== void 0) style.padding = theme.padding;
169
+ if (theme.margin !== void 0) style.margin = theme.margin;
170
+ if (theme.borderRadius !== void 0) {
171
+ style.borderRadius = theme.borderRadius;
172
+ }
173
+ if (theme.background !== void 0) style.background = theme.background;
174
+ if (typeof theme.border === "string") style.border = theme.border;
175
+ if (theme.border === false) style.border = "none";
176
+ if (typeof theme.shadow === "string") style.boxShadow = theme.shadow;
177
+ return style;
178
+ }
179
+ function readLabel(value, fallbackPosition) {
180
+ if (typeof value === "string") {
181
+ return {
182
+ text: value,
183
+ position: fallbackPosition === "bottom" ? "bottom" : "top"
184
+ };
185
+ }
186
+ if (!isRecord(value)) return void 0;
187
+ const tooltipIcon = stringValue(value.tooltip_icon);
188
+ const label = {
189
+ position: value.position === "bottom" || fallbackPosition === "bottom" ? "bottom" : "top"
190
+ };
191
+ const text = stringValue(value.text);
192
+ const tooltip = stringValue(value.tooltip);
193
+ if (text !== void 0) label.text = text;
194
+ if (tooltip !== void 0) label.tooltip = tooltip;
195
+ if (tooltipIcon === "info" || tooltipIcon === "check" || tooltipIcon === "help" || tooltipIcon === "warning") {
196
+ label.tooltipIcon = tooltipIcon;
197
+ }
198
+ return label;
199
+ }
200
+ function innerTheme(theme) {
201
+ const inner = { border: false, shadow: false };
202
+ if (theme.padding !== void 0) inner.padding = theme.padding;
203
+ return inner;
204
+ }
205
+ function rendererFrame(widget, component, widgetDefaults = {}, framed = false) {
206
+ const display = displayBlock(widget, component);
207
+ const showObjectHeader = widget.metadata.header !== void 0 && widget.metadata.header !== null && widget.metadata.header.visible !== false;
208
+ const label = showObjectHeader ? void 0 : readLabel(display.label, display.position);
209
+ const frame = {
210
+ widgetId: widget.metadata.id,
211
+ component,
212
+ theme: framed ? innerTheme(resolveTheme(widget, component, widgetDefaults)) : resolveTheme(widget, component, widgetDefaults),
213
+ showObjectHeader,
214
+ interactive: Array.isArray(widget.spec.interactions) && widget.spec.interactions.some(
215
+ (interaction) => interaction.type === "drilldown" || interaction.type === "set_filter" || interaction.type === "navigate"
216
+ )
217
+ };
218
+ if (label !== void 0) frame.label = label;
219
+ return frame;
220
+ }
221
+
222
+ // ../dashboard-renderer-web/src/dom.ts
223
+ function clearElement(element) {
224
+ element.replaceChildren();
225
+ }
226
+ function setStyles(element, styles) {
227
+ for (const [property, value] of Object.entries(styles)) {
228
+ if (value !== void 0) {
229
+ element.style.setProperty(
230
+ property,
231
+ typeof value === "number" ? String(value) : value
232
+ );
233
+ }
234
+ }
235
+ }
236
+ function applyWidgetTheme(element, frame, tokens) {
237
+ element.dataset.bideuxRenderer = frame.component;
238
+ element.dataset.widgetId = frame.widgetId;
239
+ element.style.boxSizing = "border-box";
240
+ element.style.width = "100%";
241
+ element.style.height = "100%";
242
+ element.style.color = tokens.surfaceForeground;
243
+ element.style.background = tokens.surface;
244
+ element.style.fontFamily = tokens.fontFamily;
245
+ applyThemeValues(element, frame.theme);
246
+ }
247
+ function applyThemeValues(element, theme) {
248
+ setStyles(element, {
249
+ padding: cssLength(theme.padding),
250
+ margin: cssLength(theme.margin),
251
+ "border-radius": cssLength(theme.borderRadius),
252
+ background: theme.background,
253
+ border: theme.border === true ? "1px solid currentColor" : theme.border === false ? "none" : theme.border,
254
+ "box-shadow": theme.shadow === true ? "0 12px 32px rgb(25 50 29 / 10%)" : theme.shadow === false ? "none" : theme.shadow
255
+ });
256
+ }
257
+ function cssLength(value) {
258
+ return typeof value === "number" ? `${value}px` : value;
259
+ }
260
+ function createLabel(document, text, tokens) {
261
+ const label = document.createElement("div");
262
+ label.dataset.bideuxPart = "label";
263
+ label.title = text;
264
+ label.textContent = text;
265
+ setStyles(label, {
266
+ color: tokens.mutedForeground,
267
+ "font-size": "0.875rem",
268
+ "line-height": "1.25rem",
269
+ "font-weight": "600",
270
+ overflow: "hidden",
271
+ "text-overflow": "ellipsis",
272
+ "white-space": "nowrap",
273
+ flex: "0 0 auto"
274
+ });
275
+ return label;
276
+ }
277
+ function createMessage(document, message, kind, tokens) {
278
+ const container = document.createElement("div");
279
+ container.dataset.bideuxState = kind;
280
+ container.setAttribute("role", kind === "error" ? "alert" : "status");
281
+ container.textContent = message;
282
+ setStyles(container, {
283
+ display: "grid",
284
+ "place-items": "center",
285
+ width: "100%",
286
+ height: "100%",
287
+ padding: "16px",
288
+ "box-sizing": "border-box",
289
+ color: kind === "error" ? tokens.danger : tokens.mutedForeground,
290
+ "text-align": "center"
291
+ });
292
+ return container;
293
+ }
294
+
295
+ // ../dashboard-renderer-web/src/types.ts
296
+ var defaultRendererTheme = {
297
+ foreground: "#17251b",
298
+ mutedForeground: "#526553",
299
+ border: "#d4e0d2",
300
+ surface: "#ffffff",
301
+ surfaceForeground: "#17251b",
302
+ primary: "#5b9d47",
303
+ secondary: "#3f7cac",
304
+ danger: "#a13c35",
305
+ fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif",
306
+ seriesColors: ["#5b9d47", "#3f7cac", "#f2c14e", "#bd5d38"],
307
+ heatmapColors: ["#edf3eb", "#82a878", "#315d38"]
308
+ };
309
+ function resolveRendererTheme(theme = {}) {
310
+ return { ...defaultRendererTheme, ...theme };
311
+ }
312
+
313
+ export { DEFAULT_WIDGET_DEFAULTS, applyWidgetTheme, buildDrillUrl, clearElement, createLabel, createMessage, decodeDrillStack, defaultRendererTheme, displayBlock, encodeDrillStack, findEventRow, getClickInteraction, innerTheme, isRecord, isUrlInteraction, numberValue, record, rendererFrame, resolveInteractionValue, resolveInteractionValues, resolveRendererTheme, resolveTheme, setStyles, stringValue, widgetThemeStyle };
314
+ //# sourceMappingURL=chunk-75CRTQK7.js.map
315
+ //# sourceMappingURL=chunk-75CRTQK7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../dashboard-core/src/interactions.ts","../../dashboard-renderers/src/records.ts","../../dashboard-renderers/src/theme.ts","../../dashboard-renderer-web/src/dom.ts","../../dashboard-renderer-web/src/types.ts"],"names":[],"mappings":"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","file":"chunk-75CRTQK7.js","sourcesContent":["import type { WidgetInteraction, WidgetSpec } from \"./types.js\";\n\nexport interface WidgetInteractionContext {\n widgetId: string;\n data?: Record<string, unknown>;\n value?: unknown;\n}\n\nexport interface DrillStackItem {\n id: string;\n name: string;\n filters: Record<string, unknown>;\n}\n\nexport function getClickInteraction(\n widget: WidgetSpec,\n): WidgetInteraction | undefined {\n return widget.spec.interactions?.[0];\n}\n\nexport function findEventRow(\n rows: Record<string, unknown>[],\n mappings: WidgetSpec[\"spec\"][\"mappings\"],\n name?: string | null,\n seriesName?: string | null,\n): Record<string, unknown> | undefined {\n const categoryField = mappings?.category ?? \"category\";\n const seriesField = mappings?.series;\n\n if (!rows.length) return undefined;\n\n if (name !== undefined && name !== null && name !== \"\") {\n for (const row of rows) {\n const categoryMatch = String(row[categoryField] ?? \"\") === String(name);\n const seriesMatch =\n !seriesField ||\n seriesName === undefined ||\n seriesName === null ||\n String(row[seriesField] ?? \"\") === String(seriesName);\n if (categoryMatch && seriesMatch) {\n return row;\n }\n }\n }\n\n // Fall back to a row whose series value matches the supplied raw value.\n if (seriesField && seriesName !== undefined && seriesName !== null) {\n for (const row of rows) {\n if (String(row[seriesField] ?? \"\") === String(seriesName)) {\n return row;\n }\n }\n }\n\n return rows[0];\n}\n\nexport function resolveInteractionValue(\n mapping: NonNullable<WidgetInteraction[\"variable_mappings\"]>[number],\n context: WidgetInteractionContext,\n currentFilters: Record<string, unknown>,\n): unknown {\n const source = mapping.source ?? { kind: \"event\" };\n if (source.kind === \"literal\") {\n return source.value;\n }\n if (source.kind === \"filter\") {\n return source.field ? currentFilters[source.field] : undefined;\n }\n // event\n if (source.field) {\n return context.data?.[source.field];\n }\n return context.value;\n}\n\nexport function resolveInteractionValues(\n interaction: WidgetInteraction,\n context: WidgetInteractionContext,\n currentFilters: Record<string, unknown>,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const mapping of interaction.variable_mappings ?? []) {\n values[mapping.target] = resolveInteractionValue(\n mapping,\n context,\n currentFilters,\n );\n }\n return values;\n}\n\nexport function isUrlInteraction(interaction: WidgetInteraction): boolean {\n return (\n interaction.target_type === \"url\" ||\n /^https?:\\/\\//i.test(interaction.target) ||\n interaction.target.startsWith(\"/\")\n );\n}\n\nexport function encodeDrillStack(stack: DrillStackItem[]): string {\n return encodeURIComponent(JSON.stringify(stack));\n}\n\nexport function decodeDrillStack(raw: string | null): DrillStackItem[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(decodeURIComponent(raw));\n if (Array.isArray(parsed)) return parsed;\n } catch {\n // ignore invalid drill stack\n }\n return [];\n}\n\nexport function buildDrillUrl(\n targetDashboardId: string,\n targetFilters: Record<string, unknown>,\n currentStack: DrillStackItem[],\n options?: { detail?: boolean; currentDashboard?: DrillStackItem },\n): string {\n const stack = options?.currentDashboard\n ? [...currentStack, options.currentDashboard]\n : currentStack;\n const params = [\n `filters=${encodeURIComponent(JSON.stringify(targetFilters))}`,\n ];\n if (stack.length > 0) {\n params.push(`drill_stack=${encodeURIComponent(encodeDrillStack(stack))}`);\n }\n if (options?.detail) {\n params.push(\"detail=1\");\n }\n return `/dashboards/custom/${targetDashboardId}?${params.join(\"&\")}`;\n}\n","import type { WidgetSpec } from \"./types.js\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function record(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nexport function stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nexport function numberValue(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nexport function displayBlock(\n widget: WidgetSpec,\n component: string,\n): Record<string, unknown> {\n return record(record(widget.spec.display)[component]);\n}\n","import type {\n RendererFrame,\n RendererLabel,\n WidgetComponent,\n WidgetDefaults,\n WidgetSpec,\n WidgetTheme,\n} from \"./types.js\";\nimport { displayBlock, isRecord, record, stringValue } from \"./records.js\";\n\nexport const DEFAULT_WIDGET_DEFAULTS: WidgetDefaults = {\n global: {\n borderRadius: \"0.75rem\",\n border: true,\n shadow: true,\n },\n};\n\nconst THEME_KEYS = [\n \"padding\",\n \"margin\",\n \"borderRadius\",\n \"background\",\n \"border\",\n \"shadow\",\n] as const;\n\ntype ThemeValue = string | number | boolean;\n\nfunction isDefined(value: unknown): value is ThemeValue {\n return value !== undefined && value !== null && value !== \"\";\n}\n\nfunction firstDefined(...values: unknown[]): ThemeValue | undefined {\n return values.find(isDefined);\n}\n\nfunction addBaseline(\n value: ThemeValue | undefined,\n baseline: number,\n): string | number {\n if (value === undefined || typeof value === \"boolean\") return baseline;\n if (typeof value === \"number\") return baseline + value;\n const trimmed = value.trim();\n if (trimmed === \"\") return baseline;\n if (/^-?\\d+(?:\\.\\d+)?$/u.test(trimmed)) {\n return `calc(${baseline}px + ${trimmed}px)`;\n }\n return `calc(${baseline}px + ${trimmed})`;\n}\n\nexport function resolveTheme(\n widget: WidgetSpec,\n component: WidgetComponent,\n widgetDefaults: WidgetDefaults = {},\n): WidgetTheme {\n const display = record(widget.spec.display);\n const componentDisplay = record(display[component]);\n const defaults = DEFAULT_WIDGET_DEFAULTS[component];\n const defaultGlobal = DEFAULT_WIDGET_DEFAULTS.global;\n const overrideComponent = widgetDefaults[component];\n const overrideGlobal = widgetDefaults.global;\n const theme: WidgetTheme = {};\n\n for (const key of THEME_KEYS) {\n const resolved = firstDefined(\n componentDisplay[key],\n display[key],\n overrideComponent?.[key],\n overrideGlobal?.[key],\n defaults?.[key],\n defaultGlobal?.[key],\n );\n if (key === \"padding\" || key === \"margin\") {\n theme[key] = addBaseline(resolved, key === \"padding\" ? 12 : 0);\n continue;\n }\n if (key === \"borderRadius\") {\n if (typeof resolved === \"string\" || typeof resolved === \"number\") {\n theme.borderRadius = resolved;\n }\n continue;\n }\n if (key === \"background\") {\n if (typeof resolved === \"string\") theme.background = resolved;\n continue;\n }\n if (\n (key === \"border\" || key === \"shadow\") &&\n (typeof resolved === \"string\" || typeof resolved === \"boolean\")\n ) {\n theme[key] = resolved;\n }\n }\n return theme;\n}\n\nexport function widgetThemeStyle(\n theme: WidgetTheme,\n): Record<string, string | number> {\n const style: Record<string, string | number> = {};\n if (theme.padding !== undefined) style.padding = theme.padding;\n if (theme.margin !== undefined) style.margin = theme.margin;\n if (theme.borderRadius !== undefined) {\n style.borderRadius = theme.borderRadius;\n }\n if (theme.background !== undefined) style.background = theme.background;\n if (typeof theme.border === \"string\") style.border = theme.border;\n if (theme.border === false) style.border = \"none\";\n if (typeof theme.shadow === \"string\") style.boxShadow = theme.shadow;\n return style;\n}\n\nfunction readLabel(\n value: unknown,\n fallbackPosition: unknown,\n): RendererLabel | undefined {\n if (typeof value === \"string\") {\n return {\n text: value,\n position: fallbackPosition === \"bottom\" ? \"bottom\" : \"top\",\n };\n }\n if (!isRecord(value)) return undefined;\n const tooltipIcon = stringValue(value.tooltip_icon);\n const label: RendererLabel = {\n position:\n value.position === \"bottom\" || fallbackPosition === \"bottom\"\n ? \"bottom\"\n : \"top\",\n };\n const text = stringValue(value.text);\n const tooltip = stringValue(value.tooltip);\n if (text !== undefined) label.text = text;\n if (tooltip !== undefined) label.tooltip = tooltip;\n if (\n tooltipIcon === \"info\" ||\n tooltipIcon === \"check\" ||\n tooltipIcon === \"help\" ||\n tooltipIcon === \"warning\"\n ) {\n label.tooltipIcon = tooltipIcon;\n }\n return label;\n}\n\n/**\n * The theme a renderer applies when a host frame already draws the card. Only\n * the inner spacing survives; border, radius, shadow and background belong to\n * the frame, so applying them twice would draw a second box inside the card.\n */\nexport function innerTheme(theme: WidgetTheme): WidgetTheme {\n const inner: WidgetTheme = { border: false, shadow: false };\n if (theme.padding !== undefined) inner.padding = theme.padding;\n return inner;\n}\n\nexport function rendererFrame(\n widget: WidgetSpec,\n component: WidgetComponent,\n widgetDefaults: WidgetDefaults = {},\n framed = false,\n): RendererFrame {\n const display = displayBlock(widget, component);\n const showObjectHeader =\n widget.metadata.header !== undefined &&\n widget.metadata.header !== null &&\n widget.metadata.header.visible !== false;\n const label = showObjectHeader\n ? undefined\n : readLabel(display.label, display.position);\n const frame: RendererFrame = {\n widgetId: widget.metadata.id,\n component,\n theme: framed\n ? innerTheme(resolveTheme(widget, component, widgetDefaults))\n : resolveTheme(widget, component, widgetDefaults),\n showObjectHeader,\n interactive:\n Array.isArray(widget.spec.interactions) &&\n widget.spec.interactions.some(\n (interaction) =>\n interaction.type === \"drilldown\" ||\n interaction.type === \"set_filter\" ||\n interaction.type === \"navigate\",\n ),\n };\n if (label !== undefined) frame.label = label;\n return frame;\n}\n","import type {\n RendererFrame,\n WidgetTheme,\n} from \"@dlh.io/bideux-dashboard-renderers\";\n\nimport type { RendererThemeTokens } from \"./types.js\";\n\nexport function clearElement(element: HTMLElement): void {\n element.replaceChildren();\n}\n\nexport function setStyles(\n element: HTMLElement,\n styles: Readonly<Record<string, string | number | undefined>>,\n): void {\n for (const [property, value] of Object.entries(styles)) {\n if (value !== undefined) {\n element.style.setProperty(\n property,\n typeof value === \"number\" ? String(value) : value,\n );\n }\n }\n}\n\nexport function applyWidgetTheme(\n element: HTMLElement,\n frame: RendererFrame,\n tokens: RendererThemeTokens,\n): void {\n element.dataset.bideuxRenderer = frame.component;\n element.dataset.widgetId = frame.widgetId;\n element.style.boxSizing = \"border-box\";\n element.style.width = \"100%\";\n element.style.height = \"100%\";\n element.style.color = tokens.surfaceForeground;\n element.style.background = tokens.surface;\n element.style.fontFamily = tokens.fontFamily;\n applyThemeValues(element, frame.theme);\n}\n\nfunction applyThemeValues(element: HTMLElement, theme: WidgetTheme): void {\n setStyles(element, {\n padding: cssLength(theme.padding),\n margin: cssLength(theme.margin),\n \"border-radius\": cssLength(theme.borderRadius),\n background: theme.background,\n border:\n theme.border === true\n ? \"1px solid currentColor\"\n : theme.border === false\n ? \"none\"\n : theme.border,\n \"box-shadow\":\n theme.shadow === true\n ? \"0 12px 32px rgb(25 50 29 / 10%)\"\n : theme.shadow === false\n ? \"none\"\n : theme.shadow,\n });\n}\n\nfunction cssLength(value: string | number | undefined): string | undefined {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nexport function createLabel(\n document: Document,\n text: string,\n tokens: RendererThemeTokens,\n): HTMLElement {\n const label = document.createElement(\"div\");\n label.dataset.bideuxPart = \"label\";\n label.title = text;\n label.textContent = text;\n setStyles(label, {\n color: tokens.mutedForeground,\n \"font-size\": \"0.875rem\",\n \"line-height\": \"1.25rem\",\n \"font-weight\": \"600\",\n overflow: \"hidden\",\n \"text-overflow\": \"ellipsis\",\n \"white-space\": \"nowrap\",\n flex: \"0 0 auto\",\n });\n return label;\n}\n\nexport function createMessage(\n document: Document,\n message: string,\n kind: \"error\" | \"loading\" | \"notice\",\n tokens: RendererThemeTokens,\n): HTMLElement {\n const container = document.createElement(\"div\");\n container.dataset.bideuxState = kind;\n container.setAttribute(\"role\", kind === \"error\" ? \"alert\" : \"status\");\n container.textContent = message;\n setStyles(container, {\n display: \"grid\",\n \"place-items\": \"center\",\n width: \"100%\",\n height: \"100%\",\n padding: \"16px\",\n \"box-sizing\": \"border-box\",\n color: kind === \"error\" ? tokens.danger : tokens.mutedForeground,\n \"text-align\": \"center\",\n });\n return container;\n}\n","import type {\n WidgetInteraction,\n WidgetInteractionContext,\n} from \"@dlh.io/bideux-dashboard-core\";\nimport type {\n BasicRendererModel,\n PivotViewState,\n RendererContext,\n WidgetResult,\n WidgetSpec,\n} from \"@dlh.io/bideux-dashboard-renderers\";\n\nexport interface BrowserRenderer<TInput> {\n update(input: TInput): void;\n resize(): void;\n destroy(): void;\n}\n\nexport interface RendererThemeTokens {\n foreground: string;\n mutedForeground: string;\n border: string;\n surface: string;\n surfaceForeground: string;\n primary: string;\n secondary: string;\n danger: string;\n fontFamily: string;\n seriesColors: string[];\n heatmapColors: string[];\n}\n\nexport interface RendererLicenseRequest {\n renderer: \"revogrid\";\n capability: \"pivot-pro\";\n}\n\nexport interface RendererLicensePort {\n getLicense(\n request: RendererLicenseRequest,\n ): string | null | Promise<string | null>;\n}\n\nexport interface RendererExtensionMount {\n element: HTMLElement;\n model: Extract<BasicRendererModel, { kind: \"extension\" }>;\n}\n\nexport interface RendererExportRequest {\n widgetId: string;\n format: \"csv\" | \"excel\";\n filename: string;\n}\n\nexport interface RendererPivotDetailRequest {\n widgetId: string;\n filters: Record<string, string>;\n label: string;\n}\n\nexport interface RendererHostCallbacks {\n onInteraction?: (\n interaction: WidgetInteraction,\n context: WidgetInteractionContext,\n ) => void;\n onFilterChange?: (widgetId: string, value: unknown) => void;\n onFilterLabelChange?: (widgetId: string, label: string) => void;\n onExport?: (request: RendererExportRequest) => void | Promise<void>;\n onPivotViewChange?: (widgetId: string, view: PivotViewState) => void;\n onPivotDetail?: (request: RendererPivotDetailRequest) => void | Promise<void>;\n onRetry?: () => void;\n onError?: (error: Error) => void;\n renderExtension?: (\n input: RendererExtensionMount,\n ) => BrowserRenderer<RendererExtensionMount> | void;\n}\n\nexport interface NativeWidgetRenderInput {\n element: HTMLElement;\n widget: WidgetSpec;\n result?: WidgetResult;\n context?: RendererContext;\n filterValue?: unknown;\n callbacks?: RendererHostCallbacks;\n theme?: Partial<RendererThemeTokens>;\n}\n\n/**\n * One widget renderer, whatever library draws it. A shell mounts a widget by\n * asking a factory for this handle, then updates it as results and filters\n * change, and destroys it on unmount.\n */\nexport type WidgetRendererHandle = BrowserRenderer<NativeWidgetRenderInput>;\n\nexport type WidgetRendererFactory = (\n input: NativeWidgetRenderInput,\n) => WidgetRendererHandle | Promise<WidgetRendererHandle>;\n\n/**\n * Factories keyed by widget component, with a fallback for every component the\n * host did not name. A host wires the concrete renderer packages here, so no\n * shell carries a charting or grid dependency of its own.\n */\nexport type WidgetRendererFactories = Partial<\n Record<string, WidgetRendererFactory>\n> & {\n default?: WidgetRendererFactory;\n};\n\nexport const defaultRendererTheme: RendererThemeTokens = {\n foreground: \"#17251b\",\n mutedForeground: \"#526553\",\n border: \"#d4e0d2\",\n surface: \"#ffffff\",\n surfaceForeground: \"#17251b\",\n primary: \"#5b9d47\",\n secondary: \"#3f7cac\",\n danger: \"#a13c35\",\n fontFamily: \"Inter, ui-sans-serif, system-ui, sans-serif\",\n seriesColors: [\"#5b9d47\", \"#3f7cac\", \"#f2c14e\", \"#bd5d38\"],\n heatmapColors: [\"#edf3eb\", \"#82a878\", \"#315d38\"],\n};\n\nexport function resolveRendererTheme(\n theme: Partial<RendererThemeTokens> = {},\n): RendererThemeTokens {\n return { ...defaultRendererTheme, ...theme };\n}\n"]}
@@ -0,0 +1,225 @@
1
+ import { buildChartTheme, chartLoadingOptions, buildChartRendererModel } from './chunk-OMPR32AR.js';
2
+ import { observeElementResize } from './chunk-HPFHIZWO.js';
3
+ import { clearElement, createMessage, resolveRendererTheme, applyWidgetTheme, getClickInteraction, findEventRow } from './chunk-75CRTQK7.js';
4
+ import * as echarts from 'echarts';
5
+
6
+ var groupMembers = /* @__PURE__ */ new Map();
7
+ var defaultRuntime = {
8
+ init(element, theme) {
9
+ return echarts.init(element, theme);
10
+ },
11
+ connect(group) {
12
+ echarts.connect(group);
13
+ },
14
+ disconnect(group) {
15
+ echarts.disconnect(group);
16
+ }
17
+ };
18
+ function buildAccessibleChartOption(input) {
19
+ const option = input.model.option;
20
+ if (option.aria !== void 0) return option;
21
+ return {
22
+ ...option,
23
+ aria: {
24
+ enabled: true,
25
+ label: {
26
+ description: `${input.model.frame.widgetId} chart`
27
+ }
28
+ }
29
+ };
30
+ }
31
+ function connectGroup(runtime, group) {
32
+ if (group.length === 0) return;
33
+ const members = groupMembers.get(group) ?? 0;
34
+ groupMembers.set(group, members + 1);
35
+ if (members === 1) runtime.connect(group);
36
+ }
37
+ function disconnectGroup(runtime, group) {
38
+ if (group.length === 0) return;
39
+ const members = groupMembers.get(group) ?? 0;
40
+ if (members <= 1) {
41
+ groupMembers.delete(group);
42
+ runtime.disconnect(group);
43
+ } else {
44
+ groupMembers.set(group, members - 1);
45
+ }
46
+ }
47
+ function chartRows(input) {
48
+ return Array.isArray(input.result?.rows) ? input.result.rows : [];
49
+ }
50
+ function clickHandler(input) {
51
+ const interaction = input.widget === void 0 ? void 0 : getClickInteraction(input.widget);
52
+ if (interaction === void 0 || input.widget === void 0 || input.callbacks?.onInteraction === void 0) {
53
+ return null;
54
+ }
55
+ const widget = input.widget;
56
+ return (event) => {
57
+ const row = findEventRow(
58
+ chartRows(input),
59
+ widget.spec.mappings,
60
+ event.name ?? null,
61
+ event.seriesName ?? null
62
+ );
63
+ const context = {
64
+ widgetId: widget.metadata.id,
65
+ ...row === void 0 ? {} : { data: row },
66
+ ...event.value === void 0 ? {} : { value: event.value },
67
+ ...event.seriesName === void 0 ? {} : { seriesName: event.seriesName },
68
+ ...event.name === void 0 ? {} : { category: event.name }
69
+ };
70
+ input.callbacks?.onInteraction?.(interaction, context);
71
+ };
72
+ }
73
+ function chartTokens(input) {
74
+ const theme = resolveRendererTheme(input.theme);
75
+ return {
76
+ foreground: theme.foreground,
77
+ mutedForeground: theme.mutedForeground,
78
+ border: theme.border,
79
+ surface: theme.surface,
80
+ surfaceForeground: theme.surfaceForeground,
81
+ fontFamily: theme.fontFamily,
82
+ seriesColors: theme.seriesColors,
83
+ heatmapColors: theme.heatmapColors
84
+ };
85
+ }
86
+ function surfaceMode(surface) {
87
+ const hex = /^#([0-9a-f]{6})$/i.exec(surface.trim());
88
+ if (hex === null || hex[1] === void 0) return "light";
89
+ const value = Number.parseInt(hex[1], 16);
90
+ const r = value >> 16 & 255;
91
+ const g = value >> 8 & 255;
92
+ const b = value & 255;
93
+ return (r * 299 + g * 587 + b * 114) / 1e3 < 128 ? "dark" : "light";
94
+ }
95
+ function initialize(input, runtime) {
96
+ const theme = resolveRendererTheme(input.theme);
97
+ const chartTheme = buildChartTheme(chartTokens(input));
98
+ clearElement(input.element);
99
+ applyWidgetTheme(input.element, input.model.frame, theme);
100
+ input.element.setAttribute(
101
+ "aria-label",
102
+ `${input.model.frame.widgetId} chart`
103
+ );
104
+ input.element.setAttribute("role", "img");
105
+ input.element.tabIndex = 0;
106
+ const instance = runtime.init(input.element, chartTheme);
107
+ instance.group = input.model.axisKey;
108
+ connectGroup(runtime, instance.group);
109
+ const click = clickHandler(input);
110
+ if (click !== null) instance.on("click", click);
111
+ const observer = observeElementResize(input.element, () => instance.resize());
112
+ return { instance, click, observer };
113
+ }
114
+ function updateInstance(instance, input, structureKey) {
115
+ if (input.model.loading) {
116
+ const tokens = chartTokens(input);
117
+ instance.showLoading(
118
+ "default",
119
+ chartLoadingOptions(tokens, surfaceMode(tokens.surface))
120
+ );
121
+ } else {
122
+ instance.hideLoading();
123
+ }
124
+ instance.setOption(buildAccessibleChartOption(input), {
125
+ notMerge: structureKey !== null && structureKey !== input.model.structureKey,
126
+ lazyUpdate: false
127
+ });
128
+ instance.resize();
129
+ }
130
+ function createEChartsRenderer(input, runtime = defaultRuntime) {
131
+ let current = input;
132
+ let structureKey = null;
133
+ let group = input.model.axisKey;
134
+ let initialized;
135
+ try {
136
+ initialized = initialize(input, runtime);
137
+ updateInstance(initialized.instance, input, structureKey);
138
+ structureKey = input.model.structureKey;
139
+ } catch (error) {
140
+ const normalized = error instanceof Error ? error : new Error("ECharts rendering failed");
141
+ input.callbacks?.onError?.(normalized);
142
+ clearElement(input.element);
143
+ input.element.append(
144
+ createMessage(
145
+ input.element.ownerDocument,
146
+ normalized.message,
147
+ "error",
148
+ resolveRendererTheme(input.theme)
149
+ )
150
+ );
151
+ throw normalized;
152
+ }
153
+ return {
154
+ update(next) {
155
+ if (next.element !== current.element) {
156
+ throw new Error(
157
+ "ECharts renderers cannot move between elements. Create a new renderer."
158
+ );
159
+ }
160
+ if (next.model.axisKey !== group) {
161
+ disconnectGroup(runtime, group);
162
+ group = next.model.axisKey;
163
+ initialized.instance.group = group;
164
+ connectGroup(runtime, group);
165
+ }
166
+ if (initialized.click !== null) {
167
+ initialized.instance.off("click", initialized.click);
168
+ }
169
+ current = next;
170
+ initialized.click = clickHandler(next);
171
+ if (initialized.click !== null) {
172
+ initialized.instance.on("click", initialized.click);
173
+ }
174
+ applyWidgetTheme(
175
+ next.element,
176
+ next.model.frame,
177
+ resolveRendererTheme(next.theme)
178
+ );
179
+ updateInstance(initialized.instance, next, structureKey);
180
+ structureKey = next.model.structureKey;
181
+ },
182
+ resize() {
183
+ initialized.instance.resize();
184
+ },
185
+ destroy() {
186
+ initialized.observer?.disconnect();
187
+ if (initialized.click !== null) {
188
+ initialized.instance.off("click", initialized.click);
189
+ }
190
+ disconnectGroup(runtime, group);
191
+ initialized.instance.dispose();
192
+ clearElement(current.element);
193
+ }
194
+ };
195
+ }
196
+
197
+ // ../dashboard-renderer-echarts/src/widget-factory.ts
198
+ function chartInput(input) {
199
+ return {
200
+ element: input.element,
201
+ model: buildChartRendererModel(
202
+ input.widget,
203
+ input.result ?? {},
204
+ input.context ?? {}
205
+ ),
206
+ widget: input.widget,
207
+ ...input.result === void 0 ? {} : { result: input.result },
208
+ ...input.callbacks === void 0 ? {} : { callbacks: input.callbacks },
209
+ ...input.theme === void 0 ? {} : { theme: input.theme }
210
+ };
211
+ }
212
+ function createEChartsWidgetFactory(runtime) {
213
+ return (input) => {
214
+ const renderer = runtime === void 0 ? createEChartsRenderer(chartInput(input)) : createEChartsRenderer(chartInput(input), runtime);
215
+ return {
216
+ update: (next) => renderer.update(chartInput(next)),
217
+ resize: () => renderer.resize(),
218
+ destroy: () => renderer.destroy()
219
+ };
220
+ };
221
+ }
222
+
223
+ export { buildAccessibleChartOption, createEChartsRenderer, createEChartsWidgetFactory };
224
+ //# sourceMappingURL=chunk-FVO6E22Z.js.map
225
+ //# sourceMappingURL=chunk-FVO6E22Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../dashboard-renderer-echarts/src/renderer.ts","../../dashboard-renderer-echarts/src/widget-factory.ts"],"names":[],"mappings":"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","file":"chunk-FVO6E22Z.js","sourcesContent":["import * as echarts from \"echarts\";\nimport type { ECharts, EChartsOption } from \"echarts\";\nimport {\n findEventRow,\n getClickInteraction,\n type WidgetInteractionContext,\n} from \"@dlh.io/bideux-dashboard-core\";\nimport {\n buildChartTheme,\n chartLoadingOptions,\n type ChartThemeTokens,\n type DataRow,\n} from \"@dlh.io/bideux-dashboard-renderers\";\nimport {\n applyWidgetTheme,\n clearElement,\n createMessage,\n observeElementResize,\n resolveRendererTheme,\n type BrowserRenderer,\n} from \"@dlh.io/bideux-dashboard-renderer-web\";\n\nimport type {\n EChartsClickEvent,\n EChartsInstance,\n EChartsRendererInput,\n EChartsRuntime,\n} from \"./types.js\";\n\nconst groupMembers = new Map<string, number>();\n\nconst defaultRuntime: EChartsRuntime = {\n init(element, theme) {\n return echarts.init(element, theme);\n },\n connect(group) {\n echarts.connect(group);\n },\n disconnect(group) {\n echarts.disconnect(group);\n },\n};\n\nexport function buildAccessibleChartOption(\n input: EChartsRendererInput,\n): EChartsOption {\n const option = input.model.option as EChartsOption;\n if (option.aria !== undefined) return option;\n return {\n ...option,\n aria: {\n enabled: true,\n label: {\n description: `${input.model.frame.widgetId} chart`,\n },\n },\n };\n}\n\nfunction connectGroup(runtime: EChartsRuntime, group: string): void {\n if (group.length === 0) return;\n const members = groupMembers.get(group) ?? 0;\n groupMembers.set(group, members + 1);\n if (members === 1) runtime.connect(group);\n}\n\nfunction disconnectGroup(runtime: EChartsRuntime, group: string): void {\n if (group.length === 0) return;\n const members = groupMembers.get(group) ?? 0;\n if (members <= 1) {\n groupMembers.delete(group);\n runtime.disconnect(group);\n } else {\n groupMembers.set(group, members - 1);\n }\n}\n\nfunction chartRows(input: EChartsRendererInput): DataRow[] {\n return Array.isArray(input.result?.rows) ? input.result.rows : [];\n}\n\nfunction clickHandler(\n input: EChartsRendererInput,\n): ((event: EChartsClickEvent) => void) | null {\n const interaction =\n input.widget === undefined ? undefined : getClickInteraction(input.widget);\n if (\n interaction === undefined ||\n input.widget === undefined ||\n input.callbacks?.onInteraction === undefined\n ) {\n return null;\n }\n const widget = input.widget;\n return (event) => {\n const row = findEventRow(\n chartRows(input),\n widget.spec.mappings,\n event.name ?? null,\n event.seriesName ?? null,\n );\n const context: WidgetInteractionContext = {\n widgetId: widget.metadata.id,\n ...(row === undefined ? {} : { data: row }),\n ...(event.value === undefined ? {} : { value: event.value }),\n ...(event.seriesName === undefined\n ? {}\n : { seriesName: event.seriesName }),\n ...(event.name === undefined ? {} : { category: event.name }),\n };\n input.callbacks?.onInteraction?.(interaction, context);\n };\n}\n\nfunction chartTokens(input: EChartsRendererInput): ChartThemeTokens {\n const theme = resolveRendererTheme(input.theme);\n return {\n foreground: theme.foreground,\n mutedForeground: theme.mutedForeground,\n border: theme.border,\n surface: theme.surface,\n surfaceForeground: theme.surfaceForeground,\n fontFamily: theme.fontFamily,\n seriesColors: theme.seriesColors,\n heatmapColors: theme.heatmapColors,\n };\n}\n\n/** Light or dark, read from the surface the chart is drawn on. */\nfunction surfaceMode(surface: string): \"light\" | \"dark\" {\n const hex = /^#([0-9a-f]{6})$/i.exec(surface.trim());\n if (hex === null || hex[1] === undefined) return \"light\";\n const value = Number.parseInt(hex[1], 16);\n const r = (value >> 16) & 255;\n const g = (value >> 8) & 255;\n const b = value & 255;\n return (r * 299 + g * 587 + b * 114) / 1000 < 128 ? \"dark\" : \"light\";\n}\n\nfunction initialize(\n input: EChartsRendererInput,\n runtime: EChartsRuntime,\n): {\n instance: EChartsInstance;\n click: ((event: EChartsClickEvent) => void) | null;\n observer: ReturnType<typeof observeElementResize>;\n} {\n const theme = resolveRendererTheme(input.theme);\n const chartTheme = buildChartTheme(chartTokens(input));\n clearElement(input.element);\n applyWidgetTheme(input.element, input.model.frame, theme);\n input.element.setAttribute(\n \"aria-label\",\n `${input.model.frame.widgetId} chart`,\n );\n input.element.setAttribute(\"role\", \"img\");\n input.element.tabIndex = 0;\n const instance = runtime.init(input.element, chartTheme) as EChartsInstance;\n instance.group = input.model.axisKey;\n connectGroup(runtime, instance.group);\n const click = clickHandler(input);\n if (click !== null) instance.on(\"click\", click);\n const observer = observeElementResize(input.element, () => instance.resize());\n return { instance, click, observer };\n}\n\nfunction updateInstance(\n instance: EChartsInstance,\n input: EChartsRendererInput,\n structureKey: string | null,\n): void {\n if (input.model.loading) {\n const tokens = chartTokens(input);\n instance.showLoading(\n \"default\",\n chartLoadingOptions(tokens, surfaceMode(tokens.surface)),\n );\n } else {\n instance.hideLoading();\n }\n instance.setOption(buildAccessibleChartOption(input), {\n notMerge:\n structureKey !== null && structureKey !== input.model.structureKey,\n lazyUpdate: false,\n });\n instance.resize();\n}\n\nexport function createEChartsRenderer(\n input: EChartsRendererInput,\n runtime: EChartsRuntime = defaultRuntime,\n): BrowserRenderer<EChartsRendererInput> {\n let current = input;\n let structureKey: string | null = null;\n let group = input.model.axisKey;\n let initialized: ReturnType<typeof initialize>;\n try {\n initialized = initialize(input, runtime);\n updateInstance(initialized.instance, input, structureKey);\n structureKey = input.model.structureKey;\n } catch (error) {\n const normalized =\n error instanceof Error ? error : new Error(\"ECharts rendering failed\");\n input.callbacks?.onError?.(normalized);\n clearElement(input.element);\n input.element.append(\n createMessage(\n input.element.ownerDocument,\n normalized.message,\n \"error\",\n resolveRendererTheme(input.theme),\n ),\n );\n throw normalized;\n }\n\n return {\n update(next) {\n if (next.element !== current.element) {\n throw new Error(\n \"ECharts renderers cannot move between elements. Create a new renderer.\",\n );\n }\n if (next.model.axisKey !== group) {\n disconnectGroup(runtime, group);\n group = next.model.axisKey;\n initialized.instance.group = group;\n connectGroup(runtime, group);\n }\n if (initialized.click !== null) {\n initialized.instance.off(\"click\", initialized.click);\n }\n current = next;\n initialized.click = clickHandler(next);\n if (initialized.click !== null) {\n initialized.instance.on(\"click\", initialized.click);\n }\n applyWidgetTheme(\n next.element,\n next.model.frame,\n resolveRendererTheme(next.theme),\n );\n updateInstance(initialized.instance, next, structureKey);\n structureKey = next.model.structureKey;\n },\n resize() {\n initialized.instance.resize();\n },\n destroy() {\n initialized.observer?.disconnect();\n if (initialized.click !== null) {\n initialized.instance.off(\"click\", initialized.click);\n }\n disconnectGroup(runtime, group);\n initialized.instance.dispose();\n clearElement(current.element);\n },\n };\n}\n\nexport type { ECharts };\n","import type {\n NativeWidgetRenderInput,\n WidgetRendererFactory,\n WidgetRendererHandle,\n} from \"@dlh.io/bideux-dashboard-renderer-web\";\nimport { buildChartRendererModel } from \"@dlh.io/bideux-dashboard-renderers\";\n\nimport { createEChartsRenderer } from \"./renderer.js\";\nimport type { EChartsRendererInput, EChartsRuntime } from \"./types.js\";\n\nfunction chartInput(input: NativeWidgetRenderInput): EChartsRendererInput {\n return {\n element: input.element,\n model: buildChartRendererModel(\n input.widget,\n input.result ?? {},\n input.context ?? {},\n ),\n widget: input.widget,\n ...(input.result === undefined ? {} : { result: input.result }),\n ...(input.callbacks === undefined ? {} : { callbacks: input.callbacks }),\n ...(input.theme === undefined ? {} : { theme: input.theme }),\n };\n}\n\n/**\n * The chart renderer as a shell factory. The model is built from the widget on\n * every update, so a host passes results and filters and nothing else.\n */\nexport function createEChartsWidgetFactory(\n runtime?: EChartsRuntime,\n): WidgetRendererFactory {\n return (input: NativeWidgetRenderInput): WidgetRendererHandle => {\n const renderer =\n runtime === undefined\n ? createEChartsRenderer(chartInput(input))\n : createEChartsRenderer(chartInput(input), runtime);\n return {\n update: (next) => renderer.update(chartInput(next)),\n resize: () => renderer.resize(),\n destroy: () => renderer.destroy(),\n };\n };\n}\n"]}