Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiDataGrid] Implement draggable column headers #8015

Merged
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
7a43829
feat: enable draggable datagrid column headers
mgadewoll Sep 10, 2024
08f3583
test: add tests and update snapshots
mgadewoll Sep 10, 2024
64d52ee
fix: update datagrid story column order aligning with visibleColumns
mgadewoll Sep 10, 2024
ae292c9
refactor: ensure focus management for draggable cells
mgadewoll Sep 10, 2024
9a5576b
test: add test for draggable cell focus behavior
mgadewoll Sep 10, 2024
94c23cf
fix: ensure expected border and space styles
mgadewoll Sep 11, 2024
5f61f55
refactor: ensure accessible screen reader output
mgadewoll Sep 11, 2024
d8a8224
docs: add EUI docs example
mgadewoll Sep 11, 2024
f7d2adb
chore: add changelog
mgadewoll Sep 11, 2024
fab5380
docs: align EUI docs example with other examples
mgadewoll Sep 12, 2024
41b8d59
refactor: use portal for dragged items
mgadewoll Sep 12, 2024
b80e773
refactor: cleanup
mgadewoll Sep 12, 2024
da831e3
refactor: use portal inside datagrid to ensure scoped styles still apply
mgadewoll Sep 13, 2024
0632be7
test(VRT): update reference images
mgadewoll Sep 13, 2024
2edb2a6
fix: ensure there is only a single draggable element
mgadewoll Sep 13, 2024
8bcdf6a
test: update cypress test to work with portalled draggable cell
mgadewoll Sep 13, 2024
a16b314
refactor: add dragging hint only on non-entered header cell
mgadewoll Sep 16, 2024
de342bc
refactor: remove tabindex from drag wrapper for fully custom draggabl…
mgadewoll Sep 16, 2024
85226e7
refactor: add useCallbacks
mgadewoll Sep 18, 2024
ce61447
styles: cleanup
mgadewoll Sep 18, 2024
d76447b
docs: update column dragging example
mgadewoll Sep 18, 2024
c983138
refactor: dry-out actions styles
mgadewoll Sep 18, 2024
ddc8690
test: update snapshots
mgadewoll Sep 18, 2024
513998b
refactor: move column drag prop under columnVisibility
mgadewoll Sep 19, 2024
75c3fd2
docs(storybook): add column drag story
mgadewoll Sep 19, 2024
6bf338f
test(VRT): add reference images
mgadewoll Sep 19, 2024
62938ed
refactor: change portal position and fix visual issues
mgadewoll Sep 24, 2024
b4a751a
test(VRT): update reference images
mgadewoll Sep 24, 2024
60a0824
chore: update changelog
mgadewoll Sep 24, 2024
d64ebb8
refactor: use EuiDraggable usePortal instead of custom EuiPortal for …
mgadewoll Oct 1, 2024
87c0a74
test(VRT): update VRT images
mgadewoll Oct 1, 2024
cab7faf
[PR feedback] Clean up header row droppable styles
cee-chen Oct 3, 2024
969851d
Fix `gap` CSS being lost on header actions open
cee-chen Oct 3, 2024
d100bd8
[cleanup] Move actions popover logic out of the wrapper and into `dat…
cee-chen Oct 3, 2024
96f325e
Remove onBlur event in favor of blocking any drags/closing any open p…
cee-chen Oct 4, 2024
573ed22
[cleanup] Remove unnecessary `wrapperRef` waterfalling
cee-chen Oct 4, 2024
c63040c
Syntax nit cleanups
cee-chen Oct 3, 2024
114a5f4
[UX polish] Improve mouse drag UX for both reordering and resizing co…
cee-chen Oct 4, 2024
4d7945e
[UX polish] Add more visual affordance to keyboard drag start
cee-chen Oct 4, 2024
42c46d2
Fix broken scrolling to draggable header cells
cee-chen Oct 4, 2024
478adbd
Fix columns sometimes not being full height while dragging
cee-chen Oct 4, 2024
b8e5393
[Storybook] Add interactive element to draggable storybook
cee-chen Oct 6, 2024
ae21c3f
[refactor] Move all drag-related components/logic to its own file/com…
cee-chen Oct 5, 2024
3258fd2
[cleanup] Remove need to pass `isDragging` or `closeActionsPopover` t…
cee-chen Oct 5, 2024
abd1a04
[UX polish] Add a stopgap data attr that prevents the hover animation…
cee-chen Oct 5, 2024
7757eac
[opinionated] Revert EuiDraggable changes
cee-chen Oct 6, 2024
b50182d
[refactor pt 1] Move column sorting logic to its own file
cee-chen Oct 6, 2024
a2b3352
[refactor pt 2] Move actions popover keyboard logic to `column_action…
cee-chen Oct 6, 2024
a333a36
[refactor pt 3] Move all column action popover logic to `column_actions`
cee-chen Oct 6, 2024
f9f7593
[naming pt 1] rename various column action booleans to be more consis…
cee-chen Oct 6, 2024
74d4115
[naming pt 2] rename `column_resizer` file to match other utils / non…
cee-chen Oct 6, 2024
92a9fdf
chore: revert to customDragHandle='custom'
mgadewoll Oct 7, 2024
2194419
refactor: rewrite adding aria-describedby ids by using destructuring
mgadewoll Oct 7, 2024
b256ff6
fix: ensure cell focus context is updated on aborted drag
mgadewoll Oct 7, 2024
567684c
Move draggable column E2E tests to their own file
cee-chen Oct 7, 2024
1255321
Fix another focus bug where grid body could become untabbable
cee-chen Oct 7, 2024
26c72d5
Add a fix for focus traps being enterable while dragging
cee-chen Oct 7, 2024
955cef7
feat: add column width cache
mgadewoll Oct 8, 2024
a73ced5
Fix failing style test
cee-chen Oct 9, 2024
ec1835c
Fix a `:last-child` CSS selector that no longer applies after drag/dr…
cee-chen Oct 9, 2024
8361d71
Update downstream resizer snapshots
cee-chen Oct 9, 2024
7111417
[refactor] DRY out `isLastColumn` logic
cee-chen Oct 9, 2024
429b9e7
Merge branch 'main' into datagrid/7136-draggable-column-headers
cee-chen Oct 9, 2024
fb3ff84
[PR feedback] Column widths
cee-chen Oct 10, 2024
219040a
test(VRT): update reference images
mgadewoll Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
mgadewoll marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/eui/changelogs/upcoming/8015.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added `columnVisibility.canDragAndDropColumns` on `EuiDataGrid` which enables reordering columns via draggable header cells

cee-chen marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useState } from 'react';
import { faker } from '@faker-js/faker';

import {
EuiDataGrid,
EuiAvatar,
EuiToolTip,
EuiButtonIcon,
} from '../../../../../src/components';

const CustomHeaderCell = ({ title }) => (
<>
<span>{title}</span>
<EuiToolTip content="tooltip content">
<EuiButtonIcon
iconType="questionInCircle"
aria-label="Additional information"
color="primary"
/>
</EuiToolTip>
</>
);

const columns = [
{
id: 'avatar',
initialWidth: 40,
isResizable: false,
actions: false,
},
{
id: 'name',
displayAsText: 'Name',
display: <CustomHeaderCell title="Name" />,
},
{
id: 'email',
display: <CustomHeaderCell title="Email" />,
},
{
id: 'city',
},
{
id: 'country',
},
{
id: 'account',
},
];

const data = [];

for (let i = 1; i < 5; i++) {
data.push({
avatar: (
<EuiAvatar
size="s"
name={`${faker.person.lastName()}, ${faker.person.firstName()}`}
/>
),
name: `${faker.person.lastName()}, ${faker.person.firstName()} ${faker.person.suffix()}`,
email: faker.internet.email(),
city: faker.location.city(),
country: faker.location.country(),
account: faker.finance.accountNumber(),
});
}

export default () => {
const [visibleColumns, setVisibleColumns] = useState(
columns.map(({ id }) => id)
);

return (
<EuiDataGrid
aria-label="DataGrid demonstrating column reordering on drag"
columns={columns}
columnVisibility={{
visibleColumns: visibleColumns,
setVisibleColumns: setVisibleColumns,
canDragAndDropColumns: true,
}}
rowCount={data.length}
renderCellValue={({ rowIndex, columnId }) => data[rowIndex][columnId]}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import DataGridColumnWidths from './column_widths';
const dataGridColumnWidthsSource = require('!!raw-loader!./column_widths');
import DataGridColumnActions from './column_actions';
const dataGridColumnActionsSource = require('!!raw-loader!./column_actions');
import DataGridColumnDragging from './column_dragging';
const dataGridColumnDraggingSource = require('!!raw-loader!./column_dragging');

import DataGridFooterRow from './footer_row';
const dataGridFooterRowSource = require('!!raw-loader!./footer_row');
Expand Down Expand Up @@ -238,6 +240,32 @@ schemaDetectors={[
},
demo: <DataGridColumnActions />,
},
{
source: [
{
type: GuideSectionTypes.JS,
code: dataGridColumnDraggingSource,
},
],
title: 'Draggable columns',
text: (
<Fragment>
<p>
To reorder columns directly instead of via the actions menu popover,
you can enable draggable <strong>EuiDataGrid</strong> header columns
via the <EuiCode>columnVisibility.canDragAndDropColumns</EuiCode>{' '}
prop. This will allow you to reorder the column by dragging them.
</p>
</Fragment>
),
props: {
EuiDataGrid,
EuiDataGridColumn,
EuiDataGridColumnActions,
EuiListGroupItem,
},
demo: <DataGridColumnDragging />,
},
{
title: 'Control columns',
source: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-A"
tabindex="-1"
Expand Down Expand Up @@ -663,7 +663,7 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
tabindex="-1"
>
<div
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer"
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer-isLastColumn"
data-test-subj="dataGridColumnResizer"
/>
<div
Expand All @@ -677,7 +677,7 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-B"
tabindex="-1"
Expand Down Expand Up @@ -1083,7 +1083,7 @@ exports[`EuiDataGrid rendering renders control columns 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-A"
tabindex="-1"
Expand Down Expand Up @@ -1132,7 +1132,7 @@ exports[`EuiDataGrid rendering renders control columns 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-B"
tabindex="-1"
Expand Down Expand Up @@ -1691,7 +1691,7 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-A"
tabindex="-1"
Expand Down Expand Up @@ -1726,7 +1726,7 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
tabindex="-1"
>
<div
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer"
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer-isLastColumn"
data-test-subj="dataGridColumnResizer"
/>
<div
Expand All @@ -1742,7 +1742,7 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-B"
tabindex="-1"
Expand Down Expand Up @@ -2123,7 +2123,7 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-A"
tabindex="-1"
Expand Down Expand Up @@ -2158,7 +2158,7 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
tabindex="-1"
>
<div
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer"
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer-isLastColumn"
data-test-subj="dataGridColumnResizer"
/>
<div
Expand All @@ -2172,7 +2172,7 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-B"
tabindex="-1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-columnA"
tabindex="-1"
Expand Down Expand Up @@ -71,7 +71,7 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
tabindex="-1"
>
<div
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer"
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer-isLastColumn"
data-test-subj="dataGridColumnResizer"
/>
<div
Expand All @@ -85,7 +85,7 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-columnB"
tabindex="-1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-columnA"
tabindex="-1"
Expand Down Expand Up @@ -75,7 +75,7 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
tabindex="-1"
>
<div
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer"
class="euiDataGridColumnResizer emotion-euiDataGridColumnResizer-isLastColumn"
data-test-subj="dataGridColumnResizer"
/>
<div
Expand All @@ -89,7 +89,7 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
>
<button
aria-label="Press the Enter key to view this column's actions"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__button"
class="euiButtonIcon euiDataGridHeaderCell__button emotion-euiButtonIcon-xs-empty-text-euiDataGridHeaderCell__actions"
data-euigrid-tab-managed="true"
data-test-subj="dataGridHeaderCellActionButton-columnB"
tabindex="-1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,52 @@ describe('Cell outline styles', () => {
});
});
});

describe('column header dragging', () => {
const propsWithDrag = {
...baseProps,
columnVisibility: {
...baseProps.columnVisibility,
canDragAndDropColumns: true,
},
};
const getHeaderCell = () =>
cy.get('.euiDataGridHeaderCell[data-gridcell-column-id="expandable"]');
const getDragIconWidth = () =>
getHeaderCell()
.find('.euiDataGridHeaderCell__draggableIcon')
.then(($el) => {
const { width } = $el[0].getBoundingClientRect();
return width;
});

it('should show focus state when dragging', () => {
cy.realMount(<EuiDataGrid {...propsWithDrag} />);
getDragIconWidth().then((width) => expect(width).to.eq(0));

tabToDataGrid();
cy.realPress('Space');
getHeaderCell().should('have.attr', 'data-column-moving', 'true');

cy.wait(ANIMATION.DURATION + ANIMATION.BUFFER);
getHeaderCell().then(($el) => {
expect(getOutlineColor($el[0])).to.eq(EXPECTED_FOCUS_COLOR);
});
getDragIconWidth().then((width) => expect(width).to.eq(12));
});

it('should not re-flash the header actions transition after drop', () => {
cy.realMount(<EuiDataGrid {...propsWithDrag} />);

tabToDataGrid();
cy.realPress('Space');
getDragIconWidth().then((width) => expect(width).to.eq(12));

cy.realPress('Space');
getDragIconWidth().then((width) => expect(width).to.eq(12));
getHeaderCell().should('not.have.attr', 'data-column-moving');
});
});
});

describe('mouse UI/UX', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const euiDataGridCellOutlineSelectors = (parentSelector = '&') => {

// Cell header specific selectors
const headerActionsOpen = '.euiDataGridHeaderCell--isActionsPopoverOpen';
const isMoving = '[data-column-moving]'; // prevents the header column actions hover animation from replaying on column move

// Utils
const selectors = (...args: string[]) => [...args].join(', ');
Expand All @@ -93,9 +94,14 @@ export const euiDataGridCellOutlineSelectors = (parentSelector = '&') => {
},

header: {
focus: is(selectors(focus, focusWithin, headerActionsOpen)), // :focus-within here is primarily intended for when the column actions button has been clicked twice
focus: is(selectors(focus, focusWithin, headerActionsOpen, isMoving)), // :focus-within here is primarily intended for when the column actions button has been clicked twice
focusTrapped: _(isEntered),
hideActions: not(selectors(hover, focusWithin, headerActionsOpen)),
showActions: is(
selectors(hover, focusWithin, headerActionsOpen, isMoving)
),
hideActions: not(
selectors(hover, focusWithin, headerActionsOpen, isMoving)
),
},
};
};
Expand Down
11 changes: 8 additions & 3 deletions packages/eui/src/components/datagrid/body/cell/focus_utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,24 @@ export const FocusTrappedChildren: FunctionComponent<
// direct DOM manipulation as workaround to attach required hints
useEffect(() => {
const currentAriaDescribedbyId = cellEl.getAttribute('aria-describedby');
// A11y: splitting ids to be able to append the first hint (sorting)
// while other hints should follow the keyboard navigation hints
const [sortingId, ...rest] = currentAriaDescribedbyId?.split(' ') ?? [];
const remainingIds = rest.join(' ');

cellEl.setAttribute(
'aria-describedby',
classNames(currentAriaDescribedbyId, ariaDescribedById)
classNames(sortingId, ariaDescribedById, !isCellEntered && remainingIds)
);

return () => {
if (currentAriaDescribedbyId) {
cellEl.setAttribute('aria-descibedby', currentAriaDescribedbyId);
cellEl.setAttribute('aria-describedby', currentAriaDescribedbyId);
mgadewoll marked this conversation as resolved.
Show resolved Hide resolved
} else {
cellEl.removeAttribute('aria-describedby');
}
};
}, [cellEl, ariaDescribedById]);
}, [cellEl, ariaDescribedById, isCellEntered]);

useEffect(() => {
if (isCellEntered) {
Expand Down Expand Up @@ -142,6 +146,7 @@ export const FocusTrappedChildren: FunctionComponent<
isCellEntered === false &&
isDOMNode(event.target) &&
isDOMNode(event.currentTarget) &&
event.currentTarget !== event.target &&
event.currentTarget.contains(event.target)
) {
return true;
Expand Down
Loading
Loading