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] Buttons, datepicker redux, code blocks, and avatars #8210

Merged
merged 18 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ce89ba3
[EuiButton] Add high contrast borders for increased visibility
cee-chen Dec 6, 2024
684beb6
[EuiButtonGroup] Add high contrast borders
cee-chen Dec 6, 2024
b0f3485
[EuiCard] Fix incorrect `euiButtonColor` usage
cee-chen Dec 7, 2024
061ee4a
[react-datepicker] Fix button high contrast border change affecting h…
cee-chen Dec 7, 2024
3395168
[react-datepicker] refactor need for separate high contrast util
cee-chen Dec 7, 2024
d325940
[react-datepicker] Continue DRYing out button colors, which removes n…
cee-chen Dec 7, 2024
586a17b
[react-datepicker] some more variable DRYing, just because
cee-chen Dec 7, 2024
7c0bfb3
[react-datepicker] Update VRT + add high contrast VRT
cee-chen Dec 7, 2024
3650885
[EuiFilterButton/Group] Fix Windows high contrast border rendering
cee-chen Dec 7, 2024
e02e316
[EuiResizableButton] Fix Windows rendering + improve preferred
cee-chen Dec 9, 2024
7fafd85
[vrt] update remaining EuiResizable* screenshots
cee-chen Dec 9, 2024
88bacaa
[EuiBetaBadge] Improve high contrast rendering
cee-chen Dec 6, 2024
f21dfa0
[EuiNotificationBadge] Render borders in Windows high contrast themes
cee-chen Dec 6, 2024
a7c91c9
[EuiCodeBlock] Add high contrast border
cee-chen Dec 6, 2024
7a1f045
[EuiCodeBlock] Improve contrast of line highlights/annotations
cee-chen Dec 6, 2024
92ab05a
[EuiCode] Address tech debt TODO
cee-chen Nov 28, 2024
8f78880
[EuiAvatar] Windows high contrast mode tweaks
cee-chen Dec 6, 2024
63dab9e
[PR feedback] [EuiButtonGroup] Improve border color consistency in hi…
cee-chen Dec 10, 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
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.
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.
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.
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.
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 13 additions & 2 deletions packages/eui/src/components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
euiPaletteColorBlindBehindText,
toInitials,
useEuiMemoizedStyles,
useEuiTheme,
} from '../../services';
import { IconType, EuiIcon, IconSize, IconColor } from '../icon';

Expand Down Expand Up @@ -126,10 +127,12 @@ export const EuiAvatar: FunctionComponent<EuiAvatarProps> = ({
}) => {
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',
Expand Down Expand Up @@ -174,20 +177,28 @@ export const EuiAvatar: FunctionComponent<EuiAvatarProps> = ({
}
}, [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 (
<div
css={cssStyles}
className={classes}
style={{ ...style, ...avatarStyle }}
style={{ ...style, ...avatarStyle, ...highContrastBorder }}
aria-label={isDisabled ? undefined : name}
role={isDisabled ? 'presentation' : 'img'}
title={name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
* Side Public License, v 1.
*/

import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';

import { EuiTitle } from '../../title';

import { EuiBetaBadge, EuiBetaBadgeProps } from './beta_badge';

const meta: Meta<EuiBetaBadgeProps> = {
Expand All @@ -34,3 +37,18 @@ export const Playground: Story = {
label: 'Beta',
},
};

export const TitleAlignment: Story = {
tags: ['vrt-only'],
args: {
label: 'Beta',
},
render: (args: EuiBetaBadgeProps) => (
<EuiTitle size="s">
<h1>
Beta badges will also line up nicely with titles{' '}
<EuiBetaBadge {...args} />
</h1>
</EuiTitle>
),
};
43 changes: 24 additions & 19 deletions packages/eui/src/components/badge/beta_badge/beta_badge.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { css } from '@emotion/react';
import {
logicalCSS,
logicalSizeCSS,
euiFocusRing,
euiFontSizeFromScale,
euiTextTruncate,
Expand All @@ -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};
Expand All @@ -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`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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)};
Expand All @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions packages/eui/src/components/button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
* Side Public License, v 1.
*/

import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';

import {
disableStorybookControls,
enableFunctionToggleControls,
} from '../../../.storybook/utils';

import { EuiButtonEmpty } from './button_empty';
import { EuiButton, Props as EuiButtonProps } from './button';

const meta: Meta<EuiButtonProps> = {
Expand Down Expand Up @@ -49,3 +51,16 @@ export const Playground: Story = {
},
};
disableStorybookControls(Playground, ['buttonRef']);

export const HighContrast: Story = {
tags: ['vrt-only'],
globals: { highContrastMode: true },
render: () => (
<div css={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
<EuiButton>Button</EuiButton>
<EuiButton fill>Filled</EuiButton>
<EuiButton disabled>Disabled</EuiButton>
<EuiButtonEmpty>Empty</EuiButtonEmpty>
</div>
),
};
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<>
<EuiButtonGroup {...props} color="primary" />
<br />
<br />
<EuiButtonGroup {...props} buttonSize="compressed" />
</>
);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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;
}
`,
});
};
Loading