Skip to content

Commit

Permalink
feat: New prop to disable up/down arrow keys for changing tabs (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
maumont committed Feb 6, 2021
1 parent d6fd355 commit 40ea746
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -114,6 +114,12 @@ Provide a custom class name for disabled tabs.
> This option can also be set directly at the `<Tab />` component.
#### disableUpDownKeys: `bool`
> default: `false`
Disable up & down arrow keys to change tabs.
#### domRef: `(node: ?HTMLElement) => void`
> default: `null`
Expand Down
2 changes: 2 additions & 0 deletions src/components/Tabs.js
Expand Up @@ -18,6 +18,7 @@ export default class Tabs extends Component {
selectedIndex: null,
defaultIndex: null,
environment: null,
disableUpDownKeys: false,
};

static propTypes = {
Expand All @@ -31,6 +32,7 @@ export default class Tabs extends Component {
defaultFocus: PropTypes.bool,
defaultIndex: PropTypes.number,
disabledTabClassName: PropTypes.string,
disableUpDownKeys: PropTypes.bool,
domRef: PropTypes.func,
forceRenderTabPanel: PropTypes.bool,
onSelect: onSelectPropType,
Expand Down
12 changes: 7 additions & 5 deletions src/components/UncontrolledTabs.js
Expand Up @@ -56,6 +56,7 @@ export default class UncontrolledTabs extends Component {
PropTypes.object,
]),
disabledTabClassName: PropTypes.string,
disableUpDownKeys: PropTypes.bool,
domRef: PropTypes.func,
focus: PropTypes.bool,
forceRenderTabPanel: PropTypes.bool,
Expand Down Expand Up @@ -259,7 +260,7 @@ export default class UncontrolledTabs extends Component {
}

handleKeyDown = (e) => {
const { direction } = this.props;
const { direction, disableUpDownKeys } = this.props;
if (this.isTabFromContainer(e.target)) {
let { selectedIndex: index } = this.props;
let preventDefault = false;
Expand All @@ -271,17 +272,17 @@ export default class UncontrolledTabs extends Component {
this.handleClick(e);
}

if (e.keyCode === 37 || e.keyCode === 38) {
// Select next tab to the left
if (e.keyCode === 37 || (!disableUpDownKeys && e.keyCode === 38)) {
// Select next tab to the left, validate if up arrow is not disabled
if (direction === 'rtl') {
index = this.getNextTab(index);
} else {
index = this.getPrevTab(index);
}
preventDefault = true;
useSelectedIndex = true;
} else if (e.keyCode === 39 || e.keyCode === 40) {
// Select next tab to the right
} else if (e.keyCode === 39 || (!disableUpDownKeys && e.keyCode === 40)) {
// Select next tab to the right, validate if down arrow is not disabled
if (direction === 'rtl') {
index = this.getPrevTab(index);
} else {
Expand Down Expand Up @@ -368,6 +369,7 @@ export default class UncontrolledTabs extends Component {
selectedTabClassName, // unused
selectedTabPanelClassName, // unused
environment, // unused
disableUpDownKeys, // unused
...attributes
} = this.props;

Expand Down
39 changes: 39 additions & 0 deletions src/components/__tests__/Tabs-test.js
Expand Up @@ -502,4 +502,43 @@ describe('<Tabs />', () => {
</Tabs>,
);
});

test('should change tabs when arrow up/down is pressed', () => {
render(createTabs());
const firstTab = screen.getByTestId('tab1');
const secondTab = screen.getByTestId('tab2');

userEvent.tab();
expect(firstTab).toHaveFocus();
assertTabSelected(1);

userEvent.type(firstTab, '{arrowdown}');
expect(secondTab).toHaveFocus();
assertTabSelected(2);

userEvent.type(secondTab, '{arrowup}');
expect(firstTab).toHaveFocus();
assertTabSelected(1);
});

test('should not change tabs when arrow up/down is pressed and disableUpDownKeys is passed', () => {
render(
createTabs({
disableUpDownKeys: true,
}),
);
const firstTab = screen.getByTestId('tab1');

userEvent.tab();
expect(firstTab).toHaveFocus();
assertTabSelected(1);

userEvent.type(firstTab, '{arrowdown}');
expect(firstTab).toHaveFocus();
assertTabSelected(1);

userEvent.type(firstTab, '{arrowup}');
expect(firstTab).toHaveFocus();
assertTabSelected(1);
});
});

0 comments on commit 40ea746

Please sign in to comment.