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