@@ -13,6 +13,7 @@ import { DocumentSize } from "~/lib/types";
13
13
import { DocumentContextProvider } from '~/contexts/document-context' ;
14
14
import { JSONSchema7 , JSONSchema7Definition } from 'json-schema' ;
15
15
import chalk from 'chalk' ;
16
+ import { MagnifyingGlassPlus , MagnifyingGlassMinus , ArrowClockwise } from '@phosphor-icons/react' ;
16
17
17
18
interface PreviewProps {
18
19
slug : string ;
@@ -54,6 +55,8 @@ const Preview = ({
54
55
iframe1 : renderedDocumentMetadata ?. markup ,
55
56
} ) ;
56
57
58
+ const [ zoomLevel , setZoomLevel ] = React . useState ( 1 ) ;
59
+
57
60
// Utility function to generate a simple hash from the markup
58
61
const generateHash = ( str : string ) => {
59
62
let hash = 0 ;
@@ -191,6 +194,46 @@ const Preview = ({
191
194
192
195
const previewProps = 'previewProps' in renderingResult ? renderingResult . previewProps : { } ;
193
196
197
+ const handleZoom = ( newZoom : number ) => {
198
+ setZoomLevel ( newZoom ) ;
199
+ const iframe = document . querySelector ( `iframe[title="${ slug } -${ activeIframeId } "]` ) ;
200
+ if ( iframe ) {
201
+ ( iframe as HTMLIFrameElement ) . contentWindow ?. postMessage ( {
202
+ type : 'zoom' ,
203
+ level : newZoom
204
+ } , '*' ) ;
205
+ }
206
+ } ;
207
+
208
+ const ZoomControls = ( ) => (
209
+ < div className = "absolute top-4 right-6 z-30 flex gap-1 bg-background/80 backdrop-blur-sm p-1.5 rounded-lg shadow-md border border-border" >
210
+ < button
211
+ onClick = { ( ) => handleZoom ( Math . max ( 0.75 , zoomLevel - 0.25 ) ) }
212
+ className = "p-1.5 hover:bg-muted rounded-md transition-colors"
213
+ title = "Zoom Out"
214
+ >
215
+ < MagnifyingGlassMinus className = "text-foreground" size = { 16 } />
216
+ </ button >
217
+ < span className = "flex items-center min-w-[3.5rem] justify-center text-sm text-foreground" >
218
+ { Math . round ( zoomLevel * 100 ) } %
219
+ </ span >
220
+ < button
221
+ onClick = { ( ) => handleZoom ( Math . min ( 4 , zoomLevel + 0.25 ) ) }
222
+ className = "p-1.5 hover:bg-muted rounded-md transition-colors"
223
+ title = "Zoom In"
224
+ >
225
+ < MagnifyingGlassPlus className = "text-foreground" size = { 16 } />
226
+ </ button >
227
+ < button
228
+ onClick = { ( ) => handleZoom ( 1 ) }
229
+ className = "p-1.5 hover:bg-muted rounded-md transition-colors"
230
+ title = "Reset Zoom"
231
+ >
232
+ < ArrowClockwise className = "text-foreground" size = { 16 } />
233
+ </ button >
234
+ </ div >
235
+ ) ;
236
+
194
237
return (
195
238
< DocumentContextProvider
196
239
initialDocumentPreviewProps = { previewProps }
@@ -217,6 +260,7 @@ const Preview = ({
217
260
{ Object . keys ( iframes ) . map ( ( id ) =>
218
261
renderIframe ( id , id === activeIframeId )
219
262
) }
263
+ < ZoomControls />
220
264
</ div >
221
265
) : null }
222
266
< Toaster />
0 commit comments