diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Actions.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Actions.png
index ca50c61e67d..3d2d9ddbd79 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Actions.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Actions.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png
index 2edc9b07ff9..26a5532c33f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Column_Actions.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Column_Actions.png
new file mode 100644
index 00000000000..f46ffa432a8
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Column_Actions.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Custom_Header_Content.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Custom_Header_Content.png
index e36b846da53..5d32f262af1 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Custom_Header_Content.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Custom_Header_Content.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png
index e37ce718880..9094880a22f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png
index 35af7967f7a..72604cc7467 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Playground.png
index f6ec8696489..bf559e38f18 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Virtualization.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Virtualization.png
index f5da952784a..b66ac1bbf0a 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Virtualization.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Virtualization.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png
index b8f595ce4d5..22b153c35da 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png
index a12ed9f8ff6..0288dc080df 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png
index 7f0f6167c70..8027b468a2f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png
index 57cebef1779..4351c1241b7 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png
index eaca7f7d40e..d4ee1037805 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto.png
index 519a711cdb0..253b80b9dc6 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Line_Height.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Line_Height.png
index acfa299bcaf..f864e1833c9 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Line_Height.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Line_Height.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Row_Heights.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Row_Heights.png
index 709c3af0c56..b66d31ed352 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Row_Heights.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Custom_Row_Heights.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Line_Count.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Line_Count.png
index 8dbb2989928..4d4934226d4 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Line_Count.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Line_Count.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Static_Height.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Static_Height.png
index d50be883a62..e68818083ae 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Static_Height.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Static_Height.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png
index c5b56b2b0c5..a623e5639bd 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png
index 2217b20d215..7d079031bde 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png
index 5fda52e91cc..e0be3cc91d2 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png
index 9e95900d542..1cc843240ce 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png
index 6ef1cabff08..dfa13a507e0 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png
index 8a644dcca6d..c3579f050b9 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png
index e38564eaaea..161691678a4 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png
index 74ac8382e85..1c21d47b978 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Actions.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Actions.png
index 1203d043f97..6093d2348ea 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Actions.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Actions.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png
index 8e4260f510a..d4254b541dc 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Cell_Expansion_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Column_Actions.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Column_Actions.png
new file mode 100644
index 00000000000..05f3381944d
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Column_Actions.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Custom_Header_Content.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Custom_Header_Content.png
index 7048ecc417a..518df5ae9b0 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Custom_Header_Content.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Custom_Header_Content.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png
index 5e60f5820aa..d4fcb79d797 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Flyout.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png
index 595f3e634cb..ed571c7c894 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_FullscreenVRT_Full_Screen_With_Header.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Playground.png
index 300e2cdd650..3e4d7ad724a 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png
index abf53f03899..24fb3fc5edf 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Compact.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png
index fec1775e3c1..60f8d691952 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Expanded.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png
index 6f895cd7908..9548cf694e3 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Horizontal_Lines.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png
index a75c43c328f..fb999cb9cc2 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Minimal.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png
index 9514e96ba46..5058b0eefb6 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_gridStyle_prop_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png
index 2684b934912..f43b5e6d5c9 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Selector.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png
index fe992226be5..708d99e621f 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Column_Sorting.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png
index 31721b52a4b..dc96de28009 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Display_Selector.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png
index 6425b7e09f7..8b4559e7216 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Full_Screen_Toggle.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png
index 24a4dd7ad71..97436fab22f 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png
index d726f673d2c..f9ee3ca682a 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_No_Toolbar.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png
index 3ba4b007c46..654bcea2691 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Render_Custom_Toolbar.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png
index bd3e3f70dfb..f7a5a17659b 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Toolbar_Visibility_Options.png differ
diff --git a/packages/eui/.storybook/loki.ts b/packages/eui/.storybook/loki.ts
index 9c8879cb44b..1d8d8834b02 100644
--- a/packages/eui/.storybook/loki.ts
+++ b/packages/eui/.storybook/loki.ts
@@ -25,7 +25,7 @@ export const LOKI_SELECTORS = {
/**
* Portal element content selector
*/
- portal: '#storybook-root',
+ portal: '#storybook-root > *',
} as const;
/**
diff --git a/packages/eui/.storybook/preview.tsx b/packages/eui/.storybook/preview.tsx
index 385ee472dff..b103c083dd0 100644
--- a/packages/eui/.storybook/preview.tsx
+++ b/packages/eui/.storybook/preview.tsx
@@ -35,11 +35,6 @@ appendIconComponentCache(iconCache);
import { EuiProvider } from '../src/components/provider';
import { writingModeStyles } from './writing_mode.styles';
-// Import light theme for components still using Sass styling
-// TODO: Remove this import and the `yarn compile-scss &&` command
-// once all EUI components are converted to Emotion
-import '../dist/eui_theme_light.css';
-
/**
* Ensure that any provider errors throw & warn us early
*/
diff --git a/packages/eui/changelogs/upcoming/8013.md b/packages/eui/changelogs/upcoming/8013.md
new file mode 100644
index 00000000000..0d2b3962de5
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8013.md
@@ -0,0 +1,7 @@
+**CSS-in-JS conversions**
+
+- Converted `EuiDataGrid`'s row, header, and footer cells to Emotion; Removed the following Sass variables and mixins:
+ - `$euiDataGridColumnResizerWidth`
+ - `@euiDataGridRowCell`
+ - `@euiDataGridHeaderCell`
+ - `@euiDataGridFooterCell`
diff --git a/packages/eui/cypress/support/component.tsx b/packages/eui/cypress/support/component.tsx
index 397bdbffa6c..9ddd5aef01b 100644
--- a/packages/eui/cypress/support/component.tsx
+++ b/packages/eui/cypress/support/component.tsx
@@ -30,5 +30,3 @@ Cypress.on('uncaught:exception', (err) => {
return false;
}
});
-
-require(THEME_IMPORT); // defined by DefinePlugin in the cypress webpack config
diff --git a/packages/eui/cypress/webpack.config.js b/packages/eui/cypress/webpack.config.js
index c7704a93e3f..46c175e0b35 100644
--- a/packages/eui/cypress/webpack.config.js
+++ b/packages/eui/cypress/webpack.config.js
@@ -10,8 +10,6 @@
const { ProvidePlugin, DefinePlugin } = require('webpack');
-const THEME_IMPORT = `'../../dist/eui_theme_${process.env.THEME}.css'`;
-
const alias = {};
const reactVersion = process.env.REACT_VERSION || '18';
@@ -72,7 +70,6 @@ module.exports = {
}),
new DefinePlugin({
- THEME_IMPORT, // allow cypress/support/component.tsx to require the correct css file
'process.env.REACT_VERSION': JSON.stringify(reactVersion),
}),
],
diff --git a/packages/eui/generator-eui/changelog/index.js b/packages/eui/generator-eui/changelog/index.js
index c456a47e085..6aa42a260d0 100644
--- a/packages/eui/generator-eui/changelog/index.js
+++ b/packages/eui/generator-eui/changelog/index.js
@@ -53,12 +53,6 @@ module.exports = class extends Generator {
type: 'confirm',
default: false,
},
- {
- message: 'Does your PR contain Emotion conversions?',
- name: 'emotionConversions',
- type: 'confirm',
- default: false,
- },
{
message: 'Does your PR contain dependency updates?',
name: 'dependencyUpdates',
diff --git a/packages/eui/generator-eui/changelog/templates/changelog.md b/packages/eui/generator-eui/changelog/templates/changelog.md
index 42b0f7992cb..1472557891f 100644
--- a/packages/eui/generator-eui/changelog/templates/changelog.md
+++ b/packages/eui/generator-eui/changelog/templates/changelog.md
@@ -25,11 +25,6 @@
- Removed ...
-<%_ } -%>
-<%_ if (emotionConversions) { -%>
-**CSS-in-JS conversions**
-
-- Converted `EuiComponent` to Emotion; Removed `$euiComponentSassVariable`
<%_ } -%>
<%_ if (dependencyUpdates) { -%>
**Dependency updates**
diff --git a/packages/eui/package.json b/packages/eui/package.json
index d8a248d9fed..7278d0edb40 100644
--- a/packages/eui/package.json
+++ b/packages/eui/package.json
@@ -42,8 +42,8 @@
"release": "node ./scripts/release.js",
"release-backport": "node ./scripts/release.js --type=backport",
"release-rc": "node ./scripts/release.js --type=prerelease",
- "storybook": "yarn compile-scss && storybook dev -p 6006",
- "build-storybook": "yarn compile-scss && storybook build",
+ "storybook": "storybook dev -p 6006",
+ "build-storybook": "storybook build",
"pre-push": "yarn test-staged"
},
"repository": {
diff --git a/packages/eui/scripts/test-cypress.js b/packages/eui/scripts/test-cypress.js
index e0cbde1c7f0..7fe30e1276a 100644
--- a/packages/eui/scripts/test-cypress.js
+++ b/packages/eui/scripts/test-cypress.js
@@ -18,7 +18,6 @@ const argv = yargs(hideBin(process.argv))
})
.options({
'node-options': { type: 'string', default: '' },
- 'skip-css': { type: 'boolean' },
dev: { type: 'boolean' },
theme: { type: 'string', default: 'light', choices: ['light', 'dark'] },
a11y: { type: 'boolean' },
@@ -32,23 +31,12 @@ const argv = yargs(hideBin(process.argv))
const nodeOptions = argv['node-options'];
const isDev = argv.hasOwnProperty('dev');
const isA11y = argv.hasOwnProperty('a11y');
-const skipScss = argv.hasOwnProperty('skip-css');
const theme = argv.theme;
const reactVersion = argv['react-version'];
const info = chalk.white;
const log = chalk.grey;
-// compile scss -> css so tests can render correctly
-if (!skipScss) {
- console.log(info('Compiling SCSS'));
- execSync(`TARGET_THEME=${theme} yarn compile-scss`, {
- stdio: 'inherit',
- });
-} else {
- console.log(info('Not compiling SCSS, disabled by --skip-css'));
-}
-
// compile dev and a11y options for how to run tests (headless, local UI)
// and whether to run component tests or axe checks.
const testParams = isDev
diff --git a/packages/eui/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap b/packages/eui/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap
index b8e59d3edb8..84fd9d9b42c 100644
--- a/packages/eui/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap
@@ -607,34 +607,32 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
tabindex="-1"
>
@@ -651,34 +649,32 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
tabindex="-1"
>
@@ -696,18 +692,11 @@ exports[`EuiDataGrid rendering renders additional toolbar controls 1`] = `
tabindex="-1"
>
0, A
-
- -
- A, column 1, row 1
-
0, B
-
- -
- B, column 2, row 1
-
1, A
-
- -
- A, column 1, row 2
-
1, B
-
- -
- B, column 2, row 2
-
2, A
-
- -
- A, column 1, row 3
-
2, B
-
- -
- B, column 2, row 3
-
@@ -1014,13 +968,9 @@ exports[`EuiDataGrid rendering renders control columns 1`] = `
style="width: 50px;"
tabindex="-1"
>
-
+
+ leading heading
+
@@ -1079,34 +1027,32 @@ exports[`EuiDataGrid rendering renders control columns 1`] = `
tabindex="-1"
>
@@ -1121,13 +1067,9 @@ exports[`EuiDataGrid rendering renders control columns 1`] = `
style="width: 50px;"
tabindex="-1"
>
-
+
+ trailing heading
+
0
-
- -
- leading, column 1, row 1
-
0, A
-
- -
- A, column 2, row 1
-
0, B
-
- -
- B, column 3, row 1
-
0
-
- -
- trailing, column 4, row 1
-
1
-
- -
- leading, column 1, row 2
-
1, A
-
- -
- A, column 2, row 2
-
1, B
-
- -
- B, column 3, row 2
-
1
-
- -
- trailing, column 4, row 2
-
2
-
- -
- leading, column 1, row 3
-
2, A
-
- -
- A, column 2, row 3
-
2, B
-
- -
- B, column 3, row 3
-
2
-
- -
- trailing, column 4, row 3
-
@@ -1616,34 +1474,32 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
tabindex="-1"
>
@@ -1660,12 +1516,11 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
tabindex="-1"
>
@@ -1707,18 +1561,11 @@ exports[`EuiDataGrid rendering renders custom column headers 1`] = `
tabindex="-1"
>
0, A
-
- -
- A, column 1, row 1
-
0, B
-
- -
- B, column 2, row 1
-
1, A
-
- -
- A, column 1, row 2
-
1, B
-
- -
- B, column 2, row 2
-
2, A
-
- -
- A, column 1, row 3
-
2, B
-
- -
- B, column 2, row 3
-
@@ -2024,34 +1836,32 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
tabindex="-1"
>
@@ -2068,34 +1878,32 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
tabindex="-1"
>
@@ -2113,18 +1921,11 @@ exports[`EuiDataGrid rendering renders with common and div attributes 1`] = `
tabindex="-1"
>
0, A
-
- -
- A, column 1, row 1
-
0, B
-
- -
- B, column 2, row 1
-
1, A
-
- -
- A, column 1, row 2
-
1, B
-
- -
- B, column 2, row 2
-
2, A
-
- -
- A, column 1, row 3
-
2, B
-
- -
- B, column 2, row 3
-
diff --git a/packages/eui/src/components/datagrid/_data_grid_data_row.scss b/packages/eui/src/components/datagrid/_data_grid_data_row.scss
deleted file mode 100644
index 9821e7a21af..00000000000
--- a/packages/eui/src/components/datagrid/_data_grid_data_row.scss
+++ /dev/null
@@ -1,46 +0,0 @@
-@include euiDataGridRowCell {
- .euiDataGridRowCell__content {
- height: 100%;
- overflow: hidden;
-
- &--autoHeight {
- height: auto;
- }
- }
-
- // Hack to allow focus trap to still stretch to full row height on defined heights
- > [data-focus-lock-disabled] {
- height: 100%;
- }
-
- &.euiDataGridRowCell--numeric {
- text-align: right;
- }
-
- &.euiDataGridRowCell--currency {
- text-align: right;
- }
-
- &.euiDataGridRowCell--uppercase {
- text-transform: uppercase;
- }
-
- &.euiDataGridRowCell--lowercase {
- text-transform: lowercase;
- }
-
- &.euiDataGridRowCell--capitalize {
- text-transform: capitalize;
- }
-}
-
-.euiDataGridRowCell--controlColumn .euiDataGridRowCell__content {
- max-height: 100%;
- height: auto;
- display: flex;
- align-items: center;
-
- &.euiDataGridRowCell__content--defaultHeight {
- height: 100%;
- }
-}
diff --git a/packages/eui/src/components/datagrid/_index.scss b/packages/eui/src/components/datagrid/_index.scss
deleted file mode 100644
index 5c435cae2fc..00000000000
--- a/packages/eui/src/components/datagrid/_index.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-@import 'variables';
-@import 'mixins';
-@import 'body/header/data_grid_header_row';
-@import 'body/footer/data_grid_footer_row';
-@import 'body/header/data_grid_column_resizer';
-@import 'data_grid_data_row';
diff --git a/packages/eui/src/components/datagrid/_mixins.scss b/packages/eui/src/components/datagrid/_mixins.scss
deleted file mode 100644
index aedd5a32cd5..00000000000
--- a/packages/eui/src/components/datagrid/_mixins.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-@mixin euiDataGridHeaderCell {
- .euiDataGridHeaderCell {
- @content;
- }
-}
-
-@mixin euiDataGridRowCell {
- .euiDataGridRowCell {
- @content;
- }
-}
-
-@mixin euiDataGridFooterCell {
- .euiDataGridRowCell.euiDataGridFooterCell {
- @content;
- }
-}
diff --git a/packages/eui/src/components/datagrid/_variables.scss b/packages/eui/src/components/datagrid/_variables.scss
deleted file mode 100644
index 7eab3561d0d..00000000000
--- a/packages/eui/src/components/datagrid/_variables.scss
+++ /dev/null
@@ -1 +0,0 @@
-$euiDataGridColumnResizerWidth: 3px; // Odd number because it straddles a border
diff --git a/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_custom.test.tsx.snap b/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_custom.test.tsx.snap
index 86412d4b8e7..79b0a64b860 100644
--- a/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_custom.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_custom.test.tsx.snap
@@ -22,34 +22,32 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
tabindex="-1"
>
@@ -66,34 +64,32 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
tabindex="-1"
>
@@ -114,18 +110,11 @@ exports[`EuiDataGridBodyCustomRender treats \`renderCustomGridBody\` as a render
tabindex="-1"
>
hello
-
- -
- columnA, column 1, row 1
-
world
-
- -
- columnB, column 2, row 1
-
lorem
-
- -
- columnA, column 1, row 2
-
ipsum
-
- -
- columnB, column 2, row 2
-
diff --git a/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_virtualized.test.tsx.snap b/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_virtualized.test.tsx.snap
index 3f7b371e037..e1a09ff8136 100644
--- a/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_virtualized.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/body/__snapshots__/data_grid_body_virtualized.test.tsx.snap
@@ -26,34 +26,32 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
tabindex="-1"
>
@@ -70,34 +68,32 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
tabindex="-1"
>
@@ -115,20 +111,13 @@ exports[`EuiDataGridBodyVirtualized renders 1`] = `
tabindex="-1"
>
cell content
-
- -
- columnA, column 1, row 1
-
cell content
-
- -
- columnB, column 2, row 1
-
diff --git a/packages/eui/src/components/datagrid/body/cell/__snapshots__/data_grid_cell.test.tsx.snap b/packages/eui/src/components/datagrid/body/cell/__snapshots__/data_grid_cell.test.tsx.snap
index 6b396ed0691..3020ffe3438 100644
--- a/packages/eui/src/components/datagrid/body/cell/__snapshots__/data_grid_cell.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/body/cell/__snapshots__/data_grid_cell.test.tsx.snap
@@ -49,7 +49,7 @@ exports[`EuiDataGridCell renders 1`] = `
tabindex="-1"
>
@@ -65,12 +65,5 @@ exports[`EuiDataGridCell renders 1`] = `
-
- -
- someColumn, column 1, row 1
-
`;
diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.spec.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.spec.tsx
index 1a7e43109a5..08a87922e20 100644
--- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.spec.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.spec.tsx
@@ -273,5 +273,43 @@ describe('Cell outline styles', () => {
.realMouseMove(80, 0, { position: 'right' }) // ~50% of cell width
.should('not.exist');
});
+
+ it('shows column actions on cell header hover/focus', () => {
+ const getHeaderCell = () =>
+ cy.get('.euiDataGridHeaderCell[data-gridcell-column-id="expandable"]');
+ const getHeaderActions = () =>
+ cy.get('[data-test-subj="dataGridHeaderCellActionButton-expandable"]');
+ const getActionsWidth = () =>
+ getHeaderActions().then(($el) => {
+ const { width } = $el[0].getBoundingClientRect();
+ return width;
+ });
+
+ cy.realMount( );
+ getActionsWidth().then((width) => expect(width).to.eq(0));
+
+ // Hovering over the header cell should slide in the actions from the right
+ getHeaderCell().realHover();
+ cy.wait(ANIMATION.DURATION + ANIMATION.BUFFER);
+ getActionsWidth().then((width) => expect(width).to.eq(24));
+
+ // Toggling the actions popover should render the focus outline
+ getHeaderCell().then(($el) => {
+ expect(getOutlineColor($el[0])).not.to.eq(EXPECTED_FOCUS_COLOR);
+ });
+ getHeaderActions().realClick();
+ getHeaderCell().then(($el) => {
+ expect(getOutlineColor($el[0])).to.eq(EXPECTED_FOCUS_COLOR);
+ });
+ getHeaderActions().realClick();
+
+ // Mousing off the cell should still show outline+actions since the button is still focused
+ getHeaderActions().realMouseMove(100, 0, { position: 'right' });
+ cy.wait(ANIMATION.DURATION + ANIMATION.BUFFER);
+ getActionsWidth().then((width) => expect(width).to.eq(24));
+ getHeaderCell().then(($el) => {
+ expect(getOutlineColor($el[0])).to.eq(EXPECTED_FOCUS_COLOR);
+ });
+ });
});
});
diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.ts b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.ts
index 5150ad88215..36c45a74da3 100644
--- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.ts
+++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.styles.ts
@@ -9,7 +9,11 @@
import { css } from '@emotion/react';
import { UseEuiTheme } from '../../../../services';
-import { mathWithUnits } from '../../../../global_styling';
+import {
+ logicalCSS,
+ logicalTextAlignCSS,
+ mathWithUnits,
+} from '../../../../global_styling';
export const euiDataGridCellOutlineStyles = ({ euiTheme }: UseEuiTheme) => {
const focusColor = euiTheme.colors.primary;
@@ -69,6 +73,7 @@ export const euiDataGridCellOutlineSelectors = (parentSelector = '&') => {
// Utils
const selectors = (...args: string[]) => [...args].join(', ');
const is = (selectors: string) => `${parentSelector}:is(${selectors})`;
+ const not = (selectors: string) => `${parentSelector}:not(${selectors})`;
const hoverNot = (selectors: string) =>
`${parentSelector}:hover:not(${selectors})`;
const _ = (selectors: string) => `${parentSelector}${selectors}`;
@@ -90,6 +95,7 @@ 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
focusTrapped: _(isEntered),
+ hideActions: not(selectors(hover, focusWithin, headerActionsOpen)),
},
};
};
@@ -113,6 +119,44 @@ export const euiDataGridRowCellStyles = (euiThemeContext: UseEuiTheme) => {
${outlineSelectors.focusTrapped} {
${cellOutline.hoverStyles}
}
+
+ /* Hack to allow focus trap to still stretch to full row height on defined heights */
+ & > [data-focus-lock-disabled] {
+ ${logicalCSS('height', '100%')}
+ }
+
+ &:where(.euiDataGridRowCell--numeric, .euiDataGridRowCell--currency) {
+ ${logicalTextAlignCSS('right')}
+ }
+
+ &:where(.euiDataGridRowCell--uppercase) {
+ text-transform: uppercase;
+ }
+
+ &:where(.euiDataGridRowCell--lowercase) {
+ text-transform: lowercase;
+ }
+
+ &:where(.euiDataGridRowCell--capitalize) {
+ text-transform: capitalize;
+ }
`,
+
+ content: {
+ euiDataGridRowCell__content: css`
+ overflow: hidden;
+ `,
+ controlColumn: css`
+ ${logicalCSS('max-height', '100%')}
+ display: flex;
+ align-items: center;
+ `,
+ autoHeight: css`
+ ${logicalCSS('height', 'auto')}
+ `,
+ defaultHeight: css`
+ ${logicalCSS('height', '100%')}
+ `,
+ },
};
};
diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx
index 4f0d3e6793a..b8fcfe6d774 100644
--- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx
@@ -13,6 +13,7 @@ import { render } from '../../../../test/rtl';
import { RowHeightUtils } from '../../utils/__mocks__/row_heights';
import { mockFocusContext } from '../../utils/__mocks__/focus_context';
import { DataGridFocusContext } from '../../utils/focus';
+import type { EuiDataGridProps } from '../../data_grid_types';
import { EuiDataGridCell } from './data_grid_cell';
@@ -104,6 +105,61 @@ describe('EuiDataGridCell', () => {
expect(mockPopoverContext.closeCellPopover).toHaveBeenCalledTimes(1);
});
+ describe('setCellProps', () => {
+ it('correctly merges props that also have EUI values', () => {
+ const RenderCellValue: EuiDataGridProps['renderCellValue'] = ({
+ setCellProps,
+ }) => {
+ useEffect(() => {
+ setCellProps({
+ style: { backgroundColor: 'black' },
+ css: { color: 'white' },
+ 'data-test-subj': 'test',
+ className: 'helloWorld',
+ });
+ }, [setCellProps]);
+ return 'cell render';
+ };
+
+ const { getByTestSubject } = render(
+
+ );
+
+ const cell = getByTestSubject('dataGridRowCell test'); // should have merged `data-test-subj` correctly
+ expect(cell).toHaveClass('euiDataGridRowCell helloWorld'); // should have merged `className` correctly
+ expect(cell).toHaveStyle('background-color: rgb(0, 0, 0)'); // should have merged `style` correctly
+ expect(cell).toHaveStyle('color: rgb(255, 255, 255)'); // should have applied consumer `css`
+ expect(cell.className).toMatch(/css-[\w\d]+-euiDataGridRowCell/); // should not have overridden EUI `css`
+ });
+
+ it('does not allow overriding certain EUI props/values', () => {
+ const RenderCellValue: EuiDataGridProps['renderCellValue'] = ({
+ setCellProps,
+ }) => {
+ useEffect(() => {
+ setCellProps({
+ // @ts-expect-error - deliberately passing omitted props
+ role: 'ignored',
+ tabIndex: 2,
+ 'aria-rowindex': 99,
+ 'data-gridcell-visible-row-index': -200,
+ });
+ }, [setCellProps]);
+ return 'cell render';
+ };
+
+ const { container } = render(
+
+ );
+
+ const cell = container.firstElementChild;
+ expect(cell).toHaveAttribute('role', 'gridcell');
+ expect(cell).toHaveAttribute('tabIndex', '-1');
+ expect(cell).toHaveAttribute('aria-rowindex', '1');
+ expect(cell).toHaveAttribute('data-gridcell-visible-row-index', '0');
+ });
+ });
+
describe('shouldComponentUpdate', () => {
let shouldComponentUpdate: jest.SpyInstance;
let component: ReactWrapper;
@@ -489,7 +545,9 @@ describe('EuiDataGridCell', () => {
});
it('allows overriding column.isExpandable with setCellProps({ isExpandable })', () => {
- const RenderCellValue = ({ setCellProps }: any) => {
+ const RenderCellValue: EuiDataGridProps['renderCellValue'] = ({
+ setCellProps,
+ }) => {
useEffect(() => {
setCellProps({ isExpandable: false });
}, [setCellProps]);
diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx
index 8e8c29ee203..7aee6c986a7 100644
--- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx
@@ -16,15 +16,17 @@ import React, {
KeyboardEvent,
memo,
useMemo,
+ forwardRef,
MutableRefObject,
ReactElement,
+ HTMLAttributes,
} from 'react';
import { createPortal } from 'react-dom';
import { IS_JEST_ENVIRONMENT } from '../../../../utils';
-import { keys, RenderWithEuiStylesMemoizer } from '../../../../services';
+import { keys, useEuiMemoizedStyles } from '../../../../services';
import { EuiScreenReaderOnly } from '../../../accessibility';
-import { EuiI18n } from '../../../i18n';
+import { useEuiI18n } from '../../../i18n';
import { EuiTextBlockTruncate } from '../../../text_truncate';
import { hasResizeObserver } from '../../../observer/resize_observer/resize_observer';
@@ -51,13 +53,8 @@ const EuiDataGridCellContent: FunctionComponent<
EuiDataGridCellValueProps & {
setCellProps: EuiDataGridCellValueElementProps['setCellProps'];
setCellContentsRef: (ref: HTMLDivElement | null) => void;
- showCellActions: boolean;
isExpanded: boolean;
- onExpandClick: () => void;
- popoverAnchorRef: MutableRefObject;
isControlColumn: boolean;
- isFocused: boolean;
- ariaRowIndex: number;
rowHeight?: EuiDataGridRowHeightOption;
}
> = memo(
@@ -68,14 +65,9 @@ const EuiDataGridCellContent: FunctionComponent<
setCellContentsRef,
rowIndex,
colIndex,
- ariaRowIndex,
rowHeight,
rowHeightUtils,
isControlColumn,
- isFocused,
- showCellActions,
- onExpandClick,
- popoverAnchorRef,
...rest
}) => {
// React is more permissive than the TS types indicate
@@ -100,65 +92,51 @@ const EuiDataGridCellContent: FunctionComponent<
[cellHeightType, isControlColumn]
);
+ const styles = useEuiMemoizedStyles(euiDataGridRowCellStyles);
+ const cssStyles = [
+ styles.content.euiDataGridRowCell__content,
+ ...(isControlColumn
+ ? [
+ // Control column cells should not be vertically centered (defaultHeight) except
+ // on single rows. They should be top-aligned for auto and lineCount heights
+ styles.content.controlColumn,
+ cellHeightType === 'default'
+ ? styles.content.defaultHeight
+ : styles.content.autoHeight,
+ ]
+ : [
+ // Regular data cells should always inherit height from the row wrapper,
+ // except for auto height
+ cellHeightType === 'auto'
+ ? styles.content.autoHeight
+ : styles.content.defaultHeight,
+ ]),
+ ];
+
return (
- <>
-
+
-
-
-
-
-
-
-
- {'- '}
-
- {showCellActions && (
- <>
- {'. '}
-
- >
- )}
-
-
-
- {showCellActions && (
-
- )}
- >
+
+
);
}
);
@@ -610,58 +588,61 @@ export class EuiDataGridCell extends Component<
return (
-
- {(stylesMemoizer) => {
- const styles = stylesMemoizer(euiDataGridRowCellStyles);
- const cssStyles = [styles.euiDataGridRowCell, cellProps?.css];
- return (
-
-
-
-
-
- );
- }}
-
+
+
+
+
+
+ {this.state.isFocused && (
+
+ )}
+
+ {showCellActions && (
+
+ )}
+
);
}
@@ -699,3 +680,59 @@ const RenderTruncatedCellContent: FunctionComponent<{
);
});
RenderTruncatedCellContent.displayName = 'RenderTruncatedCellContent';
+
+/**
+ * Function component utilities for easier hook usage
+ */
+
+const GridCellDiv = memo(
+ forwardRef<
+ HTMLDivElement,
+ HTMLAttributes & {
+ columnId: string;
+ columnIndex: number;
+ rowIndex: number;
+ visibleRowIndex: number;
+ }
+ >(({ columnId, columnIndex, rowIndex, visibleRowIndex, ...props }, ref) => {
+ const styles = useEuiMemoizedStyles(euiDataGridRowCellStyles);
+ return (
+
+ );
+ })
+);
+GridCellDiv.displayName = 'GridCellDiv';
+
+const CellScreenReaderDescription: FunctionComponent<{
+ columnName: string;
+ columnIndex: number;
+ rowIndex: number;
+ canExpandCell: boolean;
+}> = memo(({ columnName, columnIndex, rowIndex, canExpandCell }) => {
+ const cellPosition = useEuiI18n(
+ 'euiDataGridCell.position',
+ '{columnName}, column {columnIndex}, row {rowIndex}',
+ { columnName, columnIndex, rowIndex }
+ );
+ const enterKeyPrompt = useEuiI18n(
+ 'euiDataGridCell.expansionEnterPrompt',
+ 'Press the Enter key to expand this cell.'
+ );
+
+ return (
+
+ {` - ${cellPosition}${canExpandCell ? `. ${enterKeyPrompt}` : ''}`}
+
+ );
+});
+CellScreenReaderDescription.displayName = 'CellScreenReaderDescription';
diff --git a/packages/eui/src/components/datagrid/body/cell/focus_utils.test.tsx b/packages/eui/src/components/datagrid/body/cell/focus_utils.test.tsx
index 0373c6429d5..609efff316d 100644
--- a/packages/eui/src/components/datagrid/body/cell/focus_utils.test.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/focus_utils.test.tsx
@@ -143,14 +143,8 @@ describe('FocusTrappedChildren', () => {
data-focus-lock-disabled="disabled"
>
-
diff --git a/packages/eui/src/components/datagrid/body/cell/focus_utils.tsx b/packages/eui/src/components/datagrid/body/cell/focus_utils.tsx
index 32e46ba9c82..9b5600cbbe5 100644
--- a/packages/eui/src/components/datagrid/body/cell/focus_utils.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/focus_utils.tsx
@@ -14,12 +14,11 @@ import React, {
useMemo,
} from 'react';
import { FocusableElement, tabbable } from 'tabbable';
+import classNames from 'classnames';
-import { keys } from '../../../../services';
-import { useGeneratedHtmlId } from '../../../../services/accessibility';
+import { keys, useGeneratedHtmlId } from '../../../../services';
import { isDOMNode } from '../../../../utils';
import { EuiFocusTrap } from '../../../focus_trap';
-import { EuiScreenReaderOnly } from '../../../accessibility';
import { EuiI18n } from '../../../i18n';
/**
@@ -91,14 +90,8 @@ export const FocusTrappedChildren: FunctionComponent<
const [isCellEntered, setIsCellEntered] = useState(false);
const [isExited, setExited] = useState(false);
- const keyboardHintAriaId = useGeneratedHtmlId({
- prefix: 'euiDataGridCellHeader',
- suffix: 'keyboardHint',
- });
-
- const exitedHintAriaId = useGeneratedHtmlId({
- prefix: 'euiDataGridCellHeader',
- suffix: 'exited',
+ const ariaDescribedById = useGeneratedHtmlId({
+ suffix: 'focusTrapHint',
});
// direct DOM manipulation as workaround to attach required hints
@@ -107,9 +100,17 @@ export const FocusTrappedChildren: FunctionComponent<
cellEl.setAttribute(
'aria-describedby',
- `${currentAriaDescribedbyId} ${exitedHintAriaId} ${keyboardHintAriaId} `
+ classNames(currentAriaDescribedbyId, ariaDescribedById)
);
- }, [cellEl, keyboardHintAriaId, exitedHintAriaId]);
+
+ return () => {
+ if (currentAriaDescribedbyId) {
+ cellEl.setAttribute('aria-descibedby', currentAriaDescribedbyId);
+ } else {
+ cellEl.removeAttribute('aria-describedby');
+ }
+ };
+ }, [cellEl, ariaDescribedById]);
useEffect(() => {
if (isCellEntered) {
@@ -172,37 +173,31 @@ export const FocusTrappedChildren: FunctionComponent<
>
{children}
-
- {/**
- * Hints use aria-hidden to prevent them from being read as regular content.
- * They are still read in JAWS and NVDA via the linking with aria-describedby.
- * VoiceOver does generally not read the column on re-focus after exiting a cell,
- * which mean the exited hint is not read.
- * VoiceOver does react to aria-live (without aria-hidden) but that would causes
- * duplicate output in JAWS/NVDA (reading content & live announcement).
- * Optimizing for Windows screen readers as they have a larger usages.
- */}
-
- {isExited && (
-
- )}
-
-
-
-
- {!isCellEntered && (
-
- )}
-
-
+ {/**
+ * Hints use `hidden` to prevent them from being read by screen readers as regular content.
+ * They are still read in JAWS and NVDA via the linking with aria-describedby.
+ * VoiceOver does generally not read the column on re-focus after exiting a cell,
+ * which mean the exited hint is not read.
+ * VoiceOver does react to aria-live (without aria-hidden) but that would causes
+ * duplicate output in JAWS/NVDA (reading content & live announcement).
+ * Optimizing for Windows screen readers as they have a larger usages.
+ */}
+
+ {isExited && (
+
+ )}
+ {!isCellEntered && (
+
+ )}
+
);
};
diff --git a/packages/eui/src/components/datagrid/body/footer/_data_grid_footer_row.scss b/packages/eui/src/components/datagrid/body/footer/_data_grid_footer_row.scss
deleted file mode 100644
index 568b157ab2f..00000000000
--- a/packages/eui/src/components/datagrid/body/footer/_data_grid_footer_row.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-@include euiDataGridFooterCell {
- flex: 0 0 auto;
- position: relative;
- font-weight: $euiFontWeightBold;
-}
diff --git a/packages/eui/src/components/datagrid/body/footer/data_grid_footer.styles.ts b/packages/eui/src/components/datagrid/body/footer/data_grid_footer.styles.ts
index ac38024056c..41e964baaa8 100644
--- a/packages/eui/src/components/datagrid/body/footer/data_grid_footer.styles.ts
+++ b/packages/eui/src/components/datagrid/body/footer/data_grid_footer.styles.ts
@@ -42,5 +42,10 @@ export const euiDataGridFooterStyles = (euiThemeContext: UseEuiTheme) => {
background-color: ${euiTheme.colors.lightestShade};
}
`,
+
+ euiDataGridFooterCell: css`
+ flex: 0 0 auto;
+ font-weight: ${euiTheme.font.weight.bold};
+ `,
};
};
diff --git a/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.test.tsx b/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.test.tsx
index 19052cee4d1..d84d83c640c 100644
--- a/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.test.tsx
+++ b/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.test.tsx
@@ -35,7 +35,7 @@ describe('EuiDataGridFooterRow', () => {
>
`);
diff --git a/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.tsx b/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.tsx
index 99f76a3bd2f..30b01cfcf02 100644
--- a/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.tsx
+++ b/packages/eui/src/components/datagrid/body/footer/data_grid_footer_row.tsx
@@ -56,6 +56,7 @@ const EuiDataGridFooterRow = memo(
const popoverContext = useContext(DataGridCellPopoverContext);
const sharedCellProps = {
+ css: styles.euiDataGridFooterCell,
rowIndex,
visibleRowIndex,
interactiveCellId,
diff --git a/packages/eui/src/components/datagrid/body/header/__snapshots__/data_grid_header_cell.test.tsx.snap b/packages/eui/src/components/datagrid/body/header/__snapshots__/data_grid_header_cell.test.tsx.snap
index 62ff1f9070b..6fc8ed0541a 100644
--- a/packages/eui/src/components/datagrid/body/header/__snapshots__/data_grid_header_cell.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/body/header/__snapshots__/data_grid_header_cell.test.tsx.snap
@@ -14,34 +14,32 @@ exports[`EuiDataGridHeaderCell renders 1`] = `
tabindex="-1"
>
diff --git a/packages/eui/src/components/datagrid/body/header/_data_grid_column_resizer.scss b/packages/eui/src/components/datagrid/body/header/_data_grid_column_resizer.scss
deleted file mode 100644
index 28c836106f0..00000000000
--- a/packages/eui/src/components/datagrid/body/header/_data_grid_column_resizer.scss
+++ /dev/null
@@ -1,48 +0,0 @@
-// Resizer straddles the column border and is an invisible hitzone for dragging
-.euiDataGridColumnResizer {
- position: absolute;
- top: 0;
- right: -$euiSizeS;
- height: 100%;
- width: $euiSize;
- cursor: ew-resize;
- opacity: 0;
- z-index: 2; // Needs to be a level above the cells themselves in case of overlaps
-
- // Center a vertical line within the button above
- &::after {
- content: '';
- position: absolute;
- left: $euiSizeS - 1px;
- top: 0;
- bottom: 0;
- width: $euiDataGridColumnResizerWidth;
- background-color: $euiColorPrimary;
- }
-
- &:hover,
- &:active {
- opacity: 1;
-
- ~ .euiDataGridHeaderCell__content {
- user-select: none;
- }
- }
-}
-
-// This is important. Because the resizer sits in the negative space to the right of the column
-// it can cause the full grid to be a few pixels longer than it actually is. So for the last one
-// we don't use negative positioning and the borders from the cell will match the container.
-@include euiDataGridHeaderCell {
- &:last-child {
- .euiDataGridColumnResizer {
- right: 0;
- width: $euiSize / 2;
-
- &::after {
- left: auto;
- right: 0;
- }
- }
- }
-}
diff --git a/packages/eui/src/components/datagrid/body/header/_data_grid_header_row.scss b/packages/eui/src/components/datagrid/body/header/_data_grid_header_row.scss
deleted file mode 100644
index 513fadd5ee7..00000000000
--- a/packages/eui/src/components/datagrid/body/header/_data_grid_header_row.scss
+++ /dev/null
@@ -1,94 +0,0 @@
-@include euiDataGridHeaderCell {
- position: relative;
- display: flex;
- flex: 0 0 auto;
- align-items: center;
- font-weight: $euiFontWeightBold;
-
- // Workaround for focus trap
- & > [data-focus-lock-disabled] {
- display: flex;
- align-items: center;
- gap: $euiSizeXS;
- width: 100%;
- }
-
- .euiDataGridHeaderCell__content {
- flex-grow: 1; // ensures content stretches and allows for manual layout styles to apply
- }
-
- // We only truncate if the cell is not a control column.
- &:not(.euiDataGridHeaderCell--controlColumn) {
- .euiDataGridHeaderCell__button {
- position: relative;
- display: flex;
- align-items: center;
- gap: $euiSizeXS;
- width: 100%;
- border-radius: $euiBorderRadiusSmall;
- font-weight: $euiFontWeightBold;
- outline: none;
-
- &:focus-visible {
- outline: none;
- }
- }
-
- [data-focus-lock-disabled='false'] .euiDataGridHeaderCell__button {
- @include euiFocusRing;
- color: $euiFocusRingColor;
- }
-
- .euiDataGridHeaderCell__content {
- @include euiTextTruncate;
-
- text-align: left; // overwrites inherited 'center' styles from button
- }
-
- .euiDataGridHeaderCell__sortingArrow {
- flex: 0 0 auto; // Ensure icon doesn't shrink
- }
-
- .euiDataGridHeaderCell__icon {
- flex: 0 0 auto; // Ensure icon doesn't shrink
- margin-left: auto; // Aligns the icon to the right
- // Center the icon
- display: flex;
- align-items: center;
- justify-content: center;
- width: 0;
- height: $euiSize;
- overflow: hidden;
- opacity: 0;
- transition: width $euiAnimSpeedFast ease-in, opacity $euiAnimSpeedSlow ease-in;
- }
-
- &:focus-within,
- &:hover,
- .euiPopover-isOpen {
- .euiDataGridHeaderCell__button {
- padding: $euiSizeXS;
- // balance out additional button target size in header height, prevents increased header cell height
- margin-block: -$euiSizeXS;
- }
-
- .euiDataGridHeaderCell__icon {
- width: $euiSize;
- opacity: 1;
- }
- }
- }
-
- // Align numeric and currency schemas to the right
- &.euiDataGridHeaderCell--numeric,
- &.euiDataGridHeaderCell--currency {
- .euiDataGridHeaderCell__content {
- text-align: right;
- }
- }
-}
-
-.euiDataGridHeader__action--selected {
- // stylelint-disable-next-line declaration-no-important
- font-weight: $euiFontWeightBold !important;
-}
diff --git a/packages/eui/src/components/datagrid/body/header/column_actions.test.tsx b/packages/eui/src/components/datagrid/body/header/column_actions.test.tsx
index eb6585ad060..854b87bab59 100644
--- a/packages/eui/src/components/datagrid/body/header/column_actions.test.tsx
+++ b/packages/eui/src/components/datagrid/body/header/column_actions.test.tsx
@@ -314,7 +314,6 @@ describe('getColumnActions', () => {
it('renders a "Sort A-Z" item', () => {
expect(sortAsc).toMatchInlineSnapshot(`
{
- "className": "",
"color": "text",
"iconType": "sortUp",
"isDisabled": false,
@@ -339,7 +338,6 @@ describe('getColumnActions', () => {
it('renders a "Sort Z-A" item', () => {
expect(sortDesc).toMatchInlineSnapshot(`
{
- "className": "",
"color": "text",
"iconType": "sortDown",
"isDisabled": false,
@@ -378,10 +376,21 @@ describe('getColumnActions', () => {
});
const sortAsc = items[1];
- it('renders sortAsc as selected', () => {
- expect(sortAsc.className).toEqual(
- 'euiDataGridHeader__action--selected'
- );
+ it('changes label to unsort', () => {
+ expect(sortAsc.label).toMatchInlineSnapshot(`
+ ,
+ }
+ }
+ />
+ `);
});
it('unsets the current sort if sortAsc is clicked again', () => {
@@ -398,10 +407,21 @@ describe('getColumnActions', () => {
const sortAsc = items[1];
const sortDesc = items[2];
- it('renders sortDesc as selected', () => {
- expect(sortDesc.className).toEqual(
- 'euiDataGridHeader__action--selected'
- );
+ it('changes label to unsort', () => {
+ expect(sortDesc.label).toMatchInlineSnapshot(`
+ ,
+ }
+ }
+ />
+ `);
});
it('sets a new sort if the direction is changed', () => {
diff --git a/packages/eui/src/components/datagrid/body/header/column_actions.tsx b/packages/eui/src/components/datagrid/body/header/column_actions.tsx
index cd702168fe5..400a94c80ef 100644
--- a/packages/eui/src/components/datagrid/body/header/column_actions.tsx
+++ b/packages/eui/src/components/datagrid/body/header/column_actions.tsx
@@ -275,8 +275,17 @@ export const getSortColumnActions = ({
sortBy('asc');
};
+ const isSorted =
+ sortingIdx >= 0 && sorting.columns[sortingIdx].direction === 'asc';
+
const action = {
- label: (
+ label: isSorted ? (
+
+ ) : (
= 0 && sorting.columns[sortingIdx].direction === 'asc'
- ? 'euiDataGridHeader__action--selected'
- : '',
iconType: 'sortUp',
size: 'xs',
color: 'text',
@@ -306,8 +311,17 @@ export const getSortColumnActions = ({
sortBy('desc');
};
+ const isSorted =
+ sortingIdx >= 0 && sorting.columns[sortingIdx].direction === 'desc';
+
const action = {
- label: (
+ label: isSorted ? (
+
+ ) : (
= 0 && sorting.columns[sortingIdx].direction === 'desc'
- ? 'euiDataGridHeader__action--selected'
- : '',
iconType: 'sortDown',
size: 'xs',
color: 'text',
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.styles.ts b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.styles.ts
new file mode 100644
index 00000000000..840c371787f
--- /dev/null
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.styles.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { css } from '@emotion/react';
+
+import { UseEuiTheme } from '../../../../services';
+import { logicalCSS, mathWithUnits } from '../../../../global_styling';
+
+// Resizer straddles the column border and is an invisible hitzone for dragging
+export const euiDataGridColumnResizerStyles = (
+ euiThemeContext: UseEuiTheme
+) => {
+ const { euiTheme } = euiThemeContext;
+
+ const clickableWidth = euiTheme.size.base;
+ const positionOffset = mathWithUnits(clickableWidth, (x) => x / -2);
+
+ const indicatorWidth = mathWithUnits(
+ [euiTheme.border.width.thin, euiTheme.border.width.thick],
+ (x, y) => x + y
+ ); // Odd number because it straddles a border
+ const indicatorOffset = `-${euiTheme.border.width.thin}`;
+
+ return {
+ euiDataGridColumnResizer: css`
+ z-index: 2; /* Needs to be a level above the cells themselves in case of overlaps */
+ position: absolute;
+ ${logicalCSS('vertical', 0)}
+ ${logicalCSS('right', positionOffset)}
+ cursor: ew-resize;
+ opacity: 0;
+
+ &:hover,
+ &:active {
+ opacity: 1;
+ }
+
+ /* Center a vertical line within the button above */
+ &::after {
+ content: '';
+ position: absolute;
+ ${logicalCSS('vertical', 0)}
+ ${logicalCSS('left', positionOffset)}
+ ${logicalCSS('margin-left', indicatorOffset)}
+ ${logicalCSS('width', indicatorWidth)}
+ background-color: ${euiTheme.colors.primary};
+ }
+
+ /* Because the resizer sits in the negative space to the right of the column,
+ * it can cause the full grid to be a few pixels longer than it actually is.
+ * So for the last cell, we don't use negative positioning and the borders from
+ * the cell will match the container. */
+ .euiDataGridHeaderCell:last-child & {
+ ${logicalCSS('right', 0)}
+ ${logicalCSS('width', euiTheme.size.s)}
+
+ &::after {
+ ${logicalCSS('left', 'auto')}
+ ${logicalCSS('right', 0)}
+ }
+ }
+ `,
+ isDragging: css`
+ opacity: 1;
+ `,
+ };
+};
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.test.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.test.tsx
index 494db0ad8c7..a9c77fbaa1c 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.test.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.test.tsx
@@ -7,7 +7,8 @@
*/
import React from 'react';
-import { shallow } from 'enzyme';
+import { act } from '@testing-library/react';
+import { render } from '../../../../test/rtl';
import { EuiDataGridColumnResizer } from './data_grid_column_resizer';
@@ -18,57 +19,94 @@ describe('EuiDataGridHeaderResizer', () => {
setColumnWidth: jest.fn(),
};
- const component = shallow( );
- const componentMethods = component.instance() as EuiDataGridColumnResizer;
-
it('renders', () => {
- expect(component).toMatchInlineSnapshot(`
+ const { container } = render( );
+
+ expect(container.firstChild).toMatchInlineSnapshot(`
`);
});
- describe('on mouse down', () => {
- it('saves the current mouse horizontal position and adds mouse move & up listeners', () => {
- const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
- component.simulate('mouseDown', {
- pageX: 100,
- preventDefault: jest.fn(),
- });
+ describe('mouse events', () => {
+ const mouseEvent = {
+ preventDefault: () => {},
+ } as React.MouseEvent;
- expect(component.state('initialX')).toEqual(100);
- expect(addEventListenerSpy).toHaveBeenCalledTimes(3);
- });
- });
+ // Using a ref to reach into class methods/state directly -
+ // mocking mouse events in jsdom is too much of a headache
+ let classRef: EuiDataGridColumnResizer;
+ const setRef = (ref: EuiDataGridColumnResizer) => {
+ classRef = ref;
+ };
- describe('on mouse move', () => {
- it('does not allow an offset that would go under the mininum column width', () => {
- componentMethods.onMouseMove({ pageX: 0 });
- expect(component.state('offset')).toEqual(-10);
+ describe('on mouse down', () => {
+ it('adds mouse move & up listeners', () => {
+ render( );
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
+
+ act(() => classRef.onMouseDown({ ...mouseEvent, pageX: 100 }));
+ expect(classRef.state.initialX).toEqual(100);
+
+ const anyFn = expect.any(Function);
+ expect(addEventListenerSpy).toHaveBeenCalledWith('mouseup', anyFn);
+ expect(addEventListenerSpy).toHaveBeenCalledWith('mousemove', anyFn);
+ expect(addEventListenerSpy).toHaveBeenCalledWith('blur', anyFn);
+ });
});
- it('sets offset state to the difference of the moved pageX', () => {
- componentMethods.onMouseMove({ pageX: 200 });
- expect(component.state('offset')).toEqual(100);
+ describe('on mouse move', () => {
+ it('does not allow an offset that would go under the mininum column width', () => {
+ const { getByTestSubject } = render(
+
+ );
+
+ act(() => classRef.onMouseDown({ ...mouseEvent, pageX: 100 }));
+ act(() => classRef.onMouseMove({ pageX: 0 }));
+
+ expect(classRef.state.offset).toEqual(-10);
+ expect(getByTestSubject('dataGridColumnResizer')).toHaveStyle(
+ 'margin-inline-end: 10px'
+ );
+ });
+
+ it('sets offset state to the difference of the moved pageX', () => {
+ const { getByTestSubject } = render(
+
+ );
+
+ act(() => classRef.onMouseDown({ ...mouseEvent, pageX: 100 }));
+ act(() => classRef.onMouseMove({ pageX: 200 }));
+
+ expect(classRef.state.offset).toEqual(100);
+ expect(getByTestSubject('dataGridColumnResizer')).toHaveStyle(
+ 'margin-inline-end: -100px'
+ );
+ });
});
- });
- describe('on mouse up', () => {
- it('calls setColumnWidth, reset offset, and removes event listeners', () => {
- const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
- componentMethods.onMouseUp();
+ describe('on mouse up', () => {
+ it('calls setColumnWidth, reset offset, and removes event listeners', () => {
+ render( );
+ const removeEventListenerSpy = jest.spyOn(
+ window,
+ 'removeEventListener'
+ );
+
+ act(() => classRef.onMouseDown({ ...mouseEvent, pageX: 100 }));
+ act(() => classRef.onMouseMove({ pageX: 200 }));
+ act(() => classRef.onMouseUp());
- expect(props.setColumnWidth).toHaveBeenCalledWith('someColumn', 150);
- expect(component.state('offset')).toEqual(0);
- expect(removeEventListenerSpy).toHaveBeenCalledTimes(3);
+ expect(props.setColumnWidth).toHaveBeenCalledWith('someColumn', 150);
+ expect(classRef.state.offset).toEqual(0);
+
+ const anyFn = expect.any(Function);
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('mouseup', anyFn);
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('mousemove', anyFn);
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('blur', anyFn);
+ });
});
});
});
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.tsx
index d8577e35e39..158e5ea49a4 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_column_resizer.tsx
@@ -7,10 +7,13 @@
*/
import React, { Component } from 'react';
+import { RenderWithEuiStylesMemoizer } from '../../../../services';
+import { logicalStyle } from '../../../../global_styling';
import {
EuiDataGridColumnResizerProps,
EuiDataGridColumnResizerState,
} from '../../data_grid_types';
+import { euiDataGridColumnResizerStyles } from './data_grid_column_resizer.styles';
const MINIMUM_COLUMN_WIDTH = 40;
@@ -65,12 +68,28 @@ export class EuiDataGridColumnResizer extends Component<
const { offset } = this.state;
return (
-
+
+ {(stylesMemoizer) => {
+ const styles = stylesMemoizer(euiDataGridColumnResizerStyles);
+ const cssStyles = [
+ styles.euiDataGridColumnResizer,
+ offset && styles.isDragging,
+ ];
+ return (
+
+ );
+ }}
+
);
}
}
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.test.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.test.tsx
index 2d5accb778b..087e56a4274 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.test.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.test.tsx
@@ -7,7 +7,7 @@
*/
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '../../../../test/rtl';
import { EuiDataGridControlHeaderCell } from './data_grid_control_header_cell';
@@ -23,20 +23,45 @@ describe('EuiDataGridControlHeaderCell', () => {
};
it('renders', () => {
- const component = shallow( );
- expect(component).toMatchInlineSnapshot(`
- );
+ expect(container.firstChild).toMatchInlineSnapshot(`
+
+
-
+
+
+ Press the Enter key to interact with this cell's contents.
+
-
+
+
`);
});
});
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.tsx
index f6bc746cbe9..6971947c0b9 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_control_header_cell.tsx
@@ -32,9 +32,7 @@ export const EuiDataGridControlHeaderCell: FunctionComponent
-
-
-
+
);
});
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.styles.ts b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.styles.ts
new file mode 100644
index 00000000000..b3efb1a7614
--- /dev/null
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.styles.ts
@@ -0,0 +1,65 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { css } from '@emotion/react';
+
+import { UseEuiTheme } from '../../../../services';
+import {
+ euiCanAnimate,
+ euiTextTruncate,
+ logicalCSS,
+ logicalTextAlignCSS,
+} from '../../../../global_styling';
+import { euiDataGridCellOutlineSelectors } from '../cell/data_grid_cell.styles';
+
+/**
+ * Styles only applied to data header cell content, not control header cells
+ */
+export const euiDataGridHeaderCellStyles = (euiThemeContext: UseEuiTheme) => {
+ const { euiTheme } = euiThemeContext;
+ const { header } = euiDataGridCellOutlineSelectors('.euiDataGridHeaderCell');
+
+ return {
+ euiDataGridHeaderCell__content: css`
+ flex-grow: 1; /* ensures content stretches and allows for manual layout styles to apply */
+ ${euiTextTruncate()}
+ `,
+ // Overwrite inherited 'center' styles from
+ left: css`
+ ${logicalTextAlignCSS('left')}
+ `,
+ // Numeric and currency schemas are aligned to the right
+ right: css`
+ ${logicalTextAlignCSS('right')}
+ `,
+
+ euiDataGridHeaderCell__popover: css`
+ /* Align the button to the right */
+ ${logicalCSS('margin-left', 'auto')}
+ /* Remove inline struts from EuiButtonIcon */
+ line-height: 0;
+ `,
+ euiDataGridHeaderCell__button: css`
+ overflow: hidden;
+
+ ${header.hideActions} & {
+ ${logicalCSS('width', 0)}
+ opacity: 0;
+ }
+
+ ${euiCanAnimate} {
+ transition: inline-size ${euiTheme.animation.fast} ease-in,
+ opacity ${euiTheme.animation.slow} ease-in;
+
+ /* Unset EuiButtonIcon animations */
+ transform: none !important; /* stylelint-disable-line declaration-no-important */
+ animation: none !important; /* stylelint-disable-line declaration-no-important */
+ }
+ `,
+ };
+};
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.tsx
index 477490d0bde..298ea00ed42 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell.tsx
@@ -10,47 +10,34 @@ import classnames from 'classnames';
import React, {
AriaAttributes,
FunctionComponent,
- PropsWithChildren,
- ReactNode,
useContext,
useState,
useRef,
useCallback,
useMemo,
memo,
- HTMLAttributes,
} from 'react';
import { tabbable, FocusableElement } from 'tabbable';
-import { keys, useEuiMemoizedStyles } from '../../../../services';
-import { useGeneratedHtmlId } from '../../../../services/accessibility';
+import {
+ keys,
+ useGeneratedHtmlId,
+ useEuiMemoizedStyles,
+} from '../../../../services';
import { EuiI18n, useEuiI18n } from '../../../i18n';
import { EuiIcon } from '../../../icon';
import { EuiListGroup } from '../../../list_group';
import { EuiPopover } from '../../../popover';
-import { _emptyHoverStyles } from '../../../button/button_icon/button_icon.styles';
+import { EuiButtonIcon } from '../../../button';
+
import { DataGridFocusContext } from '../../utils/focus';
import {
EuiDataGridHeaderCellProps,
EuiDataGridSorting,
} from '../../data_grid_types';
-
import { getColumnActions } from './column_actions';
import { EuiDataGridColumnResizer } from './data_grid_column_resizer';
import { EuiDataGridHeaderCellWrapper } from './data_grid_header_cell_wrapper';
-
-const CellContent: FunctionComponent<
- PropsWithChildren &
- HTMLAttributes & { title: string; arrow?: ReactNode }
-> = ({ children, title, arrow, ...rest }) => {
- return (
- <>
-
- {children}
-
- {arrow}
- >
- );
-};
+import { euiDataGridHeaderCellStyles } from './data_grid_header_cell.styles';
export const EuiDataGridHeaderCell: FunctionComponent =
memo(
@@ -159,7 +146,13 @@ export const EuiDataGridHeaderCell: FunctionComponent
) : null}
-
+
{children}
-
+
+ {sortingArrow}
{sortingScreenReaderText && (
@@ -200,15 +198,19 @@ export const EuiDataGridHeaderCell: FunctionComponent setIsActionsButtonFocused(true)}
onBlur={() => setIsActionsButtonFocused(false)}
+ tabIndex={0} // Override EuiButtonIcon's conditional tabindex based on aria-hidden
aria-hidden={
hasFocusTrap && !isActionsButtonFocused
? 'true' // prevent the actions button from being read on cell focus
@@ -220,11 +222,7 @@ export const EuiDataGridHeaderCell: FunctionComponent
-
-
-
-
+ />
}
isOpen={isPopoverOpen}
closePopover={closePopover}
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.styles.ts b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.styles.ts
index 5ea2bfc551a..61cbac4c334 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.styles.ts
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.styles.ts
@@ -9,6 +9,7 @@
import { css } from '@emotion/react';
import { UseEuiTheme } from '../../../../services';
+import { logicalCSS } from '../../../../global_styling';
import {
euiDataGridCellOutlineStyles,
@@ -21,12 +22,24 @@ import {
export const euiDataGridHeaderCellWrapperStyles = (
euiThemeContext: UseEuiTheme
) => {
+ const { euiTheme } = euiThemeContext;
const { focusStyles, hoverStyles } =
euiDataGridCellOutlineStyles(euiThemeContext);
const { header: outlineSelectors } = euiDataGridCellOutlineSelectors();
+ const _sharedFlexCss = css`
+ display: flex;
+ align-items: center;
+ gap: ${euiTheme.size.xxs};
+ `;
+
return {
euiDataGridHeaderCell: css`
+ position: relative; /* Needed for cell outline */
+ ${_sharedFlexCss}
+ flex: 0 0 auto;
+ font-weight: ${euiTheme.font.weight.bold};
+
${outlineSelectors.focus} {
${focusStyles}
}
@@ -34,6 +47,12 @@ export const euiDataGridHeaderCellWrapperStyles = (
${outlineSelectors.focusTrapped} {
${hoverStyles}
}
+
+ /* Workaround for focus trap */
+ & > [data-focus-lock-disabled] {
+ ${_sharedFlexCss}
+ ${logicalCSS('width', '100%')}
+ }
`,
};
};
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.test.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.test.tsx
index 268781eb110..12cfcc79d5d 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.test.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_header_cell_wrapper.test.tsx
@@ -121,14 +121,8 @@ describe('EuiDataGridHeaderCellWrapper', () => {
Mock column actions
-
diff --git a/packages/eui/src/components/datagrid/body/header/data_grid_header_row.test.tsx b/packages/eui/src/components/datagrid/body/header/data_grid_header_row.test.tsx
index ebd3998d2b9..1b1048abdf6 100644
--- a/packages/eui/src/components/datagrid/body/header/data_grid_header_row.test.tsx
+++ b/packages/eui/src/components/datagrid/body/header/data_grid_header_row.test.tsx
@@ -64,34 +64,32 @@ describe('EuiDataGridHeaderRow', () => {
tabindex="-1"
>
diff --git a/packages/eui/src/components/datagrid/controls/full_screen_selector.stories.tsx b/packages/eui/src/components/datagrid/controls/full_screen_selector.stories.tsx
index 788669f6074..72008d593af 100644
--- a/packages/eui/src/components/datagrid/controls/full_screen_selector.stories.tsx
+++ b/packages/eui/src/components/datagrid/controls/full_screen_selector.stories.tsx
@@ -7,7 +7,7 @@
*/
import React, { useState } from 'react';
-import { fireEvent, within } from '@storybook/test';
+import { fireEvent, waitFor, within } from '@storybook/test';
import type { Meta, StoryObj, ReactRenderer } from '@storybook/react';
import type { PlayFunctionContext } from '@storybook/csf';
import { LOKI_SELECTORS } from '../../../../.storybook/loki';
@@ -47,7 +47,7 @@ const dataGridProps: EuiDataGridProps = {
export const FullScreenWithHeader: Story = {
tags: ['vrt-only'],
parameters: {
- loki: { chromeSelector: LOKI_SELECTORS.body },
+ loki: { chromeSelector: LOKI_SELECTORS.portal },
},
render: () => (
<>
@@ -59,6 +59,7 @@ export const FullScreenWithHeader: Story = {
),
play: async ({ canvasElement }: PlayFunctionContext) => {
const canvas = within(canvasElement);
+ await waitFor(() => canvas.getByLabelText('Enter fullscreen'));
await fireEvent.click(canvas.getByLabelText('Enter fullscreen'));
},
};
diff --git a/packages/eui/src/components/datagrid/data_grid.a11y.tsx b/packages/eui/src/components/datagrid/data_grid.a11y.tsx
index 925faff7ef8..5580f3cef82 100644
--- a/packages/eui/src/components/datagrid/data_grid.a11y.tsx
+++ b/packages/eui/src/components/datagrid/data_grid.a11y.tsx
@@ -255,6 +255,7 @@ describe('EuiDataGrid', () => {
it('has zero violations on sort and when the columns sorting menu is open', () => {
cy.get('.euiDataGridHeaderCell').last().realHover();
+ cy.wait(200); // Wait for transition
cy.get('button.euiDataGridHeaderCell__button').last().realClick();
cy.get('button.euiListGroupItem__button')
.contains('Sort Alma to Debian')
diff --git a/packages/eui/src/components/datagrid/data_grid.stories.tsx b/packages/eui/src/components/datagrid/data_grid.stories.tsx
index 1c0ee36939d..b8bdd9bce64 100644
--- a/packages/eui/src/components/datagrid/data_grid.stories.tsx
+++ b/packages/eui/src/components/datagrid/data_grid.stories.tsx
@@ -7,9 +7,11 @@
*/
import React, { useRef, useEffect } from 'react';
-import type { Meta, StoryObj } from '@storybook/react';
-
+import type { Meta, StoryObj, ReactRenderer } from '@storybook/react';
+import type { PlayFunctionContext } from '@storybook/csf';
+import { within } from '../../../.storybook/test';
import { enableFunctionToggleControls } from '../../../.storybook/utils';
+
import { EuiButtonIcon } from '../button';
import { EuiToolTip } from '../tool_tip';
@@ -144,7 +146,7 @@ export const CellActions: Story = {
dataGridRef.current?.setFocusedCell({ rowIndex: 2, colIndex: 2 });
}, []);
- return ;
+ return ;
},
};
@@ -158,6 +160,23 @@ export const CellExpansionPopover: Story = {
dataGridRef.current?.openCellPopover({ rowIndex: 1, colIndex: 1 });
}, []);
- return ;
+ return ;
+ },
+};
+
+export const ColumnActions: Story = {
+ tags: ['vrt-only'],
+ args: defaultStorybookArgs,
+ render: () => (
+
+ ),
+ play: async ({ canvasElement }: PlayFunctionContext) => {
+ const canvas = within(canvasElement);
+ await canvas.waitForAndClick('dataGridHeaderCellActionButton-account');
+ await canvas.waitForEuiPopoverVisible();
},
};
diff --git a/packages/eui/src/components/datagrid/data_grid.stories.utils.tsx b/packages/eui/src/components/datagrid/data_grid.stories.utils.tsx
index 135043bee98..f4c2d5b4da6 100644
--- a/packages/eui/src/components/datagrid/data_grid.stories.utils.tsx
+++ b/packages/eui/src/components/datagrid/data_grid.stories.utils.tsx
@@ -12,7 +12,6 @@ import React, {
useCallback,
useEffect,
useState,
- forwardRef,
FunctionComponent,
} from 'react';
import { faker } from '@faker-js/faker';
@@ -27,7 +26,6 @@ import type {
EuiDataGridColumnCellActionProps,
EuiDataGridColumnSortingConfig,
EuiDataGridProps,
- EuiDataGridRefProps,
EuiDataGridStyle,
EuiDataGridRowHeightsOptions,
EuiDataGridToolBarVisibilityOptions,
@@ -293,10 +291,7 @@ export const defaultStorybookArgs = {
} as const,
};
-export const StatefulDataGrid = forwardRef<
- EuiDataGridRefProps,
- EuiDataGridProps
->((props, ref) => {
+export const StatefulDataGrid = (props: EuiDataGridProps) => {
const { pagination, sorting, columnVisibility, ...rest } = props;
// Pagination
@@ -360,7 +355,6 @@ export const StatefulDataGrid = forwardRef<
return (
);
-});
-StatefulDataGrid.displayName = 'StatefulDataGrid';
+};
/*
* Components that exist purely for allowing Storybook to parse certain nested
diff --git a/packages/eui/src/components/datagrid/data_grid.styles.ts b/packages/eui/src/components/datagrid/data_grid.styles.ts
index 2a4b8b3166c..557b76289ae 100644
--- a/packages/eui/src/components/datagrid/data_grid.styles.ts
+++ b/packages/eui/src/components/datagrid/data_grid.styles.ts
@@ -87,6 +87,13 @@ export const euiDataGridStyles = (euiThemeContext: UseEuiTheme) => {
`${cellPadding[size]} solid transparent`
)}
}
+
+ /* Ensure the column actions button maintains its size for accessible click/tap targeting
+ * (see https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html)
+ * while not increasing the height of the header row at compact sizes. */
+ .euiDataGridHeaderCell__button {
+ margin-block: -${cellPadding[size]};
+ }
`,
get s() {
return css(this.cellPadding('s'));
diff --git a/packages/eui/src/components/datagrid/data_grid.test.tsx b/packages/eui/src/components/datagrid/data_grid.test.tsx
index 5287ff4683c..f233e57f2fa 100644
--- a/packages/eui/src/components/datagrid/data_grid.test.tsx
+++ b/packages/eui/src/components/datagrid/data_grid.test.tsx
@@ -51,9 +51,7 @@ function extractGridData(datagrid: ReactWrapper) {
const headerCells = findTestSubject(datagrid, 'dataGridHeaderCell', '|=');
const headerRow: string[] = [];
headerCells.forEach((cell: any) =>
- headerRow.push(
- cell.find('[className~="euiDataGridHeaderCell__content"]').text()
- )
+ headerRow.push(cell.find('div.euiDataGridHeaderCell__content').text())
);
rows.push(headerRow);
diff --git a/packages/eui/src/components/datagrid/data_grid_types.ts b/packages/eui/src/components/datagrid/data_grid_types.ts
index eec39af4683..64419e06d29 100644
--- a/packages/eui/src/components/datagrid/data_grid_types.ts
+++ b/packages/eui/src/components/datagrid/data_grid_types.ts
@@ -546,7 +546,10 @@ interface SharedRenderCellElementProps {
}
export type EuiDataGridSetCellProps = CommonProps &
- HTMLAttributes & {
+ Omit<
+ HTMLAttributes,
+ 'role' | 'tabIndex' | 'aria-rowindex'
+ > & {
isExpandable?: boolean;
};
diff --git a/packages/eui/src/components/datagrid/utils/row_heights.ts b/packages/eui/src/components/datagrid/utils/row_heights.ts
index 8e0acacf48b..6d898a0b98d 100644
--- a/packages/eui/src/components/datagrid/utils/row_heights.ts
+++ b/packages/eui/src/components/datagrid/utils/row_heights.ts
@@ -32,8 +32,8 @@ import {
import { euiDataGridVariables } from '../data_grid.styles';
import { DataGridSortedContext } from './sorting';
-export const AUTO_HEIGHT = 'auto';
-export const DEFAULT_ROW_HEIGHT = 34;
+const AUTO_HEIGHT = 'auto';
+const DEFAULT_ROW_HEIGHT = 34;
export type RowHeightUtilsType = RowHeightUtils | RowHeightVirtualizationUtils;
diff --git a/packages/eui/src/components/index.scss b/packages/eui/src/components/index.scss
deleted file mode 100644
index 276f366acfd..00000000000
--- a/packages/eui/src/components/index.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-// Components
-
-@import 'datagrid/index';
diff --git a/packages/eui/src/themes/amsterdam/theme_dark.scss b/packages/eui/src/themes/amsterdam/theme_dark.scss
index b18ac759e36..a578e60d010 100644
--- a/packages/eui/src/themes/amsterdam/theme_dark.scss
+++ b/packages/eui/src/themes/amsterdam/theme_dark.scss
@@ -3,6 +3,3 @@
// Global styling
@import './global_styling/index';
-
-// Components
-@import '../../components/index';
diff --git a/packages/eui/src/themes/amsterdam/theme_light.scss b/packages/eui/src/themes/amsterdam/theme_light.scss
index 504e8bc600a..0b499f9e37d 100644
--- a/packages/eui/src/themes/amsterdam/theme_light.scss
+++ b/packages/eui/src/themes/amsterdam/theme_light.scss
@@ -3,6 +3,3 @@
// Global styling
@import './global_styling/index';
-
-// Components
-@import '../../components/index';