fix(web): keep focus in modals while typing (add-artist bug)
The Modal focus-trap effect depended on [open, onClose] and called panelRef.focus() on every run. Callers that pass a fresh onClose each render (the common case, e.g. artists-client's closeAdd) re-ran the effect on every parent re-render — so typing one char into the add-artist search (setQuery → re-render → new onClose) yanked focus off the <input> back onto the panel, making the field untypable. Hold the latest onClose in a ref and depend on [open] alone, so focus-on-open runs once per open. Fixes every Modal caller, not just add-artist. Verified live via Playwright: typing "radiohead" one key at a time keeps the value and document.activeElement on the search input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,12 @@ export function Modal({
|
||||
}) {
|
||||
const panelRef = useRef<HTMLDivElement>(null);
|
||||
const lastFocus = useRef<HTMLElement | null>(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 <input> 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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user