diff --git a/packages/eui/changelogs/upcoming/8135.md b/packages/eui/changelogs/upcoming/8135.md
new file mode 100644
index 00000000000..03d2cdf4ac9
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8135.md
@@ -0,0 +1,4 @@
+**Bug fixes**
+
+- Fixed an `EuiDataGrid` bug where column actions where not clickable when `EuiDataGrid` with `columnVisibility.canDragAndDropColumns` was used inside a modal
+
diff --git a/packages/eui/src-docs/src/views/datagrid/schema_columns/column_dragging.js b/packages/eui/src-docs/src/views/datagrid/schema_columns/column_dragging.js
index b363d54b33c..fd3e11e4d60 100644
--- a/packages/eui/src-docs/src/views/datagrid/schema_columns/column_dragging.js
+++ b/packages/eui/src-docs/src/views/datagrid/schema_columns/column_dragging.js
@@ -1,41 +1,20 @@
-import React, { useState } from 'react';
+import React, { useState, useCallback } from 'react';
import { faker } from '@faker-js/faker';
-import {
- EuiDataGrid,
- EuiAvatar,
- EuiToolTip,
- EuiButtonIcon,
-} from '../../../../../src/components';
-
-const CustomHeaderCell = ({ title }) => (
- <>
- {title}
-
-
-
- >
-);
+import { EuiDataGrid, EuiAvatar } from '../../../../../src/components';
const columns = [
{
id: 'avatar',
initialWidth: 40,
isResizable: false,
- actions: false,
},
{
id: 'name',
- displayAsText: 'Name',
- display: ,
+ initialWidth: 100,
},
{
id: 'email',
- display: ,
},
{
id: 'city',
@@ -67,21 +46,42 @@ for (let i = 1; i < 5; i++) {
}
export default () => {
+ const [pagination, setPagination] = useState({ pageIndex: 0 });
+
const [visibleColumns, setVisibleColumns] = useState(
columns.map(({ id }) => id)
);
+ const setPageIndex = useCallback(
+ (pageIndex) =>
+ setPagination((pagination) => ({ ...pagination, pageIndex })),
+ []
+ );
+ const setPageSize = useCallback(
+ (pageSize) =>
+ setPagination((pagination) => ({
+ ...pagination,
+ pageSize,
+ pageIndex: 0,
+ })),
+ []
+ );
+
return (
data[rowIndex][columnId]}
+ pagination={{
+ ...pagination,
+ onChangeItemsPerPage: setPageSize,
+ onChangePage: setPageIndex,
+ }}
/>
);
};
diff --git a/packages/eui/src/components/datagrid/body/header/draggable_columns.spec.tsx b/packages/eui/src/components/datagrid/body/header/draggable_columns.spec.tsx
index 7b78578823a..a8ad5d81e55 100644
--- a/packages/eui/src/components/datagrid/body/header/draggable_columns.spec.tsx
+++ b/packages/eui/src/components/datagrid/body/header/draggable_columns.spec.tsx
@@ -12,6 +12,7 @@
import React, { useState } from 'react';
import { EuiDataGrid, EuiDataGridProps } from '../../index';
+import { EuiModal, EuiModalBody } from '../../../modal';
describe('draggable columns', () => {
const columns = [
@@ -284,4 +285,40 @@ describe('draggable columns', () => {
cy.get('[data-popover-open]').should('not.exist');
});
});
+
+ describe('inside a modal', () => {
+ it('should execute column actions on click', () => {
+ cy.realMount(
+ {}}>
+
+
+
+
+ );
+
+ cy.get('[data-test-subj=dataGridHeaderCell-a]').realHover();
+ cy.wait(50); // wait until actions button transition is progressed enough for the button to be clickable
+ cy.get('[data-test-subj=dataGridHeaderCellActionButton-a]').realClick();
+ cy.get('[data-popover-open]').should('have.focus');
+
+ cy.get(
+ '.euiListGroupItem:last-child .euiListGroupItem__button'
+ ).realClick();
+
+ cy.get('[data-test-subj=dataGridHeaderCell-a]').should(
+ 'have.attr',
+ 'data-gridcell-column-index',
+ '1'
+ );
+ cy.get('[data-test-subj=dataGridHeaderCell-b]').should(
+ 'have.attr',
+ 'data-gridcell-column-index',
+ '0'
+ );
+
+ cy.get('[data-test-subj=euiDataGridHeaderColumnActions]').should(
+ 'not.exist'
+ );
+ });
+ });
});
diff --git a/packages/eui/src/components/datagrid/body/header/draggable_columns.tsx b/packages/eui/src/components/datagrid/body/header/draggable_columns.tsx
index 7c754013184..be12c9a2669 100644
--- a/packages/eui/src/components/datagrid/body/header/draggable_columns.tsx
+++ b/packages/eui/src/components/datagrid/body/header/draggable_columns.tsx
@@ -132,16 +132,23 @@ export const DraggableColumn: FunctionComponent<{
const { setFocusedCell } = useContext(DataGridFocusContext);
const handleOnMouseDown: MouseEventHandler = useCallback(
(e) => {
- const openFocusTrap = document.querySelector(
+ const openFocusTraps = document.querySelectorAll(
'[data-focus-lock-disabled="false"]'
);
- if (
- !!openFocusTrap && // If a focus trap is open somewhere on the page
- !openFocusTrap.contains(e.target as Node) && // & the focus trap doesn't belong to this header
- e.target !== actionsPopoverToggle // & we're not closing the actions popover toggle
- ) {
+ const validOpenFocusTraps = [...openFocusTraps].filter(
+ (focusTrap) => !focusTrap.contains(e.currentTarget as Node) // remove containing focus traps (e.g. modals or flyouts)
+ );
+
+ const shouldDispatchEvent = validOpenFocusTraps.some(
+ (focusTrap) =>
+ !!focusTrap && // If there is a focus trap open
+ !focusTrap.contains(e.target as Node) && // & if it doesn't contain the target
+ e.target !== actionsPopoverToggle // & we're not closing the actions popover toggle
+ );
+
+ if (shouldDispatchEvent) {
// Trick the focus trap lib into registering an outside click -
- // the drag/drop lib otherwise otherwise prevents the event 💀
+ // the drag/drop lib otherwise prevents the event 💀
document.dispatchEvent(new MouseEvent('mousedown'));
}
setTimeout(() => {