fix: lock Beam viewer background gestures

This commit is contained in:
DCCONSTRUCTIONS 2026-06-05 13:11:32 +03:00
parent 867f7bc558
commit ff30eeb8fd
2 changed files with 59 additions and 0 deletions

View File

@ -138,6 +138,52 @@ export const IssueView = observer(function IssueView(props: IIssueView) {
isDeleteIssueModalOpen || isArchiveIssueModalOpen || isDuplicateIssueModalOpen || isEditIssueModalOpen; isDeleteIssueModalOpen || isArchiveIssueModalOpen || isDuplicateIssueModalOpen || isEditIssueModalOpen;
const shouldUseBeamPeekShell = !embedIssue && peekMode === "side-peek" && !!beamPeekViewer; const shouldUseBeamPeekShell = !embedIssue && peekMode === "side-peek" && !!beamPeekViewer;
useEffect(() => {
if (typeof window === "undefined" || !shouldUseBeamPeekShell) return;
const root = document.documentElement;
root.classList.add("nodedc-beam-viewer-interaction-lock");
const isViewerEvent = (event: Event) => {
const shell = issuePeekOverviewRef.current;
if (!shell) return false;
const viewerCard = shell.querySelector(".nodedc-beam-peek-viewer-card");
const target = event.target instanceof Node ? event.target : null;
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
return !!viewerCard && ((target && viewerCard.contains(target)) || path.includes(viewerCard));
};
const stopViewerGestureLeak = (event: Event) => {
if (!isViewerEvent(event)) return;
event.stopPropagation();
if ((event.type === "wheel" || event.type === "touchmove") && event.cancelable) {
event.preventDefault();
}
};
const passiveOptions: AddEventListenerOptions = { capture: true, passive: true };
const activeOptions: AddEventListenerOptions = { capture: true, passive: false };
window.addEventListener("wheel", stopViewerGestureLeak, activeOptions);
window.addEventListener("touchmove", stopViewerGestureLeak, activeOptions);
window.addEventListener("pointerdown", stopViewerGestureLeak, passiveOptions);
window.addEventListener("pointermove", stopViewerGestureLeak, passiveOptions);
window.addEventListener("pointerup", stopViewerGestureLeak, passiveOptions);
return () => {
root.classList.remove("nodedc-beam-viewer-interaction-lock");
window.removeEventListener("wheel", stopViewerGestureLeak, activeOptions);
window.removeEventListener("touchmove", stopViewerGestureLeak, activeOptions);
window.removeEventListener("pointerdown", stopViewerGestureLeak, passiveOptions);
window.removeEventListener("pointermove", stopViewerGestureLeak, passiveOptions);
window.removeEventListener("pointerup", stopViewerGestureLeak, passiveOptions);
};
}, [shouldUseBeamPeekShell]);
const getMaxSidePeekWidth = useCallback(() => { const getMaxSidePeekWidth = useCallback(() => {
if (typeof window === "undefined") return 720; if (typeof window === "undefined") return 720;
const minWidth = 640; const minWidth = 640;

View File

@ -360,12 +360,23 @@
align-items: stretch; align-items: stretch;
column-gap: 0.75rem; column-gap: 0.75rem;
overflow: visible; overflow: visible;
overscroll-behavior: contain;
transition: transition:
column-gap 260ms ease, column-gap 260ms ease,
grid-template-columns 260ms ease, grid-template-columns 260ms ease,
opacity 220ms ease; opacity 220ms ease;
} }
html.nodedc-beam-viewer-interaction-lock,
html.nodedc-beam-viewer-interaction-lock body {
overscroll-behavior: none;
}
html.nodedc-beam-viewer-interaction-lock main .nodedc-kanban-scroll-container {
overflow: hidden !important;
overscroll-behavior: none;
}
.nodedc-beam-peek-shell[data-resizing="true"] { .nodedc-beam-peek-shell[data-resizing="true"] {
transition: none; transition: none;
} }
@ -386,6 +397,7 @@
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
overflow: hidden; overflow: hidden;
overscroll-behavior: contain;
background: #000; background: #000;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 28px; border-radius: 28px;
@ -440,6 +452,7 @@
border: 0 !important; border: 0 !important;
outline: none !important; outline: none !important;
box-shadow: none !important; box-shadow: none !important;
overscroll-behavior: contain;
} }
.nodedc-beam-peek-shell[data-resizing="true"] iframe { .nodedc-beam-peek-shell[data-resizing="true"] iframe {