@surdeddd/bottom-sheet 0.10.0 → 0.11.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 +36 -35
- package/dist/element.cjs +227 -123
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +227 -123
- package/dist/index.cjs +234 -151
- package/dist/index.js +234 -151
- package/dist/overlay.cjs +157 -33
- package/dist/overlay.d.cts +1 -3
- package/dist/overlay.d.ts +1 -3
- package/dist/overlay.js +157 -33
- package/dist/qwik.cjs +217 -118
- package/dist/qwik.js +217 -118
- package/dist/react.cjs +234 -151
- package/dist/react.js +234 -151
- package/dist/solid.cjs +217 -118
- package/dist/solid.js +217 -118
- package/dist/solid.source.jsx +217 -118
- package/dist/svelte-core.cjs +217 -118
- package/dist/svelte-core.js +217 -118
- package/dist/svelte.cjs +229 -130
- package/dist/svelte.js +229 -130
- package/dist/vue.cjs +217 -118
- package/dist/vue.js +217 -118
- package/package.json +8 -6
package/dist/vue.js
CHANGED
|
@@ -438,46 +438,198 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
-
// src/core/features/
|
|
442
|
-
var
|
|
443
|
-
var
|
|
441
|
+
// src/core/features/history-coordinator.ts
|
|
442
|
+
var entries = [];
|
|
443
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
444
444
|
var suppress = 0;
|
|
445
|
-
var
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
445
|
+
var internalDepth = 0;
|
|
446
|
+
var pendingRebrand = null;
|
|
447
|
+
var listenerInstalled = false;
|
|
448
|
+
var patchInstalled = false;
|
|
449
|
+
var origPushState = null;
|
|
450
|
+
var origReplaceState = null;
|
|
451
|
+
var patchedPushState = null;
|
|
452
|
+
var patchedReplaceState = null;
|
|
453
|
+
var hasWindow = () => typeof window !== "undefined";
|
|
454
|
+
var hasHistory = () => typeof history !== "undefined";
|
|
455
|
+
var runInternal = (fn) => {
|
|
456
|
+
internalDepth += 1;
|
|
457
|
+
try {
|
|
458
|
+
fn();
|
|
459
|
+
} finally {
|
|
460
|
+
internalDepth -= 1;
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
var notifyRouteChange = () => {
|
|
464
|
+
const snapshot = Array.from(subscribers);
|
|
465
|
+
for (const fn of snapshot) fn();
|
|
466
|
+
};
|
|
467
|
+
var ensureListener = () => {
|
|
468
|
+
if (listenerInstalled || !hasWindow()) return;
|
|
469
|
+
window.addEventListener("popstate", onPopState);
|
|
470
|
+
listenerInstalled = true;
|
|
471
|
+
};
|
|
472
|
+
var maybeTeardownListener = () => {
|
|
473
|
+
if (!listenerInstalled) return;
|
|
474
|
+
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
475
|
+
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
476
|
+
listenerInstalled = false;
|
|
477
|
+
};
|
|
478
|
+
var installPatch = () => {
|
|
479
|
+
if (patchInstalled || !hasHistory()) return;
|
|
480
|
+
origPushState = history.pushState;
|
|
481
|
+
origReplaceState = history.replaceState;
|
|
482
|
+
patchedPushState = function(...args) {
|
|
483
|
+
origPushState.apply(this, args);
|
|
484
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
485
|
+
};
|
|
486
|
+
patchedReplaceState = function(...args) {
|
|
487
|
+
origReplaceState.apply(this, args);
|
|
488
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
489
|
+
};
|
|
490
|
+
history.pushState = patchedPushState;
|
|
491
|
+
history.replaceState = patchedReplaceState;
|
|
492
|
+
patchInstalled = true;
|
|
493
|
+
};
|
|
494
|
+
var removePatch = () => {
|
|
495
|
+
if (!patchInstalled) return;
|
|
496
|
+
if (history.pushState === patchedPushState && origPushState) {
|
|
497
|
+
history.pushState = origPushState;
|
|
498
|
+
}
|
|
499
|
+
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
500
|
+
history.replaceState = origReplaceState;
|
|
501
|
+
}
|
|
502
|
+
origPushState = null;
|
|
503
|
+
origReplaceState = null;
|
|
504
|
+
patchedPushState = null;
|
|
505
|
+
patchedReplaceState = null;
|
|
506
|
+
patchInstalled = false;
|
|
507
|
+
};
|
|
508
|
+
function onPopState() {
|
|
509
|
+
if (suppress > 0) {
|
|
510
|
+
suppress -= 1;
|
|
511
|
+
const rebrand = pendingRebrand;
|
|
512
|
+
pendingRebrand = null;
|
|
513
|
+
if (rebrand) rebrand();
|
|
514
|
+
maybeTeardownListener();
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (entries.length === 0) {
|
|
518
|
+
notifyRouteChange();
|
|
519
|
+
maybeTeardownListener();
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
let target = null;
|
|
523
|
+
let targetIdx = -1;
|
|
524
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
525
|
+
const entry = entries[i];
|
|
526
|
+
if (!entry.surface.isOpen()) continue;
|
|
527
|
+
if (!target) {
|
|
528
|
+
target = entry;
|
|
529
|
+
targetIdx = i;
|
|
452
530
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
if (!target) target = c;
|
|
458
|
-
if (c.isTop()) {
|
|
459
|
-
target = c;
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
531
|
+
if (entry.surface.isTop()) {
|
|
532
|
+
target = entry;
|
|
533
|
+
targetIdx = i;
|
|
534
|
+
break;
|
|
462
535
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
if (
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
536
|
+
}
|
|
537
|
+
if (!target) {
|
|
538
|
+
const removed = entries.pop();
|
|
539
|
+
if (removed) removed.live = false;
|
|
540
|
+
maybeTeardownListener();
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
target.live = false;
|
|
544
|
+
entries.splice(targetIdx, 1);
|
|
545
|
+
const settled = target;
|
|
546
|
+
void Promise.resolve(settled.surface.close()).then(() => {
|
|
547
|
+
if (settled.surface.isOpen()) restore(settled);
|
|
471
548
|
});
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
549
|
+
maybeTeardownListener();
|
|
550
|
+
}
|
|
551
|
+
function restore(entry) {
|
|
552
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
553
|
+
entry.live = true;
|
|
554
|
+
runInternal(() => {
|
|
555
|
+
try {
|
|
556
|
+
history.pushState(entry.surface.markerState(), "", entry.surface.url);
|
|
557
|
+
} catch {
|
|
558
|
+
entry.live = false;
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
if (entry.live) {
|
|
562
|
+
entries.push(entry);
|
|
563
|
+
ensureListener();
|
|
479
564
|
}
|
|
480
|
-
}
|
|
565
|
+
}
|
|
566
|
+
function pushBackMarker(surface) {
|
|
567
|
+
const entry = { surface, priorUrl: void 0, live: false };
|
|
568
|
+
if (!hasWindow() || !hasHistory()) {
|
|
569
|
+
return entry;
|
|
570
|
+
}
|
|
571
|
+
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
572
|
+
runInternal(() => {
|
|
573
|
+
try {
|
|
574
|
+
history.pushState(surface.markerState(), "", surface.url);
|
|
575
|
+
entry.live = true;
|
|
576
|
+
} catch {
|
|
577
|
+
entry.live = false;
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
if (entry.live) {
|
|
581
|
+
entries.push(entry);
|
|
582
|
+
ensureListener();
|
|
583
|
+
}
|
|
584
|
+
return entry;
|
|
585
|
+
}
|
|
586
|
+
function popBackMarker(handle) {
|
|
587
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
588
|
+
const entry = handle;
|
|
589
|
+
const idx = entries.indexOf(entry);
|
|
590
|
+
if (idx === -1 || !entry.live) return;
|
|
591
|
+
const last = entries.length - 1;
|
|
592
|
+
entry.live = false;
|
|
593
|
+
entries.splice(idx, 1);
|
|
594
|
+
if (idx !== last) {
|
|
595
|
+
const rebrandSurface = entries[entries.length - 1].surface;
|
|
596
|
+
const rebrandUrl = entry.priorUrl;
|
|
597
|
+
pendingRebrand = () => {
|
|
598
|
+
runInternal(() => {
|
|
599
|
+
history.replaceState(
|
|
600
|
+
rebrandSurface.markerState(),
|
|
601
|
+
"",
|
|
602
|
+
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
603
|
+
);
|
|
604
|
+
});
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
suppress += 1;
|
|
608
|
+
runInternal(() => {
|
|
609
|
+
try {
|
|
610
|
+
history.back();
|
|
611
|
+
} catch {
|
|
612
|
+
suppress = Math.max(0, suppress - 1);
|
|
613
|
+
pendingRebrand = null;
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
maybeTeardownListener();
|
|
617
|
+
}
|
|
618
|
+
function subscribeRouteChange(fn) {
|
|
619
|
+
if (!hasWindow() || !hasHistory()) return () => {
|
|
620
|
+
};
|
|
621
|
+
subscribers.add(fn);
|
|
622
|
+
if (subscribers.size === 1) installPatch();
|
|
623
|
+
ensureListener();
|
|
624
|
+
return () => {
|
|
625
|
+
if (!subscribers.has(fn)) return;
|
|
626
|
+
subscribers.delete(fn);
|
|
627
|
+
if (subscribers.size === 0) removePatch();
|
|
628
|
+
maybeTeardownListener();
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// src/core/features/route.ts
|
|
481
633
|
function installRoute(deps) {
|
|
482
634
|
if (typeof window === "undefined") {
|
|
483
635
|
return () => {
|
|
@@ -487,92 +639,39 @@ function installRoute(deps) {
|
|
|
487
639
|
return () => {
|
|
488
640
|
};
|
|
489
641
|
}
|
|
490
|
-
let
|
|
491
|
-
let closer = null;
|
|
492
|
-
const teardownEntry = () => {
|
|
493
|
-
if (closer) {
|
|
494
|
-
const idx = closers.indexOf(closer);
|
|
495
|
-
if (idx !== -1) closers.splice(idx, 1);
|
|
496
|
-
}
|
|
497
|
-
const wasConsumed = closer?.consumed ?? false;
|
|
498
|
-
closer = null;
|
|
499
|
-
if (pushed && !wasConsumed) {
|
|
500
|
-
pushed = false;
|
|
501
|
-
programmaticBack();
|
|
502
|
-
} else {
|
|
503
|
-
pushed = false;
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
const pushEntry = () => {
|
|
507
|
-
try {
|
|
508
|
-
if (deps.routedTo !== void 0) {
|
|
509
|
-
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
510
|
-
} else {
|
|
511
|
-
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
512
|
-
}
|
|
513
|
-
pushed = true;
|
|
514
|
-
} catch {
|
|
515
|
-
pushed = false;
|
|
516
|
-
}
|
|
517
|
-
};
|
|
642
|
+
let handle = null;
|
|
518
643
|
const onOpen = () => {
|
|
519
|
-
if (
|
|
520
|
-
|
|
644
|
+
if (handle) return;
|
|
645
|
+
handle = pushBackMarker({
|
|
521
646
|
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
522
|
-
isTop:
|
|
523
|
-
close:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
closer = self;
|
|
533
|
-
ensureHandler();
|
|
534
|
-
closers.push(self);
|
|
535
|
-
pushEntry();
|
|
647
|
+
isTop: deps.isTopSheet,
|
|
648
|
+
close: deps.close,
|
|
649
|
+
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
650
|
+
url: deps.routedTo
|
|
651
|
+
});
|
|
652
|
+
};
|
|
653
|
+
const onClose = () => {
|
|
654
|
+
if (!handle) return;
|
|
655
|
+
popBackMarker(handle);
|
|
656
|
+
handle = null;
|
|
536
657
|
};
|
|
537
658
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
538
|
-
const unsubscribeClose = deps.on("close",
|
|
659
|
+
const unsubscribeClose = deps.on("close", onClose);
|
|
539
660
|
if (deps.getSize() > 0) onOpen();
|
|
540
661
|
return () => {
|
|
541
662
|
unsubscribeOpen();
|
|
542
663
|
unsubscribeClose();
|
|
543
|
-
|
|
664
|
+
if (handle) {
|
|
665
|
+
popBackMarker(handle);
|
|
666
|
+
handle = null;
|
|
667
|
+
}
|
|
544
668
|
};
|
|
545
669
|
}
|
|
546
670
|
function installRouteChange(deps) {
|
|
547
|
-
|
|
548
|
-
return () => {
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
const onChange = () => {
|
|
671
|
+
return subscribeRouteChange(() => {
|
|
552
672
|
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
553
673
|
void deps.close();
|
|
554
|
-
};
|
|
555
|
-
const wrap = (key) => {
|
|
556
|
-
const original = history[key];
|
|
557
|
-
const patched = function(...args) {
|
|
558
|
-
original.apply(this, args);
|
|
559
|
-
onChange();
|
|
560
|
-
};
|
|
561
|
-
history[key] = patched;
|
|
562
|
-
return () => {
|
|
563
|
-
if (history[key] === patched) {
|
|
564
|
-
history[key] = original;
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
};
|
|
568
|
-
window.addEventListener("popstate", onChange);
|
|
569
|
-
const restorePush = wrap("pushState");
|
|
570
|
-
const restoreReplace = wrap("replaceState");
|
|
571
|
-
return () => {
|
|
572
|
-
window.removeEventListener("popstate", onChange);
|
|
573
|
-
restorePush();
|
|
574
|
-
restoreReplace();
|
|
575
|
-
};
|
|
674
|
+
});
|
|
576
675
|
}
|
|
577
676
|
|
|
578
677
|
// src/core/features/content-swipe.ts
|
|
@@ -2425,7 +2524,7 @@ var matchesRange = (def, progress) => {
|
|
|
2425
2524
|
};
|
|
2426
2525
|
function installScrimStages(deps, opts) {
|
|
2427
2526
|
const doc = deps.host.ownerDocument;
|
|
2428
|
-
const
|
|
2527
|
+
const entries2 = opts.stages.map((def) => {
|
|
2429
2528
|
const wrapper = doc.createElement("div");
|
|
2430
2529
|
wrapper.className = "bs-scrim-stage";
|
|
2431
2530
|
const ws = wrapper.style;
|
|
@@ -2446,9 +2545,9 @@ function installScrimStages(deps, opts) {
|
|
|
2446
2545
|
const resolveActive = () => {
|
|
2447
2546
|
const state = deps.getState();
|
|
2448
2547
|
if (state.size === 0) {
|
|
2449
|
-
return
|
|
2548
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2450
2549
|
}
|
|
2451
|
-
return
|
|
2550
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2452
2551
|
};
|
|
2453
2552
|
const hide = (entry, animate) => {
|
|
2454
2553
|
entry.inFlight?.cancel();
|
|
@@ -2497,13 +2596,13 @@ function installScrimStages(deps, opts) {
|
|
|
2497
2596
|
deps.on("open", () => update(true)),
|
|
2498
2597
|
deps.on("close", () => update(true))
|
|
2499
2598
|
];
|
|
2500
|
-
if (
|
|
2599
|
+
if (entries2.some((e) => e.def.forRange)) {
|
|
2501
2600
|
offs.push(deps.on("progress", () => update(true)));
|
|
2502
2601
|
}
|
|
2503
2602
|
update(false);
|
|
2504
2603
|
return () => {
|
|
2505
2604
|
offs.forEach((off) => off());
|
|
2506
|
-
for (const entry of
|
|
2605
|
+
for (const entry of entries2) {
|
|
2507
2606
|
entry.inFlight?.cancel();
|
|
2508
2607
|
entry.inFlight = null;
|
|
2509
2608
|
if (entry.wrapper.parentNode) {
|
|
@@ -2762,8 +2861,8 @@ var BottomSheetEngine = class {
|
|
|
2762
2861
|
this.attach();
|
|
2763
2862
|
this.registerInStack();
|
|
2764
2863
|
if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
|
|
2765
|
-
const io = new IntersectionObserver((
|
|
2766
|
-
for (const entry of
|
|
2864
|
+
const io = new IntersectionObserver((entries2) => {
|
|
2865
|
+
for (const entry of entries2) {
|
|
2767
2866
|
if (!entry.isIntersecting) continue;
|
|
2768
2867
|
if (this.destroyed) return;
|
|
2769
2868
|
this.snaps.recompute();
|
|
@@ -3480,9 +3579,9 @@ var BottomSheetEngine = class {
|
|
|
3480
3579
|
return;
|
|
3481
3580
|
}
|
|
3482
3581
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
3483
|
-
const
|
|
3484
|
-
if (
|
|
3485
|
-
void this.animation.animateTo(
|
|
3582
|
+
const restore2 = this.snaps.findById(previousId);
|
|
3583
|
+
if (restore2) {
|
|
3584
|
+
void this.animation.animateTo(restore2.size, 0);
|
|
3486
3585
|
}
|
|
3487
3586
|
return;
|
|
3488
3587
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@surdeddd/bottom-sheet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Universal, headless bottom sheet — framework-agnostic core with React, Vue 3, Svelte, Solid, Qwik, Preact, Lit and Custom Element adapters. Pointer Events, snap points, momentum, a11y, SSR-safe.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
{
|
|
176
176
|
"name": "core (engine + types)",
|
|
177
177
|
"path": "dist/index.js",
|
|
178
|
-
"limit": "22 KB",
|
|
178
|
+
"limit": "22.5 KB",
|
|
179
179
|
"gzip": true
|
|
180
180
|
},
|
|
181
181
|
{
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
{
|
|
188
188
|
"name": "vue adapter",
|
|
189
189
|
"path": "dist/vue.js",
|
|
190
|
-
"limit": "
|
|
190
|
+
"limit": "22 KB",
|
|
191
191
|
"gzip": true
|
|
192
192
|
},
|
|
193
193
|
{
|
|
@@ -199,13 +199,13 @@
|
|
|
199
199
|
{
|
|
200
200
|
"name": "solid adapter",
|
|
201
201
|
"path": "dist/solid.js",
|
|
202
|
-
"limit": "20 KB",
|
|
202
|
+
"limit": "20.5 KB",
|
|
203
203
|
"gzip": true
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
"name": "qwik adapter",
|
|
207
207
|
"path": "dist/qwik.js",
|
|
208
|
-
"limit": "20 KB",
|
|
208
|
+
"limit": "20.5 KB",
|
|
209
209
|
"gzip": true
|
|
210
210
|
},
|
|
211
211
|
{
|
|
@@ -226,7 +226,7 @@
|
|
|
226
226
|
{
|
|
227
227
|
"name": "web component (IIFE / CDN)",
|
|
228
228
|
"path": "dist/element.iife.global.js",
|
|
229
|
-
"limit": "
|
|
229
|
+
"limit": "25 KB",
|
|
230
230
|
"gzip": true
|
|
231
231
|
},
|
|
232
232
|
{
|
|
@@ -254,6 +254,8 @@
|
|
|
254
254
|
"typecheck": "tsc --noEmit",
|
|
255
255
|
"test": "vitest run",
|
|
256
256
|
"test:watch": "vitest",
|
|
257
|
+
"e2e": "playwright test --project=mobile-chrome",
|
|
258
|
+
"docs:check": "node ./scripts/docs-check.mjs",
|
|
257
259
|
"bench": "vitest bench",
|
|
258
260
|
"size": "size-limit",
|
|
259
261
|
"docs:api": "typedoc",
|