diff --git a/src/components/Dashboard/common/TemplatePreview.jsx b/src/components/Dashboard/common/TemplatePreview.jsx index f5086e32..251e530b 100644 --- a/src/components/Dashboard/common/TemplatePreview.jsx +++ b/src/components/Dashboard/common/TemplatePreview.jsx @@ -21,6 +21,17 @@ import ProgressDisplay from './ProgressDisplay.jsx' import { CaretDownFilled } from '@ant-design/icons' const noop = () => {} +const scaleCssSize = (size, scale) => { + if (scale === 1 || typeof size !== 'string' || !size.endsWith('px')) { + return size + } + const value = parseFloat(size) + if (!Number.isFinite(value)) { + return size + } + return `${Math.ceil(value * scale)}px` +} + const TemplatePreview = ({ objectData, documentTemplate, @@ -57,6 +68,8 @@ const TemplatePreview = ({ const [previewScale, setPreviewScale] = useState(1) const [previewType, setPreviewType] = useState('HTML') const [previewWidth, setPreviewWidth] = useState(defaultPreviewWidth) + const previewWidthRef = useRef(previewWidth) + previewWidthRef.current = previewWidth const [panMode, setPanMode] = useState(false) const [isPanning, setIsPanning] = useState(false) const panStartRef = useRef({ x: 0, y: 0, scrollLeft: 0, scrollTop: 0 }) @@ -93,12 +106,43 @@ const TemplatePreview = ({ return } + if (showWidthControl && !doc.querySelector('.previewDocument') && doc.body) { + const container = doc.createElement('div') + container.className = 'previewContainer' + const pages = doc.createElement('div') + pages.className = 'previewPages' + pages.id = 'pages' + const wrapper = doc.createElement('div') + wrapper.className = 'previewWrapper' + const page = doc.createElement('div') + page.className = 'previewDocument documentPage' + page.id = 'content' + while (doc.body.firstChild) { + page.appendChild(doc.body.firstChild) + } + wrapper.appendChild(page) + pages.appendChild(wrapper) + container.appendChild(pages) + doc.body.appendChild(container) + if (!doc.head?.querySelector('style[data-preview-chrome]')) { + const styleEl = doc.createElement('style') + styleEl.setAttribute('data-preview-chrome', 'true') + styleEl.textContent = + '.previewContainer{display:flex;justify-content:center;align-items:flex-start;padding:60px;box-sizing:border-box;width:fit-content}.previewPages{display:flex;flex-direction:row;align-items:flex-start;width:fit-content}.previewWrapper{position:relative;flex-shrink:0}.previewDocument{background:#fff;border:1px solid #000;box-shadow:0 0 5px rgba(0,0,0,.2);transform-origin:top left;position:relative;overflow:visible;box-sizing:content-box}' + doc.head?.appendChild(styleEl) + } + } + const wrappers = doc.querySelectorAll('.previewWrapper') wrappers.forEach((wrapper) => { const page = wrapper.querySelector('.previewDocument') if (!page) { return } + if (showWidthControl) { + page.style.width = `${previewWidth}px` + page.style.maxWidth = `${previewWidth}px` + } const pageVisual = page.getBoundingClientRect() if (pageVisual.width <= 0 && pageVisual.height <= 0) { return @@ -130,9 +174,7 @@ const TemplatePreview = ({ parseFloat(containerStyle.paddingBottom) } - const contentWidth = showWidthControl - ? previewWidth - : Math.ceil(visual.width + padX) + const contentWidth = Math.ceil(visual.width + padX) const contentHeight = Math.ceil( Math.max(visual.height + padY, doc.documentElement.scrollHeight) ) @@ -192,6 +234,13 @@ const TemplatePreview = ({ restoreScrollPosition() }, [iframeSize, restoreScrollPosition]) + useLayoutEffect(() => { + if (previewType != 'HTML') { + return + } + applyIframeContentSize() + }, [applyIframeContentSize, previewType, previewWidth]) + const updatePreviewContentHTML = (html) => { const scrollEl = scrollElementRef.current if (scrollEl) { @@ -370,7 +419,7 @@ const TemplatePreview = ({ ) const reloadPreview = useCallback( - (content, testObject = {}, scale = 1) => { + (content, testObject = {}) => { const templateId = currentTemplate?._id if (!templateId) { return @@ -382,7 +431,7 @@ const TemplatePreview = ({ templateId, content, testObject, - scale, + 1, (result) => { if (requestId !== previewRequestIdRef.current) { return @@ -396,14 +445,13 @@ const TemplatePreview = ({ } }, templateType, - showWidthControl ? { width: previewWidth } : {} + showWidthControl ? { width: previewWidthRef.current } : {} ) }, [ currentTemplate?._id, fetchTemplatePreview, onPreviewMessage, - previewWidth, showWidthControl, templateType ] @@ -424,7 +472,7 @@ const TemplatePreview = ({ const timeoutId = window.setTimeout(() => { if (content == null) { - reloadPreview(templateContent, objectData, previewScale) + reloadPreview(templateContent, objectData) } }, 300) @@ -435,8 +483,6 @@ const TemplatePreview = ({ objectData, templateContent, templateId, - previewScale, - previewWidth, previewType, reloadPreview, content @@ -534,6 +580,8 @@ const TemplatePreview = ({ }, [isPanning]) const showProgressOverlay = previewType != 'HTML' && downloadProgress != null + const scaledIframeWidth = scaleCssSize(iframeSize.width, previewScale) + const scaledIframeHeight = scaleCssSize(iframeSize.height, previewScale) const toolbarContent = ( <> @@ -707,14 +755,14 @@ const TemplatePreview = ({ align='center' style={{ minWidth: '100%', - width: iframeSize.width, - height: iframeSize.height + width: scaledIframeWidth, + height: scaledIframeHeight }} >