diff --git a/packages/ibm-products-styles/src/components/Datagrid/styles/_useExpandedRow.scss b/packages/ibm-products-styles/src/components/Datagrid/styles/_useExpandedRow.scss
index b22707d5f2..3c566bec65 100644
--- a/packages/ibm-products-styles/src/components/Datagrid/styles/_useExpandedRow.scss
+++ b/packages/ibm-products-styles/src/components/Datagrid/styles/_useExpandedRow.scss
@@ -71,3 +71,24 @@
td {
background: $layer-hover;
}
+
+.#{variables.$block-class}
+ .#{c4p-settings.$carbon-prefix}--data-table
+ tbody
+ tr:hover
+ td.#{variables.$block-class}__expanded-row-cell-wrapper,
+.#{variables.$block-class}
+ .#{c4p-settings.$carbon-prefix}--data-table
+ td.#{variables.$block-class}__expanded-row-cell-wrapper,
+.#{variables.$block-class}
+ .#{c4p-settings.$carbon-prefix}--data-table
+ .#{variables.$block-class}__carbon-row-expanded
+ td.#{variables.$block-class}__expandable-row-cell {
+ border: none;
+}
+
+.#{variables.$block-class}
+ .#{c4p-settings.$carbon-prefix}--data-table
+ td.#{variables.$block-class}__expanded-row-cell-wrapper {
+ padding: 0;
+}
diff --git a/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridExpandedRow.js b/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridExpandedRow.js
index 9ea0eee798..7ff2f93a79 100644
--- a/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridExpandedRow.js
+++ b/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridExpandedRow.js
@@ -34,14 +34,16 @@ const DatagridExpandedRow =
onMouseEnter={(event) => toggleParentHoverClass(event, 'enter')}
onMouseLeave={(event) => toggleParentHoverClass(event)}
>
-
-
-
+
+
+
+
+ |
);
};
diff --git a/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridRow.js b/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridRow.js
index ba095bbe4d..e372f0b0b9 100644
--- a/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridRow.js
+++ b/packages/ibm-products/src/components/Datagrid/Datagrid/DatagridRow.js
@@ -24,7 +24,15 @@ const rowHeights = {
// eslint-disable-next-line react/prop-types
const DatagridRow = (datagridState) => {
- const { row, rowSize, withNestedRows, prepareRow, key } = datagridState;
+ const {
+ row,
+ rowSize,
+ withNestedRows,
+ prepareRow,
+ key,
+ tableId,
+ withExpandedRows,
+ } = datagridState;
const getVisibleNestedRowCount = ({ isExpanded, subRows }) => {
let size = 0;
@@ -67,7 +75,7 @@ const DatagridRow = (datagridState) => {
const focusRemover = () => {
const elements = document.querySelectorAll(
- `.${blockClass}__carbon-row-expanded`
+ `#${tableId} .${blockClass}__carbon-row-expanded`
);
elements.forEach((el) => {
el.classList.remove(`${blockClass}__carbon-row-expanded-hover-active`);
@@ -107,6 +115,15 @@ const DatagridRow = (datagridState) => {
[`${carbon.prefix}--data-table--selected`]: row.isSelected,
});
+ const setAdditionalRowProps = () => {
+ if (withNestedRows || withExpandedRows) {
+ return {
+ 'data-nested-row-id': row.id,
+ };
+ }
+ return {};
+ };
+
return (
{
onFocus={hoverHandler}
onBlur={focusRemover}
onKeyUp={handleOnKeyUp}
+ {...setAdditionalRowProps()}
>
{row.cells.map((cell, index) => {
const cellProps = cell.getCellProps();
diff --git a/packages/ibm-products/src/components/Datagrid/Extensions/ExpandableRow/ExpandableRow.stories.js b/packages/ibm-products/src/components/Datagrid/Extensions/ExpandableRow/ExpandableRow.stories.js
index 622a606ccc..0f2798e9e2 100644
--- a/packages/ibm-products/src/components/Datagrid/Extensions/ExpandableRow/ExpandableRow.stories.js
+++ b/packages/ibm-products/src/components/Datagrid/Extensions/ExpandableRow/ExpandableRow.stories.js
@@ -19,7 +19,6 @@ import { DatagridActions } from '../../utils/DatagridActions';
import { DatagridPagination } from '../../utils/DatagridPagination';
import { makeData } from '../../utils/makeData';
import { ARG_TYPES } from '../../utils/getArgTypes';
-import { pkg } from '../../../../settings';
import { DocsPage } from './ExpandableRow.docs-page';
import { usePrefix } from '../../../../global/js/hooks';
@@ -189,12 +188,6 @@ const ExpandedRows = ({ ...args }) => {
useExpandedRow
);
- // Warnings are ordinarily silenced in storybook, add this to test.
- pkg._silenceWarnings(false);
- // Enable feature flag for `useExpandedRow` hook
- pkg.feature['Datagrid.useExpandedRow'] = true;
- pkg._silenceWarnings(true);
-
return ;
};
@@ -222,6 +215,5 @@ export const ExpandableRowStory = prepareStory(BasicTemplateWrapper, {
},
args: {
...expandableRowControlProps,
- featureFlags: ['Datagrid.useExpandedRow'],
},
});
diff --git a/packages/ibm-products/src/components/Datagrid/Extensions/NestedRows/NestedRows.stories.js b/packages/ibm-products/src/components/Datagrid/Extensions/NestedRows/NestedRows.stories.js
index d6d5ff0eac..21a8aa7c52 100644
--- a/packages/ibm-products/src/components/Datagrid/Extensions/NestedRows/NestedRows.stories.js
+++ b/packages/ibm-products/src/components/Datagrid/Extensions/NestedRows/NestedRows.stories.js
@@ -15,11 +15,9 @@ import {
} from '../../../../global/js/utils/story-helper';
import { Datagrid, useDatagrid, useNestedRows } from '../../index';
import styles from '../../_storybook-styles.scss';
-// import mdx from '../../Datagrid.mdx';
import { DatagridActions } from '../../utils/DatagridActions';
import { makeData } from '../../utils/makeData';
import { ARG_TYPES } from '../../utils/getArgTypes';
-import { pkg } from '../../../../settings';
import { StoryDocsPage } from '../../../../global/js/utils/StoryDocsPage';
export default {
@@ -205,12 +203,6 @@ const SingleLevelNestedRows = ({ ...args }) => {
useNestedRows
);
- // Warnings are ordinarily silenced in storybook, add this to test
- pkg._silenceWarnings(false);
- // Enable feature flag for `useNestedRows` hook
- pkg.feature['Datagrid.useNestedRows'] = true;
- pkg._silenceWarnings(true);
-
return ;
};
@@ -253,12 +245,6 @@ const NestedRows = ({ ...args }) => {
useNestedRows
);
- // Warnings are ordinarily silenced in storybook, add this to test
- pkg._silenceWarnings(false);
- // Enable feature flag for `useNestedRows` hook
- pkg.feature['Datagrid.useNestedRows'] = true;
- pkg._silenceWarnings(true);
-
return ;
};
@@ -281,6 +267,5 @@ export const NestedRowsUsageStory = prepareStory(BasicTemplateWrapper, {
},
args: {
...nestedRowsControlProps,
- featureFlags: ['Datagrid.useNestedRows'],
},
});
diff --git a/packages/ibm-products/src/components/Datagrid/useExpandedRow.js b/packages/ibm-products/src/components/Datagrid/useExpandedRow.js
index 57dfd7a28f..21c235ee3b 100644
--- a/packages/ibm-products/src/components/Datagrid/useExpandedRow.js
+++ b/packages/ibm-products/src/components/Datagrid/useExpandedRow.js
@@ -5,16 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
-import { useEffect, useState } from 'react';
-import { pkg } from '../../settings';
+import { useState } from 'react';
import DatagridExpandedRow from './Datagrid/DatagridExpandedRow';
import useRowExpander from './useRowExpander';
const useExpandedRow = (hooks) => {
- useEffect(() => {
- pkg.checkReportFeatureEnabled('Datagrid.useExpandedRow');
- }, []);
-
useRowExpander(hooks);
const useInstance = (instance) => {
const { rows, expandedContentHeight, ExpandedRowContentComponent } =
@@ -29,7 +24,11 @@ const useExpandedRow = (hooks) => {
expandedRowsHeight[row.index] || expandedContentHeight,
RowExpansionRenderer: DatagridExpandedRow(ExpandedRowContentComponent),
}));
- Object.assign(instance, { rows: rowsWithExpand, setExpandedRowHeight });
+ Object.assign(instance, {
+ rows: rowsWithExpand,
+ setExpandedRowHeight,
+ withExpandedRows: true,
+ });
};
hooks.useInstance.push(useInstance);
};
diff --git a/packages/ibm-products/src/components/Datagrid/useFocusRowExpander.js b/packages/ibm-products/src/components/Datagrid/useFocusRowExpander.js
new file mode 100644
index 0000000000..aa7cf3c68b
--- /dev/null
+++ b/packages/ibm-products/src/components/Datagrid/useFocusRowExpander.js
@@ -0,0 +1,50 @@
+/**
+ * Copyright IBM Corp. 2023, 2023
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { useEffect } from 'react';
+
+// Focuses the row expander after a nested/expandable row state change.
+// We have to add this workaround because react-table is re-rendering the entire row
+// which removes the focus from the expander and interrupts the keyboard navigation
+// flow.
+export const useFocusRowExpander = ({
+ instance,
+ lastExpandedRowIndex,
+ blockClass,
+ activeElement,
+}) => {
+ useEffect(() => {
+ // We need to return at this point so that the focus is not stolen from
+ // other interactive elements in the Datagrid
+ if (!activeElement.classList.contains(`${blockClass}__row-expander`)) {
+ return;
+ }
+ const tableId = instance?.tableId;
+ const rowElements = document.querySelectorAll(`#${tableId} tbody tr`);
+ if (lastExpandedRowIndex) {
+ const rowElementsArray = Array.from(rowElements);
+ const activeRow = rowElementsArray.filter((r) => {
+ if (r.getAttribute('data-nested-row-id') === lastExpandedRowIndex) {
+ return r;
+ }
+ return null;
+ });
+ if (activeRow.length) {
+ const rowExpander = activeRow[0].querySelector(
+ `.${blockClass}__row-expander`
+ );
+ rowExpander.focus();
+ }
+ }
+ }, [
+ instance?.tableId,
+ instance?.expandedRows,
+ lastExpandedRowIndex,
+ blockClass,
+ activeElement,
+ ]);
+};
diff --git a/packages/ibm-products/src/components/Datagrid/useNestedRowExpander.js b/packages/ibm-products/src/components/Datagrid/useNestedRowExpander.js
index aab7e45a2f..c2ad7d6ffd 100644
--- a/packages/ibm-products/src/components/Datagrid/useNestedRowExpander.js
+++ b/packages/ibm-products/src/components/Datagrid/useNestedRowExpander.js
@@ -10,14 +10,24 @@ import React, { useRef } from 'react';
import { ChevronRight } from '@carbon/react/icons';
import cx from 'classnames';
import { pkg, carbon } from '../../settings';
+import { useFocusRowExpander } from './useFocusRowExpander';
const blockClass = `${pkg.prefix}--datagrid`;
const useNestedRowExpander = (hooks) => {
const tempState = useRef();
+ const lastExpandedRowIndex = useRef();
const useInstance = (instance) => {
tempState.current = instance;
};
+
+ useFocusRowExpander({
+ instance: tempState?.current,
+ lastExpandedRowIndex: lastExpandedRowIndex?.current,
+ blockClass,
+ activeElement: document.activeElement,
+ });
+
const visibleColumns = (columns) => {
const expanderColumn = {
id: 'expander',
@@ -28,6 +38,7 @@ const useNestedRowExpander = (hooks) => {
// Prevents `onRowClick` from being called if `useOnRowClick` is included
event.stopPropagation();
row.toggleRowExpanded();
+ lastExpandedRowIndex.current = row.id;
},
};
const {
diff --git a/packages/ibm-products/src/components/Datagrid/useNestedRows.js b/packages/ibm-products/src/components/Datagrid/useNestedRows.js
index 4bfa4a17b1..d9691fe2f1 100644
--- a/packages/ibm-products/src/components/Datagrid/useNestedRows.js
+++ b/packages/ibm-products/src/components/Datagrid/useNestedRows.js
@@ -5,18 +5,13 @@
* LICENSE file in the root directory of this source tree.
*/
-import { useEffect } from 'react';
-import { pkg } from '../../settings';
import cx from 'classnames';
+import { pkg } from '../../settings';
import useNestedRowExpander from './useNestedRowExpander';
const blockClass = `${pkg.prefix}--datagrid`;
const useNestedRows = (hooks) => {
- useEffect(() => {
- pkg.checkReportFeatureEnabled('Datagrid.useNestedRows');
- }, []);
-
useNestedRowExpander(hooks);
const marginLeft = 24;
diff --git a/packages/ibm-products/src/components/Datagrid/useRowExpander.js b/packages/ibm-products/src/components/Datagrid/useRowExpander.js
index 979bcfa02d..55eaf85c0b 100644
--- a/packages/ibm-products/src/components/Datagrid/useRowExpander.js
+++ b/packages/ibm-products/src/components/Datagrid/useRowExpander.js
@@ -10,14 +10,24 @@ import React, { useRef } from 'react';
import { ChevronDown, ChevronUp } from '@carbon/react/icons';
import { pkg, carbon } from '../../settings';
import cx from 'classnames';
+import { useFocusRowExpander } from './useFocusRowExpander';
const blockClass = `${pkg.prefix}--datagrid`;
const useRowExpander = (hooks) => {
const tempState = useRef();
+ const lastExpandedRowIndex = useRef();
const useInstance = (instance) => {
tempState.current = instance;
};
+
+ useFocusRowExpander({
+ instance: tempState?.current,
+ lastExpandedRowIndex: lastExpandedRowIndex?.current,
+ blockClass,
+ activeElement: document.activeElement,
+ });
+
const visibleColumns = (columns) => {
const expanderColumn = {
id: 'expander',
@@ -28,6 +38,7 @@ const useRowExpander = (hooks) => {
// Prevents `onRowClick` from being called if `useOnRowClick` is included
event.stopPropagation();
row.toggleRowExpanded();
+ lastExpandedRowIndex.current = row.id;
},
};
const {
diff --git a/packages/ibm-products/src/global/js/package-settings.js b/packages/ibm-products/src/global/js/package-settings.js
index a79e124b6a..cfceb27072 100644
--- a/packages/ibm-products/src/global/js/package-settings.js
+++ b/packages/ibm-products/src/global/js/package-settings.js
@@ -81,8 +81,6 @@ const defaults = {
'default-portal-target-body': true,
'Datagrid.useInlineEdit': false,
'Datagrid.useEditableCell': false,
- 'Datagrid.useExpandedRow': false,
- 'Datagrid.useNestedRows': false,
'Datagrid.useFiltering': false,
'Datagrid.useCustomizeColumns': false,
'ExampleComponent.secondaryIcon': false,