@mono-lit/helper 0.0.9 → 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 (164) 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-DTqDBca7.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-B2iRpJuI.js → mono-data-dropdown-Bgj2PDfm.js} +1 -1
  38. package/dist/{mono-data-grid-llJCX9MC.js → mono-data-grid-DJkp96N-.js} +144 -46
  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/nuxt.js +1 -1
  45. package/dist/otp-core-DXg3vFLh.js +758 -0
  46. package/dist/radio-utils-Dk9Tl1jz.js +319 -0
  47. package/dist/rich-text-editor-core-Ddd_QaLn.js +1280 -0
  48. package/dist/select-utils-BgArYHk8.js +2140 -0
  49. package/dist/sidebar-core-CD6txDo3.js +583 -0
  50. package/dist/slider-core-vcWr321-.js +1014 -0
  51. package/dist/src/components/dropdown-table/dropdown-table-core.d.ts +2 -2
  52. package/dist/src/components/dropdown-table/dropdown-table-types.d.ts +1 -1
  53. package/dist/src/components/dropdown-table/index.d.ts +1 -1
  54. package/dist/src/components/dropdown-table/index.shadow.d.ts +1 -1
  55. package/dist/src/components/dropdown-table/mono-data-dropdown.d.ts +1 -1
  56. package/dist/src/components/form/form-types.d.ts +9 -3
  57. package/dist/src/components/input/input-core.d.ts +1 -1
  58. package/dist/src/components/input/input-types.d.ts +1 -1
  59. package/dist/src/components/otp/otp-core.d.ts +1 -1
  60. package/dist/src/components/select/select-core.d.ts +1 -1
  61. package/dist/src/components/select/select-types.d.ts +1 -1
  62. package/dist/src/components/slider/slider-core.d.ts +1 -1
  63. package/dist/src/components/slider/slider-types.d.ts +1 -1
  64. package/dist/src/components/table/filter-suggestion.d.ts +171 -0
  65. package/dist/src/components/table/index.d.ts +5 -4
  66. package/dist/src/components/table/index.shadow.d.ts +5 -4
  67. package/dist/src/components/table/mono-data-grid.d.ts +22 -3
  68. package/dist/src/components/table/mono-table-empty-core.d.ts +37 -0
  69. package/dist/src/components/table/mono-table-search-core.d.ts +22 -3
  70. package/dist/src/components/table/table-types.d.ts +74 -4
  71. package/dist/src/components/tag-input/tag-input-core.d.ts +1 -1
  72. package/dist/src/components/tag-input/tag-input-types.d.ts +1 -1
  73. package/dist/src/components/textarea/textarea-core.d.ts +1 -1
  74. package/dist/src/composables/mono-event.d.ts +7 -1
  75. package/dist/src/entries/index.d.ts +8 -6
  76. package/dist/src/entries/index.node.d.ts +8 -6
  77. package/dist/src/search/index.d.ts +1 -1
  78. package/dist/src/utils/group-count.d.ts +36 -0
  79. package/dist/switch-utils-CTZ4id2V.js +338 -0
  80. package/dist/tabs-core-r5-B8k_N.js +317 -0
  81. package/dist/tag-input-utils-D2JA90DQ.js +3060 -0
  82. package/dist/textarea-utils-VU1KeXm8.js +821 -0
  83. package/dist/ui/accordion.js +2 -274
  84. package/dist/ui/alert.js +2 -131
  85. package/dist/ui/breadcrumb.js +4 -745
  86. package/dist/ui/button-dropdown.js +4 -652
  87. package/dist/ui/button.js +2 -63
  88. package/dist/ui/card.js +2 -310
  89. package/dist/ui/chart.js +4 -800
  90. package/dist/ui/checkbox.js +4 -335
  91. package/dist/ui/chip.js +4 -402
  92. package/dist/ui/date.js +3 -732
  93. package/dist/ui/drawer.js +3 -757
  94. package/dist/ui/dropdown-table.js +5 -1341
  95. package/dist/ui/dropdown.js +4 -509
  96. package/dist/ui/file-upload.js +3 -622
  97. package/dist/ui/filter.js +5 -380
  98. package/dist/ui/form.js +1 -1
  99. package/dist/ui/index.css +118 -1
  100. package/dist/ui/input.js +3 -1141
  101. package/dist/ui/menu.js +4 -828
  102. package/dist/ui/modal.js +4 -843
  103. package/dist/ui/nav.js +4 -223
  104. package/dist/ui/otp.js +4 -756
  105. package/dist/ui/radio.js +4 -317
  106. package/dist/ui/rich-text-editor.js +4 -1278
  107. package/dist/ui/select.js +5 -2138
  108. package/dist/ui/shadow/accordion.js +4 -273
  109. package/dist/ui/shadow/alert.js +4 -130
  110. package/dist/ui/shadow/breadcrumb.js +5 -744
  111. package/dist/ui/shadow/button-dropdown.js +6 -652
  112. package/dist/ui/shadow/button.js +3 -63
  113. package/dist/ui/shadow/card.js +4 -309
  114. package/dist/ui/shadow/chart.js +6 -1576
  115. package/dist/ui/shadow/checkbox.js +4 -334
  116. package/dist/ui/shadow/chip.js +4 -396
  117. package/dist/ui/shadow/date.js +7 -731
  118. package/dist/ui/shadow/drawer.js +4 -756
  119. package/dist/ui/shadow/dropdown-table.js +8 -1762
  120. package/dist/ui/shadow/dropdown.js +4 -508
  121. package/dist/ui/shadow/file-upload.js +4 -620
  122. package/dist/ui/shadow/filter.js +7 -379
  123. package/dist/ui/shadow/input.js +6 -1140
  124. package/dist/ui/shadow/menu.js +5 -828
  125. package/dist/ui/shadow/modal.js +6 -1063
  126. package/dist/ui/shadow/nav.js +5 -223
  127. package/dist/ui/shadow/otp.js +6 -754
  128. package/dist/ui/shadow/radio.js +4 -316
  129. package/dist/ui/shadow/rich-text-editor.js +4 -1276
  130. package/dist/ui/shadow/select.js +6 -2136
  131. package/dist/ui/shadow/sidebar.js +5 -581
  132. package/dist/ui/shadow/slider.js +5 -1010
  133. package/dist/ui/shadow/switch.js +4 -335
  134. package/dist/ui/shadow/table.js +10 -4501
  135. package/dist/ui/shadow/tabs.js +6 -315
  136. package/dist/ui/shadow/tag-input.js +7 -3057
  137. package/dist/ui/shadow/textarea.js +6 -817
  138. package/dist/ui/sidebar.js +3 -581
  139. package/dist/ui/slider.js +4 -1012
  140. package/dist/ui/switch.js +4 -336
  141. package/dist/ui/table.js +9 -4502
  142. package/dist/ui/tabs.js +4 -315
  143. package/dist/ui/tag-input.js +5 -3058
  144. package/dist/ui/textarea.js +4 -819
  145. package/dist/{vite-CivRCJaf.js → vite-CfW7z2wn.js} +21 -14
  146. package/dist/vite.js +1 -1
  147. package/dist/vue.d.ts +3 -2
  148. package/package.json +10 -11
  149. package/dist/chip-strip-bNfLn52Z.js +0 -215
  150. package/dist/data-source-controller-Dx6IQ2CN.js +0 -243
  151. package/dist/data-source-options-BM4r4PRw.js +0 -558
  152. package/dist/data-source-read-HyBCRg1t.js +0 -242
  153. package/dist/excel-BXzr3uI1.js +0 -784
  154. package/dist/export-ixRdCS2y.js +0 -2388
  155. package/dist/field-tooltip-addon-CWCp19mJ.js +0 -702
  156. package/dist/field-tooltip.css_raw-U5UeTa2d.js +0 -269
  157. package/dist/filter-builder-C0T3pMx2.js +0 -208
  158. package/dist/form-control-core-BbiACMtL.js +0 -226
  159. package/dist/icon-ClxnYhBG.js +0 -19
  160. package/dist/import-Dc4eXC02.js +0 -612
  161. package/dist/light-slots-_no0r2Z-.js +0 -246
  162. package/dist/markdown-uGlE_OfJ.js +0 -20191
  163. package/dist/mono-data-grid-e9ZVBlNN.js +0 -4240
  164. package/dist/normalize-error-BmLbgANw.js +0 -1048
@@ -1,702 +0,0 @@
1
- import { i as registerPopupLayer, o as unregisterPopupLayer } from "./popup-stack-C64WCuXq.js";
2
- import { n as unwrapReactive, t as resolveMaybeReactive } from "./reactive-Dtd-esHO.js";
3
-
4
- //#region src/components/tooltip/tooltip-config.ts
5
- const DEFAULT_TOOLTIP_OPTIONS = {
6
- allowHTML: false,
7
- placement: "top",
8
- offset: 6,
9
- padding: 8,
10
- flip: true,
11
- shift: true,
12
- arrow: true,
13
- trigger: ["hover", "focus"],
14
- delay: [100, 0],
15
- interactive: false,
16
- variant: "inverted",
17
- size: "md",
18
- disabled: false,
19
- hideOnClick: true
20
- };
21
- let globalOptions = null;
22
- /** Keys of the global object that configure the addon, not a tooltip. */
23
- const NOT_TOOLTIP_OPTIONS = /* @__PURE__ */ new Set(["attributes"]);
24
- /**
25
- * `DEFAULTS ← local ← global ← anchor`, key by key; `undefined` never
26
- * overwrites. `anchor` is the options read off the element's own attributes.
27
- */
28
- function resolveTooltipOptions(local, anchor) {
29
- const out = { ...DEFAULT_TOOLTIP_OPTIONS };
30
- for (const layer of [
31
- local,
32
- globalOptions,
33
- anchor
34
- ]) {
35
- if (!layer) continue;
36
- for (const [key, value] of Object.entries(layer)) if (value !== void 0 && !NOT_TOOLTIP_OPTIONS.has(key)) out[key] = value;
37
- }
38
- return out;
39
- }
40
-
41
- //#endregion
42
- //#region src/components/tooltip/tooltip-loader.ts
43
- /**
44
- * Cached loader for the OPTIONAL `@floating-ui/dom` peer (which itself depends on
45
- * `@floating-ui/core` — both are the consumer's to install).
46
- *
47
- * Loaded on the FIRST show, never at import: registering a tooltip in
48
- * `<script setup>` costs nothing until somebody actually hovers. Externalized by
49
- * `NEVER_BUNDLE` in `tsdown.config.ts`, so the consumer's bundler resolves and splits it.
50
- */
51
- let _floatingPromise = null;
52
- function loadFloatingUi() {
53
- _floatingPromise ??= import("@floating-ui/dom").catch((err) => {
54
- _floatingPromise = null;
55
- throw new Error("[mono-tooltip] needs the optional peer dependencies \"@floating-ui/dom\" and \"@floating-ui/core\". Install them in your app: pnpm add @floating-ui/dom @floating-ui/core" + (err?.message ? ` (original error: ${err.message})` : ""));
56
- });
57
- return _floatingPromise;
58
- }
59
-
60
- //#endregion
61
- //#region src/components/tooltip/control-tooltip.ts
62
- /** Grace period so an INTERACTIVE tooltip can be reached across the offset gap. */
63
- const INTERACTIVE_HIDE_GRACE = 120;
64
- /** Longest the exit transition may take before the element is removed anyway. */
65
- const EXIT_FALLBACK_MS = 200;
66
- let nextId = 0;
67
- const live = /* @__PURE__ */ new Set();
68
- let bound = false;
69
- function each(fn) {
70
- for (const inst of Array.from(live)) fn(inst);
71
- }
72
- const onPointerOver = (e) => {
73
- const path = e.composedPath();
74
- each((i) => i._pointerOver(path, e));
75
- };
76
- const onPointerOut = (e) => {
77
- if (!e.relatedTarget) each((i) => i._pointerOver([], e));
78
- };
79
- const onFocusIn = (e) => {
80
- const path = e.composedPath();
81
- each((i) => i._focusIn(path));
82
- };
83
- const onFocusOut = (e) => {
84
- if (!e.relatedTarget) each((i) => i._focusIn([]));
85
- };
86
- const onClick = (e) => {
87
- const path = e.composedPath();
88
- each((i) => i._click(path));
89
- };
90
- /**
91
- * A REAL document. `typeof document` is not enough on the server: Lit's SSR DOM shim (loaded by
92
- * VitePress / Nuxt SSR through @mono-lit/helper's server entries) defines a global `document` stub with no
93
- * `addEventListener`, so a `typeof` guard passed and `createMonoTooltip()` in an app's setup threw
94
- * "document.addEventListener is not a function" during server render.
95
- */
96
- function hasLiveDocument() {
97
- return typeof document !== "undefined" && typeof document.addEventListener === "function";
98
- }
99
- function bindDocument() {
100
- if (bound || !hasLiveDocument()) return;
101
- document.addEventListener("pointerover", onPointerOver, true);
102
- document.addEventListener("pointerout", onPointerOut, true);
103
- document.addEventListener("focusin", onFocusIn, true);
104
- document.addEventListener("focusout", onFocusOut, true);
105
- document.addEventListener("click", onClick, true);
106
- bound = true;
107
- }
108
- function unbindDocument() {
109
- if (!bound || live.size > 0 || !hasLiveDocument()) return;
110
- document.removeEventListener("pointerover", onPointerOver, true);
111
- document.removeEventListener("pointerout", onPointerOut, true);
112
- document.removeEventListener("focusin", onFocusIn, true);
113
- document.removeEventListener("focusout", onFocusOut, true);
114
- document.removeEventListener("click", onClick, true);
115
- bound = false;
116
- }
117
- const warnedSelectors = /* @__PURE__ */ new Set();
118
- function safeMatches(el, selector) {
119
- try {
120
- return el.matches(selector);
121
- } catch {
122
- if (!warnedSelectors.has(selector)) {
123
- warnedSelectors.add(selector);
124
- console.warn(`[mono-tooltip] invalid selector: ${JSON.stringify(selector)}`);
125
- }
126
- return false;
127
- }
128
- }
129
- /** Every element a non-selector target names (refs / proxies unwrapped). */
130
- function toElements(value) {
131
- if (!value || typeof value === "string") return [];
132
- if (value instanceof Element) return [value];
133
- const out = [];
134
- const list = typeof value[Symbol.iterator] === "function" ? Array.from(value) : Array.from(value);
135
- for (const item of list) {
136
- const raw = unwrapReactive(item);
137
- const el = raw instanceof Element ? raw : raw?.$el;
138
- if (el instanceof Element) out.push(el);
139
- }
140
- return out;
141
- }
142
- function unwrapTarget(target) {
143
- const value = resolveMaybeReactive(target);
144
- if (value && !(value instanceof Element) && typeof value === "object" && value.$el instanceof Element) return value.$el;
145
- return value;
146
- }
147
- /** Composed-tree parent — crosses shadow boundaries (cf. `popup-portal.ts`). */
148
- function flatTreeParent(node) {
149
- const slot = node.assignedSlot;
150
- if (slot) return slot;
151
- const parent = node.parentNode;
152
- if (parent instanceof ShadowRoot) return parent.host;
153
- return parent;
154
- }
155
- /**
156
- * The theme classes of the NEAREST scoped theme wrapper above the anchor.
157
- *
158
- * The tooltip lives on `<body>`, so it already inherits the page-level theme
159
- * (`applyTheme` writes to body). A section themed on its own — `<div class="mono-theme
160
- * dark theme-color-rose">` — is not in its inheritance chain any more; copying that
161
- * wrapper's theme classes onto the tooltip re-resolves the same tokens there.
162
- */
163
- function scopedThemeClasses(anchor) {
164
- const stop = /* @__PURE__ */ new Set([
165
- document.body,
166
- document.documentElement,
167
- null
168
- ]);
169
- for (let n = anchor; !stop.has(n); n = flatTreeParent(n)) {
170
- if (!(n instanceof Element)) continue;
171
- const found = Array.from(n.classList).filter((c) => c === "mono-theme" || c === "dark" || c === "light" || c.startsWith("theme-"));
172
- if (found.length) return found;
173
- }
174
- return [];
175
- }
176
- function isFocusVisible(el) {
177
- if (!(el instanceof Element)) return false;
178
- try {
179
- return el.matches(":focus-visible");
180
- } catch {
181
- return true;
182
- }
183
- }
184
- /** The bubble's four computed corner radii — read once per open, BEFORE any cap lands. */
185
- function readCorners(bubble) {
186
- const cs = getComputedStyle(bubble);
187
- return [
188
- cs.borderTopLeftRadius,
189
- cs.borderTopRightRadius,
190
- cs.borderBottomRightRadius,
191
- cs.borderBottomLeftRadius
192
- ];
193
- }
194
- /**
195
- * Where the arrow may sit on the edge of `side`, and whether the bubble's rounding
196
- * has to give way for it.
197
- *
198
- * `padding` keeps the arrow past the rounding, on the straight part of the edge. A
199
- * fixed 4px let a `-start` / `-end` arrow land on the curve of a well-rounded
200
- * flavor, where the edge has already pulled away and the diamond hung off the
201
- * corner.
202
- *
203
- * `cap` handles the edge that has NO straight part: a pill's short side is all
204
- * curve (height = 2 × radius), so whatever the padding, the diamond sat on a curve
205
- * and looked glued to the corner. When the edge can't fit the arrow between its two
206
- * roundings, the radius is capped to the widest value that still leaves the
207
- * diamond a straight run — the bubble turns from a pill into a rounded rectangle
208
- * only on the placements that need it. `null` = the painted radius already fits.
209
- *
210
- * Read from the PAINTED radius, so every flavor and radius preset is covered. CSS
211
- * scales radii that overflow the box down to fit it (a `9999px` pill paints half
212
- * its height), hence the clamp to half the smaller side. The diamond is the arrow
213
- * box rotated 45°: where it meets the edge it is `size·√2` wide, so it overhangs
214
- * its own box by `size·(√2−1)/2` on each side.
215
- */
216
- function arrowGeometry(bubble, arrowEl, corners, side) {
217
- const width = bubble.offsetWidth;
218
- const height = bubble.offsetHeight;
219
- const half = Math.min(width, height) / 2;
220
- const painted = Math.min(half, Math.max(...corners.map((v) => {
221
- const n = parseFloat(v) || 0;
222
- return v.trim().endsWith("%") ? n / 100 * half * 2 : n;
223
- })));
224
- const size = arrowEl.offsetWidth;
225
- const diagonal = size * Math.SQRT2;
226
- const overhang = (diagonal - size) / 2;
227
- const fit = Math.max(0, Math.floor(((side === "left" || side === "right" ? height : width) - diagonal) / 2) - 2);
228
- const radius = Math.min(painted, fit);
229
- return {
230
- padding: Math.max(4, Math.ceil(radius + overhang) + 1),
231
- cap: radius < painted ? radius : null
232
- };
233
- }
234
- function toDelays(delay) {
235
- if (Array.isArray(delay)) return [Number(delay[0]) || 0, Number(delay[1]) || 0];
236
- const d = Number(delay) || 0;
237
- return [d, d];
238
- }
239
- function toTriggers(trigger) {
240
- return new Set(Array.isArray(trigger) ? trigger : [trigger]);
241
- }
242
- /**
243
- * The anchor's own text, when no `content` option is given: the declarative
244
- * `mono-tooltip-content` / `mono-tooltip-message`, then a native `title` (moved to
245
- * `data-mono-title` while open), then `aria-label`.
246
- */
247
- function anchorText(anchor) {
248
- const attr = (name) => anchor.getAttribute(name)?.trim() || null;
249
- return attr("mono-tooltip-content") ?? attr("mono-tooltip-message") ?? attr("data-mono-title") ?? attr("title") ?? attr("aria-label");
250
- }
251
- function resolveContent(content, anchor) {
252
- const value = typeof content === "function" ? content(anchor) : content;
253
- if (value instanceof Node) return value;
254
- if (value !== void 0 && value !== null && String(value).trim() !== "") return String(value);
255
- if (content !== void 0) return null;
256
- return anchorText(anchor);
257
- }
258
- /** Prefix of the declarative anchor attributes (`mono-tooltip-content`, …). */
259
- const ANCHOR_ATTR_PREFIX = "mono-tooltip-";
260
- var TooltipInstance = class {
261
- constructor(_target, options, _anchorOptions) {
262
- this._target = _target;
263
- this._anchorOptions = _anchorOptions;
264
- this._open = null;
265
- this._reasons = /* @__PURE__ */ new Set();
266
- this._token = 0;
267
- this._pending = null;
268
- this._pendingReason = null;
269
- this._suppressed = null;
270
- this._lastPath = [];
271
- this._destroyed = false;
272
- this._id = `mono-tooltip-${++nextId}`;
273
- this._options = { ...options };
274
- if (!hasLiveDocument()) {
275
- this._destroyed = true;
276
- return;
277
- }
278
- live.add(this);
279
- bindDocument();
280
- }
281
- get isOpen() {
282
- return !!this._open;
283
- }
284
- get anchor() {
285
- return this._open?.anchor ?? null;
286
- }
287
- get tooltip() {
288
- return this._open?.el ?? null;
289
- }
290
- async show(anchor) {
291
- const el = anchor ?? this._firstTarget();
292
- if (!el) return;
293
- this._lastPath = [];
294
- await this._openOn(el, "manual", 0);
295
- }
296
- hide() {
297
- this._close(false);
298
- }
299
- async toggle(anchor) {
300
- if (this._open && (!anchor || anchor === this._open.anchor)) this.hide();
301
- else await this.show(anchor);
302
- }
303
- update(options) {
304
- this._options = {
305
- ...this._options,
306
- ...options
307
- };
308
- this._refresh();
309
- }
310
- /** Re-apply the resolved options to an open tooltip (or close it when now disabled). */
311
- _refresh() {
312
- const o = this._resolved(this._open?.anchor);
313
- if (o.disabled) return this._close(true);
314
- if (this._open) {
315
- this._applyAppearance(this._open.el, o);
316
- this._renderBody(this._open, o);
317
- }
318
- }
319
- setContent(content) {
320
- this.update({ content });
321
- }
322
- enable() {
323
- this.update({ disabled: false });
324
- }
325
- disable() {
326
- this.update({ disabled: true });
327
- }
328
- destroy() {
329
- if (this._destroyed) return;
330
- this._close(true);
331
- this._destroyed = true;
332
- live.delete(this);
333
- unbindDocument();
334
- }
335
- /** @internal — pointer entered something (or `[]`: left the window). */
336
- _pointerOver(path, e) {
337
- if (e.pointerType === "touch") return;
338
- const candidate = this._findAnchor(path);
339
- const o = this._resolved(candidate ?? this._open?.anchor);
340
- const anchor = candidate && toTriggers(o.trigger).has("hover") ? candidate : null;
341
- if (this._suppressed && anchor !== this._suppressed) this._suppressed = null;
342
- if (anchor) {
343
- if (anchor === this._suppressed || o.disabled) return;
344
- this._lastPath = path;
345
- if (this._open?.anchor === anchor) {
346
- this._cancelHide();
347
- this._reasons.add("hover");
348
- return;
349
- }
350
- if (this._pending === anchor) return;
351
- this._openOn(anchor, "hover", toDelays(o.delay)[0]);
352
- return;
353
- }
354
- if (o.interactive && this._open && path.includes(this._open.el)) {
355
- this._cancelHide();
356
- return;
357
- }
358
- this._dropReason("hover");
359
- }
360
- /** @internal — focus landed somewhere (or `[]`: focus left the document). */
361
- _focusIn(path) {
362
- const candidate = this._findAnchor(path);
363
- const o = this._resolved(candidate);
364
- const anchor = candidate && toTriggers(o.trigger).has("focus") ? candidate : null;
365
- if (anchor && !o.disabled && isFocusVisible(path[0])) {
366
- this._lastPath = path;
367
- if (this._open?.anchor === anchor) {
368
- this._cancelHide();
369
- this._reasons.add("focus");
370
- } else this._openOn(anchor, "focus", toDelays(o.delay)[0]);
371
- return;
372
- }
373
- if (this._open && path.includes(this._open.el)) return;
374
- this._dropReason("focus");
375
- }
376
- /** @internal */
377
- _click(path) {
378
- const anchor = this._findAnchor(path);
379
- const o = this._resolved(anchor ?? this._open?.anchor);
380
- const triggers = toTriggers(o.trigger);
381
- const inTooltip = !!this._open && path.includes(this._open.el);
382
- if (triggers.has("click") && !o.disabled) {
383
- if (anchor) {
384
- if (this._open?.anchor === anchor && this._reasons.has("click")) this._close(false);
385
- else {
386
- this._lastPath = path;
387
- this._openOn(anchor, "click", 0);
388
- }
389
- return;
390
- }
391
- if (!inTooltip && this._reasons.has("click")) this._close(false);
392
- return;
393
- }
394
- if (anchor && o.hideOnClick) {
395
- this._suppressed = anchor;
396
- if (this._pending === anchor) {
397
- if (this._pendingReason !== "focus") this._cancelShow();
398
- return;
399
- }
400
- if (this._open?.anchor !== anchor || this._reasons.has("manual")) return;
401
- if (this._reasons.has("focus")) this._reasons.delete("hover");
402
- else this._close(false);
403
- }
404
- }
405
- _resolved(anchor) {
406
- const own = anchor && this._anchorOptions ? this._anchorOptions(anchor) : null;
407
- return resolveTooltipOptions(this._options, own);
408
- }
409
- /** The innermost element on the path this controller's target names. */
410
- _findAnchor(path) {
411
- if (!path.length) return null;
412
- const value = unwrapTarget(this._target);
413
- if (!value) return null;
414
- if (typeof value === "string") {
415
- for (const node of path) if (node instanceof Element && safeMatches(node, value)) return node;
416
- return null;
417
- }
418
- const set = new Set(toElements(value));
419
- if (!set.size) return null;
420
- for (const node of path) if (set.has(node)) return node;
421
- return null;
422
- }
423
- _firstTarget() {
424
- const value = unwrapTarget(this._target);
425
- if (typeof value === "string") try {
426
- return document.querySelector(value);
427
- } catch {
428
- return null;
429
- }
430
- return toElements(value)[0] ?? null;
431
- }
432
- _cancelShow() {
433
- clearTimeout(this._showTimer);
434
- this._showTimer = void 0;
435
- this._pending = null;
436
- this._pendingReason = null;
437
- }
438
- _cancelHide() {
439
- clearTimeout(this._hideTimer);
440
- this._hideTimer = void 0;
441
- }
442
- /** One reason to stay open went away — close once none is left. */
443
- _dropReason(reason) {
444
- if (this._pending && !this._open && this._pendingReason === reason) {
445
- this._cancelShow();
446
- this._token++;
447
- }
448
- if (!this._open || !this._reasons.has(reason)) return;
449
- this._reasons.delete(reason);
450
- if (this._reasons.size) return;
451
- const o = this._resolved(this._open.anchor);
452
- let delay = toDelays(o.delay)[1];
453
- if (o.interactive) delay = Math.max(delay, INTERACTIVE_HIDE_GRACE);
454
- this._cancelHide();
455
- if (delay > 0) this._hideTimer = setTimeout(() => this._close(false), delay);
456
- else this._close(false);
457
- }
458
- async _openOn(anchor, reason, delay) {
459
- if (this._destroyed) return;
460
- this._cancelHide();
461
- this._cancelShow();
462
- if (this._open?.anchor === anchor) {
463
- this._reasons.add(reason);
464
- return;
465
- }
466
- const token = ++this._token;
467
- if (delay > 0) {
468
- this._pending = anchor;
469
- this._pendingReason = reason;
470
- await new Promise((resolve) => {
471
- this._showTimer = setTimeout(resolve, delay);
472
- });
473
- if (token !== this._token) return;
474
- }
475
- this._pending = null;
476
- this._pendingReason = null;
477
- await this._mount(anchor, reason, token);
478
- }
479
- async _mount(anchor, reason, token) {
480
- const o = this._resolved(anchor);
481
- if (o.disabled || !anchor.isConnected) return;
482
- const content = resolveContent(o.content, anchor);
483
- if (content === null) return;
484
- let floating;
485
- try {
486
- floating = await loadFloatingUi();
487
- } catch (err) {
488
- console.error(err);
489
- return;
490
- }
491
- if (token !== this._token || this._destroyed || !anchor.isConnected) return;
492
- if (this._open) this._teardown(this._open);
493
- const el = document.createElement("div");
494
- el.id = this._id;
495
- el.setAttribute("role", "tooltip");
496
- el.setAttribute("mono-tooltip", "");
497
- const body = document.createElement("div");
498
- body.setAttribute("mono-tooltip-body", "");
499
- const arrow = document.createElement("div");
500
- arrow.setAttribute("mono-tooltip-arrow", "");
501
- el.append(body, arrow);
502
- this._applyAppearance(el, o, anchor);
503
- if (o.onShow?.(anchor, el) === false) return;
504
- const state = {
505
- anchor,
506
- el,
507
- body,
508
- arrow,
509
- stopAutoUpdate: () => {},
510
- layer: {
511
- setStackZ: (z) => el.style.setProperty("--mono-popup-z", String(z)),
512
- onStackEscape: () => this._close(false)
513
- },
514
- stashed: [],
515
- describedBy: anchor.getAttribute("aria-describedby"),
516
- observer: null
517
- };
518
- if (this._anchorOptions && typeof MutationObserver !== "undefined") {
519
- state.observer = new MutationObserver((records) => {
520
- if (this._open !== state) return;
521
- if (records.some((r) => r.attributeName?.startsWith("mono-tooltip-"))) this._refresh();
522
- });
523
- state.observer.observe(anchor, { attributes: true });
524
- }
525
- this._open = state;
526
- this._reasons = /* @__PURE__ */ new Set([reason]);
527
- this._renderContent(body, content, o.allowHTML);
528
- ((typeof o.appendTo === "function" ? o.appendTo() : o.appendTo) ?? document.body).appendChild(el);
529
- this._stashTitles(state);
530
- const ids = (state.describedBy ?? "").split(/\s+/).filter(Boolean);
531
- if (!ids.includes(this._id)) anchor.setAttribute("aria-describedby", [...ids, this._id].join(" "));
532
- registerPopupLayer(state.layer);
533
- const reposition = () => void this._position(floating, state);
534
- state.stopAutoUpdate = floating.autoUpdate(anchor, el, reposition);
535
- await this._position(floating, state);
536
- if (this._open === state) requestAnimationFrame(() => {
537
- if (this._open === state) el.setAttribute("data-open", "");
538
- });
539
- }
540
- async _position(floating, state) {
541
- if (this._open !== state) return;
542
- if (!state.anchor.isConnected) {
543
- this._close(true);
544
- return;
545
- }
546
- const o = this._resolved(state.anchor);
547
- const { computePosition, offset, flip, shift, arrow, hide } = floating;
548
- const middleware = [offset(o.offset)];
549
- if (o.flip) middleware.push(flip({ padding: o.padding }));
550
- if (o.shift) middleware.push(shift({ padding: o.padding }));
551
- const corners = state.corners ??= readCorners(state.el);
552
- const geometry = (placement) => arrowGeometry(state.el, state.arrow, corners, placement.split("-")[0]);
553
- if (o.arrow) middleware.push(arrow(({ placement }) => ({
554
- element: state.arrow,
555
- padding: geometry(placement).padding
556
- })));
557
- middleware.push(hide());
558
- const { x, y, placement, middlewareData } = await computePosition(state.anchor, state.el, {
559
- placement: o.placement,
560
- strategy: "fixed",
561
- middleware
562
- });
563
- if (this._open !== state) return;
564
- state.el.style.left = `${x}px`;
565
- state.el.style.top = `${y}px`;
566
- const [side, align] = placement.split("-");
567
- state.el.setAttribute("data-side", side);
568
- if (align) state.el.setAttribute("data-align", align);
569
- else state.el.removeAttribute("data-align");
570
- const cap = o.arrow ? geometry(placement).cap : null;
571
- if (cap === null) state.el.style.removeProperty("--_mono-tooltip-radius-cap");
572
- else state.el.style.setProperty("--_mono-tooltip-radius-cap", `${cap}px`);
573
- const a = middlewareData.arrow;
574
- state.arrow.style.left = a?.x != null ? `${a.x}px` : "";
575
- state.arrow.style.top = a?.y != null ? `${a.y}px` : "";
576
- state.el.style.visibility = middlewareData.hide?.referenceHidden ? "hidden" : "";
577
- }
578
- /** Attributes + classes the CSS keys on. Re-run by `update()` on an open tooltip. */
579
- _applyAppearance(el, o, anchor) {
580
- el.className = [
581
- "mono-tooltip",
582
- ...scopedThemeClasses(anchor ?? this._open?.anchor ?? el),
583
- ...o.class ? o.class.split(/\s+/) : []
584
- ].filter(Boolean).join(" ");
585
- const attr = (name, value) => value === null ? el.removeAttribute(name) : el.setAttribute(name, value);
586
- attr("mono-variant", o.variant && o.variant !== "inverted" ? o.variant : null);
587
- attr("mono-color", o.color ?? null);
588
- attr("mono-size", o.size && o.size !== "md" ? o.size : null);
589
- attr("mono-interactive", o.interactive ? "" : null);
590
- attr("mono-arrow", o.arrow ? "" : null);
591
- if (o.maxWidth) el.style.setProperty("--mono-tooltip-max-width", o.maxWidth);
592
- else el.style.removeProperty("--mono-tooltip-max-width");
593
- }
594
- _renderBody(state, o) {
595
- const content = resolveContent(o.content, state.anchor);
596
- if (content === null) return this._close(true);
597
- this._renderContent(state.body, content, o.allowHTML);
598
- }
599
- _renderContent(body, content, allowHTML) {
600
- if (content instanceof Node) body.replaceChildren(content);
601
- else if (allowHTML) body.innerHTML = content;
602
- else body.textContent = content;
603
- }
604
- /**
605
- * Move `title`s aside while open — the anchor's, and any between the pointer
606
- * and the anchor (a component may render one on an inner element) — or the
607
- * browser shows its own tooltip on top of ours.
608
- */
609
- _stashTitles(state) {
610
- const chain = [];
611
- for (const node of this._lastPath) {
612
- if (node instanceof Element) chain.push(node);
613
- if (node === state.anchor) break;
614
- }
615
- if (!chain.includes(state.anchor)) chain.push(state.anchor);
616
- for (const el of chain) {
617
- const title = el.getAttribute("title");
618
- if (title === null) continue;
619
- state.stashed.push([el, title]);
620
- el.setAttribute("data-mono-title", title);
621
- el.removeAttribute("title");
622
- }
623
- }
624
- _close(force) {
625
- this._cancelShow();
626
- this._cancelHide();
627
- this._token++;
628
- const state = this._open;
629
- if (!state) return;
630
- if (!force && this._resolved(state.anchor).onHide?.(state.anchor, state.el) === false) return;
631
- this._teardown(state);
632
- }
633
- _teardown(state) {
634
- state.stopAutoUpdate();
635
- state.observer?.disconnect();
636
- unregisterPopupLayer(state.layer);
637
- for (const [el, title] of state.stashed) {
638
- if (el.getAttribute("title") === null) el.setAttribute("title", title);
639
- el.removeAttribute("data-mono-title");
640
- }
641
- const ids = (state.anchor.getAttribute("aria-describedby") ?? "").split(/\s+/).filter((id) => id && id !== this._id);
642
- if (ids.length) state.anchor.setAttribute("aria-describedby", ids.join(" "));
643
- else if (state.describedBy === null) state.anchor.removeAttribute("aria-describedby");
644
- else state.anchor.setAttribute("aria-describedby", state.describedBy);
645
- if (this._open === state) {
646
- this._open = null;
647
- this._reasons.clear();
648
- }
649
- const el = state.el;
650
- el.removeAttribute("data-open");
651
- el.removeAttribute("id");
652
- let done = false;
653
- const remove = () => {
654
- if (done) return;
655
- done = true;
656
- el.remove();
657
- };
658
- el.addEventListener("transitionend", remove, { once: true });
659
- setTimeout(remove, EXIT_FALLBACK_MS);
660
- }
661
- };
662
- /**
663
- * Attach a tooltip to every element `target` names — now or later.
664
- *
665
- * ```ts
666
- * // <script setup> — the elements need not exist yet
667
- * const tip = controlMonoTooltip('.save-btn', { content: 'Save changes', placement: 'bottom' })
668
- * onBeforeUnmount(() => tip.destroy())
669
- * ```
670
- *
671
- * `target` is a CSS selector, an element, a list of elements, or a Vue ref /
672
- * getter of any of those. Light `<mono-*>` elements, shadow `<mono-shadow-*>`
673
- * hosts and elements inside open shadow roots all match.
674
- *
675
- * Needs the optional peers `@floating-ui/dom` + `@floating-ui/core`, loaded on
676
- * the first show. Options set with `createMonoTooltip` override these.
677
- */
678
- function controlMonoTooltip(target, options = {}) {
679
- return new TooltipInstance(target, options);
680
- }
681
-
682
- //#endregion
683
- //#region src/components/tooltip/field-tooltip-addon.ts
684
- /**
685
- * The tooltip addon as `field-tooltip` lazy-loads it — ONE module, imported dynamically and
686
- * from nowhere else.
687
- *
688
- * `field-tooltip` used to `import()` `control-tooltip` and `tooltip-loader` directly. Both are
689
- * also imported STATICALLY by the root entry, so rolldown had to hand the dynamic importer a
690
- * synthesized namespace object (`__exportAll`) — and its runtime helpers sat in the report
691
- * engine's markdown chunk, so `import … from '@mono-lit/helper'` loaded and evaluated ~500KB of
692
- * remark/micromark. A module that is only ever dynamically imported is its own chunk entry, and
693
- * `import()` returns its real namespace: no helper, no markdown.
694
- */
695
- /** `controlMonoTooltip` once the optional `@floating-ui/dom` peer has loaded; rejects without it. */
696
- async function loadFieldTooltipAddon() {
697
- await loadFloatingUi();
698
- return controlMonoTooltip;
699
- }
700
-
701
- //#endregion
702
- export { loadFieldTooltipAddon };