fix(sw): focus anchored SWPopup / property panel when it opens
With anchorRef the frame renders visibility:hidden until useSWHeaderOverlay places it, and the focus effect ran in that same commit, so focus() on the hidden element was ignored. Focus now runs once the frame is placed; the previous element is still captured first, so Escape / close return focus. Align the SWPopup autoFocus default doc (true with anchorRef) and catalog. (cherry picked from commit 65bc0dbd5df059ead06f10a3f95f2bd2734fbf2f)
This commit is contained in:
1 parent
b7227ee963
commit
b434f272e2
3 files changed
+7
-3
No files matched your search
@@ -327,13 +327,17 @@ export function SWPopupFrame({
|
||||
if (!focus) return
|
||||
const panel = panelRef.current
|
||||
const previous = document.activeElement as HTMLElement | null
|
||||
panel?.focus()
|
||||
return () => {
|
||||
// Closing with focus still inside (e.g. Escape on a field) returns it to where it came from.
|
||||
const active = document.activeElement
|
||||
if (panel && (active === document.body || active === null || panel.contains(active)) && previous?.isConnected) previous.focus()
|
||||
}
|
||||
}, [focus, panelRef])
|
||||
// An anchored frame stays hidden until it is placed, and a hidden element cannot take focus.
|
||||
const placed = style.visibility !== "hidden"
|
||||
useLayoutEffect(() => {
|
||||
if (focus && placed) panelRef.current?.focus()
|
||||
}, [focus, placed, panelRef])
|
||||
return (
|
||||
<div ref={panelRef} id={id} tabIndex={-1} className={`hm-sw-property${className ? ` ${className}` : ""}`} data-selection-kind={kind} role="dialog" aria-modal="false" aria-labelledby={titleId}
|
||||
style={{ ...style, ...customStyle }} {...rest}
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface SWPopupProps extends Omit<HTMLAttributes<HTMLDivElement>, "titl
|
||||
* the project's own elements. Nothing is restricted; the frame keeps the SW design whatever is inside.
|
||||
*/
|
||||
children?: ReactNode
|
||||
/** Focus the popup when it opens (and return focus when it closes from inside). Default false. */
|
||||
/** Focus the popup when it opens (and return focus when it closes from inside). Default: true with `anchorRef`, false without. */
|
||||
autoFocus?: boolean
|
||||
/** Anchor element: the popup is fixed below it and kept inside the viewport (as SWHeader does). */
|
||||
anchorRef?: RefObject<HTMLElement | null>
|
||||
|
||||
Reference in new issue
Block a user