mnfst 0.5.52 → 0.5.54
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/README.md +1 -1
- package/lib/manifest.components.js +5 -0
- package/lib/manifest.css +400 -2
- package/lib/manifest.data.js +24 -0
- package/lib/manifest.dropdown.css +1 -1
- package/lib/manifest.dropdowns.js +7 -1
- package/lib/manifest.input.css +1 -1
- package/lib/manifest.js +198 -11
- package/lib/manifest.markdown.js +31 -4
- package/lib/manifest.min.css +1 -1
- package/lib/manifest.tooltips.js +67 -33
- package/package.json +6 -6
package/lib/manifest.tooltips.js
CHANGED
|
@@ -43,6 +43,18 @@ function getTooltipHoverDelay(element) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Keep anchor-name on the trigger long after hide so position-anchor stays valid through any close transition/layout. */
|
|
47
|
+
const ANCHOR_RESTORE_DELAY_MS = 2000;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* DOM parent for the tooltip popover. Must be the same popover subtree as the trigger when the trigger
|
|
51
|
+
* lives inside menu/dialog/etc.; otherwise CSS anchor positioning cannot resolve (tooltip in body + anchor
|
|
52
|
+
* inside top-layer popover → invalid position-anchor, jump to origin).
|
|
53
|
+
*/
|
|
54
|
+
function getTooltipHostForTrigger(triggerEl) {
|
|
55
|
+
return triggerEl.closest('[popover]') || document.body;
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
function initializeTooltipPlugin() {
|
|
47
59
|
|
|
48
60
|
Alpine.directive('tooltip', (el, { modifiers, expression }, { effect, evaluateLater }) => {
|
|
@@ -92,9 +104,9 @@ function initializeTooltipPlugin() {
|
|
|
92
104
|
originalTarget = el.getAttribute('x-dropdown');
|
|
93
105
|
}
|
|
94
106
|
|
|
95
|
-
// Create the tooltip element
|
|
107
|
+
// Create the tooltip element (hint popovers coexist with auto menus/dialogs)
|
|
96
108
|
const tooltip = document.createElement('div');
|
|
97
|
-
tooltip.setAttribute('popover', '');
|
|
109
|
+
tooltip.setAttribute('popover', 'hint');
|
|
98
110
|
tooltip.setAttribute('id', tooltipId);
|
|
99
111
|
tooltip.setAttribute('class', 'tooltip');
|
|
100
112
|
|
|
@@ -117,15 +129,55 @@ function initializeTooltipPlugin() {
|
|
|
117
129
|
tooltip.classList.add(positionClass);
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
//
|
|
121
|
-
|
|
132
|
+
// Mount under the same popover as the trigger when applicable (see getTooltipHostForTrigger)
|
|
133
|
+
getTooltipHostForTrigger(el).appendChild(tooltip);
|
|
122
134
|
|
|
123
135
|
// State variables for managing tooltip behavior
|
|
124
136
|
let showTimeout;
|
|
137
|
+
let restoreAnchorTimeout = null;
|
|
138
|
+
let anchorRestoreGeneration = 0;
|
|
125
139
|
let isMouseDown = false;
|
|
126
140
|
let isDynamic = expression.includes('+') || expression.includes('`') || expression.includes('${') || expression.startsWith('$x.');
|
|
127
141
|
let isUpdatingContent = false;
|
|
128
142
|
|
|
143
|
+
function restoreOriginalAnchor() {
|
|
144
|
+
if (el._originalAnchorName) {
|
|
145
|
+
el.style.setProperty('anchor-name', el._originalAnchorName);
|
|
146
|
+
} else {
|
|
147
|
+
el.style.removeProperty('anchor-name');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function cancelScheduledAnchorRestore() {
|
|
152
|
+
anchorRestoreGeneration += 1;
|
|
153
|
+
if (restoreAnchorTimeout !== null) {
|
|
154
|
+
clearTimeout(restoreAnchorTimeout);
|
|
155
|
+
restoreAnchorTimeout = null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function scheduleAnchorRestoreAfterTooltipDismissal(restoreFn) {
|
|
160
|
+
cancelScheduledAnchorRestore();
|
|
161
|
+
const gen = anchorRestoreGeneration;
|
|
162
|
+
const run = () => {
|
|
163
|
+
if (gen !== anchorRestoreGeneration) return;
|
|
164
|
+
restoreAnchorTimeout = null;
|
|
165
|
+
restoreFn();
|
|
166
|
+
};
|
|
167
|
+
restoreAnchorTimeout = setTimeout(run, ANCHOR_RESTORE_DELAY_MS);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function scheduleRestoreAnchorAfterClose() {
|
|
171
|
+
scheduleAnchorRestoreAfterTooltipDismissal(() => restoreOriginalAnchor());
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function ensureTooltipHostMatchesTrigger() {
|
|
175
|
+
const host = getTooltipHostForTrigger(el);
|
|
176
|
+
if (tooltip.parentNode !== host) {
|
|
177
|
+
host.appendChild(tooltip);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
129
181
|
// Function to update tooltip content - prevents double updates
|
|
130
182
|
const updateTooltipContent = () => {
|
|
131
183
|
// Prevent concurrent updates that cause flicker
|
|
@@ -148,6 +200,8 @@ function initializeTooltipPlugin() {
|
|
|
148
200
|
}
|
|
149
201
|
|
|
150
202
|
el.addEventListener('mouseenter', () => {
|
|
203
|
+
cancelScheduledAnchorRestore();
|
|
204
|
+
clearTimeout(showTimeout);
|
|
151
205
|
if (!isMouseDown) {
|
|
152
206
|
const hoverDelay = getTooltipHoverDelay(el);
|
|
153
207
|
showTimeout = setTimeout(() => {
|
|
@@ -161,6 +215,8 @@ function initializeTooltipPlugin() {
|
|
|
161
215
|
updateTooltipContent();
|
|
162
216
|
}
|
|
163
217
|
|
|
218
|
+
ensureTooltipHostMatchesTrigger();
|
|
219
|
+
|
|
164
220
|
// Only manage anchor-name if element has other popover functionality
|
|
165
221
|
if (originalTarget) {
|
|
166
222
|
// Store current anchor name (dropdown may have set it by now)
|
|
@@ -190,10 +246,7 @@ function initializeTooltipPlugin() {
|
|
|
190
246
|
clearTimeout(showTimeout);
|
|
191
247
|
if (tooltip.matches(':popover-open')) {
|
|
192
248
|
tooltip.hidePopover();
|
|
193
|
-
|
|
194
|
-
if (originalTarget) {
|
|
195
|
-
restoreOriginalAnchor();
|
|
196
|
-
}
|
|
249
|
+
scheduleRestoreAnchorAfterClose();
|
|
197
250
|
}
|
|
198
251
|
});
|
|
199
252
|
|
|
@@ -203,10 +256,7 @@ function initializeTooltipPlugin() {
|
|
|
203
256
|
if (tooltip.matches(':popover-open')) {
|
|
204
257
|
tooltip.hidePopover();
|
|
205
258
|
}
|
|
206
|
-
|
|
207
|
-
if (originalTarget) {
|
|
208
|
-
restoreOriginalAnchor();
|
|
209
|
-
}
|
|
259
|
+
scheduleRestoreAnchorAfterClose();
|
|
210
260
|
});
|
|
211
261
|
|
|
212
262
|
el.addEventListener('mouseup', () => {
|
|
@@ -222,43 +272,26 @@ function initializeTooltipPlugin() {
|
|
|
222
272
|
tooltip.hidePopover();
|
|
223
273
|
}
|
|
224
274
|
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
setTimeout(() => {
|
|
228
|
-
// Only restore anchor if no popover opened from this click
|
|
275
|
+
// After computed transition time: restore anchor only if no popover opened from this click
|
|
276
|
+
scheduleAnchorRestoreAfterTooltipDismissal(() => {
|
|
229
277
|
if (originalTarget) {
|
|
230
278
|
const targetPopover = document.getElementById(originalTarget);
|
|
231
279
|
const isPopoverOpen = targetPopover?.matches(':popover-open');
|
|
232
280
|
if (!targetPopover || !isPopoverOpen) {
|
|
233
281
|
restoreOriginalAnchor();
|
|
234
282
|
}
|
|
235
|
-
// If popover is open, keep current anchor (don't restore)
|
|
236
283
|
} else {
|
|
237
284
|
restoreOriginalAnchor();
|
|
238
285
|
}
|
|
239
|
-
}
|
|
286
|
+
});
|
|
240
287
|
});
|
|
241
288
|
|
|
242
|
-
// Helper function to restore original anchor
|
|
243
|
-
function restoreOriginalAnchor() {
|
|
244
|
-
if (el._originalAnchorName) {
|
|
245
|
-
// Restore the original anchor name
|
|
246
|
-
el.style.setProperty('anchor-name', el._originalAnchorName);
|
|
247
|
-
} else {
|
|
248
|
-
// Remove the tooltip anchor name so other plugins can set their own
|
|
249
|
-
el.style.removeProperty('anchor-name');
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
289
|
// Listen for other popovers opening and close tooltip if needed
|
|
254
290
|
const handlePopoverOpen = (event) => {
|
|
255
291
|
// If another popover opens and it's not our tooltip, close our tooltip
|
|
256
292
|
if (event.target !== tooltip && tooltip.matches(':popover-open')) {
|
|
257
293
|
tooltip.hidePopover();
|
|
258
|
-
|
|
259
|
-
if (originalTarget) {
|
|
260
|
-
restoreOriginalAnchor();
|
|
261
|
-
}
|
|
294
|
+
scheduleRestoreAnchorAfterClose();
|
|
262
295
|
}
|
|
263
296
|
};
|
|
264
297
|
|
|
@@ -270,6 +303,7 @@ function initializeTooltipPlugin() {
|
|
|
270
303
|
|
|
271
304
|
// Cleanup function for when element is removed
|
|
272
305
|
const cleanup = () => {
|
|
306
|
+
cancelScheduledAnchorRestore();
|
|
273
307
|
if (el._tooltipPopoverListener) {
|
|
274
308
|
document.removeEventListener('toggle', el._tooltipPopoverListener);
|
|
275
309
|
delete el._tooltipPopoverListener;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mnfst",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.54",
|
|
4
4
|
"private": false,
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"templates/starter",
|
|
@@ -17,15 +17,16 @@
|
|
|
17
17
|
"clean": "rimraf src/scripts/manifest.js src/scripts/manifest.render.mjs src/styles/manifest.css src/styles/manifest.min.css src/styles/manifest.code.min.css lib",
|
|
18
18
|
"build": "cd src && node scripts/build.mjs",
|
|
19
19
|
"build:docs": "echo 'Docs is a static website - no build needed'",
|
|
20
|
-
"start:src": "
|
|
21
|
-
"start:docs": "
|
|
22
|
-
"start:starter": "
|
|
23
|
-
"start:dist": "
|
|
20
|
+
"start:src": "node packages/run/serve.mjs src",
|
|
21
|
+
"start:docs": "node packages/run/serve.mjs docs",
|
|
22
|
+
"start:starter": "node packages/run/serve.mjs templates/starter --port 3001",
|
|
23
|
+
"start:dist": "node packages/run/serve.mjs src/test-prerender --port 5003",
|
|
24
24
|
"prerender": "node src/scripts/manifest.render.mjs --root src",
|
|
25
25
|
"prerender:docs": "node src/scripts/manifest.render.mjs --root docs",
|
|
26
26
|
"prerender:starter": "node src/scripts/manifest.render.mjs --root templates/starter",
|
|
27
27
|
"render": "node src/scripts/manifest.render.mjs --root src",
|
|
28
28
|
"publish:starter": "cd packages/create-starter && npm publish --auth-type=web",
|
|
29
|
+
"publish:run": "cd packages/run && npm publish --auth-type=web",
|
|
29
30
|
"publish:render": "cd packages/render && npm publish --auth-type=web",
|
|
30
31
|
"prepublishOnly": "npm run build",
|
|
31
32
|
"test": "vitest run",
|
|
@@ -35,7 +36,6 @@
|
|
|
35
36
|
"@rollup/plugin-commonjs": "^28.0.1",
|
|
36
37
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
37
38
|
"@rollup/plugin-terser": "^0.4.4",
|
|
38
|
-
"browser-sync": "^3.0.3",
|
|
39
39
|
"cssnano": "^7.1.1",
|
|
40
40
|
"glob": "^11.0.2",
|
|
41
41
|
"puppeteer": "^24.15.0",
|