diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Dark_Mode.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Dark_Mode.png
new file mode 100644
index 00000000000..4485a2b5ba7
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Dark_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_High_Contrast_Mode.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_High_Contrast_Mode.png
new file mode 100644
index 00000000000..3cc49e526b7
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_High_Contrast_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Playground.png
index 9b5193c7d96..3d9f07e8553 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiToolTip_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTourStep_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTourStep_Playground.png
index 13215c321ed..adf685c4c48 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTourStep_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTourStep_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTour_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTour_Playground.png
index c2660eb1b38..115f561c333 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTour_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiTour_EuiTour_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input.png
index 7d3fb2048af..28a36993d7a 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input_With_Popover.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input_With_Popover.png
index e79e57f6576..1fabca62ddc 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input_With_Popover.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Input_With_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Levels.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Levels.png
index 1c4dfa789a1..72062106e27 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Levels.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Levels.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Ticks.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Ticks.png
index 81c85e8ee02..3f7e8762949 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Ticks.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDualRange_Ticks.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input.png
index 9a0e81649d4..cfb521f37e4 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input_With_Popover.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input_With_Popover.png
new file mode 100644
index 00000000000..eaa486f2c0d
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Input_With_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Levels.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Levels.png
index dd549126cb3..7ff07fcac2f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Levels.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Levels.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Ticks.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Ticks.png
index bfa99e190a6..4cf2664190a 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Ticks.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Ticks.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Value_Tooltip.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Value_Tooltip.png
index 4864dbf371d..f2cf78b4da5 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Value_Tooltip.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiRange_Value_Tooltip.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPanel_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPanel_Playground.png
index 5ce41497360..8df9aa9780f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPanel_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPanel_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverFooter_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverFooter_Playground.png
index 37f84eb5448..42ec4f27ce5 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverFooter_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverFooter_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverTitle_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverTitle_Playground.png
index b9a38da081f..f0b3b903e4f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverTitle_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopoverTitle_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png
new file mode 100644
index 00000000000..937a7ecd9cc
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png
index 03be63076af..b1a89f991c7 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Playground.png
index de240518d89..fec995dd7c5 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiPopover_EuiPopover_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Dark_Mode.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Dark_Mode.png
new file mode 100644
index 00000000000..7d5dfaf063d
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Dark_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_High_Contrast_Mode.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_High_Contrast_Mode.png
new file mode 100644
index 00000000000..0d002ca526f
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_High_Contrast_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Playground.png
index 3f3a86e1107..43fc3920cda 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiToolTip_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTourStep_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTourStep_Playground.png
index b28c58b387c..519a7992dfa 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTourStep_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTourStep_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTour_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTour_Playground.png
index 405298cf883..83886da58cb 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTour_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiTour_EuiTour_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input.png
index 8f73613b183..6ff82473eab 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input_With_Popover.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input_With_Popover.png
index cb8b4eb2974..9a9607b0574 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input_With_Popover.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Input_With_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Levels.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Levels.png
index b0223dfbd55..76ca99d9074 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Levels.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Levels.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Ticks.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Ticks.png
index 57cd818c303..815f24ac8ba 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Ticks.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDualRange_Ticks.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input.png
index 7cd7f7e4681..e82e830a946 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input_With_Popover.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input_With_Popover.png
new file mode 100644
index 00000000000..6b40ff087ac
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Input_With_Popover.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Levels.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Levels.png
index 3f850c9d448..e1ff7d8bc41 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Levels.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Levels.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Ticks.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Ticks.png
index 5f4115f53d8..c18a999ca4a 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Ticks.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Ticks.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Value_Tooltip.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Value_Tooltip.png
index b6e46f3124b..d54fb313f73 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Value_Tooltip.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiRange_Value_Tooltip.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPanel_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPanel_Playground.png
index 24837b35c4f..00b83900ad4 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPanel_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPanel_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverFooter_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverFooter_Playground.png
index 193cc213528..c37d94530f3 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverFooter_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverFooter_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverTitle_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverTitle_Playground.png
index 34fbaedfb4b..a1bf9ddf1b9 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverTitle_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopoverTitle_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png
new file mode 100644
index 00000000000..ad67e7ac0af
Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_High_Contrast_Mode.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png
index 038157528e4..b8096b8d775 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Panel_Padding_Size.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Playground.png
index 5b934428063..d5b1608390e 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiPopover_EuiPopover_Playground.png differ
diff --git a/packages/eui/changelogs/upcoming/8174.md b/packages/eui/changelogs/upcoming/8174.md
new file mode 100644
index 00000000000..1ff1c591cad
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8174.md
@@ -0,0 +1 @@
+- Updated `EuiPopover` and `EuiToolTip` to be easier to see in dark mode.
diff --git a/packages/eui/src/components/basic_table/__snapshots__/collapsed_item_actions.test.tsx.snap b/packages/eui/src/components/basic_table/__snapshots__/collapsed_item_actions.test.tsx.snap
index c4bcc9134dc..3fc78452fba 100644
--- a/packages/eui/src/components/basic_table/__snapshots__/collapsed_item_actions.test.tsx.snap
+++ b/packages/eui/src/components/basic_table/__snapshots__/collapsed_item_actions.test.tsx.snap
@@ -48,14 +48,18 @@ exports[`CollapsedItemActions custom actions 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: -22px; left: -16px; z-index: 2000;"
+ style="top: -18px; left: -16px; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="top: 9px; left: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="top: 9px; left: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="top: 9px; right: 100%;"
+ >
+
+
Nav item
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/__snapshots__/collapsed_nav_popover.test.tsx.snap b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/__snapshots__/collapsed_nav_popover.test.tsx.snap
index 6fc0081a4bd..8efdac1f7ad 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/__snapshots__/collapsed_nav_popover.test.tsx.snap
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/__snapshots__/collapsed_nav_popover.test.tsx.snap
@@ -47,14 +47,18 @@ exports[`EuiCollapsedNavPopover renders 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: -22px; left: 16px; z-index: 2000;"
+ style="top: -18px; left: 16px; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="top: 9px; right: 100%;"
+ >
+
+
tooltip content
diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell_popover.spec.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell_popover.spec.tsx
index da2ae883a92..5c87de9db26 100644
--- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell_popover.spec.tsx
+++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell_popover.spec.tsx
@@ -254,7 +254,7 @@ describe('EuiDataGridCellPopover', () => {
openCellPopover('B');
cy.get('[data-test-subj="euiDataGridExpansionPopover"]')
.should('have.css', 'width', '400px')
- .should('have.css', 'height', '88px');
+ .should('have.css', 'height', '90px');
});
it('matches the width of the column if the column width is larger than 400px', () => {
@@ -270,7 +270,7 @@ describe('EuiDataGridCellPopover', () => {
openCellPopover('B');
cy.get('[data-test-subj="euiDataGridExpansionPopover"]')
.should('have.css', 'width', '500px')
- .should('have.css', 'height', '64px');
+ .should('have.css', 'height', '66px');
});
});
});
diff --git a/packages/eui/src/components/datagrid/body/header/__snapshots__/column_actions.test.tsx.snap b/packages/eui/src/components/datagrid/body/header/__snapshots__/column_actions.test.tsx.snap
index 6c37e70bbda..5ed8e1084c2 100644
--- a/packages/eui/src/components/datagrid/body/header/__snapshots__/column_actions.test.tsx.snap
+++ b/packages/eui/src/components/datagrid/body/header/__snapshots__/column_actions.test.tsx.snap
@@ -42,14 +42,18 @@ exports[`ColumnActions renders 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: 23px; left: -22px; z-index: 2000;"
+ style="top: 23px; left: -18px; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
{
`,
outside: css`
/* Match dropshadow */
- ${euiShadowXLarge(euiThemeContext)}
+ ${euiShadowXLarge(euiThemeContext, { borderAllInHighContrastMode: true })}
/* Override the hover and focus transitions of buttons */
animation: none !important; /* stylelint-disable-line declaration-no-important */
`,
diff --git a/packages/eui/src/components/flyout/flyout.styles.ts b/packages/eui/src/components/flyout/flyout.styles.ts
index 58df36deb6c..2d469ed8c10 100644
--- a/packages/eui/src/components/flyout/flyout.styles.ts
+++ b/packages/eui/src/components/flyout/flyout.styles.ts
@@ -107,7 +107,7 @@ export const euiFlyoutStyles = (euiThemeContext: UseEuiTheme) => {
// Type
overlay: css`
- ${euiShadowXLarge(euiThemeContext)}
+ ${euiShadowXLarge(euiThemeContext, { borderAllInHighContrastMode: true })}
`,
push: {
push: css`
diff --git a/packages/eui/src/components/form/range/__snapshots__/range.test.tsx.snap b/packages/eui/src/components/form/range/__snapshots__/range.test.tsx.snap
index 6d56644398d..b62d669abd2 100644
--- a/packages/eui/src/components/form/range/__snapshots__/range.test.tsx.snap
+++ b/packages/eui/src/components/form/range/__snapshots__/range.test.tsx.snap
@@ -454,7 +454,7 @@ exports[`EuiRange props slider should display in popover 1`] = `
data-popover-panel="true"
data-test-subj="test"
role="dialog"
- style="top: 0px; left: -22px; will-change: transform, opacity; z-index: 2000; inline-size: 0px;"
+ style="top: 0px; left: -18px; will-change: transform, opacity; z-index: 2000; inline-size: 0px;"
>
= {
},
showInput: {
control: 'radio',
- options: [true, false, 'inputWithPopover'],
+ options: [false, true, 'inputWithPopover'],
},
inputPopoverProps: {
if: { arg: 'showInput', eq: 'inputWithPopover' },
@@ -70,7 +71,6 @@ const meta: Meta = {
minInputProps: {},
maxInputProps: {},
inputPopoverProps: {},
- ticks: [],
},
};
moveStorybookControlsToCategory(
@@ -152,31 +152,6 @@ export const Input: Story = {
render: (args) => ,
};
-export const InputWithPopover: Story = {
- parameters: {
- controls: {
- include: [
- 'showInput',
- 'append',
- 'prepend',
- 'inputPopoverProps',
- 'isInvalid',
- 'isLoading',
- 'max',
- 'min',
- 'value',
- 'minInputProps',
- 'maxInputProps',
- ],
- },
- },
- args: {
- value: [25, 50],
- showInput: 'inputWithPopover',
- },
- render: (args) => ,
-};
-
export const Levels: Story = {
parameters: {
controls: {
@@ -207,7 +182,7 @@ const StatefulPlayground = ({
}
}, [value]);
- const handelOnChange = (
+ const handleOnChange = (
values: EuiDualRangeProps['value'],
isValid: boolean,
e?: _DualRangeChangeEvent
@@ -216,5 +191,41 @@ const StatefulPlayground = ({
onChange?.(values, isValid, e);
};
- return ;
+ return ;
+};
+
+/**
+ * VRT only
+ */
+
+export const InputWithPopover: Story = {
+ tags: ['vrt-only'],
+ parameters: {
+ loki: { chromeSelector: LOKI_SELECTORS.portal },
+ },
+ args: {
+ showInput: 'inputWithPopover',
+ min: 0,
+ max: 100,
+ value: [10, 80],
+ // Should render ticks, levels, highlights, and tooltips in their correct positions
+ showLabels: true,
+ showTicks: true,
+ ticks: [
+ { label: '20kb', value: 20 },
+ { label: '100kb', value: 100 },
+ ],
+ levels: [
+ { min: 0, max: 20, color: 'danger' },
+ { min: 20, max: 100, color: 'success' },
+ ],
+ },
+ // Force input popover open via programmatic ref
+ render: function Render(args) {
+ const [ref, setRef] = useState();
+ useEffect(() => {
+ ref?.onInputFocus();
+ }, [ref]);
+ return ;
+ },
};
diff --git a/packages/eui/src/components/form/range/range.spec.tsx b/packages/eui/src/components/form/range/range.spec.tsx
deleted file mode 100644
index 46489c8861f..00000000000
--- a/packages/eui/src/components/form/range/range.spec.tsx
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 React from 'react';
-
-import { EuiRange } from './range';
-import { EuiDualRange } from './dual_range';
-
-const sharedProps = {
- min: 0,
- max: 100,
- onChange: () => {},
- showTicks: true,
- showLabels: true,
- levels: [
- {
- min: 0,
- max: 20,
- color: 'danger',
- },
- {
- min: 20,
- max: 100,
- color: 'success',
- },
- ],
-};
-const firstExpectedLevel = /^0px 256[.0-9]+px$/;
-const secondExpectedLevel = /^72[.0-9]+px 0px$/;
-
-describe('EuiRange', () => {
- const props = {
- ...sharedProps,
- value: 50,
- showValue: true,
- showRange: true,
- tickInterval: 20,
- };
-
- // TODO: These should likely be visual snapshot regression tests instead
- const assertRangePositions = () => {
- // Ticks
- cy.get('.euiRangeTick')
- .first()
- .should('have.css', 'inset-inline-start', '8px');
- cy.get('.euiRangeTick')
- .eq(3)
- .should('have.css', 'inset-inline-start')
- .and('match', /^195[.0-9]+px$/);
- cy.get('.euiRangeTick')
- .last()
- .should('have.css', 'inset-inline-start')
- .and('match', /^320[.0-9]+px$/);
-
- // Levels - present in both EuiRangeLevels and EuiHighlight
- cy.get('.euiRangeLevel')
- .eq(0)
- .should('have.css', 'inset-inline')
- .and('match', firstExpectedLevel);
- cy.get('.euiRangeLevel')
- .eq(2)
- .should('have.css', 'inset-inline')
- .and('match', firstExpectedLevel);
-
- cy.get('.euiRangeLevel')
- .eq(1)
- .should('have.css', 'inset-inline')
- .and('match', secondExpectedLevel);
- cy.get('.euiRangeLevel')
- .eq(3)
- .should('have.css', 'inset-inline')
- .and('match', secondExpectedLevel);
-
- // Highlight
- cy.get('.euiRangeHighlight > div')
- .should('have.css', 'margin-inline-start', '0px')
- .should('have.css', 'inline-size')
- .and('match', /^164[.0-9]+px$/);
-
- // Tooltip
- cy.get('.euiRangeTooltip > output')
- .should('have.css', 'inset-inline-start')
- .and('match', /^156[.0-9]+px$/);
- };
-
- it('renders ticks, levels, highlights, and tooltips in their correct positions', () => {
- cy.mount();
- assertRangePositions();
- });
-
- it('inputWithPopover', () => {
- cy.realMount(
-
- );
- cy.realPress('Tab');
- assertRangePositions();
- });
-});
-
-describe('EuiDualRange', () => {
- const props = {
- ...sharedProps,
- value: [10, 80] as [number, number],
- ticks: [
- { label: '20kb', value: 20 },
- { label: '100kb', value: 100 },
- ],
- };
-
- // TODO: These should likely be visual snapshot regression tests instead
- const assertRangePositions = () => {
- // Ticks
- cy.get('.euiRangeTick')
- .first()
- .should('have.css', 'inset-inline-start')
- .and('match', /^69[.0-9]+px$/);
- cy.get('.euiRangeTick')
- .last()
- .should('have.css', 'inset-inline-end', '0px');
-
- // Levels - present in both EuiRangeLevels and EuiHighlight
- cy.get('.euiRangeLevel')
- .eq(0)
- .should('have.css', 'inset-inline')
- .and('match', firstExpectedLevel);
- cy.get('.euiRangeLevel')
- .eq(2)
- .should('have.css', 'inset-inline')
- .and('match', firstExpectedLevel);
-
- cy.get('.euiRangeLevel')
- .eq(1)
- .should('have.css', 'inset-inline')
- .and('match', secondExpectedLevel);
- cy.get('.euiRangeLevel')
- .eq(3)
- .should('have.css', 'inset-inline')
- .and('match', secondExpectedLevel);
-
- // Highlight
- cy.get('.euiRangeHighlight > div')
- .should('have.css', 'margin-inline-start')
- .and('match', /^32[.0-9]+px$/);
- cy.get('.euiRangeHighlight > div')
- .should('have.css', 'inline-size')
- .and('match', /^229[.0-9]+px$/);
-
- // Thumbs
- cy.get('.euiRangeThumb')
- .first()
- .should('have.css', 'inset-inline-start')
- .and('match', /^31[.0-9]+px$/);
- cy.get('.euiRangeThumb')
- .last()
- .should('have.css', 'inset-inline-start')
- .and('match', /^249[.0-9]+px$/);
- };
-
- it('renders ticks, levels, highlights, and thumbs in their correct positions', () => {
- cy.mount();
- assertRangePositions();
- });
-
- it('inputWithPopover', () => {
- cy.realMount(
-
- );
- cy.realPress('Tab');
- assertRangePositions();
- });
-});
diff --git a/packages/eui/src/components/form/range/range.stories.tsx b/packages/eui/src/components/form/range/range.stories.tsx
index 1885e0afef0..1064ce772c2 100644
--- a/packages/eui/src/components/form/range/range.stories.tsx
+++ b/packages/eui/src/components/form/range/range.stories.tsx
@@ -9,6 +9,7 @@
import React, { useEffect, useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { LOKI_SELECTORS } from '../../../../.storybook/loki';
import {
enableFunctionToggleControls,
moveStorybookControlsToCategory,
@@ -66,6 +67,13 @@ const meta: Meta = {
undefined: undefined,
},
},
+ showInput: {
+ control: 'radio',
+ options: [false, true, 'inputWithPopover'],
+ },
+ inputPopoverProps: {
+ if: { arg: 'showInput', eq: 'inputWithPopover' },
+ },
},
args: {
min: 0,
@@ -88,7 +96,6 @@ const meta: Meta = {
// adding tickInterval value to prevent error about
// too many ticks when enabling showTicks
tickInterval: 10,
- ticks: [],
},
};
@@ -200,6 +207,7 @@ export const Levels: Story = {
{ min: 20, max: 100, color: 'success' },
],
showLabels: true,
+ showRange: true,
},
render: (args) => ,
};
@@ -213,10 +221,47 @@ const StatefulPlayground = ({ value, onChange, ...rest }: EuiRangeProps) => {
}
}, [value]);
- const handelOnChange = (e: _SingleRangeChangeEvent, isValid: boolean) => {
+ const handleOnChange = (e: _SingleRangeChangeEvent, isValid: boolean) => {
setValue(e.currentTarget.value);
onChange?.(e, isValid);
};
- return ;
+ return ;
+};
+
+/**
+ * VRT only
+ */
+
+export const InputWithPopover: Story = {
+ tags: ['vrt-only'],
+ parameters: {
+ loki: { chromeSelector: LOKI_SELECTORS.portal },
+ },
+ args: {
+ showInput: 'inputWithPopover',
+ min: 0,
+ max: 100,
+ value: 50,
+ // Should render ticks, levels, highlights, and tooltips in their correct positions
+ showLabels: true,
+ showValue: true,
+ showRange: true,
+ showTicks: true,
+ tickInterval: 20,
+ levels: [
+ { min: 0, max: 20, color: 'danger' },
+ { min: 20, max: 100, color: 'success' },
+ ],
+ },
+ // Force input popover open via programmatic ref
+ render: function Render(args) {
+ const [ref, setRef] = useState();
+ useEffect(() => {
+ // For some reason Loki throws a width/render error if not wrapped in a timeout.
+ // This doesn't happen on production
+ if (ref) setTimeout(() => ref.onInputFocus(), 1);
+ }, [ref]);
+ return ;
+ },
};
diff --git a/packages/eui/src/components/form/super_select/__snapshots__/super_select.test.tsx.snap b/packages/eui/src/components/form/super_select/__snapshots__/super_select.test.tsx.snap
index e068fa19900..10fdc402366 100644
--- a/packages/eui/src/components/form/super_select/__snapshots__/super_select.test.tsx.snap
+++ b/packages/eui/src/components/form/super_select/__snapshots__/super_select.test.tsx.snap
@@ -190,7 +190,7 @@ exports[`EuiSuperSelect renders 1`] = `
class="euiPanel euiPanel--plain euiPopover__panel emotion-euiPanel-grow-m-plain-euiPopover__panel-light-isAttached-bottom"
data-popover-panel="true"
role="dialog"
- style="top: 0px; left: -22px; will-change: transform, opacity; z-index: 2000; inline-size: 0px;"
+ style="top: 0px; left: -18px; will-change: transform, opacity; z-index: 2000; inline-size: 0px;"
>
{
return {
euiModal: css`
- ${euiShadowXLarge(euiThemeContext)}
+ ${euiShadowXLarge(euiThemeContext, { borderAllInHighContrastMode: true })}
display: flex;
flex-direction: column;
max-block-size: 75vh; /* We overflow the modal body based off this */
@@ -69,7 +69,10 @@ export const euiModalStyles = (euiThemeContext: UseEuiTheme) => {
min-inline-size: ${euiFormVariables(euiThemeContext).maxWidth};
${euiMaxBreakpoint(euiThemeContext, 'm')} {
- ${euiShadowXLarge(euiThemeContext, { reverse: true })}
+ ${euiShadowXLarge(euiThemeContext, {
+ reverse: true,
+ borderAllInHighContrastMode: true,
+ })}
inset-block-start: auto;
}
`,
diff --git a/packages/eui/src/components/panel/panel.styles.ts b/packages/eui/src/components/panel/panel.styles.ts
index 12806b48a73..2beb090d478 100644
--- a/packages/eui/src/components/panel/panel.styles.ts
+++ b/packages/eui/src/components/panel/panel.styles.ts
@@ -16,7 +16,7 @@ import {
} from '../../global_styling';
export const euiPanelStyles = (euiThemeContext: UseEuiTheme) => {
- const { euiTheme } = euiThemeContext;
+ const { euiTheme, highContrastMode } = euiThemeContext;
return {
// Base
@@ -61,7 +61,10 @@ export const euiPanelStyles = (euiThemeContext: UseEuiTheme) => {
&:hover,
&:focus {
- ${euiShadow(euiThemeContext, 'l')}
+ ${highContrastMode
+ ? // Use drop-shadow instead of box-shadow, as Windows high contrast themes ignores box-shadows
+ `filter: drop-shadow(0 ${euiTheme.border.width.thick} 0 ${euiTheme.border.color});`
+ : euiShadow(euiThemeContext, 'l')}
transform: translateY(-2px);
cursor: pointer;
}
diff --git a/packages/eui/src/components/panel/panel.tsx b/packages/eui/src/components/panel/panel.tsx
index b7eb932f53f..6cc3d35fbb7 100644
--- a/packages/eui/src/components/panel/panel.tsx
+++ b/packages/eui/src/components/panel/panel.tsx
@@ -13,9 +13,10 @@ import React, {
Ref,
} from 'react';
import classNames from 'classnames';
-import { useEuiMemoizedStyles } from '../../services';
+import { useEuiMemoizedStyles, useEuiTheme } from '../../services';
import {
useEuiBackgroundColorCSS,
+ useEuiBorderColorCSS,
useEuiPaddingCSS,
_EuiBackgroundColor,
EuiPaddingSize,
@@ -107,8 +108,12 @@ export const EuiPanel: FunctionComponent
= ({
element,
...rest
}) => {
+ // Add borders to panels in high contrast mode
+ const { highContrastMode, euiTheme } = useEuiTheme();
+ const borderColors = useEuiBorderColorCSS();
+
// Shadows are only allowed when there's a white background (plain)
- const canHaveShadow = !hasBorder && color === 'plain';
+ const canHaveShadow = !hasBorder && color === 'plain' && !highContrastMode;
const canHaveBorder = color === 'plain' || color === 'transparent';
const styles = useEuiMemoizedStyles(euiPanelStyles);
@@ -120,6 +125,9 @@ export const EuiPanel: FunctionComponent = ({
useEuiBackgroundColorCSS()[color],
canHaveShadow && hasShadow === true && styles.hasShadow,
canHaveBorder && hasBorder === true && styles.hasBorder,
+ ...(highContrastMode
+ ? [{ border: euiTheme.border.thin }, borderColors[color]]
+ : []),
rest.onClick && styles.isClickable,
];
diff --git a/packages/eui/src/components/panel/split_panel/split_panel.styles.ts b/packages/eui/src/components/panel/split_panel/split_panel.styles.ts
index 7e6b3bb8948..f89340b8c82 100644
--- a/packages/eui/src/components/panel/split_panel/split_panel.styles.ts
+++ b/packages/eui/src/components/panel/split_panel/split_panel.styles.ts
@@ -9,6 +9,7 @@
import { css } from '@emotion/react';
import { logicalCSS } from '../../../global_styling';
+import { UseEuiTheme } from '../../../services';
export const euiSplitPanelOuterStyles = {
euiSplitPanelOuter: css`
@@ -24,7 +25,9 @@ export const euiSplitPanelOuterStyles = {
`,
};
-export const euiSplitPanelInnerStyles = {
+export const euiSplitPanelInnerStyles = ({
+ highContrastMode,
+}: UseEuiTheme) => ({
euiSplitPanelInner: css`
/* Make sure they're evenly split */
flex-basis: 0%;
@@ -33,5 +36,8 @@ export const euiSplitPanelInnerStyles = {
/* stylelint-disable declaration-no-important */
transform: none !important;
box-shadow: none !important;
+
+ /* Don't double up on borders in high contrast mode */
+ ${highContrastMode ? 'border: none;' : ''}
`,
-};
+});
diff --git a/packages/eui/src/components/panel/split_panel/split_panel.tsx b/packages/eui/src/components/panel/split_panel/split_panel.tsx
index 0de7ec8c659..e0e2f536263 100644
--- a/packages/eui/src/components/panel/split_panel/split_panel.tsx
+++ b/packages/eui/src/components/panel/split_panel/split_panel.tsx
@@ -13,6 +13,7 @@ import {
EuiBreakpointSize,
useIsWithinBreakpoints,
} from '../../../services/breakpoint';
+import { useEuiMemoizedStyles } from '../../../services';
import { EuiPanel, _EuiPanelProps } from '../panel';
import {
@@ -31,6 +32,7 @@ export const _EuiSplitPanelInner: FunctionComponent<
_EuiSplitPanelInnerProps
> = ({ children, className, ...rest }) => {
const classes = classNames('euiSplitPanel__inner', className);
+ const styles = useEuiMemoizedStyles(euiSplitPanelInnerStyles);
const panelProps: _EuiPanelProps = {
hasShadow: false,
@@ -43,7 +45,7 @@ export const _EuiSplitPanelInner: FunctionComponent<
diff --git a/packages/eui/src/components/popover/__snapshots__/popover.rtl.test.tsx.snap b/packages/eui/src/components/popover/__snapshots__/popover.rtl.test.tsx.snap
index 760c7ab008a..85de7afacc3 100644
--- a/packages/eui/src/components/popover/__snapshots__/popover.rtl.test.tsx.snap
+++ b/packages/eui/src/components/popover/__snapshots__/popover.rtl.test.tsx.snap
@@ -44,14 +44,18 @@ exports[`EuiPopover snapshot testing renders with popover contents 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: 16px; left: -22px; will-change: transform, opacity; z-index: 2000;"
+ style="top: 16px; left: -18px; will-change: transform, opacity; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
@@ -431,14 +458,18 @@ exports[`EuiPopover props panelClassName is rendered 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: 16px; left: -22px; will-change: transform, opacity; z-index: 2000;"
+ style="top: 16px; left: -18px; will-change: transform, opacity; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; bottom: 100%;"
+ >
+
+
,
};
+
+export const HighContrastMode: Story = {
+ tags: ['vrt-only'],
+ globals: { highContrastMode: true },
+ args: {
+ children: (
+ <>
+ Popover title
+ High contrast mode
+ {/* Move the initialFocus so the popover border shows up more plainly in the screenshot */}
+
+ >
+ ),
+ panelPaddingSize: 's',
+ anchorPosition: 'upCenter',
+ button: 'popover trigger',
+ isOpen: true,
+ initialFocus: '#focus',
+ },
+ render: (args) => ,
+};
diff --git a/packages/eui/src/components/popover/popover.tsx b/packages/eui/src/components/popover/popover.tsx
index d78b25eb1dd..6c683a0ce91 100644
--- a/packages/eui/src/components/popover/popover.tsx
+++ b/packages/eui/src/components/popover/popover.tsx
@@ -543,7 +543,7 @@ export class EuiPopover extends Component {
? 16 + offset
: 8 + offset,
arrowConfig: this.props.hasArrow
- ? { arrowWidth: 24, arrowBuffer: 10 }
+ ? { arrowWidth: 16, arrowBuffer: 10 }
: { arrowWidth: 0, arrowBuffer: 0 },
returnBoundingBox: this.props.attachToAnchor,
allowCrossAxis: this.props.repositionToCrossAxis,
diff --git a/packages/eui/src/components/popover/popover_arrow/__snapshots__/_popover_arrow.test.tsx.snap b/packages/eui/src/components/popover/popover_arrow/__snapshots__/_popover_arrow.test.tsx.snap
index e1f6c22cb47..14d477c8c7c 100644
--- a/packages/eui/src/components/popover/popover_arrow/__snapshots__/_popover_arrow.test.tsx.snap
+++ b/packages/eui/src/components/popover/popover_arrow/__snapshots__/_popover_arrow.test.tsx.snap
@@ -3,35 +3,51 @@
exports[`EuiPopoverArrow position bottom is rendered 1`] = `
+>
+
+
`;
exports[`EuiPopoverArrow position left is rendered 1`] = `
+>
+
+
`;
exports[`EuiPopoverArrow position right is rendered 1`] = `
+>
+
+
`;
exports[`EuiPopoverArrow position top is rendered 1`] = `
+>
+
+
`;
diff --git a/packages/eui/src/components/popover/popover_arrow/_popover_arrow.styles.ts b/packages/eui/src/components/popover/popover_arrow/_popover_arrow.styles.ts
index c1d911738df..64b39ad7e39 100644
--- a/packages/eui/src/components/popover/popover_arrow/_popover_arrow.styles.ts
+++ b/packages/eui/src/components/popover/popover_arrow/_popover_arrow.styles.ts
@@ -7,68 +7,31 @@
*/
import { css } from '@emotion/react';
-import { logicals, logicalSizeCSS } from '../../../global_styling';
+import { logicalSizeCSS } from '../../../global_styling';
+import { _popoverArrowStyles } from '../../../services/popover';
import { UseEuiTheme } from '../../../services';
-export const popoverArrowSize = 'm';
-
export const euiPopoverArrowStyles = (euiThemeContext: UseEuiTheme) => {
- const { euiTheme } = euiThemeContext;
+ const { euiTheme, highContrastMode, colorMode } = euiThemeContext;
+ const hasBorder = highContrastMode || colorMode === 'DARK';
- const borderColor = 'var(--euiPopoverBackgroundColor)';
- const arrowSize = euiTheme.size[popoverArrowSize];
+ const arrowSize = euiTheme.size.base;
+ const arrowStyles = _popoverArrowStyles(euiThemeContext, arrowSize);
return {
- // Base
- euiPopoverArrow: css`
+ // Wrapper
+ euiPopoverArrowWrapper: css`
position: absolute;
- ${logicalSizeCSS(0, 0)}
-
- /* This part of the arrow matches the panel. */
- &::before {
- content: '';
- position: absolute;
- ${logicalSizeCSS(0, 0)}
- }
- `,
-
- // POSITIONS
- top: css`
- &::before {
- ${logicals.bottom}: -${arrowSize};
- ${logicals['border-left']}: ${arrowSize} solid transparent;
- ${logicals['border-right']}: ${arrowSize} solid transparent;
- ${logicals['border-top']}: ${arrowSize} solid ${borderColor};
- }
+ ${logicalSizeCSS(arrowSize)}
`,
- bottom: css`
- &::before {
- ${logicals.top}: -${arrowSize};
- ${logicals['border-left']}: ${arrowSize} solid transparent;
- ${logicals['border-right']}: ${arrowSize} solid transparent;
- ${logicals['border-bottom']}: ${arrowSize} solid ${borderColor};
- }
- `,
-
- left: css`
- &::before {
- ${logicals.top}: 50%;
- ${logicals.right}: -${arrowSize};
- ${logicals['border-top']}: ${arrowSize} solid transparent;
- ${logicals['border-bottom']}: ${arrowSize} solid transparent;
- ${logicals['border-left']}: ${arrowSize} solid ${borderColor};
- }
+ // Base
+ euiPopoverArrow: css`
+ ${arrowStyles._arrowStyles}
+ background-color: var(--euiPopoverBackgroundColor);
+ ${hasBorder ? `border: ${euiTheme.border.thin};` : ''}
`,
- right: css`
- &::before {
- ${logicals.top}: 50%;
- ${logicals.left}: -${arrowSize};
- ${logicals['border-top']}: ${arrowSize} solid transparent;
- ${logicals['border-bottom']}: ${arrowSize} solid transparent;
- ${logicals['border-right']}: ${arrowSize} solid ${borderColor};
- }
- `,
+ ...arrowStyles.positions,
};
};
diff --git a/packages/eui/src/components/popover/popover_arrow/_popover_arrow.tsx b/packages/eui/src/components/popover/popover_arrow/_popover_arrow.tsx
index 4238824ae23..eef2ad09c82 100644
--- a/packages/eui/src/components/popover/popover_arrow/_popover_arrow.tsx
+++ b/packages/eui/src/components/popover/popover_arrow/_popover_arrow.tsx
@@ -7,9 +7,9 @@
*/
import React, { HTMLAttributes, FunctionComponent } from 'react';
+import { useEuiTheme } from '../../../services';
import { CommonProps } from '../../common';
import { euiPopoverArrowStyles } from './_popover_arrow.styles';
-import { useEuiTheme } from '../../../services';
export const POSITIONS = ['top', 'left', 'right', 'bottom'] as const;
export type EuiPopoverArrowPositions = (typeof POSITIONS)[number];
@@ -22,6 +22,7 @@ export type EuiPopoverArrowProps = HTMLAttributes &
export const EuiPopoverArrow: FunctionComponent = ({
children,
position,
+ style,
...rest
}) => {
const euiTheme = useEuiTheme();
@@ -30,11 +31,16 @@ export const EuiPopoverArrow: FunctionComponent = ({
return (
);
diff --git a/packages/eui/src/components/popover/popover_footer.stories.tsx b/packages/eui/src/components/popover/popover_footer.stories.tsx
index 9ddb92a8a7e..397869eab26 100644
--- a/packages/eui/src/components/popover/popover_footer.stories.tsx
+++ b/packages/eui/src/components/popover/popover_footer.stories.tsx
@@ -9,6 +9,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { LOKI_SELECTORS } from '../../../.storybook/loki';
import { PADDING_SIZES } from '../../global_styling';
import { EuiButton } from '../button';
import { EuiPopover } from './popover';
@@ -30,6 +31,9 @@ const meta: Meta = {
options: [undefined, ...PADDING_SIZES],
},
},
+ parameters: {
+ loki: { chromeSelector: LOKI_SELECTORS.portal },
+ },
};
export default meta;
diff --git a/packages/eui/src/components/popover/popover_panel/_popover_panel.styles.ts b/packages/eui/src/components/popover/popover_panel/_popover_panel.styles.ts
index f31ce85e5a1..d88e3ce59ef 100644
--- a/packages/eui/src/components/popover/popover_panel/_popover_panel.styles.ts
+++ b/packages/eui/src/components/popover/popover_panel/_popover_panel.styles.ts
@@ -30,7 +30,7 @@ export const openAnimationTiming = 'slow';
*/
export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
- const { euiTheme, colorMode } = euiThemeContext;
+ const { euiTheme, highContrastMode, colorMode } = euiThemeContext;
const translateDistance = euiTheme.size.s;
const animationSpeed = euiTheme.animation[openAnimationTiming];
@@ -40,6 +40,9 @@ export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
euiTheme.animation.bounce
} ${mathWithUnits(animationSpeed, (x) => x + 100)}`;
+ const hasShadow = !highContrastMode;
+ const hasVisibleBorder = highContrastMode || colorMode === 'DARK';
+
return {
// Base
euiPopover__panel: css`
@@ -50,6 +53,8 @@ export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
pointer-events: none;
opacity: 0; /* 2 */
background-color: var(--euiPopoverBackgroundColor); /* 4 */
+ border: ${euiTheme.border.width.thin} solid
+ ${hasVisibleBorder ? euiTheme.border.color : 'transparent'};
${euiCanAnimate} {
/* 2 */
@@ -78,7 +83,9 @@ export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
hasTransform: {
hasTransform: css`
transform: translateY(0) translateX(0) translateZ(0); /* 2 */
- ${euiShadowMedium(euiThemeContext, { property: 'filter' })}
+ ${hasShadow
+ ? euiShadowMedium(euiThemeContext, { property: 'filter' })
+ : ''}
${euiCanAnimate} {
transition: ${opacityTransition}, ${transformTransition}; /* 2 */
@@ -107,10 +114,10 @@ export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
}
`,
top: css`
- ${euiShadowFlat(euiThemeContext)}
+ ${hasShadow ? euiShadowFlat(euiThemeContext) : ''}
`,
bottom: css`
- ${euiShadow(euiThemeContext, 'm')}
+ ${hasShadow ? euiShadow(euiThemeContext, 'm') : ''}
`,
get left() {
return this.bottom;
@@ -124,7 +131,9 @@ export const euiPopoverPanelStyles = (euiThemeContext: UseEuiTheme) => {
// stacking context that messes up the drag/drop fixed positioning
hasDragDrop: {
hasDragDrop: css`
- ${euiShadowMedium(euiThemeContext, { property: 'box-shadow' })}
+ ${hasShadow
+ ? euiShadowMedium(euiThemeContext, { property: 'box-shadow' })
+ : ''}
${euiCanAnimate} {
transition: ${opacityTransition}; /* 2 */
diff --git a/packages/eui/src/components/popover/popover_title.stories.tsx b/packages/eui/src/components/popover/popover_title.stories.tsx
index 357c987f98b..889932164a6 100644
--- a/packages/eui/src/components/popover/popover_title.stories.tsx
+++ b/packages/eui/src/components/popover/popover_title.stories.tsx
@@ -9,6 +9,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { LOKI_SELECTORS } from '../../../.storybook/loki';
import { PADDING_SIZES } from '../../global_styling';
import { EuiButton } from '../button';
import { EuiPopover } from './popover';
@@ -30,6 +31,9 @@ const meta: Meta = {
options: [undefined, ...PADDING_SIZES],
},
},
+ parameters: {
+ loki: { chromeSelector: LOKI_SELECTORS.portal },
+ },
};
export default meta;
diff --git a/packages/eui/src/components/resizable_container/resizable_panel.styles.ts b/packages/eui/src/components/resizable_container/resizable_panel.styles.ts
index cda10b5402f..1ca29022a9f 100644
--- a/packages/eui/src/components/resizable_container/resizable_panel.styles.ts
+++ b/packages/eui/src/components/resizable_container/resizable_panel.styles.ts
@@ -26,11 +26,13 @@ export const euiResizablePanelStyles = {
export const euiResizablePanelContentStyles = (
euiThemeContext: UseEuiTheme
) => {
- const { euiTheme } = euiThemeContext;
+ const { euiTheme, highContrastMode } = euiThemeContext;
return {
euiResizablePanel__content: css`
${logicalCSS('height', '100%')}
+ /* Disable default high contrast borders - they make the resize indicators too hard to see */
+ ${highContrastMode ? 'border: none;' : ''}
`,
scrollable: css`
${euiScrollBarStyles(euiThemeContext)}
diff --git a/packages/eui/src/components/selectable/selectable_list/__snapshots__/selectable_list_item.test.tsx.snap b/packages/eui/src/components/selectable/selectable_list/__snapshots__/selectable_list_item.test.tsx.snap
index f870d340b47..498d2d9346b 100644
--- a/packages/eui/src/components/selectable/selectable_list/__snapshots__/selectable_list_item.test.tsx.snap
+++ b/packages/eui/src/components/selectable/selectable_list/__snapshots__/selectable_list_item.test.tsx.snap
@@ -557,7 +557,7 @@ exports[`EuiSelectableListItem props tooltip behavior on mouseover 1`] = `
I am a tooltip!
@@ -637,7 +637,7 @@ exports[`EuiSelectableListItem props tooltip behavior when isFocused 1`] = `
I am a tooltip!
diff --git a/packages/eui/src/components/table/table_pagination/__snapshots__/table_pagination.test.tsx.snap b/packages/eui/src/components/table/table_pagination/__snapshots__/table_pagination.test.tsx.snap
index 5cf804dd3ed..cb9441e795d 100644
--- a/packages/eui/src/components/table/table_pagination/__snapshots__/table_pagination.test.tsx.snap
+++ b/packages/eui/src/components/table/table_pagination/__snapshots__/table_pagination.test.tsx.snap
@@ -209,14 +209,18 @@ exports[`EuiTablePagination renders 1`] = `
data-autofocus="true"
data-popover-panel="true"
role="dialog"
- style="top: -16px; left: -22px; will-change: transform, opacity; z-index: 2000;"
+ style="top: -16px; left: -18px; will-change: transform, opacity; z-index: 2000;"
tabindex="0"
>
+ class="euiPopover__arrowWrapper emotion-euiPopoverArrowWrapper"
+ style="left: 9px; top: 100%;"
+ >
+
+
{
// Base
euiToast: css`
border-radius: ${euiTheme.border.radius.medium};
- ${euiShadowLarge(euiThemeContext)}
+ ${euiShadowLarge(euiThemeContext, { borderAllInHighContrastMode: true })}
position: relative;
${logicalCSS('padding-horizontal', euiTheme.size.base)}
diff --git a/packages/eui/src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap b/packages/eui/src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap
index 3b61b989efe..282ad6a7e4a 100644
--- a/packages/eui/src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap
+++ b/packages/eui/src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap
@@ -81,7 +81,7 @@ exports[`EuiToolTip shows tooltip on mouseover and focus 1`] = `
content
diff --git a/packages/eui/src/components/tool_tip/tool_tip.stories.tsx b/packages/eui/src/components/tool_tip/tool_tip.stories.tsx
index 8c4deb06263..dd4f75092ac 100644
--- a/packages/eui/src/components/tool_tip/tool_tip.stories.tsx
+++ b/packages/eui/src/components/tool_tip/tool_tip.stories.tsx
@@ -10,7 +10,8 @@ import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { enableFunctionToggleControls } from '../../../.storybook/utils';
-import { LOKI_SELECTORS } from '../../../.storybook/loki';
+import { LOKI_SELECTORS, lokiPlayDecorator } from '../../../.storybook/loki';
+import { sleep } from '../../test';
import { EuiFlexGroup } from '../flex';
import { EuiButton } from '../button';
import { EuiToolTip, EuiToolTipProps } from './tool_tip';
@@ -71,4 +72,32 @@ export const Playground: Story = {
// });
// });
// }),
+ play: lokiPlayDecorator(async () => {
+ // Reduce VRT flakiness/screenshots before tooltip is fully visible
+ await sleep(300);
+ }),
+};
+
+/**
+ * VRT only stories
+ */
+
+export const DarkMode: Story = {
+ tags: ['vrt-only'],
+ globals: { colorMode: 'dark' },
+ ...Playground,
+ args: {
+ ...Playground.args,
+ position: 'bottom',
+ },
+};
+
+export const HighContrastMode: Story = {
+ tags: ['vrt-only'],
+ globals: { highContrastMode: true, colorMode: 'dark' },
+ ...Playground,
+ args: {
+ ...Playground.args,
+ position: 'left',
+ },
};
diff --git a/packages/eui/src/components/tool_tip/tool_tip.styles.ts b/packages/eui/src/components/tool_tip/tool_tip.styles.ts
index 3ce4e8b7eb0..28695ffd284 100644
--- a/packages/eui/src/components/tool_tip/tool_tip.styles.ts
+++ b/packages/eui/src/components/tool_tip/tool_tip.styles.ts
@@ -7,14 +7,9 @@
*/
import { css, keyframes } from '@emotion/react';
-import {
- logicalCSS,
- logicalSizeCSS,
- euiFontSize,
- euiCanAnimate,
- mathWithUnits,
-} from '../../global_styling';
+import { logicalCSS, euiFontSize, euiCanAnimate } from '../../global_styling';
import { COLOR_MODES_STANDARD, UseEuiTheme, tint, shade } from '../../services';
+import { _popoverArrowStyles } from '../../services/popover';
import { euiShadow } from '../../themes/amsterdam';
export const euiToolTipBackgroundColor = (
@@ -58,16 +53,21 @@ const euiToolTipAnimationHorizontal = (size: string) => keyframes`
`;
export const euiToolTipStyles = (euiThemeContext: UseEuiTheme) => {
- const { euiTheme, colorMode } = euiThemeContext;
+ const { euiTheme, colorMode, highContrastMode } = euiThemeContext;
+
+ const hasShadow = !highContrastMode;
+ const hasVisibleBorder = highContrastMode || colorMode === 'DARK';
const animationTiming = `${euiTheme.animation.slow} ease-out 0s forwards`;
- // Shift arrow 1px more than half its size to account for border radius
+
const arrowSize = euiTheme.size.m;
- const arrowPlusSize = mathWithUnits(arrowSize, (x) => (x / 2 + 1) * -1);
- const arrowMinusSize = mathWithUnits(arrowSize, (x) => (x / 2 - 1) * -1);
+ const arrowStyles = _popoverArrowStyles(euiThemeContext, arrowSize);
+
return {
// Base
euiToolTip: css`
- ${euiShadow(euiThemeContext)}
+ ${hasShadow ? euiShadow(euiThemeContext) : ''}
+ border: ${euiTheme.border.width.thin} solid
+ ${hasVisibleBorder ? euiTheme.border.color : 'transparent'};
border-radius: ${euiTheme.border.radius.medium};
background-color: ${euiToolTipBackgroundColor(euiTheme, colorMode)};
color: ${euiTheme.colors.ghost};
@@ -114,30 +114,11 @@ export const euiToolTipStyles = (euiThemeContext: UseEuiTheme) => {
`,
// Arrow
euiToolTip__arrow: css`
- content: '';
- position: absolute;
- transform-origin: center;
- border-radius: ${mathWithUnits(
- euiTheme.border.radius.small,
- (x) => x / 2
- )};
- background-color: ${euiToolTipBackgroundColor(euiTheme, colorMode)};
- ${logicalSizeCSS(arrowSize, arrowSize)}
+ ${arrowStyles._arrowStyles}
+ background-color: inherit;
+ border: inherit;
`,
- arrowPositions: {
- top: css`
- transform: translateY(${arrowPlusSize}) rotateZ(45deg);
- `,
- bottom: css`
- transform: translateY(${arrowMinusSize}) rotateZ(45deg);
- `,
- left: css`
- transform: translateX(${arrowPlusSize}) rotateZ(45deg);
- `,
- right: css`
- transform: translateX(${arrowMinusSize}) rotateZ(45deg);
- `,
- },
+ arrowPositions: arrowStyles.positions,
// Title
euiToolTip__title: css`
font-weight: ${euiTheme.font.weight.bold};
diff --git a/packages/eui/src/components/tool_tip/tool_tip.tsx b/packages/eui/src/components/tool_tip/tool_tip.tsx
index 616ca2b5ab0..ff3112f8aa0 100644
--- a/packages/eui/src/components/tool_tip/tool_tip.tsx
+++ b/packages/eui/src/components/tool_tip/tool_tip.tsx
@@ -17,6 +17,7 @@ import classNames from 'classnames';
import { CommonProps } from '../common';
import { findPopoverPosition, htmlIdGenerator, keys } from '../../services';
+import { type EuiPopoverPosition } from '../../services/popover';
import { enqueueStateChange } from '../../services/react';
import { EuiResizeObserver } from '../observer/resize_observer';
import { EuiPortal } from '../portal';
@@ -117,7 +118,7 @@ interface State {
hasFocus: boolean;
calculatedPosition: ToolTipPositions;
toolTipStyles: ToolTipStyles;
- arrowStyles: undefined | { left: number; top: number };
+ arrowStyles?: Record
;
id: string;
}
diff --git a/packages/eui/src/components/tour/__snapshots__/tour_step.test.tsx.snap b/packages/eui/src/components/tour/__snapshots__/tour_step.test.tsx.snap
index 0aa353e4849..73848e8ae1b 100644
--- a/packages/eui/src/components/tour/__snapshots__/tour_step.test.tsx.snap
+++ b/packages/eui/src/components/tour/__snapshots__/tour_step.test.tsx.snap
@@ -27,13 +27,16 @@ exports[`EuiTourStep renders 1`] = `
data-popover-open="true"
data-popover-panel="true"
role="dialog"
- style="top: -22px; left: -26px; will-change: transform, opacity; z-index: 2000;"
+ style="top: -18px; left: -26px; will-change: transform, opacity; z-index: 2000;"
>
+
({
// Targets EuiPopoverPanel
euiTour: css`
- [data-popover-arrow='top']::before {
- ${logicalCSS('border-top-color', _tourFooterBgColor(euiThemeContext))}
+ [data-popover-arrow='top'] {
+ background-color: ${_tourFooterBgColor(euiThemeContext)};
}
`,
});
export const euiTourBeaconStyles = ({ euiTheme }: UseEuiTheme) => {
- const arrowSize = euiTheme.size[popoverArrowSize];
- const arrowHalfSize = mathWithUnits(arrowSize, (x) => x / 2);
- const arrowOffset = mathWithUnits(arrowSize, (x) => x * -2);
+ const beaconSize = euiTheme.size.m;
+ const beaconOffset = mathWithUnits(beaconSize, (x) => x / -2);
return {
// Base
@@ -45,20 +43,24 @@ export const euiTourBeaconStyles = ({ euiTheme }: UseEuiTheme) => {
`,
// Positions
right: css`
- ${logicalCSS('top', arrowHalfSize)}
- ${logicalCSS('left', arrowOffset)}
+ ${logicalCSS('top', '50%')}
+ ${logicalCSS('left', '-50%')}
+ ${logicalCSS('margin-top', beaconOffset)}
`,
left: css`
- ${logicalCSS('top', arrowHalfSize)}
- ${logicalCSS('left', arrowSize)}
+ ${logicalCSS('top', '50%')}
+ ${logicalCSS('right', '-50%')}
+ ${logicalCSS('margin-top', beaconOffset)}
`,
top: css`
- ${logicalCSS('top', arrowSize)}
- ${logicalCSS('left', arrowHalfSize)}
+ ${logicalCSS('left', '50%')}
+ ${logicalCSS('bottom', '-50%')}
+ ${logicalCSS('margin-left', beaconOffset)}
`,
bottom: css`
- ${logicalCSS('top', arrowOffset)}
- ${logicalCSS('left', arrowHalfSize)}
+ ${logicalCSS('left', '50%')}
+ ${logicalCSS('top', '-50%')}
+ ${logicalCSS('margin-left', beaconOffset)}
`,
};
};
diff --git a/packages/eui/src/global_styling/mixins/_color.ts b/packages/eui/src/global_styling/mixins/_color.ts
index 74087f584ff..d36fd84eafa 100644
--- a/packages/eui/src/global_styling/mixins/_color.ts
+++ b/packages/eui/src/global_styling/mixins/_color.ts
@@ -131,7 +131,7 @@ export const useEuiBackgroundColorCSS = () =>
*/
export const euiBorderColor = (
- { euiTheme, colorMode }: UseEuiTheme,
+ { euiTheme, colorMode, highContrastMode }: UseEuiTheme,
color: _EuiBackgroundColor
) => {
switch (color) {
@@ -140,9 +140,13 @@ export const euiBorderColor = (
case 'subdued':
return euiTheme.border.color;
case 'warning':
- return tintOrShade(euiTheme.colors.warning, 0.4, colorMode);
+ return highContrastMode
+ ? euiTheme.colors.warningText
+ : tintOrShade(euiTheme.colors.warning, 0.4, colorMode);
default:
- return tintOrShade(euiTheme.colors[color], 0.6, colorMode);
+ return highContrastMode
+ ? euiTheme.colors[`${color}Text`]
+ : tintOrShade(euiTheme.colors[color], 0.6, colorMode);
}
};
diff --git a/packages/eui/src/global_styling/variables/shadow.ts b/packages/eui/src/global_styling/variables/shadow.ts
index 7761fbdb9a0..e8bd284645b 100644
--- a/packages/eui/src/global_styling/variables/shadow.ts
+++ b/packages/eui/src/global_styling/variables/shadow.ts
@@ -25,4 +25,5 @@ export const _EuiShadowSizesDescriptions: Record<_EuiThemeShadowSize, string> =
export interface _EuiThemeShadowCustomColor {
color?: string;
property?: 'box-shadow' | 'filter';
+ borderAllInHighContrastMode?: boolean;
}
diff --git a/packages/eui/src/services/popover/index.ts b/packages/eui/src/services/popover/index.ts
index b89b73f6184..9553f62ccf4 100644
--- a/packages/eui/src/services/popover/index.ts
+++ b/packages/eui/src/services/popover/index.ts
@@ -8,4 +8,7 @@
export { calculatePopoverPosition } from './calculate_popover_position';
export { findPopoverPosition, getElementZIndex } from './popover_positioning';
+
+// Not exported as public APIs
+export { _popoverArrowStyles } from './popover_arrow.styles';
export type { EuiPopoverPosition } from './types';
diff --git a/packages/eui/src/services/popover/popover_arrow.styles.ts b/packages/eui/src/services/popover/popover_arrow.styles.ts
new file mode 100644
index 00000000000..860f88e1e05
--- /dev/null
+++ b/packages/eui/src/services/popover/popover_arrow.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 {
+ logicalCSS,
+ logicalSizeCSS,
+ mathWithUnits,
+} from '../../global_styling/functions';
+import { UseEuiTheme } from '../../services';
+
+/**
+ * Arrow clipping/transform/positioning CSS shared between EuiPopover and EuiToolTip
+ */
+export const _popoverArrowStyles = (
+ { euiTheme }: UseEuiTheme,
+ arrowSize: string
+) => {
+ const arrowOffset = mathWithUnits(arrowSize, (x) => x / -2);
+
+ const arrowBorderRadius = mathWithUnits(
+ euiTheme.border.radius.small,
+ (x) => x / 2
+ );
+
+ return {
+ _arrowStyles: `
+ position: absolute;
+ ${logicalSizeCSS(arrowSize)}
+ border-radius: ${arrowBorderRadius};
+ /* Use clip-path to ensure that arrows don't overlap into popover content */
+ clip-path: polygon(0 0, 100% 100%, 0 100%);
+ transform-origin: center;
+ `,
+
+ positions: {
+ top: css`
+ ${logicalCSS('margin-top', arrowOffset)}
+ transform: rotate(-45deg);
+ `,
+
+ bottom: css`
+ ${logicalCSS('bottom', 0)}
+ ${logicalCSS('margin-bottom', arrowOffset)}
+ transform: rotate(135deg);
+ `,
+
+ left: css`
+ ${logicalCSS('margin-left', arrowOffset)}
+ transform: rotate(-135deg);
+ `,
+
+ right: css`
+ ${logicalCSS('right', 0)}
+ ${logicalCSS('margin-right', arrowOffset)}
+ transform: rotate(45deg);
+ `,
+ },
+ };
+};
diff --git a/packages/eui/src/services/popover/popover_positioning.test.ts b/packages/eui/src/services/popover/popover_positioning.test.ts
index bae2c9d40ec..c31abd94f25 100644
--- a/packages/eui/src/services/popover/popover_positioning.test.ts
+++ b/packages/eui/src/services/popover/popover_positioning.test.ts
@@ -337,8 +337,8 @@ describe('popover_positioning', () => {
top: 40,
left: 25,
arrow: {
- top: 50,
- left: 22.5,
+ top: '100%',
+ left: 21.5,
},
});
});
@@ -359,8 +359,8 @@ describe('popover_positioning', () => {
top: -15,
left: 37.5,
arrow: {
- top: 50,
- left: 10,
+ top: '100%',
+ left: 9,
},
});
});
@@ -382,8 +382,8 @@ describe('popover_positioning', () => {
top: -15,
left: 37.5,
arrow: {
- top: 50,
- left: 10,
+ top: '100%',
+ left: 9,
},
});
});
@@ -406,8 +406,8 @@ describe('popover_positioning', () => {
top: 50,
left: 75,
arrow: {
- top: 50,
- left: 22,
+ top: '100%',
+ left: 21,
},
});
@@ -426,8 +426,8 @@ describe('popover_positioning', () => {
top: 110,
left: 25,
arrow: {
- top: 0,
- left: 72,
+ bottom: '100%',
+ left: 71,
},
});
});
@@ -448,8 +448,8 @@ describe('popover_positioning', () => {
top: -82,
left: 125,
arrow: {
- top: 184,
- left: 0,
+ top: 183,
+ right: '100%',
},
});
});
diff --git a/packages/eui/src/services/popover/popover_positioning.ts b/packages/eui/src/services/popover/popover_positioning.ts
index 8cc1a131600..933b5478140 100644
--- a/packages/eui/src/services/popover/popover_positioning.ts
+++ b/packages/eui/src/services/popover/popover_positioning.ts
@@ -83,7 +83,7 @@ interface FindPopoverPositionResult {
left: number;
position: EuiPopoverPosition;
fit: number;
- arrow?: { left: number; top: number };
+ arrow?: Record;
anchorBoundingBox?: EuiClientRect;
}
@@ -265,7 +265,7 @@ interface GetPopoverScreenCoordinatesResult {
top: number;
left: number;
fit: number;
- arrow: { top: number; left: number } | undefined;
+ arrow?: Record;
}
/**
@@ -360,14 +360,12 @@ export function getPopoverScreenCoordinates({
const primaryAxisPositionName =
dimensionPositionAttribute[primaryAxisDimension]; // "height" -> "top"
- const { primaryAxisPosition, primaryAxisArrowPosition } =
- getPrimaryAxisPosition({
- position,
- offset,
- popoverBoundingBox,
- anchorBoundingBox,
- arrowConfig,
- });
+ const { primaryAxisPosition } = getPrimaryAxisPosition({
+ position,
+ offset,
+ popoverBoundingBox,
+ anchorBoundingBox,
+ });
const popoverPlacement = {
[crossAxisFirstSide]: crossAxisPosition,
@@ -401,18 +399,18 @@ export function getPopoverScreenCoordinates({
);
const arrow = arrowConfig
- ? {
+ ? ({
[crossAxisFirstSide]:
- crossAxisArrowPosition! - popoverPlacement[crossAxisFirstSide],
- [primaryAxisPositionName]: primaryAxisArrowPosition,
- }
+ crossAxisArrowPosition! - popoverPlacement[crossAxisFirstSide] - 1, // Account for 1px border thin width
+ [position]: '100%',
+ } as Record)
: undefined;
return {
fit,
top: popoverPlacement.top,
left: popoverPlacement.left,
- arrow: arrow ? { left: arrow.left!, top: arrow.top! } : undefined,
+ arrow,
};
}
@@ -560,7 +558,6 @@ interface GetPrimaryAxisPositionArgs {
offset: number;
popoverBoundingBox: BoundingBox;
anchorBoundingBox: BoundingBox;
- arrowConfig?: { arrowWidth: number; arrowBuffer: number };
}
function getPrimaryAxisPosition({
@@ -568,7 +565,6 @@ function getPrimaryAxisPosition({
offset,
popoverBoundingBox,
anchorBoundingBox,
- arrowConfig,
}: GetPrimaryAxisPositionArgs) {
// if positioning to the top or left, the target position decreases
// from the anchor's top or left, otherwise the position adds to the anchor's
@@ -591,18 +587,7 @@ function getPrimaryAxisPosition({
(offset + primaryAxisOffset!) * (isOffsetDecreasing ? -1 : 1);
const primaryAxisPosition = anchorEdgeOrigin + contentOffset;
- let primaryAxisArrowPosition;
-
- if (arrowConfig) {
- primaryAxisArrowPosition = isOffsetDecreasing
- ? popoverSizeOnPrimaryAxis
- : 0;
- }
-
- return {
- primaryAxisPosition,
- primaryAxisArrowPosition,
- };
+ return { primaryAxisPosition };
}
/**
diff --git a/packages/eui/src/services/theme/provider.stories.tsx b/packages/eui/src/services/theme/provider.stories.tsx
index 63c8a20f6aa..de54247f3d3 100644
--- a/packages/eui/src/services/theme/provider.stories.tsx
+++ b/packages/eui/src/services/theme/provider.stories.tsx
@@ -123,6 +123,6 @@ export const HighContrastMode: Story = {
tags: ['vrt-only'],
args: {
highContrastMode: true,
- children: High contrast mode,
+ children: High contrast mode,
},
};
diff --git a/packages/eui/src/themes/amsterdam/global_styling/mixins/shadow.ts b/packages/eui/src/themes/amsterdam/global_styling/mixins/shadow.ts
index f183e9423ce..ea3d4253ee2 100644
--- a/packages/eui/src/themes/amsterdam/global_styling/mixins/shadow.ts
+++ b/packages/eui/src/themes/amsterdam/global_styling/mixins/shadow.ts
@@ -26,7 +26,7 @@ export const euiShadowXSmall = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -46,7 +46,7 @@ export const euiShadowSmall = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -67,7 +67,7 @@ export const euiShadowMedium = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -96,7 +96,7 @@ export const euiShadowLarge = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -121,7 +121,7 @@ export const euiShadowXLarge = (
options?: EuiShadowXLarge
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -144,7 +144,7 @@ export const euiSlightShadowHover = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -175,7 +175,7 @@ export const euiShadowFlat = (
options?: _EuiThemeShadowCustomColor
) => {
if (highContrastMode) {
- return _highContrastBorderBottom(euiTheme);
+ return _highContrastBorder(euiTheme, options);
}
const color = options?.color || euiTheme.colors.shadow;
@@ -201,7 +201,7 @@ export const euiShadow = (
options?: _EuiThemeShadowCustomColor
) => {
if (euiThemeContext.highContrastMode) {
- return _highContrastBorderBottom(euiThemeContext.euiTheme);
+ return _highContrastBorder(euiThemeContext.euiTheme, options);
}
switch (size) {
@@ -236,5 +236,11 @@ export const useEuiShadow = (
* so we use `border` CSS explicitly instead of shadows
*/
-const _highContrastBorderBottom = ({ border }: UseEuiTheme['euiTheme']) =>
- logicalCSS('border-bottom', border.thin);
+const _highContrastBorder = (
+ { border }: UseEuiTheme['euiTheme'],
+ { borderAllInHighContrastMode }: _EuiThemeShadowCustomColor = {}
+) => {
+ return borderAllInHighContrastMode
+ ? `border: ${border.thin};`
+ : logicalCSS('border-bottom', border.thin);
+};