Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 1da91c033c738ab74538d13d
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
src/ui.tsx
// Small shared pieces: dialog sheet, menu, toast, copy and share.
import { useEffect, useRef, useState, type ReactNode } from "react";
const FOCUSABLE = "a[href], button:not([disabled]), input:not([disabled]), select, textarea, [tabindex]:not([tabindex='-1'])";
/** Keeps rendering the last content while `open` turns false, so the dialog can animate out. */
function usePresence(open: boolean, content: ReactNode) {
const last = useRef(content);
if (open) last.current = content;
const [mounted, setMounted] = useState(open);
useEffect(() => { if (open) setMounted(true); }, [open]);
return { mounted: open || mounted, leaving: !open && mounted, content: last.current, done: () => setMounted(false) };
}
/** A centered dialog on wide screens, a bottom sheet on phones. Escape, the backdrop and the close button call onClose. */
export function Modal({ open, title, onClose, children, footer }: { open: boolean; title: string; onClose: () => void; children: ReactNode; footer?: ReactNode }) {
const p = usePresence(open, <><div className="dialog-body">{children}</div>{footer && <div className="dialog-foot">{footer}</div>}</>);
const ref = useRef<HTMLDivElement>(null);
const close = useRef(onClose);
close.current = onClose;
useEffect(() => {
if (!open) return;
const prev = document.activeElement as HTMLElement | null;
const onKey = (e: KeyboardEvent) => {
if (e.key === "Escape") { e.stopPropagation(); close.current(); }
if (e.key === "Tab" && ref.current) {
const items = [...ref.current.querySelectorAll<HTMLElement>(FOCUSABLE)].filter((el) => el.offsetParent !== null);
if (!items.length) return;
const first = items[0], last = items[items.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
};
document.addEventListener("keydown", onKey, true);
document.body.style.overflow = "hidden";
// Focus the control marked data-autofocus, or the dialog itself (so phones do not open the keyboard uninvited).
(ref.current?.querySelector<HTMLElement>("[data-autofocus]") ?? ref.current)?.focus({ preventScroll: true });
return () => {
document.removeEventListener("keydown", onKey, true);
document.body.style.overflow = "";
prev?.focus({ preventScroll: true });
};
}, [open]);
if (!p.mounted) return null;
return (
<div className={`dialog-backdrop${p.leaving ? " leaving" : ""}`}
onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}
onAnimationEnd={(e) => { if (p.leaving && e.target === e.currentTarget) p.done(); }}>
<div className="dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title" ref={ref} tabIndex={-1}>
<div className="dialog-head">
<h2 className="dialog-title" id="dialog-title">{title}</h2>
<button className="btn btn-quiet btn-icon btn-sm" type="button" onClick={onClose} aria-label="Close">
<svg width="18" height="18" viewBox="0 0 20 20" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" /></svg>
</button>
</div>
{p.content}
</div>
</div>
);
}
/** A button that shows a short list of actions (a disclosure, so Tab moves through the items). The list closes after one is chosen. */
export function Menu({ label, icon, children, end = true, className = "btn btn-line" }: { label: string; icon?: boolean; children: ReactNode; end?: boolean; className?: string }) {
const [open, setOpen] = useState(false);
const [leaving, setLeaving] = useState(false);
const box = useRef<HTMLDivElement>(null);
const shut = () => { if (open) setLeaving(true); };
useEffect(() => {
if (!open) return;
const away = (e: Event) => { if (!box.current?.contains(e.target as Node)) setLeaving(true); };
const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") { setLeaving(true); box.current?.querySelector<HTMLElement>("button")?.focus(); } };
document.addEventListener("pointerdown", away);
document.addEventListener("keydown", onKey);
box.current?.querySelector<HTMLElement>(".dropdown-menu :is(a, button)")?.focus();
return () => { document.removeEventListener("pointerdown", away); document.removeEventListener("keydown", onKey); };
}, [open]);
return (
<div className="dropdown" ref={box}>
<button type="button" className={`${className}${icon ? " btn-icon" : ""}`} aria-expanded={open} aria-label={icon ? label : undefined}
onClick={() => (open ? shut() : setOpen(true))}>
{icon ? <svg width="20" height="20" viewBox="0 0 20 20" aria-hidden="true"><circle cx="4.5" cy="10" r="1.6" fill="currentColor" /><circle cx="10" cy="10" r="1.6" fill="currentColor" /><circle cx="15.5" cy="10" r="1.6" fill="currentColor" /></svg> : label}
</button>
{open && (
<div className={`dropdown-menu${end ? " dropdown-menu-end" : ""}${leaving ? " leaving" : ""}`}
onClick={(e) => { if ((e.target as HTMLElement).closest("a, button")) shut(); }}
onAnimationEnd={() => { if (leaving) { setOpen(false); setLeaving(false); } }}>
{children}
</div>
)}
</div>
);
}
let pushToast: ((text: string) => void) | null = null;
export function toast(text: string) { pushToast?.(text); }
export function Toaster() {
const [text, setText] = useState<string | null>(null);
const [leaving, setLeaving] = useState(false);
useEffect(() => {
let timer: number | undefined;
pushToast = (t) => {
setText(t);
setLeaving(false);
window.clearTimeout(timer);
timer = window.setTimeout(() => setLeaving(true), 2600);
};
return () => { pushToast = null; window.clearTimeout(timer); };
}, []);
return text ? <div className={`toast${leaving ? " leaving" : ""}`} role="status" onAnimationEnd={() => { if (leaving) { setText(null); setLeaving(false); } }}>{text}</div> : null;
}
/** Shows a notice while the browser is offline, since nothing saves until it reconnects. */
export function OfflineNotice() {
const [offline, setOffline] = useState(typeof navigator !== "undefined" && navigator.onLine === false);
useEffect(() => {
const on = () => setOffline(false);
const off = () => setOffline(true);
window.addEventListener("online", on);
window.addEventListener("offline", off);
return () => { window.removeEventListener("online", on); window.removeEventListener("offline", off); };
}, []);
return offline ? <p className="offline enter" role="status">You are offline. Nothing saves until you reconnect.</p> : null;
}
export async function copy(text: string, done = "Copied") {
try {
await navigator.clipboard.writeText(text);
toast(done);
} catch {
window.prompt("Copy this:", text);
}
}
/** The phone's share sheet where there is one (pick Messages, WhatsApp, Mail...). */
export const canShare = () => typeof navigator !== "undefined" && typeof navigator.share === "function" && matchMedia("(pointer: coarse)").matches;
export async function share(url: string, title: string, text?: string) {
if (canShare()) {
try { await navigator.share({ title, text, url }); return; } catch { return; /* cancelled */ }
}
await copy(url, "Link copied");
}
Change history
Quality pass: phone signing, edit signers, copy to send again
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync