@surdeddd/bottom-sheet 0.2.0 → 0.3.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-CAymrH-P.d.cts} +67 -1
- package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-DcqcuudN.d.ts} +67 -1
- package/dist/element.cjs +699 -116
- package/dist/element.d.cts +7 -2
- package/dist/element.d.ts +7 -2
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +699 -116
- package/dist/index.cjs +715 -145
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +713 -146
- 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 +168 -35
- package/dist/overlay.d.cts +13 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +168 -35
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +619 -119
- package/dist/qwik.d.cts +2 -2
- package/dist/qwik.d.ts +2 -2
- package/dist/qwik.js +620 -120
- package/dist/react.cjs +821 -191
- package/dist/react.d.cts +20 -3
- package/dist/react.d.ts +20 -3
- package/dist/react.js +821 -191
- package/dist/solid.cjs +656 -161
- package/dist/solid.d.cts +263 -4
- package/dist/solid.d.ts +263 -4
- package/dist/solid.js +657 -162
- package/dist/solid.source.jsx +3215 -0
- package/dist/styles.css +10 -10
- package/dist/svelte-core.cjs +3149 -0
- package/dist/svelte-core.js +3147 -0
- package/dist/svelte-src/BottomSheet.svelte +210 -0
- package/dist/svelte-src/index.js +2 -0
- package/dist/svelte.cjs +618 -124
- package/dist/svelte.d.cts +100 -0
- package/dist/svelte.d.ts +7 -3
- package/dist/svelte.js +619 -125
- package/dist/vue.cjs +612 -119
- package/dist/vue.d.cts +78 -0
- package/dist/vue.d.ts +6 -2
- package/dist/vue.js +612 -119
- package/package.json +103 -43
package/dist/overlay.cjs
CHANGED
|
@@ -22,6 +22,18 @@ 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
|
}
|
|
@@ -29,9 +41,24 @@ var SheetStack = class {
|
|
|
29
41
|
this.entries = [];
|
|
30
42
|
}
|
|
31
43
|
recompute() {
|
|
44
|
+
let top = null;
|
|
45
|
+
const open = [];
|
|
46
|
+
for (const entry of this.entries) {
|
|
47
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
48
|
+
top = entry;
|
|
49
|
+
open.push(entry);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!top && this.entries.length > 0) {
|
|
53
|
+
top = this.entries[this.entries.length - 1];
|
|
54
|
+
}
|
|
32
55
|
this.entries.forEach((entry, i) => {
|
|
33
56
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
34
|
-
entry.setIsTop(
|
|
57
|
+
entry.setIsTop(entry === top);
|
|
58
|
+
if (entry.setDepth) {
|
|
59
|
+
const openIdx = open.indexOf(entry);
|
|
60
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
61
|
+
}
|
|
35
62
|
});
|
|
36
63
|
}
|
|
37
64
|
};
|
|
@@ -154,9 +181,13 @@ var isVisible = (el) => {
|
|
|
154
181
|
var focusables = (root) => Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
155
182
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
156
183
|
);
|
|
184
|
+
var trapStack = [];
|
|
157
185
|
var installFocusTrap = (container, options = {}) => {
|
|
158
186
|
if (typeof document === "undefined") return () => {
|
|
159
187
|
};
|
|
188
|
+
const token = {};
|
|
189
|
+
trapStack.push(token);
|
|
190
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
160
191
|
const previouslyFocused = document.activeElement;
|
|
161
192
|
const focusInitial = () => {
|
|
162
193
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -164,6 +195,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
164
195
|
};
|
|
165
196
|
focusInitial();
|
|
166
197
|
const handleKey = (e) => {
|
|
198
|
+
if (!isActive()) return;
|
|
167
199
|
if (e.key === "Escape" && options.onEscape) {
|
|
168
200
|
options.onEscape();
|
|
169
201
|
return;
|
|
@@ -186,6 +218,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
186
218
|
}
|
|
187
219
|
};
|
|
188
220
|
const handleFocusIn = (e) => {
|
|
221
|
+
if (!isActive()) return;
|
|
189
222
|
const target = e.target;
|
|
190
223
|
if (target && !container.contains(target)) {
|
|
191
224
|
const list = focusables(container);
|
|
@@ -198,6 +231,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
198
231
|
return () => {
|
|
199
232
|
if (released) return;
|
|
200
233
|
released = true;
|
|
234
|
+
const idx = trapStack.indexOf(token);
|
|
235
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
201
236
|
document.removeEventListener("keydown", handleKey, true);
|
|
202
237
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
203
238
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -253,11 +288,17 @@ function createInertSiblings(rootProvider) {
|
|
|
253
288
|
return {
|
|
254
289
|
apply() {
|
|
255
290
|
if (typeof document === "undefined") return;
|
|
256
|
-
|
|
257
|
-
|
|
291
|
+
let top = rootProvider();
|
|
292
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
293
|
+
top = top.parentElement;
|
|
294
|
+
}
|
|
295
|
+
const parent = top.parentElement ?? document.body;
|
|
258
296
|
for (const child of Array.from(parent.children)) {
|
|
259
|
-
if (child ===
|
|
297
|
+
if (child === top) continue;
|
|
260
298
|
if (child.hasAttribute("inert")) continue;
|
|
299
|
+
if (child.classList.contains("bs-backdrop") || child.classList.contains("bs-screen") || child.classList.contains("bs-root")) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
261
302
|
child.setAttribute("inert", "");
|
|
262
303
|
tracked.push(child);
|
|
263
304
|
}
|
|
@@ -273,7 +314,6 @@ function createInertSiblings(rootProvider) {
|
|
|
273
314
|
var LifecycleController = class {
|
|
274
315
|
constructor(deps, opts) {
|
|
275
316
|
__publicField(this, "element");
|
|
276
|
-
__publicField(this, "closeFn");
|
|
277
317
|
__publicField(this, "focusTrapEnabled");
|
|
278
318
|
__publicField(this, "initialFocus");
|
|
279
319
|
__publicField(this, "closeOnEscape");
|
|
@@ -287,7 +327,6 @@ var LifecycleController = class {
|
|
|
287
327
|
__publicField(this, "installed", false);
|
|
288
328
|
__publicField(this, "destroyed", false);
|
|
289
329
|
this.element = deps.element;
|
|
290
|
-
this.closeFn = deps.close;
|
|
291
330
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
292
331
|
this.initialFocus = opts.initialFocus;
|
|
293
332
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -297,6 +336,9 @@ var LifecycleController = class {
|
|
|
297
336
|
this.returnFocus = opts.returnFocus;
|
|
298
337
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
299
338
|
}
|
|
339
|
+
get isInstalled() {
|
|
340
|
+
return this.installed;
|
|
341
|
+
}
|
|
300
342
|
install() {
|
|
301
343
|
if (this.destroyed) return;
|
|
302
344
|
this.installed = true;
|
|
@@ -305,8 +347,7 @@ var LifecycleController = class {
|
|
|
305
347
|
}
|
|
306
348
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
307
349
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
308
|
-
initialFocus: this.initialFocus
|
|
309
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
350
|
+
initialFocus: this.initialFocus
|
|
310
351
|
});
|
|
311
352
|
}
|
|
312
353
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -336,6 +377,12 @@ var LifecycleController = class {
|
|
|
336
377
|
}
|
|
337
378
|
};
|
|
338
379
|
|
|
380
|
+
// src/core/animation/animation.ts
|
|
381
|
+
var prefersReducedMotion = () => {
|
|
382
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
383
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
384
|
+
};
|
|
385
|
+
|
|
339
386
|
// src/core/overlay.ts
|
|
340
387
|
var OVERLAY_PRESETS = Object.freeze({
|
|
341
388
|
sheet: Object.freeze({
|
|
@@ -415,6 +462,10 @@ var OverlayEngine = class {
|
|
|
415
462
|
__publicField(this, "closeOnOutsidePointerEnabled");
|
|
416
463
|
__publicField(this, "detachOutsidePointer", null);
|
|
417
464
|
__publicField(this, "detachSwipe", null);
|
|
465
|
+
__publicField(this, "respectReducedMotionEnabled");
|
|
466
|
+
__publicField(this, "isTop", true);
|
|
467
|
+
__publicField(this, "backPushed", false);
|
|
468
|
+
__publicField(this, "movedToTarget", false);
|
|
418
469
|
__publicField(this, "onOpenCb");
|
|
419
470
|
__publicField(this, "onCloseCb");
|
|
420
471
|
__publicField(this, "isOpen_", false);
|
|
@@ -451,6 +502,7 @@ var OverlayEngine = class {
|
|
|
451
502
|
this.mountTarget = opts.mountTo;
|
|
452
503
|
this.peekRaw = opts.peek;
|
|
453
504
|
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer ?? false;
|
|
505
|
+
this.respectReducedMotionEnabled = opts.respectReducedMotion ?? true;
|
|
454
506
|
this.onOpenCb = opts.onOpen;
|
|
455
507
|
this.onCloseCb = opts.onClose;
|
|
456
508
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
@@ -498,15 +550,17 @@ var OverlayEngine = class {
|
|
|
498
550
|
this.emit("before-open", void 0);
|
|
499
551
|
this.isOpen_ = true;
|
|
500
552
|
this.isAnimating_ = true;
|
|
553
|
+
sheetStack.promote(this.id);
|
|
501
554
|
this.element.removeAttribute("hidden");
|
|
502
555
|
this.element.setAttribute("data-state", "entering");
|
|
503
556
|
if (this.focusTrapEnabled) {
|
|
504
557
|
this.element.setAttribute("aria-modal", "true");
|
|
505
558
|
}
|
|
506
|
-
const
|
|
559
|
+
const dur = this.effectiveDuration();
|
|
560
|
+
const transitionStr = `transform ${dur}ms ${this.enterEasing}, opacity ${dur}ms ease-out`;
|
|
507
561
|
this.element.style.transition = transitionStr;
|
|
508
562
|
if (this.backdrop) {
|
|
509
|
-
this.backdrop.style.transition = `opacity ${
|
|
563
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-out`;
|
|
510
564
|
}
|
|
511
565
|
const cycle = ++this.cycleNonce;
|
|
512
566
|
return new Promise((resolve) => {
|
|
@@ -518,7 +572,7 @@ var OverlayEngine = class {
|
|
|
518
572
|
this.element.style.opacity = "1";
|
|
519
573
|
if (this.backdrop) {
|
|
520
574
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
521
|
-
this.backdrop.style.pointerEvents = "auto";
|
|
575
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
522
576
|
if (this.backdropFilter) {
|
|
523
577
|
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
524
578
|
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
@@ -554,7 +608,10 @@ var OverlayEngine = class {
|
|
|
554
608
|
});
|
|
555
609
|
return resolve();
|
|
556
610
|
}
|
|
557
|
-
this.awaitTransition(
|
|
611
|
+
this.awaitTransition(
|
|
612
|
+
cycle,
|
|
613
|
+
this.enterAnimation === "fade" ? "opacity" : "transform"
|
|
614
|
+
).then(() => {
|
|
558
615
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
559
616
|
this.isAnimating_ = false;
|
|
560
617
|
this.element.setAttribute("data-state", "open");
|
|
@@ -571,11 +628,14 @@ var OverlayEngine = class {
|
|
|
571
628
|
this.emit("before-close", void 0);
|
|
572
629
|
this.isOpen_ = false;
|
|
573
630
|
this.isAnimating_ = true;
|
|
631
|
+
sheetStack.update();
|
|
632
|
+
this.popBackMarker(reason);
|
|
574
633
|
this.element.setAttribute("data-state", "exiting");
|
|
575
|
-
const
|
|
634
|
+
const dur = this.effectiveDuration();
|
|
635
|
+
const transitionStr = `transform ${dur}ms ${this.exitEasing}, opacity ${dur}ms ease-in`;
|
|
576
636
|
this.element.style.transition = transitionStr;
|
|
577
637
|
if (this.backdrop) {
|
|
578
|
-
this.backdrop.style.transition = `opacity ${
|
|
638
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-in`;
|
|
579
639
|
}
|
|
580
640
|
const cycle = ++this.cycleNonce;
|
|
581
641
|
return new Promise((resolve) => {
|
|
@@ -586,7 +646,7 @@ var OverlayEngine = class {
|
|
|
586
646
|
this.exitAnimation,
|
|
587
647
|
this.peekPx
|
|
588
648
|
);
|
|
589
|
-
this.element.style.opacity = "0";
|
|
649
|
+
this.element.style.opacity = this.peekPx !== void 0 ? "1" : "0";
|
|
590
650
|
if (this.backdrop) {
|
|
591
651
|
this.backdrop.style.opacity = "0";
|
|
592
652
|
this.backdrop.style.pointerEvents = "none";
|
|
@@ -596,7 +656,10 @@ var OverlayEngine = class {
|
|
|
596
656
|
}
|
|
597
657
|
}
|
|
598
658
|
this.releaseInteractiveListeners();
|
|
599
|
-
this.awaitTransition(
|
|
659
|
+
this.awaitTransition(
|
|
660
|
+
cycle,
|
|
661
|
+
this.exitAnimation === "fade" ? "opacity" : "transform"
|
|
662
|
+
).then(() => {
|
|
600
663
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
601
664
|
this.isAnimating_ = false;
|
|
602
665
|
if (this.peekPx === void 0) {
|
|
@@ -624,7 +687,11 @@ var OverlayEngine = class {
|
|
|
624
687
|
this.releaseInteractiveListeners();
|
|
625
688
|
this.releaseStackEntry?.();
|
|
626
689
|
this.releaseStackEntry = null;
|
|
690
|
+
const hadOriginalParent = this.originalParent !== null;
|
|
627
691
|
this.restoreMount();
|
|
692
|
+
if (this.movedToTarget && !hadOriginalParent && this.element.parentNode) {
|
|
693
|
+
this.element.parentNode.removeChild(this.element);
|
|
694
|
+
}
|
|
628
695
|
}
|
|
629
696
|
setBackdropOpacity(opacity) {
|
|
630
697
|
if (this.destroyed) return;
|
|
@@ -725,6 +792,36 @@ var OverlayEngine = class {
|
|
|
725
792
|
}
|
|
726
793
|
}
|
|
727
794
|
}
|
|
795
|
+
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
796
|
+
if (opts.enterEasing !== void 0) this.enterEasing = opts.enterEasing;
|
|
797
|
+
if (opts.exitEasing !== void 0) this.exitEasing = opts.exitEasing;
|
|
798
|
+
if (opts.closeOnEscape !== void 0) {
|
|
799
|
+
this.closeOnEscape = opts.closeOnEscape;
|
|
800
|
+
if (!opts.closeOnEscape) {
|
|
801
|
+
this.detachEscape?.();
|
|
802
|
+
this.detachEscape = null;
|
|
803
|
+
} else if (this.isOpen_) {
|
|
804
|
+
this.installInteractiveListeners();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (opts.closeOnBackdrop !== void 0) {
|
|
808
|
+
this.closeOnBackdropEnabled = opts.closeOnBackdrop;
|
|
809
|
+
if (!opts.closeOnBackdrop) {
|
|
810
|
+
this.detachBackdrop?.();
|
|
811
|
+
this.detachBackdrop = null;
|
|
812
|
+
} else if (this.isOpen_) {
|
|
813
|
+
this.installInteractiveListeners();
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
if (opts.closeOnOutsidePointer !== void 0) {
|
|
817
|
+
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer;
|
|
818
|
+
if (!opts.closeOnOutsidePointer) {
|
|
819
|
+
this.detachOutsidePointer?.();
|
|
820
|
+
this.detachOutsidePointer = null;
|
|
821
|
+
} else if (this.isOpen_) {
|
|
822
|
+
this.installInteractiveListeners();
|
|
823
|
+
}
|
|
824
|
+
}
|
|
728
825
|
if (opts.children !== void 0) {
|
|
729
826
|
if (opts.children === null) {
|
|
730
827
|
this.clearOverlayChildren();
|
|
@@ -758,6 +855,22 @@ var OverlayEngine = class {
|
|
|
758
855
|
emit(event, payload) {
|
|
759
856
|
this.bus.emit(event, payload);
|
|
760
857
|
}
|
|
858
|
+
effectiveDuration() {
|
|
859
|
+
return this.respectReducedMotionEnabled && prefersReducedMotion() ? 0 : this.duration;
|
|
860
|
+
}
|
|
861
|
+
popBackMarker(reason) {
|
|
862
|
+
if (!this.backPushed) return;
|
|
863
|
+
this.backPushed = false;
|
|
864
|
+
if (reason === "back") return;
|
|
865
|
+
const state = history.state;
|
|
866
|
+
if (state && state.__bsOverlay === this.id) {
|
|
867
|
+
try {
|
|
868
|
+
history.back();
|
|
869
|
+
} catch {
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
761
874
|
resolvePeekPx(raw) {
|
|
762
875
|
if (typeof raw === "number") return Math.max(0, raw);
|
|
763
876
|
try {
|
|
@@ -779,6 +892,7 @@ var OverlayEngine = class {
|
|
|
779
892
|
this.originalParent = this.element.parentNode;
|
|
780
893
|
this.originalNextSibling = this.element.nextSibling;
|
|
781
894
|
target.appendChild(this.element);
|
|
895
|
+
this.movedToTarget = true;
|
|
782
896
|
this.mounted = true;
|
|
783
897
|
}
|
|
784
898
|
restoreMount() {
|
|
@@ -812,7 +926,7 @@ var OverlayEngine = class {
|
|
|
812
926
|
this.backdrop.style.willChange = "opacity";
|
|
813
927
|
}
|
|
814
928
|
}
|
|
815
|
-
awaitTransition(cycle) {
|
|
929
|
+
awaitTransition(cycle, property = "transform") {
|
|
816
930
|
return new Promise((resolve) => {
|
|
817
931
|
let done = false;
|
|
818
932
|
const finish = () => {
|
|
@@ -827,10 +941,10 @@ var OverlayEngine = class {
|
|
|
827
941
|
finish();
|
|
828
942
|
return;
|
|
829
943
|
}
|
|
830
|
-
if (e.propertyName ===
|
|
944
|
+
if (e.target === this.element && e.propertyName === property) finish();
|
|
831
945
|
};
|
|
832
946
|
this.element.addEventListener("transitionend", onEnd);
|
|
833
|
-
const timer = window.setTimeout(finish, this.
|
|
947
|
+
const timer = window.setTimeout(finish, this.effectiveDuration() + 50);
|
|
834
948
|
});
|
|
835
949
|
}
|
|
836
950
|
installInteractiveListeners() {
|
|
@@ -840,7 +954,10 @@ var OverlayEngine = class {
|
|
|
840
954
|
}
|
|
841
955
|
if (this.closeOnEscape && !this.detachEscape) {
|
|
842
956
|
const handler = (e) => {
|
|
843
|
-
if (e.
|
|
957
|
+
if (e.defaultPrevented) return;
|
|
958
|
+
if (e.key === "Escape" && this.isOpen_ && this.isTop) {
|
|
959
|
+
void this.close("escape");
|
|
960
|
+
}
|
|
844
961
|
};
|
|
845
962
|
document.addEventListener("keydown", handler);
|
|
846
963
|
this.detachEscape = () => document.removeEventListener("keydown", handler);
|
|
@@ -853,10 +970,14 @@ var OverlayEngine = class {
|
|
|
853
970
|
if (this.closeOnBackEnabled && typeof window !== "undefined" && !this.detachHardwareBack) {
|
|
854
971
|
try {
|
|
855
972
|
history.pushState({ __bsOverlay: this.id }, "");
|
|
973
|
+
this.backPushed = true;
|
|
856
974
|
} catch {
|
|
857
975
|
}
|
|
858
976
|
const onPop = () => {
|
|
859
|
-
if (this.isOpen_
|
|
977
|
+
if (this.isOpen_ && this.isTop) {
|
|
978
|
+
this.backPushed = false;
|
|
979
|
+
void this.close("back");
|
|
980
|
+
}
|
|
860
981
|
};
|
|
861
982
|
window.addEventListener("popstate", onPop);
|
|
862
983
|
this.detachHardwareBack = () => window.removeEventListener("popstate", onPop);
|
|
@@ -892,43 +1013,52 @@ var OverlayEngine = class {
|
|
|
892
1013
|
const edge = this.edge;
|
|
893
1014
|
const isVertical = edge === "bottom" || edge === "top";
|
|
894
1015
|
const sign = edge === "bottom" || edge === "right" ? 1 : -1;
|
|
895
|
-
const
|
|
896
|
-
const velocityThreshold = this.swipeVelocityThreshold;
|
|
1016
|
+
const SLOP = 8;
|
|
897
1017
|
let startX = 0;
|
|
898
1018
|
let startY = 0;
|
|
899
1019
|
let startT = 0;
|
|
1020
|
+
let tracking = false;
|
|
900
1021
|
let dragging = false;
|
|
901
1022
|
let pointerId = null;
|
|
1023
|
+
const previousTouchAction = el.style.touchAction;
|
|
1024
|
+
el.style.touchAction = isVertical ? "pan-x" : "pan-y";
|
|
902
1025
|
const onDown = (e) => {
|
|
903
1026
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
904
1027
|
pointerId = e.pointerId;
|
|
905
1028
|
startX = e.clientX;
|
|
906
1029
|
startY = e.clientY;
|
|
907
1030
|
startT = performance.now();
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
try {
|
|
911
|
-
el.setPointerCapture(e.pointerId);
|
|
912
|
-
} catch {
|
|
913
|
-
}
|
|
1031
|
+
tracking = true;
|
|
1032
|
+
dragging = false;
|
|
914
1033
|
};
|
|
915
1034
|
const onMove = (e) => {
|
|
916
|
-
if (!
|
|
1035
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
917
1036
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
1037
|
+
if (!dragging) {
|
|
1038
|
+
if (Math.abs(delta) < SLOP) return;
|
|
1039
|
+
dragging = true;
|
|
1040
|
+
el.style.transition = "none";
|
|
1041
|
+
try {
|
|
1042
|
+
el.setPointerCapture(e.pointerId);
|
|
1043
|
+
} catch {
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
918
1046
|
const offset = Math.max(0, sign * delta);
|
|
919
1047
|
el.style.transform = isVertical ? `translate3d(0, ${sign * offset}px, 0)` : `translate3d(${sign * offset}px, 0, 0)`;
|
|
920
1048
|
};
|
|
921
1049
|
const finish = (e) => {
|
|
922
|
-
if (!
|
|
923
|
-
|
|
1050
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
1051
|
+
tracking = false;
|
|
924
1052
|
pointerId = null;
|
|
1053
|
+
if (!dragging) return;
|
|
1054
|
+
dragging = false;
|
|
925
1055
|
const dt = performance.now() - startT || 1;
|
|
926
1056
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
927
1057
|
const offset = Math.max(0, sign * delta);
|
|
928
1058
|
const velocity = sign * delta / dt;
|
|
929
1059
|
const size = isVertical ? el.offsetHeight : el.offsetWidth;
|
|
930
|
-
const past = offset > size *
|
|
931
|
-
el.style.transition = `transform ${this.
|
|
1060
|
+
const past = offset > size * this.swipeThreshold || velocity > this.swipeVelocityThreshold;
|
|
1061
|
+
el.style.transition = `transform ${this.effectiveDuration()}ms ${this.exitEasing}`;
|
|
932
1062
|
if (past) {
|
|
933
1063
|
void this.close("swipe");
|
|
934
1064
|
} else {
|
|
@@ -940,6 +1070,7 @@ var OverlayEngine = class {
|
|
|
940
1070
|
el.addEventListener("pointerup", finish);
|
|
941
1071
|
el.addEventListener("pointercancel", finish);
|
|
942
1072
|
return () => {
|
|
1073
|
+
el.style.touchAction = previousTouchAction;
|
|
943
1074
|
el.removeEventListener("pointerdown", onDown);
|
|
944
1075
|
el.removeEventListener("pointermove", onMove);
|
|
945
1076
|
el.removeEventListener("pointerup", finish);
|
|
@@ -954,10 +1085,12 @@ var OverlayEngine = class {
|
|
|
954
1085
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
955
1086
|
},
|
|
956
1087
|
setIsTop: (isTop) => {
|
|
1088
|
+
this.isTop = isTop;
|
|
957
1089
|
if (this.backdrop) {
|
|
958
1090
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
959
1091
|
}
|
|
960
|
-
}
|
|
1092
|
+
},
|
|
1093
|
+
isOpen: () => this.isOpen_
|
|
961
1094
|
});
|
|
962
1095
|
}
|
|
963
1096
|
};
|
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;
|