Skip to content

Commit

Permalink
fix(Datagrid): clickable row retain focus after sidepanel closes
Browse files Browse the repository at this point in the history
  • Loading branch information
anamikaanu96 committed Aug 27, 2024
1 parent 791e2b3 commit c0cff54
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
30 changes: 30 additions & 0 deletions e2e/components/Datagrid/Datagrid-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import { expect, test } from '@playwright/test';
import { visitStory } from '../../test-utils/storybook';

test.describe.configure({ mode: 'parallel' });

test.describe('Datagrid @avt', () => {
test('@avt-basic-usage', async ({ page }) => {
await visitStory(page, {
Expand All @@ -21,4 +23,32 @@ test.describe('Datagrid @avt', () => {
});
await expect(page).toHaveNoACViolations('Datagrid @avt-basic-usage');
});

test('@avt-open-and-dismiss-sidepanel-onRowClick', async ({ page }) => {
await visitStory(page, {
component: 'Datagrid',
id: 'ibm-products-components-datagrid-clickablerow--clickable-row-story',
globals: {
carbonTheme: 'white',
},
});
const table = await page.getByLabel('Data table title');
await expect(table).toBeVisible();
const firstRow = await table.getByRole('row', {
name: 'Toggle Row Selected 1',
});
firstRow.click();
await page.waitForTimeout(3000);
const sidePanel = page.locator('[aria-label="Title"]');
await page.waitForTimeout(3000);
await expect(sidePanel).toBeVisible();
const button = sidePanel.getByText('View details');
await expect(button).toBeFocused();
await page.keyboard.press('Shift+Tab');
await page.keyboard.press('Enter');
await expect(firstRow).toBeFocused();
await expect(page).toHaveNoACViolations(
'Datagrid @avt-open-and-dismiss-sidepanel-onRowClick'
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { Edit, TrashCan, Add } from '@carbon/react/icons';
import { action } from '@storybook/addon-actions';
import {
Expand Down Expand Up @@ -351,6 +351,26 @@ const ClickableRowWithPanel = ({ ...args }) => {
const [data] = useState(makeData(10));
const [openSidePanel, setOpenSidePanel] = useState(false);
const [rowData, setRowData] = useState({});
const [focusBackElm, setFocusBackElm] = useState();
const sidePanelRef = useRef();

useEffect(() => {
if (openSidePanel) {
const focusableElements = sidePanelRef.current.querySelectorAll(
'button, [href], input, select, [tabindex]:not([tabindex="-1"])'
);
const lastFocusableElement =
focusableElements[focusableElements.length - 2]; //excluding 'Focus sentinel' span
const handleFocus = () => {
focusBackElm.focus();
};
lastFocusableElement.addEventListener('blur', handleFocus);
return () => {
lastFocusableElement.removeEventListener('blur', handleFocus);
};
}
}, [openSidePanel]);

const datagridState = useDatagrid(
{
columns,
Expand All @@ -359,6 +379,7 @@ const ClickableRowWithPanel = ({ ...args }) => {
action()(event);
setOpenSidePanel(true);
setRowData(row);
setFocusBackElm(event.currentTarget);
},
DatagridActions,
batchActions: true,
Expand All @@ -383,7 +404,12 @@ const ClickableRowWithPanel = ({ ...args }) => {
selectorPageContent={true && '.page-content-wrapper'} // Only if SlideIn
selectorPrimaryFocus="#side-panel-story__view-link"
open={openSidePanel}
onRequestClose={() => setOpenSidePanel(false)}
onRequestClose={() => {
setOpenSidePanel(false);
focusBackElm.focus();
}}
ref={sidePanelRef}
tabIndex="0"
size={'sm'}
title={'Title'}
slideIn
Expand Down

0 comments on commit c0cff54

Please sign in to comment.