73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useRef } from 'react';
|
|
|
|
interface ResponsiveIframeProps {
|
|
src: string;
|
|
className?: string;
|
|
allow?: string;
|
|
}
|
|
|
|
export function ResponsiveIframe({ src, className = '', allow }: ResponsiveIframeProps) {
|
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
|
|
useEffect(() => {
|
|
const iframe = iframeRef.current;
|
|
if (!iframe) return;
|
|
|
|
const calculateHeight = () => {
|
|
const pageY = (elem: HTMLElement): number => {
|
|
return elem.offsetParent ?
|
|
(elem.offsetTop + pageY(elem.offsetParent as HTMLElement)) :
|
|
elem.offsetTop;
|
|
};
|
|
|
|
const height = document.documentElement.clientHeight;
|
|
const iframeY = pageY(iframe);
|
|
const newHeight = Math.max(0, height - iframeY);
|
|
iframe.style.height = `${newHeight}px`;
|
|
};
|
|
|
|
const handleHashChange = () => {
|
|
if (window.location.hash && window.location.hash.length) {
|
|
const iframeURL = new URL(iframe.src);
|
|
iframeURL.hash = window.location.hash;
|
|
iframe.src = iframeURL.toString();
|
|
}
|
|
};
|
|
|
|
// Initial setup
|
|
calculateHeight();
|
|
handleHashChange();
|
|
|
|
// Event listeners
|
|
window.addEventListener('resize', calculateHeight);
|
|
window.addEventListener('hashchange', handleHashChange);
|
|
iframe.addEventListener('load', calculateHeight);
|
|
|
|
// Cleanup
|
|
return () => {
|
|
window.removeEventListener('resize', calculateHeight);
|
|
window.removeEventListener('hashchange', handleHashChange);
|
|
iframe.removeEventListener('load', calculateHeight);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<iframe
|
|
ref={iframeRef}
|
|
id="myFrame"
|
|
src={src}
|
|
className={`w-full border-none ${className}`}
|
|
style={{
|
|
display: 'block',
|
|
width: '100%',
|
|
height: '100%',
|
|
marginTop: '-48px',
|
|
position: 'relative'
|
|
}}
|
|
allow={allow}
|
|
allowFullScreen
|
|
/>
|
|
);
|
|
}
|