Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions packages/eui/changelogs/upcoming/9630.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Bug fixes**

- Fixed `EuiDataGrid` cell expansion popovers being hidden behind sibling or nested `EuiFlyout`s. The cell popover now derives its `z-index` from its anchor's stacking context (matching default `EuiPopover` behavior) instead of being pinned to `levels.header`.
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ describe('EuiDataGridCellPopover', () => {
cy.get('.euiDataGridRowCell__popover.hello.world').should('exist');
});

it('renders above an ancestor stacking context (e.g. a flyout)', () => {
// Regression test for https://github.com/elastic/eui/issues/8801 β€” the
// popover's z-index must be derived from its anchor's stacking context,
// not a fixed theme value, so it stays above the host flyout.
cy.realMount(
// eslint-disable-next-line @elastic/eui/no-static-z-index -- intentionally a literal value to simulate a flyout's stacking context
<div style={{ position: 'relative', zIndex: 6000 }}>
<EuiDataGrid {...baseProps} />
</div>
);
cy.get(
'[data-gridcell-row-index="0"][data-gridcell-column-index="0"]'
).click();
cy.realPress('Enter');
cy.get('[data-test-subj="euiDataGridExpansionPopover"]')
.invoke('css', 'z-index')
.then((zIndex) => expect(Number(zIndex)).to.be.greaterThan(6000));
});

describe('popover anchor/positioning', () => {
const props = {
...baseProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe('useCellPopover', () => {
data-test-subj="euiDataGridExpansionPopover"
id="euiPopover_generated-id_panelId"
role="dialog"
style="top: 4px; left: 0px; will-change: transform, opacity; max-inline-size: min(75vw, max(0px, 400px)); max-block-size: 50vh; z-index: 1000;"
style="top: 4px; left: 0px; will-change: transform, opacity; max-inline-size: min(75vw, max(0px, 400px)); max-block-size: 50vh; z-index: 2000;"
tabindex="0"
Comment thread
weronikaolejniczak marked this conversation as resolved.
>
<p
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
DataGridCellPopoverContextShape,
EuiDataGridCellPopoverElementProps,
} from '../../data_grid_types';
import { euiDataGridVariables } from '../../data_grid.styles';
import { euiDataGridCellPopoverStyles } from './data_grid_cell_popover.styles';

export const DataGridCellPopoverContext =
Expand Down Expand Up @@ -130,14 +129,20 @@ export const useCellPopover = (): {
}, [popoverIsOpen, closeCellPopover, openCellPopover, cellLocation]);

const styles = useEuiMemoizedStyles(euiDataGridCellPopoverStyles);
const { levels } = useEuiMemoizedStyles(euiDataGridVariables);

const cellPopover = useMemo(() => {
if (!popoverIsOpen || !popoverAnchor) return null;

const cell = popoverAnchor.closest<HTMLElement>('.euiDataGridRowCell');

// Note that this popover is rendered once at the top grid level, rather than one popover per cell
// Note that this popover is rendered once at the top grid level, rather than one popover per cell.
//
// We intentionally do NOT pass `zIndex` here. Letting `EuiPopover` derive the
// panel's z-index from the anchor's stacking context (`getElementZIndex(button) + 2000`)
// keeps cell popovers above their host flyout β€” including when sibling/nested
// flyouts push the host's z-index above `levels.header`. See
// https://github.com/elastic/eui/issues/8801. Consumers that need a fixed
// value can still override via `setCellPopoverProps({ zIndex })`.
return (
<EuiWrappingPopover
isOpen={popoverIsOpen}
Expand All @@ -147,7 +152,6 @@ export const useCellPopover = (): {
panelPaddingSize="s"
anchorPosition={popoverAnchorPosition}
repositionToCrossAxis={false}
zIndex={levels.cellPopover}
{...cellPopoverProps}
focusTrapProps={{ onClickOutside, clickOutsideDisables: false }}
panelProps={{
Expand All @@ -173,7 +177,6 @@ export const useCellPopover = (): {
);
}, [
styles,
levels.cellPopover,
popoverIsOpen,
popoverAnchor,
popoverContent,
Expand Down
10 changes: 6 additions & 4 deletions packages/eui/src/components/datagrid/data_grid.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ export const euiDataGridVariables = (euiThemeContext: UseEuiTheme) => {
m: euiFontSize(euiThemeContext, 's').fontSize,
},
levels: {
cellPopover: Number(euiTheme.levels.header), // Same z-index as EuiFlyout mask overlays - cell popovers should be under both modal and flyout overlays
get stickyHeader() {
return this.cellPopover - 1; // Needs to sit above the content + cell focus outlines/actions, but below actual popovers
},
// Sits above content and cell focus outlines/actions, but below cell
// expansion popovers. Cell popovers no longer use a fixed z-index β€” they
// derive theirs from their anchor's stacking context (see
// data_grid_cell_popover.tsx) β€” so this only needs to clear the grid's
// own internal layers.
stickyHeader: Number(euiTheme.levels.header) - 1,
},
};
};
Expand Down