@@ -109,11 +109,16 @@ export function useSWHeaderDropdown({ open: openProp, onOpenChange, disabled = f
/** Focusable entries of the panel in DOM order (rows, inputs, footer). */ /** Focusable entries of the panel in DOM order (rows, inputs, footer). */
const entries = () => Array.from(panelRef.current?.querySelectorAll<HTMLElement>("button:not(:disabled), input:not(:disabled)") ?? []) const entries = () => Array.from(panelRef.current?.querySelectorAll<HTMLElement>("button:not(:disabled), input:not(:disabled)") ?? [])
// ArrowDown on the closed trigger asks for the entry focus. A fixed overlay (property window, SW popup) stays
// visibility: hidden until its position is measured, and focus() on it is a no-op: the request stays pending and is
// retried on the render that shows the list (the position update), then cleared once focus moved; closing drops it.
useEffect(() => { useEffect(() => {
if (open && focusEntryRef.current) { if (!open) { focusEntryRef.current = false; return }
focusEntryRef.current = false if (focusEntryRef.current) {
const current = panelRef.current?.querySelector<HTMLElement>('[aria-current="true"]:not(:disabled), [aria-pressed="true"]:not(:disabled)') const current = panelRef.current?.querySelector<HTMLElement>('[aria-current="true"]:not(:disabled), [aria-pressed="true"]:not(:disabled)')
;(current ?? entries()[0])?.focus() const target = current ?? entries()[0]
target?.focus()
if (!target || document.activeElement === target) focusEntryRef.current = false
} }
}) })