Skip to content

Commit 40ea746

Browse files
authored
feat: New prop to disable up/down arrow keys for changing tabs (#368)
1 parent d6fd355 commit 40ea746

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ Provide a custom class name for disabled tabs.
114114
115115
> This option can also be set directly at the `<Tab />` component.
116116
117+
#### disableUpDownKeys: `bool`
118+
119+
> default: `false`
120+
121+
Disable up & down arrow keys to change tabs.
122+
117123
#### domRef: `(node: ?HTMLElement) => void`
118124
119125
> default: `null`

src/components/Tabs.js

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default class Tabs extends Component {
1818
selectedIndex: null,
1919
defaultIndex: null,
2020
environment: null,
21+
disableUpDownKeys: false,
2122
};
2223

2324
static propTypes = {
@@ -31,6 +32,7 @@ export default class Tabs extends Component {
3132
defaultFocus: PropTypes.bool,
3233
defaultIndex: PropTypes.number,
3334
disabledTabClassName: PropTypes.string,
35+
disableUpDownKeys: PropTypes.bool,
3436
domRef: PropTypes.func,
3537
forceRenderTabPanel: PropTypes.bool,
3638
onSelect: onSelectPropType,

src/components/UncontrolledTabs.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default class UncontrolledTabs extends Component {
5656
PropTypes.object,
5757
]),
5858
disabledTabClassName: PropTypes.string,
59+
disableUpDownKeys: PropTypes.bool,
5960
domRef: PropTypes.func,
6061
focus: PropTypes.bool,
6162
forceRenderTabPanel: PropTypes.bool,
@@ -259,7 +260,7 @@ export default class UncontrolledTabs extends Component {
259260
}
260261

261262
handleKeyDown = (e) => {
262-
const { direction } = this.props;
263+
const { direction, disableUpDownKeys } = this.props;
263264
if (this.isTabFromContainer(e.target)) {
264265
let { selectedIndex: index } = this.props;
265266
let preventDefault = false;
@@ -271,17 +272,17 @@ export default class UncontrolledTabs extends Component {
271272
this.handleClick(e);
272273
}
273274

274-
if (e.keyCode === 37 || e.keyCode === 38) {
275-
// Select next tab to the left
275+
if (e.keyCode === 37 || (!disableUpDownKeys && e.keyCode === 38)) {
276+
// Select next tab to the left, validate if up arrow is not disabled
276277
if (direction === 'rtl') {
277278
index = this.getNextTab(index);
278279
} else {
279280
index = this.getPrevTab(index);
280281
}
281282
preventDefault = true;
282283
useSelectedIndex = true;
283-
} else if (e.keyCode === 39 || e.keyCode === 40) {
284-
// Select next tab to the right
284+
} else if (e.keyCode === 39 || (!disableUpDownKeys && e.keyCode === 40)) {
285+
// Select next tab to the right, validate if down arrow is not disabled
285286
if (direction === 'rtl') {
286287
index = this.getPrevTab(index);
287288
} else {
@@ -368,6 +369,7 @@ export default class UncontrolledTabs extends Component {
368369
selectedTabClassName, // unused
369370
selectedTabPanelClassName, // unused
370371
environment, // unused
372+
disableUpDownKeys, // unused
371373
...attributes
372374
} = this.props;
373375

src/components/__tests__/Tabs-test.js

+39
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,43 @@ describe('<Tabs />', () => {
502502
</Tabs>,
503503
);
504504
});
505+
506+
test('should change tabs when arrow up/down is pressed', () => {
507+
render(createTabs());
508+
const firstTab = screen.getByTestId('tab1');
509+
const secondTab = screen.getByTestId('tab2');
510+
511+
userEvent.tab();
512+
expect(firstTab).toHaveFocus();
513+
assertTabSelected(1);
514+
515+
userEvent.type(firstTab, '{arrowdown}');
516+
expect(secondTab).toHaveFocus();
517+
assertTabSelected(2);
518+
519+
userEvent.type(secondTab, '{arrowup}');
520+
expect(firstTab).toHaveFocus();
521+
assertTabSelected(1);
522+
});
523+
524+
test('should not change tabs when arrow up/down is pressed and disableUpDownKeys is passed', () => {
525+
render(
526+
createTabs({
527+
disableUpDownKeys: true,
528+
}),
529+
);
530+
const firstTab = screen.getByTestId('tab1');
531+
532+
userEvent.tab();
533+
expect(firstTab).toHaveFocus();
534+
assertTabSelected(1);
535+
536+
userEvent.type(firstTab, '{arrowdown}');
537+
expect(firstTab).toHaveFocus();
538+
assertTabSelected(1);
539+
540+
userEvent.type(firstTab, '{arrowup}');
541+
expect(firstTab).toHaveFocus();
542+
assertTabSelected(1);
543+
});
505544
});

0 commit comments

Comments
 (0)