Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

High contrast mode support #8232

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5fe668e
[EuiProvider][EuiThemeProvider] `highContrastMode` set up and documen…
cee-chen Nov 21, 2024
a55ed3d
Remove `no-extra-semicolons` stylelint rule
cee-chen Nov 12, 2024
8339bf7
[High Contrast Mode] Panels, modals, flyouts, toasts, popovers, and t…
cee-chen Nov 27, 2024
112f1e5
[High Contrast Mode] Form controls (#8193)
cee-chen Dec 2, 2024
478ea3f
[High Contrast Mode] Ranges, color pickers, and date pickers (#8199)
cee-chen Dec 5, 2024
7edd66c
[High Contrast Mode] Allow forced high contrast themes to also force …
cee-chen Dec 4, 2024
7ca2a69
[High contrast mode] DRY utilities (#8205)
cee-chen Dec 6, 2024
569f13d
[High Contrast Mode] Buttons, datepicker redux, code blocks, and avat…
cee-chen Dec 10, 2024
5d0084b
[High Contrast Mode] Horizontal rules, side navs, tabs, and breadcrum…
cee-chen Dec 11, 2024
6c415ca
[High Contrast Mode] Loading components and beacons (#8215)
cee-chen Dec 11, 2024
841ef86
[High Contrast Mode] Markdown, highlighting, misc text fixes (#8219)
cee-chen Dec 11, 2024
8e6f8c1
[High Contrast Mode] EuiKeyPadMenu, EuiImage, EuiOverlayMask, EuiBott…
cee-chen Dec 12, 2024
82c62d4
[High Contrast Mode] Steps, timelines, and comment lists (#8223)
cee-chen Dec 12, 2024
bdbbdf6
[High Contrast Mode] Tables and data grid (#8226)
cee-chen Dec 12, 2024
0997448
Update changelog file
cee-chen Dec 12, 2024
03229db
[PR feedback] Changelog typo
cee-chen Dec 12, 2024
578de0b
docs: ensure high contrast mode works in EUI+
mgadewoll Dec 12, 2024
34e5db8
[High Contrast Mode] new_final_final(2).psd (#8234)
cee-chen Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[High Contrast Mode] Horizontal rules, side navs, tabs, and breadcrum…
…bs (#8218)
  • Loading branch information
cee-chen committed Dec 12, 2024
commit 5d0084bb98af511f58373bf2fff0b02873c51c88
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import {
logicalBorderRadiusCSS,
mathWithUnits,
} from '../../global_styling';
import { highContrastModeStyles } from '../../global_styling/functions/high_contrast';
import { euiButtonColor } from '../../themes/amsterdam/global_styling/mixins/button';

/**
* Styles cast to inner <a>, <button>, <span> elements
*/
export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme, colorMode } = euiThemeContext;
const { euiTheme, colorMode, highContrastMode } = euiThemeContext;

// Reuse button colors for `type="application`" clickable breadcrumbs
const applicationButtonColors = euiButtonColor(euiThemeContext, 'primary');
Expand All @@ -39,6 +40,28 @@ export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
color: tintOrShade(euiTheme.colors.darkestShade, 0.2, colorMode),
};

// Create an arrow "border" in high contrast modes. We have to use a
// filter/drop-shadow workaround to get a border working with clip-path.
// Note: the filter must be on the parent wrapper, not on the clipped element
const dropShadow = (borderColor: string) =>
`filter: drop-shadow(${euiTheme.border.width.thin} 0 0 ${
highContrastMode === 'forced' ? euiTheme.border.color : borderColor
});`;
const applicationHighContrastArrow = highContrastModeStyles(euiThemeContext, {
preferred: `
&:is(a, button) {
.euiBreadcrumb:has(&) {
${dropShadow(applicationButtonColors.color)}
}
}
&:not(a, button) {
.euiBreadcrumb:has(&) {
${dropShadow(applicationTextColors.color)}
}
}
`,
});

return {
euiBreadcrumb__content: css`
/* Unset EuiLink's bolder font weight */
Expand Down Expand Up @@ -90,38 +113,38 @@ export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
${euiFontSize(euiThemeContext, 'xs')}
font-weight: ${euiTheme.font.weight.medium};
background-color: ${applicationTextColors.backgroundColor};
clip-path: polygon(
0 0,
calc(100% - ${euiTheme.size.s}) 0,
100% 50%,
calc(100% - ${euiTheme.size.s}) 100%,
0 100%,
${euiTheme.size.s} 50%
);
${highContrastModeStyles(euiThemeContext, {
preferred: `border: ${euiTheme.border.width.thin} solid currentColor;`,
})}
color: ${applicationTextColors.color};
line-height: ${euiTheme.size.base};
${logicalCSS('padding-vertical', euiTheme.size.xs)}
${logicalCSS('padding-horizontal', euiTheme.size.base)}

&:is(a),
&:is(button) {
&:is(a, button) {
background-color: ${applicationButtonColors.backgroundColor};
color: ${applicationButtonColors.color};
}

:focus {
${euiFocusRing(euiThemeContext, 'inset')}
&:focus {
${euiFocusRing(euiThemeContext, 'inset')}
}

:focus-visible {
border-radius: ${euiTheme.border.radius.medium};
clip-path: none;
}
&:focus-visible {
border-radius: ${euiTheme.border.radius.medium};
clip-path: none;

.euiBreadcrumb:has(&) {
z-index: 2;
${highContrastModeStyles(euiThemeContext, {
preferred: 'filter: none;',
})}
}
}
`,
applicationStyles: {
onlyChild: css`
border-radius: ${euiTheme.border.radius.medium};
clip-path: none;
${logicalCSS('padding-horizontal', euiTheme.size.m)}
`,
firstChild: css`
Expand All @@ -137,6 +160,18 @@ export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
0 100%
);
${logicalCSS('padding-left', euiTheme.size.m)}
${applicationHighContrastArrow}
`,
intermediateChild: `
clip-path: polygon(
0 0,
calc(100% - ${euiTheme.size.s}) 0,
100% 50%,
calc(100% - ${euiTheme.size.s}) 100%,
0 100%,
${euiTheme.size.s} 50%
);
${applicationHighContrastArrow}
`,
lastChild: css`
${logicalBorderRadiusCSS(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,19 @@ export const EuiBreadcrumbContent: FunctionComponent<
const classes = classNames('euiBreadcrumb__content', className);

const styles = useEuiMemoizedStyles(euiBreadcrumbContentStyles);
const cssStyles = [styles.euiBreadcrumb__content, styles[type]];
const cssStyles: ArrayCSSInterpolation = [
styles.euiBreadcrumb__content,
styles[type],
];
if (isApplication) {
if (isOnlyBreadcrumb) {
cssStyles.push(styles.applicationStyles.onlyChild);
} else if (isFirstBreadcrumb) {
cssStyles.push(styles.applicationStyles.firstChild);
} else if (isLastBreadcrumb) {
cssStyles.push(styles.applicationStyles.lastChild);
} else {
cssStyles.push(styles.applicationStyles.intermediateChild);
}
}
const truncationStyles = [
Expand Down
10 changes: 2 additions & 8 deletions packages/eui/src/components/breadcrumbs/breadcrumb.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ export const euiBreadcrumbStyles = (euiThemeContext: UseEuiTheme) => {
euiBreadcrumb: css`
align-items: center;
display: flex;
${logicalCSS(
// See .euiBreadcrumbs__list's negative margin-bottom
'margin-bottom',
euiTheme.size.xs
)}
`,
isTruncated: css`
overflow: hidden;
Expand All @@ -36,15 +31,14 @@ export const euiBreadcrumbStyles = (euiThemeContext: UseEuiTheme) => {
page: css`
&:not(:last-of-type) {
&::after {
background: ${euiTheme.colors.lightShade};
content: '';
flex-shrink: 0;
${logicalCSS('margin-top', euiTheme.size.xs)}
${logicalCSS('margin-bottom', 0)}
${logicalCSS('margin-horizontal', euiTheme.size.s)}
${logicalCSS('height', euiTheme.size.base)}
${logicalCSS('width', '1px')}
transform: translateY(-1px) rotate(15deg);
${logicalCSS('border-right', euiTheme.border.thin)}
transform: translateY(-${euiTheme.border.width.thin}) rotate(15deg);
}
}
`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ export const euiBreadcrumbsListStyles = (euiThemeContext: UseEuiTheme) => {
display: flex;
flex-wrap: wrap;
line-height: ${euiTheme.size.l};
${logicalCSS(
// Add vertical space between breadcrumbs, but make sure the whole breadcrumb set doesn't add space below itself
'margin-bottom',
`-${euiTheme.size.xs}`
)}
row-gap: ${euiTheme.size.xs};
${logicalCSS(
// Ensure it shrinks if the window is narrow
'min-width',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ export const Playground: Story = {
],
},
};

export const HighContrast: Story = {
...Playground,
tags: ['vrt-only'],
globals: { highContrastMode: true },
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,59 @@

import { css } from '@emotion/react';
import { logicalCSS } from '../../global_styling';
import { highContrastModeStyles } from '../../global_styling/functions/high_contrast';
import { UseEuiTheme } from '../../services';

export const euiHorizontalRuleStyles = ({ euiTheme }: UseEuiTheme) => ({
euiHorizontalRule: css`
border: none;
${logicalCSS('height', euiTheme.border.width.thin)}
background-color: ${euiTheme.border.color};
/* Ensure when used in flex group, it retains its size */
flex-shrink: 0;
flex-grow: 0;
`,
export const euiHorizontalRuleStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme } = euiThemeContext;
return {
euiHorizontalRule: css`
border: none;
${highContrastModeStyles(euiThemeContext, {
none: `
${logicalCSS('height', euiTheme.border.width.thin)}
background-color: ${euiTheme.border.color};
`,
// Windows high contrast themes ignore background colors
forced: logicalCSS('border-bottom', euiTheme.border.thin),
})}
/* Ensure when used in flex group, it retains its size */
flex-shrink: 0;
flex-grow: 0;
`,

// Sizes
full: css`
${logicalCSS('width', '100%')}
`,
half: css`
${logicalCSS('width', '50%')}
${logicalCSS('margin-horizontal', 'auto')}
`,
quarter: css`
${logicalCSS('width', '25%')}
${logicalCSS('margin-horizontal', 'auto')}
`,
// Sizes
full: css`
${logicalCSS('width', '100%')}
`,
half: css`
${logicalCSS('width', '50%')}
${logicalCSS('margin-horizontal', 'auto')}
`,
quarter: css`
${logicalCSS('width', '25%')}
${logicalCSS('margin-horizontal', 'auto')}
`,

// Margins
none: '',
xs: css`
margin-block: ${euiTheme.size.s};
`,
s: css`
margin-block: ${euiTheme.size.m};
`,
m: css`
margin-block: ${euiTheme.size.base};
`,
l: css`
margin-block: ${euiTheme.size.l};
`,
xl: css`
margin-block: ${euiTheme.size.xl};
`,
xxl: css`
margin-block: ${euiTheme.size.xxl};
`,
});
// Margins
none: '',
xs: css`
margin-block: ${euiTheme.size.s};
`,
s: css`
margin-block: ${euiTheme.size.m};
`,
m: css`
margin-block: ${euiTheme.size.base};
`,
l: css`
margin-block: ${euiTheme.size.l};
`,
xl: css`
margin-block: ${euiTheme.size.xl};
`,
xxl: css`
margin-block: ${euiTheme.size.xxl};
`,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ export const euiSideNavItemStyles = (euiThemeContext: UseEuiTheme) => {
content: '';
${logicalCSS('vertical', 0)}
${logicalCSS('left', 0)}
${logicalCSS('width', euiTheme.border.width.thin)}
background-color: ${euiTheme.border.color};
${logicalCSS('border-left', euiTheme.border.thin)}
}

/* If this is actually the last item, we don't want the vertical line to stretch all the way down */
Expand Down Expand Up @@ -166,8 +165,7 @@ export const euiSideNavItemButtonStyles = (euiThemeContext: UseEuiTheme) => {
${logicalCSS('top', euiTheme.size.m)}
${logicalCSS('left', 0)}
${logicalCSS('width', euiTheme.size.xs)}
${logicalCSS('height', euiTheme.border.width.thin)}
background-color: ${euiTheme.border.color};
${logicalCSS('border-bottom', euiTheme.border.thin)}
}
`,

Expand Down
31 changes: 28 additions & 3 deletions packages/eui/src/components/tabs/tab.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ import { css } from '@emotion/react';
import { logicalCSS, mathWithUnits, euiFontSize } from '../../global_styling';
import { UseEuiTheme } from '../../services';

export const euiTabStyles = ({ euiTheme }: UseEuiTheme) => {
export const euiTabStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme, highContrastMode } = euiThemeContext;

const selectedUnderlineSize = highContrastMode
? mathWithUnits(euiTheme.border.thick, (x) => x * 2)
: euiTheme.border.width.thick;

return {
euiTab: css`
position: relative;
display: flex;
cursor: pointer;
flex-direction: row;
Expand All @@ -28,6 +35,17 @@ export const euiTabStyles = ({ euiTheme }: UseEuiTheme) => {
&:focus {
outline-offset: -${euiTheme.focus.width};
}

/* Selected underline - use a pseudo element instead of box-shadow for easier
color setting, as well as Windows high contrast theme rendering */
&::after {
position: absolute;
${logicalCSS('bottom', 0)}
${logicalCSS('horizontal', 0)}
${logicalCSS('border-bottom-style', 'solid')}
${logicalCSS('border-bottom-width', selectedUnderlineSize)}
pointer-events: none;
}
`,
// variations
expanded: css`
Expand All @@ -36,16 +54,23 @@ export const euiTabStyles = ({ euiTheme }: UseEuiTheme) => {
justify-content: center;
`,
selected: css`
box-shadow: inset 0 -${euiTheme.border.width.thick} 0 ${euiTheme.colors.primary};
color: ${euiTheme.colors.primaryText};

&::after {
content: '';
border-color: ${euiTheme.colors.primary};
}
`,
disabled: {
disabled: css`
cursor: not-allowed;
color: ${euiTheme.colors.disabledText};
`,
selected: css`
box-shadow: inset 0 -${euiTheme.border.width.thick} 0 ${euiTheme.colors.disabledText};
&::after {
content: '';
border-color: ${euiTheme.colors.disabledText};
}
`,
},
};
Expand Down
6 changes: 5 additions & 1 deletion packages/eui/src/components/tabs/tabs.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { css } from '@emotion/react';
import { logicalCSS, logicalCSSWithFallback } from '../../global_styling';
import { highContrastModeStyles } from '../../global_styling/functions/high_contrast';
import { UseEuiTheme } from '../../services';

export const euiTabsStyles = (euiThemeContext: UseEuiTheme) => {
Expand All @@ -23,7 +24,10 @@ export const euiTabsStyles = (euiThemeContext: UseEuiTheme) => {
flex-shrink: 0;
`,
bottomBorder: css`
box-shadow: inset 0 -${euiTheme.border.width.thin} 0 ${euiTheme.border.color};
${highContrastModeStyles(euiThemeContext, {
none: `box-shadow: inset 0 -${euiTheme.border.width.thin} 0 ${euiTheme.border.color};`,
forced: logicalCSS('border-bottom', euiTheme.border.thin),
})}
`,
// sizes
s: css`
Expand Down