From f4b80d5301d3213dbacd1ba654f5d94f045c1fc4 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 6 Jun 2026 10:14:35 -0400 Subject: [PATCH] fix: PDF display does not correctly scale on ombile (#12608) --- app/editor/menus/block.tsx | 2 - shared/editor/components/PDF.tsx | 37 +++++++++++-------- shared/editor/components/Styles.ts | 25 ------------- .../editor/components/hooks/useDragResize.ts | 4 +- 4 files changed, 24 insertions(+), 44 deletions(-) diff --git a/app/editor/menus/block.tsx b/app/editor/menus/block.tsx index 0ed9f5bea6..413aef9d79 100644 --- a/app/editor/menus/block.tsx +++ b/app/editor/menus/block.tsx @@ -124,8 +124,6 @@ export default function blockMenuItems( keywords: "pdf upload attach", attrs: { accept: "application/pdf", - width: 300, - height: 424, preview: true, }, }, diff --git a/shared/editor/components/PDF.tsx b/shared/editor/components/PDF.tsx index 02c8fe1142..184b884631 100644 --- a/shared/editor/components/PDF.tsx +++ b/shared/editor/components/PDF.tsx @@ -9,6 +9,13 @@ import { s } from "../../styles"; import { Preview, Subtitle, Title } from "./Widget"; import { EditorStyleHelper } from "../styles/EditorStyleHelper"; +/** + * Default dimensions for the PDF preview – approximately the width of a standard + * document with an A4 portrait aspect ratio. + */ +const naturalWidth = 768; +const naturalHeight = 1086; + type Props = ComponentProps & { /** Icon to display on the left side of the widget */ icon: React.ReactNode; @@ -27,16 +34,14 @@ export default function PdfViewer(props: Props) { const embedRef = useRef(null); const debounceTimerRef = useRef(null); - const { width, height, setSize, handlePointerDown, dragging } = useDragResize( - { - width: node.attrs.width, - height: node.attrs.height, - naturalWidth: 300, - naturalHeight: 424, - onChangeSize, - ref, - } - ); + const { width, setSize, handlePointerDown, dragging } = useDragResize({ + width: node.attrs.width, + height: node.attrs.height, + naturalWidth, + naturalHeight, + onChangeSize, + ref, + }); useEffect(() => { if (node.attrs.width && node.attrs.width !== width) { @@ -96,7 +101,7 @@ export default function PdfViewer(props: Props) { ? "pdf-wrapper ProseMirror-selectednode" : "pdf-wrapper" } - style={{ width: width ?? "auto" }} + style={{ width: width ?? "100%" }} $dragging={dragging} > @@ -110,12 +115,10 @@ export default function PdfViewer(props: Props) { title={name} src={href} ref={embedRef} - width={ - // subtract padding and borders from width - width - 24 - } - height={height} style={{ + width: "100%", + height: "auto", + aspectRatio: `${naturalWidth} / ${naturalHeight}`, pointerEvents: !isEditable || (isSelected && !dragging) ? "initial" : "none", marginTop: 6, @@ -153,6 +156,8 @@ const PDFWrapper = styled.div<{ $dragging: boolean }>` padding: ${EditorStyleHelper.blockRadius}; embed { + display: block; + max-width: 100%; transition-property: width, height; transition-duration: ${(props) => (props.$dragging ? "0ms" : "120ms")}; transition-timing-function: ease-in-out; diff --git a/shared/editor/components/Styles.ts b/shared/editor/components/Styles.ts index b16353f0b9..a199663ccd 100644 --- a/shared/editor/components/Styles.ts +++ b/shared/editor/components/Styles.ts @@ -822,31 +822,6 @@ iframe.embed { } } -.pdf { - position: relative; - width: max-content; - height: max-content; - margin-right: auto; - margin-left: auto; - max-width: 100%; - clear: both; - z-index: 1; - transition-property: width, height; - transition-duration: 80ms; - transition-timing-function: ease-in-out; - - embed { - display: block; - max-width: 100%; - contain: strict, - content-visibility: auto, - backface-visibility: hidden, - transition-property: width, height; - transition-duration: 80ms; - transition-timing-function: ease-in-out; - } -} - .image-replacement-uploading { img { opacity: 0.5; diff --git a/shared/editor/components/hooks/useDragResize.ts b/shared/editor/components/hooks/useDragResize.ts index 0937c5a605..29a278f854 100644 --- a/shared/editor/components/hooks/useDragResize.ts +++ b/shared/editor/components/hooks/useDragResize.ts @@ -192,7 +192,9 @@ export default function useDragResize(props: Params): ReturnValue { : Infinity; setMaxWidth(max); setSizeAtDragStart({ - width: constrainWidth(size.width, max), + // When no width has been set yet the element is displayed at full width, + // so begin resizing from the maximum width rather than the minimum. + width: constrainWidth(size.width || max, max), height: size.height, }); setOffset(