Skip to content

ChoiceGroup: Set data-is-focusable attribute so that FocusTrapZone can detect focusable elements#5842

Merged
JasonGore merged 7 commits intomicrosoft:masterfrom
JasonGore:jg/5160-fix-choicegroup-in-ftz
Aug 8, 2018
Merged

ChoiceGroup: Set data-is-focusable attribute so that FocusTrapZone can detect focusable elements#5842
JasonGore merged 7 commits intomicrosoft:masterfrom
JasonGore:jg/5160-fix-choicegroup-in-ftz

Conversation

@JasonGore
Copy link
Member

@JasonGore JasonGore commented Aug 7, 2018

Pull request checklist

Description of changes

#5160 is caused by FocusTrapZone's inability to properly identify the last focusable element in a ChoiceGroup. Tabbing from any ChoiceGroupOption except the last would cause a break out of FocusTrapZone.

The fix is to set data-is-focusable attribute on ChoiceGroupOptions to allow FocusTrapZone to properly detect focusable elements.

Adding data-is-focusable introduces some edge case scenarios where we need to ensure that ChoiceGroup is still focusable. For example, data-is-focusable needs to be set on the first non-disabled element when no options are checked. If you can think of any other possible regressions caused by introducing data-is-focusable to ChoiceGroup, please let me know.

Focus areas to test

Add tests to ensure data-is-focusable is set properly based on checked and disabled states.

Microsoft Reviewers: Open in CodeFlow

Copy link
Contributor

@natalieethell natalieethell left a comment

Choose a reason for hiding this comment

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

These changes look good to me, given that tabIndex is already an attribute on radio buttons in the following W3C standards example: https://www.w3.org/TR/wai-aria-practices/examples/radio/radio-1/radio-1.html. I would like someone else to look over this, though, in case I'm missing something.

@JasonGore
Copy link
Member Author

JasonGore commented Aug 8, 2018

Yep! I based this on a similar ARIA example. I think this is good for accessibility as well as fixing the bug.


// In cases where no option is checked, set tab index to first enabled option so that ChoiceGroup remains tabbable.
// If no options are enabled, ChoiceGroup is not tabbable. If any option is checked, do not set keyDefaultTab.
const firstEnabledOption = disabled || options === undefined ? undefined : options.find(option => !option.disabled);
Copy link
Member

Choose a reason for hiding this comment

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

I think you should avoid tabIndex here. Let me try to understand the issue a little better, but I think in general tabIndex=0 should not be required to make an input element focusable.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I can pretty easily try data-is-focusable here and see if FTZ recognizes it since it's almost a 1:1 substitution. If you know of any other methods, let me know.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

I tested data-is-focusable and it works! I've switched the approach.

@JasonGore JasonGore changed the title ChoiceGroup: Set tabIndex so that FocusTrapZone can detect tabbable elements ChoiceGroup: Set data-is-focusable attribute so that FocusTrapZone can detect focusable elements Aug 8, 2018
)}
<div className={classNames.flexContainer}>
{options!.map((option: IChoiceGroupOption) => {
const innerOptionProps: IChoiceGroupOptionProps = {
Copy link
Member Author

Choose a reason for hiding this comment

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

Is there any way to keep this typing without getting an error when using data-is-focusable attribute? Every usage I can find in OUFR has no typing.

Copy link
Contributor

@jspurlin jspurlin left a comment

Choose a reason for hiding this comment

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

Why are we using just data-is-focusable and not additionally setting the tabIndex?

@JasonGore
Copy link
Member Author

Per David's PR comments that we shouldn't use tabIndex simply to make an element focusable.

@jspurlin
Copy link
Contributor

jspurlin commented Aug 8, 2018

I'm suggesting we do both use the data attribute AND set the tabIndex

@JasonGore
Copy link
Member Author

I know what you are suggesting, but David is wary of adding tabIndex. I'm hoping you two can agree on the approach.

@JasonGore JasonGore merged commit e675d58 into microsoft:master Aug 8, 2018
@jspurlin
Copy link
Contributor

jspurlin commented Aug 8, 2018

considering that the W3C example does that and we do that with other components (like FocusZone) it doesn't seem unreasonable to do it as well and be consistent... Although if there's a ChoiceGroup in a FocusZone there may be some tabIndex inconsistencies, maybe the ChoiceGroup could be wrapped in a FocusZone to isolate it

@JasonGore
Copy link
Member Author

The example does it, but after looking at the ARIA role definition there is no requirement to manipulate tabIndex for accessibility reasons.

@jspurlin
Copy link
Contributor

jspurlin commented Aug 8, 2018

true, but it's listed as a way to manager focus within components: https://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex (and we already use this concept in FocusZone)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ChoiceGroup: focus is wrong when using ChoiceGroup inside of Panel

5 participants