unify detailpanel and documentviewer

This commit is contained in:
2025-11-11 14:45:19 +01:00
parent 10f9f3be2f
commit a8589a864a
8 changed files with 139 additions and 480 deletions
+8 -104
View File
@@ -1,7 +1,6 @@
import React, {
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
@@ -20,46 +19,7 @@ import PanelHeader from '../ui/PanelHeader';
import BreadcrumbTrail from '../ui/BreadcrumbTrail';
import { useAssetNavigator } from '../hooks/useAssetNavigator';
import DocumentViewerLayout from './DocumentViewerLayout';
const PORTRAIT_WIDTH_TO_HEIGHT = 1 / Math.sqrt(2); // ≈0.707 (A-series aspect ratio)
const DOCUMENT_VIEWER_PORTRAIT_HEIGHT_RATIO = 0.4;
const PORTRAIT_RATIO_STYLE_ID = 'document-viewer-portrait-ratio-style';
const ensurePortraitRatioStyle = () => {
if (typeof document === 'undefined') {
return;
}
const cssValue = String(DOCUMENT_VIEWER_PORTRAIT_HEIGHT_RATIO);
const cssText = `:root { --document-viewer-portrait-height-ratio: ${cssValue}; }`;
let styleEl = document.getElementById(PORTRAIT_RATIO_STYLE_ID);
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = PORTRAIT_RATIO_STYLE_ID;
document.head.appendChild(styleEl);
}
if (styleEl.textContent !== cssText) {
styleEl.textContent = cssText;
}
};
if (typeof document !== 'undefined') {
ensurePortraitRatioStyle();
}
const computeStackedLayoutBreakpoint = () => {
const viewportHeight = typeof window !== 'undefined' ? window.innerHeight : 900;
const portraitViewportWidth = viewportHeight
* DOCUMENT_VIEWER_PORTRAIT_HEIGHT_RATIO
* PORTRAIT_WIDTH_TO_HEIGHT;
const detailsColumnWidth = 320; // px ~ 20rem for metadata & tabs
const gutterAllowance = 48; // padding + grid gap
const desiredWidth = portraitViewportWidth + detailsColumnWidth + gutterAllowance;
return desiredWidth;
};
import useViewerLayoutMode from './useViewerLayoutMode';
export const createDocumentViewerHeaderActions = ({
document,
@@ -226,8 +186,6 @@ const DocumentViewerPanel = ({
[hasOcr, loadOcrContent],
);
const viewerRef = useRef(null);
const [isStackedLayout, setIsStackedLayout] = useState(false);
const [zoomOverlayOpen, setZoomOverlayOpen] = useState(false);
const previewNavigator = useAssetNavigator({
document,
@@ -263,60 +221,8 @@ const DocumentViewerPanel = ({
}
}, [hydrateDocument, document?.id]);
useLayoutEffect(() => {
ensurePortraitRatioStyle();
}, []);
useLayoutEffect(() => {
const node = viewerRef.current;
if (!node) {
setIsStackedLayout(false);
return undefined;
}
let frame = null;
const commitMeasure = (width) => {
if (frame) {
cancelAnimationFrame(frame);
}
frame = requestAnimationFrame(() => {
const breakpoint = computeStackedLayoutBreakpoint();
setIsStackedLayout(width < breakpoint);
});
};
const measure = () => {
commitMeasure(node.getBoundingClientRect().width);
};
measure();
if (typeof ResizeObserver === 'undefined') {
window.addEventListener('resize', measure);
return () => {
if (frame) {
cancelAnimationFrame(frame);
}
window.removeEventListener('resize', measure);
};
}
const observer = new ResizeObserver((entries) => {
if (!entries.length) {
return;
}
commitMeasure(entries[0].contentRect.width);
});
observer.observe(node);
return () => {
observer.disconnect();
if (frame) {
cancelAnimationFrame(frame);
}
};
}, [document?.id]);
const panelRef = useRef(null);
const isStackedLayout = useViewerLayoutMode(panelRef, document?.id);
const viewerClassName = isStackedLayout
? 'document-viewer document-viewer--stacked'
@@ -450,15 +356,13 @@ const DocumentViewerPanel = ({
if (!document) {
return (
<section className="document-viewer-panel">
<section className="document-viewer-panel" ref={panelRef}>
<PanelHeader title="Document preview" />
<div className="document-viewer-panel__body">
<section className="document-viewer document-viewer--loading" ref={viewerRef}>
<section className="document-viewer document-viewer--loading">
<div className="document-viewer__details-pane">
<div className="document-viewer__details">
<div className="document-viewer__message">
Loading document
</div>
<div className="document-viewer__message">Loading document</div>
</div>
</div>
<div className="document-viewer__viewport">
@@ -482,7 +386,7 @@ const DocumentViewerPanel = ({
return (
<>
<section className="document-viewer-panel">
<section className="document-viewer-panel" ref={panelRef}>
<PanelHeader
leading={headerLeadingContent}
title={headerTitle}
@@ -490,7 +394,7 @@ const DocumentViewerPanel = ({
actions={headerActions}
/>
<div className="document-viewer-panel__body">
<section className={viewerClassName} ref={viewerRef}>
<section className={viewerClassName}>
<DocumentViewerLayout
document={document}
previewEntry={previewEntry}