@@ -67,19 +67,29 @@ function MarkdownPreview({ content, fontSize }: { content: string; fontSize: num
6767 ) ;
6868}
6969
70- function HtmlPreview ( { content } : { content : string } ) {
70+ function HtmlPreview ( { content, zoom } : { content : string ; zoom : number } ) {
7171 const blob = useMemo ( ( ) => {
7272 const b = new Blob ( [ content ] , { type : "text/html" } ) ;
7373 return URL . createObjectURL ( b ) ;
7474 } , [ content ] ) ;
7575
76+ const scale = zoom / 100 ;
77+
7678 return (
77- < iframe
78- src = { blob }
79- className = "w-full h-full border-0 bg-white"
80- title = "HTML Preview"
81- sandbox = "allow-scripts"
82- />
79+ < div className = "w-full h-full overflow-auto bg-white" >
80+ < iframe
81+ src = { blob }
82+ title = "HTML Preview"
83+ sandbox = "allow-scripts"
84+ style = { {
85+ border : "none" ,
86+ width : `${ 100 / scale } %` ,
87+ height : `${ 100 / scale } %` ,
88+ transform : `scale(${ scale } )` ,
89+ transformOrigin : "0 0" ,
90+ } }
91+ />
92+ </ div >
8393 ) ;
8494}
8595
@@ -194,6 +204,8 @@ export default function CodeEditor({ path, content, onSave, onClose }: CodeEdito
194204 const [ dirty , setDirty ] = useState ( false ) ;
195205 const [ mode , setMode ] = useState < "edit" | "preview" > ( canPreview ? "preview" : "edit" ) ;
196206 const [ editorFontSize , setEditorFontSize ] = useState ( 6 ) ;
207+ const isHtml = ext === "html" || ext === "htm" ;
208+ const [ htmlZoom , setHtmlZoom ] = useState ( 100 ) ;
197209
198210 const handleChange = ( v : string | undefined ) => {
199211 if ( v !== undefined ) {
@@ -237,22 +249,30 @@ export default function CodeEditor({ path, content, onSave, onClose }: CodeEdito
237249 </ button >
238250 </ div >
239251 ) }
240- { /* Font size */ }
241- < div className = "flex items-center border border-gray-700 rounded overflow-hidden" >
242- < button
243- onClick = { ( ) => setEditorFontSize ( ( s ) => Math . max ( 6 , s - 1 ) ) }
244- className = "px-1.5 py-0.5 text-gray-400 hover:text-white hover:bg-gray-700 transition-colors leading-none"
245- >
246- < span className = "text-[9px] font-bold" > a</ span >
247- </ button >
248- < span className = "text-[10px] text-gray-500 w-5 text-center tabular-nums" > { editorFontSize } </ span >
249- < button
250- onClick = { ( ) => setEditorFontSize ( ( s ) => Math . min ( 32 , s + 1 ) ) }
251- className = "px-1.5 py-0.5 text-gray-400 hover:text-white hover:bg-gray-700 transition-colors leading-none"
252- >
253- < span className = "text-[14px] font-bold" > A</ span >
254- </ button >
255- </ div >
252+ { /* Font size / Zoom controls */ }
253+ { isHtml && mode === "preview" ? (
254+ < div className = "flex items-center gap-1 border border-gray-700 rounded overflow-hidden" >
255+ < button onClick = { ( ) => setHtmlZoom ( ( z ) => Math . max ( 25 , z - 25 ) ) } className = "px-2 py-0.5 text-xs text-gray-400 hover:text-white hover:bg-gray-700" > -</ button >
256+ < button onClick = { ( ) => setHtmlZoom ( 100 ) } className = "px-2 py-0.5 text-[10px] text-gray-400 hover:text-white hover:bg-gray-700 tabular-nums" > { htmlZoom } %</ button >
257+ < button onClick = { ( ) => setHtmlZoom ( ( z ) => Math . min ( 300 , z + 25 ) ) } className = "px-2 py-0.5 text-xs text-gray-400 hover:text-white hover:bg-gray-700" > +</ button >
258+ </ div >
259+ ) : (
260+ < div className = "flex items-center border border-gray-700 rounded overflow-hidden" >
261+ < button
262+ onClick = { ( ) => setEditorFontSize ( ( s ) => Math . max ( 6 , s - 1 ) ) }
263+ className = "px-1.5 py-0.5 text-gray-400 hover:text-white hover:bg-gray-700 transition-colors leading-none"
264+ >
265+ < span className = "text-[9px] font-bold" > a</ span >
266+ </ button >
267+ < span className = "text-[10px] text-gray-500 w-5 text-center tabular-nums" > { editorFontSize } </ span >
268+ < button
269+ onClick = { ( ) => setEditorFontSize ( ( s ) => Math . min ( 32 , s + 1 ) ) }
270+ className = "px-1.5 py-0.5 text-gray-400 hover:text-white hover:bg-gray-700 transition-colors leading-none"
271+ >
272+ < span className = "text-[14px] font-bold" > A</ span >
273+ </ button >
274+ </ div >
275+ ) }
256276 < a
257277 href = { `/api/files/download?path=${ encodeURIComponent ( path ) } ` }
258278 download
@@ -286,7 +306,7 @@ export default function CodeEditor({ path, content, onSave, onClose }: CodeEdito
286306 ext === "ipynb" ? (
287307 < NotebookPreview content = { value } fontSize = { editorFontSize } />
288308 ) : ext === "html" || ext === "htm" ? (
289- < HtmlPreview content = { value } />
309+ < HtmlPreview content = { value } zoom = { htmlZoom } />
290310 ) : (
291311 < MarkdownPreview content = { value } fontSize = { editorFontSize } />
292312 )
0 commit comments