/** * "Download…" on a book overview: a small menu offering the book as * EPUB or PDF, served by the /{did}/{rkey}/download/{format} route. * Rendered only when the author has opted the book in * (page.cavu.book allowDownloads) — the caller decides; this component * just draws the menu. Plain anchors do the download so it works * without JS once the page is up, and closes on outside click/Escape. */ import { useEffect, useId, useRef, useState } from 'react' export function DownloadMenu({ did, rkey, title }: { did: string; rkey: string; title: string }) { const [open, setOpen] = useState(false) const rootRef = useRef(null) const menuId = useId() useEffect(() => { if (!open) return const onPointerDown = (e: PointerEvent) => { if (!rootRef.current?.contains(e.target as Node)) setOpen(false) } const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) } document.addEventListener('pointerdown', onPointerDown) document.addEventListener('keydown', onKeyDown) return () => { document.removeEventListener('pointerdown', onPointerDown) document.removeEventListener('keydown', onKeyDown) } }, [open]) const href = (format: 'epub' | 'pdf') => `/${encodeURIComponent(did)}/${encodeURIComponent(rkey)}/download/${format}` return (
{open && ( )}
) }