Skip to content

Commit cd38ac3

Browse files
committed
fix(drawer): open/disabled state for swipe and pointer handlers
1 parent 4f01025 commit cd38ac3

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

packages/bits-ui/src/lib/bits/drawer/drawer.svelte.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ export class DrawerTether<Payload = unknown> {
574574
}
575575

576576
get isOpen() {
577-
return this.#state.root?.opts.open.current ?? false;
577+
return this.#state.root?.isOpen ?? false;
578578
}
579579

580580
get payload() {
@@ -659,6 +659,7 @@ export class DrawerRootState {
659659
lastTouchTriggerUpId = $state<string | null>(null);
660660
lastCommittedSnapOffset = $state<number | null>(null);
661661
backdropSwipeProgress = $state(0);
662+
isOpen = false;
662663

663664
popupPresence: PresenceManager;
664665
backdropPresence: PresenceManager;
@@ -669,6 +670,7 @@ export class DrawerRootState {
669670
this.depth = parent ? parent.depth + 1 : 0;
670671
this.tetherState = opts.tether.current?.state ?? null;
671672
this.registry = this.tetherState?.registry ?? new DrawerTriggerRegistryState();
673+
this.isOpen = this.opts.open.current;
672674

673675
this.popupPresence = new PresenceManager({
674676
ref: boxWith(() => this.popupNode),
@@ -720,6 +722,7 @@ export class DrawerRootState {
720722
watch(
721723
() => this.opts.open.current,
722724
(isOpen) => {
725+
this.isOpen = isOpen;
723726
if (isOpen) {
724727
this.ensureActiveTrigger();
725728
this.parent?.incrementNested();
@@ -761,7 +764,7 @@ export class DrawerRootState {
761764
}
762765

763766
onDestroyEffect(() => {
764-
if (this.opts.open.current) {
767+
if (this.isOpen) {
765768
this.parent?.decrementNested();
766769
}
767770
this.provider?.removeDrawer(this.opts.id.current);
@@ -770,17 +773,20 @@ export class DrawerRootState {
770773

771774
handleOpen = () => {
772775
this.ensureActiveTrigger();
776+
this.isOpen = true;
773777
this.opts.open.current = true;
774778
};
775779

776780
handleOpenWithPayload = (payload: unknown) => {
777781
this.registry.setActiveTrigger(null);
778782
this.tetherPayload = payload;
783+
this.isOpen = true;
779784
this.opts.open.current = true;
780785
};
781786

782787
handleClose = () => {
783-
if (!this.opts.open.current) return;
788+
if (!this.isOpen) return;
789+
this.isOpen = false;
784790
this.opts.open.current = false;
785791
};
786792

@@ -1567,7 +1573,7 @@ export class DrawerViewportState {
15671573
});
15681574
this.swipe = new SwipeDismiss({
15691575
enabled: () =>
1570-
!this.destroyed && this.root.opts.open.current && this.root.nestedOpenCount === 0,
1576+
!this.destroyed && this.root.isOpen && this.root.nestedOpenCount === 0,
15711577
directions: () => {
15721578
if (this.destroyed) return [];
15731579
const hasSnapPoints =
@@ -1801,7 +1807,7 @@ export class DrawerViewportState {
18011807

18021808
if (
18031809
shouldIgnoreSwipeForTextSelection(doc, rootElement) ||
1804-
!this.root.opts.open.current ||
1810+
!this.root.isOpen ||
18051811
this.root.nestedOpenCount > 0
18061812
) {
18071813
updateTouchScrollPosition(touchState, touch);
@@ -1907,7 +1913,7 @@ export class DrawerViewportState {
19071913
? viewport.ownerDocument.defaultView.visualViewport.offsetTop +
19081914
viewport.ownerDocument.defaultView.visualViewport.height
19091915
: viewport.getBoundingClientRect().bottom;
1910-
if (isIOS && this.root.opts.open.current && this.keyboardViewportInset > 0) {
1916+
if (isIOS && this.root.isOpen && this.keyboardViewportInset > 0) {
19111917
this.syncFocusedInputVisibilityWithinPopup(visualViewportBottom);
19121918
}
19131919
};
@@ -2167,7 +2173,7 @@ export class DrawerViewportState {
21672173
const backdropElement = this.root.backdropNode;
21682174
if (!popupElement) return;
21692175

2170-
const isActive = this.root.opts.open.current && shouldTrackProgress;
2176+
const isActive = this.root.isOpen && shouldTrackProgress;
21712177
const swipeProgress = isActive ? progress : 0;
21722178
this.root.backdropSwipeProgress = swipeProgress;
21732179
if (notifyParent && this.root.parent) {
@@ -2444,7 +2450,7 @@ export class DrawerViewportState {
24442450
onpointerdown(event: PointerEvent) {
24452451
if (this.destroyed) return;
24462452
if (event.pointerType === "touch") return;
2447-
if (!this.root.opts.open.current || this.root.nestedOpenCount > 0) return;
2453+
if (!this.root.isOpen || this.root.nestedOpenCount > 0) return;
24482454
const currentTarget = event.currentTarget;
24492455
if (!(currentTarget instanceof Element)) return;
24502456
const elementAtPoint = currentTarget.ownerDocument.elementFromPoint(
@@ -2487,7 +2493,7 @@ export class DrawerViewportState {
24872493
const touch = event.touches[0];
24882494
const rootElement = this.root.viewportNode ?? this.root.popupNode;
24892495
if (
2490-
!this.root.opts.open.current ||
2496+
!this.root.isOpen ||
24912497
this.root.nestedOpenCount > 0 ||
24922498
!touch ||
24932499
!rootElement
@@ -3232,6 +3238,7 @@ export class DrawerSwipeAreaState {
32323238
openedBySwipe = false;
32333239
closedOffset: number | null = null;
32343240
popupSwipeTransition: string | null = null;
3241+
isDisabled = false;
32353242
destroyed = false;
32363243

32373244
constructor(opts: DrawerSwipeAreaStateOpts, root: DrawerRootState) {
@@ -3246,11 +3253,12 @@ export class DrawerSwipeAreaState {
32463253
this.ontouchmove = this.ontouchmove.bind(this);
32473254
this.ontouchend = this.ontouchend.bind(this);
32483255
this.ontouchcancel = this.ontouchcancel.bind(this);
3256+
this.isDisabled = this.opts.disabled.current;
32493257
this.swipe = new SwipeDismiss({
32503258
enabled: () =>
32513259
!this.destroyed &&
3252-
!this.opts.disabled.current &&
3253-
(!this.root.opts.open.current || this.swipeActive),
3260+
!this.isDisabled &&
3261+
(!this.root.isOpen || this.swipeActive),
32543262
directions: () => (this.destroyed ? [] : [this.resolvedSwipeDirection]),
32553263
element: () => (this.destroyed ? null : this.opts.ref.current),
32563264
trackDrag: false,
@@ -3306,10 +3314,10 @@ export class DrawerSwipeAreaState {
33063314
threshold != null &&
33073315
direction === this.resolvedSwipeDirection &&
33083316
(hasEnoughDistance || hasEnoughVelocity || softCommitWhileDragging) &&
3309-
!this.opts.disabled.current;
3317+
!this.isDisabled;
33103318

33113319
if (shouldOpen) {
3312-
if (!this.root.opts.open.current) {
3320+
if (!this.root.isOpen) {
33133321
this.root.handleOpen();
33143322
}
33153323
} else if (this.openedBySwipe) {
@@ -3324,6 +3332,13 @@ export class DrawerSwipeAreaState {
33243332
},
33253333
});
33263334

3335+
watch(
3336+
() => this.opts.disabled.current,
3337+
(disabled) => {
3338+
this.isDisabled = disabled;
3339+
}
3340+
);
3341+
33273342
onDestroyEffect(() => {
33283343
this.destroyed = true;
33293344
this.swipe.destroy();
@@ -3357,7 +3372,7 @@ export class DrawerSwipeAreaState {
33573372
if (!this.swipeActive) return;
33583373
const popupElement = this.root.popupNode;
33593374
if (!popupElement) return;
3360-
if (!this.root.opts.open.current) return;
3375+
if (!this.root.isOpen) return;
33613376

33623377
if (this.closedOffset == null) {
33633378
this.closedOffset = this.resolvePopupSize();

0 commit comments

Comments
 (0)