Skip to content

Commit 7e02f07

Browse files
author
Tim Sinaeve
committed
Fix MD preview zoom to reflow text when scaling
Added useZoomProperty prop to ZoomPanContainer that uses CSS zoom instead of transform:scale(). This allows text to reflow when zooming, eliminating the whitespace issue.
1 parent 3bd827b commit 7e02f07

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

components/ZoomPanContainer.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ interface ZoomPanContainerProps extends React.HTMLAttributes<HTMLDivElement> {
1717
wrapperClassName?: string;
1818
layout?: 'overlay' | 'natural';
1919
lockOverflow?: boolean;
20+
/**
21+
* When true, uses CSS `zoom` property instead of `transform: scale()`.
22+
* This allows text to reflow when zooming, but panning becomes unavailable.
23+
*/
24+
useZoomProperty?: boolean;
2025
}
2126

2227
const clamp = (value: number, min: number, max: number) => {
@@ -49,6 +54,7 @@ const ZoomPanContainer = React.forwardRef<HTMLDivElement, ZoomPanContainerProps>
4954
disableZoom = false,
5055
layout = 'overlay',
5156
lockOverflow = true,
57+
useZoomProperty = false,
5258
...rest
5359
} = props;
5460

@@ -208,11 +214,18 @@ const ZoomPanContainer = React.forwardRef<HTMLDivElement, ZoomPanContainerProps>
208214
}, [initialScale, previewZoom, setOffset, setScale]);
209215

210216
const transformStyle = useMemo(() => {
217+
// When useZoomProperty is true, use CSS zoom for text reflow
218+
if (useZoomProperty) {
219+
return {
220+
zoom: scale,
221+
} as React.CSSProperties;
222+
}
223+
// Otherwise use transform: scale() for panning support
211224
return {
212225
transform: `translate3d(${offset.x}px, ${offset.y}px, 0) scale(${scale})`,
213226
transformOrigin: disablePan ? '0 0' : undefined,
214227
} as React.CSSProperties;
215-
}, [disablePan, offset.x, offset.y, scale]);
228+
}, [disablePan, offset.x, offset.y, scale, useZoomProperty]);
216229

217230
const naturalWrapperStyle = useMemo<React.CSSProperties | undefined>(() => {
218231
if (layout !== 'natural' || !disablePan) {
@@ -244,8 +257,12 @@ const ZoomPanContainer = React.forwardRef<HTMLDivElement, ZoomPanContainerProps>
244257
}, [className, disablePan, isPanning, lockOverflow]);
245258

246259
const renderContent = useCallback(() => {
260+
// When using CSS zoom, no transform-gpu needed
261+
const contentClass = useZoomProperty
262+
? contentClassName ?? ''
263+
: `transform-gpu origin-center ${contentClassName ?? ''}`;
247264
const content = (
248-
<div className={`transform-gpu origin-center ${contentClassName ?? ''}`} style={transformStyle}>
265+
<div className={contentClass} style={transformStyle}>
249266
{children}
250267
</div>
251268
);

services/preview/markdownRenderer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ const MarkdownViewer = forwardRef<HTMLDivElement, MarkdownViewerProps>(({ conten
312312
disablePan
313313
layout="natural"
314314
lockOverflow={false}
315+
useZoomProperty
315316
className="min-h-full"
316317
wrapperClassName="df-markdown-shell"
317318
contentClassName="df-markdown-stage origin-top"

0 commit comments

Comments
 (0)