diff --git a/packages/eui-theme-borealis/changelogs/upcoming/8767.md b/packages/eui-theme-borealis/changelogs/upcoming/8767.md new file mode 100644 index 00000000000..c7ee13c1bb1 --- /dev/null +++ b/packages/eui-theme-borealis/changelogs/upcoming/8767.md @@ -0,0 +1,23 @@ +- Added semantic tokens: + - `colors.borderInteractiveFormsHoverPlain` + - `colors.borderInteractiveFormsHoverDanger` +- Added component tokens: + - `components.forms.backgroundDropping` + - `components.forms.borderFocused` + - `components.forms.borderInvalid` + - `components.forms.borderHovered` + - `components.forms.borderInvalidHovered` + - `components.forms.borderAutofilledHovered` + - `components.forms.clearButtonBackground` +- Updated values for tokens: + - `colors.textWarning` + - `colors.borderStrongPrimary` + - `colors.borderStrongAccent` + - `colors.borderStrongAccentSecondary` + - `colors.borderStrongNeutral` + - `colors.borderStrongSuccess` + - `colors.borderStrongWarning` + - `colors.borderStrongRisk` + - `colors.borderStrongDanger` + - `components.forms.backgroundReadOnly` + diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json index ed01cd7edb3..e818196e12f 100644 --- a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json +++ b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json @@ -136,6 +136,24 @@ }, "euiBreakpointKeys": "'xs', 's', 'm', 'l', 'xl'", "euiShadowColor": "#000000", + "euiShadows": { + "xs": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px 2px 8px 0px hsl(0deg 0% 0% / 0.24)", + "s": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 2px 7px 0px hsl(0deg 0% 0% / 0.46), 0px 4px 11px 0px hsl(0deg 0% 0% / 0.26)", + "m": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 3px 10px 0px hsl(0deg 0% 0% / 0.52), 0px 6px 14px 0px hsl(0deg 0% 0% / 0.28)", + "l": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 4px 13px 0px hsl(0deg 0% 0% / 0.58), 0px 8px 17px 0px hsl(0deg 0% 0% / 0.3)", + "xl": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 5px 16px 0px hsl(0deg 0% 0% / 0.64), 0px 10px 20px 0px hsl(0deg 0% 0% / 0.32)", + "xlHover": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 6px 19px 0px hsl(0deg 0% 0% / 0.7), 0px 12px 23px 0px hsl(0deg 0% 0% / 0.34)", + "flat": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px 2px 8px 0px hsl(0deg 0% 0% / 0.24)" + }, + "euiShadowsUp": { + "xs": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px -2px 8px 0px hsl(0deg 0% 0% / 0.24)", + "s": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -2px 7px 0px hsl(0deg 0% 0% / 0.46), 0px -4px 11px 0px hsl(0deg 0% 0% / 0.26)", + "m": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -3px 10px 0px hsl(0deg 0% 0% / 0.52), 0px -6px 14px 0px hsl(0deg 0% 0% / 0.28)", + "l": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -4px 13px 0px hsl(0deg 0% 0% / 0.58), 0px -8px 17px 0px hsl(0deg 0% 0% / 0.3)", + "xl": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -5px 16px 0px hsl(0deg 0% 0% / 0.64), 0px -10px 20px 0px hsl(0deg 0% 0% / 0.32)", + "xlHover": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -6px 19px 0px hsl(0deg 0% 0% / 0.7), 0px -12px 23px 0px hsl(0deg 0% 0% / 0.34)", + "flat": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px -2px 8px 0px hsl(0deg 0% 0% / 0.24)" + }, "euiSize": "16px", "euiSizeXS": "4px", "euiSizeS": "8px", diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json.d.ts b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json.d.ts index 67f9282cfaf..ac9ab669404 100644 --- a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json.d.ts +++ b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json.d.ts @@ -137,6 +137,24 @@ declare module '@elastic/eui-theme-borealis/lib/eui_theme_borealis_dark.json' { }; euiBreakpointKeys: string; euiShadowColor: string; + euiShadows: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, + euiShadowsUp: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, euiSize: string; euiSizeXS: string; euiSizeS: string; diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json index 941b63776a6..b9fd888861c 100644 --- a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json +++ b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json @@ -136,6 +136,24 @@ }, "euiBreakpointKeys": "'xs', 's', 'm', 'l', 'xl'", "euiShadowColor": "#000000", + "euiShadows": { + "xs": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px 2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)", + "s": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 2px 7px 0px hsl(216.67deg 29.51% 23.92% / 0.08), 0px 4px 11px 0px hsl(216.67deg 29.51% 23.92% / 0.05)", + "m": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 3px 10px 0px hsl(216.67deg 29.51% 23.92% / 0.1), 0px 6px 14px 0px hsl(216.67deg 29.51% 23.92% / 0.06)", + "l": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 4px 13px 0px hsl(216.67deg 29.51% 23.92% / 0.12), 0px 8px 17px 0px hsl(216.67deg 29.51% 23.92% / 0.07)", + "xl": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 5px 16px 0px hsl(216.67deg 29.51% 23.92% / 0.14), 0px 10px 20px 0px hsl(216.67deg 29.51% 23.92% / 0.08)", + "xlHover": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 6px 19px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 12px 23px 0px hsl(216.67deg 29.51% 23.92% / 0.09)", + "flat": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px 2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)" + }, + "euiShadowsUp": { + "xs": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px -2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)", + "s": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -2px 7px 0px hsl(216.67deg 29.51% 23.92% / 0.08), 0px -4px 11px 0px hsl(216.67deg 29.51% 23.92% / 0.05)", + "m": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -3px 10px 0px hsl(216.67deg 29.51% 23.92% / 0.1), 0px -6px 14px 0px hsl(216.67deg 29.51% 23.92% / 0.06)", + "l": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -4px 13px 0px hsl(216.67deg 29.51% 23.92% / 0.12), 0px -8px 17px 0px hsl(216.67deg 29.51% 23.92% / 0.07)", + "xl": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -5px 16px 0px hsl(216.67deg 29.51% 23.92% / 0.14), 0px -10px 20px 0px hsl(216.67deg 29.51% 23.92% / 0.08)", + "xlHover": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -6px 19px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -12px 23px 0px hsl(216.67deg 29.51% 23.92% / 0.09)", + "flat": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px -2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)" + }, "euiSize": "16px", "euiSizeXS": "4px", "euiSizeS": "8px", diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json.d.ts b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json.d.ts index 4ac26aabd31..15129919ca6 100644 --- a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json.d.ts +++ b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json.d.ts @@ -137,6 +137,24 @@ declare module '@elastic/eui-theme-borealis/lib/eui_theme_borealis_light.json' { }; euiBreakpointKeys: string; euiShadowColor: string; + euiShadows: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, + euiShadowsUp: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, euiSize: string; euiSizeXS: string; euiSizeS: string; diff --git a/packages/eui-theme-borealis/src/index.ts b/packages/eui-theme-borealis/src/index.ts index 078c739583c..819a8beb5c1 100644 --- a/packages/eui-theme-borealis/src/index.ts +++ b/packages/eui-theme-borealis/src/index.ts @@ -15,6 +15,7 @@ import { base, size } from './variables/_size'; import { border } from './variables/_borders'; import { levels } from './variables/_levels'; import { font } from './variables/_typography'; +import { shadows } from './variables/_shadows'; import { focus } from './variables/_states'; import { components } from './variables/_components'; import { overrides } from './variables/_overrides'; @@ -35,6 +36,7 @@ export const euiThemeBorealis: EuiThemeShape = { animation, breakpoint, levels, + shadows, focus, components, flags: { diff --git a/packages/eui-theme-borealis/src/variables/_shadows.ts b/packages/eui-theme-borealis/src/variables/_shadows.ts new file mode 100644 index 00000000000..1406ca42d86 --- /dev/null +++ b/packages/eui-theme-borealis/src/variables/_shadows.ts @@ -0,0 +1,445 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import chroma from 'chroma-js'; +import { + computed, + type _EuiThemeShadows, + type _EuiThemeShadowLayer, +} from '@elastic/eui-theme-common'; +import { SEMANTIC_COLORS } from './colors/_semantic_colors'; + +export const shadows: _EuiThemeShadows = { + xs: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.06, + x: 0, + y: 1, + blur: 4, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.04, + x: 0, + y: 2, + blur: 8, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.4, + x: 0, + y: 1, + blur: 4, + spread: 0, + }, + { + color: '#000', + opacity: 0.24, + x: 0, + y: 2, + blur: 8, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xs.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xs.values'] + ), + }, + s: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.08, + x: 0, + y: 2, + blur: 7, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.05, + x: 0, + y: 4, + blur: 11, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.46, + x: 0, + y: 2, + blur: 7, + spread: 0, + }, + { + color: '#000', + opacity: 0.26, + x: 0, + y: 4, + blur: 11, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.s.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.s.values'] + ), + }, + m: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.1, + x: 0, + y: 3, + blur: 10, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.06, + x: 0, + y: 6, + blur: 14, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.52, + x: 0, + y: 3, + blur: 10, + spread: 0, + }, + { + color: '#000', + opacity: 0.28, + x: 0, + y: 6, + blur: 14, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.m.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.m.values'] + ), + }, + l: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.12, + x: 0, + y: 4, + blur: 13, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.07, + x: 0, + y: 8, + blur: 17, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.58, + x: 0, + y: 4, + blur: 13, + spread: 0, + }, + { + color: '#000', + opacity: 0.3, + x: 0, + y: 8, + blur: 17, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.l.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.l.values'] + ), + }, + xl: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.14, + x: 0, + y: 5, + blur: 16, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.08, + x: 0, + y: 10, + blur: 20, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.64, + x: 0, + y: 5, + blur: 16, + spread: 0, + }, + { + color: '#000', + opacity: 0.32, + x: 0, + y: 10, + blur: 20, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xl.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xl.values'] + ), + }, + xlHover: { + values: { + LIGHT: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.16, + x: 0, + y: 6, + blur: 19, + spread: 0, + }, + { + color: SEMANTIC_COLORS.shade120, + opacity: 0.09, + x: 0, + y: 12, + blur: 23, + spread: 0, + }, + ], + DARK: [ + { + color: SEMANTIC_COLORS.shade120, + opacity: 1, + x: 0, + y: 0, + blur: 0, + spread: 1, + }, + { + color: '#000', + opacity: 0.7, + x: 0, + y: 6, + blur: 19, + spread: 0, + }, + { + color: '#000', + opacity: 0.34, + x: 0, + y: 12, + blur: 23, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xlHover.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xlHover.values'] + ), + }, + // Falls back to `xs` (defined only to support legacy `euiShadowFlat` mixin) + flat: { + values: { + LIGHT: [], + DARK: [], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xs.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xs.values'] + ), + } +}; + +/** + * Format an array of shadow "objects" into a string for CSS. + * The "up" direction is built by making the y offset from layers + * two and three, negative. + * + * @param layers + * @param up - Modifies some values in order to get the "up" direction + * @returns - A value for the CSS `box-shadow` property + */ +function formatMultipleBoxShadow( + layers: _EuiThemeShadowLayer[], + up: boolean = false +) { + const [a, b, c] = layers; + /* prettier-ignore */ + const shadowLayers = [ + `${a.x}px ${a.y}px ${a.blur}px ${a.spread}px ${formatColor(a.color, a.opacity)}`, + `${b.x}px ${up ? -b.y : b.y}px ${b.blur}px ${b.spread}px ${formatColor(b.color, b.opacity)}`, + `${c.x}px ${up ? -c.y : c.y}px ${c.blur}px ${c.spread}px ${formatColor(c.color, c.opacity)}` + ]; + + return shadowLayers.join(', '); +} + +function formatColor(value: string, opacity: number) { + return chroma(value).alpha(opacity).css('hsl'); +} diff --git a/packages/eui-theme-common/changelogs/upcoming/8767.md b/packages/eui-theme-common/changelogs/upcoming/8767.md new file mode 100644 index 00000000000..69442487422 --- /dev/null +++ b/packages/eui-theme-common/changelogs/upcoming/8767.md @@ -0,0 +1,12 @@ +- Added semantic tokens: + - `colors.borderInteractiveFormsHoverPlain` + - `colors.borderInteractiveFormsHoverDanger` +- Added component tokens: + - `components.forms.backgroundDropping` + - `components.forms.borderFocused` + - `components.forms.borderInvalid` + - `components.forms.borderHovered` + - `components.forms.borderInvalidHovered` + - `components.forms.borderAutofilledHovered` + - `components.forms.clearButtonBackground` + diff --git a/packages/eui-theme-common/src/global_styling/functions/shadows.ts b/packages/eui-theme-common/src/global_styling/functions/shadows.ts index b3dd876d5ea..89ea8250669 100644 --- a/packages/eui-theme-common/src/global_styling/functions/shadows.ts +++ b/packages/eui-theme-common/src/global_styling/functions/shadows.ts @@ -14,7 +14,7 @@ import { // Create a CSS color value using whose opacity is determined based // on either a light or dark theme. We use a multiplier -// of 1 for light themes and 2.5 for dark themes +// of 1 for light themes and 3.5 for dark themes export const getShadowColor = ( color: string, opacity: number, diff --git a/packages/eui-theme-common/src/global_styling/mixins/shadow.ts b/packages/eui-theme-common/src/global_styling/mixins/shadow.ts index 889eb7bba71..a0e92d31001 100644 --- a/packages/eui-theme-common/src/global_styling/mixins/shadow.ts +++ b/packages/eui-theme-common/src/global_styling/mixins/shadow.ts @@ -11,7 +11,10 @@ import { getShadowColor } from '../functions'; import { _EuiThemeShadowSize } from '../variables/shadow'; export interface EuiShadowOptions { + /** @deprecated */ color?: string; + /** @default `down` */ + direction?: 'down' | 'up'; /** * Note: not supported by all shadow utilities. */ @@ -23,41 +26,30 @@ export interface EuiShadowOptions { * euiSlightShadow */ export const euiShadowXSmall = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, + { euiTheme, highContrastMode }: UseEuiTheme, options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; - const color = options?.color || euiTheme.colors.shadow; - - return ` -box-shadow: - 0 .8px .8px ${getShadowColor(color, 0.04, colorMode)}, - 0 2.3px 2px ${getShadowColor(color, 0.03, colorMode)}; -`; + return `box-shadow: ${euiTheme.shadows.xs[direction]};`; }; /** * bottomShadowSmall */ export const euiShadowSmall = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, + { euiTheme, highContrastMode }: UseEuiTheme, options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; - const color = options?.color || euiTheme.colors.shadow; - - return ` -box-shadow: - 0 .7px 1.4px ${getShadowColor(color, 0.07, colorMode)}, - 0 1.9px 4px ${getShadowColor(color, 0.05, colorMode)}, - 0 4.5px 10px ${getShadowColor(color, 0.05, colorMode)}; -`; + return `box-shadow: ${euiTheme.shadows.s[direction]};`; }; /** @@ -70,7 +62,7 @@ export const euiShadowMedium = ( if (highContrastMode) { return _highContrastBorder(euiTheme, options); } - + const direction = options?.direction ?? 'down'; const color = options?.color || euiTheme.colors.shadow; if (options?.property === 'filter') { @@ -81,11 +73,7 @@ export const euiShadowMedium = ( colorMode )});`; } else { - return `box-shadow: - 0 .9px 4px ${getShadowColor(color, 0.08, colorMode)}, - 0 2.6px 8px ${getShadowColor(color, 0.06, colorMode)}, - 0 5.7px 12px ${getShadowColor(color, 0.05, colorMode)}, - 0 15px 15px ${getShadowColor(color, 0.04, colorMode)};`; + return `box-shadow: ${euiTheme.shadows.m[direction]};`; } }; @@ -93,22 +81,15 @@ export const euiShadowMedium = ( * bottomShadow */ export const euiShadowLarge = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, + { euiTheme, highContrastMode }: UseEuiTheme, options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; - const color = options?.color || euiTheme.colors.shadow; - - return ` -box-shadow: - 0 1px 5px ${getShadowColor(color, 0.1, colorMode)}, - 0 3.6px 13px ${getShadowColor(color, 0.07, colorMode)}, - 0 8.4px 23px ${getShadowColor(color, 0.06, colorMode)}, - 0 23px 35px ${getShadowColor(color, 0.05, colorMode)}; -`; + return `box-shadow: ${euiTheme.shadows.l[direction]};`; }; /** @@ -118,45 +99,43 @@ export interface EuiShadowXLarge extends EuiShadowOptions { reverse?: boolean; } export const euiShadowXLarge = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, - options?: EuiShadowXLarge + { euiTheme, highContrastMode }: UseEuiTheme, + options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; - const color = options?.color || euiTheme.colors.shadow; + return `box-shadow: ${euiTheme.shadows.xlHover[direction]};`; +}; +export const euiShadowXLargeHover = ( + { euiTheme, highContrastMode }: UseEuiTheme, + options?: EuiShadowXLarge +) => { + if (highContrastMode) { + return _highContrastBorder(euiTheme, options); + } const reverse = options?.reverse ?? false; + const direction = options?.direction ?? reverse ? 'up' : 'down'; - return ` -box-shadow: - 0 ${reverse ? '-' : ''}2.7px 9px ${getShadowColor(color, 0.13, colorMode)}, - 0 ${reverse ? '-' : ''}9.4px 24px ${getShadowColor(color, 0.09, colorMode)}, - 0 ${reverse ? '-' : ''}21.8px 43px ${getShadowColor(color, 0.08, colorMode)}; -`; + return `box-shadow: ${euiTheme.shadows.xlHover[direction]};`; }; /** - * slightShadowHover + * @deprecated slightShadowHover */ export const euiSlightShadowHover = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, + { euiTheme, highContrastMode }: UseEuiTheme, options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; - const color = options?.color || euiTheme.colors.shadow; - - return ` -box-shadow: - 0 1px 5px ${getShadowColor(color, 0.1, colorMode)}, - 0 3.6px 13px ${getShadowColor(color, 0.07, colorMode)}, - 0 8.4px 23px ${getShadowColor(color, 0.06, colorMode)}, - 0 23px 35px ${getShadowColor(color, 0.05, colorMode)}; -`; + return `box-shadow: ${euiTheme.shadows.s[direction]};`; }; /** @@ -166,22 +145,16 @@ box-shadow: * Useful for popovers that drop UP rather than DOWN. */ export const euiShadowFlat = ( - { euiTheme, colorMode, highContrastMode }: UseEuiTheme, + { euiTheme, highContrastMode }: UseEuiTheme, options?: EuiShadowOptions ) => { if (highContrastMode) { return _highContrastBorder(euiTheme, options); } + const direction = options?.direction ?? 'down'; + const value = euiTheme.shadows.flat?.[direction] ?? euiTheme.shadows.xs[direction] - const color = options?.color || euiTheme.colors.shadow; - - return ` -box-shadow: - 0 0 .8px ${getShadowColor(color, 0.06, colorMode)}, - 0 0 2px ${getShadowColor(color, 0.04, colorMode)}, - 0 0 5px ${getShadowColor(color, 0.04, colorMode)}, - 0 0 17px ${getShadowColor(color, 0.03, colorMode)}; -`; + return `box-shadow: ${value};`; }; export const euiShadow = ( @@ -204,6 +177,8 @@ export const euiShadow = ( return euiShadowLarge(euiThemeContext, options); case 'xl': return euiShadowXLarge(euiThemeContext, options); + case 'xlHover': + return euiShadowXLargeHover(euiThemeContext, options); default: console.warn('Please provide a valid size option to useEuiShadow'); diff --git a/packages/eui-theme-common/src/global_styling/variables/shadow.ts b/packages/eui-theme-common/src/global_styling/variables/shadow.ts index e8bd284645b..62b12847456 100644 --- a/packages/eui-theme-common/src/global_styling/variables/shadow.ts +++ b/packages/eui-theme-common/src/global_styling/variables/shadow.ts @@ -6,7 +6,10 @@ * Side Public License, v 1. */ -export const EuiThemeShadowSizes = ['xs', 's', 'm', 'l', 'xl'] as const; +import { CSSProperties } from 'react'; +import { ColorModeSwitch } from "../../services/theme/types"; + +export const EuiThemeShadowSizes = ['xs', 's', 'm', 'l', 'xl', `xlHover`] as const; export type _EuiThemeShadowSize = (typeof EuiThemeShadowSizes)[number]; @@ -20,6 +23,7 @@ export const _EuiShadowSizesDescriptions: Record<_EuiThemeShadowSize, string> = m: 'Used on small sized portalled content like popovers.', l: 'Primary shadow used in most cases to add visible depth.', xl: 'Very large shadows used for large portalled style containers like modals and flyouts.', + xlHover: 'Special size to be used exclusively as hovered state for the `xl` size', }; export interface _EuiThemeShadowCustomColor { @@ -27,3 +31,36 @@ export interface _EuiThemeShadowCustomColor { property?: 'box-shadow' | 'filter'; borderAllInHighContrastMode?: boolean; } + +/** + * Represents a single shadow + * @see https://tr.designtokens.org/format/#shadow + */ +export type _EuiThemeShadowLayer = { + color: string; + opacity: number; + x: number; + y: number; + blur: number; + spread: number; +} + +export type _EuiThemeShadow = { + /** An array of shadows, 3 by design */ + values: ColorModeSwitch<_EuiThemeShadowLayer[]>; + /** Default direction of the shadow */ + down: CSSProperties['boxShadow']; + /** Reverse direction */ + up: CSSProperties['boxShadow']; +} + +export type _EuiThemeShadows = { + xs: _EuiThemeShadow, + s: _EuiThemeShadow, + m: _EuiThemeShadow, + l: _EuiThemeShadow, + xl: _EuiThemeShadow, + xlHover: _EuiThemeShadow, + /** Not in the spec, defined only to support the legacy `euiShadowFlat` mixin */ + flat?: _EuiThemeShadow, +}; diff --git a/packages/eui-theme-common/src/services/theme/types.ts b/packages/eui-theme-common/src/services/theme/types.ts index ababd204dd8..8e149cf9d9f 100644 --- a/packages/eui-theme-common/src/services/theme/types.ts +++ b/packages/eui-theme-common/src/services/theme/types.ts @@ -20,6 +20,7 @@ import type { } from '../../global_styling/variables/size'; import type { _EuiThemeFont } from '../../global_styling/variables/typography'; import type { _EuiThemeFocus } from '../../global_styling/variables/states'; +import type { _EuiThemeShadows } from '../../global_styling/variables/shadow'; import type { _EuiThemeLevels } from '../../global_styling/variables/levels'; import type { _EuiThemeComponents } from '../../global_styling/variables/components'; import type { _EuiThemeFlags } from '../../global_styling/variables'; @@ -73,6 +74,7 @@ export type EuiThemeShapeBase = { animation: _EuiThemeAnimation; breakpoint: _EuiThemeBreakpoints; levels: _EuiThemeLevels; + shadows: _EuiThemeShadows; components: _EuiThemeComponents; flags: _EuiThemeFlags; }; diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png index 1eb2da609ff..8d06f6b7201 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png index ce4cf0f948f..cac76d1b0aa 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Full_Width.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Full_Width.png index 9d20beb244e..e093ea971b4 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Full_Width.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Full_Width.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Playground.png index 46da76a803a..307c6519195 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePickerRange_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiForm_EuiFormRow_Column_Layout.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiForm_EuiFormRow_Column_Layout.png index cc82f368524..ab3767c36af 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiForm_EuiFormRow_Column_Layout.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiForm_EuiFormRow_Column_Layout.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiBasicTable_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiBasicTable_Playground.png index 85a8ef70ee4..13a7e87fa14 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiBasicTable_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiBasicTable_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png index 5276b1a15fa..857d6a1bd2d 100644 Binary files a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_toolbarVisibility_prop_Keyboard_Shortcuts.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png index 13e5ea4ab39..1d29a73d59e 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png index 7e4104d9605..ed1d22fc793 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiColorPicker_EuiColorPicker_High_Contrast_Dark_Mode.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Full_Width.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Full_Width.png index 90383a7dc41..c6a0816ac1e 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Full_Width.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Full_Width.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Playground.png index 90383a7dc41..c6a0816ac1e 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePickerRange_Playground.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiBasicTable_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiBasicTable_Playground.png index 51260959e7a..67706d333fd 100644 Binary files a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiBasicTable_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiBasicTable_Playground.png differ diff --git a/packages/eui/changelogs/upcoming/8767.md b/packages/eui/changelogs/upcoming/8767.md new file mode 100644 index 00000000000..bb3624a140a --- /dev/null +++ b/packages/eui/changelogs/upcoming/8767.md @@ -0,0 +1,36 @@ +- Added new `refresh` design for input styles and form layout components: + - `EuiFieldText` + - `EuiFieldNumber` + - `EuiFieldPassword` + - `EuiFieldSearch` + - `EuiTextarea` + - `EuiSelect` + - `EuiSuperSelect` + - `EuiFormControlLayout` + - `EuiFormControlLayoutDelimited` + - `EuiFormControlLayoutIcons` + - `EuiFormLabel` + - `EuiFormErrorText` +- Added semantic tokens: + - `colors.borderInteractiveFormsHoverPlain` + - `colors.borderInteractiveFormsHoverDanger` +- Added component tokens: + - `components.forms.backgroundDropping` + - `components.forms.borderFocused` + - `components.forms.borderInvalid` + - `components.forms.borderHovered` + - `components.forms.borderInvalidHovered` + - `components.forms.borderAutofilledHovered` + - `components.forms.clearButtonBackground` +- Updated values for tokens: + - `colors.textWarning` + - `colors.borderStrongPrimary` + - `colors.borderStrongAccent` + - `colors.borderStrongAccentSecondary` + - `colors.borderStrongNeutral` + - `colors.borderStrongSuccess` + - `colors.borderStrongWarning` + - `colors.borderStrongRisk` + - `colors.borderStrongDanger` + - `components.forms.backgroundReadOnly` + diff --git a/packages/eui/changelogs/upcoming/8778.md b/packages/eui/changelogs/upcoming/8778.md new file mode 100644 index 00000000000..1b97002b7b7 --- /dev/null +++ b/packages/eui/changelogs/upcoming/8778.md @@ -0,0 +1,7 @@ +- Added new `refresh` design for input styles on form picker components: + - `EuiComboBox` + - `EuiFilePicker` + - `EuiDatePicker` + - `EuiSuperDatePicker` +- Updated the font size of `xs` size `EuiButtonEmpty` to `14px` + diff --git a/packages/eui/changelogs/upcoming/8806.md b/packages/eui/changelogs/upcoming/8806.md new file mode 100644 index 00000000000..43536976f3e --- /dev/null +++ b/packages/eui/changelogs/upcoming/8806.md @@ -0,0 +1,6 @@ +- Added `theme` prop to `EuiSelectableTemplateSitewide` to support granular control over the applied `colorMode` for the search and popover components + +**Breaking changes** + +- Removed custom style overrides for `EuiSelectableTemplateSitewide` search inside `EuiHeader` - Use the `theme` prop on `EuiSelectableTemplateSitewide` instead to control the color mode output. + diff --git a/packages/eui/src/components/form/form_control_layout/form_control_layout.styles.ts b/packages/eui/src/components/form/form_control_layout/form_control_layout.styles.ts index dc966fcf3c2..27c9c54b1ba 100644 --- a/packages/eui/src/components/form/form_control_layout/form_control_layout.styles.ts +++ b/packages/eui/src/components/form/form_control_layout/form_control_layout.styles.ts @@ -68,14 +68,14 @@ export const euiFormControlLayoutStyles = (euiThemeContext: UseEuiTheme) => { `; const prependOnlyStyles = ` - > :last-child { + > :first-child { ${logicalCSS('border-top-right-radius', 'inherit')} ${logicalCSS('border-bottom-right-radius', 'inherit')} } `; const appendOnlyStyles = ` - > :first-child { + > :last-child { ${logicalCSS('border-top-left-radius', 'inherit')} ${logicalCSS('border-bottom-left-radius', 'inherit')} } diff --git a/packages/eui/src/global_styling/mixins/_shadow.ts b/packages/eui/src/global_styling/mixins/_shadow.ts index db6b48dcd13..bed13bff908 100644 --- a/packages/eui/src/global_styling/mixins/_shadow.ts +++ b/packages/eui/src/global_styling/mixins/_shadow.ts @@ -15,6 +15,7 @@ import { euiShadowMedium, euiShadowLarge, euiShadowXLarge, + euiShadowXLargeHover, type _EuiThemeShadowSize, type EuiShadowOptions, } from '@elastic/eui-theme-common'; @@ -30,17 +31,21 @@ export { euiShadowMedium, euiShadowLarge, euiShadowXLarge, + euiShadowXLargeHover, }; +/** @deprecated */ export interface EuiShadowCustomColor { color?: string; } +/** @deprecated */ export const useEuiSlightShadowHover = (options?: EuiShadowOptions) => { const euiThemeContext = useEuiTheme(); return euiSlightShadowHover(euiThemeContext, options); }; +/** @deprecated */ export const useEuiShadowFlat = (options?: EuiShadowOptions) => { const euiThemeContext = useEuiTheme(); return euiShadowFlat(euiThemeContext, options); diff --git a/packages/eui/src/global_styling/variables/shadow.ts b/packages/eui/src/global_styling/variables/shadow.ts index 69aeb0d5846..e4dbea37c8e 100644 --- a/packages/eui/src/global_styling/variables/shadow.ts +++ b/packages/eui/src/global_styling/variables/shadow.ts @@ -9,6 +9,8 @@ export { EuiThemeShadowSizes, _EuiShadowSizesDescriptions, + type _EuiThemeShadows, type _EuiThemeShadowSize, + type _EuiThemeShadowLayer, type _EuiThemeShadowCustomColor, } from '@elastic/eui-theme-common'; diff --git a/packages/eui/src/themes/amsterdam/global_styling/variables/_shadows.ts b/packages/eui/src/themes/amsterdam/global_styling/variables/_shadows.ts new file mode 100644 index 00000000000..2732a8d17d8 --- /dev/null +++ b/packages/eui/src/themes/amsterdam/global_styling/variables/_shadows.ts @@ -0,0 +1,476 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import chroma from 'chroma-js'; +import { + _EuiThemeShadows, + _EuiThemeShadowLayer, +} from '../../../../global_styling/variables'; +import { computed } from '../../../../services/theme/utils'; + +// in Amsterdam this is `color.shadow`, which computes to `ink` (#000) +const SHADOW_COLOR = '#000000'; + +export const shadows: _EuiThemeShadows = { + xs: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.04 * 1, + x: 0, + y: 0.8, + blur: 0.8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.03 * 1, + x: 0, + y: 2.3, + blur: 2, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.04 * 3.5, + x: 0, + y: 0.8, + blur: 0.8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.03 * 3.5, + x: 0, + y: 2.3, + blur: 2, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xs.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xs.values'] + ), + }, + s: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.07 * 1, + x: 0, + y: 0.7, + blur: 1.4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 1, + x: 0, + y: 1.9, + blur: 4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 1, + x: 0, + y: 4.5, + blur: 10, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.07 * 3.5, + x: 0, + y: 0.7, + blur: 1.4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 3.5, + x: 0, + y: 1.9, + blur: 4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 3.5, + x: 0, + y: 4.5, + blur: 10, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.s.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.s.values'] + ), + }, + m: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.08 * 1, + x: 0, + y: 0.9, + blur: 4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.06 * 1, + x: 0, + y: 2.6, + blur: 8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 1, + x: 0, + y: 5.7, + blur: 12, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 1, + x: 0, + y: 15, + blur: 15, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.08 * 3.5, + x: 0, + y: 0.9, + blur: 4, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.06 * 3.5, + x: 0, + y: 2.6, + blur: 8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 3.5, + x: 0, + y: 5.7, + blur: 12, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 3.5, + x: 0, + y: 15, + blur: 15, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.m.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.m.values'] + ), + }, + l: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.1 * 1, + x: 0, + y: 1, + blur: 5, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.07 * 1, + x: 0, + y: 3.6, + blur: 13, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.06 * 1, + x: 0, + y: 8.4, + blur: 23, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 1, + x: 0, + y: 23, + blur: 35, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.1 * 3.5, + x: 0, + y: 1, + blur: 5, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.07 * 3.5, + x: 0, + y: 3.6, + blur: 13, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.06 * 3.5, + x: 0, + y: 8.4, + blur: 23, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.05 * 3.5, + x: 0, + y: 23, + blur: 35, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.l.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.l.values'] + ), + }, + xl: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.13 * 1, + x: 0, + y: 2.7, + blur: 9, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.09 * 1, + x: 0, + y: 9.4, + blur: 24, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.08 * 1, + x: 0, + y: 21.8, + blur: 43, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.13 * 3.5, + x: 0, + y: 2.7, + blur: 9, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.09 * 3.5, + x: 0, + y: 9.4, + blur: 24, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.08 * 3.5, + x: 0, + y: 21.8, + blur: 43, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xl.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xl.values'] + ), + }, + xlHover: { + values: { + LIGHT: [], + DARK: [], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.xl.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.xl.values'] + ), + }, + flat: { + values: { + LIGHT: [ + { + color: SHADOW_COLOR, + opacity: 0.06 * 1, + x: 0, + y: 0, + blur: 0.8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 1, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 1, + x: 0, + y: 0, + blur: 5, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.03 * 1, + x: 0, + y: 0, + blur: 17, + spread: 0, + }, + ], + DARK: [ + { + color: SHADOW_COLOR, + opacity: 0.06 * 3.5, + x: 0, + y: 0, + blur: 0.8, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 3.5, + x: 0, + y: 0, + blur: 2, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.04 * 3.5, + x: 0, + y: 0, + blur: 5, + spread: 0, + }, + { + color: SHADOW_COLOR, + opacity: 0.03 * 3.5, + x: 0, + y: 0, + blur: 17, + spread: 0, + }, + ], + }, + down: computed( + ([values]) => formatMultipleBoxShadow(values), + ['shadows.flat.values'] + ), + up: computed( + ([values]) => formatMultipleBoxShadow(values, true), + ['shadows.flat.values'] + ), + }, +}; + +/** + * Format an array of shadow "objects" into a string for CSS. + * The "up" direction is built by making the y offset from layers + * two and three, negative. + * + * @param layers + * @param up - Modifies some values in order to get the "up" direction + * @returns - A value for the CSS `box-shadow` property + */ +function formatMultipleBoxShadow( + layers: _EuiThemeShadowLayer[], + up: boolean = false +) { + /* prettier-ignore */ + const shadowLayers = layers.map((layer, i) => { + const y = (up && i > 0) ? -layer.y : layer.y; + return `${layer.x}px ${y}px ${layer.blur}px ${layer.spread}px ${formatColor(layer.color, layer.opacity)}`; + }); + + return shadowLayers.join(', '); +} + +function formatColor(value: string, opacity: number) { + return chroma(value).alpha(opacity).css('hsl'); +} diff --git a/packages/eui/src/themes/amsterdam/theme.ts b/packages/eui/src/themes/amsterdam/theme.ts index 96a4eceee00..30a05254236 100644 --- a/packages/eui/src/themes/amsterdam/theme.ts +++ b/packages/eui/src/themes/amsterdam/theme.ts @@ -17,6 +17,7 @@ import { border } from './global_styling/variables/_borders'; import { levels } from './global_styling/variables/_levels'; import { font } from './global_styling/variables/_typography'; import { focus } from './global_styling/variables/_states'; +import { shadows } from './global_styling/variables/_shadows'; import { components } from './global_styling/variables/_components'; export const AMSTERDAM_NAME_KEY = 'EUI_THEME_AMSTERDAM'; @@ -31,6 +32,7 @@ export const euiThemeAmsterdam: EuiThemeShape = { breakpoint, levels, focus, + shadows, components, flags: { hasGlobalFocusColor: false, diff --git a/packages/eui/src/themes/json/eui_theme_borealis_dark.json b/packages/eui/src/themes/json/eui_theme_borealis_dark.json index ed01cd7edb3..e818196e12f 100644 --- a/packages/eui/src/themes/json/eui_theme_borealis_dark.json +++ b/packages/eui/src/themes/json/eui_theme_borealis_dark.json @@ -136,6 +136,24 @@ }, "euiBreakpointKeys": "'xs', 's', 'm', 'l', 'xl'", "euiShadowColor": "#000000", + "euiShadows": { + "xs": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px 2px 8px 0px hsl(0deg 0% 0% / 0.24)", + "s": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 2px 7px 0px hsl(0deg 0% 0% / 0.46), 0px 4px 11px 0px hsl(0deg 0% 0% / 0.26)", + "m": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 3px 10px 0px hsl(0deg 0% 0% / 0.52), 0px 6px 14px 0px hsl(0deg 0% 0% / 0.28)", + "l": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 4px 13px 0px hsl(0deg 0% 0% / 0.58), 0px 8px 17px 0px hsl(0deg 0% 0% / 0.3)", + "xl": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 5px 16px 0px hsl(0deg 0% 0% / 0.64), 0px 10px 20px 0px hsl(0deg 0% 0% / 0.32)", + "xlHover": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 6px 19px 0px hsl(0deg 0% 0% / 0.7), 0px 12px 23px 0px hsl(0deg 0% 0% / 0.34)", + "flat": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px 1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px 2px 8px 0px hsl(0deg 0% 0% / 0.24)" + }, + "euiShadowsUp": { + "xs": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px -2px 8px 0px hsl(0deg 0% 0% / 0.24)", + "s": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -2px 7px 0px hsl(0deg 0% 0% / 0.46), 0px -4px 11px 0px hsl(0deg 0% 0% / 0.26)", + "m": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -3px 10px 0px hsl(0deg 0% 0% / 0.52), 0px -6px 14px 0px hsl(0deg 0% 0% / 0.28)", + "l": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -4px 13px 0px hsl(0deg 0% 0% / 0.58), 0px -8px 17px 0px hsl(0deg 0% 0% / 0.3)", + "xl": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -5px 16px 0px hsl(0deg 0% 0% / 0.64), 0px -10px 20px 0px hsl(0deg 0% 0% / 0.32)", + "xlHover": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -6px 19px 0px hsl(0deg 0% 0% / 0.7), 0px -12px 23px 0px hsl(0deg 0% 0% / 0.34)", + "flat": "0px 0px 0px 1px hsl(216.67deg 29.51% 23.92%), 0px -1px 4px 0px hsl(0deg 0% 0% / 0.4), 0px -2px 8px 0px hsl(0deg 0% 0% / 0.24)" + }, "euiSize": "16px", "euiSizeXS": "4px", "euiSizeS": "8px", diff --git a/packages/eui/src/themes/json/eui_theme_borealis_dark.json.d.ts b/packages/eui/src/themes/json/eui_theme_borealis_dark.json.d.ts index 76518684bcf..2db61adf70c 100644 --- a/packages/eui/src/themes/json/eui_theme_borealis_dark.json.d.ts +++ b/packages/eui/src/themes/json/eui_theme_borealis_dark.json.d.ts @@ -137,6 +137,24 @@ declare module '@elastic/eui/dist/eui_theme_borealis_dark.json' { }; euiBreakpointKeys: string; euiShadowColor: string; + euiShadows: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, + euiShadowsUp: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, euiSize: string; euiSizeXS: string; euiSizeS: string; diff --git a/packages/eui/src/themes/json/eui_theme_borealis_light.json b/packages/eui/src/themes/json/eui_theme_borealis_light.json index 941b63776a6..b9fd888861c 100644 --- a/packages/eui/src/themes/json/eui_theme_borealis_light.json +++ b/packages/eui/src/themes/json/eui_theme_borealis_light.json @@ -136,6 +136,24 @@ }, "euiBreakpointKeys": "'xs', 's', 'm', 'l', 'xl'", "euiShadowColor": "#000000", + "euiShadows": { + "xs": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px 2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)", + "s": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 2px 7px 0px hsl(216.67deg 29.51% 23.92% / 0.08), 0px 4px 11px 0px hsl(216.67deg 29.51% 23.92% / 0.05)", + "m": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 3px 10px 0px hsl(216.67deg 29.51% 23.92% / 0.1), 0px 6px 14px 0px hsl(216.67deg 29.51% 23.92% / 0.06)", + "l": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 4px 13px 0px hsl(216.67deg 29.51% 23.92% / 0.12), 0px 8px 17px 0px hsl(216.67deg 29.51% 23.92% / 0.07)", + "xl": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 5px 16px 0px hsl(216.67deg 29.51% 23.92% / 0.14), 0px 10px 20px 0px hsl(216.67deg 29.51% 23.92% / 0.08)", + "xlHover": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 6px 19px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 12px 23px 0px hsl(216.67deg 29.51% 23.92% / 0.09)", + "flat": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px 1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px 2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)" + }, + "euiShadowsUp": { + "xs": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px -2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)", + "s": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -2px 7px 0px hsl(216.67deg 29.51% 23.92% / 0.08), 0px -4px 11px 0px hsl(216.67deg 29.51% 23.92% / 0.05)", + "m": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -3px 10px 0px hsl(216.67deg 29.51% 23.92% / 0.1), 0px -6px 14px 0px hsl(216.67deg 29.51% 23.92% / 0.06)", + "l": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -4px 13px 0px hsl(216.67deg 29.51% 23.92% / 0.12), 0px -8px 17px 0px hsl(216.67deg 29.51% 23.92% / 0.07)", + "xl": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -5px 16px 0px hsl(216.67deg 29.51% 23.92% / 0.14), 0px -10px 20px 0px hsl(216.67deg 29.51% 23.92% / 0.08)", + "xlHover": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -6px 19px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -12px 23px 0px hsl(216.67deg 29.51% 23.92% / 0.09)", + "flat": "0px 0px 2px 0px hsl(216.67deg 29.51% 23.92% / 0.16), 0px -1px 4px 0px hsl(216.67deg 29.51% 23.92% / 0.06), 0px -2px 8px 0px hsl(216.67deg 29.51% 23.92% / 0.04)" + }, "euiSize": "16px", "euiSizeXS": "4px", "euiSizeS": "8px", diff --git a/packages/eui/src/themes/json/eui_theme_borealis_light.json.d.ts b/packages/eui/src/themes/json/eui_theme_borealis_light.json.d.ts index 9db35efb731..f81b2a0d072 100644 --- a/packages/eui/src/themes/json/eui_theme_borealis_light.json.d.ts +++ b/packages/eui/src/themes/json/eui_theme_borealis_light.json.d.ts @@ -137,6 +137,24 @@ declare module '@elastic/eui/dist/eui_theme_borealis_light.json' { }; euiBreakpointKeys: string; euiShadowColor: string; + euiShadows: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, + euiShadowsUp: { + xs: string; + s: string; + m: string; + l: string; + xl: string; + xlHover: string; + flat: string; + }, euiSize: string; euiSizeXS: string; euiSizeS: string; diff --git a/packages/website/docs/getting-started/theming/tokens/shadows/index.mdx b/packages/website/docs/getting-started/theming/tokens/shadows/index.mdx new file mode 100644 index 00000000000..81ad84ffa14 --- /dev/null +++ b/packages/website/docs/getting-started/theming/tokens/shadows/index.mdx @@ -0,0 +1,96 @@ +--- +sidebar_position: 10 +--- + +# Shadows + +There are 5 sizes of shadows. The first level of each shadow enhances contrast and remains consistent across all sizes. + +:::info In dark mode, shadows get an additional lighter border, to ensure they are visible +::: + +```mdx-code-block +import { ShadowsTable } from './shadows_table'; +``` + + + +:::warning Use `xlHover` exclusively as the hover state for size `xl` +::: + +## Direction + +Shadows can only have two directions, up and down. By default shadows point down. + + + +## Hover state + +Each shadowed surface, when interactive, follows a hover effect rule: it moves up one level. + +- `xs` hovered → `s` +- `s` hovered → `m` +- `m` hovered → `l` +- `l` hovered → `xl` +- `xl` hovered → `xlHover` + +```tsx interactive +import React, { useState } from 'react'; +import { useEuiTheme, EuiSelect, EuiSpacer, EuiCodeBlock } from '@elastic/eui'; + +type ShadowSize = 'xs' | 's' | 'm' | 'l' | 'xl'; +const hoverPairs = { + xs: ['xs', 's'], + s: ['s', 'm'], + m: ['m', 'l'], + l: ['l', 'xl'], + xl: ['xl', 'xlHover'], +}; + +export default () => { + const { euiTheme } = useEuiTheme(); + const [selectedSize, setSelectedSize] = useState('m'); + const selectedPair = hoverPairs[selectedSize]; + const options = [ + { value: 'xs', text: 'xs' }, + { value: 's' , text: 's' }, + { value: 'm' , text: 'm' }, + { value: 'l' , text: 'l' }, + { value: 'xl', text: 'xl' }, + ]; + + const styles = css` + box-shadow: ${euiTheme.shadows[selectedPair[0]].down}; + &:hover { + box-shadow: ${euiTheme.shadows[selectedPair[1]].down}; + } + background-color: ${euiTheme.colors.backgroundBasePlain}; + border-radius: ${euiTheme.border.radius.medium}; + ` + const stylesText = ` +const styles = css\` + box-shadow: \${euiTheme.shadows.${selectedPair[0]}.down\}; + &:hover { + box-shadow: \${euiTheme.shadows.${selectedPair[1]}.down\}; + } +\` + ` + + return ( + <> + + {stylesText} + + + { setSelectedSize(e.target.value) }} + /> + + ); +} +``` diff --git a/packages/website/docs/getting-started/theming/tokens/shadows/shadows_table.tsx b/packages/website/docs/getting-started/theming/tokens/shadows/shadows_table.tsx new file mode 100644 index 00000000000..20d8456f635 --- /dev/null +++ b/packages/website/docs/getting-started/theming/tokens/shadows/shadows_table.tsx @@ -0,0 +1,43 @@ +import { css } from '@emotion/react'; +import { + useEuiTheme, + EuiColorPickerSwatch, + _EuiThemeShadowSize, +} from '@elastic/eui'; +import { ThemeValuesTable } from '../../theme_values_table'; + +const shadowTypes: _EuiThemeShadowSize[] = [ + 'xs', + 's', + 'm', + 'l', + 'xl', + 'xlHover', +]; + +export const ShadowsTable = ({ direction = "down" }) => { + const { euiTheme } = useEuiTheme(); + + return ( + ({ + id: type, + token: `shadows.${type}.${direction}`, + value: euiTheme.shadows[type]![direction], + }))} + render={(item) => ( + + )} + /> + ); +};