Skip to content
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

fix: add trapFocus to RadioButtonGroup #7044

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Conversation

ShimiSun
Copy link
Member

@ShimiSun ShimiSun commented Dec 1, 2023

What does this PR do?

This PR is enhancing RadioButtonGroup with a new prop trapFocus.
The trapFocus prop allows the user to set focus inside the RadioButtonGroup and on the first element.
The current behavior, w/o trapFocus, is that the component assigns a given ref to RadioButtonGroup which is a Box; the Box doesn't process the focus and the focus is lost. The keyboard focus works as expected, the ref focus doesn't.

The use case this fix will solve for our team is when the RadioButtonGroup is inside of a form, and we apply a logic that focuses on an input field that has an error upon submission, the RBG doesn't accept the focus. We send the ref of the RadioButtonGroup via form hook; this mostly works well for Grommet components that we use, aside of RGB which doesn't capture the focus.

The goal is to be able to focus on RGB, but since RGB is a Box, and the Box shouldn't be focusable, we expect to be focusing on the first RB element; a similar behavior to how the keyboard navigation works when tabbing between form elements and the first RB within a RBG gets the focus upon entering the component with Tab.

I am not locked on this solution, and I'm very much open to other proposals or workarounds that will help my team solve the problem and move forward. I used the trapFocus approach to somewhat be consistent with the Drop component that uses this prop as well. Please let me know what other type of info you might be needing to understand and agree on a solution for this issue.

Where should the reviewer start?

RBG

What testing has been done on this PR?

Storybook - but it is not completed yet, I'd like to get feedback on the approach if possible

How should this be manually tested?

Do Jest tests follow these best practices?

  • screen is used for querying.
  • The correct query is used. (Refer to this list of queries)
  • asFragment() is used for snapshot testing.

Any background context you want to provide?

What are the relevant issues?

Screenshots (if appropriate)

Do the grommet docs need to be updated?

Yes, new prop

Should this PR be mentioned in the release notes?

Yes

Is this change backwards compatible or is it a breaking change?

b/c

@ShimiSun ShimiSun marked this pull request as draft December 1, 2023 08:25
@ShimiSun ShimiSun added the accessibility WCAG support label Dec 1, 2023
@ShimiSun ShimiSun changed the title fix: add an alternative to trap the focus in RadioButtonGroup fix: add trapFocus to RadioButtonGroup Dec 1, 2023
setFocus(true);
// In case the focus needs to be trapped inside the input instead of the
// Box wrapper
if (trapFocus) {
Copy link
Collaborator

@taysea taysea Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Shimi! Thanks for the proposal. I understand the use case, but I'm trying to think of a better way to handle it. A couple reactions:

  • The reuse of trapFocus as a prop name doesn't quite feel applicable here because in the case of Drop/Layer, trapFocus indicates that something should behave like a modal and not allow tab stops to continue to anywhere else on the page. That is a bit different from the intent here to place the focus on an individual radiobutton.
  • setFocus in the code is just a boolean to track if focus is set. I'm not following why we would set it to something other than a boolean here. Also, if I try to use arrows to navigate amongst the options in your storybook example, I can't. I would expect to be able to use keyboard to navigate.

I don't have a suggestion at the moment for a better path, but just wanted to drop my reactions and let you know that I'm thinking on it.

Copy link
Member Author

@ShimiSun ShimiSun Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback @taysea, appreciate your time and thoughts on this.
I agree it is not trivial. I sent the initial proposal to get the convo started so I appreciate you chiming in.

Here are some follow-up thoughts.

  • I had a similar thought after filing the PR regarding the name of the prop. A name like 'setFirstInputFocus', 'defaultFocusToFirst', 'focusFirstInGroup' might be more self-explanatory - let me know if you like any of those, or whether we should branch off one of them.
  • Yes I know, I'll need to work on it further, this is why the PR is still in Draft. I was seeking initial thoughts from the team before I continued to invest in the solution.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, I'm wondering if a potential workaround you team could use is before setting the focus on input.current check if role="radiogroup". If so instead of focusing input.current do something like this:

const inputEl = input.current?.querySelectorAll('input[type=radio]')[0];
inputEl.focus();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility WCAG support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants