kerfjs 4.4.0 → 5.0.0-beta.3
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/CHANGELOG.md +116 -0
- package/LICENSE +1 -1
- package/README.md +34 -35
- package/ai/cursorrules +46 -1
- package/ai/manifest.json +62 -5
- package/ai/skill.md +53 -2
- package/dist/actions.d.ts +1 -1
- package/dist/actions.js +4 -4
- package/dist/actions.js.map +1 -1
- package/dist/array-signal.js +5 -5
- package/dist/async.js +17 -10
- package/dist/async.js.map +1 -1
- package/dist/attach.d.ts +11 -8
- package/dist/attach.js +52 -4
- package/dist/attach.js.map +1 -1
- package/dist/chunk-GY4XV2UV.js +1 -1
- package/dist/{chunk-VVDJLWMP.js → chunk-HW7KSM2Y.js} +2 -2
- package/dist/chunk-HW7KSM2Y.js.map +1 -0
- package/dist/{chunk-KEZTD6H4.js → chunk-KPXIOG2C.js} +3 -3
- package/dist/{chunk-KEZTD6H4.js.map → chunk-KPXIOG2C.js.map} +1 -1
- package/dist/{chunk-SAYPJ6XR.js → chunk-KZJXHFIB.js} +10 -6
- package/dist/chunk-KZJXHFIB.js.map +1 -0
- package/dist/{chunk-MRYM3O3V.js → chunk-LVH3GC6B.js} +11 -8
- package/dist/chunk-LVH3GC6B.js.map +1 -0
- package/dist/chunk-QIP723L4.js +1 -1
- package/dist/{chunk-SRWQKB33.js → chunk-SVATPF5R.js} +97 -74
- package/dist/chunk-SVATPF5R.js.map +1 -0
- package/dist/{chunk-3APBEVHF.js → chunk-U6FK33SG.js} +3 -3
- package/dist/{chunk-3APBEVHF.js.map → chunk-U6FK33SG.js.map} +1 -1
- package/dist/{chunk-U32TFTGZ.js → chunk-UZJ6I4T6.js} +3 -3
- package/dist/chunk-UZJ6I4T6.js.map +1 -0
- package/dist/{chunk-YHH7OUFA.js → chunk-V46JKE44.js} +3 -3
- package/dist/chunk-V46JKE44.js.map +1 -0
- package/dist/{chunk-SUPUPSBE.js → chunk-ZDCJZCNO.js} +9 -8
- package/dist/chunk-ZDCJZCNO.js.map +1 -0
- package/dist/dev.d.ts +9 -6
- package/dist/dev.js +5 -5
- package/dist/dev.js.map +1 -1
- package/dist/html.d.ts +1 -1
- package/dist/html.js +5 -5
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/jsx-runtime.js +5 -5
- package/dist/list.d.ts +1 -1
- package/dist/list.js +273 -211
- package/dist/list.js.map +1 -1
- package/dist/overlay.d.ts +190 -280
- package/dist/overlay.js +401 -361
- package/dist/overlay.js.map +1 -1
- package/dist/remount.d.ts +5 -3
- package/dist/remount.js +29 -10
- package/dist/remount.js.map +1 -1
- package/dist/router.d.ts +1 -1
- package/dist/router.js +44 -22
- package/dist/router.js.map +1 -1
- package/dist/scope.d.ts +4 -3
- package/dist/scope.js +10 -10
- package/dist/scope.js.map +1 -1
- package/dist/testing.js +4 -4
- package/dist/timing.d.ts +3 -2
- package/dist/timing.js +5 -5
- package/dist/timing.js.map +1 -1
- package/llms.txt +7 -4
- package/package.json +12 -10
- package/dist/chunk-MRYM3O3V.js.map +0 -1
- package/dist/chunk-SAYPJ6XR.js.map +0 -1
- package/dist/chunk-SRWQKB33.js.map +0 -1
- package/dist/chunk-SUPUPSBE.js.map +0 -1
- package/dist/chunk-U32TFTGZ.js.map +0 -1
- package/dist/chunk-VVDJLWMP.js.map +0 -1
- package/dist/chunk-YHH7OUFA.js.map +0 -1
- /package/dist/{attrSelector-Cmu2ZoGO.d.ts → attr-Cmu2ZoGO.d.ts} +0 -0
package/dist/overlay.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { mount } from './chunk-
|
|
2
|
-
import { delegate } from './chunk-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { jsx } from './chunk-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { mount } from './chunk-SVATPF5R.js';
|
|
2
|
+
import { delegate } from './chunk-KPXIOG2C.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import { jsx, escapeHtml } from './chunk-ZDCJZCNO.js';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
9
|
|
|
10
10
|
// src/overlay-position.ts
|
|
11
11
|
function positionAnchored(el, anchor, options = {}) {
|
|
12
12
|
const { placement = "bottom", align = "start", gap = 4 } = options;
|
|
13
13
|
el.style.position = "fixed";
|
|
14
14
|
el.style.margin = "0";
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const belowTop =
|
|
20
|
-
const aboveTop =
|
|
15
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
16
|
+
const elementRect = el.getBoundingClientRect();
|
|
17
|
+
const viewportWidth = window.innerWidth;
|
|
18
|
+
const viewportHeight = window.innerHeight;
|
|
19
|
+
const belowTop = anchorRect.bottom + gap;
|
|
20
|
+
const aboveTop = anchorRect.top - gap - elementRect.height;
|
|
21
21
|
let below = placement !== "top";
|
|
22
|
-
if (below && belowTop +
|
|
23
|
-
else if (!below && aboveTop < 0 && belowTop +
|
|
24
|
-
let left = align === "end" ?
|
|
25
|
-
left = Math.max(0, Math.min(left,
|
|
22
|
+
if (below && belowTop + elementRect.height > viewportHeight && aboveTop >= 0) below = false;
|
|
23
|
+
else if (!below && aboveTop < 0 && belowTop + elementRect.height <= viewportHeight) below = true;
|
|
24
|
+
let left = align === "end" ? anchorRect.right - elementRect.width : anchorRect.left;
|
|
25
|
+
left = Math.max(0, Math.min(left, viewportWidth - elementRect.width));
|
|
26
26
|
el.style.left = `${left}px`;
|
|
27
27
|
el.style.top = `${below ? belowTop : aboveTop}px`;
|
|
28
28
|
}
|
|
@@ -37,91 +37,328 @@ function autoReposition(el, anchor, options = {}) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// src/overlay-
|
|
41
|
-
|
|
40
|
+
// src/overlay-core.ts
|
|
41
|
+
var FOCUSABLE = 'a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),iframe,[tabindex]:not([tabindex="-1"]),[contenteditable="true"]';
|
|
42
|
+
function focusable(root) {
|
|
43
|
+
const items = Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
44
|
+
(el) => !el.hasAttribute("hidden") && el.tabIndex >= 0
|
|
45
|
+
);
|
|
46
|
+
for (const el of items) if (!el.hasAttribute("tabindex")) el.tabIndex = 0;
|
|
47
|
+
return items;
|
|
48
|
+
}
|
|
49
|
+
function supportsDialog() {
|
|
50
|
+
return typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
|
|
51
|
+
}
|
|
52
|
+
function supportsPopover() {
|
|
53
|
+
return typeof HTMLElement !== "undefined" && typeof HTMLElement.prototype.showPopover === "function";
|
|
54
|
+
}
|
|
55
|
+
var FALLBACK_OVERLAY_STACK = /* @__PURE__ */ Symbol("kerf.fallbackOverlayStack");
|
|
56
|
+
function fallbackOverlayStack(wrapper) {
|
|
57
|
+
const document2 = wrapper.ownerDocument;
|
|
58
|
+
return document2[FALLBACK_OVERLAY_STACK] ??= [];
|
|
59
|
+
}
|
|
60
|
+
function overlay(content, options = {}) {
|
|
42
61
|
const {
|
|
43
|
-
container,
|
|
62
|
+
container = document.body,
|
|
44
63
|
className = "kerf-overlay",
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
dismiss = ["escape", "backdrop"],
|
|
65
|
+
initialFocus = true,
|
|
66
|
+
trap = true,
|
|
67
|
+
role = "dialog",
|
|
68
|
+
onDismiss,
|
|
69
|
+
outsideIgnore,
|
|
70
|
+
native = false
|
|
51
71
|
} = options;
|
|
52
|
-
const
|
|
53
|
-
|
|
72
|
+
const triggers = dismiss === false ? [] : Array.isArray(dismiss) ? dismiss : [dismiss];
|
|
73
|
+
const restoreTo = document.activeElement;
|
|
74
|
+
const useDialog = native && trap && supportsDialog();
|
|
75
|
+
const usePopover = native && !trap && supportsPopover();
|
|
76
|
+
const wrapper = useDialog ? document.createElement("dialog") : document.createElement("div");
|
|
77
|
+
wrapper.className = className;
|
|
78
|
+
if (usePopover) wrapper.setAttribute("popover", "manual");
|
|
79
|
+
if (trap && !useDialog) {
|
|
80
|
+
wrapper.setAttribute("role", role);
|
|
81
|
+
wrapper.setAttribute("aria-modal", "true");
|
|
82
|
+
}
|
|
83
|
+
container.appendChild(wrapper);
|
|
84
|
+
const fallback = !useDialog && !usePopover;
|
|
85
|
+
const fallbackStack = fallback ? fallbackOverlayStack(wrapper) : void 0;
|
|
86
|
+
const isTopmostFallback = () => fallbackStack === void 0 || fallbackStack[fallbackStack.length - 1] === wrapper;
|
|
87
|
+
const disposeMount = mount(wrapper, typeof content === "function" ? content : () => content);
|
|
88
|
+
fallbackStack?.push(wrapper);
|
|
89
|
+
let nativeOpened = false;
|
|
90
|
+
if (useDialog) {
|
|
91
|
+
wrapper.showModal();
|
|
92
|
+
nativeOpened = true;
|
|
93
|
+
} else if (usePopover) {
|
|
94
|
+
wrapper.showPopover();
|
|
95
|
+
wrapper.style.inset = "auto";
|
|
96
|
+
nativeOpened = true;
|
|
97
|
+
}
|
|
98
|
+
const removers = [];
|
|
99
|
+
const resultBox = {};
|
|
100
|
+
const result = new Promise((resolve) => {
|
|
101
|
+
resultBox.resolve = resolve;
|
|
102
|
+
});
|
|
103
|
+
const state = { closed: false };
|
|
104
|
+
function close(value) {
|
|
105
|
+
if (state.closed) return;
|
|
106
|
+
state.closed = true;
|
|
107
|
+
if (fallbackStack !== void 0) {
|
|
108
|
+
const stackIndex = fallbackStack.indexOf(wrapper);
|
|
109
|
+
if (stackIndex !== -1) fallbackStack.splice(stackIndex, 1);
|
|
110
|
+
}
|
|
111
|
+
for (const remove of removers) remove();
|
|
112
|
+
disposeMount();
|
|
113
|
+
if (nativeOpened) {
|
|
114
|
+
nativeOpened = false;
|
|
115
|
+
if (useDialog) wrapper.close();
|
|
116
|
+
else wrapper.hidePopover();
|
|
117
|
+
}
|
|
118
|
+
wrapper.remove();
|
|
119
|
+
if (restoreTo instanceof HTMLElement && restoreTo.isConnected) restoreTo.focus();
|
|
120
|
+
resultBox.resolve?.(value);
|
|
121
|
+
}
|
|
122
|
+
function userDismiss() {
|
|
123
|
+
onDismiss?.();
|
|
124
|
+
close();
|
|
125
|
+
}
|
|
126
|
+
const wantEscape = triggers.includes("escape");
|
|
127
|
+
if (useDialog) {
|
|
128
|
+
const onCancel = (event) => {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
if (wantEscape) userDismiss();
|
|
131
|
+
};
|
|
132
|
+
wrapper.addEventListener("cancel", onCancel);
|
|
133
|
+
removers.push(() => wrapper.removeEventListener("cancel", onCancel));
|
|
134
|
+
} else if (wantEscape || trap) {
|
|
135
|
+
const onKeydown = (event) => {
|
|
136
|
+
if (!isTopmostFallback()) return;
|
|
137
|
+
if (wantEscape && event.key === "Escape") {
|
|
138
|
+
event.stopPropagation();
|
|
139
|
+
userDismiss();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (trap && event.key === "Tab") {
|
|
143
|
+
const items = focusable(wrapper);
|
|
144
|
+
if (items.length === 0) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const first = items[0];
|
|
149
|
+
const last = items[items.length - 1];
|
|
150
|
+
const active = document.activeElement;
|
|
151
|
+
const outside = !wrapper.contains(active);
|
|
152
|
+
if (event.shiftKey && (active === first || outside)) {
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
last.focus();
|
|
155
|
+
} else if (!event.shiftKey && (active === last || outside)) {
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
first.focus();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
document.addEventListener("keydown", onKeydown, true);
|
|
162
|
+
removers.push(() => document.removeEventListener("keydown", onKeydown, true));
|
|
163
|
+
}
|
|
164
|
+
if (triggers.includes("backdrop")) {
|
|
165
|
+
const onClick = (event) => {
|
|
166
|
+
if (!isTopmostFallback()) return;
|
|
167
|
+
if (event.target === wrapper) userDismiss();
|
|
168
|
+
};
|
|
169
|
+
wrapper.addEventListener("click", onClick);
|
|
170
|
+
removers.push(() => wrapper.removeEventListener("click", onClick));
|
|
171
|
+
}
|
|
172
|
+
if (triggers.includes("outside")) {
|
|
173
|
+
const ignore = outsideIgnore === void 0 ? [] : Array.isArray(outsideIgnore) ? outsideIgnore : [outsideIgnore];
|
|
174
|
+
const onDocClick = (event) => {
|
|
175
|
+
if (!isTopmostFallback()) return;
|
|
176
|
+
const target = event.target;
|
|
177
|
+
if (target === null) return;
|
|
178
|
+
if (wrapper.contains(target)) return;
|
|
179
|
+
if (ignore.some((el) => el === target || el.contains(target))) return;
|
|
180
|
+
userDismiss();
|
|
181
|
+
};
|
|
182
|
+
document.addEventListener("click", onDocClick, true);
|
|
183
|
+
removers.push(() => document.removeEventListener("click", onDocClick, true));
|
|
184
|
+
}
|
|
185
|
+
if (initialFocus !== false) {
|
|
186
|
+
if (typeof initialFocus === "string") {
|
|
187
|
+
wrapper.querySelector(initialFocus)?.focus();
|
|
188
|
+
} else {
|
|
189
|
+
const first = focusable(wrapper)[0];
|
|
190
|
+
if (first !== void 0) {
|
|
191
|
+
first.focus();
|
|
192
|
+
} else {
|
|
193
|
+
wrapper.tabIndex = -1;
|
|
194
|
+
wrapper.focus();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return { el: wrapper, close, result };
|
|
199
|
+
}
|
|
200
|
+
function popover(anchor, content, options = {}) {
|
|
201
|
+
const {
|
|
202
|
+
container,
|
|
203
|
+
className = "kerf-popover",
|
|
204
|
+
placement = "bottom",
|
|
205
|
+
align = "start",
|
|
206
|
+
gap = 4,
|
|
207
|
+
dismiss = ["outside"],
|
|
208
|
+
initialFocus = false,
|
|
209
|
+
outsideIgnore,
|
|
210
|
+
onDismiss,
|
|
211
|
+
native = false
|
|
212
|
+
} = options;
|
|
213
|
+
const extraIgnore = outsideIgnore === void 0 ? [] : Array.isArray(outsideIgnore) ? [...outsideIgnore] : [outsideIgnore];
|
|
214
|
+
const handle = overlay(content, {
|
|
215
|
+
container,
|
|
216
|
+
className,
|
|
217
|
+
dismiss,
|
|
218
|
+
trap: false,
|
|
219
|
+
initialFocus,
|
|
220
|
+
onDismiss,
|
|
221
|
+
outsideIgnore: [anchor, ...extraIgnore],
|
|
222
|
+
native
|
|
223
|
+
});
|
|
224
|
+
const stopReposition = autoReposition(handle.el, anchor, { placement, align, gap });
|
|
225
|
+
void handle.result.then(stopReposition);
|
|
226
|
+
return handle;
|
|
227
|
+
}
|
|
228
|
+
function tooltip(anchor, content, options = {}) {
|
|
229
|
+
const {
|
|
230
|
+
container,
|
|
231
|
+
className = "kerf-tooltip",
|
|
232
|
+
delay = 400,
|
|
233
|
+
hideDelay = 100,
|
|
234
|
+
role = "tooltip",
|
|
235
|
+
placement = "top",
|
|
236
|
+
align = "start",
|
|
237
|
+
gap = 4,
|
|
238
|
+
native = false
|
|
239
|
+
} = options;
|
|
240
|
+
const body = typeof content === "function" ? content : typeof content === "string" ? jsx("span", { class: `${className}__text`, children: content }) : content;
|
|
241
|
+
const timers = {};
|
|
242
|
+
let current;
|
|
243
|
+
let presence = 0;
|
|
244
|
+
function show() {
|
|
245
|
+
const handle = overlay(body, { container, className, dismiss: false, trap: false, initialFocus: false, native });
|
|
246
|
+
handle.el.setAttribute("role", role);
|
|
247
|
+
const stop = autoReposition(handle.el, anchor, { placement, align, gap });
|
|
248
|
+
current = { handle, stop };
|
|
249
|
+
}
|
|
250
|
+
function hide() {
|
|
251
|
+
if (current === void 0) return;
|
|
252
|
+
current.stop();
|
|
253
|
+
current.handle.close();
|
|
254
|
+
current = void 0;
|
|
255
|
+
}
|
|
256
|
+
const onEnter = (event) => {
|
|
257
|
+
presence |= event.type === "focus" ? 2 : 1;
|
|
258
|
+
if (timers.hide !== void 0) clearTimeout(timers.hide);
|
|
259
|
+
if (current !== void 0) return;
|
|
260
|
+
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
261
|
+
timers.show = setTimeout(show, delay);
|
|
262
|
+
};
|
|
263
|
+
const onLeave = (event) => {
|
|
264
|
+
presence &= event.type === "blur" ? -3 : -2;
|
|
265
|
+
if (presence) return;
|
|
266
|
+
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
267
|
+
if (current === void 0) return;
|
|
268
|
+
timers.hide = setTimeout(hide, hideDelay);
|
|
269
|
+
};
|
|
270
|
+
anchor.addEventListener("pointerenter", onEnter);
|
|
271
|
+
anchor.addEventListener("pointerleave", onLeave);
|
|
272
|
+
anchor.addEventListener("focus", onEnter);
|
|
273
|
+
anchor.addEventListener("blur", onLeave);
|
|
274
|
+
return () => {
|
|
275
|
+
anchor.removeEventListener("pointerenter", onEnter);
|
|
276
|
+
anchor.removeEventListener("pointerleave", onLeave);
|
|
277
|
+
anchor.removeEventListener("focus", onEnter);
|
|
278
|
+
anchor.removeEventListener("blur", onLeave);
|
|
279
|
+
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
280
|
+
if (timers.hide !== void 0) clearTimeout(timers.hide);
|
|
281
|
+
hide();
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/overlay-choice.ts
|
|
286
|
+
function choice(message, actions, options = {}) {
|
|
287
|
+
const { container, className = "kerf-overlay", title, defaultValue, native = false, render } = options;
|
|
288
|
+
const hasDefault = "defaultValue" in options;
|
|
289
|
+
const actionAttrs = actions.map((_, i) => ({ "data-choice": String(i) }));
|
|
290
|
+
const body = render !== void 0 ? render({ message, actions: actionAttrs }) : jsx("div", {
|
|
291
|
+
class: "kerf-choice",
|
|
54
292
|
children: [
|
|
55
|
-
title !== void 0 ? jsx("h2", { class: "kerf-
|
|
56
|
-
jsx("p", { class: "kerf-
|
|
293
|
+
title !== void 0 ? jsx("h2", { class: "kerf-choice__title", children: title }) : "",
|
|
294
|
+
jsx("p", { class: "kerf-choice__message", children: message }),
|
|
57
295
|
jsx("div", {
|
|
58
|
-
class: "kerf-
|
|
59
|
-
children:
|
|
60
|
-
|
|
61
|
-
jsx("button", {
|
|
296
|
+
class: "kerf-choice__actions",
|
|
297
|
+
children: actions.map(
|
|
298
|
+
(action, i) => jsx("button", {
|
|
62
299
|
type: "button",
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
children:
|
|
300
|
+
class: action.className !== void 0 ? `kerf-choice__action ${action.className}` : "kerf-choice__action",
|
|
301
|
+
...actionAttrs[i],
|
|
302
|
+
children: action.label
|
|
66
303
|
})
|
|
67
|
-
|
|
304
|
+
)
|
|
68
305
|
})
|
|
69
306
|
]
|
|
70
307
|
});
|
|
308
|
+
let resolveChoice;
|
|
309
|
+
const result = new Promise((resolve) => {
|
|
310
|
+
resolveChoice = resolve;
|
|
311
|
+
});
|
|
71
312
|
const handle = overlay(body, {
|
|
72
313
|
container,
|
|
73
|
-
className
|
|
314
|
+
className,
|
|
74
315
|
dismiss: ["escape", "backdrop"],
|
|
75
|
-
initialFocus:
|
|
316
|
+
initialFocus: "[data-choice]",
|
|
76
317
|
trap: true,
|
|
77
318
|
native
|
|
78
319
|
});
|
|
79
|
-
delegate(handle.el, "click", "[data-
|
|
80
|
-
|
|
320
|
+
delegate(handle.el, "click", "[data-choice]", (_event, el) => {
|
|
321
|
+
resolveChoice(actions[Number(el.getAttribute("data-choice"))].value);
|
|
322
|
+
handle.close();
|
|
81
323
|
});
|
|
82
|
-
|
|
324
|
+
if (hasDefault) {
|
|
325
|
+
handle.el.addEventListener("keydown", (event) => {
|
|
326
|
+
if (event.key === "Enter") {
|
|
327
|
+
event.preventDefault();
|
|
328
|
+
resolveChoice(defaultValue);
|
|
329
|
+
handle.close();
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
void handle.result.then(() => resolveChoice(null));
|
|
334
|
+
return result;
|
|
83
335
|
}
|
|
84
|
-
|
|
336
|
+
|
|
337
|
+
// src/overlay-confirm.ts
|
|
338
|
+
function confirm(message, options = {}) {
|
|
85
339
|
const {
|
|
86
340
|
container,
|
|
87
341
|
className = "kerf-overlay",
|
|
88
342
|
title,
|
|
89
|
-
defaultValue = "",
|
|
90
|
-
placeholder,
|
|
91
|
-
inputType = "text",
|
|
92
343
|
okText = "OK",
|
|
93
344
|
cancelText = "Cancel",
|
|
94
|
-
|
|
345
|
+
danger = false,
|
|
95
346
|
native = false,
|
|
96
347
|
render
|
|
97
348
|
} = options;
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
type: inputType,
|
|
101
|
-
value: defaultValue,
|
|
102
|
-
...placeholder !== void 0 ? { placeholder } : {}
|
|
103
|
-
};
|
|
104
|
-
const body = render !== void 0 ? render({
|
|
105
|
-
message,
|
|
106
|
-
input: inputAttrs,
|
|
107
|
-
error: { "data-prompt-error": "" },
|
|
108
|
-
ok: { "data-prompt": "ok" },
|
|
109
|
-
cancel: { "data-prompt": "cancel" }
|
|
110
|
-
}) : jsx("div", {
|
|
111
|
-
class: "kerf-prompt",
|
|
349
|
+
const body = render !== void 0 ? render({ message, ok: { "data-confirm": "ok" }, cancel: { "data-confirm": "cancel" } }) : jsx("div", {
|
|
350
|
+
class: "kerf-confirm",
|
|
112
351
|
children: [
|
|
113
|
-
title !== void 0 ? jsx("h2", { class: "kerf-
|
|
114
|
-
jsx("
|
|
115
|
-
jsx("input", { class: "kerf-prompt__input", ...inputAttrs }),
|
|
116
|
-
jsx("p", { class: "kerf-prompt__error", "data-prompt-error": "", children: "" }),
|
|
352
|
+
title !== void 0 ? jsx("h2", { class: "kerf-confirm__title", children: title }) : "",
|
|
353
|
+
jsx("p", { class: "kerf-confirm__message", children: message }),
|
|
117
354
|
jsx("div", {
|
|
118
|
-
class: "kerf-
|
|
355
|
+
class: "kerf-confirm__actions",
|
|
119
356
|
children: [
|
|
120
|
-
jsx("button", { type: "button", "data-
|
|
357
|
+
jsx("button", { type: "button", "data-confirm": "cancel", children: cancelText }),
|
|
121
358
|
jsx("button", {
|
|
122
359
|
type: "button",
|
|
123
|
-
"data-
|
|
124
|
-
class: "kerf-
|
|
360
|
+
"data-confirm": "ok",
|
|
361
|
+
class: "kerf-confirm__ok",
|
|
125
362
|
children: okText
|
|
126
363
|
})
|
|
127
364
|
]
|
|
@@ -130,40 +367,19 @@ function prompt(message, options = {}) {
|
|
|
130
367
|
});
|
|
131
368
|
const handle = overlay(body, {
|
|
132
369
|
container,
|
|
133
|
-
className,
|
|
370
|
+
className: danger ? `${className} kerf-confirm--danger` : className,
|
|
134
371
|
dismiss: ["escape", "backdrop"],
|
|
135
|
-
initialFocus:
|
|
372
|
+
initialFocus: '[data-confirm="ok"]',
|
|
136
373
|
trap: true,
|
|
137
374
|
native
|
|
138
375
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (errorEl !== null) errorEl.hidden = true;
|
|
142
|
-
function attemptOk() {
|
|
143
|
-
const value = input.value;
|
|
144
|
-
const error = validate?.(value);
|
|
145
|
-
if (typeof error === "string" && error.length > 0) {
|
|
146
|
-
if (errorEl !== null) {
|
|
147
|
-
errorEl.textContent = error;
|
|
148
|
-
errorEl.hidden = false;
|
|
149
|
-
}
|
|
150
|
-
input.focus();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
handle.close(value);
|
|
154
|
-
}
|
|
155
|
-
delegate(handle.el, "click", "[data-prompt]", (_event, el) => {
|
|
156
|
-
if (el.getAttribute("data-prompt") === "ok") attemptOk();
|
|
157
|
-
else handle.close(null);
|
|
158
|
-
});
|
|
159
|
-
handle.el.addEventListener("keydown", (event) => {
|
|
160
|
-
if (event.key === "Enter" && event.target === input) {
|
|
161
|
-
event.preventDefault();
|
|
162
|
-
attemptOk();
|
|
163
|
-
}
|
|
376
|
+
delegate(handle.el, "click", "[data-confirm]", (_event, el) => {
|
|
377
|
+
handle.close(el.getAttribute("data-confirm") === "ok");
|
|
164
378
|
});
|
|
165
|
-
return handle.result.then((value) =>
|
|
379
|
+
return handle.result.then((value) => value === true);
|
|
166
380
|
}
|
|
381
|
+
|
|
382
|
+
// src/overlay-form.ts
|
|
167
383
|
function form(fields, options = {}) {
|
|
168
384
|
const {
|
|
169
385
|
container,
|
|
@@ -226,13 +442,19 @@ function form(fields, options = {}) {
|
|
|
226
442
|
trap: true,
|
|
227
443
|
native
|
|
228
444
|
});
|
|
229
|
-
const byAttr = (attr, name) => Array.from(handle.el.querySelectorAll(`[${attr}]`)).find(
|
|
230
|
-
(el) => el.getAttribute(attr) === name
|
|
231
|
-
);
|
|
232
445
|
const errorFor = (name) => Array.from(handle.el.querySelectorAll("[data-field-error]")).find(
|
|
233
446
|
(el) => el.getAttribute("data-field-error") === name
|
|
234
447
|
) ?? null;
|
|
448
|
+
const inputFor = (name) => {
|
|
449
|
+
const input = Array.from(handle.el.querySelectorAll("input[data-field]")).find(
|
|
450
|
+
(el) => el.getAttribute("data-field") === name
|
|
451
|
+
);
|
|
452
|
+
if (input !== void 0) return input;
|
|
453
|
+
handle.close(null);
|
|
454
|
+
throw new Error(`form(): render missing <input data-field="${name}">.`);
|
|
455
|
+
};
|
|
235
456
|
for (const field of fields) {
|
|
457
|
+
inputFor(field.name);
|
|
236
458
|
const errorEl = errorFor(field.name);
|
|
237
459
|
if (errorEl !== null) errorEl.hidden = true;
|
|
238
460
|
}
|
|
@@ -240,7 +462,7 @@ function form(fields, options = {}) {
|
|
|
240
462
|
const record = {};
|
|
241
463
|
let firstInvalid = null;
|
|
242
464
|
for (const field of fields) {
|
|
243
|
-
const el =
|
|
465
|
+
const el = inputFor(field.name);
|
|
244
466
|
const value = el.value;
|
|
245
467
|
record[field.name] = value;
|
|
246
468
|
const error = field.validate?.(value);
|
|
@@ -275,55 +497,95 @@ function form(fields, options = {}) {
|
|
|
275
497
|
(value) => value !== null && typeof value === "object" ? value : null
|
|
276
498
|
);
|
|
277
499
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
500
|
+
|
|
501
|
+
// src/overlay-prompt.ts
|
|
502
|
+
function prompt(message, options = {}) {
|
|
503
|
+
const {
|
|
504
|
+
container,
|
|
505
|
+
className = "kerf-overlay",
|
|
506
|
+
title,
|
|
507
|
+
defaultValue = "",
|
|
508
|
+
placeholder,
|
|
509
|
+
inputType = "text",
|
|
510
|
+
okText = "OK",
|
|
511
|
+
cancelText = "Cancel",
|
|
512
|
+
validate,
|
|
513
|
+
native = false,
|
|
514
|
+
render
|
|
515
|
+
} = options;
|
|
516
|
+
const inputAttrs = {
|
|
517
|
+
"data-prompt-input": "",
|
|
518
|
+
type: inputType,
|
|
519
|
+
value: defaultValue,
|
|
520
|
+
...placeholder !== void 0 ? { placeholder } : {}
|
|
521
|
+
};
|
|
522
|
+
const body = render !== void 0 ? render({
|
|
523
|
+
message,
|
|
524
|
+
input: inputAttrs,
|
|
525
|
+
error: { "data-prompt-error": "" },
|
|
526
|
+
ok: { "data-prompt": "ok" },
|
|
527
|
+
cancel: { "data-prompt": "cancel" }
|
|
528
|
+
}) : jsx("div", {
|
|
529
|
+
class: "kerf-prompt",
|
|
284
530
|
children: [
|
|
285
|
-
title !== void 0 ? jsx("h2", { class: "kerf-
|
|
286
|
-
jsx("
|
|
531
|
+
title !== void 0 ? jsx("h2", { class: "kerf-prompt__title", children: title }) : "",
|
|
532
|
+
jsx("label", { class: "kerf-prompt__message", children: message }),
|
|
533
|
+
jsx("input", { class: "kerf-prompt__input", ...inputAttrs }),
|
|
534
|
+
jsx("p", { class: "kerf-prompt__error", "data-prompt-error": "", children: "" }),
|
|
287
535
|
jsx("div", {
|
|
288
|
-
class: "kerf-
|
|
289
|
-
children:
|
|
290
|
-
(
|
|
536
|
+
class: "kerf-prompt__actions",
|
|
537
|
+
children: [
|
|
538
|
+
jsx("button", { type: "button", "data-prompt": "cancel", children: cancelText }),
|
|
539
|
+
jsx("button", {
|
|
291
540
|
type: "button",
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
children:
|
|
541
|
+
"data-prompt": "ok",
|
|
542
|
+
class: "kerf-prompt__ok",
|
|
543
|
+
children: okText
|
|
295
544
|
})
|
|
296
|
-
|
|
545
|
+
]
|
|
297
546
|
})
|
|
298
547
|
]
|
|
299
548
|
});
|
|
300
|
-
let resolveChoice;
|
|
301
|
-
const result = new Promise((resolve) => {
|
|
302
|
-
resolveChoice = resolve;
|
|
303
|
-
});
|
|
304
549
|
const handle = overlay(body, {
|
|
305
550
|
container,
|
|
306
551
|
className,
|
|
307
552
|
dismiss: ["escape", "backdrop"],
|
|
308
|
-
initialFocus: "[data-
|
|
553
|
+
initialFocus: "[data-prompt-input]",
|
|
309
554
|
trap: true,
|
|
310
555
|
native
|
|
311
556
|
});
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
handle.close();
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
557
|
+
const input = handle.el.querySelector("input[data-prompt-input]");
|
|
558
|
+
if (input === null) {
|
|
559
|
+
handle.close(null);
|
|
560
|
+
throw new Error("prompt(): render missing <input data-prompt-input>.");
|
|
561
|
+
}
|
|
562
|
+
const promptInput = input;
|
|
563
|
+
const errorEl = handle.el.querySelector("[data-prompt-error]");
|
|
564
|
+
if (errorEl !== null) errorEl.hidden = true;
|
|
565
|
+
function attemptOk() {
|
|
566
|
+
const value = promptInput.value;
|
|
567
|
+
const error = validate?.(value);
|
|
568
|
+
if (typeof error === "string" && error.length > 0) {
|
|
569
|
+
if (errorEl !== null) {
|
|
570
|
+
errorEl.textContent = error;
|
|
571
|
+
errorEl.hidden = false;
|
|
322
572
|
}
|
|
323
|
-
|
|
573
|
+
promptInput.focus();
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
handle.close(value);
|
|
324
577
|
}
|
|
325
|
-
|
|
326
|
-
|
|
578
|
+
delegate(handle.el, "click", "[data-prompt]", (_event, el) => {
|
|
579
|
+
if (el.getAttribute("data-prompt") === "ok") attemptOk();
|
|
580
|
+
else handle.close(null);
|
|
581
|
+
});
|
|
582
|
+
handle.el.addEventListener("keydown", (event) => {
|
|
583
|
+
if (event.key === "Enter" && event.target === promptInput) {
|
|
584
|
+
event.preventDefault();
|
|
585
|
+
attemptOk();
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
return handle.result.then((value) => typeof value === "string" ? value : null);
|
|
327
589
|
}
|
|
328
590
|
|
|
329
591
|
// src/overlay-toast.ts
|
|
@@ -364,7 +626,8 @@ function toast(content, options = {}) {
|
|
|
364
626
|
if (variant !== void 0) el.classList.add(`${className}--${variant}`);
|
|
365
627
|
el.setAttribute("role", role);
|
|
366
628
|
region.appendChild(el);
|
|
367
|
-
const
|
|
629
|
+
const render = typeof content === "function" ? content : () => typeof content === "string" ? escapeHtml(content) : content;
|
|
630
|
+
const disposeMount = mount(el, render);
|
|
368
631
|
const state = { dismissed: false, removed: false, timer: void 0, exitTimer: void 0 };
|
|
369
632
|
if (enterClass !== void 0) {
|
|
370
633
|
globalThis.requestAnimationFrame(() => {
|
|
@@ -406,229 +669,6 @@ function toast(content, options = {}) {
|
|
|
406
669
|
return { el, dismiss };
|
|
407
670
|
}
|
|
408
671
|
|
|
409
|
-
// src/overlay.ts
|
|
410
|
-
var FOCUSABLE = 'a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),iframe,[tabindex]:not([tabindex="-1"]),[contenteditable="true"]';
|
|
411
|
-
function focusable(root) {
|
|
412
|
-
return Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
413
|
-
(el) => !el.hasAttribute("hidden")
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
function supportsDialog() {
|
|
417
|
-
return typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
|
|
418
|
-
}
|
|
419
|
-
function supportsPopover() {
|
|
420
|
-
return typeof HTMLElement !== "undefined" && typeof HTMLElement.prototype.showPopover === "function";
|
|
421
|
-
}
|
|
422
|
-
function overlay(content, options = {}) {
|
|
423
|
-
const {
|
|
424
|
-
container = document.body,
|
|
425
|
-
className = "kerf-overlay",
|
|
426
|
-
dismiss = ["escape", "backdrop"],
|
|
427
|
-
initialFocus = true,
|
|
428
|
-
trap = true,
|
|
429
|
-
role = "dialog",
|
|
430
|
-
onDismiss,
|
|
431
|
-
outsideIgnore,
|
|
432
|
-
native = false
|
|
433
|
-
} = options;
|
|
434
|
-
const triggers = dismiss === false ? [] : Array.isArray(dismiss) ? dismiss : [dismiss];
|
|
435
|
-
const restoreTo = document.activeElement;
|
|
436
|
-
const useDialog = native && trap && supportsDialog();
|
|
437
|
-
const usePopover = native && !trap && supportsPopover();
|
|
438
|
-
const wrapper = useDialog ? document.createElement("dialog") : document.createElement("div");
|
|
439
|
-
wrapper.className = className;
|
|
440
|
-
if (usePopover) wrapper.setAttribute("popover", "manual");
|
|
441
|
-
if (trap && !useDialog) {
|
|
442
|
-
wrapper.setAttribute("role", role);
|
|
443
|
-
wrapper.setAttribute("aria-modal", "true");
|
|
444
|
-
}
|
|
445
|
-
container.appendChild(wrapper);
|
|
446
|
-
const disposeMount = mount(wrapper, typeof content === "function" ? content : () => content);
|
|
447
|
-
let nativeOpened = false;
|
|
448
|
-
if (useDialog) {
|
|
449
|
-
wrapper.showModal();
|
|
450
|
-
nativeOpened = true;
|
|
451
|
-
} else if (usePopover) {
|
|
452
|
-
wrapper.showPopover();
|
|
453
|
-
wrapper.style.inset = "auto";
|
|
454
|
-
nativeOpened = true;
|
|
455
|
-
}
|
|
456
|
-
const removers = [];
|
|
457
|
-
const resultBox = {};
|
|
458
|
-
const result = new Promise((resolve) => {
|
|
459
|
-
resultBox.resolve = resolve;
|
|
460
|
-
});
|
|
461
|
-
const state = { closed: false };
|
|
462
|
-
function close(value) {
|
|
463
|
-
if (state.closed) return;
|
|
464
|
-
state.closed = true;
|
|
465
|
-
for (const remove of removers) remove();
|
|
466
|
-
disposeMount();
|
|
467
|
-
if (nativeOpened) {
|
|
468
|
-
nativeOpened = false;
|
|
469
|
-
if (useDialog) wrapper.close();
|
|
470
|
-
else wrapper.hidePopover();
|
|
471
|
-
}
|
|
472
|
-
wrapper.remove();
|
|
473
|
-
if (restoreTo instanceof HTMLElement && restoreTo.isConnected) restoreTo.focus();
|
|
474
|
-
resultBox.resolve?.(value);
|
|
475
|
-
}
|
|
476
|
-
function userDismiss() {
|
|
477
|
-
onDismiss?.();
|
|
478
|
-
close();
|
|
479
|
-
}
|
|
480
|
-
const wantEscape = triggers.includes("escape");
|
|
481
|
-
if (useDialog) {
|
|
482
|
-
const onCancel = (event) => {
|
|
483
|
-
event.preventDefault();
|
|
484
|
-
if (wantEscape) userDismiss();
|
|
485
|
-
};
|
|
486
|
-
wrapper.addEventListener("cancel", onCancel);
|
|
487
|
-
removers.push(() => wrapper.removeEventListener("cancel", onCancel));
|
|
488
|
-
} else if (wantEscape || trap) {
|
|
489
|
-
const onKeydown = (event) => {
|
|
490
|
-
if (wantEscape && event.key === "Escape") {
|
|
491
|
-
event.stopPropagation();
|
|
492
|
-
userDismiss();
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
if (trap && event.key === "Tab") {
|
|
496
|
-
const items = focusable(wrapper);
|
|
497
|
-
if (items.length === 0) {
|
|
498
|
-
event.preventDefault();
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
const first = items[0];
|
|
502
|
-
const last = items[items.length - 1];
|
|
503
|
-
const active = document.activeElement;
|
|
504
|
-
const outside = !wrapper.contains(active);
|
|
505
|
-
if (event.shiftKey && (active === first || outside)) {
|
|
506
|
-
event.preventDefault();
|
|
507
|
-
last.focus();
|
|
508
|
-
} else if (!event.shiftKey && (active === last || outside)) {
|
|
509
|
-
event.preventDefault();
|
|
510
|
-
first.focus();
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
document.addEventListener("keydown", onKeydown, true);
|
|
515
|
-
removers.push(() => document.removeEventListener("keydown", onKeydown, true));
|
|
516
|
-
}
|
|
517
|
-
if (triggers.includes("backdrop")) {
|
|
518
|
-
const onClick = (event) => {
|
|
519
|
-
if (event.target === wrapper) userDismiss();
|
|
520
|
-
};
|
|
521
|
-
wrapper.addEventListener("click", onClick);
|
|
522
|
-
removers.push(() => wrapper.removeEventListener("click", onClick));
|
|
523
|
-
}
|
|
524
|
-
if (triggers.includes("outside")) {
|
|
525
|
-
const ignore = outsideIgnore === void 0 ? [] : Array.isArray(outsideIgnore) ? outsideIgnore : [outsideIgnore];
|
|
526
|
-
const onDocClick = (event) => {
|
|
527
|
-
const target = event.target;
|
|
528
|
-
if (target === null) return;
|
|
529
|
-
if (wrapper.contains(target)) return;
|
|
530
|
-
if (ignore.some((el) => el === target || el.contains(target))) return;
|
|
531
|
-
userDismiss();
|
|
532
|
-
};
|
|
533
|
-
document.addEventListener("click", onDocClick, true);
|
|
534
|
-
removers.push(() => document.removeEventListener("click", onDocClick, true));
|
|
535
|
-
}
|
|
536
|
-
if (initialFocus !== false) {
|
|
537
|
-
if (typeof initialFocus === "string") {
|
|
538
|
-
wrapper.querySelector(initialFocus)?.focus();
|
|
539
|
-
} else {
|
|
540
|
-
const first = focusable(wrapper)[0];
|
|
541
|
-
if (first !== void 0) {
|
|
542
|
-
first.focus();
|
|
543
|
-
} else {
|
|
544
|
-
wrapper.tabIndex = -1;
|
|
545
|
-
wrapper.focus();
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
return { el: wrapper, close, result };
|
|
550
|
-
}
|
|
551
|
-
function popover(anchor, content, options = {}) {
|
|
552
|
-
const {
|
|
553
|
-
container,
|
|
554
|
-
className = "kerf-popover",
|
|
555
|
-
placement = "bottom",
|
|
556
|
-
align = "start",
|
|
557
|
-
gap = 4,
|
|
558
|
-
dismiss = ["outside"],
|
|
559
|
-
initialFocus = false,
|
|
560
|
-
outsideIgnore,
|
|
561
|
-
onDismiss,
|
|
562
|
-
native = false
|
|
563
|
-
} = options;
|
|
564
|
-
const extraIgnore = outsideIgnore === void 0 ? [] : Array.isArray(outsideIgnore) ? [...outsideIgnore] : [outsideIgnore];
|
|
565
|
-
const handle = overlay(content, {
|
|
566
|
-
container,
|
|
567
|
-
className,
|
|
568
|
-
dismiss,
|
|
569
|
-
trap: false,
|
|
570
|
-
initialFocus,
|
|
571
|
-
onDismiss,
|
|
572
|
-
outsideIgnore: [anchor, ...extraIgnore],
|
|
573
|
-
native
|
|
574
|
-
});
|
|
575
|
-
const stopReposition = autoReposition(handle.el, anchor, { placement, align, gap });
|
|
576
|
-
void handle.result.then(stopReposition);
|
|
577
|
-
return handle;
|
|
578
|
-
}
|
|
579
|
-
function tooltip(anchor, content, options = {}) {
|
|
580
|
-
const {
|
|
581
|
-
container,
|
|
582
|
-
className = "kerf-tooltip",
|
|
583
|
-
delay = 400,
|
|
584
|
-
hideDelay = 100,
|
|
585
|
-
role = "tooltip",
|
|
586
|
-
placement = "top",
|
|
587
|
-
align = "start",
|
|
588
|
-
gap = 4,
|
|
589
|
-
native = false
|
|
590
|
-
} = options;
|
|
591
|
-
const body = typeof content === "function" ? content : typeof content === "string" ? jsx("span", { class: `${className}__text`, children: content }) : content;
|
|
592
|
-
const timers = {};
|
|
593
|
-
let current;
|
|
594
|
-
function show() {
|
|
595
|
-
const handle = overlay(body, { container, className, dismiss: false, trap: false, initialFocus: false, native });
|
|
596
|
-
handle.el.setAttribute("role", role);
|
|
597
|
-
const stop = autoReposition(handle.el, anchor, { placement, align, gap });
|
|
598
|
-
current = { handle, stop };
|
|
599
|
-
}
|
|
600
|
-
function hide() {
|
|
601
|
-
if (current === void 0) return;
|
|
602
|
-
current.stop();
|
|
603
|
-
current.handle.close();
|
|
604
|
-
current = void 0;
|
|
605
|
-
}
|
|
606
|
-
const onEnter = () => {
|
|
607
|
-
if (timers.hide !== void 0) clearTimeout(timers.hide);
|
|
608
|
-
if (current !== void 0) return;
|
|
609
|
-
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
610
|
-
timers.show = setTimeout(show, delay);
|
|
611
|
-
};
|
|
612
|
-
const onLeave = () => {
|
|
613
|
-
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
614
|
-
if (current === void 0) return;
|
|
615
|
-
timers.hide = setTimeout(hide, hideDelay);
|
|
616
|
-
};
|
|
617
|
-
anchor.addEventListener("pointerenter", onEnter);
|
|
618
|
-
anchor.addEventListener("pointerleave", onLeave);
|
|
619
|
-
anchor.addEventListener("focus", onEnter);
|
|
620
|
-
anchor.addEventListener("blur", onLeave);
|
|
621
|
-
return () => {
|
|
622
|
-
anchor.removeEventListener("pointerenter", onEnter);
|
|
623
|
-
anchor.removeEventListener("pointerleave", onLeave);
|
|
624
|
-
anchor.removeEventListener("focus", onEnter);
|
|
625
|
-
anchor.removeEventListener("blur", onLeave);
|
|
626
|
-
if (timers.show !== void 0) clearTimeout(timers.show);
|
|
627
|
-
if (timers.hide !== void 0) clearTimeout(timers.hide);
|
|
628
|
-
hide();
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
|
|
632
672
|
export { autoReposition, choice, confirm, form, overlay, popover, positionAnchored, prompt, toast, tooltip };
|
|
633
|
-
|
|
673
|
+
|
|
634
674
|
//# sourceMappingURL=overlay.js.map
|