-
Notifications
You must be signed in to change notification settings - Fork 589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overlay: only prevent focus on open when component is open #5636
Changes from all commits
fb33fed
d4253a8
8b89620
9b745ba
b386f7c
c10a157
5dc41f9
868ece3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@primer/react": patch | ||
--- | ||
|
||
Update useOpenAndCloseFocus hook to apply return focus when preventFocusOnOpen prop is given |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,18 +16,21 @@ export function useOpenAndCloseFocus({ | |
preventFocusOnOpen, | ||
}: UseOpenAndCloseFocusSettings): void { | ||
useEffect(() => { | ||
if (preventFocusOnOpen) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering what exactly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The two cases I'm aware of were both used to keep focus on the "entrypoint" element when an overlay was opened:
|
||
return | ||
} | ||
Comment on lines
-19
to
-21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These lines are the most critical change. By returning early here, we prevent the hook from ever applying focus to the given There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also worth noting -- Should this prop be documented? 🤔 On the one hand, I suspect we don't want to encourage its use. However, by not documenting it, users are more susceptible to "misusing" the prop, resulting in unexpected behavior. Maybe that's not a concern if these changes are merged, but I wanted to ask anyway since it seems worth considering. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I see! So that meant that
I think we have some pretty old and mostly hidden docs for this hook in primer.style. It doesn't really explain too much, so I think it's worth updating! Ideally, we'll need to rely on this hook even less once we utilize popover in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Cool, makes sense! Also thanks for linking to the hooks docs. I never checked outside the component docs 🤦♀️ I'll make sure There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hook docs update: primer/design#926 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. component docs updated here: 868ece3 |
||
const returnRef = returnFocusRef.current | ||
if (initialFocusRef && initialFocusRef.current) { | ||
initialFocusRef.current.focus() | ||
} else if (containerRef.current) { | ||
const firstItem = iterateFocusableElements(containerRef.current).next().value | ||
firstItem?.focus() | ||
// If focus should be applied on open, apply focus to correct element, | ||
// either the initialFocusRef if given, otherwise the first focusable element | ||
if (!preventFocusOnOpen) { | ||
if (initialFocusRef && initialFocusRef.current) { | ||
initialFocusRef.current.focus() | ||
} else if (containerRef.current) { | ||
const firstItem = iterateFocusableElements(containerRef.current).next().value | ||
firstItem?.focus() | ||
} | ||
} | ||
|
||
// If returnFocusRef element is rendered, apply focus | ||
const returnFocusRefCurrent = returnFocusRef.current | ||
return function () { | ||
returnRef?.focus() | ||
returnFocusRefCurrent?.focus() | ||
} | ||
}, [initialFocusRef, returnFocusRef, containerRef, preventFocusOnOpen]) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this story is copy/pasted from existing Overlay stories. Key changes:
preventFocusOnOpen
prop