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] Ranges, color pickers, and date pickers #8199

Merged
merged 18 commits into from
Dec 5, 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
33b1981
[Eui(Dual)Range] Increase track contrast + fix Windows forced rendering
cee-chen Dec 2, 2024
aaa0095
[Eui(Dual)Range] Misc syntax cleanup
cee-chen Dec 3, 2024
6d02877
[Eui(Dual)Range] Set up CSS variable for dynamic thumb colors
cee-chen Dec 3, 2024
bca189a
[Eui(Dual)Range] Improve the visibility of thumbs in high contrast mode
cee-chen Dec 3, 2024
ab074ed
[Eui(Dual)Range] Increase contrast of ticks + fix Win high contrast t…
cee-chen Dec 3, 2024
4d9497e
[Eui(Dual)Range] Fix tooltips in high contrast Windows + increase dar…
cee-chen Dec 3, 2024
1747af4
[EuiColorPalette] Add border + fix Windows high contrast theme display
cee-chen Dec 2, 2024
8f853e7
[EuiColorPalette] Misc optional perf improvements in subcomponents
cee-chen Dec 2, 2024
9538ee5
[EuiColorPicker] Add border + fix hue/saturation pickers in Win high …
cee-chen Dec 2, 2024
7856503
[EuiColorPicker] Fix unnecessary CSS workaround
cee-chen Dec 2, 2024
2c89304
[EuiColorPicker] (opinionated) Increase visible thumb contrast further
cee-chen Dec 2, 2024
859eb61
[EuiColorPicker] Fix alpha selection append display
cee-chen Dec 3, 2024
c016bc5
[react-datepicker] Fix Windows high contrast/forced color modes rende…
cee-chen Nov 27, 2024
d225ace
[EuiDatePicker][EuiDatePickerRange] Fix inline shadows
cee-chen Nov 27, 2024
1011d27
[EuiSuperDatePicker] Fix duplicate high contrast borders
cee-chen Nov 11, 2024
543f22b
[EuiSuperDatePicker] Improve Windows high contrast state indication
cee-chen Dec 3, 2024
9331f5a
[PR feedback] Fix border-radius issues with saturation picker
cee-chen Dec 3, 2024
c7e35b0
[PR feedback] Standardize hue/saturation indicator focus outline on l…
cee-chen Dec 4, 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.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
* Side Public License, v 1.
*/

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

import { euiPaletteColorBlind } from '../../../services';
import {
euiPaletteColorBlind,
euiPaletteForStatus,
euiPaletteForTemperature,
} from '../../../services';
import { EuiSpacer } from '../../spacer';

import {
EuiColorPaletteDisplay,
Expand All @@ -33,3 +39,51 @@ export const Playground: Story = {
palette: euiPaletteColorBlind(),
},
};

const paletteWithStops = [
{ stop: 100, color: 'white' },
{ stop: 250, color: 'lightgray' },
{ stop: 320, color: 'gray' },
{ stop: 470, color: 'black' },
];

export const PaletteWithStops: Story = {
args: {
palette: paletteWithStops,
},
};

/**
* VRT only
*/

export const KitchenSink: Story = {
tags: ['vrt-only'],
render: () => (
<>
<EuiColorPaletteDisplay
type="fixed"
palette={euiPaletteForStatus(6)}
mgadewoll marked this conversation as resolved.
Show resolved Hide resolved
size="xs"
/>
<EuiSpacer />
<EuiColorPaletteDisplay
type="gradient"
palette={euiPaletteForTemperature(4)}
size="s"
/>
<EuiSpacer />
<EuiColorPaletteDisplay
type="gradient"
palette={paletteWithStops}
size="m"
/>
</>
),
};

export const HighContrast: Story = {
...KitchenSink,
tags: ['vrt-only'],
globals: { highContrastMode: true },
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ import { UseEuiTheme, transparentize } from '../../../services';
import { logicalCSS } from '../../../global_styling';

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

// Border is a pseudo element with transparency
const border = `${euiTheme.border.width.thin} solid ${transparentize(
euiTheme.colors.darkestShade,
0.2
)}`;
const border = highContrastMode
? euiTheme.border.thin
: // Border is a pseudo element with transparency
`${euiTheme.border.width.thin} solid ${transparentize(
euiTheme.colors.darkestShade,
0.2
)}`;

return {
euiColorPaletteDisplay: css`
position: relative;
display: flex;
flex-direction: row;
overflow: hidden;
${highContrastMode === 'forced' ? 'forced-color-adjust: none;' : ''}

&::after {
content: '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React, { FunctionComponent, HTMLAttributes } from 'react';
import React, { FunctionComponent, HTMLAttributes, useMemo } from 'react';
import { CommonProps } from '../../common';
import { getFixedLinearGradient } from '../utils';
import { EuiScreenReaderOnly } from '../../accessibility';
Expand All @@ -26,14 +26,15 @@ interface paletteItem {
export const EuiColorPaletteDisplayFixed: FunctionComponent<
EuiColorPaletteDisplayFixedProps
> = ({ palette, title, ...rest }) => {
const fixedGradient = getFixedLinearGradient(palette);

const paletteStops = fixedGradient.map((item: paletteItem, index: number) => (
<span
style={{ backgroundColor: item.color, width: item.width }}
key={`${item.color}-${index}`}
/>
));
const paletteStops = useMemo(() => {
const fixedGradient = getFixedLinearGradient(palette);
return fixedGradient.map((item: paletteItem, index: number) => (
<span
style={{ backgroundColor: item.color, width: item.width }}
key={`${item.color}-${index}`}
/>
));
}, [palette]);

return (
<span {...rest}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface EuiColorPaletteDisplayGradientProps

export const EuiColorPaletteDisplayGradient: FunctionComponent<
EuiColorPaletteDisplayGradientProps
> = ({ palette, title, style = {}, ...rest }) => {
> = ({ palette, title, style, ...rest }) => {
const gradient = getLinearGradient(palette);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ export const InlineWithAllElements: Story = {
},
};

export const HighContrast: Story = {
...InlineWithAllElements,
tags: ['vrt-only'],
globals: { highContrastMode: true },
};

export const HighContrastDarkMode: Story = {
...HighContrast,
tags: ['vrt-only'],
globals: { highContrastMode: true, colorMode: 'dark' },
play: async ({ canvasElement }) => {
canvasElement.querySelector<HTMLInputElement>('.euiHue__range')?.focus?.();
},
};

const StatefulColorPicker: FunctionComponent<EuiColorPickerProps> = ({
color: _color,
format,
Expand Down
20 changes: 18 additions & 2 deletions packages/eui/src/components/color_picker/color_picker.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { UseEuiTheme, transparentize } from '../../services';
import { logicalCSS, mathWithUnits } from '../../global_styling';

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

// 5 columns of swatches + margins + border
const colorPickerWidth = mathWithUnits(
Expand All @@ -37,18 +37,34 @@ export const euiColorPickerStyles = (euiThemeContext: UseEuiTheme) => {
gap: ${euiTheme.size.s};
`,

// `!important`s required to override default EuiFormControlLayout styles */
euiColorPicker__alphaRange: css`
/* stylelint-disable declaration-no-important */
.euiRangeInput {
${logicalCSS('min-width', 0)}
${logicalCSS('width', `calc(3ch + ${euiTheme.size.l}) !important`)}
padding-inline: ${euiTheme.size.xs};
}

.euiFormControlLayout__append {
padding-inline: ${euiTheme.size.xxs} !important;
}

& > .euiFormControlLayout {
flex-shrink: 0;
}
/* stylelint-enable declaration-no-important */
`,

// Adds a stroke color for the swatchInput icon. Unlike most EuiIcons it has a stroke in the SVG
// Targets a custom className applied directly to the <svg> icon
euiColorPicker__swatchInputIcon: css`
.euiSwatchInput__stroke {
fill: none;
stroke: ${transparentize(euiTheme.colors.fullShade, 0.2)};
stroke: ${transparentize(
euiTheme.colors.fullShade,
highContrastMode ? 1 : 0.2
)};
}
`,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '../../global_styling';

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

return {
euiColorPickerSwatch: css`
Expand All @@ -27,10 +27,15 @@ export const euiColorPickerSwatchStyles = (euiThemeContext: UseEuiTheme) => {
euiTheme.border.radius.medium,
(x) => x / 2
)};
border: ${euiTheme.border.width.thin} solid
${transparentize(euiTheme.colors.fullShade, 0.1)};
box-shadow: inset 0 0 0 ${euiTheme.border.width.thin}
${transparentize(euiTheme.colors.emptyShade, 0.05)};
${highContrastMode
? `border: ${euiTheme.border.thin};`
: `
border: ${euiTheme.border.width.thin} solid
${transparentize(euiTheme.colors.fullShade, 0.1)};
box-shadow: inset 0 0 0 ${euiTheme.border.width.thin}
${transparentize(euiTheme.colors.emptyShade, 0.05)};
`}
${highContrastMode === 'forced' ? 'forced-color-adjust: none;' : ''}
cursor: pointer;

&:disabled {
Expand Down
50 changes: 34 additions & 16 deletions packages/eui/src/components/color_picker/hue.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '../form/range/range.styles';

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

const height = euiTheme.size.m;
const thumbSize = euiTheme.size.l;
Expand All @@ -33,9 +33,12 @@ export const euiHueStyles = (euiThemeContext: UseEuiTheme) => {
// This wraps the range and sets a rainbow gradient,
// which allows the range thumb to be larger than the visible track
euiHue: css`
/* stylelint-disable color-no-hex */
${logicalCSS('height', height)}
border-radius: ${height};
/* stylelint-disable color-no-hex */
${highContrastMode ? `border: ${euiTheme.border.thin};` : ''}
${highContrastMode === 'forced' ? 'forced-color-adjust: none;' : ''}

background: linear-gradient(
to right,
#ff3232 0%,
Expand Down Expand Up @@ -70,26 +73,41 @@ export const euiHueStyles = (euiThemeContext: UseEuiTheme) => {
}
/* stylelint-enable property-no-vendor-prefix */

/* Indicator styles - for some incredibly bizarre reason, stylelint is unhappy about
the semicolons here and can't be stylelint-disabled, hence the syntax workaround */
${euiRangeThumbPerBrowser(
[
euiRangeThumbStyle(euiThemeContext),
'background-color: inherit',
`border-width: ${thumbBorder}`,
'border-radius: 100%',
`box-shadow: ${thumbBoxShadow}`,
].join(';\n')
)}
${euiRangeThumbPerBrowser(`
${euiRangeThumbStyle(euiThemeContext)}
border-width: ${thumbBorder};
${
highContrastMode
? `
background-color: ${euiTheme.colors.ghost};
mgadewoll marked this conversation as resolved.
Show resolved Hide resolved
border: ${thumbBorder} solid ${euiTheme.colors.ink};
box-shadow: none;
`
: `
background-color: transparent;
box-shadow: ${thumbBoxShadow};
`
}`)}

/* Remove wrapping outline and show focus on thumb only */
&:focus {
outline: none;
}

&:focus-visible {
${euiRangeThumbPerBrowser(euiRangeThumbFocusBoxShadow(euiThemeContext))}
}
${highContrastMode
? `
&:focus {
${euiRangeThumbPerBrowser(`
outline: ${euiTheme.border.width.thin} solid ${euiTheme.colors.ink};
outline-offset: 0;
`)}
}`
: `
&:focus-visible {
${euiRangeThumbPerBrowser(
euiRangeThumbFocusBoxShadow(euiThemeContext)
)}
}`}
`,
};
};
Loading