diff --git a/index.d.ts b/index.d.ts index 43c2618205..cf7af97c66 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,6 +8,7 @@ export interface TabsProps direction?: 'rtl' | 'ltr' | undefined; disabledTabClassName?: string | undefined; disableUpDownKeys?: boolean | undefined; + disableLeftRightKeys?: boolean | undefined; domRef?: ((node?: HTMLElement) => void) | undefined; environment?: Window | undefined; focusTabOnClick?: boolean | undefined; diff --git a/src/components/Tabs.js b/src/components/Tabs.js index 3fcb038def..df731d2cbf 100644 --- a/src/components/Tabs.js +++ b/src/components/Tabs.js @@ -22,6 +22,7 @@ const propTypes = { direction: PropTypes.oneOf(['rtl', 'ltr']), disabledTabClassName: PropTypes.string, disableUpDownKeys: PropTypes.bool, + disableLeftRightKeys: PropTypes.bool, domRef: PropTypes.func, environment: PropTypes.object, focusTabOnClick: PropTypes.bool, @@ -39,6 +40,7 @@ const defaultProps = { defaultIndex: null, environment: null, disableUpDownKeys: false, + disableLeftRightKeys: false, }; const getModeFromProps = (props) => { diff --git a/src/components/UncontrolledTabs.js b/src/components/UncontrolledTabs.js index c90e3e6bd8..525230f867 100644 --- a/src/components/UncontrolledTabs.js +++ b/src/components/UncontrolledTabs.js @@ -57,6 +57,7 @@ const propTypes = { ]), disabledTabClassName: PropTypes.string, disableUpDownKeys: PropTypes.bool, + disableLeftRightKeys: PropTypes.bool, domRef: PropTypes.func, focus: PropTypes.bool, forceRenderTabPanel: PropTypes.bool, @@ -256,7 +257,7 @@ const UncontrolledTabs = (props) => { } function handleKeyDown(e) { - const { direction, disableUpDownKeys } = props; + const { direction, disableUpDownKeys, disableLeftRightKeys } = props; if (isTabFromContainer(e.target)) { let { selectedIndex: index } = props; let preventDefault = false; @@ -276,8 +277,8 @@ const UncontrolledTabs = (props) => { // keyCode is deprecated and only used here for IE if ( - e.code === 'ArrowLeft' || - e.keyCode === 37 /* arrow left */ || + (!disableLeftRightKeys && + (e.keyCode === 37 || e.code === 'ArrowLeft')) /* arrow left */ || (!disableUpDownKeys && (e.keyCode === 38 || e.code === 'ArrowUp')) /* arrow up */ ) { @@ -290,8 +291,8 @@ const UncontrolledTabs = (props) => { preventDefault = true; useSelectedIndex = true; } else if ( - e.code === 'ArrowRight' || - e.keyCode === 39 /* arrow right */ || + (!disableLeftRightKeys && + (e.keyCode === 39 || e.code === 'ArrowRight')) /* arrow right */ || (!disableUpDownKeys && (e.keyCode === 40 || e.code === 'ArrowDown')) /* arrow down */ ) { @@ -380,6 +381,7 @@ const UncontrolledTabs = (props) => { selectedTabPanelClassName, // unused environment, // unused disableUpDownKeys, // unused + disableLeftRightKeys, // unused ...attributes } = props; return ( diff --git a/src/components/__tests__/Tabs-test.js b/src/components/__tests__/Tabs-test.js index a993e82c67..1842b170ba 100644 --- a/src/components/__tests__/Tabs-test.js +++ b/src/components/__tests__/Tabs-test.js @@ -608,6 +608,27 @@ describe('', () => { assertTabSelected(1); }); + test('should not change tabs when arrow left/right is pressed and disableLeftRightKeys is passed', async () => { + render( + createTabs({ + disableLeftRightKeys: true, + }), + ); + const firstTab = screen.getByTestId('tab1'); + + await userEvent.tab(); + expect(firstTab).toHaveFocus(); + assertTabSelected(1); + + await userEvent.type(firstTab, '[ArrowLeft]'); + expect(firstTab).toHaveFocus(); + assertTabSelected(1); + + await userEvent.type(firstTab, '[ArrowRight]'); + expect(firstTab).toHaveFocus(); + assertTabSelected(1); + }); + test('should render first tab once tabs are available', () => { const { rerender } = render();