diff --git a/web/src/app/_ui/modal.tsx b/web/src/app/_ui/modal.tsx index ae8678d..6f098ca 100644 --- a/web/src/app/_ui/modal.tsx +++ b/web/src/app/_ui/modal.tsx @@ -22,6 +22,12 @@ export function Modal({ }) { const panelRef = useRef(null); const lastFocus = useRef(null); + // Keep the latest onClose in a ref so the setup effect can depend on [open] alone. If it + // depended on onClose, a caller passing a fresh callback each render (the common case) + // would re-run the effect on every parent re-render — and panelRef.focus() below would + // yank focus off a just-typed back onto the panel (the add-artist modal bug). + const onCloseRef = useRef(onClose); + onCloseRef.current = onClose; useEffect(() => { if (!open) return; @@ -32,7 +38,7 @@ export function Modal({ function onKey(e: KeyboardEvent) { if (e.key === "Escape") { - onClose(); + onCloseRef.current(); return; } if (e.key !== "Tab") return; @@ -54,7 +60,7 @@ export function Modal({ document.body.style.overflow = prevOverflow; lastFocus.current?.focus(); }; - }, [open, onClose]); + }, [open]); if (!open || typeof document === "undefined") return null;