fix(12-02): body scroll lock and z-index/portal fix for PreviewModal

- Bug 1: add useEffect that locks document.body.overflow on mount and
  restores original value on unmount — prevents page scrolling behind modal
- Bug 2: render modal via ReactDOM.createPortal to document.body so it
  escapes the sticky sidebar's stacking context; raise z-index to 9999
  so backdrop sits definitively above all FieldPlacer overlay boxes
  (zIndex: 10/12) and dnd-kit DragOverlay regardless of parent context
This commit is contained in:
Chandler Copeland
2026-03-21 15:50:22 -06:00
parent 422c9a89aa
commit 43f396b4c5

View File

@@ -1,5 +1,6 @@
'use client'; 'use client';
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { Document, Page, pdfjs } from 'react-pdf'; import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css'; import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css'; import 'react-pdf/dist/Page/TextLayer.css';
@@ -19,13 +20,23 @@ export function PreviewModal({ pdfBytes, onClose }: PreviewModalProps) {
const [numPages, setNumPages] = useState(0); const [numPages, setNumPages] = useState(0);
const [pageNumber, setPageNumber] = useState(1); const [pageNumber, setPageNumber] = useState(1);
return ( // Bug 1 fix: lock body scroll while modal is open
useEffect(() => {
const original = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => { document.body.style.overflow = original; };
}, []);
// Bug 2 fix: render via portal so the modal escapes the sticky sidebar's stacking
// context. The zIndex of 9999 ensures the backdrop sits above all field overlay boxes
// (zIndex: 10/12) and dnd-kit DragOverlay regardless of parent stacking contexts.
const modal = (
<div <div
style={{ style={{
position: 'fixed', position: 'fixed',
inset: 0, inset: 0,
background: 'rgba(0,0,0,0.7)', background: 'rgba(0,0,0,0.7)',
zIndex: 50, zIndex: 9999,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
@@ -76,4 +87,6 @@ export function PreviewModal({ pdfBytes, onClose }: PreviewModalProps) {
</div> </div>
</div> </div>
); );
return createPortal(modal, document.body);
} }