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(Tabs): ignore disabled tabs on keyboard navigation #4784

Merged

Conversation

emyarod
Copy link
Member

@emyarod emyarod commented Nov 27, 2019

Closes #2880
Closes #1495 (our tabs are now "single tab stop")

This PR modifies the tab navigation logic to cycle through enabled tabs only rather than blindly looping through the tab list. It also resolves a performance issue when cycling through tabs

Testing / Reviewing

cycle through the tab list with the arrow keys and ensure that disabled tabs are ignored

(notice that the focus outline jump occurs at the same time as the font weight change rather than a second later)

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for the-carbon-components ready!

Built with commit 26eda89

https://deploy-preview-4784--the-carbon-components.netlify.com

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for carbon-components-react ready!

Built with commit 26eda89

https://deploy-preview-4784--carbon-components-react.netlify.com

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for carbon-elements ready!

Built with commit 26eda89

https://deploy-preview-4784--carbon-elements.netlify.com

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for the-carbon-components ready!

Built with commit f614ee6

https://deploy-preview-4784--the-carbon-components.netlify.com

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for carbon-elements failed.

Built with commit f614ee6

https://app.netlify.com/sites/carbon-elements/deploys/5e166f2407e065000939f226

@netlify
Copy link

netlify bot commented Nov 27, 2019

Deploy preview for carbon-components-react failed.

Built with commit f614ee6

https://app.netlify.com/sites/carbon-components-react/deploys/5e166f24ed5a2300099f9de5

Copy link
Contributor

@asudoh asudoh left a comment

Choose a reason for hiding this comment

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

LGTM 👍 - Thanks @emyarod!

@asudoh asudoh requested a review from a team November 27, 2019 09:38
@ghost ghost requested review from jillianhowarth and removed request for a team November 27, 2019 09:38
};

getNextIndex = (index, direction) => {
const enabledTabs = this.getEnabledTabs();
Copy link
Contributor

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.

that doesn't look like a drop-in replacement for the function I have currently

Copy link
Contributor

Choose a reason for hiding this comment

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

Just was speaking to figuring out the nextIndex and using a ring buffer instead of the current logic 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

how does it account for disabled tab indices?

Copy link
Contributor

Choose a reason for hiding this comment

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

@emyarod if I understand correctly, the ring buffer would be done on a filtered down version of tabs, correct?

const tabs = [
  {
    title: 'Tab A',
    disabled: false,
  },
  {
    title: 'Tab B',
    disabled: true,
  },
  {
    title: 'Tab B',
    disabled: false,
  },
];

const enabledTabs = tabs.filter(tab => !tab.disabled);
getNextIndex(ArrowRight, 0, enabledTabs.length); // 1
getNextIndex(ArrowRight, 1, enabledTabs.length); // 0
getNextIndex(ArrowLeft, 0, enabledTabs.length); // 1

Definitely get that it's not mapping exactly 1:1, but just was seeing if the pattern was worthwhile to match 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

the returned index from that function corresponds to the element's location in the filtered array and not the full array. but if you are just referring to the pattern then I have implemented it already, I'm just also accounting for the fact that the component is expecting the full array and not only the enabled tabs

@@ -116,6 +117,12 @@ export default class Tabs extends React.Component {
return React.Children.map(this.props.children, tab => tab);
}

getEnabledTabs = () =>
React.Children.toArray(this.props.children).reduce(
(acc, tab, index) => (!tab.props.disabled ? acc.concat(index) : acc),
Copy link
Contributor

Choose a reason for hiding this comment

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

When we're looping through children, do we ever need to do null checks? Wasn't sure about toArray but was just remembering some issues with UI Shell where this was coming up.

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

@jillianhowarth jillianhowarth left a comment

Choose a reason for hiding this comment

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

The focus area jumps a second after the font-weight change for me

@mattrosno mattrosno removed this from the ♿Carbon WCAG Compliance♿ milestone Dec 13, 2019
@emyarod emyarod force-pushed the 2880-tabs-keyboard-navigation branch from 5d62674 to 7eb4cee Compare January 6, 2020 16:07
@emyarod
Copy link
Member Author

emyarod commented Jan 6, 2020

@jillianhowarth is that the case with the full story view? https://deploy-preview-4784--carbon-components-react.netlify.com/iframe.html?id=tabs--default

seems the issue still persists with the normal story view but is likely storybook related

Copy link

@jillianhowarth jillianhowarth left a comment

Choose a reason for hiding this comment

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

@emyarod it works great with full story view. Thanks!

@asudoh asudoh dismissed joshblack’s stale review January 6, 2020 23:11

Updating the review status given visual review is complete and we revealed that one technical review comment does not account for the specific use case for tab component.

@emyarod emyarod force-pushed the 2880-tabs-keyboard-navigation branch from 07eefa2 to 6ef3515 Compare January 7, 2020 15:47
@emyarod emyarod force-pushed the 2880-tabs-keyboard-navigation branch from 6ef3515 to 2ce31ea Compare January 7, 2020 23:48
Copy link
Member

@tw15egan tw15egan left a comment

Choose a reason for hiding this comment

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

Performance fixes look good (in full view anyways, storybook still has issues). Confirmed no longer able to arrow through disabled tabs. 👍

@asudoh asudoh merged commit 83ddb6a into carbon-design-system:master Jan 9, 2020
@emyarod emyarod deleted the 2880-tabs-keyboard-navigation branch January 9, 2020 13:19
@anibapat
Copy link

This fixes the issue with the keyboard nav on the disabled tab, but now creates another problem where it is not possible to come out from the Tabs, i.e when I hit Tab (instead of arrow keys), the focus should go to the content section. Now, it is not going to content.

E.g https://codesandbox.io/s/codesandbox-86xgt

I have a button under Tab3, which should take focus on pressing Tab, which was working before the fix).

cc @joshblack @emyarod

@emyarod
Copy link
Member Author

emyarod commented Jan 21, 2020

addressed in #5124

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants