Initial QuestionGraph library and documentation

This commit is contained in:
Peter Stockings
2026-09-13 12:59:36 +10:00
commit 0879a3e786
48 changed files with 7712 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
import { useEffect, useRef, type ReactNode } from "react";
import { createPortal } from "react-dom";
export function InspectorModal({ title, onClose, children }: { title: string; onClose: () => void; children: ReactNode }) {
const dialogRef = useRef<HTMLDialogElement>(null);
useEffect(() => {
const dialog = dialogRef.current!;
const opener = document.activeElement instanceof HTMLElement ? document.activeElement : null;
const overflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
dialog.showModal();
return () => {
dialog.close();
document.body.style.overflow = overflow;
opener?.focus({ preventScroll: true });
};
}, []);
return createPortal(
<dialog ref={dialogRef} className="inspector-modal" aria-labelledby="inspector-modal-title"
onCancel={event => { event.preventDefault(); onClose(); }}
onClick={event => {
if (event.target !== event.currentTarget) return;
const rect = event.currentTarget.getBoundingClientRect();
if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) onClose();
}}>
<header className="inspector-modal-header">
<div><p className="eyebrow">Questionnaire inspector</p><h2 id="inspector-modal-title">{title}</h2></div>
<button type="button" className="secondary" onClick={onClose} autoFocus aria-label="Close expanded inspector">Close <span aria-hidden="true">×</span></button>
</header>
<div className={`inspector-modal-content${title === "JSON" ? " inspector-modal-json" : ""}`}>{children}</div>
</dialog>, document.body
);
}