Build and publish Eldorado documentation / build (pull_request) Successful in 30s
29 lines
1.8 KiB
TypeScript
29 lines
1.8 KiB
TypeScript
import React, {useEffect, useId, useRef, useState} from 'react';
|
||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||
|
||
export default function ArchifyDiagram({name, title}: {name: string; title: string}): React.ReactElement {
|
||
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) throw new Error('Invalid diagram name');
|
||
const source = useBaseUrl(`/diagrams/${name}/`);
|
||
const json = useBaseUrl(`/diagrams/${name}.json`);
|
||
const dialog = useRef<HTMLDialogElement>(null);
|
||
const opener = useRef<HTMLButtonElement>(null);
|
||
const headingId = useId();
|
||
const [expanded, setExpanded] = useState(false);
|
||
useEffect(() => {
|
||
if (!expanded) return;
|
||
dialog.current?.showModal();
|
||
const previousOverflow = document.body.style.overflow;
|
||
document.body.style.overflow = 'hidden';
|
||
return () => {document.body.style.overflow = previousOverflow;};
|
||
}, [expanded]);
|
||
const close = () => {dialog.current?.close();};
|
||
return <section className="archify-panel" aria-label={title}>
|
||
<div className="archify-toolbar"><strong>Interactive diagram</strong><div><button ref={opener} type="button" className="archify-expand" onClick={() => setExpanded(true)}>Open full viewer ⛶</button><a href={json} download>JSON source ↓</a></div></div>
|
||
<iframe src={source} title={title} sandbox="allow-scripts allow-downloads" loading="lazy" referrerPolicy="no-referrer" />
|
||
<dialog ref={dialog} className="archify-modal" aria-labelledby={headingId} onClose={() => {setExpanded(false); opener.current?.focus();}}>
|
||
<div className="archify-modal-toolbar"><strong id={headingId}>{title}</strong><button type="button" onClick={close} autoFocus aria-label="Close full-screen diagram">Close ×</button></div>
|
||
{expanded && <iframe src={source} title={`${title} — expanded`} sandbox="allow-scripts allow-downloads" referrerPolicy="no-referrer" />}
|
||
</dialog>
|
||
</section>;
|
||
}
|