Skip to content

Commit 4199e17

Browse files
committed
auto height for html preview
1 parent dfd0891 commit 4199e17

1 file changed

Lines changed: 37 additions & 9 deletions

File tree

app/components/markdown.tsx

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import LoadingIcon from "../icons/three-dots.svg";
1313
import React from "react";
1414
import { useDebouncedCallback } from "use-debounce";
1515
import { showImageModal } from "./ui-lib";
16+
import { nanoid } from "nanoid";
1617

1718
export function Mermaid(props: { code: string }) {
1819
const ref = useRef<HTMLDivElement>(null);
@@ -62,6 +63,31 @@ export function Mermaid(props: { code: string }) {
6263

6364
export function HTMLPreview(props: { code: string }) {
6465
const ref = useRef<HTMLDivElement>(null);
66+
const frameId = useRef<string>(nanoid());
67+
const [height, setHeight] = useState(600);
68+
/*
69+
* https://stackoverflow.com/questions/19739001/what-is-the-difference-between-srcdoc-and-src-datatext-html-in-an
70+
* 1. using srcdoc
71+
* 2. using src with dataurl:
72+
* easy to share
73+
* length limit (Data URIs cannot be larger than 32,768 characters.)
74+
*/
75+
76+
useEffect(() => {
77+
window.addEventListener("message", (e) => {
78+
const { id, height } = e.data;
79+
if (id == frameId.current) {
80+
console.log("setHeight", height);
81+
if (height < 600) {
82+
setHeight(height + 40);
83+
}
84+
}
85+
});
86+
}, []);
87+
88+
const script = encodeURIComponent(
89+
`<script>new ResizeObserver((entries) => parent.postMessage({id: '${frameId.current}', height: entries[0].target.clientHeight}, '*')).observe(document.body)</script>`,
90+
);
6591

6692
return (
6793
<div
@@ -70,14 +96,16 @@ export function HTMLPreview(props: { code: string }) {
7096
cursor: "pointer",
7197
overflow: "auto",
7298
}}
73-
ref={ref}
74-
onClick={() => console.log("click")}
99+
onClick={(e) => e.stopPropapation()}
75100
>
76101
<iframe
102+
id={frameId}
103+
ref={ref}
77104
frameBorder={0}
78-
sandbox="allow-scripts"
79-
style={{ width: "100%", height: 400 }}
80-
srcDoc={props.code}
105+
sandbox="allow-forms allow-modals allow-scripts"
106+
style={{ width: "100%", height }}
107+
src={`data:text/html,${encodeURIComponent(props.code)}${script}`}
108+
// srcDoc={props.code + script}
81109
></iframe>
82110
</div>
83111
);
@@ -108,10 +136,6 @@ export function PreCode(props: { children: any }) {
108136

109137
return (
110138
<>
111-
{mermaidCode.length > 0 && (
112-
<Mermaid code={mermaidCode} key={mermaidCode} />
113-
)}
114-
{htmlCode.length > 0 && <HTMLPreview code={htmlCode} key={htmlCode} />}
115139
<pre ref={ref}>
116140
<span
117141
className="copy-code-button"
@@ -124,6 +148,10 @@ export function PreCode(props: { children: any }) {
124148
></span>
125149
{props.children}
126150
</pre>
151+
{mermaidCode.length > 0 && (
152+
<Mermaid code={mermaidCode} key={mermaidCode} />
153+
)}
154+
{htmlCode.length > 0 && <HTMLPreview code={htmlCode} key={htmlCode} />}
127155
</>
128156
);
129157
}

0 commit comments

Comments
 (0)