Skip to content

Commit 284c1f0

Browse files
committed
fix(drawer): correct close animation for left/top and prevent double-close
- Fix _animateAndClose target formula: use ±dimension instead of dimension + getTranslate() which produced wrong position for left/top drawers (negative transforms), causing drawer to stay half-closed - Add animation: none inline style before close() to prevent Tailwind data-closed:slide-out-* keyframe animation from overriding inline transform (was visually reopening drawer) - Add setPointerCapture for reliable pointercancel delivery - Add DestroyRef.onDestroy cleanup to prevent pointermove listener leak if directive is destroyed mid-gesture - Remove unused _scrollEl field
1 parent e327139 commit 284c1f0

1 file changed

Lines changed: 18 additions & 7 deletions

File tree

libs/brain/drawer/src/lib/brn-drawer-handle.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DOCUMENT } from '@angular/common';
2-
import { Directive, ElementRef, inject, input } from '@angular/core';
2+
import { DestroyRef, Directive, ElementRef, inject, input } from '@angular/core';
33
import { BrnDialogRef } from '@spartan-ng/brain/dialog';
44
import { BrnDrawer } from './brn-drawer';
55

@@ -28,12 +28,17 @@ export class BrnDrawerHandle {
2828
private readonly _brnDrawer = inject(BrnDrawer, { optional: true });
2929
private readonly _element: ElementRef<HTMLElement> = inject(ElementRef);
3030
private readonly _document = inject(DOCUMENT);
31+
private readonly _destroyRef = inject(DestroyRef);
32+
private _pointerId = -1;
33+
34+
constructor() {
35+
this._destroyRef.onDestroy(() => this._cleanup());
36+
}
3137

3238
private _drawerEl: HTMLElement | null = null;
3339
private _backdropEl: HTMLElement | null = null;
3440
private _direction: 'bottom' | 'top' | 'left' | 'right' = 'bottom';
3541
private _initialBackdropOpacity = 1;
36-
private _scrollEl: HTMLElement | null = null;
3742

3843
private _pointerStartX = 0;
3944
private _pointerStartY = 0;
@@ -87,8 +92,7 @@ export class BrnDrawerHandle {
8792

8893
this._drawerEl.style.transition = 'none';
8994

90-
this._scrollEl = this._findScrollableAncestor(event.target as HTMLElement);
91-
if (!this._scrollEl) {
95+
if (!this._findScrollableAncestor(event.target as HTMLElement)) {
9296
event.preventDefault();
9397
}
9498

@@ -98,6 +102,13 @@ export class BrnDrawerHandle {
98102
this._initialBackdropOpacity = parseFloat(getComputedStyle(this._backdropEl).opacity) || 1;
99103
}
100104

105+
try {
106+
this._element.nativeElement.setPointerCapture(event.pointerId);
107+
} catch {
108+
/* empty - pointer capture not supported */
109+
}
110+
this._pointerId = event.pointerId;
111+
101112
this._document.addEventListener('pointermove', this._onPointerMove, { passive: false });
102113
this._document.addEventListener('pointerup', this._onPointerUp, { once: true });
103114
this._document.addEventListener('pointercancel', this._onPointerCancel, { once: true });
@@ -297,11 +308,11 @@ export class BrnDrawerHandle {
297308
private _animateAndClose(): void {
298309
if (!this._drawerEl) return;
299310
const dimension = this._isVertical ? this._drawerEl.offsetHeight : this._drawerEl.offsetWidth;
300-
const dist = dimension + this._getTranslate();
301-
const signedClose = this._isPositive ? dist : -dist;
311+
const targetClose = this._isPositive ? dimension : -dimension;
302312
const prop = this._isVertical ? 'translateY' : 'translateX';
303313
this._drawerEl.style.transition = 'transform 0.3s cubic-bezier(0.32, 0.72, 0, 1)';
304-
this._drawerEl.style.transform = `${prop}(${signedClose}px)`;
314+
this._drawerEl.style.transform = `${prop}(${targetClose}px)`;
315+
this._drawerEl.style.animation = 'none';
305316
if (this._backdropEl) {
306317
this._backdropEl.style.transition = 'opacity 0.3s cubic-bezier(0.32, 0.72, 0, 1)';
307318
this._backdropEl.style.opacity = '0';

0 commit comments

Comments
 (0)