@surdeddd/bottom-sheet 0.2.0 → 0.4.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.
- package/README.md +51 -21
- package/dist/{BottomSheetEngine-CIT9Htti.d.cts → BottomSheetEngine-BJrH7qY3.d.cts} +105 -3
- package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-L05jGZvU.d.ts} +105 -3
- package/dist/element.cjs +1170 -196
- package/dist/element.d.cts +29 -5
- package/dist/element.d.ts +29 -5
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +1170 -196
- package/dist/index.cjs +1051 -220
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +1049 -221
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +181 -37
- package/dist/overlay.d.cts +13 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +181 -37
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +966 -195
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +967 -196
- package/dist/react.cjs +1242 -272
- package/dist/react.d.cts +47 -5
- package/dist/react.d.ts +47 -5
- package/dist/react.js +1242 -272
- package/dist/solid.cjs +992 -236
- package/dist/solid.d.cts +299 -4
- package/dist/solid.d.ts +299 -4
- package/dist/solid.js +993 -237
- package/dist/solid.source.jsx +3476 -0
- package/dist/styles.css +67 -66
- package/dist/svelte-core.cjs +3415 -0
- package/dist/svelte-core.js +3413 -0
- package/dist/svelte-src/BottomSheet.svelte +308 -0
- package/dist/svelte-src/index.js +2 -0
- package/dist/svelte.cjs +1034 -207
- package/dist/svelte.d.cts +121 -0
- package/dist/svelte.d.ts +28 -3
- package/dist/svelte.js +1035 -208
- package/dist/vue.cjs +1191 -205
- package/dist/vue.d.cts +127 -0
- package/dist/vue.d.ts +57 -4
- package/dist/vue.js +1192 -206
- package/package.json +105 -45
package/dist/overlay.cjs
CHANGED
|
@@ -22,16 +22,52 @@ var SheetStack = class {
|
|
|
22
22
|
this.entries.splice(idx, 1);
|
|
23
23
|
this.recompute();
|
|
24
24
|
}
|
|
25
|
+
promote(id) {
|
|
26
|
+
const idx = this.entries.findIndex((e) => e.id === id);
|
|
27
|
+
if (idx === -1) return;
|
|
28
|
+
if (idx !== this.entries.length - 1) {
|
|
29
|
+
const [entry] = this.entries.splice(idx, 1);
|
|
30
|
+
this.entries.push(entry);
|
|
31
|
+
}
|
|
32
|
+
this.recompute();
|
|
33
|
+
}
|
|
34
|
+
update() {
|
|
35
|
+
this.recompute();
|
|
36
|
+
}
|
|
25
37
|
size() {
|
|
26
38
|
return this.entries.length;
|
|
27
39
|
}
|
|
40
|
+
depthOf(id) {
|
|
41
|
+
const open = [];
|
|
42
|
+
for (const entry of this.entries) {
|
|
43
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
44
|
+
}
|
|
45
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
46
|
+
if (idx === -1) return 0;
|
|
47
|
+
return open.length - 1 - idx;
|
|
48
|
+
}
|
|
28
49
|
clear() {
|
|
29
50
|
this.entries = [];
|
|
30
51
|
}
|
|
31
52
|
recompute() {
|
|
53
|
+
let top = null;
|
|
54
|
+
const open = [];
|
|
55
|
+
for (const entry of this.entries) {
|
|
56
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
57
|
+
top = entry;
|
|
58
|
+
open.push(entry);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!top && this.entries.length > 0) {
|
|
62
|
+
top = this.entries[this.entries.length - 1];
|
|
63
|
+
}
|
|
32
64
|
this.entries.forEach((entry, i) => {
|
|
33
65
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
34
|
-
entry.setIsTop(
|
|
66
|
+
entry.setIsTop(entry === top);
|
|
67
|
+
if (entry.setDepth) {
|
|
68
|
+
const openIdx = open.indexOf(entry);
|
|
69
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
70
|
+
}
|
|
35
71
|
});
|
|
36
72
|
}
|
|
37
73
|
};
|
|
@@ -76,7 +112,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
76
112
|
var resolveSnap = (point, mode, measureFit) => {
|
|
77
113
|
if (typeof point === "number") return Math.max(0, point);
|
|
78
114
|
if (point === "full") return viewportSize();
|
|
79
|
-
if (point === "fit"
|
|
115
|
+
if (point === "fit" || point === "content") {
|
|
116
|
+
return Math.max(0, 0);
|
|
117
|
+
}
|
|
80
118
|
const pctMatch = point.match(PERCENT);
|
|
81
119
|
if (pctMatch) {
|
|
82
120
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -154,9 +192,13 @@ var isVisible = (el) => {
|
|
|
154
192
|
var focusables = (root) => Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
155
193
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
156
194
|
);
|
|
195
|
+
var trapStack = [];
|
|
157
196
|
var installFocusTrap = (container, options = {}) => {
|
|
158
197
|
if (typeof document === "undefined") return () => {
|
|
159
198
|
};
|
|
199
|
+
const token = {};
|
|
200
|
+
trapStack.push(token);
|
|
201
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
160
202
|
const previouslyFocused = document.activeElement;
|
|
161
203
|
const focusInitial = () => {
|
|
162
204
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -164,6 +206,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
164
206
|
};
|
|
165
207
|
focusInitial();
|
|
166
208
|
const handleKey = (e) => {
|
|
209
|
+
if (!isActive()) return;
|
|
167
210
|
if (e.key === "Escape" && options.onEscape) {
|
|
168
211
|
options.onEscape();
|
|
169
212
|
return;
|
|
@@ -186,6 +229,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
186
229
|
}
|
|
187
230
|
};
|
|
188
231
|
const handleFocusIn = (e) => {
|
|
232
|
+
if (!isActive()) return;
|
|
189
233
|
const target = e.target;
|
|
190
234
|
if (target && !container.contains(target)) {
|
|
191
235
|
const list = focusables(container);
|
|
@@ -198,6 +242,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
198
242
|
return () => {
|
|
199
243
|
if (released) return;
|
|
200
244
|
released = true;
|
|
245
|
+
const idx = trapStack.indexOf(token);
|
|
246
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
201
247
|
document.removeEventListener("keydown", handleKey, true);
|
|
202
248
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
203
249
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -253,11 +299,17 @@ function createInertSiblings(rootProvider) {
|
|
|
253
299
|
return {
|
|
254
300
|
apply() {
|
|
255
301
|
if (typeof document === "undefined") return;
|
|
256
|
-
|
|
257
|
-
|
|
302
|
+
let top = rootProvider();
|
|
303
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
304
|
+
top = top.parentElement;
|
|
305
|
+
}
|
|
306
|
+
const parent = top.parentElement ?? document.body;
|
|
258
307
|
for (const child of Array.from(parent.children)) {
|
|
259
|
-
if (child ===
|
|
308
|
+
if (child === top) continue;
|
|
260
309
|
if (child.hasAttribute("inert")) continue;
|
|
310
|
+
if (child.classList.contains("bs-backdrop") || child.classList.contains("bs-screen") || child.classList.contains("bs-root")) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
261
313
|
child.setAttribute("inert", "");
|
|
262
314
|
tracked.push(child);
|
|
263
315
|
}
|
|
@@ -273,7 +325,6 @@ function createInertSiblings(rootProvider) {
|
|
|
273
325
|
var LifecycleController = class {
|
|
274
326
|
constructor(deps, opts) {
|
|
275
327
|
__publicField(this, "element");
|
|
276
|
-
__publicField(this, "closeFn");
|
|
277
328
|
__publicField(this, "focusTrapEnabled");
|
|
278
329
|
__publicField(this, "initialFocus");
|
|
279
330
|
__publicField(this, "closeOnEscape");
|
|
@@ -287,7 +338,6 @@ var LifecycleController = class {
|
|
|
287
338
|
__publicField(this, "installed", false);
|
|
288
339
|
__publicField(this, "destroyed", false);
|
|
289
340
|
this.element = deps.element;
|
|
290
|
-
this.closeFn = deps.close;
|
|
291
341
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
292
342
|
this.initialFocus = opts.initialFocus;
|
|
293
343
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -297,6 +347,9 @@ var LifecycleController = class {
|
|
|
297
347
|
this.returnFocus = opts.returnFocus;
|
|
298
348
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
299
349
|
}
|
|
350
|
+
get isInstalled() {
|
|
351
|
+
return this.installed;
|
|
352
|
+
}
|
|
300
353
|
install() {
|
|
301
354
|
if (this.destroyed) return;
|
|
302
355
|
this.installed = true;
|
|
@@ -305,8 +358,7 @@ var LifecycleController = class {
|
|
|
305
358
|
}
|
|
306
359
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
307
360
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
308
|
-
initialFocus: this.initialFocus
|
|
309
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
361
|
+
initialFocus: this.initialFocus
|
|
310
362
|
});
|
|
311
363
|
}
|
|
312
364
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -326,7 +378,7 @@ var LifecycleController = class {
|
|
|
326
378
|
this.releaseScrollLock = null;
|
|
327
379
|
this.inertSiblings.remove();
|
|
328
380
|
if (this.returnFocus) {
|
|
329
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
381
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
330
382
|
target?.focus?.();
|
|
331
383
|
}
|
|
332
384
|
}
|
|
@@ -336,6 +388,12 @@ var LifecycleController = class {
|
|
|
336
388
|
}
|
|
337
389
|
};
|
|
338
390
|
|
|
391
|
+
// src/core/animation/animation.ts
|
|
392
|
+
var prefersReducedMotion = () => {
|
|
393
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
394
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
395
|
+
};
|
|
396
|
+
|
|
339
397
|
// src/core/overlay.ts
|
|
340
398
|
var OVERLAY_PRESETS = Object.freeze({
|
|
341
399
|
sheet: Object.freeze({
|
|
@@ -415,6 +473,10 @@ var OverlayEngine = class {
|
|
|
415
473
|
__publicField(this, "closeOnOutsidePointerEnabled");
|
|
416
474
|
__publicField(this, "detachOutsidePointer", null);
|
|
417
475
|
__publicField(this, "detachSwipe", null);
|
|
476
|
+
__publicField(this, "respectReducedMotionEnabled");
|
|
477
|
+
__publicField(this, "isTop", true);
|
|
478
|
+
__publicField(this, "backPushed", false);
|
|
479
|
+
__publicField(this, "movedToTarget", false);
|
|
418
480
|
__publicField(this, "onOpenCb");
|
|
419
481
|
__publicField(this, "onCloseCb");
|
|
420
482
|
__publicField(this, "isOpen_", false);
|
|
@@ -451,6 +513,7 @@ var OverlayEngine = class {
|
|
|
451
513
|
this.mountTarget = opts.mountTo;
|
|
452
514
|
this.peekRaw = opts.peek;
|
|
453
515
|
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer ?? false;
|
|
516
|
+
this.respectReducedMotionEnabled = opts.respectReducedMotion ?? true;
|
|
454
517
|
this.onOpenCb = opts.onOpen;
|
|
455
518
|
this.onCloseCb = opts.onClose;
|
|
456
519
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
@@ -498,15 +561,17 @@ var OverlayEngine = class {
|
|
|
498
561
|
this.emit("before-open", void 0);
|
|
499
562
|
this.isOpen_ = true;
|
|
500
563
|
this.isAnimating_ = true;
|
|
564
|
+
sheetStack.promote(this.id);
|
|
501
565
|
this.element.removeAttribute("hidden");
|
|
502
566
|
this.element.setAttribute("data-state", "entering");
|
|
503
567
|
if (this.focusTrapEnabled) {
|
|
504
568
|
this.element.setAttribute("aria-modal", "true");
|
|
505
569
|
}
|
|
506
|
-
const
|
|
570
|
+
const dur = this.effectiveDuration();
|
|
571
|
+
const transitionStr = `transform ${dur}ms ${this.enterEasing}, opacity ${dur}ms ease-out`;
|
|
507
572
|
this.element.style.transition = transitionStr;
|
|
508
573
|
if (this.backdrop) {
|
|
509
|
-
this.backdrop.style.transition = `opacity ${
|
|
574
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-out`;
|
|
510
575
|
}
|
|
511
576
|
const cycle = ++this.cycleNonce;
|
|
512
577
|
return new Promise((resolve) => {
|
|
@@ -518,7 +583,7 @@ var OverlayEngine = class {
|
|
|
518
583
|
this.element.style.opacity = "1";
|
|
519
584
|
if (this.backdrop) {
|
|
520
585
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
521
|
-
this.backdrop.style.pointerEvents = "auto";
|
|
586
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
522
587
|
if (this.backdropFilter) {
|
|
523
588
|
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
524
589
|
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
@@ -554,7 +619,10 @@ var OverlayEngine = class {
|
|
|
554
619
|
});
|
|
555
620
|
return resolve();
|
|
556
621
|
}
|
|
557
|
-
this.awaitTransition(
|
|
622
|
+
this.awaitTransition(
|
|
623
|
+
cycle,
|
|
624
|
+
this.enterAnimation === "fade" ? "opacity" : "transform"
|
|
625
|
+
).then(() => {
|
|
558
626
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
559
627
|
this.isAnimating_ = false;
|
|
560
628
|
this.element.setAttribute("data-state", "open");
|
|
@@ -571,11 +639,14 @@ var OverlayEngine = class {
|
|
|
571
639
|
this.emit("before-close", void 0);
|
|
572
640
|
this.isOpen_ = false;
|
|
573
641
|
this.isAnimating_ = true;
|
|
642
|
+
sheetStack.update();
|
|
643
|
+
this.popBackMarker(reason);
|
|
574
644
|
this.element.setAttribute("data-state", "exiting");
|
|
575
|
-
const
|
|
645
|
+
const dur = this.effectiveDuration();
|
|
646
|
+
const transitionStr = `transform ${dur}ms ${this.exitEasing}, opacity ${dur}ms ease-in`;
|
|
576
647
|
this.element.style.transition = transitionStr;
|
|
577
648
|
if (this.backdrop) {
|
|
578
|
-
this.backdrop.style.transition = `opacity ${
|
|
649
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-in`;
|
|
579
650
|
}
|
|
580
651
|
const cycle = ++this.cycleNonce;
|
|
581
652
|
return new Promise((resolve) => {
|
|
@@ -586,7 +657,7 @@ var OverlayEngine = class {
|
|
|
586
657
|
this.exitAnimation,
|
|
587
658
|
this.peekPx
|
|
588
659
|
);
|
|
589
|
-
this.element.style.opacity = "0";
|
|
660
|
+
this.element.style.opacity = this.peekPx !== void 0 ? "1" : "0";
|
|
590
661
|
if (this.backdrop) {
|
|
591
662
|
this.backdrop.style.opacity = "0";
|
|
592
663
|
this.backdrop.style.pointerEvents = "none";
|
|
@@ -596,7 +667,10 @@ var OverlayEngine = class {
|
|
|
596
667
|
}
|
|
597
668
|
}
|
|
598
669
|
this.releaseInteractiveListeners();
|
|
599
|
-
this.awaitTransition(
|
|
670
|
+
this.awaitTransition(
|
|
671
|
+
cycle,
|
|
672
|
+
this.exitAnimation === "fade" ? "opacity" : "transform"
|
|
673
|
+
).then(() => {
|
|
600
674
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
601
675
|
this.isAnimating_ = false;
|
|
602
676
|
if (this.peekPx === void 0) {
|
|
@@ -624,7 +698,11 @@ var OverlayEngine = class {
|
|
|
624
698
|
this.releaseInteractiveListeners();
|
|
625
699
|
this.releaseStackEntry?.();
|
|
626
700
|
this.releaseStackEntry = null;
|
|
701
|
+
const hadOriginalParent = this.originalParent !== null;
|
|
627
702
|
this.restoreMount();
|
|
703
|
+
if (this.movedToTarget && !hadOriginalParent && this.element.parentNode) {
|
|
704
|
+
this.element.parentNode.removeChild(this.element);
|
|
705
|
+
}
|
|
628
706
|
}
|
|
629
707
|
setBackdropOpacity(opacity) {
|
|
630
708
|
if (this.destroyed) return;
|
|
@@ -725,6 +803,36 @@ var OverlayEngine = class {
|
|
|
725
803
|
}
|
|
726
804
|
}
|
|
727
805
|
}
|
|
806
|
+
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
807
|
+
if (opts.enterEasing !== void 0) this.enterEasing = opts.enterEasing;
|
|
808
|
+
if (opts.exitEasing !== void 0) this.exitEasing = opts.exitEasing;
|
|
809
|
+
if (opts.closeOnEscape !== void 0) {
|
|
810
|
+
this.closeOnEscape = opts.closeOnEscape;
|
|
811
|
+
if (!opts.closeOnEscape) {
|
|
812
|
+
this.detachEscape?.();
|
|
813
|
+
this.detachEscape = null;
|
|
814
|
+
} else if (this.isOpen_) {
|
|
815
|
+
this.installInteractiveListeners();
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
if (opts.closeOnBackdrop !== void 0) {
|
|
819
|
+
this.closeOnBackdropEnabled = opts.closeOnBackdrop;
|
|
820
|
+
if (!opts.closeOnBackdrop) {
|
|
821
|
+
this.detachBackdrop?.();
|
|
822
|
+
this.detachBackdrop = null;
|
|
823
|
+
} else if (this.isOpen_) {
|
|
824
|
+
this.installInteractiveListeners();
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (opts.closeOnOutsidePointer !== void 0) {
|
|
828
|
+
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer;
|
|
829
|
+
if (!opts.closeOnOutsidePointer) {
|
|
830
|
+
this.detachOutsidePointer?.();
|
|
831
|
+
this.detachOutsidePointer = null;
|
|
832
|
+
} else if (this.isOpen_) {
|
|
833
|
+
this.installInteractiveListeners();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
728
836
|
if (opts.children !== void 0) {
|
|
729
837
|
if (opts.children === null) {
|
|
730
838
|
this.clearOverlayChildren();
|
|
@@ -758,6 +866,22 @@ var OverlayEngine = class {
|
|
|
758
866
|
emit(event, payload) {
|
|
759
867
|
this.bus.emit(event, payload);
|
|
760
868
|
}
|
|
869
|
+
effectiveDuration() {
|
|
870
|
+
return this.respectReducedMotionEnabled && prefersReducedMotion() ? 0 : this.duration;
|
|
871
|
+
}
|
|
872
|
+
popBackMarker(reason) {
|
|
873
|
+
if (!this.backPushed) return;
|
|
874
|
+
this.backPushed = false;
|
|
875
|
+
if (reason === "back") return;
|
|
876
|
+
const state = history.state;
|
|
877
|
+
if (state && state.__bsOverlay === this.id) {
|
|
878
|
+
try {
|
|
879
|
+
history.back();
|
|
880
|
+
} catch {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
761
885
|
resolvePeekPx(raw) {
|
|
762
886
|
if (typeof raw === "number") return Math.max(0, raw);
|
|
763
887
|
try {
|
|
@@ -779,6 +903,7 @@ var OverlayEngine = class {
|
|
|
779
903
|
this.originalParent = this.element.parentNode;
|
|
780
904
|
this.originalNextSibling = this.element.nextSibling;
|
|
781
905
|
target.appendChild(this.element);
|
|
906
|
+
this.movedToTarget = true;
|
|
782
907
|
this.mounted = true;
|
|
783
908
|
}
|
|
784
909
|
restoreMount() {
|
|
@@ -812,7 +937,7 @@ var OverlayEngine = class {
|
|
|
812
937
|
this.backdrop.style.willChange = "opacity";
|
|
813
938
|
}
|
|
814
939
|
}
|
|
815
|
-
awaitTransition(cycle) {
|
|
940
|
+
awaitTransition(cycle, property = "transform") {
|
|
816
941
|
return new Promise((resolve) => {
|
|
817
942
|
let done = false;
|
|
818
943
|
const finish = () => {
|
|
@@ -827,10 +952,10 @@ var OverlayEngine = class {
|
|
|
827
952
|
finish();
|
|
828
953
|
return;
|
|
829
954
|
}
|
|
830
|
-
if (e.propertyName ===
|
|
955
|
+
if (e.target === this.element && e.propertyName === property) finish();
|
|
831
956
|
};
|
|
832
957
|
this.element.addEventListener("transitionend", onEnd);
|
|
833
|
-
const timer = window.setTimeout(finish, this.
|
|
958
|
+
const timer = window.setTimeout(finish, this.effectiveDuration() + 50);
|
|
834
959
|
});
|
|
835
960
|
}
|
|
836
961
|
installInteractiveListeners() {
|
|
@@ -840,7 +965,10 @@ var OverlayEngine = class {
|
|
|
840
965
|
}
|
|
841
966
|
if (this.closeOnEscape && !this.detachEscape) {
|
|
842
967
|
const handler = (e) => {
|
|
843
|
-
if (e.
|
|
968
|
+
if (e.defaultPrevented) return;
|
|
969
|
+
if (e.key === "Escape" && this.isOpen_ && this.isTop) {
|
|
970
|
+
void this.close("escape");
|
|
971
|
+
}
|
|
844
972
|
};
|
|
845
973
|
document.addEventListener("keydown", handler);
|
|
846
974
|
this.detachEscape = () => document.removeEventListener("keydown", handler);
|
|
@@ -853,10 +981,14 @@ var OverlayEngine = class {
|
|
|
853
981
|
if (this.closeOnBackEnabled && typeof window !== "undefined" && !this.detachHardwareBack) {
|
|
854
982
|
try {
|
|
855
983
|
history.pushState({ __bsOverlay: this.id }, "");
|
|
984
|
+
this.backPushed = true;
|
|
856
985
|
} catch {
|
|
857
986
|
}
|
|
858
987
|
const onPop = () => {
|
|
859
|
-
if (this.isOpen_
|
|
988
|
+
if (this.isOpen_ && this.isTop) {
|
|
989
|
+
this.backPushed = false;
|
|
990
|
+
void this.close("back");
|
|
991
|
+
}
|
|
860
992
|
};
|
|
861
993
|
window.addEventListener("popstate", onPop);
|
|
862
994
|
this.detachHardwareBack = () => window.removeEventListener("popstate", onPop);
|
|
@@ -892,43 +1024,52 @@ var OverlayEngine = class {
|
|
|
892
1024
|
const edge = this.edge;
|
|
893
1025
|
const isVertical = edge === "bottom" || edge === "top";
|
|
894
1026
|
const sign = edge === "bottom" || edge === "right" ? 1 : -1;
|
|
895
|
-
const
|
|
896
|
-
const velocityThreshold = this.swipeVelocityThreshold;
|
|
1027
|
+
const SLOP = 8;
|
|
897
1028
|
let startX = 0;
|
|
898
1029
|
let startY = 0;
|
|
899
1030
|
let startT = 0;
|
|
1031
|
+
let tracking = false;
|
|
900
1032
|
let dragging = false;
|
|
901
1033
|
let pointerId = null;
|
|
1034
|
+
const previousTouchAction = el.style.touchAction;
|
|
1035
|
+
el.style.touchAction = isVertical ? "pan-x" : "pan-y";
|
|
902
1036
|
const onDown = (e) => {
|
|
903
1037
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
904
1038
|
pointerId = e.pointerId;
|
|
905
1039
|
startX = e.clientX;
|
|
906
1040
|
startY = e.clientY;
|
|
907
1041
|
startT = performance.now();
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
try {
|
|
911
|
-
el.setPointerCapture(e.pointerId);
|
|
912
|
-
} catch {
|
|
913
|
-
}
|
|
1042
|
+
tracking = true;
|
|
1043
|
+
dragging = false;
|
|
914
1044
|
};
|
|
915
1045
|
const onMove = (e) => {
|
|
916
|
-
if (!
|
|
1046
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
917
1047
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
1048
|
+
if (!dragging) {
|
|
1049
|
+
if (Math.abs(delta) < SLOP) return;
|
|
1050
|
+
dragging = true;
|
|
1051
|
+
el.style.transition = "none";
|
|
1052
|
+
try {
|
|
1053
|
+
el.setPointerCapture(e.pointerId);
|
|
1054
|
+
} catch {
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
918
1057
|
const offset = Math.max(0, sign * delta);
|
|
919
1058
|
el.style.transform = isVertical ? `translate3d(0, ${sign * offset}px, 0)` : `translate3d(${sign * offset}px, 0, 0)`;
|
|
920
1059
|
};
|
|
921
1060
|
const finish = (e) => {
|
|
922
|
-
if (!
|
|
923
|
-
|
|
1061
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
1062
|
+
tracking = false;
|
|
924
1063
|
pointerId = null;
|
|
1064
|
+
if (!dragging) return;
|
|
1065
|
+
dragging = false;
|
|
925
1066
|
const dt = performance.now() - startT || 1;
|
|
926
1067
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
927
1068
|
const offset = Math.max(0, sign * delta);
|
|
928
1069
|
const velocity = sign * delta / dt;
|
|
929
1070
|
const size = isVertical ? el.offsetHeight : el.offsetWidth;
|
|
930
|
-
const past = offset > size *
|
|
931
|
-
el.style.transition = `transform ${this.
|
|
1071
|
+
const past = offset > size * this.swipeThreshold || velocity > this.swipeVelocityThreshold;
|
|
1072
|
+
el.style.transition = `transform ${this.effectiveDuration()}ms ${this.exitEasing}`;
|
|
932
1073
|
if (past) {
|
|
933
1074
|
void this.close("swipe");
|
|
934
1075
|
} else {
|
|
@@ -940,6 +1081,7 @@ var OverlayEngine = class {
|
|
|
940
1081
|
el.addEventListener("pointerup", finish);
|
|
941
1082
|
el.addEventListener("pointercancel", finish);
|
|
942
1083
|
return () => {
|
|
1084
|
+
el.style.touchAction = previousTouchAction;
|
|
943
1085
|
el.removeEventListener("pointerdown", onDown);
|
|
944
1086
|
el.removeEventListener("pointermove", onMove);
|
|
945
1087
|
el.removeEventListener("pointerup", finish);
|
|
@@ -954,10 +1096,12 @@ var OverlayEngine = class {
|
|
|
954
1096
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
955
1097
|
},
|
|
956
1098
|
setIsTop: (isTop) => {
|
|
1099
|
+
this.isTop = isTop;
|
|
957
1100
|
if (this.backdrop) {
|
|
958
1101
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
959
1102
|
}
|
|
960
|
-
}
|
|
1103
|
+
},
|
|
1104
|
+
isOpen: () => this.isOpen_
|
|
961
1105
|
});
|
|
962
1106
|
}
|
|
963
1107
|
};
|
package/dist/overlay.d.cts
CHANGED
|
@@ -25,6 +25,12 @@ type OverlayUpdate = {
|
|
|
25
25
|
enterAnimation?: OverlayAnimation;
|
|
26
26
|
exitAnimation?: OverlayAnimation;
|
|
27
27
|
preset?: OverlayPreset;
|
|
28
|
+
duration?: number;
|
|
29
|
+
enterEasing?: string;
|
|
30
|
+
exitEasing?: string;
|
|
31
|
+
closeOnEscape?: boolean;
|
|
32
|
+
closeOnBackdrop?: boolean;
|
|
33
|
+
closeOnOutsidePointer?: boolean;
|
|
28
34
|
children?: HTMLElement | DocumentFragment | (() => HTMLElement | DocumentFragment) | null;
|
|
29
35
|
};
|
|
30
36
|
type OverlayOptions = {
|
|
@@ -52,6 +58,7 @@ type OverlayOptions = {
|
|
|
52
58
|
peek?: number | string;
|
|
53
59
|
closeOnOutsidePointer?: boolean;
|
|
54
60
|
preset?: OverlayPreset;
|
|
61
|
+
respectReducedMotion?: boolean;
|
|
55
62
|
onOpen?: () => void;
|
|
56
63
|
onClose?: () => void;
|
|
57
64
|
};
|
|
@@ -99,6 +106,10 @@ declare class OverlayEngine {
|
|
|
99
106
|
private closeOnOutsidePointerEnabled;
|
|
100
107
|
private detachOutsidePointer;
|
|
101
108
|
private detachSwipe;
|
|
109
|
+
private respectReducedMotionEnabled;
|
|
110
|
+
private isTop;
|
|
111
|
+
private backPushed;
|
|
112
|
+
private movedToTarget;
|
|
102
113
|
private onOpenCb?;
|
|
103
114
|
private onCloseCb?;
|
|
104
115
|
private isOpen_;
|
|
@@ -130,6 +141,8 @@ declare class OverlayEngine {
|
|
|
130
141
|
clearOverlayChildren(): void;
|
|
131
142
|
private assignSwipeFromConfig;
|
|
132
143
|
private emit;
|
|
144
|
+
private effectiveDuration;
|
|
145
|
+
private popBackMarker;
|
|
133
146
|
private resolvePeekPx;
|
|
134
147
|
private maybeMount;
|
|
135
148
|
private restoreMount;
|
package/dist/overlay.d.ts
CHANGED
|
@@ -25,6 +25,12 @@ type OverlayUpdate = {
|
|
|
25
25
|
enterAnimation?: OverlayAnimation;
|
|
26
26
|
exitAnimation?: OverlayAnimation;
|
|
27
27
|
preset?: OverlayPreset;
|
|
28
|
+
duration?: number;
|
|
29
|
+
enterEasing?: string;
|
|
30
|
+
exitEasing?: string;
|
|
31
|
+
closeOnEscape?: boolean;
|
|
32
|
+
closeOnBackdrop?: boolean;
|
|
33
|
+
closeOnOutsidePointer?: boolean;
|
|
28
34
|
children?: HTMLElement | DocumentFragment | (() => HTMLElement | DocumentFragment) | null;
|
|
29
35
|
};
|
|
30
36
|
type OverlayOptions = {
|
|
@@ -52,6 +58,7 @@ type OverlayOptions = {
|
|
|
52
58
|
peek?: number | string;
|
|
53
59
|
closeOnOutsidePointer?: boolean;
|
|
54
60
|
preset?: OverlayPreset;
|
|
61
|
+
respectReducedMotion?: boolean;
|
|
55
62
|
onOpen?: () => void;
|
|
56
63
|
onClose?: () => void;
|
|
57
64
|
};
|
|
@@ -99,6 +106,10 @@ declare class OverlayEngine {
|
|
|
99
106
|
private closeOnOutsidePointerEnabled;
|
|
100
107
|
private detachOutsidePointer;
|
|
101
108
|
private detachSwipe;
|
|
109
|
+
private respectReducedMotionEnabled;
|
|
110
|
+
private isTop;
|
|
111
|
+
private backPushed;
|
|
112
|
+
private movedToTarget;
|
|
102
113
|
private onOpenCb?;
|
|
103
114
|
private onCloseCb?;
|
|
104
115
|
private isOpen_;
|
|
@@ -130,6 +141,8 @@ declare class OverlayEngine {
|
|
|
130
141
|
clearOverlayChildren(): void;
|
|
131
142
|
private assignSwipeFromConfig;
|
|
132
143
|
private emit;
|
|
144
|
+
private effectiveDuration;
|
|
145
|
+
private popBackMarker;
|
|
133
146
|
private resolvePeekPx;
|
|
134
147
|
private maybeMount;
|
|
135
148
|
private restoreMount;
|