diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index 15ffd90d0..c1e5f25a2 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -88,13 +88,16 @@ const MarkdownSource = (props: any) => { return null; }; -const MarkdownImg = (props: any) => { +const MarkdownImg = ({ + props, + resolveOpts, +}: { + props: React.ImgHTMLAttributes; + resolveOpts: MarkdownResolveOpts; +}) => { const [resolvedSrc, setResolvedSrc] = useState(props.src); const [resolvedStr, setResolvedStr] = useState(null); const [resolving, setResolving] = useState(true); - const resolveOpts: MarkdownResolveOpts = props.resolveOpts; - const propsScrubbed = { ...props }; - delete propsScrubbed.resolveOpts; useEffect(() => { if (props.src.startsWith("http://") || props.src.startsWith("https://")) { @@ -138,7 +141,7 @@ const MarkdownImg = (props: any) => { return {resolvedStr}; } if (resolvedSrc != null) { - return ; + return ; } return [img]; }; @@ -158,14 +161,19 @@ const Markdown = ({ text, textAtom, showTocAtom, style, className, resolveOpts, const tocRef = useRef([]); const showToc = useAtomValueSafe(showTocAtom) ?? false; const contentsOsRef = useRef(null); + const [focusedHeading, setFocusedHeading] = useState(null); // Ensure uniqueness of ids between MD preview instances. const [idPrefix] = useState(crypto.randomUUID()); const onTocClick = useCallback((href: string) => { - if (contentsOsRef.current && contentsOsRef.current.osInstance()) { + setFocusedHeading(href); + }, []); + + useEffect(() => { + if (focusedHeading && contentsOsRef.current && contentsOsRef.current.osInstance()) { const { viewport } = contentsOsRef.current.osInstance().elements(); - const heading = document.getElementById(idPrefix + href.slice(1)); + const heading = document.getElementById(idPrefix + focusedHeading.slice(1)); if (heading) { const headingBoundingRect = heading.getBoundingClientRect(); const viewportBoundingRect = viewport.getBoundingClientRect(); @@ -173,20 +181,34 @@ const Markdown = ({ text, textAtom, showTocAtom, style, className, resolveOpts, viewport.scrollBy({ top: headingTop }); } } - }, []); + }, [focusedHeading]); const markdownComponents = { a: Link, - h1: (props: any) => , - h2: (props: any) => , - h3: (props: any) => , - h4: (props: any) => , - h5: (props: any) => , - h6: (props: any) => , - img: (props: any) => , - source: (props: any) => , + h1: (props: React.HTMLAttributes) => ( + + ), + h2: (props: React.HTMLAttributes) => ( + + ), + h3: (props: React.HTMLAttributes) => ( + + ), + h4: (props: React.HTMLAttributes) => ( + + ), + h5: (props: React.HTMLAttributes) => ( + + ), + h6: (props: React.HTMLAttributes) => ( + + ), + img: (props: React.HTMLAttributes) => , + source: (props: React.HTMLAttributes) => , code: Code, - pre: (props: any) => , + pre: (props: React.HTMLAttributes) => ( + + ), }; const toc = useMemo(() => {