@mono-lit/helper 0.0.8 → 0.0.10

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 (161) hide show
  1. package/dist/accordion-core-DaNyPWRr.js +277 -0
  2. package/dist/alert-core-DWtHbX_-.js +134 -0
  3. package/dist/breadcrumb-list-core-Dh68T8Cf.js +747 -0
  4. package/dist/{mono-button-CLkHg3WW.js → button-core-DerXg84Q.js} +3 -276
  5. package/dist/button-dropdown-core-DKYEOyjy.js +654 -0
  6. package/dist/button-utils-D5-66M02.js +63 -0
  7. package/dist/card-utils-l80qAmrN.js +312 -0
  8. package/dist/chart-core-DV7hD3ZY.js +801 -0
  9. package/dist/checkbox-utils-DKdrhAzF.js +337 -0
  10. package/dist/chip-utils-DpRrd7Zj.js +403 -0
  11. package/dist/{data-source-controller-C6C4ej_M.js → data-source-controller-DS_JLrmS.js} +1 -1
  12. package/dist/{data-source-options-fxT5QIX4.js → data-source-options-DJUNU26C.js} +6 -6
  13. package/dist/{data-source-read-BL266IW0.js → data-source-read-uKJpRAzx.js} +2 -2
  14. package/dist/date-core-CyuSyvvG.js +734 -0
  15. package/dist/drawer-core-DbFWvNln.js +759 -0
  16. package/dist/dropdown-core-BCH1pK14.js +511 -0
  17. package/dist/dropdown-table-core-SfHUJVFq.js +1342 -0
  18. package/dist/export.js +1 -1
  19. package/dist/{field-path-BabiMrrA.js → field-path-DK2VBWHl.js} +1 -1
  20. package/dist/field-tooltip.css_raw-DVblekCl.js +5 -0
  21. package/dist/{field-validation.css_raw-Cx6SGrfP.js → field-validation.css_raw-BU7C6173.js} +1 -170
  22. package/dist/file-upload-core-Cz_dBQMx.js +624 -0
  23. package/dist/filter-builder-core-DyWjbBP7.js +381 -0
  24. package/dist/{filter-builder-B6Y2mmbM.js → filter-builder-vbqIuPhX.js} +1 -1
  25. package/dist/{filter-eval-ChDSaAUH.js → filter-eval-CqeBnMYh.js} +1 -1
  26. package/dist/{filter-odata-Bi27XUpQ.js → filter-odata-GsczYKNC.js} +1 -1
  27. package/dist/{hydration-flush-BaE9gN3C.js → hydration-flush-Volt9X7Q.js} +2 -1071
  28. package/dist/index.js +11 -11
  29. package/dist/{index.node-CLqE8F8P.js → index.node-Csy9zrr1.js} +4 -4
  30. package/dist/index.node.js +11 -11
  31. package/dist/input-utils-BglY-k0H.js +1145 -0
  32. package/dist/menu-core-DkAYuCZ2.js +831 -0
  33. package/dist/modal-core-CSBSPN_m.js +844 -0
  34. package/dist/mono-button-DVvZ03P-.js +280 -0
  35. package/dist/{mono-button.shadow-DqZMpcqY.js → mono-button.shadow-BANxMGln.js} +6 -594
  36. package/dist/{mono-data-chart-NKPdAgVq.js → mono-data-chart-ChF4J9RT.js} +6 -6
  37. package/dist/{mono-data-dropdown-DUXo_jxd.js → mono-data-dropdown-Bgj2PDfm.js} +1 -1
  38. package/dist/{mono-data-grid-Bb00QM72.js → mono-data-grid-DJkp96N-.js} +346 -51
  39. package/dist/{mono-event-BPku9HpS.js → mono-event-CAZf0F_k.js} +14 -9
  40. package/dist/{mono-form-controller-BrA10erm.js → mono-form-controller-DxZLvyg6.js} +2 -1
  41. package/dist/mono-table-checkbox-core-BKOMx8R5.js +5288 -0
  42. package/dist/nav-core-B5qU2dzn.js +225 -0
  43. package/dist/{normalize-error-D93O4q8g.js → normalize-error-BEcd1tmS.js} +2 -2
  44. package/dist/otp-core-DXg3vFLh.js +758 -0
  45. package/dist/radio-utils-Dk9Tl1jz.js +319 -0
  46. package/dist/rich-text-editor-core-Ddd_QaLn.js +1280 -0
  47. package/dist/select-utils-BgArYHk8.js +2140 -0
  48. package/dist/sidebar-core-CD6txDo3.js +583 -0
  49. package/dist/slider-core-vcWr321-.js +1014 -0
  50. package/dist/src/components/dropdown-table/dropdown-table-core.d.ts +2 -2
  51. package/dist/src/components/dropdown-table/dropdown-table-types.d.ts +1 -1
  52. package/dist/src/components/dropdown-table/index.d.ts +1 -1
  53. package/dist/src/components/dropdown-table/index.shadow.d.ts +1 -1
  54. package/dist/src/components/dropdown-table/mono-data-dropdown.d.ts +1 -1
  55. package/dist/src/components/form/form-types.d.ts +9 -3
  56. package/dist/src/components/input/input-core.d.ts +1 -1
  57. package/dist/src/components/input/input-types.d.ts +1 -1
  58. package/dist/src/components/otp/otp-core.d.ts +1 -1
  59. package/dist/src/components/select/select-core.d.ts +1 -1
  60. package/dist/src/components/select/select-types.d.ts +1 -1
  61. package/dist/src/components/slider/slider-core.d.ts +1 -1
  62. package/dist/src/components/slider/slider-types.d.ts +1 -1
  63. package/dist/src/components/table/filter-suggestion.d.ts +171 -0
  64. package/dist/src/components/table/index.d.ts +5 -4
  65. package/dist/src/components/table/index.shadow.d.ts +5 -4
  66. package/dist/src/components/table/mono-data-grid.d.ts +58 -3
  67. package/dist/src/components/table/mono-table-empty-core.d.ts +37 -0
  68. package/dist/src/components/table/mono-table-search-core.d.ts +22 -3
  69. package/dist/src/components/table/table-types.d.ts +74 -4
  70. package/dist/src/components/tag-input/tag-input-core.d.ts +1 -1
  71. package/dist/src/components/tag-input/tag-input-types.d.ts +1 -1
  72. package/dist/src/components/textarea/textarea-core.d.ts +1 -1
  73. package/dist/src/composables/mono-event.d.ts +7 -1
  74. package/dist/src/entries/index.d.ts +8 -6
  75. package/dist/src/entries/index.node.d.ts +8 -6
  76. package/dist/src/search/index.d.ts +1 -1
  77. package/dist/src/utils/group-count.d.ts +36 -0
  78. package/dist/switch-utils-CTZ4id2V.js +338 -0
  79. package/dist/tabs-core-r5-B8k_N.js +317 -0
  80. package/dist/tag-input-utils-D2JA90DQ.js +3060 -0
  81. package/dist/textarea-utils-VU1KeXm8.js +821 -0
  82. package/dist/ui/accordion.js +2 -274
  83. package/dist/ui/alert.js +2 -131
  84. package/dist/ui/breadcrumb.js +4 -745
  85. package/dist/ui/button-dropdown.js +4 -652
  86. package/dist/ui/button.js +2 -63
  87. package/dist/ui/card.js +2 -310
  88. package/dist/ui/chart.js +4 -800
  89. package/dist/ui/checkbox.js +4 -335
  90. package/dist/ui/chip.js +4 -402
  91. package/dist/ui/date.js +3 -732
  92. package/dist/ui/drawer.js +3 -757
  93. package/dist/ui/dropdown-table.js +5 -1341
  94. package/dist/ui/dropdown.js +4 -509
  95. package/dist/ui/file-upload.js +3 -622
  96. package/dist/ui/filter.js +5 -380
  97. package/dist/ui/form.js +1 -1
  98. package/dist/ui/index.css +130 -5
  99. package/dist/ui/input.js +3 -1141
  100. package/dist/ui/menu.js +4 -828
  101. package/dist/ui/modal.js +4 -843
  102. package/dist/ui/nav.js +4 -223
  103. package/dist/ui/otp.js +4 -756
  104. package/dist/ui/radio.js +4 -317
  105. package/dist/ui/rich-text-editor.js +4 -1278
  106. package/dist/ui/select.js +5 -2138
  107. package/dist/ui/shadow/accordion.js +4 -273
  108. package/dist/ui/shadow/alert.js +4 -130
  109. package/dist/ui/shadow/breadcrumb.js +5 -744
  110. package/dist/ui/shadow/button-dropdown.js +6 -652
  111. package/dist/ui/shadow/button.js +3 -63
  112. package/dist/ui/shadow/card.js +4 -309
  113. package/dist/ui/shadow/chart.js +6 -1576
  114. package/dist/ui/shadow/checkbox.js +4 -334
  115. package/dist/ui/shadow/chip.js +4 -396
  116. package/dist/ui/shadow/date.js +7 -731
  117. package/dist/ui/shadow/drawer.js +4 -756
  118. package/dist/ui/shadow/dropdown-table.js +8 -1762
  119. package/dist/ui/shadow/dropdown.js +4 -508
  120. package/dist/ui/shadow/file-upload.js +4 -620
  121. package/dist/ui/shadow/filter.js +7 -379
  122. package/dist/ui/shadow/input.js +6 -1140
  123. package/dist/ui/shadow/menu.js +5 -828
  124. package/dist/ui/shadow/modal.js +6 -1063
  125. package/dist/ui/shadow/nav.js +5 -223
  126. package/dist/ui/shadow/otp.js +6 -754
  127. package/dist/ui/shadow/radio.js +4 -316
  128. package/dist/ui/shadow/rich-text-editor.js +4 -1276
  129. package/dist/ui/shadow/select.js +6 -2136
  130. package/dist/ui/shadow/sidebar.js +5 -581
  131. package/dist/ui/shadow/slider.js +5 -1010
  132. package/dist/ui/shadow/switch.js +4 -335
  133. package/dist/ui/shadow/table.js +10 -4501
  134. package/dist/ui/shadow/tabs.js +6 -315
  135. package/dist/ui/shadow/tag-input.js +7 -3057
  136. package/dist/ui/shadow/textarea.js +6 -817
  137. package/dist/ui/sidebar.js +3 -581
  138. package/dist/ui/slider.js +4 -1012
  139. package/dist/ui/switch.js +4 -336
  140. package/dist/ui/table.js +9 -4502
  141. package/dist/ui/tabs.js +4 -315
  142. package/dist/ui/tag-input.js +5 -3058
  143. package/dist/ui/textarea.js +4 -819
  144. package/dist/vue.d.ts +3 -2
  145. package/package.json +3 -3
  146. package/dist/chip-strip-bNfLn52Z.js +0 -215
  147. package/dist/data-source-controller-Dx6IQ2CN.js +0 -243
  148. package/dist/data-source-options-BM4r4PRw.js +0 -558
  149. package/dist/data-source-read-HyBCRg1t.js +0 -242
  150. package/dist/excel-BXzr3uI1.js +0 -784
  151. package/dist/export-ixRdCS2y.js +0 -2388
  152. package/dist/field-tooltip-addon-CWCp19mJ.js +0 -702
  153. package/dist/field-tooltip.css_raw-U5UeTa2d.js +0 -269
  154. package/dist/filter-builder-C0T3pMx2.js +0 -208
  155. package/dist/form-control-core-BbiACMtL.js +0 -226
  156. package/dist/icon-ClxnYhBG.js +0 -19
  157. package/dist/import-Dc4eXC02.js +0 -612
  158. package/dist/light-slots-_no0r2Z-.js +0 -246
  159. package/dist/markdown-uGlE_OfJ.js +0 -20191
  160. package/dist/mono-data-grid-Bkr-e1-i.js +0 -4043
  161. package/dist/normalize-error-BmLbgANw.js +0 -1048
@@ -0,0 +1,801 @@
1
+ import { a as errorTitle, i as errorText, n as describeError } from "./normalize-error-BEcd1tmS.js";
2
+ import { f as toCssSize, y as monoPendingGrace } from "./mono-ui-kvLVIf1V.js";
3
+ import { n as detachEventHandlers, t as applyProps } from "./element-props-xvw0EB7H.js";
4
+ import { a as defineHybridPropAliases, i as defineHybridPropAlias, o as numberStringConverter, r as booleanStringConverter, t as __decorate } from "./decorate-DbYFpi8R.js";
5
+ import { t as dispatchMonoEvent } from "./mono-event-CAZf0F_k.js";
6
+ import { c as spinnerIcon, s as refreshIcon } from "./field-icons-t8rXRCKs.js";
7
+ import { html, isServer, nothing } from "lit";
8
+ import { property, query, state } from "lit/decorators.js";
9
+ import { styleMap } from "lit/directives/style-map.js";
10
+
11
+ //#region src/components/chart/chart-core.ts
12
+ /**
13
+ * The mono color names a chart accepts wherever a color is expected. They map to
14
+ * the `--_mono-chart-<name>` resolvers in chart.css, which chain through the
15
+ * public `--mono-chart-*` overrides to the Basecoat tokens — `chart-1` … `chart-5`
16
+ * are Basecoat's own chart palette (`--chart-1` … `--chart-5`), the roles are the
17
+ * page's. `surface` is internal: the hairline between slices.
18
+ */
19
+ const MONO_COLOR_NAMES = /* @__PURE__ */ new Set([
20
+ "chart-1",
21
+ "chart-2",
22
+ "chart-3",
23
+ "chart-4",
24
+ "chart-5",
25
+ "primary",
26
+ "secondary",
27
+ "accent",
28
+ "success",
29
+ "warning",
30
+ "danger",
31
+ "info",
32
+ "surface"
33
+ ]);
34
+ /** Used before the element is in the DOM (SSR) or if a token resolves empty — ONE, light. */
35
+ const MONO_COLOR_FALLBACK = {
36
+ "chart-1": "oklch(0.859 0.069 267.7)",
37
+ "chart-2": "oklch(0.735 0.12 268.04)",
38
+ "chart-3": "oklch(0.61 0.12 267.95)",
39
+ "chart-4": "oklch(0.485 0.119 267.92)",
40
+ "chart-5": "oklch(0.36 0.12 268.21)",
41
+ primary: "oklch(0.299 0.119 267.96)",
42
+ secondary: "oklch(0.554 0.041 257.42)",
43
+ accent: "oklch(0.735 0.12 268.04)",
44
+ success: "oklch(0.5239 0.0917 180.004)",
45
+ warning: "oklch(0.5423 0.1066 70.504)",
46
+ danger: "oklch(0.561 0.202 26.71)",
47
+ info: "oklch(0.431 0.163 267.72)",
48
+ surface: "oklch(0.973 0.007 268.55)"
49
+ };
50
+ /** The tooltip lines come from the data (labels, formatted values) — never markup. */
51
+ function escapeHtml(s) {
52
+ return s.replace(/[&<>"']/g, (c) => ({
53
+ "&": "&amp;",
54
+ "<": "&lt;",
55
+ ">": "&gt;",
56
+ "\"": "&quot;",
57
+ "'": "&#39;"
58
+ })[c]);
59
+ }
60
+ /**
61
+ * Cached loader for the OPTIONAL `chart.js` peer.
62
+ *
63
+ * `chart.js/auto` self-registers every controller/scale/element — the right
64
+ * trade here because the library is externalized, so the consumer's bundler
65
+ * owns the cost and tree-shaking on our side would buy nothing.
66
+ */
67
+ let _chartPromise = null;
68
+ function loadChartJs() {
69
+ _chartPromise ??= import("chart.js/auto").then((m) => m?.default ?? m).catch((err) => {
70
+ _chartPromise = null;
71
+ throw new Error("[mono-chart] needs the optional peer dependency \"chart.js\". Install it in your app: pnpm add chart.js@4.5.1" + (err?.message ? ` (original error: ${err.message})` : ""));
72
+ });
73
+ return _chartPromise;
74
+ }
75
+ /**
76
+ * `MonoChartCore` — render-mode-agnostic logic for the chart elements.
77
+ *
78
+ * It owns the imperative Chart.js lifecycle, following the same shape as the
79
+ * flatpickr wrapper in `date-core.ts`: create in `firstUpdated` behind an
80
+ * `isServer` guard and a dynamic import, split `updated()` into a cheap data
81
+ * update vs a full rebuild, and destroy in `disconnectedCallback` BEFORE
82
+ * `super`. A `ResizeObserver` is added on top because, unlike flatpickr, a
83
+ * canvas needs to be told when its box changes.
84
+ */
85
+ const MonoChartCore = (superClass) => {
86
+ class MonoChartCoreClass extends superClass {
87
+ constructor(...args) {
88
+ super(...args);
89
+ this.aspectRatio = 2;
90
+ this.legend = true;
91
+ this.title = "";
92
+ this.stacked = false;
93
+ this.cssClass = {};
94
+ this.cssClassName = "";
95
+ this.loadingText = "Loading…";
96
+ this.retryLabel = "Retry";
97
+ this.loading = false;
98
+ this.loadingError = null;
99
+ this._appFailure = null;
100
+ this._error = "";
101
+ this._chart = null;
102
+ this._buildToken = 0;
103
+ this._onThemeChanged = () => {
104
+ if (isServer || !this._chart) return;
105
+ requestAnimationFrame(() => {
106
+ if (!this._chart) return;
107
+ const palette = this._colors;
108
+ if (palette?.length) this.dataChart?.setColors(palette);
109
+ else this.dataChart?._setColorResolver((c) => this._resolveColor(c));
110
+ this.rebuild();
111
+ });
112
+ };
113
+ this._applyQueued = false;
114
+ this._onRetry = (event) => {
115
+ event.stopPropagation();
116
+ const error = this._dsError;
117
+ if (!error) return;
118
+ const fromApp = !!this._appFailure;
119
+ dispatchMonoEvent(this, "retry", {
120
+ error,
121
+ source: fromApp ? "app" : "dataSource"
122
+ });
123
+ if (!fromApp) this.dataChart?.retry();
124
+ };
125
+ this._externalTooltip = (context) => {
126
+ const el = this._tooltipEl;
127
+ if (!el) return;
128
+ const tip = context.tooltip;
129
+ if (!tip || tip.opacity === 0) {
130
+ el.removeAttribute("data-open");
131
+ el.setAttribute("aria-hidden", "true");
132
+ return;
133
+ }
134
+ const title = tip.title ?? [];
135
+ const bodies = (tip.body ?? []).map((b) => b.lines ?? []);
136
+ const colors = tip.labelColors ?? [];
137
+ const parts = [];
138
+ for (const t of title) parts.push(`<div class="mono-chart-tooltip-title">${escapeHtml(String(t))}</div>`);
139
+ bodies.forEach((lines, i) => {
140
+ const swatch = colors[i]?.backgroundColor ?? colors[i]?.borderColor;
141
+ for (const line of lines) {
142
+ const m = /^(.*?):\s*(.+)$/.exec(String(line));
143
+ const text = m ? `<span class="mono-chart-tooltip-label">${escapeHtml(m[1])}</span><span class="mono-chart-tooltip-value">${escapeHtml(m[2])}</span>` : `<span class="mono-chart-tooltip-label">${escapeHtml(String(line))}</span>`;
144
+ parts.push(`<div class="mono-chart-tooltip-row">${swatch ? `<span class="mono-chart-tooltip-swatch" style="background:${escapeHtml(String(swatch))}"></span>` : ""}${text}</div>`);
145
+ }
146
+ });
147
+ el.innerHTML = parts.join("");
148
+ const width = el.parentElement?.clientWidth ?? context.chart.width;
149
+ const gap = 8;
150
+ el.setAttribute("data-open", "");
151
+ el.setAttribute("aria-hidden", "false");
152
+ const h = el.offsetHeight;
153
+ const w = el.offsetWidth;
154
+ const side = tip.caretY - h - gap < 0 ? "bottom" : "top";
155
+ el.setAttribute("data-side", side);
156
+ const x = Math.min(Math.max(tip.caretX, w / 2), Math.max(width - w / 2, w / 2));
157
+ el.style.left = `${x}px`;
158
+ el.style.top = `${tip.caretY}px`;
159
+ };
160
+ defineHybridPropAliases(this, [
161
+ "dataChart",
162
+ "chartOptions",
163
+ "aspectRatio",
164
+ "cssClass",
165
+ "loadingText",
166
+ "loadingError"
167
+ ]);
168
+ defineHybridPropAlias(this, "controlChart", "dataChart");
169
+ for (const alias of ["css-class", "cssclass"]) Object.defineProperty(this, alias, {
170
+ get: () => this.cssClass,
171
+ set: (value) => this._setCssClass(value),
172
+ configurable: true,
173
+ enumerable: false
174
+ });
175
+ }
176
+ static {
177
+ this.monoPendingAuto = "data";
178
+ }
179
+ _monoPendingReady() {
180
+ const ctrl = this.dataChart;
181
+ if (!ctrl) return this.data != null || monoPendingGrace(this);
182
+ if (ctrl.loading) return false;
183
+ return monoPendingGrace(this) || ctrl.data().datasets.length > 0;
184
+ }
185
+ static {
186
+ this._rebuildKeys = [
187
+ "type",
188
+ "chartOptions",
189
+ "legend",
190
+ "title",
191
+ "stacked",
192
+ "aspectRatio"
193
+ ];
194
+ }
195
+ static get observedAttributes() {
196
+ return [
197
+ ...super.observedAttributes ?? [],
198
+ "aspectratio",
199
+ "chartoptions",
200
+ "css-class",
201
+ "cssclass",
202
+ "colors"
203
+ ];
204
+ }
205
+ attributeChangedCallback(name, old, value) {
206
+ super.attributeChangedCallback(name, old, value);
207
+ if (old === value) return;
208
+ if (name === "css-class" || name === "cssclass") this._setCssClass(value);
209
+ else if (name === "colors") this.colors = value ?? void 0;
210
+ }
211
+ _setCssClass(value) {
212
+ if (value == null) {
213
+ this.cssClass = {};
214
+ this.cssClassName = "";
215
+ return;
216
+ }
217
+ if (typeof value === "object") {
218
+ this.cssClass = value;
219
+ return;
220
+ }
221
+ const trimmed = String(value).trim();
222
+ if (!trimmed) {
223
+ this.cssClass = {};
224
+ this.cssClassName = "";
225
+ return;
226
+ }
227
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) try {
228
+ this.cssClass = JSON.parse(trimmed);
229
+ return;
230
+ } catch {}
231
+ this.cssClassName = trimmed;
232
+ }
233
+ /** The live chart.js instance, or null before it mounts. */
234
+ get chart() {
235
+ return this._chart;
236
+ }
237
+ connectedCallback() {
238
+ super.connectedCallback();
239
+ this._subscribe();
240
+ if (!isServer) {
241
+ window.addEventListener("theme-changed", this._onThemeChanged);
242
+ this._watchMode();
243
+ }
244
+ }
245
+ disconnectedCallback() {
246
+ this._off?.();
247
+ this._off = void 0;
248
+ if (!isServer) {
249
+ window.removeEventListener("theme-changed", this._onThemeChanged);
250
+ this._modeObserver?.disconnect();
251
+ this._modeObserver = void 0;
252
+ this._modeQuery?.removeEventListener("change", this._onThemeChanged);
253
+ this._modeQuery = void 0;
254
+ }
255
+ this._destroyChart();
256
+ super.disconnectedCallback();
257
+ }
258
+ /**
259
+ * Dark mode is the same tokens flipped by the `.dark` class on `<html>` /
260
+ * `<body>` (or the OS, under `color-scheme: system`) — and nothing fires
261
+ * `theme-changed` for that: VitePress's appearance toggle and a consumer's
262
+ * own switch just swap the class. Watch the class and the media query and
263
+ * treat a flip exactly like a theme change.
264
+ */
265
+ _watchMode() {
266
+ if (typeof MutationObserver === "undefined") return;
267
+ let dark = document.documentElement.classList.contains("dark") || document.body?.classList.contains("dark");
268
+ this._modeObserver = new MutationObserver(() => {
269
+ const next = document.documentElement.classList.contains("dark") || document.body?.classList.contains("dark");
270
+ if (next === dark) return;
271
+ dark = next;
272
+ this._onThemeChanged();
273
+ });
274
+ this._modeObserver.observe(document.documentElement, {
275
+ attributes: true,
276
+ attributeFilter: ["class"]
277
+ });
278
+ if (document.body) this._modeObserver.observe(document.body, {
279
+ attributes: true,
280
+ attributeFilter: ["class"]
281
+ });
282
+ this._modeQuery = window.matchMedia?.("(prefers-color-scheme: dark)");
283
+ this._modeQuery?.addEventListener?.("change", this._onThemeChanged);
284
+ }
285
+ willUpdate(changed) {
286
+ if (changed.has("loadingError")) {
287
+ const v = this.loadingError;
288
+ this._appFailure = v == null || v === false || v === "" ? null : describeError(v === true ? void 0 : v);
289
+ }
290
+ super.willUpdate?.(changed);
291
+ if (changed.has("dataChart")) this._subscribe();
292
+ }
293
+ _subscribe() {
294
+ this._off?.();
295
+ detachEventHandlers(this);
296
+ this._off = this.dataChart?.subscribe(() => {
297
+ this._scheduleApplyProps();
298
+ this.requestUpdate();
299
+ });
300
+ if (!isServer) this.dataChart?._setColorResolver((c) => this._resolveColor(c));
301
+ this._scheduleApplyProps();
302
+ }
303
+ /**
304
+ * Drive the apply from `update()` as well as `_subscribe()` — every render
305
+ * reaches here, so a controller that arrives late (or a `setProps` between
306
+ * subscriptions) can't be missed. Same arrangement as
307
+ * `table-controller-core`, which documents why `_subscribe` alone is fragile.
308
+ */
309
+ update(changed) {
310
+ this._scheduleApplyProps();
311
+ super.update(changed);
312
+ }
313
+ /**
314
+ * Deferred + de-duplicated: the apply writes reactive props, and doing that
315
+ * inside the update cycle would trip Lit's change-in-update warning.
316
+ */
317
+ _scheduleApplyProps() {
318
+ if (isServer) return;
319
+ if (this._applyQueued) return;
320
+ if (typeof queueMicrotask !== "function") {
321
+ this._applyControllerProps();
322
+ return;
323
+ }
324
+ this._applyQueued = true;
325
+ queueMicrotask(() => {
326
+ this._applyQueued = false;
327
+ this._applyControllerProps();
328
+ });
329
+ }
330
+ /**
331
+ * Pull `controlMonoChart({ props })` onto this element, so the template needs
332
+ * nothing but the controller binding.
333
+ *
334
+ * The CONTROLLER WINS for keys it declares (matching `controlMonoTable` and
335
+ * `controlMonoForm`); keys it doesn't mention are left to whatever the
336
+ * template set. `applyProps` supplies the skip-undefined, read-only and
337
+ * equality guards. `?.props` is optional-called so a controller built before
338
+ * this option existed simply contributes nothing.
339
+ */
340
+ _applyControllerProps() {
341
+ applyProps(this, this.dataChart?.props?.());
342
+ }
343
+ /**
344
+ * Effective type. A preset's locked type wins (a `<mono-chart-pie>` is a pie),
345
+ * then an explicit element `type`, then the controller's, then `'bar'`.
346
+ */
347
+ get _type() {
348
+ return this._presetType ?? this.type ?? this.dataChart?.type ?? "bar";
349
+ }
350
+ /** Effective data: the element's raw `data` wins, else the controller's. */
351
+ get _data() {
352
+ return this.data ?? this.dataChart?.data() ?? {
353
+ labels: [],
354
+ datasets: []
355
+ };
356
+ }
357
+ get _loading() {
358
+ return !!this.dataChart?.loading;
359
+ }
360
+ /** The FIRST load (or a retry) is in flight — nothing to show yet, so a spinner. */
361
+ get _dsBusy() {
362
+ if (this.loading) return true;
363
+ const c = this.dataChart;
364
+ return !this.data && !!c && c.loading && !c.hasLoaded && !c.error;
365
+ }
366
+ /** The app's `loading-error`, else the controller's failed load (the peer-load `_error` is separate). */
367
+ get _dsError() {
368
+ if (this.loading) return null;
369
+ return this._appFailure ?? (this.data ? null : this.dataChart?.error ?? null);
370
+ }
371
+ /** Spinner over the first load; the failure + ↻ after one failed. */
372
+ _renderSourceState() {
373
+ const err = this._dsError;
374
+ if (err) return html`
375
+ <div class="mono-chart-state" mono-ds-state="error" role="alert">
376
+ <span class="mono-chart-state-text" title=${errorTitle(err)}>${errorText(err)}</span>
377
+ <button
378
+ type="button"
379
+ mono-ds-retry
380
+ aria-label=${this.retryLabel}
381
+ title=${this.retryLabel}
382
+ @click=${this._onRetry}
383
+ >
384
+ ${refreshIcon()}
385
+ </button>
386
+ </div>
387
+ `;
388
+ if (this._dsBusy) return html`
389
+ <div class="mono-chart-state" mono-ds-state="loading" role="status">
390
+ <span mono-ds-spinner>${spinnerIcon()}</span>
391
+ <span class="mono-chart-state-text">${this.loadingText}</span>
392
+ </div>
393
+ `;
394
+ return nothing;
395
+ }
396
+ get _empty() {
397
+ const d = this._data;
398
+ return !d.datasets?.length || d.datasets.every((s) => !s.data?.length);
399
+ }
400
+ /** Palette from the `colors` prop, as an array. */
401
+ /** The raw `colors` prop as a list, before name resolution. */
402
+ get _colorList() {
403
+ const c = this.colors;
404
+ if (!c) return null;
405
+ if (Array.isArray(c)) return c.filter(Boolean);
406
+ return String(c).split(",").map((s) => s.trim()).filter(Boolean);
407
+ }
408
+ /**
409
+ * The palette handed to Chart.js: the `colors` list if given, else the single
410
+ * `color` accent, else null (the controller keeps its own default).
411
+ * Mono color NAMES are resolved to real values here — see `_resolveColor`.
412
+ */
413
+ get _colors() {
414
+ const list = this._colorList ?? (this.color ? [this.color] : null);
415
+ if (!list?.length) return null;
416
+ return list.map((c) => this._resolveColor(c));
417
+ }
418
+ /**
419
+ * The element's own computed style scope.
420
+ *
421
+ * Read from the inner `.mono-chart` wrapper, not the host: in the shadow
422
+ * build the custom properties are declared inside the shadow root, so the
423
+ * host would return empty strings.
424
+ */
425
+ _styleScope() {
426
+ if (isServer) return null;
427
+ return this.renderRoot?.querySelector?.(".mono-chart") ?? this;
428
+ }
429
+ /**
430
+ * Turn a mono color NAME into the value the canvas needs.
431
+ *
432
+ * Chart.js paints onto a bitmap and never resolves `var()`, so `success` (or
433
+ * a literal `var(--x)`) would render as transparent. Names map to the
434
+ * component's `--_mono-chart-*` resolvers, which chain through the public
435
+ * `--mono-chart-*` overrides down to the Basecoat tokens — so a consumer
436
+ * who re-themes the app gets re-themed charts for free. Anything that isn't
437
+ * a known name (a hex, `rgb()`, `hsl()`) is passed through untouched.
438
+ */
439
+ _resolveColor(value) {
440
+ const name = value.trim();
441
+ if (!MONO_COLOR_NAMES.has(name)) return name;
442
+ const scope = this._styleScope();
443
+ if (!scope) return MONO_COLOR_FALLBACK[name] ?? name;
444
+ const prop = name.startsWith("chart-") ? `--_mono-chart-${name.slice(6)}` : `--_mono-chart-${name}`;
445
+ return getComputedStyle(scope).getPropertyValue(prop).trim() || MONO_COLOR_FALLBACK[name] || name;
446
+ }
447
+ /**
448
+ * The inks and type Chart.js paints the chrome with — read off the element's
449
+ * own box, where chart.css resolved them from the Basecoat tokens: legend
450
+ * and title in `--foreground`, ticks in `--muted-foreground`, the grid in
451
+ * `--border`, the tooltip as a popover, the page font at text-xs.
452
+ */
453
+ _themeColors() {
454
+ const fallback = {
455
+ text: "oklch(0.372 0.039 257.29)",
456
+ muted: "oklch(0.554 0.041 257.42)",
457
+ grid: "oklch(0.929 0.013 255.51)",
458
+ tooltipBg: "oklch(1 0 0)",
459
+ tooltipColor: "oklch(0.372 0.039 257.29)",
460
+ tooltipBorder: "oklch(0.929 0.013 255.51)",
461
+ fontFamily: "ui-sans-serif, system-ui, sans-serif",
462
+ fontSize: 12,
463
+ radius: 8,
464
+ barRadius: 8
465
+ };
466
+ const scope = this._styleScope();
467
+ if (!scope) return fallback;
468
+ const cs = getComputedStyle(scope);
469
+ const read = (name, fb) => cs.getPropertyValue(name).trim() || fb;
470
+ const px = (v, fb, min = 1) => {
471
+ const n = parseFloat(v);
472
+ return Number.isFinite(n) && n >= min ? n : fb;
473
+ };
474
+ return {
475
+ text: read("--_mono-chart-text", fallback.text),
476
+ muted: read("--_mono-chart-muted", fallback.muted),
477
+ grid: read("--_mono-chart-grid", fallback.grid),
478
+ tooltipBg: read("--_mono-chart-tooltip-bg", fallback.tooltipBg),
479
+ tooltipColor: read("--_mono-chart-tooltip-color", fallback.tooltipColor),
480
+ tooltipBorder: read("--_mono-chart-tooltip-border", fallback.tooltipBorder),
481
+ fontFamily: cs.fontFamily || fallback.fontFamily,
482
+ fontSize: px(cs.fontSize, fallback.fontSize),
483
+ radius: px(cs.borderTopLeftRadius, fallback.radius, 0),
484
+ barRadius: px(getComputedStyle(this.renderRoot?.querySelector?.(".mono-chart-canvas-wrap") ?? scope).borderTopLeftRadius, fallback.barRadius, 0)
485
+ };
486
+ }
487
+ /** Merge the element's presentational props with the consumer's raw options. */
488
+ _buildOptions() {
489
+ const theme = this._themeColors();
490
+ const legendOn = this.legend !== false && this.legend !== "false";
491
+ const legendPos = typeof this.legend === "string" && this.legend !== "true" ? this.legend : "top";
492
+ const scaled = this._type !== "pie" && this._type !== "doughnut" && this._type !== "polarArea";
493
+ const base = {
494
+ responsive: true,
495
+ maintainAspectRatio: !this.height,
496
+ aspectRatio: this.aspectRatio,
497
+ font: {
498
+ family: theme.fontFamily,
499
+ size: theme.fontSize
500
+ },
501
+ color: theme.text,
502
+ plugins: {
503
+ legend: {
504
+ display: legendOn,
505
+ position: legendPos,
506
+ labels: {
507
+ color: theme.text,
508
+ font: {
509
+ family: theme.fontFamily,
510
+ size: theme.fontSize
511
+ },
512
+ boxWidth: theme.fontSize,
513
+ boxHeight: theme.fontSize,
514
+ useBorderRadius: true,
515
+ borderRadius: Math.round(theme.fontSize / 4)
516
+ }
517
+ },
518
+ title: this.title ? {
519
+ display: true,
520
+ text: this.title,
521
+ color: theme.text,
522
+ font: {
523
+ family: theme.fontFamily,
524
+ size: theme.fontSize + 2,
525
+ weight: 500
526
+ }
527
+ } : { display: false },
528
+ tooltip: {
529
+ enabled: false,
530
+ external: this._externalTooltip,
531
+ backgroundColor: theme.tooltipBg,
532
+ titleColor: theme.tooltipColor,
533
+ bodyColor: theme.tooltipColor,
534
+ borderColor: theme.tooltipBorder,
535
+ borderWidth: 1,
536
+ cornerRadius: theme.radius,
537
+ padding: {
538
+ x: 12,
539
+ y: 6
540
+ },
541
+ titleFont: {
542
+ family: theme.fontFamily,
543
+ size: theme.fontSize,
544
+ weight: 500
545
+ },
546
+ bodyFont: {
547
+ family: theme.fontFamily,
548
+ size: theme.fontSize
549
+ },
550
+ boxPadding: 4,
551
+ usePointStyle: true
552
+ }
553
+ },
554
+ onClick: (_e, els) => {
555
+ const hit = els?.[0];
556
+ if (!hit) return;
557
+ this.dataChart?._emitPoint?.(hit.datasetIndex, hit.index);
558
+ }
559
+ };
560
+ if (scaled) {
561
+ base.elements = { bar: { borderRadius: theme.barRadius } };
562
+ base.interaction = {
563
+ mode: "index",
564
+ intersect: false
565
+ };
566
+ base.scales = {
567
+ x: {
568
+ stacked: this.stacked,
569
+ ticks: {
570
+ color: theme.muted,
571
+ font: {
572
+ family: theme.fontFamily,
573
+ size: theme.fontSize
574
+ }
575
+ },
576
+ grid: { color: theme.grid },
577
+ border: { color: theme.grid }
578
+ },
579
+ y: {
580
+ stacked: this.stacked,
581
+ ticks: {
582
+ color: theme.muted,
583
+ font: {
584
+ family: theme.fontFamily,
585
+ size: theme.fontSize
586
+ }
587
+ },
588
+ grid: { color: theme.grid },
589
+ border: { color: theme.grid }
590
+ }
591
+ };
592
+ }
593
+ return deepMerge(deepMerge(base, this.dataChart?.options() ?? {}), this.chartOptions ?? {});
594
+ }
595
+ async firstUpdated(changed) {
596
+ super.firstUpdated?.(changed);
597
+ if (isServer) return;
598
+ this.dataChart?._setColorResolver((c) => this._resolveColor(c));
599
+ const palette = this._colors;
600
+ if (palette?.length) this.dataChart?.setColors(palette);
601
+ this._syncTypeToController();
602
+ await this._createChart();
603
+ }
604
+ updated(changed) {
605
+ super.updated?.(changed);
606
+ if (isServer) return;
607
+ if (changed.has("colors") || changed.has("color")) {
608
+ const palette = this._colors;
609
+ if (palette?.length) this.dataChart?.setColors(palette);
610
+ }
611
+ this._syncTypeToController();
612
+ if (!this._chart) {
613
+ if (!this._error && !this._empty) this._createChart();
614
+ return;
615
+ }
616
+ if (MonoChartCoreClass._rebuildKeys.some((k) => changed.has(k))) {
617
+ this.rebuild();
618
+ return;
619
+ }
620
+ if (this._chart.config?.type !== this._type) {
621
+ this.rebuild();
622
+ return;
623
+ }
624
+ this._applyData();
625
+ }
626
+ /**
627
+ * Tell the controller which type actually won.
628
+ *
629
+ * The projection depends on it: pie-family charts colour every SLICE, bar
630
+ * and line colour each DATASET. A preset (`<mono-chart-pie>`) fixes its type
631
+ * on the element, so without this the controller would still think it was
632
+ * projecting for the default `bar` and every slice would come out the same
633
+ * colour. `setType` early-returns when unchanged, so this settles in one
634
+ * extra update rather than looping.
635
+ *
636
+ * NOTE: the type is controller state, so pointing a bar element and a pie
637
+ * element at ONE shared controller makes them fight — give each its own.
638
+ */
639
+ _syncTypeToController() {
640
+ const grid = this.dataChart;
641
+ if (grid && grid.type !== this._type) grid.setType(this._type);
642
+ }
643
+ async _createChart() {
644
+ if (isServer || this._chart) return;
645
+ if (!this._canvas) return;
646
+ const token = ++this._buildToken;
647
+ let Chart;
648
+ try {
649
+ Chart = await loadChartJs();
650
+ } catch (err) {
651
+ this._error = err?.message ?? String(err);
652
+ return;
653
+ }
654
+ if (token !== this._buildToken || !this.isConnected || !this._canvas) return;
655
+ try {
656
+ this._chart = new Chart(this._canvas, {
657
+ type: this._type,
658
+ data: this._cloneData(),
659
+ options: this._buildOptions()
660
+ });
661
+ this._error = "";
662
+ this.dataChart?._attachInstance(this._chart);
663
+ this._observeResize();
664
+ } catch (err) {
665
+ this._error = err?.message ?? String(err);
666
+ }
667
+ }
668
+ /**
669
+ * Hand chart.js its own copy. It mutates `data` in place (adding computed
670
+ * metadata), so sharing the controller's projected object would corrupt it.
671
+ */
672
+ _cloneData() {
673
+ const d = this._data;
674
+ return {
675
+ labels: [...d.labels ?? []],
676
+ datasets: (d.datasets ?? []).map((s) => ({
677
+ ...s,
678
+ data: [...s.data ?? []]
679
+ }))
680
+ };
681
+ }
682
+ _applyData() {
683
+ if (!this._chart) return;
684
+ const next = this._cloneData();
685
+ this._chart.data.labels = next.labels;
686
+ this._chart.data.datasets = next.datasets;
687
+ this._chart.update();
688
+ }
689
+ /** Destroy + recreate. Needed for `type` and structural option changes. */
690
+ rebuild() {
691
+ if (isServer) return;
692
+ this._destroyChart();
693
+ this._createChart();
694
+ }
695
+ _destroyChart() {
696
+ this._buildToken++;
697
+ this._ro?.disconnect();
698
+ this._ro = void 0;
699
+ try {
700
+ this._chart?.destroy();
701
+ } catch {}
702
+ this._chart = null;
703
+ this.dataChart?._attachInstance(null);
704
+ this._tooltipEl?.removeAttribute("data-open");
705
+ }
706
+ /**
707
+ * Chart.js `responsive` already listens for window resizes, but not for a
708
+ * container that changes size on its own (a sidebar opening, a flex reflow).
709
+ */
710
+ _observeResize() {
711
+ if (this._ro || typeof ResizeObserver === "undefined") return;
712
+ const wrap = this.renderRoot?.querySelector?.(".mono-chart-canvas-wrap");
713
+ if (!wrap) return;
714
+ this._ro = new ResizeObserver(() => this._chart?.resize());
715
+ this._ro.observe(wrap);
716
+ }
717
+ _cls(base, key) {
718
+ const extra = this.cssClass?.[key];
719
+ return extra ? `${base} ${extra}` : base;
720
+ }
721
+ get _rootClasses() {
722
+ return [
723
+ "mono-chart",
724
+ this._loading ? "loading" : "",
725
+ this.cssClassName,
726
+ this.cssClass?.root
727
+ ].filter(Boolean).join(" ");
728
+ }
729
+ _wrapStyle() {
730
+ const s = {};
731
+ const w = toCssSize(this.width);
732
+ const h = toCssSize(this.height);
733
+ if (w) s.width = w;
734
+ if (h) s.height = h;
735
+ return s;
736
+ }
737
+ renderChart() {
738
+ return html`
739
+ <div
740
+ class=${this._rootClasses}
741
+ ?mono-ds-loading=${this._dsBusy}
742
+ ?mono-ds-error=${!!this._dsError}
743
+ aria-busy=${this._dsBusy ? "true" : nothing}
744
+ >
745
+ ${this._error ? html`<div class=${this._cls("mono-chart-message error", "message")} role="alert">
746
+ ${this._error}
747
+ </div>` : nothing}
748
+ <div class="mono-chart-canvas-wrap" style=${styleMap(this._wrapStyle())}>
749
+ <canvas class=${this._cls("", "canvas")} role="img"></canvas>
750
+ <div class="mono-chart-tooltip" role="tooltip" aria-hidden="true"></div>
751
+ ${this._renderSourceState()}
752
+ </div>
753
+ </div>
754
+ `;
755
+ }
756
+ }
757
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "dataChart", void 0);
758
+ __decorate([property({ type: String })], MonoChartCoreClass.prototype, "type", void 0);
759
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "data", void 0);
760
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "chartOptions", void 0);
761
+ __decorate([property({ type: String })], MonoChartCoreClass.prototype, "width", void 0);
762
+ __decorate([property({ type: String })], MonoChartCoreClass.prototype, "height", void 0);
763
+ __decorate([property({
764
+ attribute: "aspect-ratio",
765
+ converter: numberStringConverter
766
+ })], MonoChartCoreClass.prototype, "aspectRatio", void 0);
767
+ __decorate([property()], MonoChartCoreClass.prototype, "legend", void 0);
768
+ __decorate([property({ type: String })], MonoChartCoreClass.prototype, "title", void 0);
769
+ __decorate([property({ converter: booleanStringConverter })], MonoChartCoreClass.prototype, "stacked", void 0);
770
+ __decorate([property({ type: String })], MonoChartCoreClass.prototype, "color", void 0);
771
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "colors", void 0);
772
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "cssClass", void 0);
773
+ __decorate([property({ attribute: false })], MonoChartCoreClass.prototype, "cssClassName", void 0);
774
+ __decorate([property({
775
+ type: String,
776
+ attribute: "loading-text"
777
+ })], MonoChartCoreClass.prototype, "loadingText", void 0);
778
+ __decorate([property({
779
+ type: String,
780
+ attribute: "retry-label"
781
+ })], MonoChartCoreClass.prototype, "retryLabel", void 0);
782
+ __decorate([property({ converter: booleanStringConverter })], MonoChartCoreClass.prototype, "loading", void 0);
783
+ __decorate([property({ attribute: "loading-error" })], MonoChartCoreClass.prototype, "loadingError", void 0);
784
+ __decorate([state()], MonoChartCoreClass.prototype, "_error", void 0);
785
+ __decorate([query("canvas")], MonoChartCoreClass.prototype, "_canvas", void 0);
786
+ __decorate([query(".mono-chart-tooltip")], MonoChartCoreClass.prototype, "_tooltipEl", void 0);
787
+ return MonoChartCoreClass;
788
+ };
789
+ /** Shallow-recursive merge; arrays and non-plain values are replaced wholesale. */
790
+ function deepMerge(base, over) {
791
+ const out = { ...base };
792
+ for (const [k, v] of Object.entries(over)) {
793
+ const prev = out[k];
794
+ if (v && typeof v === "object" && !Array.isArray(v) && prev && typeof prev === "object" && !Array.isArray(prev)) out[k] = deepMerge(prev, v);
795
+ else out[k] = v;
796
+ }
797
+ return out;
798
+ }
799
+
800
+ //#endregion
801
+ export { loadChartJs as n, MonoChartCore as t };