Skip to content

Commit

Permalink
feat(Tabs): QLT-8 - Support ArrowLeft/ArrowRight tabs edge + Home/End…
Browse files Browse the repository at this point in the history
… support to Tabs
  • Loading branch information
AlexisH committed Nov 25, 2020
1 parent ae95e8f commit c208d18
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 11 deletions.
212 changes: 212 additions & 0 deletions packages/react/src/components/tabs/tabs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,218 @@ describe('Tabs', () => {
expectPanelToBeVisible(wrapper, 'tab-panel--1', true);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
});

test('when the left arrow and the space keys are entered and first tab is active then it should display the last tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');

tabButtonsDiv.simulate('keydown', { key: 'ArrowLeft' });
tabButtonsDiv.simulate('keydown', { key: ' ' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', false);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', true);
});

test('when the left arrow and the enter keys are entered and first tab is active then it should display the last tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');

tabButtonsDiv.simulate('keydown', { key: 'ArrowLeft' });
tabButtonsDiv.simulate('keydown', { key: 'Enter' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', false);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', true);
});

test('when the right arrow and the space keys are entered and last tab is active then it should display the first tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');
getByTestId(wrapper, 'tab-button--3').simulate('click');

tabButtonsDiv.simulate('keydown', { key: 'ArrowRight' });
tabButtonsDiv.simulate('keydown', { key: ' ' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', true);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', false);
});

test('when the right arrow and the enter keys are entered and last tab is active then it should display the first tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');
getByTestId(wrapper, 'tab-button--3').simulate('click');

tabButtonsDiv.simulate('keydown', { key: 'ArrowRight' });
tabButtonsDiv.simulate('keydown', { key: 'Enter' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', true);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', false);
});

test('when the home and the space keys are entered then it should display the first tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');
getByTestId(wrapper, 'tab-button--3').simulate('click');

tabButtonsDiv.simulate('keydown', { key: 'Home' });
tabButtonsDiv.simulate('keydown', { key: ' ' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', true);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', false);
});

test('when the home and the enter keys are entered then it should display the first tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');
getByTestId(wrapper, 'tab-button--3').simulate('click');

tabButtonsDiv.simulate('keydown', { key: 'Home' });
tabButtonsDiv.simulate('keydown', { key: 'Enter' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', true);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', false);
});

test('when the end and the space keys are entered then it should display the last tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');

tabButtonsDiv.simulate('keydown', { key: 'End' });
tabButtonsDiv.simulate('keydown', { key: ' ' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', false);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', true);
});

test('when the end and the enter keys are entered then it should display the last tab', () => {
const tabs: Tab[] = [
{
title: 'button 1',
panelContent: <div>content</div>,
},
{
title: 'button 2',
panelContent: <div>content</div>,
},
{
title: 'button 3',
panelContent: <div>content</div>,
},
];
const wrapper = mountWithProviders(<Tabs tabs={tabs} />);
const tabButtonsDiv = getByTestId(wrapper, 'tab-buttons-div');

tabButtonsDiv.simulate('keydown', { key: 'End' });
tabButtonsDiv.simulate('keydown', { key: 'Enter' });

expectPanelToBeVisible(wrapper, 'tab-panel--1', false);
expectPanelToBeVisible(wrapper, 'tab-panel--2', false);
expectPanelToBeVisible(wrapper, 'tab-panel--3', true);
});
});

const simulateTabSelectionToTheRight = (tabButtonsDiv: CommonWrapper) => {
Expand Down
34 changes: 23 additions & 11 deletions packages/react/src/components/tabs/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,29 @@ export function Tabs({ tabs }: TabsProps): ReactElement {
const [tabsState, setTabsState] = useReducer(reducer, tabs, initTabsSelection);

function handleKeyDown(event: KeyboardEvent<HTMLDivElement>): void {
const selectedIndex = tabsState.findIndex(tabState => tabState.isButtonSelected);
if (event.key === 'ArrowLeft' && selectedIndex > 0) {
const tabToSelect = tabsState[selectedIndex - 1];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
} else if (event.key === 'ArrowRight' && selectedIndex < tabsState.length - 1) {
const tabToSelect = tabsState[selectedIndex + 1];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
} else if (event.key === 'Enter' || event.key === ' ') {
const tabToSelect = tabsState[selectedIndex];
setTabsState({ id: tabToSelect.id, isPanelSelection: true });
event.preventDefault();
let selectedIndex = tabsState.findIndex(tabState => tabState.isButtonSelected);
if (selectedIndex >= 0) {
if (event.key === 'ArrowLeft') {
selectedIndex = (selectedIndex === 0) ? tabsState.length - 1 : selectedIndex - 1;
const tabToSelect = tabsState[selectedIndex];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
} else if (event.key === 'ArrowRight') {
selectedIndex = (selectedIndex === tabsState.length - 1) ? 0 : selectedIndex + 1;
const tabToSelect = tabsState[selectedIndex];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
} else if (event.key === 'Home') {
const tabToSelect = tabsState[0];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
event.preventDefault();
} else if (event.key === 'End') {
const tabToSelect = tabsState[tabsState.length - 1];
setTabsState({ id: tabToSelect.id, isPanelSelection: false });
event.preventDefault();
} else if (event.key === 'Enter' || event.key === ' ') {
const tabToSelect = tabsState[selectedIndex];
setTabsState({ id: tabToSelect.id, isPanelSelection: true });
event.preventDefault();
}
}
}

Expand Down

0 comments on commit c208d18

Please sign in to comment.