auto height for html preview

This commit is contained in:
lloydzhou 2024-07-23 17:44:15 +08:00
parent dfd089132d
commit 4199e17da0
1 changed files with 37 additions and 9 deletions

View File

@ -13,6 +13,7 @@ import LoadingIcon from "../icons/three-dots.svg";
import React from "react"; import React from "react";
import { useDebouncedCallback } from "use-debounce"; import { useDebouncedCallback } from "use-debounce";
import { showImageModal } from "./ui-lib"; import { showImageModal } from "./ui-lib";
import { nanoid } from "nanoid";
export function Mermaid(props: { code: string }) { export function Mermaid(props: { code: string }) {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
@ -62,6 +63,31 @@ export function Mermaid(props: { code: string }) {
export function HTMLPreview(props: { code: string }) { export function HTMLPreview(props: { code: string }) {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const frameId = useRef<string>(nanoid());
const [height, setHeight] = useState(600);
/*
* https://stackoverflow.com/questions/19739001/what-is-the-difference-between-srcdoc-and-src-datatext-html-in-an
* 1. using srcdoc
* 2. using src with dataurl:
* easy to share
* length limit (Data URIs cannot be larger than 32,768 characters.)
*/
useEffect(() => {
window.addEventListener("message", (e) => {
const { id, height } = e.data;
if (id == frameId.current) {
console.log("setHeight", height);
if (height < 600) {
setHeight(height + 40);
}
}
});
}, []);
const script = encodeURIComponent(
`<script>new ResizeObserver((entries) => parent.postMessage({id: '${frameId.current}', height: entries[0].target.clientHeight}, '*')).observe(document.body)</script>`,
);
return ( return (
<div <div
@ -70,14 +96,16 @@ export function HTMLPreview(props: { code: string }) {
cursor: "pointer", cursor: "pointer",
overflow: "auto", overflow: "auto",
}} }}
ref={ref} onClick={(e) => e.stopPropapation()}
onClick={() => console.log("click")}
> >
<iframe <iframe
id={frameId}
ref={ref}
frameBorder={0} frameBorder={0}
sandbox="allow-scripts" sandbox="allow-forms allow-modals allow-scripts"
style={{ width: "100%", height: 400 }} style={{ width: "100%", height }}
srcDoc={props.code} src={`data:text/html,${encodeURIComponent(props.code)}${script}`}
// srcDoc={props.code + script}
></iframe> ></iframe>
</div> </div>
); );
@ -108,10 +136,6 @@ export function PreCode(props: { children: any }) {
return ( return (
<> <>
{mermaidCode.length > 0 && (
<Mermaid code={mermaidCode} key={mermaidCode} />
)}
{htmlCode.length > 0 && <HTMLPreview code={htmlCode} key={htmlCode} />}
<pre ref={ref}> <pre ref={ref}>
<span <span
className="copy-code-button" className="copy-code-button"
@ -124,6 +148,10 @@ export function PreCode(props: { children: any }) {
></span> ></span>
{props.children} {props.children}
</pre> </pre>
{mermaidCode.length > 0 && (
<Mermaid code={mermaidCode} key={mermaidCode} />
)}
{htmlCode.length > 0 && <HTMLPreview code={htmlCode} key={htmlCode} />}
</> </>
); );
} }