Skip to content

Instantly share code, notes, and snippets.

@svrnm
Created December 18, 2025 09:13
Show Gist options
  • Select an option

  • Save svrnm/5983107069437531ddc687d44c33949c to your computer and use it in GitHub Desktop.

Select an option

Save svrnm/5983107069437531ddc687d44c33949c to your computer and use it in GitHub Desktop.
A view that can be embeeded into docusaurus to show an exported HTML view of your product instead of a screenshot
import React, { useState, useRef } from 'react';
import { useColorMode } from '@docusaurus/theme-common';
const DEFAULT_ZOOM = 0.75; // 75% zoom by default
interface SinglePageViewerProps {
src: string;
hint?: string;
defaultZoom?: number;
}
export default function SinglePageViewer({ src, hint, defaultZoom = DEFAULT_ZOOM }: SinglePageViewerProps) {
const { colorMode } = useColorMode();
const isDarkMode = colorMode === 'dark';
const [isFullWidth, setIsFullWidth] = useState(false);
const [zoom, setZoom] = useState(defaultZoom);
const containerRef = useRef<HTMLDivElement>(null);
const iframeWrapperRef = useRef<HTMLDivElement>(null);
const toggleFullWidth = () => {
const newFullWidth = !isFullWidth;
setIsFullWidth(newFullWidth);
if (newFullWidth) {
// Reset zoom to 100% when entering full width
setZoom(1.0);
// Use setTimeout to ensure the layout has updated before scrolling
setTimeout(() => {
containerRef.current?.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'nearest',
});
// Add a small scroll offset to ensure the frame header is visible
window.scrollBy({ top: -20, behavior: 'smooth' });
}, 100);
} else {
// Restore default zoom when exiting full width
setZoom(defaultZoom);
}
};
const openInNewWindow = () => {
window.open(src, '_blank', 'noopener,noreferrer');
};
return (
<>
{isFullWidth && (
<div
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.1)',
zIndex: 99,
pointerEvents: 'none',
}}
/>
)}
<div
ref={containerRef}
style={{
position: 'relative',
marginBottom: '1rem',
marginTop: isFullWidth ? '1rem' : '0',
width: isFullWidth ? 'calc(100vw - 2rem)' : '100%',
maxWidth: isFullWidth ? 'calc(100vw - 2rem)' : 'none',
marginLeft: isFullWidth ? 'calc(-50vw + 50% + 1rem)' : '0',
marginRight: isFullWidth ? 'calc(-50vw + 50% + 1rem)' : '0',
transition: 'all 0.3s ease',
zIndex: isFullWidth ? 100 : 'auto',
isolation: 'isolate',
boxSizing: 'border-box',
}}
>
<div
style={{
border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid rgba(0, 0, 0, 0.1)',
borderRadius: '8px',
padding: '1rem',
background: isDarkMode ? 'rgba(30, 41, 59, 0.8)' : 'rgba(255, 255, 255, 0.7)',
backdropFilter: 'blur(10px) saturate(180%)',
WebkitBackdropFilter: 'blur(10px) saturate(180%)',
boxShadow: isDarkMode
? '0 8px 32px 0 rgba(0, 0, 0, 0.5), 0 0 15px rgba(136, 97, 216, 0.12), 0 0 30px rgba(136, 97, 216, 0.06)'
: '0 8px 32px 0 rgba(31, 38, 135, 0.37), 0 0 15px rgba(136, 97, 216, 0.2), 0 0 30px rgba(136, 97, 216, 0.12)',
position: 'relative',
isolation: 'isolate',
boxSizing: 'border-box',
}}
>
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: '0.75rem',
gap: '1rem',
flexWrap: 'wrap',
}}
>
{hint && (
<div
style={{
fontSize: '0.875rem',
color: 'var(--ifm-color-content-secondary)',
display: 'flex',
alignItems: 'flex-start',
gap: '0.5rem',
marginRight: 'auto',
flex: '1 1 0',
minWidth: '200px',
}}
>
<svg
width='20'
height='32'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
xmlns='http://www.w3.org/2000/svg'
style={{ flexShrink: 0, alignSelf: 'flex-start' }}
>
<path d='M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5' />
<path d='M9 18h6' />
<path d='M10 22h4' />
</svg>
<span>{hint}</span>
</div>
)}
<div style={{ display: 'flex', gap: '0.5rem', flexShrink: 0, marginLeft: hint ? 0 : 'auto' }}>
<button
onClick={toggleFullWidth}
style={{
padding: '0.5rem 1rem',
backgroundColor: isFullWidth ? '#059669' : '#07bc85',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '0.875rem',
fontWeight: '500',
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
}}
onMouseOver={(e) => {
if (!isFullWidth) {
e.currentTarget.style.backgroundColor = '#059669';
}
}}
onMouseOut={(e) => {
if (!isFullWidth) {
e.currentTarget.style.backgroundColor = '#07bc85';
}
}}
>
<svg
width='16'
height='16'
viewBox='0 0 16 16'
fill='none'
xmlns='http://www.w3.org/2000/svg'
style={{ flexShrink: 0 }}
>
{isFullWidth ? (
<path d='M3 3h10v10H3V3zm1 1v8h8V4H4zm2 2h4v4H6V6z' fill='currentColor' />
) : (
<path d='M2 2h12v12H2V2zm1 1v10h10V3H3zm1 1h8v8H4V4z' fill='currentColor' />
)}
</svg>
{isFullWidth ? 'Exit Full Width' : 'Full Width'}
</button>
<button
onClick={openInNewWindow}
style={{
padding: '0.5rem 1rem',
backgroundColor: '#07bc85',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '0.875rem',
fontWeight: '500',
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
}}
onMouseOver={(e) => (e.currentTarget.style.backgroundColor = '#059669')}
onMouseOut={(e) => (e.currentTarget.style.backgroundColor = '#07bc85')}
>
<svg
width='16'
height='16'
viewBox='0 0 16 16'
fill='none'
xmlns='http://www.w3.org/2000/svg'
style={{ flexShrink: 0 }}
>
<path
d='M10 2h4v4M14 2l-6 6M14 6v4a2 2 0 01-2 2H4a2 2 0 01-2-2V4a2 2 0 012-2h4'
stroke='currentColor'
strokeWidth='1.5'
strokeLinecap='round'
strokeLinejoin='round'
fill='none'
/>
</svg>
Open in New Window
</button>
</div>
</div>
<div
ref={iframeWrapperRef}
style={{
overflow: 'hidden',
width: '100%',
height: isFullWidth ? `${800 * zoom}px` : `${600 * zoom}px`,
position: 'relative',
borderRadius: '4px',
border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.15)' : '1px solid rgba(0, 0, 0, 0.1)',
isolation: 'isolate',
backgroundColor: 'white',
boxShadow: isDarkMode
? 'inset 0 1px 2px 0 rgba(0, 0, 0, 0.2)'
: 'inset 0 1px 2px 0 rgba(255, 255, 255, 0.5)',
}}
>
<div
style={{
transform: `scale(${zoom})`,
transformOrigin: 'top left',
width: `${100 / zoom}%`,
height: `${(isFullWidth ? 800 : 600) / zoom}px`,
transition: 'transform 0.2s ease',
}}
>
<iframe
src={src}
style={{
width: '100%',
height: isFullWidth ? '800px' : '600px',
border: 'none',
pointerEvents: 'auto',
display: 'block',
isolation: 'isolate',
position: 'relative',
zIndex: 1,
}}
/>
</div>
</div>
</div>
</div>
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment