diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiAvatar_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiAvatar_Playground.png index 88bfba2aef1..c57647cdd35 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiAvatar_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiAvatar_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Playground.png index 48a3ae2efc3..337819a67fa 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Title_Alignment.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Title_Alignment.png new file mode 100644 index 00000000000..96a6a9cd28f Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiBetaBadge_Title_Alignment.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Display_EuiNotificationBadge_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Display_EuiNotificationBadge_Playground.png index 91fb689dcdd..f306fc51005 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Display_EuiNotificationBadge_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Display_EuiNotificationBadge_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_High_Contrast.png new file mode 100644 index 00000000000..0d4d5c5e4d3 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png b/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png index f50feea42cc..b366af92333 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png and b/packages/eui/.loki/reference/chrome_desktop_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_High_Contrast.png new file mode 100644 index 00000000000..3a764e22f9f Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_High_Contrast.png new file mode 100644 index 00000000000..f4463aa2a20 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png index 5a912c528f9..61fc234d404 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png index 10a2e147d56..c0a9894fcf2 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Full_Width_And_Grow.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Full_Width_And_Grow.png index 4f368a56ccc..acae0bdc5ae 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Full_Width_And_Grow.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Full_Width_And_Grow.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_High_Contrast.png new file mode 100644 index 00000000000..78980edc926 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Multiple_Buttons.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Multiple_Buttons.png index 953a571a030..c88cec89ef0 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Multiple_Buttons.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Multiple_Buttons.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Playground.png index e104fba7eb2..472da9a0366 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterButton_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Multiple_Popovers.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Multiple_Popovers.png index 554e7fac72d..ab9fc9f76d1 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Multiple_Popovers.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Multiple_Popovers.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Playground.png index e104fba7eb2..472da9a0366 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_With_Popover.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_With_Popover.png index addc5e8e5d4..73a8e8ea030 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_With_Popover.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiFilterGroup_With_Popover.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png index be431e6092e..41adf03a5e6 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png index f86e3afc02d..17bd838e817 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png new file mode 100644 index 00000000000..6a27d94f061 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png index 8b875f7e415..b55cdf33e95 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png index 6a3450edabb..c294287cdde 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonEmpty_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonEmpty_Playground.png index ea94e15c0a8..a5a04d43775 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonEmpty_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonEmpty_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_High_Contrast.png new file mode 100644 index 00000000000..e5bbd88deda Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Multi_Selection.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Multi_Selection.png index 9e997512402..9a11a0af60f 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Multi_Selection.png and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Multi_Selection.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Single_Selection.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Single_Selection.png index 9e997512402..9a11a0af60f 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Single_Selection.png and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_Single_Selection.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_With_Tooltips.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_With_Tooltips.png index f01cfedf46d..bf05c66c0eb 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_With_Tooltips.png and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButtonGroup_With_Tooltips.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_High_Contrast.png new file mode 100644 index 00000000000..07f92cedb63 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_Playground.png index 1f565af1cc1..e233be44f7f 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Navigation_EuiButton_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiAvatar_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiAvatar_Playground.png index 1d10ff60e0e..470898f24f9 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiAvatar_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiAvatar_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Playground.png index 2ef6d0c0e3f..a20de7d7c71 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Title_Alignment.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Title_Alignment.png new file mode 100644 index 00000000000..ec0b542ab5c Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiBetaBadge_Title_Alignment.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Display_EuiNotificationBadge_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Display_EuiNotificationBadge_Playground.png index 2b742522ba7..2c030144e81 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Display_EuiNotificationBadge_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Display_EuiNotificationBadge_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_High_Contrast.png new file mode 100644 index 00000000000..07199eaddd5 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png b/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png index a49bed9c0ac..0082f0cecdf 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png and b/packages/eui/.loki/reference/chrome_mobile_Editors_Syntax_EuiCodeBlock_Highlighted_Lines.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_High_Contrast.png new file mode 100644 index 00000000000..3382927c5b9 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_High_Contrast.png new file mode 100644 index 00000000000..3642736f32a Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png index 7581d33dbf4..4466ee73138 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png index f5ceec053c4..a41cc028904 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Full_Width_And_Grow.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Full_Width_And_Grow.png index e8974e4a98b..facbe8036be 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Full_Width_And_Grow.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Full_Width_And_Grow.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_High_Contrast.png new file mode 100644 index 00000000000..fb448619161 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Multiple_Buttons.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Multiple_Buttons.png index 18d9d55cd28..c59a9fc87bc 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Multiple_Buttons.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Multiple_Buttons.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Playground.png index b8441ac74fd..68f31a4ce11 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterButton_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Multiple_Popovers.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Multiple_Popovers.png index fba5ca718d5..8b719ab42f8 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Multiple_Popovers.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Multiple_Popovers.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Playground.png index b8441ac74fd..68f31a4ce11 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_With_Popover.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_With_Popover.png index 9df3cd6ede3..595f3ebdb8c 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_With_Popover.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiFilterGroup_With_Popover.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png index a54becc7f34..acd9de6e477 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Collapsible_Panels.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png index d67e90a4870..b51e5b8dec0 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_EuiResizableContainer_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png new file mode 100644 index 00000000000..3c5f5d96645 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png index 1b2a6189ab4..85b4e51b896 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizableCollapseButton_Production_Usage.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png index c4fe9edfa68..139720b93ac 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiResizableContainer_Subcomponents_EuiResizablePanel_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonEmpty_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonEmpty_Playground.png index db55463c9ba..c36978f7718 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonEmpty_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonEmpty_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_High_Contrast.png new file mode 100644 index 00000000000..a4d6facb284 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Multi_Selection.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Multi_Selection.png index 9c79216a724..133060874ae 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Multi_Selection.png and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Multi_Selection.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Single_Selection.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Single_Selection.png index 9c79216a724..133060874ae 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Single_Selection.png and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_Single_Selection.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_With_Tooltips.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_With_Tooltips.png index f6d5ea7f8f4..8e9319252df 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_With_Tooltips.png and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButtonGroup_With_Tooltips.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_High_Contrast.png new file mode 100644 index 00000000000..d685e40f6d0 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_Playground.png index 6731bd56a16..d8a5608cb5e 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Navigation_EuiButton_Playground.png differ diff --git a/packages/eui/src/components/avatar/avatar.tsx b/packages/eui/src/components/avatar/avatar.tsx index fc410e87abc..8bf445c8cc7 100644 --- a/packages/eui/src/components/avatar/avatar.tsx +++ b/packages/eui/src/components/avatar/avatar.tsx @@ -15,6 +15,7 @@ import { euiPaletteColorBlindBehindText, toInitials, useEuiMemoizedStyles, + useEuiTheme, } from '../../services'; import { IconType, EuiIcon, IconSize, IconColor } from '../icon'; @@ -126,10 +127,12 @@ export const EuiAvatar: FunctionComponent = ({ }) => { checkValidInitials(initials); const { casing = type === 'space' ? 'none' : 'uppercase', ...rest } = props; + const { highContrastMode, euiTheme } = useEuiTheme(); const isPlain = color === 'plain'; const isSubdued = color === 'subdued'; const isNamedColor = isPlain || isSubdued || color === null; + const isForcedColors = highContrastMode === 'forced'; const classes = classNames( 'euiAvatar', @@ -174,20 +177,28 @@ export const EuiAvatar: FunctionComponent = ({ } }, [imageUrl, color, isNamedColor, name.length]); + const highContrastBorder = useMemo( + // Render a border since background-colors are ignored in Windows forced contrast themes + () => (isForcedColors ? { border: euiTheme.border.thin } : undefined), + [isForcedColors, euiTheme] + ); + const iconCustomColor = useMemo(() => { + // Force icons to single colors in forced high contrast mode + if (isForcedColors) return euiTheme.colors.fullShade; // `null` allows icons to keep their default color (e.g. app icons) if (iconColor === null) return undefined; // Otherwise continue to pass on `iconColor` if (iconColor) return iconColor; // Fall back to the adjusted text color if it exists return avatarStyle?.color; - }, [iconColor, avatarStyle?.color]); + }, [iconColor, avatarStyle?.color, isForcedColors, euiTheme]); return (
= { @@ -34,3 +37,18 @@ export const Playground: Story = { label: 'Beta', }, }; + +export const TitleAlignment: Story = { + tags: ['vrt-only'], + args: { + label: 'Beta', + }, + render: (args: EuiBetaBadgeProps) => ( + +

+ Beta badges will also line up nicely with titles{' '} + +

+
+ ), +}; diff --git a/packages/eui/src/components/badge/beta_badge/beta_badge.styles.ts b/packages/eui/src/components/badge/beta_badge/beta_badge.styles.ts index 625e21d99a5..af08ada3785 100644 --- a/packages/eui/src/components/badge/beta_badge/beta_badge.styles.ts +++ b/packages/eui/src/components/badge/beta_badge/beta_badge.styles.ts @@ -9,6 +9,7 @@ import { css } from '@emotion/react'; import { logicalCSS, + logicalSizeCSS, euiFocusRing, euiFontSizeFromScale, euiTextTruncate, @@ -21,10 +22,25 @@ export const euiBetaBadgeStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme, colorMode } = euiThemeContext; const badgeColors = euiBadgeColors(euiThemeContext); + const sizes = { + m: { + height: euiTheme.size.l, + padding: euiTheme.size.base, + }, + s: { + height: mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base), + padding: euiTheme.size.m, + }, + }; + // Line height is needed over inline-flex centering for text `vertical-align`ment + const getLineHeight = (height: string) => + mathWithUnits([height, euiTheme.border.width.thin], (x, y) => x - y * 2); + return { euiBetaBadge: css` display: inline-block; border-radius: ${euiTheme.size.l}; + border: ${euiTheme.border.width.thin} solid transparent; cursor: default; font-weight: ${euiTheme.font.weight.bold}; @@ -46,38 +62,27 @@ export const euiBetaBadgeStyles = (euiThemeContext: UseEuiTheme) => { hollow: css` color: ${badgeColors.hollow.color}; background-color: ${badgeColors.hollow.backgroundColor}; - box-shadow: inset 0 0 0 ${euiTheme.border.width.thin} - ${badgeColors.hollow.borderColor}; + border-color: ${badgeColors.hollow.borderColor}; `, warning: css(badgeColors.warning), // Font sizes m: css` font-size: ${euiFontSizeFromScale('xs', euiTheme)}; - line-height: ${euiTheme.size.l}; + line-height: ${getLineHeight(sizes.m.height)}; `, s: css` - font-size: 0.625rem; - line-height: ${mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base)}; + font-size: ${euiFontSizeFromScale('xxxs', euiTheme)}; + line-height: ${getLineHeight(sizes.s.height)}; `, - // Padding/width sizes badgeSizes: { default: { - m: ` - ${logicalCSS('padding-horizontal', euiTheme.size.base)}`, - s: ` - ${logicalCSS('padding-horizontal', euiTheme.size.m)}`, + m: logicalCSS('padding-horizontal', sizes.m.padding), + s: logicalCSS('padding-horizontal', sizes.s.padding), }, // When it's just an icon or a single letter, make the badge a circle circle: { - m: ` - ${logicalCSS('width', euiTheme.size.l)} - `, - s: ` - ${logicalCSS( - 'width', - mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base) - )} - `, + m: logicalSizeCSS(sizes.m.height), + s: logicalSizeCSS(sizes.s.height), }, }, euiBetaBadge__icon: css` diff --git a/packages/eui/src/components/badge/notification_badge/badge_notification.styles.ts b/packages/eui/src/components/badge/notification_badge/badge_notification.styles.ts index 04e0c4bb2e6..722ba4aeda8 100644 --- a/packages/eui/src/components/badge/notification_badge/badge_notification.styles.ts +++ b/packages/eui/src/components/badge/notification_badge/badge_notification.styles.ts @@ -14,6 +14,7 @@ import { euiNumberFormat, mathWithUnits, } from '../../../global_styling'; +import { highContrastModeStyles } from '../../../global_styling/functions/high_contrast'; import { UseEuiTheme } from '../../../services'; import { euiBadgeColors } from '../color_utils'; @@ -24,10 +25,18 @@ export const euiNotificationBadgeStyles = (euiThemeContext: UseEuiTheme) => { return { euiNotificationBadge: css` flex-shrink: 0; /* Ensures it never scales down below its intended size */ - display: inline-block; + display: inline-flex; + justify-content: center; + align-items: center; vertical-align: middle; ${logicalCSS('padding-horizontal', euiTheme.size.xs)} border-radius: ${euiTheme.border.radius.small}; + ${highContrastModeStyles(euiThemeContext, { + forced: ` + border: ${euiTheme.border.thin}; + overflow: hidden; /* Fix text clipping */ + `, + })} cursor: default; font-size: ${euiFontSizeFromScale('xs', euiTheme)}; @@ -41,12 +50,10 @@ export const euiNotificationBadgeStyles = (euiThemeContext: UseEuiTheme) => { `, // Sizes s: css` - line-height: ${euiTheme.size.base}; ${logicalCSS('height', euiTheme.size.base)} ${logicalCSS('min-width', euiTheme.size.base)} `, m: css` - line-height: ${mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base)}; ${logicalCSS( 'height', mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base) diff --git a/packages/eui/src/components/button/button.stories.tsx b/packages/eui/src/components/button/button.stories.tsx index f6135409d97..dfb9e9e7691 100644 --- a/packages/eui/src/components/button/button.stories.tsx +++ b/packages/eui/src/components/button/button.stories.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { @@ -13,6 +14,7 @@ import { enableFunctionToggleControls, } from '../../../.storybook/utils'; +import { EuiButtonEmpty } from './button_empty'; import { EuiButton, Props as EuiButtonProps } from './button'; const meta: Meta = { @@ -49,3 +51,16 @@ export const Playground: Story = { }, }; disableStorybookControls(Playground, ['buttonRef']); + +export const HighContrast: Story = { + tags: ['vrt-only'], + globals: { highContrastMode: true }, + render: () => ( +
+ Button + Filled + Disabled + Empty +
+ ), +}; diff --git a/packages/eui/src/components/button/button_group/button_group.stories.tsx b/packages/eui/src/components/button/button_group/button_group.stories.tsx index 41537d321ea..8ec87a08ae6 100644 --- a/packages/eui/src/components/button/button_group/button_group.stories.tsx +++ b/packages/eui/src/components/button/button_group/button_group.stories.tsx @@ -155,3 +155,32 @@ export const WithTooltips: Story = { idToSelectedMap: { button1: true }, }, }; + +export const HighContrast: Story = { + tags: ['vrt-only'], + globals: { highContrastMode: true }, + render: () => { + const props = { + options: [ + { id: '1', label: 'One', isDisabled: true }, + { id: '2', label: 'Two' }, + { id: '3', label: 'Three' }, + { id: '4', label: 'Four' }, + { id: '5', label: 'Five' }, + { id: '6', label: 'Six' }, + ], + type: 'multi' as const, + idToSelectedMap: { '3': true, '4': true }, + legend: '', + onChange: () => {}, + }; + return ( + <> + +
+
+ + + ); + }, +}; diff --git a/packages/eui/src/components/button/button_group/button_group.styles.ts b/packages/eui/src/components/button/button_group/button_group.styles.ts index cd934fc9d26..048ad0c60d5 100644 --- a/packages/eui/src/components/button/button_group/button_group.styles.ts +++ b/packages/eui/src/components/button/button_group/button_group.styles.ts @@ -9,6 +9,10 @@ import { css } from '@emotion/react'; import { UseEuiTheme } from '../../../services'; import { logicalCSS } from '../../../global_styling'; +import { + highContrastModeStyles, + preventForcedColors, +} from '../../../global_styling/functions/high_contrast'; import { euiFormVariables } from '../../form/form.styles'; export const euiButtonGroupStyles = { @@ -50,15 +54,64 @@ export const euiButtonGroupButtonsStyles = (euiThemeContext: UseEuiTheme) => { // Sizes m: css` border-radius: ${euiTheme.border.radius.medium}; + ${_highContrastStyles(euiThemeContext)} `, s: css` border-radius: ${euiTheme.border.radius.small}; + ${_highContrastStyles(euiThemeContext)} `, compressed: css` ${logicalCSS('height', controlCompressedHeight)} background-color: ${backgroundColor}; border: ${euiTheme.border.width.thin} solid ${borderColor}; border-radius: ${controlCompressedBorderRadius}; + ${_highContrastStyles(euiThemeContext, true)} `, }; }; + +const _highContrastStyles = ( + euiThemeContext: UseEuiTheme, + compressed?: boolean +) => { + const { euiTheme } = euiThemeContext; + + // Account for buttons within tooltip wrappers in selectors + const getButtonChildSelectors = (selector: string) => ` + & > .euiButtonGroupButton${selector}, + & > .euiButtonGroup__tooltipWrapper${selector} .euiButtonGroupButton`; + + return highContrastModeStyles(euiThemeContext, { + preferred: compressed + ? ` + .euiButtonGroupButton { + border: none; + } + ` + : // Conditionally unset the high contrast borders passed by `euiButtonColor` - + // faux borders between selected/unselected buttons are rendered by pseudo elements, + // and can flip colors depending on selected/unselected siblings + ` + ${getButtonChildSelectors(':not(:first-child, :last-child)')} { + ${logicalCSS('border-horizontal', 'none')} + } + ${getButtonChildSelectors(':first-child')} { + ${logicalCSS('border-right', 'none')} + } + ${getButtonChildSelectors(':last-child')} { + ${logicalCSS('border-left', 'none')} + } + `, + forced: ` + .euiButtonGroupButton-isSelected { + ${preventForcedColors(euiThemeContext)} + color: ${euiTheme.colors.emptyShade}; + background-color: ${euiTheme.colors.fullShade}; + } + + .euiButtonGroupButton[disabled] { + opacity: 0.5; + } + `, + }); +}; diff --git a/packages/eui/src/components/button/button_group/button_group_button.styles.ts b/packages/eui/src/components/button/button_group/button_group_button.styles.ts index 2074d38e79a..5b5a0e1324f 100644 --- a/packages/eui/src/components/button/button_group/button_group_button.styles.ts +++ b/packages/eui/src/components/button/button_group/button_group_button.styles.ts @@ -31,7 +31,7 @@ import { euiScreenReaderOnly } from '../../accessibility'; import { euiFormVariables } from '../../form/form.styles'; export const euiButtonGroupButtonStyles = (euiThemeContext: UseEuiTheme) => { - const { euiTheme } = euiThemeContext; + const { euiTheme, highContrastMode } = euiThemeContext; const { controlCompressedHeight, controlCompressedBorderRadius } = euiFormVariables(euiThemeContext); @@ -82,20 +82,46 @@ export const euiButtonGroupButtonStyles = (euiThemeContext: UseEuiTheme) => { } `, get borders() { + // We use pseudo elements to avoid affecing button width, and to allow + // inheriting high contrast border colors const selectors = '.euiButtonGroupButton-isSelected, .euiButtonGroup__tooltipWrapper-isSelected'; - const selectedColor = transparentize(euiTheme.colors.emptyShade, 0.2); - const unselectedColor = transparentize(euiTheme.colors.fullShade, 0.1); - const borderWidth = euiTheme.border.width.thin; + const selectedColor = highContrastMode + ? euiTheme.colors.emptyShade + : transparentize(euiTheme.colors.emptyShade, 0.2); + const unselectedColor = highContrastMode + ? 'inherit' + : transparentize(euiTheme.colors.fullShade, 0.1); // "Borders" between buttons should be present between two of the same colored buttons, // and absent between selected vs non-selected buttons (different colors) return ` + position: relative; + + &::before { + position: absolute; + ${logicalCSS('left', 0)} + ${logicalCSS( + 'vertical', + highContrastMode ? `-${euiTheme.border.width.thin}` : 0 + )} + ${logicalCSS('border-left-style', 'solid')} + ${logicalCSS('border-left-width', euiTheme.border.width.thin)} + pointer-events: none; + } + &:not(${selectors}) + *:not(${selectors}) { - box-shadow: -${borderWidth} 0 0 0 ${unselectedColor}; + &::before { + content: ''; + border-color: ${unselectedColor}; + } } + &:is(${selectors}) + *:is(${selectors}) { - box-shadow: -${borderWidth} 0 0 0 ${selectedColor}; + &::before { + content: ''; + border-color: ${selectedColor}; + } } `; }, diff --git a/packages/eui/src/components/card/card.styles.ts b/packages/eui/src/components/card/card.styles.ts index 40330325af4..fdd7be66970 100644 --- a/packages/eui/src/components/card/card.styles.ts +++ b/packages/eui/src/components/card/card.styles.ts @@ -67,8 +67,7 @@ export const euiCardStyles = ( }, disabled: css` cursor: not-allowed; /* Duplicate property due to Chrome bug */ - background-color: ${euiButtonColor(euiThemeContext, 'disabled')}; - color: ${euiTheme.colors.disabledText}; + ${euiButtonColor(euiThemeContext, 'disabled')} `, }, diff --git a/packages/eui/src/components/code/__snapshots__/utils.test.tsx.snap b/packages/eui/src/components/code/__snapshots__/utils.test.tsx.snap index 0c229ef9d34..2bd4013988c 100644 --- a/packages/eui/src/components/code/__snapshots__/utils.test.tsx.snap +++ b/packages/eui/src/components/code/__snapshots__/utils.test.tsx.snap @@ -1009,7 +1009,7 @@ exports[`line utils highlightByLine with line numbers with highlighted lines add "properties": { "className": [ "euiCodeBlock__lineText", - "css-96t2rh-euiCodeBlock__lineText-isHighlighted", + "css-qzoymg-euiCodeBlock__lineText-isHighlighted", ], }, "tagName": "span", @@ -1160,7 +1160,7 @@ exports[`line utils highlightByLine with line numbers with highlighted lines add "properties": { "className": [ "euiCodeBlock__lineText", - "css-96t2rh-euiCodeBlock__lineText-isHighlighted", + "css-qzoymg-euiCodeBlock__lineText-isHighlighted", ], }, "tagName": "span", diff --git a/packages/eui/src/components/code/code_block.stories.tsx b/packages/eui/src/components/code/code_block.stories.tsx index 7d4d0b7f832..082b01f7907 100644 --- a/packages/eui/src/components/code/code_block.stories.tsx +++ b/packages/eui/src/components/code/code_block.stories.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import React from 'react'; import type { Meta, StoryObj, ReactRenderer } from '@storybook/react'; import type { PlayFunctionContext } from '@storybook/csf'; @@ -102,3 +103,32 @@ export const Annotations: Story = { expect(dialog).toHaveTextContent('Hello world'); }, }; + +export const HighContrast: Story = { + tags: ['vrt-only'], + globals: { highContrastMode: true }, + args: { + language: 'json', + lineNumbers: { + start: 32, + highlight: '32, 34-37, 40', + annotations: { + 34: ( + <> + A special note about this line + + ), + 38: 'Also accepts quick plaintext notes', + }, + }, + children: `"OriginLocation": [ + { + "coordinates": [ + -97.43309784, + 37.64989853 + ], + "type": "Point" + } +],`, + }, +}; diff --git a/packages/eui/src/components/code/code_block.styles.ts b/packages/eui/src/components/code/code_block.styles.ts index 895051a72cc..b9eebda59d6 100644 --- a/packages/eui/src/components/code/code_block.styles.ts +++ b/packages/eui/src/components/code/code_block.styles.ts @@ -13,6 +13,7 @@ import { euiScrollBarStyles, mathWithUnits, } from '../../global_styling'; +import { highContrastModeStyles } from '../../global_styling/functions/high_contrast'; import { UseEuiTheme } from '../../services'; import { euiCodeSyntaxVariables } from './code_syntax.styles'; @@ -27,6 +28,9 @@ export const euiCodeBlockStyles = (euiThemeContext: UseEuiTheme) => { display: block; position: relative; background: ${codeSyntaxVariables.backgroundColor}; + ${highContrastModeStyles(euiThemeContext, { + preferred: `border: ${euiTheme.border.thin};`, + })} ${codeSyntaxVariables.tokensCss} `, diff --git a/packages/eui/src/components/code/code_block_annotations.style.ts b/packages/eui/src/components/code/code_block_annotations.style.ts index b9faf685fc1..ade4170b3cd 100644 --- a/packages/eui/src/components/code/code_block_annotations.style.ts +++ b/packages/eui/src/components/code/code_block_annotations.style.ts @@ -12,9 +12,11 @@ import { logicalSizeCSS, mathWithUnits, } from '../../global_styling'; +import { highContrastModeStyles } from '../../global_styling/functions/high_contrast'; import { UseEuiTheme } from '../../services'; -export const euiCodeBlockAnnotationsStyles = ({ euiTheme }: UseEuiTheme) => { +export const euiCodeBlockAnnotationsStyles = (euiThemeContext: UseEuiTheme) => { + const { euiTheme } = euiThemeContext; const buttonIconSize = mathWithUnits(euiTheme.size.base, (x) => x - 1.5); return { @@ -30,8 +32,15 @@ export const euiCodeBlockAnnotationsStyles = ({ euiTheme }: UseEuiTheme) => { display: flex; align-items: center; justify-content: center; - background-color: ${euiTheme.colors.primary}; border-radius: 50%; + ${highContrastModeStyles(euiThemeContext, { + none: `background-color: ${euiTheme.colors.primary};`, + // Windows high contrast themes ignore background-color + forced: ` + border: ${mathWithUnits(buttonIconSize, (x) => x / 2)} solid ${ + euiTheme.colors.primary + };`, + })} `, }; }; diff --git a/packages/eui/src/components/code/code_block_line.styles.ts b/packages/eui/src/components/code/code_block_line.styles.ts index 74766b8dbbe..6b1402101b0 100644 --- a/packages/eui/src/components/code/code_block_line.styles.ts +++ b/packages/eui/src/components/code/code_block_line.styles.ts @@ -14,14 +14,26 @@ */ import { css } from '@emotion/css'; -import { euiBackgroundColor } from '../../global_styling'; +import { euiBackgroundColor, mathWithUnits } from '../../global_styling'; import { UseEuiTheme } from '../../services'; // Note: These styles must be in a separate file due to using `css` from `@emotion/css` // (i.e., applying styles in vanilla JS / directly to DOM nodes instead of React) export const euiCodeBlockLineStyles = (euiThemeContext: UseEuiTheme) => { - const { euiTheme } = euiThemeContext; + const { euiTheme, highContrastMode } = euiThemeContext; + + const lineMargins = euiTheme.size.m; + const lineWidth = euiTheme.border.width.thin; + + // Increase highlight border width in high contrast modes + const highlightWidth = highContrastMode + ? mathWithUnits(euiTheme.border.width.thick, (x) => x * 1.5) + : euiTheme.border.width.thick; + const highlightOffset = mathWithUnits( + [lineMargins, lineWidth, highlightWidth], + (x, y, z) => x + y - z + ); return { euiCodeBlock__line: css` @@ -35,14 +47,14 @@ export const euiCodeBlockLineStyles = (euiThemeContext: UseEuiTheme) => { euiCodeBlock__lineText: css` flex-grow: 1; display: inline-block; - padding-inline-start: ${euiTheme.size.m}; - border-inline-start: ${euiTheme.border.thin}; + padding-inline-start: ${lineMargins}; + border-inline-start: ${lineWidth} solid ${euiTheme.border.color}; user-select: text; `, isHighlighted: css` background: ${euiBackgroundColor(euiThemeContext, 'primary')}; - border-inline-start: ${euiTheme.border.width.thick} solid - ${euiTheme.colors.primary}; + border-inline-start: ${highlightWidth} solid ${euiTheme.colors.primary}; + padding-inline-start: ${highlightOffset}; `, }, lineNumber: { @@ -51,7 +63,7 @@ export const euiCodeBlockLineStyles = (euiThemeContext: UseEuiTheme) => { flex-grow: 0; flex-shrink: 0; user-select: none; - padding-inline-end: ${euiTheme.size.m}; + padding-inline-end: ${lineMargins}; box-sizing: content-box; /* Width is calculated in JS and padding needs to be added on to that value */ `, euiCodeBlock__lineNumber: css` diff --git a/packages/eui/src/components/code/code_syntax.styles.ts b/packages/eui/src/components/code/code_syntax.styles.ts index 4a7b9e374bb..f8b4fa0b51b 100644 --- a/packages/eui/src/components/code/code_syntax.styles.ts +++ b/packages/eui/src/components/code/code_syntax.styles.ts @@ -14,13 +14,21 @@ import { const visColors = euiPaletteColorBlind(); +export const euiCodeTextColors = ({ euiTheme }: UseEuiTheme) => { + return { + backgroundColor: euiTheme.colors.lightestShade, + color: euiTheme.colors.text, + }; +}; + // These variables are computationally expensive - do not call them outside `useEuiMemoizedStyles` -export const euiCodeSyntaxVariables = ({ euiTheme }: UseEuiTheme) => { - const backgroundColor = euiTheme.colors.lightestShade; +export const euiCodeSyntaxVariables = (euiThemeContext: UseEuiTheme) => { + const { backgroundColor, color } = euiCodeTextColors(euiThemeContext); + const { euiTheme } = euiThemeContext; return { - backgroundColor: backgroundColor, - color: makeHighContrastColor(euiTheme.colors.text)(backgroundColor), + backgroundColor, + color, inlineCodeColor: makeHighContrastColor(visColors[3])(backgroundColor), selectedBackgroundColor: 'inherit', commentColor: makeHighContrastColor(euiTheme.colors.subduedText)( diff --git a/packages/eui/src/components/date_picker/date_picker.stories.tsx b/packages/eui/src/components/date_picker/date_picker.stories.tsx index c0fb6439e9e..9aea2690272 100644 --- a/packages/eui/src/components/date_picker/date_picker.stories.tsx +++ b/packages/eui/src/components/date_picker/date_picker.stories.tsx @@ -205,6 +205,16 @@ export const RestrictedDaySelect: Story = { }, }; +export const HighContrast: Story = { + tags: ['vrt-only'], + globals: { highContrastMode: true }, + args: { + ...TimeSelect.args, + ...RestrictedDaySelect.args, + selected: moment('01/02/1970').hours(23).minutes(0), + }, +}; + const StatefulDatePicker = ({ selected, onChange, diff --git a/packages/eui/src/components/date_picker/date_picker_range.stories.tsx b/packages/eui/src/components/date_picker/date_picker_range.stories.tsx index fb6a21b5711..612e49e58db 100644 --- a/packages/eui/src/components/date_picker/date_picker_range.stories.tsx +++ b/packages/eui/src/components/date_picker/date_picker_range.stories.tsx @@ -118,6 +118,12 @@ export const FullWidth: Story = { render: (args) => , }; +export const HighContrast: Story = { + ...RestrictedSelection, + tags: ['vrt-only'], + globals: { highContrastMode: true }, +}; + /** * Helpers */ diff --git a/packages/eui/src/components/date_picker/react_date_picker.styles.ts b/packages/eui/src/components/date_picker/react_date_picker.styles.ts index bc7e6944fd6..661050d2f22 100644 --- a/packages/eui/src/components/date_picker/react_date_picker.styles.ts +++ b/packages/eui/src/components/date_picker/react_date_picker.styles.ts @@ -8,9 +8,6 @@ // Needs to use vanilla `css` to pass a className directly to react-datepicker import { css } from '@emotion/css'; -// Emotion can handle serializing objects passed directly to css``, but not objs nested -// in another function util, so we need to serialize some style objects manually -import { serializeStyles } from '@emotion/serialize'; import { UseEuiTheme } from '../../services'; import { @@ -19,12 +16,10 @@ import { euiFontSize, euiYScroll, logicalCSS, + logicalSizeCSS, mathWithUnits, } from '../../global_styling'; -import { - highContrastModeStyles, - preventForcedColors, -} from '../../global_styling/functions/high_contrast'; +import { highContrastModeStyles } from '../../global_styling/functions/high_contrast'; import { euiButtonColor, euiButtonEmptyColor, @@ -37,7 +32,13 @@ import { euiFormControlDefaultShadow, } from '../form/form.styles'; -export const euiDatePickerVariables = ({ euiTheme }: UseEuiTheme) => { +export const euiDatePickerVariables = (euiThemeContext: UseEuiTheme) => { + const { euiTheme, highContrastMode } = euiThemeContext; + const unsetHighContrastBorder = (styles: T) => ({ + ...styles, + border: undefined, + }); + return { gapSize: euiTheme.size.xs, get paddingSize() { @@ -51,13 +52,59 @@ export const euiDatePickerVariables = ({ euiTheme }: UseEuiTheme) => { (x, y) => x + y ); }, + + colors: { + day: { + inMonth: euiTheme.colors.title, + outsideMonth: euiTheme.colors.subduedText, + header: euiTheme.colors.subduedText, + today: euiTheme.colors.primary, + }, + + hover: unsetHighContrastBorder( + euiButtonColor(euiThemeContext, 'primary') + ), + disabled: unsetHighContrastBorder( + euiButtonColor(euiThemeContext, 'disabled') + ), + + get inRange() { + return this.hover; + }, + inRangeAndDisabled: { + backgroundColor: euiButtonEmptyColor(euiThemeContext, 'primary') + .backgroundColor, + }, + + selected: + highContrastMode !== 'forced' + ? euiButtonFillColor(euiThemeContext, 'primary') + : { + color: euiTheme.colors.emptyShade, + backgroundColor: euiTheme.colors.fullShade, + forcedColorAdjust: 'none', + }, + selectedAndDisabled: + highContrastMode !== 'forced' + ? euiButtonColor(euiThemeContext, 'danger') + : { + color: euiTheme.colors.dangerText, + backgroundColor: euiTheme.colors.emptyShade, + border: `${euiTheme.border.width.thin} solid ${euiTheme.colors.dangerText};`, + }, + + highlighted: euiButtonColor(euiThemeContext, 'success'), + }, + + animationSpeed: euiTheme.animation.fast, }; }; +type DatePickerVars = ReturnType; export const euiReactDatePickerStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme } = euiThemeContext; - const { gapSize, paddingSize, headerOffset } = - euiDatePickerVariables(euiThemeContext); + const datePickerVars = euiDatePickerVariables(euiThemeContext); + const { gapSize, paddingSize, headerOffset } = datePickerVars; return { euiReactDatePicker: css` @@ -144,14 +191,17 @@ export const euiReactDatePickerStyles = (euiThemeContext: UseEuiTheme) => { } } - ${_monthYearDropdowns(euiThemeContext)} - ${_dayCalendarStyles(euiThemeContext)} - ${_timeSelectStyles(euiThemeContext)} + ${_monthYearDropdowns(euiThemeContext, datePickerVars)} + ${_dayCalendarStyles(euiThemeContext, datePickerVars)} + ${_timeSelectStyles(euiThemeContext, datePickerVars)} `, }; }; -export const _monthYearDropdowns = (euiThemeContext: UseEuiTheme) => { +const _monthYearDropdowns = ( + euiThemeContext: UseEuiTheme, + { colors }: DatePickerVars +) => { const { euiTheme } = euiThemeContext; const formStyles = euiFormControlStyles(euiThemeContext); @@ -209,10 +259,11 @@ export const _monthYearDropdowns = (euiThemeContext: UseEuiTheme) => { .react-datepicker__year-option, .react-datepicker__month-option, .react-datepicker__month-year-option { + display: flex; + align-items: center; + ${logicalCSS('height', euiTheme.size.l)} ${logicalCSS('margin-vertical', euiTheme.size.xs)} ${logicalCSS('padding-horizontal', euiTheme.size.s)} - ${logicalCSS('height', euiTheme.size.l)} - line-height: ${euiTheme.size.l}; font-size: ${euiFontSize(euiThemeContext, 's').fontSize}; border-radius: ${euiTheme.border.radius.small}; cursor: pointer; @@ -222,12 +273,12 @@ export const _monthYearDropdowns = (euiThemeContext: UseEuiTheme) => { } &--preselected { - background-color: ${euiTheme.focus.backgroundColor}; + ${colors.hover} } &--selected_year, &--selected_month { - ${_highContrastSelected(euiThemeContext)} + ${colors.selected} } /* Hide checkmark next to selected option */ @@ -238,41 +289,37 @@ export const _monthYearDropdowns = (euiThemeContext: UseEuiTheme) => { `; }; -export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { +const _dayCalendarStyles = ( + euiThemeContext: UseEuiTheme, + { gapSize, colors, animationSpeed }: DatePickerVars +) => { const { euiTheme } = euiThemeContext; - const { gapSize } = euiDatePickerVariables(euiThemeContext); const daySize = euiTheme.size.xl; const dayMargin = mathWithUnits(gapSize, (x) => x / 2); - const rangeBackgroundColor = euiButtonColor( - euiThemeContext, - 'primary' - ).backgroundColor; const rangeMarginOffset = mathWithUnits(dayMargin, (x) => x * 1.5); - const animationSpeed = euiTheme.animation.fast; - return css` .react-datepicker__day-names, .react-datepicker__week { display: flex; justify-content: space-between; flex-grow: 1; - color: ${euiTheme.colors.subduedText}; + color: ${colors.day.header}; } .react-datepicker__day-name, .react-datepicker__day { - display: inline-block; - ${logicalCSS('width', daySize)} - line-height: ${daySize}; + display: inline-flex; + justify-content: center; + align-items: center; + ${logicalSizeCSS(daySize)} margin: ${dayMargin}; font-weight: ${euiTheme.font.weight.medium}; - text-align: center; } .react-datepicker__day { - color: ${euiTheme.colors.title}; + color: ${colors.day.inMonth}; border-radius: ${euiTheme.border.radius.small}; ${euiCanAnimate} { @@ -281,7 +328,7 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { } &:hover { - ${euiButtonColor(euiThemeContext, 'primary')} + ${colors.hover} text-decoration: underline; cursor: pointer; @@ -292,26 +339,22 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { } &--today { - color: ${euiTheme.colors.primary}; + color: ${colors.day.today}; font-weight: ${euiTheme.font.weight.bold}; } &--outside-month { - color: ${euiTheme.colors.subduedText}; + color: ${colors.day.outsideMonth}; } &--highlighted, &--highlighted:hover { - ${highContrastModeStyles(euiThemeContext, { - none: serializeStyles([euiButtonColor(euiThemeContext, 'success')]) - .styles, - forced: `border: ${euiTheme.border.thin};`, - })} + ${colors.highlighted} } &--in-range, &--in-range:hover { - ${euiButtonColor(euiThemeContext, 'primary')}; + ${colors.inRange} } ${highContrastModeStyles(euiThemeContext, { @@ -319,16 +362,16 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { // background to fill the gap between margins none: ` &--in-range:not(&--selected):not(:hover):not(&--disabled) { - box-shadow: -${rangeMarginOffset} 0 ${rangeBackgroundColor}, - ${rangeMarginOffset} 0 ${rangeBackgroundColor}; + box-shadow: -${rangeMarginOffset} 0 ${colors.inRange.backgroundColor}, + ${rangeMarginOffset} 0 ${colors.inRange.backgroundColor}; border-radius: 0; &:first-child { - box-shadow: ${rangeMarginOffset} 0 ${rangeBackgroundColor}; + box-shadow: ${rangeMarginOffset} 0 ${colors.inRange.backgroundColor}; } &:last-child { - box-shadow: -${rangeMarginOffset} 0 ${rangeBackgroundColor}; + box-shadow: -${rangeMarginOffset} 0 ${colors.inRange.backgroundColor}; } } /* Animate smoothly on hover */ @@ -346,6 +389,7 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { &--in-range:not(&--selected) { position: relative; transform: none; + &::before { content: ''; position: absolute; @@ -368,15 +412,14 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { &--selected:hover, &--in-selecting-range, &--in-selecting-range:hover { - ${_highContrastSelected(euiThemeContext)} + ${colors.selected} } &--disabled, &--disabled:hover { + ${colors.disabled} ${highContrastModeStyles(euiThemeContext, { - none: serializeStyles([euiButtonColor(euiThemeContext, 'disabled')]) - .styles, - forced: `opacity: 0.5;`, + forced: 'opacity: 0.5;', })} cursor: not-allowed; text-decoration: none; @@ -386,32 +429,27 @@ export const _dayCalendarStyles = (euiThemeContext: UseEuiTheme) => { &--disabled.react-datepicker__day--in-range:not(&--selected) { &, &:hover { - background-color: ${euiButtonEmptyColor(euiThemeContext, 'primary') - .backgroundColor}; + ${colors.inRangeAndDisabled} } } &--in-selecting-range:not(&--in-range), &--disabled.react-datepicker__day--selected, &--disabled.react-datepicker__day--selected:hover { + ${colors.selectedAndDisabled} ${highContrastModeStyles(euiThemeContext, { - none: serializeStyles([euiButtonColor(euiThemeContext, 'danger')]) - .styles, - forced: ` - color: ${euiTheme.colors.dangerText}; - border: ${euiTheme.border.width.thin} solid ${euiTheme.colors.dangerText}; - background-color: ${euiTheme.colors.emptyShade}; - opacity: 1; - `, + forced: 'opacity: 1;', })} } } `; }; -export const _timeSelectStyles = (euiThemeContext: UseEuiTheme) => { - const { euiTheme, highContrastMode } = euiThemeContext; - const { gapSize } = euiDatePickerVariables(euiThemeContext); +const _timeSelectStyles = ( + euiThemeContext: UseEuiTheme, + { gapSize, colors, animationSpeed }: DatePickerVars +) => { + const { euiTheme } = euiThemeContext; return css` .react-datepicker__time-container { @@ -450,14 +488,15 @@ export const _timeSelectStyles = (euiThemeContext: UseEuiTheme) => { } .react-datepicker__time-list-item { - ${logicalCSS('margin-horizontal', 'auto')}; - ${logicalCSS('padding-horizontal', euiTheme.size.s)}; - ${logicalCSS('height', euiTheme.size.l)} - line-height: ${euiTheme.size.l}; + display: flex; + justify-content: align-center; + align-items: center; + ${logicalCSS('min-height', euiTheme.size.l)} + ${logicalCSS('margin-horizontal', 'auto')} + ${logicalCSS('padding-horizontal', euiTheme.size.s)} font-size: ${euiFontSize(euiThemeContext, 'xs').fontSize}; font-weight: ${euiTheme.font.weight.medium}; white-space: nowrap; - text-align: center; border-radius: ${euiTheme.border.radius.small}; &:not(:disabled):hover { @@ -467,28 +506,31 @@ export const _timeSelectStyles = (euiThemeContext: UseEuiTheme) => { &--disabled { cursor: not-allowed; - color: ${euiTheme.colors.disabledText}; + color: ${colors.disabled.color}; } &--injected { - ${highContrastMode !== 'forced' - ? euiButtonEmptyColor(euiThemeContext, 'success') - : `border: ${euiTheme.border.thin};`} + ${colors.highlighted} } &--selected { - ${_highContrastSelected(euiThemeContext)} + ${colors.selected} } /* closest current time but not selected (also applied when using arrow keys to indicate focus) */ &--preselected { - ${highContrastMode !== 'forced' - ? `background-color: ${euiTheme.focus.backgroundColor};` - : `border: ${euiTheme.border.thin};`} + ${colors.hover} + ${highContrastModeStyles(euiThemeContext, { + // Use negative margins to offset the added border width + forced: ` + border: ${euiTheme.border.thin}; + margin-inline: -${euiTheme.border.width.thin}; + `, + })} } ${euiCanAnimate} { - transition: background-color ${euiTheme.animation.fast} ease-in; + transition: background-color ${animationSpeed} ease-in; } } @@ -513,14 +555,3 @@ export const _timeSelectStyles = (euiThemeContext: UseEuiTheme) => { } `; }; - -const _highContrastSelected = (euiThemeContext: UseEuiTheme) => { - const { highContrastMode, euiTheme } = euiThemeContext; - return highContrastMode !== 'forced' - ? euiButtonFillColor(euiThemeContext, 'primary') - : ` - background-color: ${euiTheme.colors.fullShade}; - color: ${euiTheme.colors.emptyShade}; - ${preventForcedColors(euiThemeContext)} - `; -}; diff --git a/packages/eui/src/components/filter_group/filter_button.stories.tsx b/packages/eui/src/components/filter_group/filter_button.stories.tsx index bf881964f74..ef0979a0a28 100644 --- a/packages/eui/src/components/filter_group/filter_button.stories.tsx +++ b/packages/eui/src/components/filter_group/filter_button.stories.tsx @@ -94,3 +94,9 @@ export const FullWidthAndGrow: Story = { ), }; + +export const HighContrast: Story = { + ...FullWidthAndGrow, + tags: ['vrt-only'], + globals: { highContrastMode: true }, +}; diff --git a/packages/eui/src/components/filter_group/filter_button.styles.ts b/packages/eui/src/components/filter_group/filter_button.styles.ts index 682458bde8c..7025a0accdc 100644 --- a/packages/eui/src/components/filter_group/filter_button.styles.ts +++ b/packages/eui/src/components/filter_group/filter_button.styles.ts @@ -28,17 +28,39 @@ export const euiFilterButtonStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme } = euiThemeContext; const { controlHeight, borderColor } = euiFormVariables(euiThemeContext); - // Box shadow simulates borders without affecting width - const leftBoxShadow = `-${euiTheme.border.width.thin} 0 0 0 ${borderColor}`; + const border = `${euiTheme.border.width.thin} solid ${borderColor}`; + + // Pseudo elements create borders without affecting width. We also prefer them + // over box-shadow for Windows high contrast theme compatibility + const leftBorder = ` + &::before { + content: ''; + position: absolute; + ${logicalCSS('right', '100%')} + ${logicalCSS('vertical', 0)} + ${logicalCSS('border-left', border)} + } + `; // Bottom borders are needed for responsive flex-wrap behavior - const bottomBoxShadow = `0 ${euiTheme.border.width.thin} 0 0 ${borderColor}`; + const bottomBorder = ` + &::after { + content: ''; + position: absolute; + ${logicalCSS('top', '100%')} + ${logicalCSS('horizontal', 0)} + ${logicalCSS('border-bottom', border)} + } + `; return { euiFilterButton: css` + position: relative; ${euiFilterButtonDisplay(euiThemeContext)} ${logicalCSS('height', controlHeight)} border-radius: 0; - box-shadow: ${leftBoxShadow}, ${bottomBoxShadow}; + + ${leftBorder} + ${bottomBorder} /* :not(:disabled) specificity needed to override EuiButtonEmpty styles */ &:hover:not(:disabled), @@ -59,8 +81,11 @@ export const euiFilterButtonStyles = (euiThemeContext: UseEuiTheme) => { withNext: css` & + .euiFilterButton { ${logicalCSS('margin-left', `-${euiTheme.size.xs}`)} + /* Remove just the left faux border */ - box-shadow: ${bottomBoxShadow}; + &::before { + display: none; + } } `, noGrow: css` diff --git a/packages/eui/src/components/filter_group/filter_group.styles.ts b/packages/eui/src/components/filter_group/filter_group.styles.ts index 561b04e5612..407742a5fff 100644 --- a/packages/eui/src/components/filter_group/filter_group.styles.ts +++ b/packages/eui/src/components/filter_group/filter_group.styles.ts @@ -11,7 +11,9 @@ import { css } from '@emotion/react'; import { UseEuiTheme } from '../../services'; import { logicalCSS, mathWithUnits, euiBreakpoint } from '../../global_styling'; +import { highContrastModeStyles } from '../../global_styling/functions/high_contrast'; import { euiFormVariables } from '../form/form.styles'; + import { euiFilterButtonDisplay } from './filter_button.styles'; export const euiFilterGroupStyles = (euiThemeContext: UseEuiTheme) => { @@ -32,7 +34,10 @@ export const euiFilterGroupStyles = (euiThemeContext: UseEuiTheme) => { overflow: hidden; background-color: ${backgroundColor}; - box-shadow: inset 0 0 0 ${euiTheme.border.width.thin} ${borderColor}; + ${highContrastModeStyles(euiThemeContext, { + none: `box-shadow: inset 0 0 0 ${euiTheme.border.width.thin} ${borderColor};`, + forced: `border: ${euiTheme.border.thin};`, + })} /* Account for popover or tooltip wrappers around EuiFilterButtons */ > *:not(.euiFilterButton) { diff --git a/packages/eui/src/components/resizable_container/resizable_button.stories.tsx b/packages/eui/src/components/resizable_container/resizable_button.stories.tsx index 04e3597d0a3..127903c4aba 100644 --- a/packages/eui/src/components/resizable_container/resizable_button.stories.tsx +++ b/packages/eui/src/components/resizable_container/resizable_button.stories.tsx @@ -49,3 +49,24 @@ export const Playground: Story = { ), }; + +export const HighContrast: Story = { + tags: ['vrt-only'], + globals: { highContrastMode: true }, + render: () => ( +
+ + + +
+ ), +}; diff --git a/packages/eui/src/components/resizable_container/resizable_button.styles.ts b/packages/eui/src/components/resizable_container/resizable_button.styles.ts index 17d172ef233..c64527556d3 100644 --- a/packages/eui/src/components/resizable_container/resizable_button.styles.ts +++ b/packages/eui/src/components/resizable_container/resizable_button.styles.ts @@ -10,6 +10,10 @@ import { css } from '@emotion/react'; import { UseEuiTheme, transparentize } from '../../services'; import { logicalCSS, mathWithUnits, euiCanAnimate } from '../../global_styling'; +import { + highContrastModeStyles, + preventForcedColors, +} from '../../global_styling/functions/high_contrast'; export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme } = euiThemeContext; @@ -18,7 +22,6 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { const negativeMargin = mathWithUnits(buttonSize, (x) => x / -2); const grabHandleWidth = euiTheme.size.m; const grabHandleHeight = euiTheme.border.width.thin; - const transitionSpeed = euiTheme.animation.fast; const transition = `${transitionSpeed} ease`; @@ -27,11 +30,13 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { // 1. The "grab" handle transforms into a thicker straight line on :hover and :focus // 2. Start/end aligned grab handles should have a slight margin offset that disappears on hover/focus // 3. CSS hack to smooth out/anti-alias the 1px wide handles at various zoom levels + // 4. High contrast modes should not rely on background-color to indicate focus state, but on border width euiResizableButton: css` z-index: 1; flex-shrink: 0; display: flex; justify-content: center; + ${preventForcedColors(euiThemeContext)} /* 4 */ &:disabled { display: none; @@ -48,24 +53,36 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { } } - /* Lighten color on :hover */ - &:hover { - &::before, - &::after { - background-color: ${euiTheme.colors.mediumShade}; - } - } + /* Lighten color on :hover for non-high-contrast modes */ + ${highContrastModeStyles(euiThemeContext, { + /* 4 */ + none: ` + &:hover { + &::before, + &::after { + background-color: ${euiTheme.colors.mediumShade}; + } + }`, + })} /* Add a transparent background to the container and color the border primary with primary color on :focus (NOTE - :active is needed for Safari) */ &:focus, &:active { - background-color: ${transparentize(euiTheme.colors.primary, 0.1)}; + ${highContrastModeStyles(euiThemeContext, { + /* 4 */ + none: ` + background-color: ${transparentize(euiTheme.colors.primary, 0.1)}; + + &::before, + &::after { + background-color: ${euiTheme.colors.primary}; + } + `, + })} &::before, &::after { - background-color: ${euiTheme.colors.primary}; - /* Overrides default transition so that "grab" background-color doesn't animate */ ${euiCanAnimate} { transition: width ${transition}, height ${transition}; @@ -121,6 +138,7 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { ${logicalCSS('height', '100%')} } } + ${_highContrastForcedBorder(euiThemeContext, 'horizontal')} `, vertical: css` &::before { @@ -136,6 +154,7 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { ${logicalCSS('width', '100%')} } } + ${_highContrastForcedBorder(euiThemeContext, 'vertical')} `, }, @@ -190,6 +209,7 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { transform: none; /* 3 */ } } + ${_highContrastForcedBorder(euiThemeContext, 'horizontal')} `, vertical: css` &::before, @@ -210,6 +230,7 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { transform: none; /* 3 */ } } + ${_highContrastForcedBorder(euiThemeContext, 'vertical')} `, }, alignIndicator: { @@ -225,3 +246,27 @@ export const euiResizableButtonStyles = (euiThemeContext: UseEuiTheme) => { }, }; }; + +/* 4 */ +const _highContrastForcedBorder = ( + euiThemeContext: UseEuiTheme, + direction: 'horizontal' | 'vertical' +) => { + const { highContrastMode, euiTheme } = euiThemeContext; + if (!highContrastMode) return ''; + + const dimension = direction === 'horizontal' ? 'width' : 'height'; + + return ` + &:focus, &:active { + &::before, &::after { + ${logicalCSS(dimension, euiTheme.border.width.thick)} + background-color: ${ + highContrastMode === 'forced' + ? euiTheme.border.color + : euiTheme.colors.primary + }; + } + } + `; +}; diff --git a/packages/eui/src/components/text/text.styles.ts b/packages/eui/src/components/text/text.styles.ts index fbafc8bb87c..3512df0d559 100644 --- a/packages/eui/src/components/text/text.styles.ts +++ b/packages/eui/src/components/text/text.styles.ts @@ -13,13 +13,14 @@ import { logicalShorthandCSS, logicalTextAlignCSS, euiFontSize, - euiBackgroundColor, _FontScaleOptions, mathWithUnits, } from '../../global_styling'; +import { highContrastModeStyles } from '../../global_styling/functions/high_contrast'; import { euiLinkCSS } from '../link/link.styles'; import { euiTitle } from '../title/title.styles'; +import { euiCodeTextColors } from '../code/code_syntax.styles'; /** * TODO: Make this a global value so it can be set by theme? @@ -234,6 +235,7 @@ const euiScaleText = ( */ export const euiTextStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme } = euiThemeContext; + const codeColors = euiCodeTextColors(euiThemeContext); return { euiText: css` @@ -303,12 +305,13 @@ export const euiTextStyles = (euiThemeContext: UseEuiTheme) => { color: inherit; } - pre:not(.euiCodeBlock__pre) { + pre:not(.euiCodeBlock > pre) { white-space: pre-wrap; - /* TODO: $euiCodeBlockBackgroundColor - switch to var once EuiCode is converted */ - background: ${euiBackgroundColor(euiThemeContext, 'subdued')}; - /* TODO: $euiCodeBlockColor - switch to var once EuiCode is converted */ - color: ${euiTheme.colors.text}; + background-color: ${codeColors.backgroundColor}; + color: ${codeColors.color}; + ${highContrastModeStyles(euiThemeContext, { + preferred: `border: ${euiTheme.border.thin}`, + })} } pre:not(.euiCodeBlock__pre), diff --git a/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts b/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts index 3a94d5609a2..ca74b0dd3ca 100644 --- a/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts +++ b/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts @@ -46,9 +46,9 @@ export const euiButtonColor = ( color: _EuiButtonColor | 'disabled' ) => { const { euiTheme, colorMode } = euiThemeContext; - function tintOrShade(color: string) { - return colorMode === 'DARK' ? shade(color, 0.7) : tint(color, 0.8); - } + + const tintOrShade = (color: string) => + colorMode === 'DARK' ? shade(color, 0.7) : tint(color, 0.8); let foreground; let background; @@ -58,6 +58,7 @@ export const euiButtonColor = ( return { color: euiTheme.colors.disabledText, backgroundColor: transparentize(euiTheme.colors.lightShade, 0.15), + ..._highContrastBorder(euiThemeContext, euiTheme.colors.disabledText), }; case 'text': foreground = euiTheme.colors[color]; @@ -75,6 +76,7 @@ export const euiButtonColor = ( return { color: makeHighContrastColor(foreground)(background), backgroundColor: background, + ..._highContrastBorder(euiThemeContext, foreground), }; }; @@ -101,9 +103,7 @@ export const euiButtonFillColor = ( switch (color) { case 'disabled': - background = euiButtonColor(euiThemeContext, color).backgroundColor; - foreground = euiButtonColor(euiThemeContext, color).color; - break; + return euiButtonColor(euiThemeContext, color); case 'text': background = colorMode === 'DARK' ? euiTheme.colors.text : euiTheme.colors.darkShade; @@ -129,6 +129,10 @@ export const euiButtonFillColor = ( return { color: foreground, backgroundColor: background, + ..._highContrastBorder( + euiThemeContext, + background // The border is necessary for Windows high contrast themes, which ignore background-color + ), }; }; @@ -297,3 +301,14 @@ export const euiButtonSizeMap = ({ euiTheme }: UseEuiTheme) => ({ fontScale: 's' as const, }, }); + +/** + * Internal util for high contrast button borders + */ +const _highContrastBorder = ( + { highContrastMode, euiTheme }: UseEuiTheme, + color: string +) => + highContrastMode + ? { border: `${euiTheme.border.width.thin} solid ${color}` } + : {};