import { Alert02Icon, Globe02Icon } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; import { forwardRef, useImperativeHandle, useRef, useState } from "react"; import { PreviewAddressBar, type PreviewAddressBarHandle, } from "./PreviewAddressBar"; export type PreviewPaneHandle = { reload: () => void; focusAddressBar: () => void; getUrl: () => string; }; type Props = { url: string; visible: boolean; onUrlChange: (url: string) => void; }; export const PreviewPane = forwardRef( function PreviewPane({ url, visible, onUrlChange }, ref) { // `nonce` is part of the iframe `key`. Bumping it remounts the iframe, // which is the only reliable cross-origin reload (calling // contentWindow.location.reload() throws on cross-origin frames). const [nonce, setNonce] = useState(0); const addressRef = useRef(null); useImperativeHandle( ref, () => ({ reload: () => setNonce((n) => n + 1), focusAddressBar: () => addressRef.current?.focus(), getUrl: () => url, }), [url], ); const showXfoHint = url ? !isLocalUrl(url) : false; return (
setNonce((n) => n + 1)} /> {showXfoHint ? (
Many public sites refuse to embed (X-Frame-Options). If the page is blank, open it externally.
) : null}
{url ? (