Route Soma drawer scroll guard timer

active-uix
dev 5 months ago
parent 46009592ed
commit 51945706d2

@ -34,6 +34,7 @@ import { DRAWER_LANGS } from './langs';
import { drawerMorfo } from '../../../morfo/components/drawer'; import { drawerMorfo } from '../../../morfo/components/drawer';
import { type SomaRuntime, type SomaRuntimePart } from '$soma'; import { type SomaRuntime, type SomaRuntimePart } from '$soma';
import type { SemaSignatureOverride } from '$uix/sema'; import type { SemaSignatureOverride } from '$uix/sema';
import type { TimerHandle } from '$timer';
// ── Direction resolution ──────────────────────────────────────────────────── // ── Direction resolution ────────────────────────────────────────────────────
@ -404,7 +405,7 @@ export class DrawerContentProvider {
// Scroll-drag guard: cancel gesture if user scrolled recently // Scroll-drag guard: cancel gesture if user scrolled recently
private scrollDragBlocked = $state(false); private scrollDragBlocked = $state(false);
private scrollTimer: ReturnType<typeof setTimeout> | null = null; private scrollTimer: TimerHandle | null = null;
// Tracks whether the current pointer interaction has already fired // Tracks whether the current pointer interaction has already fired
// drag-start. Reset on release so the next gesture re-fires it. // drag-start. Reset on release so the next gesture re-fires it.
private wasDragging = $state(false); private wasDragging = $state(false);
@ -698,15 +699,21 @@ export class DrawerContentProvider {
if (!el) return; if (!el) return;
const onScroll = () => { const onScroll = () => {
this.scrollDragBlocked = true; this.scrollDragBlocked = true;
if (this.scrollTimer) clearTimeout(this.scrollTimer); this.clearScrollTimer();
this.scrollTimer = setTimeout(() => { this.scrollTimer = this.provider.soma.uix.timers.schedule(
this.scrollDragBlocked = false; this.scrollTimerKey,
}, this.provider.opts.scrollLockTimeout.current); this.provider.opts.scrollLockTimeout.current,
() => {
this.scrollTimer = null;
this.scrollDragBlocked = false;
},
{ replace: true, meta: { component: 'drawer', action: 'scroll-drag-guard' } }
);
}; };
el.addEventListener('scroll', onScroll, { passive: true, capture: true }); el.addEventListener('scroll', onScroll, { passive: true, capture: true });
return () => { return () => {
el.removeEventListener('scroll', onScroll, { capture: true }); el.removeEventListener('scroll', onScroll, { capture: true });
if (this.scrollTimer) clearTimeout(this.scrollTimer); this.clearScrollTimer();
}; };
}); });
@ -828,6 +835,17 @@ export class DrawerContentProvider {
readonly isPresent = $derived.by(() => this.provider.contentPresence.isPresent); readonly isPresent = $derived.by(() => this.provider.contentPresence.isPresent);
private clearScrollTimer() {
if (this.scrollTimer) {
this.scrollTimer.cancel();
this.scrollTimer = null;
}
}
private get scrollTimerKey() {
return `soma:drawer:${this.opts.id.current}:scroll-drag-guard`;
}
// Escape for non-modal (Dismissal layer is disabled for non-modal) // Escape for non-modal (Dismissal layer is disabled for non-modal)
readonly onkeydown = (e: KeyboardEvent) => { readonly onkeydown = (e: KeyboardEvent) => {
if ( if (

Loading…
Cancel
Save

Powered by TurnKey Linux.