diff --git a/packages/eui/elastic_eui_95.9.0_VR_option3_01.tgz b/packages/eui/elastic_eui_95.9.0_VR_option3_01.tgz new file mode 100644 index 00000000000..560665cdafc Binary files /dev/null and b/packages/eui/elastic_eui_95.9.0_VR_option3_01.tgz differ diff --git a/packages/eui/elastic_eui_95.9.0_VR_option3_02.tgz b/packages/eui/elastic_eui_95.9.0_VR_option3_02.tgz new file mode 100644 index 00000000000..ff62c941d56 Binary files /dev/null and b/packages/eui/elastic_eui_95.9.0_VR_option3_02.tgz differ diff --git a/packages/eui/src-docs/src/components/with_theme/theme_context.tsx b/packages/eui/src-docs/src/components/with_theme/theme_context.tsx index fc16b9a5358..9f3da31982f 100644 --- a/packages/eui/src-docs/src/components/with_theme/theme_context.tsx +++ b/packages/eui/src-docs/src/components/with_theme/theme_context.tsx @@ -32,7 +32,7 @@ const defaultState = { themeLanguage: THEME_LANGS[0], // eslint-disable-next-line @typescript-eslint/no-unused-vars changeThemeLanguage: (language: THEME_LANGUAGES['id']) => {}, - theme: THEME_NAMES[0], + theme: THEME_NAMES[2], changeTheme: (themeValue: EUI_THEME['value']) => { applyTheme(themeValue); }, diff --git a/packages/eui/src-docs/src/index.js b/packages/eui/src-docs/src/index.js index b9254d7da37..3ba3b658a45 100644 --- a/packages/eui/src-docs/src/index.js +++ b/packages/eui/src-docs/src/index.js @@ -19,6 +19,8 @@ import { ThemeProvider } from './components/with_theme/theme_context'; registerTheme('light', [themeLight]); registerTheme('dark', [themeDark]); +registerTheme('new_light', [themeLight]); +registerTheme('new_dark', [themeDark]); // Set up app diff --git a/packages/eui/src-docs/src/views/app_context.js b/packages/eui/src-docs/src/views/app_context.js index 606ce277bb1..073b847e5ca 100644 --- a/packages/eui/src-docs/src/views/app_context.js +++ b/packages/eui/src-docs/src/views/app_context.js @@ -36,6 +36,12 @@ export const AppContext = ({ children }) => { const { theme } = useContext(ThemeContext); const locale = useSelector((state) => getLocale(state)); + // NOTE: temp. override solution + // TODO: remove once not needed for testing + const overrides = JSON.parse( + localStorage.getItem('eui-theme-overrides') || '{}' + ); + const mappingFuncs = { 'en-xa': translateUsingPseudoLocale, }; @@ -57,6 +63,7 @@ export const AppContext = ({ children }) => { }} theme={EUI_THEMES.find((t) => t.value === theme)?.provider} colorMode={theme.includes('light') ? 'light' : 'dark'} + modify={overrides} > { - const { euiTheme, colorMode } = euiThemeContext; + const { euiTheme } = euiThemeContext; return { // Colors shared between buttons and badges @@ -31,16 +31,10 @@ export const euiBadgeColors = (euiThemeContext: UseEuiTheme) => { // Hollow has a border and is used for autocompleters and beta badges hollow: { ...getBadgeColors(euiThemeContext, euiTheme.colors.emptyShade), - borderColor: - colorMode === 'DARK' - ? tint(euiTheme.border.color, 0.15) - : euiTheme.border.color, + borderColor: euiTheme.colors.borderHollow, }, // Colors used by beta and notification badges - subdued: getBadgeColors( - euiThemeContext, - tint(euiTheme.colors.lightShade, 0.3) - ), + subdued: getBadgeColors(euiThemeContext, euiTheme.colors.borderSubdued), accentText: getBadgeColors(euiThemeContext, euiTheme.colors.accentText), }; }; diff --git a/packages/eui/src/components/button/button.tsx b/packages/eui/src/components/button/button.tsx index 63a0ad3a319..c0ee438ad43 100644 --- a/packages/eui/src/components/button/button.tsx +++ b/packages/eui/src/components/button/button.tsx @@ -21,7 +21,7 @@ import { useEuiButtonColorCSS, useEuiButtonFocusCSS, _EuiButtonColor, -} from '../../themes/amsterdam/global_styling/mixins/button'; +} from '../../global_styling/mixins/_button'; import { EuiButtonDisplay, EuiButtonDisplayCommonProps, diff --git a/packages/eui/src/components/flyout/flyout_resizable.tsx b/packages/eui/src/components/flyout/flyout_resizable.tsx index a91d4b20c54..aac4baa17a9 100644 --- a/packages/eui/src/components/flyout/flyout_resizable.tsx +++ b/packages/eui/src/components/flyout/flyout_resizable.tsx @@ -173,7 +173,7 @@ export const EuiFlyoutResizable = forwardRef( > mathWithUnits(euiTheme.size.base, (x) => x * 25); export const euiFormVariables = (euiThemeContext: UseEuiTheme) => { - const { euiTheme, colorMode } = euiThemeContext; - const isColorDark = colorMode === 'DARK'; - const backgroundColor = isColorDark - ? shade(euiTheme.colors.lightestShade, 0.4) - : tint(euiTheme.colors.lightestShade, 0.6); + const { euiTheme } = euiThemeContext; + const backgroundColor = euiTheme.colors.formBackground; const controlHeight = euiTheme.size.xxl; const controlCompressedHeight = euiTheme.size.xl; @@ -53,22 +42,13 @@ export const euiFormVariables = (euiThemeContext: UseEuiTheme) => { const colors = { textColor: euiTheme.colors.text, backgroundColor: backgroundColor, - backgroundDisabledColor: darken(euiTheme.colors.lightestShade, 0.05), + backgroundDisabledColor: euiTheme.colors.formBackgroundDisabled, backgroundReadOnlyColor: euiTheme.colors.emptyShade, - borderColor: transparentize( - colorMode === 'DARK' - ? euiTheme.colors.ghost - : darken(euiTheme.border.color, 4), - 0.1 - ), + borderColor: euiTheme.colors.formBorderColor, controlDisabledColor: euiTheme.colors.mediumShade, controlBoxShadow: '0 0 transparent', - controlPlaceholderText: makeHighContrastColor(euiTheme.colors.subduedText)( - backgroundColor - ), - appendPrependBackground: isColorDark - ? shade(euiTheme.colors.lightShade, 0.15) - : tint(euiTheme.colors.lightShade, 0.5), + controlPlaceholderText: euiTheme.colors.formControlPlaceholderColor, + appendPrependBackground: euiTheme.colors.formAppendBackground, }; const controlLayout = { @@ -234,16 +214,9 @@ export const euiFormControlDefaultShadow = ( `; }; -export const euiFormControlFocusStyles = ({ - euiTheme, - colorMode, -}: UseEuiTheme) => ` +export const euiFormControlFocusStyles = ({ euiTheme }: UseEuiTheme) => ` --euiFormControlStateColor: ${euiTheme.colors.primary}; - background-color: ${ - colorMode === 'DARK' - ? shade(euiTheme.colors.emptyShade, 0.4) - : euiTheme.colors.emptyShade - }; + background-color: ${euiTheme.colors.formBackgroundFocused}; background-size: 100% 100%; outline: none; /* Remove all outlines and rely on our own bottom border gradient */ `; @@ -285,23 +258,19 @@ export const euiFormControlReadOnlyStyles = (euiThemeContext: UseEuiTheme) => { }; export const euiFormControlAutoFillStyles = (euiThemeContext: UseEuiTheme) => { - const { euiTheme, colorMode } = euiThemeContext; + const { euiTheme } = euiThemeContext; // Make the text color slightly less prominent than the default colors.text const textColor = euiTheme.colors.darkestShade; - const { backgroundColor } = euiButtonColor(euiThemeContext, 'primary'); - const tintedBackgroundColor = - colorMode === 'DARK' - ? shade(backgroundColor, 0.5) - : tint(backgroundColor, 0.7); + const tintedBackgroundColor = euiTheme.colors.formAutofillBackground; // Hacky workaround to background-color, since Chrome doesn't normally allow overriding its styles // @see https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill#sect1 const backgroundShadow = `inset 0 0 0 100vw ${tintedBackgroundColor}`; // Re-create the border, since the above webkit box shadow overrides the default border box-shadow // + change the border color to match states, since the underline background gradient no longer works - const borderColor = transparentize(euiTheme.colors.primaryText, 0.2); + const borderColor = euiTheme.colors.formAutofillBorderColor; const invalidBorder = euiTheme.colors.danger; const borderShadow = (color: string) => `inset 0 0 0 ${euiTheme.border.width.thin} ${color}`; @@ -332,7 +301,7 @@ const euiPlaceholderPerBrowser = (content: string) => ` */ export const euiFormCustomControlVariables = (euiThemeContext: UseEuiTheme) => { - const { euiTheme, colorMode } = euiThemeContext; + const { euiTheme } = euiThemeContext; const sizes = { control: euiTheme.size.base, @@ -342,10 +311,7 @@ export const euiFormCustomControlVariables = (euiThemeContext: UseEuiTheme) => { const colors = { unselected: euiTheme.colors.emptyShade, - unselectedBorder: - colorMode === 'DARK' - ? tint(euiTheme.colors.lightestShade, 0.31) // WCAG AA requirements - : shade(euiTheme.colors.lightestShade, 0.4), + unselectedBorder: euiTheme.colors.formControlBorder, selected: euiTheme.colors.primary, selectedIcon: euiTheme.colors.emptyShade, disabled: euiTheme.colors.lightShade, diff --git a/packages/eui/src/components/provider/provider.tsx b/packages/eui/src/components/provider/provider.tsx index 2275009bd7c..6c8a12eda55 100644 --- a/packages/eui/src/components/provider/provider.tsx +++ b/packages/eui/src/components/provider/provider.tsx @@ -22,7 +22,7 @@ import { EuiGlobalStylesProps, } from '../../global_styling/reset/global_styles'; import { EuiUtilityClasses } from '../../global_styling/utility/utility'; -import { EuiThemeAmsterdam } from '../../themes'; +import { EuiThemeNew } from '../../themes'; import { EuiCacheProvider } from './cache'; import { EuiProviderNestedCheck, useIsNestedEuiProvider } from './nested'; @@ -84,7 +84,7 @@ export interface EuiProviderProps export const EuiProvider = ({ cache = fallbackCache, - theme = EuiThemeAmsterdam, + theme = EuiThemeNew, globalStyles: Globals = EuiGlobalStyles, utilityClasses: Utilities = EuiUtilityClasses, colorMode, diff --git a/packages/eui/src/global_styling/mixins/_button.ts b/packages/eui/src/global_styling/mixins/_button.ts new file mode 100644 index 00000000000..3a5cb550ff2 --- /dev/null +++ b/packages/eui/src/global_styling/mixins/_button.ts @@ -0,0 +1,227 @@ +/* + * 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 { css, keyframes, type SerializedStyles } from '@emotion/react'; +import { _EuiThemeButtonColors, euiCanAnimate } from '../index'; +import { UseEuiTheme, useEuiMemoizedStyles } from '../../services'; + +export const BUTTON_COLORS = [ + 'text', + 'accent', + 'primary', + 'success', + 'warning', + 'danger', +] as const; +export type _EuiButtonColor = (typeof BUTTON_COLORS)[number]; + +export const BUTTON_DISPLAYS = ['base', 'fill', 'empty'] as const; +export type _EuiButtonDisplay = (typeof BUTTON_DISPLAYS)[number]; + +export interface _EuiButtonOptions { + display?: _EuiButtonDisplay; +} + +/** + * Creates the `base` version of button styles with proper text contrast. + * @param euiThemeContext + * @param color One of the named button colors or 'disabled' + * @returns Style object `{ backgroundColor, color }` + */ +export const euiButtonColor = ( + euiThemeContext: UseEuiTheme, + color: _EuiButtonColor | 'disabled' +) => { + const { euiTheme } = euiThemeContext; + + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const backgroundToken = + `buttonSecondaryBackground${colorName}` as keyof _EuiThemeButtonColors; + const colorToken = + `buttonSecondaryColor${colorName}` as keyof _EuiThemeButtonColors; + + return { + color: euiTheme.colors[colorToken], + backgroundColor: euiTheme.colors[backgroundToken], + }; +}; + +/** + * Creates the `fill` version of buttons styles with proper text contrast. + * @param euiThemeContext + * @param color One of the named button colors or 'disabled' + * @returns Style object `{ backgroundColor, color }` + */ +export const euiButtonFillColor = ( + euiThemeContext: UseEuiTheme, + color: _EuiButtonColor | 'disabled' +) => { + const { euiTheme } = euiThemeContext; + + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const backgroundToken = + `buttonBackground${colorName}` as keyof _EuiThemeButtonColors; + const colorToken = `buttonColor${colorName}` as keyof _EuiThemeButtonColors; + + return { + color: euiTheme.colors[colorToken], + backgroundColor: euiTheme.colors[backgroundToken], + }; +}; + +/** + * Creates the `empty` version of button styles using the text-variant and adding interactive styles. + * @param euiThemeContext + * @param color One of the named button colors or 'disabled' + * @returns Style object `{ backgroundColor, color }` where `background` is typically used for interactive states + */ +export const euiButtonEmptyColor = ( + euiThemeContext: UseEuiTheme, + color: _EuiButtonColor | 'disabled' +) => { + const { euiTheme } = euiThemeContext; + + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const backgroundToken = + `buttonEmptyBackground${colorName}` as keyof _EuiThemeButtonColors; + const colorToken = + `buttonEmptyColor${colorName}` as keyof _EuiThemeButtonColors; + + return { + color: euiTheme.colors[colorToken], + backgroundColor: euiTheme.colors[backgroundToken], + }; +}; + +/** + * Given the button display type, returns the Emotion based color keys. + * @param options Button display type + * @returns An object of `_EuiButtonColor` keys including `disabled` + */ +export const useEuiButtonColorCSS = (options: _EuiButtonOptions = {}) => { + const { display = 'base' } = options; + + const colorsDisplaysMap = useEuiMemoizedStyles(euiButtonDisplaysColors); + return colorsDisplaysMap[display]; +}; + +const euiButtonDisplaysColors = (euiThemeContext: UseEuiTheme) => { + const COLORS = [...BUTTON_COLORS, 'disabled'] as const; + type Colors = (typeof COLORS)[number]; + + const displaysColorsMap = {} as Record< + _EuiButtonDisplay, + Record + >; + + BUTTON_DISPLAYS.forEach((display) => { + displaysColorsMap[display] = {} as Record; + + COLORS.forEach((color) => { + switch (display) { + case 'base': + displaysColorsMap[display][color] = css` + ${euiButtonColor(euiThemeContext, color)} + `; + break; + case 'fill': + displaysColorsMap[display][color] = css` + ${euiButtonFillColor(euiThemeContext, color)} + + /* Use full shade for outline-color except for dark mode text buttons which need to stay currentColor */ + outline-color: ${euiThemeContext.colorMode === 'DARK' && + color === 'text' + ? 'currentColor' + : euiThemeContext.euiTheme.colors.fullShade}; + `; + break; + case 'empty': + displaysColorsMap[display][color] = css` + color: ${euiButtonEmptyColor(euiThemeContext, color).color}; + + &:focus, + &:active { + background-color: ${euiButtonEmptyColor(euiThemeContext, color) + .backgroundColor}; + } + `; + break; + } + + // Tweak auto-generated Emotion label/className output + const emotionOutput = displaysColorsMap[display][color]; + emotionOutput.styles = emotionOutput.styles.replace( + 'label:displaysColorsMap-display-color;', + `label:${display}-${color};` + ); + }); + }); + + return displaysColorsMap; +}; + +/** + * Creates the translate animation when button is in focus. + * @returns string + */ +export const useEuiButtonFocusCSS = () => + useEuiMemoizedStyles(euiButtonFocusCSS); + +const euiButtonFocusAnimation = keyframes` + 50% { + transform: translateY(1px); + } +`; +const euiButtonFocusCSS = ({ euiTheme }: UseEuiTheme) => { + const focusCSS = css` + ${euiCanAnimate} { + transition: transform ${euiTheme.animation.normal} ease-in-out, + background-color ${euiTheme.animation.normal} ease-in-out; + + &:hover:not(:disabled) { + transform: translateY(-1px); + } + + &:focus { + animation: ${euiButtonFocusAnimation} ${euiTheme.animation.normal} + ${euiTheme.animation.bounce}; + } + + &:active:not(:disabled) { + transform: translateY(1px); + } + } + `; + // Remove the auto-generated label. + // We could typically avoid a label by using a plain string `` instead of css``, + // but we need css`` for keyframes`` to work for the focus animation + focusCSS.styles = focusCSS.styles.replace('label:focusCSS;', ''); + return focusCSS; +}; + +/** + * Map of `size` props to various sizings/scales + * that should remain consistent across all buttons + */ +export const euiButtonSizeMap = ({ euiTheme }: UseEuiTheme) => ({ + xs: { + height: euiTheme.size.l, + radius: euiTheme.border.radius.small, + fontScale: 'xs' as const, + }, + s: { + height: euiTheme.size.xl, + radius: euiTheme.border.radius.small, + fontScale: 's' as const, + }, + m: { + height: euiTheme.size.xxl, + radius: euiTheme.border.radius.medium, + fontScale: 's' as const, + }, +}); diff --git a/packages/eui/src/global_styling/mixins/_color.ts b/packages/eui/src/global_styling/mixins/_color.ts index 74087f584ff..f49b505c830 100644 --- a/packages/eui/src/global_styling/mixins/_color.ts +++ b/packages/eui/src/global_styling/mixins/_color.ts @@ -7,14 +7,12 @@ */ import { css, SerializedStyles } from '@emotion/react'; +import { UseEuiTheme, useEuiMemoizedStyles } from '../../services'; import { - shade, - tint, - tintOrShade, - transparentize, - UseEuiTheme, - useEuiMemoizedStyles, -} from '../../services'; + _EuiThemeBackgroundColors, + _EuiThemeBorderColors, + _EuiThemeTransparentBackgroundColors, +} from '../variables'; export const BACKGROUND_COLORS = [ 'transparent', @@ -40,34 +38,31 @@ export interface _EuiBackgroundColorOptions { * @returns A single background color with optional alpha transparency */ export const euiBackgroundColor = ( - { euiTheme, colorMode }: UseEuiTheme, + { euiTheme }: UseEuiTheme, color: _EuiBackgroundColor, { method }: _EuiBackgroundColorOptions = {} ) => { if (color === 'transparent') return 'transparent'; if (method === 'transparent') { - if (color === 'plain') { - return transparentize(euiTheme.colors.ghost, 0.2); - } else if (color === 'subdued') { - return colorMode === 'DARK' - ? transparentize(euiTheme.colors.lightShade, 0.4) - : transparentize(euiTheme.colors.lightShade, 0.2); - } else { - return transparentize(euiTheme.colors[color], 0.1); - } - } else { - function tintOrShade(color: string) { - return colorMode === 'DARK' ? shade(color, 0.8) : tint(color, 0.9); - } + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const colorToken = + `background${colorName}Transparent` as keyof _EuiThemeTransparentBackgroundColors; + return euiTheme.colors[colorToken]; + } else { switch (color) { case 'plain': return euiTheme.colors.emptyShade; case 'subdued': return euiTheme.colors.body; - default: - return tintOrShade(euiTheme.colors[color]); + default: { + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const colorToken = + `background${colorName}` as keyof _EuiThemeBackgroundColors; + + return euiTheme.colors[colorToken]; + } } } }; @@ -131,18 +126,17 @@ export const useEuiBackgroundColorCSS = () => */ export const euiBorderColor = ( - { euiTheme, colorMode }: UseEuiTheme, + { euiTheme }: UseEuiTheme, color: _EuiBackgroundColor ) => { switch (color) { case 'transparent': - case 'plain': - case 'subdued': return euiTheme.border.color; - case 'warning': - return tintOrShade(euiTheme.colors.warning, 0.4, colorMode); - default: - return tintOrShade(euiTheme.colors[color], 0.6, colorMode); + default: { + const colorName = color.charAt(0).toUpperCase() + color.slice(1); + const colorToken = `border${colorName}` as keyof _EuiThemeBorderColors; + return euiTheme.colors[colorToken]; + } } }; diff --git a/packages/eui/src/global_styling/variables/_color_matrix.ts b/packages/eui/src/global_styling/variables/_color_matrix.ts new file mode 100644 index 00000000000..0ad79596de7 --- /dev/null +++ b/packages/eui/src/global_styling/variables/_color_matrix.ts @@ -0,0 +1,247 @@ +/* + * 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 { _EuiThemeSemanticMatrixColors } from './colors'; + +export const COLOR_SHADES_COUNT = 14; + +export type _ColorData = string[]; + +export type _ColorMatrix = { + blue: _ColorData; + blueGrey: _ColorData; + teal: _ColorData; + pink: _ColorData; + green: _ColorData; + yellow: _ColorData; + red: _ColorData; +}; + +export type _SemanticColors = { + shade: string; +}; + +export const MATRIX_TO_SEMANTIC_COLOR_NAME_MAP = { + blueGrey: 'shade', + blue: 'primary', + pink: 'accent', + teal: 'highlight', + green: 'success', + red: 'danger', + yellow: 'warning', +}; + +export const COLOR_MATRIX: _ColorMatrix = { + blue: [ + '#f1f9ff', + '#d2e7ff', + '#b4d5ff', + '#96c3ff', + '#78b0ff', + '#599dff', + '#3788ff', + '#2476f0', + '#0b64dd', + '#004fc7', + '#00419e', + '#043376', + '#092551', + '#09182f', + ], + blueGrey: [ + '#f6f9fc', + '#ebeff6', + '#e0e6f1', + '#d4ddeb', + '#c9d4e6', + '#becce0', + '#b3c3da', + '#a9bad5', + '#9eb1cf', + '#93a8c9', + '#89a0c4', + '#7e97be', + '#748fb8', + '#6c86af', + '#647ea7', + '#5c759e', + '#546d95', + '#4c658c', + '#445c83', + '#3d5479', + '#364c6f', + '#2f4466', + '#283c5c', + '#223553', + '#1b2d49', + '#152640', + '#0f1f38', + '#09182F', + ], + // neutralGrey: [ + // '#f5f9fe', + // '#e1e6ee', + // '#ced4de', + // '#bac2ce', + // '#a7b0bf', + // '#959faf', + // '#838ea0', + // '#727d8f', + // '#626d7e', + // '#505b6b', + // '#404958', + // '#303845', + // '#212833', + // '#131922', + // ], + teal: [ + '#eafdfc', + '#c0f1ee', + '#93e5e0', + '#5dd8d2', + '#00cbc5', + '#00beb8', + '#00b0aa', + '#009e99', + '#008c88', + '#007775', + '#00605d', + '#004947', + '#003432', + '#001f1e', + ], + pink: [ + '#fff3f9', + '#ffd9e7', + '#ffbed5', + '#fba3c4', + '#f588b3', + '#ed6ba2', + '#e54a91', + '#d13680', + '#bd1f70', + '#a6005e', + '#85044b', + '#650d3a', + '#460f29', + '#290d19', + ], + green: [ + '#eefdf4', + '#caf1db', + '#a6e4c2', + '#7ed8a9', + '#4dcb91', + '#00bd79', + '#00b060', + '#009e50', + '#008c40', + '#00782d', + '#006026', + '#00491f', + '#003317', + '#001f10', + ], + yellow: [ + '#fef8ea', + '#f3e5c1', + '#e8d297', + '#ddbf6a', + '#d2ab30', + '#c79700', + '#bc8300', + '#aa7100', + '#996000', + '#854d00', + '#6A3f00', + '#503100', + '#382400', + '#211700', + ], + red: [ + '#fff4f1', + '#ffdad5', + '#ffc0b8', + '#ffa59c', + '#fc8a80', + '#f66d64', + '#ee4c48', + '#da3737', + '#c61e25', + '#af000e', + '#8c0210', + '#6a0d10', + '#4a100f', + '#2b0e0c', + ], +}; + +// color matrix map for fast lookup +// valu based definition hierarchy: value-name-shade +// e.g.: '#AF000E': { group: 'danger', shade: 10 } +export const COLOR_MATRIX_MAP = new Map< + string, + { group: keyof _ColorMatrix; shade: number } +>(); + +if (COLOR_MATRIX_MAP.size === 0) { + for (const [key, value] of Object.entries<_ColorData>(COLOR_MATRIX)) { + for (const [index, colorValue] of value.entries()) { + const position = index + 1; + + COLOR_MATRIX_MAP.set(colorValue.toLowerCase(), { + group: key as keyof _ColorMatrix, + shade: position, + }); + } + } +} + +export const getColorMatrixValue = ( + group: keyof _ColorMatrix, + shade: number +) => { + const hasLargeScale = group === 'blueGrey'; + + const step = hasLargeScale ? (shade / 10) * 2 - 1 : shade / 10; + const position = step > 0 ? step - 1 : step; + + return COLOR_MATRIX[group][position].toLowerCase(); +}; + +export const semanticColors: _EuiThemeSemanticMatrixColors = + {} as _EuiThemeSemanticMatrixColors; + +export const matrixColors = Object.keys(COLOR_MATRIX).reduce((acc, cur) => { + const group = cur as keyof _ColorMatrix; + const groupColors = COLOR_MATRIX[group]; + const hasLargeScale = groupColors.length > COLOR_SHADES_COUNT; + let largeScaleIndex = 0; + + const colors = groupColors.reduce((acc, color, i) => { + largeScaleIndex = i === 0 ? 1 : largeScaleIndex + 0.5; + + const shade = hasLargeScale ? largeScaleIndex * 10 : (i + 1) * 10; + + const semanticGroup = MATRIX_TO_SEMANTIC_COLOR_NAME_MAP[group]; + const semanticColorName = + `${semanticGroup}${shade}` as unknown as keyof _EuiThemeSemanticMatrixColors; + + semanticColors[semanticColorName] = color; + + return { + ...acc, + [`${group}-${shade}`]: color, + }; + }, {}); + + return { + ...acc, + ...colors, + }; +}, {}); diff --git a/packages/eui/src/global_styling/variables/colors.ts b/packages/eui/src/global_styling/variables/colors.ts index ab15e23d166..318a9bbe3b2 100644 --- a/packages/eui/src/global_styling/variables/colors.ts +++ b/packages/eui/src/global_styling/variables/colors.ts @@ -111,6 +111,17 @@ export type _EuiThemeTextColors = { * Computed against `colors.primaryText` */ link: ColorModeSwitch; + + textHeading: ColorModeSwitch; + textParagraph: ColorModeSwitch; + textSubdued: ColorModeSwitch; + textPrimary: ColorModeSwitch; + textAccent: ColorModeSwitch; + textSuccess: ColorModeSwitch; + textWarning: ColorModeSwitch; + textDanger: ColorModeSwitch; + textDisabled: ColorModeSwitch; + textInverse: ColorModeSwitch; }; export type _EuiThemeSpecialColors = { @@ -149,11 +160,241 @@ export type _EuiThemeConstantColors = { ink: string; }; +export type _EuiThemeSemanticMatrixColors = { + shade10: string; + shade15: string; + shade20: string; + shade25: string; + shade30: string; + shade35: string; + shade40: string; + shade45: string; + shade50: string; + shade55: string; + shade60: string; + shade65: string; + shade70: string; + shade75: string; + shade80: string; + shade85: string; + shade90: string; + shade95: string; + shade100: string; + shade105: string; + shade110: string; + shade115: string; + shade120: string; + shade125: string; + shade130: string; + shade135: string; + shade140: string; + shade145: string; + + primary10: string; + primary20: string; + primary30: string; + primary40: string; + primary50: string; + primary60: string; + primary70: string; + primary80: string; + primary90: string; + primary100: string; + primary110: string; + primary120: string; + primary130: string; + primary140: string; + + accent10: string; + accent20: string; + accent30: string; + accent40: string; + accent50: string; + accent60: string; + accent70: string; + accent80: string; + accent90: string; + accent100: string; + accent110: string; + accent120: string; + accent130: string; + accent140: string; + + highlight10: string; + highlight20: string; + highlight30: string; + highlight40: string; + highlight50: string; + highlight60: string; + highlight70: string; + highlight80: string; + highlight90: string; + highlight100: string; + highlight110: string; + highlight120: string; + highlight130: string; + highlight140: string; + + success10: string; + success20: string; + success30: string; + success40: string; + success50: string; + success60: string; + success70: string; + success80: string; + success90: string; + success100: string; + success110: string; + success120: string; + success130: string; + success140: string; + + warning10: string; + warning20: string; + warning30: string; + warning40: string; + warning50: string; + warning60: string; + warning70: string; + warning80: string; + warning90: string; + warning100: string; + warning110: string; + warning120: string; + warning130: string; + warning140: string; + + danger10: string; + danger20: string; + danger30: string; + danger40: string; + danger50: string; + danger60: string; + danger70: string; + danger80: string; + danger90: string; + danger100: string; + danger110: string; + danger120: string; + danger130: string; + danger140: string; +}; + +export type _EuiThemeSemanticColors = _EuiThemeSemanticMatrixColors & { + plain: string; + ink: string; + developerBlue: string; +}; + +export type _EuiThemeBackgroundColors = { + backgroundPrimary: ColorModeSwitch; + backgroundAccent: ColorModeSwitch; + backgroundSuccess: ColorModeSwitch; + backgroundWarning: ColorModeSwitch; + backgroundDanger: ColorModeSwitch; + backgroundSubdued: ColorModeSwitch; + backgroundPlain: ColorModeSwitch; + backgroundDisabled: ColorModeSwitch; +}; + +export type _EuiThemeTransparentBackgroundColors = { + backgroundPrimaryTransparent: ColorModeSwitch; + backgroundAccentTransparent: ColorModeSwitch; + backgroundSuccessTransparent: ColorModeSwitch; + backgroundWarningTransparent: ColorModeSwitch; + backgroundDangerTransparent: ColorModeSwitch; + backgroundSubduedTransparent: ColorModeSwitch; + backgroundPlainTransparent: ColorModeSwitch; +}; + +export type _EuiThemeBorderColors = { + borderPrimary: ColorModeSwitch; + borderAccent: ColorModeSwitch; + borderSuccess: ColorModeSwitch; + borderWarning: ColorModeSwitch; + borderDanger: ColorModeSwitch; + borderSubdued: ColorModeSwitch; + borderPlain: ColorModeSwitch; + borderDisabled: ColorModeSwitch; + borderHollow: ColorModeSwitch; +}; + +export type _EuiThemeFormColors = { + formBackground: ColorModeSwitch; + formBackgroundDisabled: ColorModeSwitch; + formBackgroundFocused: ColorModeSwitch; + formBorderColor: ColorModeSwitch; + formAppendBackground: ColorModeSwitch; + formControlPlaceholderColor: ColorModeSwitch; + formControlBorder: ColorModeSwitch; + formAutofillBackground: ColorModeSwitch; + formAutofillBorderColor: ColorModeSwitch; +}; + +export type _EuiThemeButtonColors = { + buttonBackgroundPrimary: ColorModeSwitch; + buttonBackgroundAccent: ColorModeSwitch; + buttonBackgroundSuccess: ColorModeSwitch; + buttonBackgroundWarning: ColorModeSwitch; + buttonBackgroundDanger: ColorModeSwitch; + buttonBackgroundText: ColorModeSwitch; + buttonBackgroundDisabled: ColorModeSwitch; + + buttonSecondaryBackgroundPrimary: ColorModeSwitch; + buttonSecondaryBackgroundAccent: ColorModeSwitch; + buttonSecondaryBackgroundSuccess: ColorModeSwitch; + buttonSecondaryBackgroundWarning: ColorModeSwitch; + buttonSecondaryBackgroundDanger: ColorModeSwitch; + buttonSecondaryBackgroundText: ColorModeSwitch; + buttonSecondaryBackgroundDisabled: ColorModeSwitch; + + buttonEmptyBackgroundPrimary: ColorModeSwitch; + buttonEmptyBackgroundAccent: ColorModeSwitch; + buttonEmptyBackgroundSuccess: ColorModeSwitch; + buttonEmptyBackgroundWarning: ColorModeSwitch; + buttonEmptyBackgroundDanger: ColorModeSwitch; + buttonEmptyBackgroundText: ColorModeSwitch; + buttonEmptyBackgroundDisabled: ColorModeSwitch; + + buttonColorPrimary: ColorModeSwitch; + buttonColorAccent: ColorModeSwitch; + buttonColorSuccess: ColorModeSwitch; + buttonColorWarning: ColorModeSwitch; + buttonColorDanger: ColorModeSwitch; + buttonColorText: ColorModeSwitch; + buttonColorDisabled: ColorModeSwitch; + + buttonSecondaryColorPrimary: ColorModeSwitch; + buttonSecondaryColorAccent: ColorModeSwitch; + buttonSecondaryColorSuccess: ColorModeSwitch; + buttonSecondaryColorWarning: ColorModeSwitch; + buttonSecondaryColorDanger: ColorModeSwitch; + buttonSecondaryColorText: ColorModeSwitch; + buttonSecondaryColorDisabled: ColorModeSwitch; + + buttonEmptyColorPrimary: ColorModeSwitch; + buttonEmptyColorAccent: ColorModeSwitch; + buttonEmptyColorSuccess: ColorModeSwitch; + buttonEmptyColorWarning: ColorModeSwitch; + buttonEmptyColorDanger: ColorModeSwitch; + buttonEmptyColorText: ColorModeSwitch; + buttonEmptyColorDisabled: ColorModeSwitch; + + buttonBorderColorPrimary: ColorModeSwitch; +}; + export type _EuiThemeColorsMode = _EuiThemeBrandColors & + _EuiThemeSemanticColors & _EuiThemeBrandTextColors & _EuiThemeShadeColors & _EuiThemeSpecialColors & - _EuiThemeTextColors; + _EuiThemeTextColors & + _EuiThemeBackgroundColors & + _EuiThemeTransparentBackgroundColors & + _EuiThemeBorderColors & + _EuiThemeFormColors & + _EuiThemeButtonColors; export type _EuiThemeColors = StrictColorModeSwitch<_EuiThemeColorsMode> & _EuiThemeConstantColors; diff --git a/packages/eui/src/services/color/eui_palettes.ts b/packages/eui/src/services/color/eui_palettes.ts index c44a3bbfb0a..b48c4cfded2 100644 --- a/packages/eui/src/services/color/eui_palettes.ts +++ b/packages/eui/src/services/color/eui_palettes.ts @@ -64,16 +64,16 @@ export const euiPaletteColorBlind = ({ let colors: string[] = []; let base = [ - '#54B399', // 0 green - '#6092C0', // 1 blue - '#D36086', // 2 dark pink - '#9170B8', // 3 purple - '#CA8EAE', // 4 light pink - '#D6BF57', // 5 yellow - '#B9A888', // 6 tan - '#DA8B45', // 7 orange - '#AA6556', // 8 brown - '#E7664C', // 9 red + '#00BEB8', // 0 green + '#93E5E0', // 1 light green + '#599DFF', // 2 blue + '#B4D5FF', // 3 light blue + '#ED6BA2', // 4 dark pink + '#FFBED5', // 5 light pink + '#F66D64', // 6 red + '#FFC0B8', // 7 tan + '#C79700', // 8 brown + '#E8D297', // 9 yellow ]; if (sortBy === 'natural') { @@ -134,18 +134,18 @@ export const euiPaletteColorBlindBehindText = ( }; export const euiPaletteForLightBackground = function (): EuiPalette { - return ['#006BB4', '#017D73', '#F5A700', '#BD271E', '#DD0A73']; + return ['#007775', '#004FC7', '#A6005E', '#AF000E', '#854D00']; }; export const euiPaletteForDarkBackground = function (): EuiPalette { - return ['#1BA9F5', '#7DE2D1', '#F990C0', '#F66', '#FFCE7A']; + return ['#00BEB8', '#599DFF', '#ED6BA2', '#F66D64', '#C79700']; }; -const greenColor: HEX = '#209280'; -const redColor: HEX = '#CC5642'; -const lightRedColor: HEX = euiPaletteColorBlind()[9]; -const coolArray: HEX[] = [euiPaletteColorBlind()[1], '#6092C0']; -const warmArray: HEX[] = [euiPaletteColorBlind()[7], euiPaletteColorBlind()[9]]; +const greenColor: HEX = '#007775'; +const redColor: HEX = '#AF000E'; +const lightRedColor: HEX = euiPaletteColorBlind()[6]; +const coolArray: HEX[] = [euiPaletteColorBlind()[2], '#599DFF']; +const warmArray: HEX[] = [euiPaletteColorBlind()[7], euiPaletteColorBlind()[6]]; export const euiPaletteForStatus = function (steps: number): EuiPalette { if (steps === 1) { @@ -162,7 +162,7 @@ export const euiPaletteForStatus = function (steps: number): EuiPalette { [ greenColor, euiPaletteColorBlind()[0], - euiPaletteColorBlind()[5], + euiPaletteColorBlind()[9], lightRedColor, redColor, ], @@ -172,8 +172,8 @@ export const euiPaletteForStatus = function (steps: number): EuiPalette { }; export const euiPaletteForTemperature = function (steps: number): EuiPalette { - const cools = colorPalette([...coolArray.slice().reverse(), '#EBEFF5'], 3); - const warms = colorPalette(['#F4F3DB', ...warmArray], 3); + const cools = colorPalette([...coolArray.slice().reverse(), '#F1F9FF'], 3); + const warms = colorPalette(['#FFF4F1', ...warmArray], 3); if (steps === 1) { return [cools[0]]; @@ -186,11 +186,11 @@ export const euiPaletteForTemperature = function (steps: number): EuiPalette { export const euiPaletteComplementary = function (steps: number): EuiPalette { if (steps === 1) { - return [euiPaletteColorBlind()[1]]; + return [euiPaletteColorBlind()[2]]; } return euiPalette( - [euiPaletteColorBlind()[1], euiPaletteColorBlind()[7]], + [euiPaletteColorBlind()[2], euiPaletteColorBlind()[8]], steps, true ); @@ -225,16 +225,16 @@ export const euiPaletteWarm = function (steps: number): EuiPalette { return [lightRedColor]; } - return euiPalette(['#FBFBDC', ...warmArray], steps); + return euiPalette(['#FFF4F1', ...warmArray], steps); }; export const euiPaletteGray = function (steps: number): EuiPalette { if (steps === 1) { - return ['#98a2b3']; + return ['#B1C3DE']; } return euiPalette( - ['white', '#d3dae6', '#98a2b3', '#69707d', '#343741'], + ['white', '#F5F9FF', '#DEE7F4', '#C7D5E9', '#B1C3DE', '#9CB1D3', '#86A0C8'], steps, false ); diff --git a/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts b/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts index 3a94d5609a2..7e3e89f952c 100644 --- a/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts +++ b/packages/eui/src/themes/amsterdam/global_styling/mixins/button.ts @@ -6,294 +6,4 @@ * Side Public License, v 1. */ -import { css, keyframes, type SerializedStyles } from '@emotion/react'; -import { euiBackgroundColor, euiCanAnimate } from '../../../../global_styling'; -import { - hexToRgb, - isColorDark, - makeHighContrastColor, - shade, - tint, - transparentize, - UseEuiTheme, - useEuiMemoizedStyles, -} from '../../../../services'; - -export const BUTTON_COLORS = [ - 'text', - 'accent', - 'primary', - 'success', - 'warning', - 'danger', -] as const; -export type _EuiButtonColor = (typeof BUTTON_COLORS)[number]; - -export const BUTTON_DISPLAYS = ['base', 'fill', 'empty'] as const; -export type _EuiButtonDisplay = (typeof BUTTON_DISPLAYS)[number]; -export interface _EuiButtonOptions { - display?: _EuiButtonDisplay; -} - -/** - * Creates the `base` version of button styles with proper text contrast. - * @param euiThemeContext - * @param color One of the named button colors or 'disabled' - * @returns Style object `{ backgroundColor, color }` - */ -export const euiButtonColor = ( - euiThemeContext: UseEuiTheme, - color: _EuiButtonColor | 'disabled' -) => { - const { euiTheme, colorMode } = euiThemeContext; - function tintOrShade(color: string) { - return colorMode === 'DARK' ? shade(color, 0.7) : tint(color, 0.8); - } - - let foreground; - let background; - - switch (color) { - case 'disabled': - return { - color: euiTheme.colors.disabledText, - backgroundColor: transparentize(euiTheme.colors.lightShade, 0.15), - }; - case 'text': - foreground = euiTheme.colors[color]; - background = - colorMode === 'DARK' - ? shade(euiTheme.colors.lightShade, 0.2) - : tint(euiTheme.colors.lightShade, 0.5); - break; - default: - foreground = euiTheme.colors[`${color}Text`]; - background = tintOrShade(euiTheme.colors[color]); - break; - } - - return { - color: makeHighContrastColor(foreground)(background), - backgroundColor: background, - }; -}; - -/** - * Creates the `fill` version of buttons styles with proper text contrast. - * @param euiThemeContext - * @param color One of the named button colors or 'disabled' - * @returns Style object `{ backgroundColor, color }` - */ -export const euiButtonFillColor = ( - euiThemeContext: UseEuiTheme, - color: _EuiButtonColor | 'disabled' -) => { - const { euiTheme, colorMode } = euiThemeContext; - - const getForegroundColor = (background: string) => { - return isColorDark(...hexToRgb(background)) - ? euiTheme.colors.ghost - : euiTheme.colors.ink; - }; - - let background; - let foreground; - - switch (color) { - case 'disabled': - background = euiButtonColor(euiThemeContext, color).backgroundColor; - foreground = euiButtonColor(euiThemeContext, color).color; - break; - case 'text': - background = - colorMode === 'DARK' ? euiTheme.colors.text : euiTheme.colors.darkShade; - foreground = getForegroundColor(background); - break; - case 'success': - case 'accent': - // Success / accent fills are hard to read on light mode even though they pass color contrast ratios - // TODO: If WCAG 3 gets adopted (which would calculates luminosity & would allow us to use white text instead), - // we can get rid of this case (https://blog.datawrapper.de/color-contrast-check-data-vis-wcag-apca/) - background = - colorMode === 'LIGHT' - ? tint(euiTheme.colors[color], 0.3) - : euiTheme.colors[color]; - foreground = getForegroundColor(background); - break; - default: - background = euiTheme.colors[color]; - foreground = getForegroundColor(background); - break; - } - - return { - color: foreground, - backgroundColor: background, - }; -}; - -/** - * Creates the `empty` version of button styles using the text-variant and adding interactive styles. - * @param euiThemeContext - * @param color One of the named button colors or 'disabled' - * @returns Style object `{ backgroundColor, color }` where `background` is typically used for interactive states - */ -export const euiButtonEmptyColor = ( - euiThemeContext: UseEuiTheme, - color: _EuiButtonColor | 'disabled' -) => { - let foreground; - let background; - - switch (color) { - case 'disabled': - foreground = euiButtonColor(euiThemeContext, color).color; - background = 'transparent'; - break; - case 'text': - foreground = euiButtonColor(euiThemeContext, color).color; - background = euiBackgroundColor(euiThemeContext, 'subdued', { - method: 'transparent', - }); - break; - default: - foreground = euiButtonColor(euiThemeContext, color).color; - background = euiBackgroundColor(euiThemeContext, color, { - method: 'transparent', - }); - break; - } - - return { - color: foreground, - backgroundColor: background, - }; -}; - -/** - * Given the button display type, returns the Emotion based color keys. - * @param options Button display type - * @returns An object of `_EuiButtonColor` keys including `disabled` - */ -export const useEuiButtonColorCSS = (options: _EuiButtonOptions = {}) => { - const { display = 'base' } = options; - - const colorsDisplaysMap = useEuiMemoizedStyles(euiButtonDisplaysColors); - return colorsDisplaysMap[display]; -}; - -const euiButtonDisplaysColors = (euiThemeContext: UseEuiTheme) => { - const COLORS = [...BUTTON_COLORS, 'disabled'] as const; - type Colors = (typeof COLORS)[number]; - - const displaysColorsMap = {} as Record< - _EuiButtonDisplay, - Record - >; - - BUTTON_DISPLAYS.forEach((display) => { - displaysColorsMap[display] = {} as Record; - - COLORS.forEach((color) => { - switch (display) { - case 'base': - displaysColorsMap[display][color] = css` - ${euiButtonColor(euiThemeContext, color)} - `; - break; - case 'fill': - displaysColorsMap[display][color] = css` - ${euiButtonFillColor(euiThemeContext, color)} - - /* Use full shade for outline-color except for dark mode text buttons which need to stay currentColor */ - outline-color: ${euiThemeContext.colorMode === 'DARK' && - color === 'text' - ? 'currentColor' - : euiThemeContext.euiTheme.colors.fullShade}; - `; - break; - case 'empty': - displaysColorsMap[display][color] = css` - color: ${euiButtonEmptyColor(euiThemeContext, color).color}; - - &:focus, - &:active { - background-color: ${euiButtonEmptyColor(euiThemeContext, color) - .backgroundColor}; - } - `; - break; - } - - // Tweak auto-generated Emotion label/className output - const emotionOutput = displaysColorsMap[display][color]; - emotionOutput.styles = emotionOutput.styles.replace( - 'label:displaysColorsMap-display-color;', - `label:${display}-${color};` - ); - }); - }); - - return displaysColorsMap; -}; - -/** - * Creates the translate animation when button is in focus. - * @returns string - */ -export const useEuiButtonFocusCSS = () => - useEuiMemoizedStyles(euiButtonFocusCSS); - -const euiButtonFocusAnimation = keyframes` - 50% { - transform: translateY(1px); - } -`; -const euiButtonFocusCSS = ({ euiTheme }: UseEuiTheme) => { - const focusCSS = css` - ${euiCanAnimate} { - transition: transform ${euiTheme.animation.normal} ease-in-out, - background-color ${euiTheme.animation.normal} ease-in-out; - - &:hover:not(:disabled) { - transform: translateY(-1px); - } - - &:focus { - animation: ${euiButtonFocusAnimation} ${euiTheme.animation.normal} - ${euiTheme.animation.bounce}; - } - - &:active:not(:disabled) { - transform: translateY(1px); - } - } - `; - // Remove the auto-generated label. - // We could typically avoid a label by using a plain string `` instead of css``, - // but we need css`` for keyframes`` to work for the focus animation - focusCSS.styles = focusCSS.styles.replace('label:focusCSS;', ''); - return focusCSS; -}; - -/** - * Map of `size` props to various sizings/scales - * that should remain consistent across all buttons - */ -export const euiButtonSizeMap = ({ euiTheme }: UseEuiTheme) => ({ - xs: { - height: euiTheme.size.l, - radius: euiTheme.border.radius.small, - fontScale: 'xs' as const, - }, - s: { - height: euiTheme.size.xl, - radius: euiTheme.border.radius.small, - fontScale: 's' as const, - }, - m: { - height: euiTheme.size.xxl, - radius: euiTheme.border.radius.medium, - fontScale: 's' as const, - }, -}); +export * from '../../../../global_styling/mixins/_button'; diff --git a/packages/eui/src/themes/amsterdam/global_styling/variables/_colors.ts b/packages/eui/src/themes/amsterdam/global_styling/variables/_colors.ts index aa86e3f1ee6..8bb53f519e4 100644 --- a/packages/eui/src/themes/amsterdam/global_styling/variables/_colors.ts +++ b/packages/eui/src/themes/amsterdam/global_styling/variables/_colors.ts @@ -6,8 +6,15 @@ * Side Public License, v 1. */ -import { shade, tint } from '../../../../services/color'; +import { + darken, + shade, + tint, + transparentize, +} from '../../../../services/color'; import { computed } from '../../../../services/theme/utils'; +import { isColorDark } from '../../../../services/color/is_color_dark'; +import { hexToRgb } from '../../../../services/color/hex_to_rgb'; import { makeHighContrastColor, makeDisabledContrastColor, @@ -20,13 +27,23 @@ import { _EuiThemeSpecialColors, _EuiThemeTextColors, _EuiThemeColorsMode, + _EuiThemeBackgroundColors, + _EuiThemeButtonColors, } from '../../../../global_styling/variables/colors'; +import { semanticColors } from '../../../../global_styling/variables/_color_matrix'; /* * LIGHT THEME * Only split up in the light theme to access the keys by section in the docs */ +const semantic_colors = { + plain: '#fff', + ink: '#000', + developerBlue: '#080F21', + ...semanticColors, +}; + export const brand_colors: _EuiThemeBrandColors = { primary: '#07C', accent: '#F04E98', @@ -69,21 +86,337 @@ export const text_colors: _EuiThemeTextColors = { title: computed(([text]) => shade(text, 0.5), ['colors.text']), subduedText: computed(makeHighContrastColor('colors.darkShade')), link: computed(([primaryText]) => primaryText, ['colors.primaryText']), + + textHeading: computed(([text]) => shade(text, 0.5), ['colors.text']), + textParagraph: computed( + ([darkestShade]) => darkestShade, + ['colors.darkestShade'] + ), + textSubdued: computed(makeHighContrastColor('colors.darkShade')), + textPrimary: computed(makeHighContrastColor('colors.primary')), + textAccent: computed(makeHighContrastColor('colors.accent')), + textSuccess: computed(makeHighContrastColor('colors.success')), + textWarning: computed(makeHighContrastColor('colors.warning')), + textDanger: computed(makeHighContrastColor('colors.danger')), + textDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + textInverse: computed(([ink]) => ink, ['colors.ink']), +}; + +export const background_colors: _EuiThemeBackgroundColors = { + backgroundPrimary: computed( + ([primary]) => tint(primary, 0.9), + ['colors.primary'] + ), + backgroundAccent: computed( + ([accent]) => tint(accent, 0.9), + ['colors.accent'] + ), + backgroundSuccess: computed( + ([success]) => tint(success, 0.9), + ['colors.success'] + ), + backgroundWarning: computed( + ([warning]) => tint(warning, 0.9), + ['colors.warning'] + ), + backgroundDanger: computed( + ([danger]) => tint(danger, 0.9), + ['colors.danger'] + ), + backgroundSubdued: special_colors.body, + backgroundPlain: shade_colors.emptyShade, + backgroundDisabled: computed( + ([disabled]) => tint(disabled, 0.9), + ['colors.disabled'] + ), +}; + +export const transparent_background_colors = { + backgroundPrimaryTransparent: computed( + ([primary]) => transparentize(primary, 0.1), + ['colors.primary'] + ), + backgroundAccentTransparent: computed( + ([accent]) => transparentize(accent, 0.1), + ['colors.accent'] + ), + backgroundSuccessTransparent: computed( + ([success]) => transparentize(success, 0.1), + ['colors.success'] + ), + backgroundWarningTransparent: computed( + ([warning]) => transparentize(warning, 0.1), + ['colors.warning'] + ), + backgroundDangerTransparent: computed( + ([danger]) => transparentize(danger, 0.1), + ['colors.danger'] + ), + backgroundSubduedTransparent: computed( + ([lightShade]) => transparentize(lightShade, 0.2), + ['colors.lightShade'] + ), + backgroundPlainTransparent: computed( + ([ghost]) => transparentize(ghost, 0.2), + ['colors.ghost'] + ), +}; + +export const border_colors = { + borderPrimary: computed( + ([primary]) => tint(primary, 0.6), + ['colors.primary'] + ), + borderAccent: computed(([accent]) => tint(accent, 0.6), ['colors.accent']), + borderSuccess: computed( + ([success]) => tint(success, 0.6), + ['colors.success'] + ), + borderWarning: computed( + ([warning]) => tint(warning, 0.4), + ['colors.warning'] + ), + borderDanger: computed(([danger]) => tint(danger, 0.6), ['colors.danger']), + borderPlain: computed(([lightShade]) => lightShade, ['colors.lightShade']), + borderSubdued: computed( + ([lightShade]) => tint(lightShade, 0.3), + ['colors.lightShade'] + ), + borderDisabled: computed( + ([borderPlain]) => borderPlain, + ['colors.borderPlain'] + ), + borderHollow: computed( + ([borderPlain]) => borderPlain, + ['colors.borderPlain'] + ), +}; + +const form_colors = { + formBackground: computed( + ([lightestShade]) => tint(lightestShade, 0.6), + ['colors.lightestShade'] + ), + formBackgroundDisabled: computed( + ([lightestShade]) => darken(lightestShade, 0.05), + ['colors.lightestShade'] + ), + formBackgroundFocused: computed( + ([emptyShade]) => emptyShade, + ['colors.emptyShade'] + ), + formBorderColor: computed( + ([borderPlain]) => transparentize(darken(borderPlain, 4), 0.1), + ['colors.borderPlain'] + ), + formAppendBackground: computed( + ([lightShade]) => tint(lightShade, 0.5), + ['colors.lightShade'] + ), + formControlPlaceholderColor: computed( + ([subduedText, lightestShade]) => + makeHighContrastColor(subduedText)(tint(lightestShade, 0.6)), + ['colors.subduedText', 'colors.lightestShade'] + ), + formControlBorder: computed( + ([lightestShade]) => shade(lightestShade, 0.4), + ['colors.lightestShade'] + ), + formAutofillBackground: computed( + ([primary]) => tint(primary, 0.8), + ['colors.primary'] + ), + formAutofillBorderColor: computed( + ([primaryText]) => transparentize(primaryText, 0.2), + ['colors.primaryText'] + ), +}; + +const button_colors: _EuiThemeButtonColors = { + buttonBackgroundPrimary: computed(([primary]) => primary, ['colors.primary']), + buttonBackgroundAccent: computed( + ([accent]) => tint(accent, 0.3), + ['colors.accent'] + ), + buttonBackgroundSuccess: computed( + ([success]) => tint(success, 0.3), + ['colors.success'] + ), + buttonBackgroundWarning: computed(([warning]) => warning, ['colors.warning']), + buttonBackgroundDanger: computed(([danger]) => danger, ['colors.danger']), + buttonBackgroundText: computed( + ([darkShade]) => darkShade, + ['colors.darkShade'] + ), + buttonBackgroundDisabled: computed( + ([lightShade]) => transparentize(lightShade, 0.15), + ['colors.lightShade'] + ), + + buttonSecondaryBackgroundPrimary: computed( + ([primary]) => tint(primary, 0.8), + ['colors.primary'] + ), + buttonSecondaryBackgroundAccent: computed( + ([accent]) => tint(accent, 0.8), + ['colors.accent'] + ), + buttonSecondaryBackgroundSuccess: computed( + ([success]) => tint(success, 0.8), + ['colors.success'] + ), + buttonSecondaryBackgroundWarning: computed( + ([warning]) => tint(warning, 0.8), + ['colors.warning'] + ), + buttonSecondaryBackgroundDanger: computed( + ([danger]) => tint(danger, 0.8), + ['colors.danger'] + ), + buttonSecondaryBackgroundText: computed( + ([lightShade]) => tint(lightShade, 0.5), + ['colors.lightShade'] + ), + buttonSecondaryBackgroundDisabled: computed( + ([lightShade]) => transparentize(lightShade, 0.15), + ['colors.lightShade'] + ), + + buttonEmptyBackgroundPrimary: computed( + ([primary]) => tint(primary, 0.9), + ['colors.primary'] + ), + buttonEmptyBackgroundAccent: computed( + ([accent]) => tint(accent, 0.9), + ['colors.accent'] + ), + buttonEmptyBackgroundSuccess: computed( + ([success]) => tint(success, 0.9), + ['colors.success'] + ), + buttonEmptyBackgroundWarning: computed( + ([warning]) => tint(warning, 0.9), + ['colors.warning'] + ), + buttonEmptyBackgroundDanger: computed( + ([danger]) => tint(danger, 0.9), + ['colors.danger'] + ), + buttonEmptyBackgroundText: computed( + ([lightShade]) => transparentize(lightShade, 0.2), + ['colors.lightShade'] + ), + buttonEmptyBackgroundDisabled: 'transparent', + + buttonColorPrimary: isColorDark(...hexToRgb(brand_colors.primary as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorAccent: isColorDark(...hexToRgb(brand_colors.accent as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorSuccess: isColorDark(...hexToRgb(brand_colors.success as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorWarning: isColorDark(...hexToRgb(brand_colors.warning as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDanger: isColorDark(...hexToRgb(brand_colors.danger as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorText: isColorDark(...hexToRgb(shade_colors.darkShade as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonSecondaryColorPrimary: computed( + ([primaryText]) => primaryText, + ['colors.primaryText'] + ), + buttonSecondaryColorAccent: computed( + ([accentText]) => accentText, + ['colors.accentText'] + ), + buttonSecondaryColorSuccess: computed( + ([successText]) => successText, + ['colors.successText'] + ), + buttonSecondaryColorWarning: computed( + ([warningText]) => warningText, + ['colors.warningText'] + ), + buttonSecondaryColorDanger: computed( + ([dangerText]) => dangerText, + ['colors.dangerText'] + ), + buttonSecondaryColorText: computed(([text]) => text, ['colors.text']), + buttonSecondaryColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonEmptyColorPrimary: computed( + ([primaryText]) => primaryText, + ['colors.primaryText'] + ), + buttonEmptyColorAccent: computed( + ([accentText]) => accentText, + ['colors.accentText'] + ), + buttonEmptyColorSuccess: computed( + ([successText]) => successText, + ['colors.successText'] + ), + buttonEmptyColorWarning: computed( + ([warningText]) => warningText, + ['colors.warningText'] + ), + buttonEmptyColorDanger: computed( + ([dangerText]) => dangerText, + ['colors.dangerText'] + ), + buttonEmptyColorText: computed(([text]) => text, ['colors.text']), + buttonEmptyColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonBorderColorPrimary: 'transparent', }; export const light_colors: _EuiThemeColorsMode = { + ...semantic_colors, ...brand_colors, ...shade_colors, ...special_colors, // Need to come after special colors so they can react to `body` ...brand_text_colors, + // experimental new tokens ...text_colors, + ...background_colors, + ...transparent_background_colors, + ...border_colors, + ...form_colors, + ...button_colors, }; /* * DARK THEME */ +export const dark_brand_colors = { + primary: '#36A2EF', + accent: '#F68FBE', + success: '#7DDED8', + warning: '#F3D371', + danger: '#F86B63', +}; + export const dark_shades: _EuiThemeShadeColors = { emptyShade: '#1D1E24', lightestShade: '#25262E', @@ -94,13 +427,282 @@ export const dark_shades: _EuiThemeShadeColors = { fullShade: '#FFF', }; +export const dark_background_colors: _EuiThemeBackgroundColors = { + backgroundPrimary: computed( + ([primary]) => shade(primary, 0.9), + ['colors.primary'] + ), + backgroundAccent: computed( + ([accent]) => shade(accent, 0.9), + ['colors.accent'] + ), + backgroundSuccess: computed( + ([success]) => shade(success, 0.9), + ['colors.success'] + ), + backgroundWarning: computed( + ([warning]) => shade(warning, 0.9), + ['colors.warning'] + ), + backgroundDanger: computed( + ([danger]) => shade(danger, 0.9), + ['colors.danger'] + ), + backgroundSubdued: special_colors.body, + backgroundPlain: shade_colors.emptyShade, + backgroundDisabled: computed( + ([disabled]) => shade(disabled, 0.9), + ['colors.disabled'] + ), +}; + +export const dark_transparent_background_colors = { + ...transparent_background_colors, + backgroundSubduedTransparent: computed( + ([lightShade]) => transparentize(lightShade, 0.4), + ['colors.lightShade'] + ), +}; + +export const dark_border_colors = { + borderPrimary: computed( + ([primary]) => shade(primary, 0.6), + ['colors.primary'] + ), + borderAccent: computed(([accent]) => shade(accent, 0.6), ['colors.accent']), + borderSuccess: computed( + ([success]) => shade(success, 0.6), + ['colors.success'] + ), + borderWarning: computed( + ([warning]) => shade(warning, 0.4), + ['colors.warning'] + ), + borderDanger: computed(([danger]) => shade(danger, 0.6), ['colors.danger']), + borderPlain: computed(([lightShade]) => lightShade, ['colors.lightShade']), + borderSubdued: computed( + ([lightShade]) => tint(lightShade, 0.3), + ['colors.lightShade'] + ), + borderDisabled: computed( + ([borderPlain]) => borderPlain, + ['colors.borderPlain'] + ), + borderHollow: computed( + ([borderPlain]) => tint(borderPlain, 0.15), + ['colors.borderPlain'] + ), +}; + +const dark_text_colors = { + text: '#DFE5EF', + title: computed(([text]) => text, ['colors.text']), + subduedText: computed(makeHighContrastColor('colors.mediumShade')), + link: computed(([primaryText]) => primaryText, ['colors.primaryText']), + + textHeading: computed(([text]) => text, ['colors.text']), + textParagraph: '#DFE5EF', + textSubdued: computed(makeHighContrastColor('colors.mediumShade')), + textPrimary: computed(makeHighContrastColor('colors.primary')), + textAccent: computed(makeHighContrastColor('colors.accent')), + textSuccess: computed(makeHighContrastColor('colors.success')), + textWarning: computed(makeHighContrastColor('colors.warning')), + textDanger: computed(makeHighContrastColor('colors.danger')), + textDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + textInverse: computed(([ghost]) => ghost, ['colors.ghost']), +}; + +const dark_form_colors = { + ...form_colors, + formBackground: computed( + ([lightestShade]) => shade(lightestShade, 0.4), + ['colors.lightestShade'] + ), + formBackgroundFocused: computed( + ([emptyShade]) => shade(emptyShade, 0.4), + ['colors.emptyShade'] + ), + formBorderColor: computed( + ([ghost]) => transparentize(ghost, 0.1), + ['colors.ghost'] + ), + formAppendBackground: computed( + ([lightShade]) => shade(lightShade, 0.15), + ['colors.lightShade'] + ), + formControlBorder: computed( + ([lightestShade]) => tint(lightestShade, 0.31), + ['colors.lightestShade'] + ), + formAutofillBackground: computed( + ([primary]) => shade(primary, 0.2), + ['colors.primary'] + ), +}; + +const dark_button_colors: _EuiThemeButtonColors = { + buttonBackgroundPrimary: computed(([primary]) => primary, ['colors.primary']), + buttonBackgroundAccent: computed(([accent]) => accent, ['colors.accent']), + buttonBackgroundSuccess: computed(([success]) => success, ['colors.success']), + buttonBackgroundWarning: computed(([warning]) => warning, ['colors.warning']), + buttonBackgroundDanger: computed(([danger]) => danger, ['colors.danger']), + buttonBackgroundText: computed(([text]) => text, ['colors.text']), + buttonBackgroundDisabled: computed( + ([lightShade]) => transparentize(lightShade, 0.15), + ['colors.lightShade'] + ), + + buttonSecondaryBackgroundPrimary: computed( + ([primary]) => shade(primary, 0.7), + ['colors.primary'] + ), + buttonSecondaryBackgroundAccent: computed( + ([accent]) => shade(accent, 0.7), + ['colors.accent'] + ), + buttonSecondaryBackgroundSuccess: computed( + ([success]) => shade(success, 0.7), + ['colors.success'] + ), + buttonSecondaryBackgroundWarning: computed( + ([warning]) => shade(warning, 0.7), + ['colors.warning'] + ), + buttonSecondaryBackgroundDanger: computed( + ([danger]) => shade(danger, 0.7), + ['colors.danger'] + ), + buttonSecondaryBackgroundText: computed( + ([lightShade]) => shade(lightShade, 0.2), + ['colors.lightShade'] + ), + buttonSecondaryBackgroundDisabled: computed( + ([lightShade]) => transparentize(lightShade, 0.15), + ['colors.lightShade'] + ), + + buttonEmptyBackgroundPrimary: computed( + ([primary]) => tint(primary, 0.9), + ['colors.primary'] + ), + buttonEmptyBackgroundAccent: computed( + ([accent]) => tint(accent, 0.9), + ['colors.accent'] + ), + buttonEmptyBackgroundSuccess: computed( + ([success]) => tint(success, 0.9), + ['colors.success'] + ), + buttonEmptyBackgroundWarning: computed( + ([warning]) => tint(warning, 0.9), + ['colors.warning'] + ), + buttonEmptyBackgroundDanger: computed( + ([danger]) => tint(danger, 0.9), + ['colors.danger'] + ), + buttonEmptyBackgroundText: computed( + ([lightShade]) => transparentize(lightShade, 0.2), + ['colors.lightShade'] + ), + buttonEmptyBackgroundDisabled: 'transparent', + + buttonColorPrimary: isColorDark( + ...hexToRgb(dark_brand_colors.primary as string) + ) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorAccent: isColorDark( + ...hexToRgb(tint(dark_brand_colors.accent as string, 0.3)) + ) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorSuccess: isColorDark( + ...hexToRgb(tint(dark_brand_colors.success as string, 0.3)) + ) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorWarning: isColorDark( + ...hexToRgb(tint(dark_brand_colors.warning as string, 0.3)) + ) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDanger: isColorDark( + ...hexToRgb(tint(dark_brand_colors.danger as string, 0.3)) + ) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorText: isColorDark(...hexToRgb(dark_text_colors.text as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonSecondaryColorPrimary: computed( + ([primaryText]) => primaryText, + ['colors.primaryText'] + ), + buttonSecondaryColorAccent: computed( + ([accentText]) => accentText, + ['colors.accentText'] + ), + buttonSecondaryColorSuccess: computed( + ([successText]) => successText, + ['colors.successText'] + ), + buttonSecondaryColorWarning: computed( + ([warningText]) => warningText, + ['colors.warningText'] + ), + buttonSecondaryColorDanger: computed( + ([dangerText]) => dangerText, + ['colors.dangerText'] + ), + buttonSecondaryColorText: computed(([text]) => text, ['colors.text']), + buttonSecondaryColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonEmptyColorPrimary: computed( + ([primaryText]) => primaryText, + ['colors.primaryText'] + ), + buttonEmptyColorAccent: computed( + ([accentText]) => accentText, + ['colors.accentText'] + ), + buttonEmptyColorSuccess: computed( + ([successText]) => successText, + ['colors.successText'] + ), + buttonEmptyColorWarning: computed( + ([warningText]) => warningText, + ['colors.warningText'] + ), + buttonEmptyColorDanger: computed( + ([dangerText]) => dangerText, + ['colors.dangerText'] + ), + buttonEmptyColorText: computed(([text]) => text, ['colors.text']), + buttonEmptyColorDisabled: computed( + ([disabledText]) => disabledText, + ['colors.disabledText'] + ), + + buttonBorderColorPrimary: 'transparent', +}; + export const dark_colors_ams: _EuiThemeColorsMode = { + ...semantic_colors, + // Brand - primary: '#36A2EF', - accent: '#F68FBE', - success: '#7DDED8', - warning: '#F3D371', - danger: '#F86B63', + ...dark_brand_colors, // Shades ...dark_shades, @@ -119,10 +721,13 @@ export const dark_colors_ams: _EuiThemeColorsMode = { ...brand_text_colors, // Text - text: '#DFE5EF', - title: computed(([text]) => text, ['colors.text']), - subduedText: computed(makeHighContrastColor('colors.mediumShade')), - link: computed(([primaryText]) => primaryText, ['colors.primaryText']), + ...dark_text_colors, + + ...dark_background_colors, + ...dark_transparent_background_colors, + ...dark_border_colors, + ...dark_form_colors, + ...dark_button_colors, }; /* diff --git a/packages/eui/src/themes/index.ts b/packages/eui/src/themes/index.ts index cec3cda26c3..5664a409003 100644 --- a/packages/eui/src/themes/index.ts +++ b/packages/eui/src/themes/index.ts @@ -7,8 +7,9 @@ */ export type { EUI_THEME } from './themes'; -export { EUI_THEMES, isDefaultTheme } from './themes'; +export { EUI_THEMES } from './themes'; -export { AMSTERDAM_NAME_KEY, EuiThemeAmsterdam } from './amsterdam/theme'; +export { EuiThemeAmsterdam } from './amsterdam/theme'; +export { EuiThemeNew } from './new_theme/theme'; export * from './amsterdam'; diff --git a/packages/eui/src/themes/new_theme/_colors_dark.scss b/packages/eui/src/themes/new_theme/_colors_dark.scss new file mode 100644 index 00000000000..460c456fb98 --- /dev/null +++ b/packages/eui/src/themes/new_theme/_colors_dark.scss @@ -0,0 +1,49 @@ +// stylelint-disable color-no-hex + +// This extra import allows any variables that are created via functions to work when loaded into JS +@import '../../global_styling/functions/index'; + +// These colors stay the same no matter the theme +$euiColorGhost: #FFF !default; +$euiColorInk: #000 !default; + +// Core +$euiColorPrimary: #599dff !default; +$euiColorAccent: #f588b3 !default; + +// Status +$euiColorSuccess: #7ed8a9 !default; +$euiColorWarning: #ddbf6a !default; +$euiColorDanger: #f66d64 !default; + +// Grays +$euiColorEmptyShade: #0f1f38 !default; +$euiColorLightestShade: #1b2d49 !default; +$euiColorLightShade: #283c5c !default; +$euiColorMediumShade: #445c83 !default; +$euiColorDarkShade: #89a0c4 !default; +$euiColorDarkestShade: #c9d4e6 !default; +$euiColorFullShade: #FFF !default; + +// Backgrounds +$euiPageBackgroundColor: #080F21 !default; +$euiColorHighlight: "#382400"#382400 !default; + +// Variations from core +$euiTextColor: #e0e6f1 !default; +$euiTitleColor: $euiTextColor !default; +$euiTextSubduedColor: #748fb8 !default; +$euiColorDisabled: #152640 !default; + +// Contrasty text variants +$euiColorPrimaryText: #599dff !default; +$euiColorSuccessText: #7ed8a9 !default; +$euiColorAccentText: #f588b3 !default; +$euiColorWarningText: #ddbf6a !default; +$euiColorDangerText: #f66d64 !default; +$euiColorDisabledText: #748fb8 !default; +$euiLinkColor: $euiColorPrimaryText !default; + +// Charts +$euiColorChartLines: $euiColorLightShade !default; +$euiColorChartBand: tint($euiColorLightestShade, 2.5%) !default; diff --git a/packages/eui/src/themes/new_theme/_colors_light.scss b/packages/eui/src/themes/new_theme/_colors_light.scss new file mode 100644 index 00000000000..da70f0f24e6 --- /dev/null +++ b/packages/eui/src/themes/new_theme/_colors_light.scss @@ -0,0 +1,49 @@ +// stylelint-disable color-no-hex + +// This extra import allows any variables that are created via functions to work when loaded into JS +@import '../../global_styling/functions/index'; + +// These colors stay the same no matter the theme +$euiColorGhost: #FFF !default; +$euiColorInk: #000 !default; + +// Core +$euiColorPrimary: #0b64dd !default; +$euiColorAccent: #f588b3 !default; + +// Status +$euiColorSuccess: #7ed8a9 !default; +$euiColorWarning: #ddbf6a !default; +$euiColorDanger: #c61e25 !default; + +// Grays +$euiColorEmptyShade: #FFF !default; +$euiColorLightestShade: #f6f9fc !default; +$euiColorLightShade: #c9d4e6 !default; +$euiColorMediumShade: #9eb1cf !default; +$euiColorDarkShade: #546d95 !default; +$euiColorDarkestShade: #283c5c !default; +$euiColorFullShade: #000 !default; + +// Backgrounds +$euiPageBackgroundColor: $euiColorLightestShade !default; +$euiColorHighlight: #fef8ea !default; + +// Every color below must be based mathematically on the set above and in a particular order. +$euiTextColor: #0f1f38 !default; +$euiTitleColor: $euiTextColor !default; +$euiTextSubduedColor: #445c83 !default; +$euiColorDisabled: #ebeff6 !default; + +// Contrasty text variants +$euiColorPrimaryText: #004fc7 !default; +$euiColorSuccessText: #00782d !default; +$euiColorAccentText: #a6005e !default; +$euiColorWarningText: #854d00 !default; +$euiColorDangerText: #af000e !default; +$euiColorDisabledText: #647ea7 !default; +$euiLinkColor: $euiColorPrimaryText !default; + +// Charts +$euiColorChartLines: shade($euiColorLightestShade, 3%) !default; +$euiColorChartBand: $euiColorLightestShade !default; diff --git a/packages/eui/src/themes/new_theme/_globals.scss b/packages/eui/src/themes/new_theme/_globals.scss new file mode 100644 index 00000000000..496a0212d28 --- /dev/null +++ b/packages/eui/src/themes/new_theme/_globals.scss @@ -0,0 +1,11 @@ +// Helper file for supplying EUI Amsterdam globals (invisibles only) +// Must be imported AFTER a colors modifier file + +// Functions need to be first, since we use them in our variables and mixin definitions +@import '../../global_styling/functions/index'; + +// Variables come next, and are used in some mixins +@import 'global_styling/variables/index'; + +// Mixins provide generic code expansion through helpers +@import 'global_styling/mixins/index'; diff --git a/packages/eui/src/themes/new_theme/global_styling/functions/index.ts b/packages/eui/src/themes/new_theme/global_styling/functions/index.ts new file mode 100644 index 00000000000..aa98697ba6d --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/functions/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export * from './shadows'; diff --git a/packages/eui/src/themes/new_theme/global_styling/functions/shadows.ts b/packages/eui/src/themes/new_theme/global_styling/functions/shadows.ts new file mode 100644 index 00000000000..00349a07209 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/functions/shadows.ts @@ -0,0 +1,26 @@ +/* + * 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 { + COLOR_MODES_STANDARD, + EuiThemeColorModeStandard, +} from '../../../../services/theme/types'; + +// 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 +export const getShadowColor = ( + color: string, + opacity: number, + colorMode: EuiThemeColorModeStandard +) => { + const themeOpacity = + colorMode === COLOR_MODES_STANDARD.dark ? opacity * 3.5 : opacity * 1; + return chroma(color).alpha(themeOpacity).css(); +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/index.scss b/packages/eui/src/themes/new_theme/global_styling/index.scss new file mode 100644 index 00000000000..2e08b76dd50 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/index.scss @@ -0,0 +1,15 @@ +// Core + +// Functions need to be first, since we use them in our variables and mixin definitions +@import '../../../global_styling/functions/index'; + +// Variables come next, and are used in some mixins +@import 'variables/index'; + +// Mixins provide generic code expansion through helpers +@import 'mixins/index'; + +// Utility classes provide one-off selectors for common css problems +@import '../../../global_styling/utility/index'; + +// The reset file has moved to global_styles.tsx diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/__snapshots__/button.test.ts.snap b/packages/eui/src/themes/new_theme/global_styling/mixins/__snapshots__/button.test.ts.snap new file mode 100644 index 00000000000..96beb3b0e63 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/__snapshots__/button.test.ts.snap @@ -0,0 +1,181 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`useEuiButtonColorCSS base 1`] = ` +{ + "accent": { + "map": undefined, + "name": "1uoldaz-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#a03465;background-color:#fcdcea;;;label:base-accent;", + "toString": [Function], + }, + "danger": { + "map": undefined, + "name": "1cquuvx-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#ab231c;background-color:#f2d4d2;;;label:base-danger;", + "toString": [Function], + }, + "disabled": { + "map": undefined, + "name": "13xo60b-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#a2abba;background-color:rgba(211,218,230,0.15);;;label:base-disabled;", + "toString": [Function], + }, + "primary": { + "map": undefined, + "name": "1thox14-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#0061a6;background-color:#cce4f5;;;label:base-primary;", + "toString": [Function], + }, + "success": { + "map": undefined, + "name": "1j0clgi-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#006c66;background-color:#ccf2f0;;;label:base-success;", + "toString": [Function], + }, + "text": { + "map": undefined, + "name": "40srs0-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#343741;background-color:#e9edf3;;;label:base-text;", + "toString": [Function], + }, + "warning": { + "map": undefined, + "name": "19dh407-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#83650a;background-color:#fff3d0;;;label:base-warning;", + "toString": [Function], + }, +} +`; + +exports[`useEuiButtonColorCSS empty 1`] = ` +{ + "accent": { + "map": undefined, + "name": "cy4kjs-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#a03465;&:focus,&:active{background-color:rgba(240,78,152,0.1);};label:empty-accent;", + "toString": [Function], + }, + "danger": { + "map": undefined, + "name": "j8xrk3-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#ab231c;&:focus,&:active{background-color:rgba(189,39,30,0.1);};label:empty-danger;", + "toString": [Function], + }, + "disabled": { + "map": undefined, + "name": "2vymtv-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#a2abba;&:focus,&:active{background-color:transparent;};label:empty-disabled;", + "toString": [Function], + }, + "primary": { + "map": undefined, + "name": "15isz8i-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#0061a6;&:focus,&:active{background-color:rgba(0,119,204,0.1);};label:empty-primary;", + "toString": [Function], + }, + "success": { + "map": undefined, + "name": "h2w3e9-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#006c66;&:focus,&:active{background-color:rgba(0,191,179,0.1);};label:empty-success;", + "toString": [Function], + }, + "text": { + "map": undefined, + "name": "1dqg6bz-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#343741;&:focus,&:active{background-color:rgba(211,218,230,0.2);};label:empty-text;", + "toString": [Function], + }, + "warning": { + "map": undefined, + "name": "w61e3r-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#83650a;&:focus,&:active{background-color:rgba(254,197,20,0.1);};label:empty-warning;", + "toString": [Function], + }, +} +`; + +exports[`useEuiButtonColorCSS fill 1`] = ` +{ + "accent": { + "map": undefined, + "name": "vi45v3-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#000;background-color:#f583b7;outline-color:#000;;label:fill-accent;", + "toString": [Function], + }, + "danger": { + "map": undefined, + "name": "1ge48z4-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#FFF;background-color:#BD271E;outline-color:#000;;label:fill-danger;", + "toString": [Function], + }, + "disabled": { + "map": undefined, + "name": "xc42v8-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#a2abba;background-color:rgba(211,218,230,0.15);outline-color:#000;;label:fill-disabled;", + "toString": [Function], + }, + "primary": { + "map": undefined, + "name": "btstjy-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#FFF;background-color:#07C;outline-color:#000;;label:fill-primary;", + "toString": [Function], + }, + "success": { + "map": undefined, + "name": "p9aexd-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#000;background-color:#4dd2ca;outline-color:#000;;label:fill-success;", + "toString": [Function], + }, + "text": { + "map": undefined, + "name": "5c80s5-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#FFF;background-color:#69707D;outline-color:#000;;label:fill-text;", + "toString": [Function], + }, + "warning": { + "map": undefined, + "name": "17xxsr5-displaysColorsMap-display-color", + "next": undefined, + "styles": "color:#000;background-color:#FEC514;outline-color:#000;;label:fill-warning;", + "toString": [Function], + }, +} +`; + +exports[`useEuiButtonFocusCSS 1`] = ` +{ + "map": undefined, + "name": "1s8jae7-focusCSS", + "next": { + "name": "animation-70pju1", + "next": undefined, + "styles": "@keyframes animation-70pju1{ + 50% { + transform: translateY(1px); + } +}", + }, + "styles": "@media screen and (prefers-reduced-motion: no-preference){transition:transform 250ms ease-in-out,background-color 250ms ease-in-out;&:hover:not(:disabled){transform:translateY(-1px);}&:focus{animation:animation-70pju1 250ms cubic-bezier(.34, 1.61, .7, 1);}&:active:not(:disabled){transform:translateY(1px);}};", + "toString": [Function], +} +`; diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/_index.scss b/packages/eui/src/themes/new_theme/global_styling/mixins/_index.scss new file mode 100644 index 00000000000..3d83a4cd823 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/_index.scss @@ -0,0 +1,17 @@ +// Import base theme first, then override +@import '../../../../global_styling/mixins/responsive'; +@import '../../../../global_styling/mixins/shadow'; +@import '../../../../global_styling/mixins/size'; +@import '../../../../global_styling/mixins/typography'; +@import 'typography'; +@import '../../../../global_styling/mixins/helpers'; +@import 'states'; +@import '../../../../global_styling/mixins/icons'; + +@import '../../../../global_styling/mixins/button'; +@import '../../../../global_styling/mixins/form'; +@import '../../../../global_styling/mixins/loading'; +@import 'link'; +@import '../../../../global_styling/mixins/panel'; +@import '../../../../global_styling/mixins/range'; +@import '../../../../global_styling/mixins/tool_tip'; diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/_link.scss b/packages/eui/src/themes/new_theme/global_styling/mixins/_link.scss new file mode 100644 index 00000000000..9d30a5346d2 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/_link.scss @@ -0,0 +1,23 @@ +@mixin euiLink { + text-align: left; + font-weight: $euiButtonFontWeight; + + &:hover { + @include euiLinkHover; + } + + &:focus { + @include euiFocusRing(null, 'outer'); + @include euiLinkFocus; + } +} + +@mixin euiLinkHover { + text-decoration: underline; +} + +@mixin euiLinkFocus { + text-decoration: underline; + // stylelint-disable-next-line declaration-no-important + text-decoration-thickness: $euiBorderWidthThick !important; +} diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/_states.scss b/packages/eui/src/themes/new_theme/global_styling/mixins/_states.scss new file mode 100644 index 00000000000..81279d81b98 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/_states.scss @@ -0,0 +1,74 @@ +// In Amsterdam, focus rings default to the browser's `outline` +// However, some components need to be forced to have the same behavior +// This re-uses the same faux focus ring mixin, but adjusts the outline instead +// @param {size} Old param from default theme that won't be used, so it should always be `null` +// @param {offset} Accepts a specific number or 'inner' or 'outer' to adjust outline position +// @param {includeFocusVisible} Allows turning off :not:focus-visible selector (which can interfere with some manual usages) +@mixin euiFocusRing($size: null, $offset: false, $focusVisibleSelectors: true) { + // Safari & Firefox + outline: $euiFocusRingSize solid currentColor; + + @if ($focusVisibleSelectors) { + // Chrome + &:focus-visible { + outline-style: auto; + } + + &:not(:focus-visible) { + outline: none; + } + } @else { + outline-style: auto; + } + + // Adjusting position with offset + @if (type-of($offset) == number) { + @if (unitless($offset)) { + outline-offset: #{$offset}px; + } @else { + outline-offset: #{$offset}; + } + } @else if ($offset == 'inner') { + outline-offset: -$euiFocusRingSize; + } @else if ($offset == 'outer') { + outline-offset: $euiFocusRingSize; + } +} + +// Amsterdam uses transparency instead of shading/tinting +@mixin euiFocusBackground($color: $euiColorPrimary) { + background-color: transparentize($color, $euiFocusTransparency); +} + +@mixin euiHoverState { + cursor: pointer; + text-decoration: underline; +} + +@mixin euiFocusState($color: $euiColorPrimary) { + @include euiHoverState; + @include euiFocusBackground($color); +} + +@mixin euiDisabledState($color: $euiButtonColorDisabledText) { + cursor: not-allowed; + text-decoration: none; + + @if ($color) { + color: $color; + } +} + +@mixin euiInteractiveStates($focusColor: $euiColorPrimary, $disabledColor: $euiButtonColorDisabledText) { + &:hover { + @include euiHoverState; + } + + &:focus { + @include euiFocusState($focusColor); + } + + &:disabled { + @include euiDisabledState($disabledColor); + } +} diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/_typography.scss b/packages/eui/src/themes/new_theme/global_styling/mixins/_typography.scss new file mode 100644 index 00000000000..e275d87bc6f --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/_typography.scss @@ -0,0 +1,82 @@ +// Font sizing extends, using rem mixin +// All line-heights are aligned to baseline grid +// stylelint-disable property-no-vendor-prefix + +@function fontSizeToRemOrEm($size, $sizingMethod: 'rem') { + @if ($sizingMethod == 'rem') { + @return #{$size / $euiFontSize}rem; + } @else if ($sizingMethod == 'em') { + @return #{$size / $euiFontSize}em; + } +} + +@function marginToRemOrEm($elementSize, $elementFontSize, $sizingMethod: 'rem') { + @if ($sizingMethod == 'rem') { + @return #{$elementSize / $euiFontSize}rem; + } @else if ($sizingMethod == 'em') { + @return #{$elementSize / $elementFontSize}em; + } +} + +// Spit out rem and px +@mixin fontSize($size: $euiFontSize, $sizingMethod: 'rem') { + @if ($sizingMethod == 'rem') { + font-size: $size; + font-size: fontSizeToRemOrEm($size, 'rem'); + } @else if ($sizingMethod == 'em') { + font-size: fontSizeToRemOrEm($size, 'em'); + } +} + +@mixin lineHeightFromBaseline($multiplier: 3) { + line-height: lineHeightFromBaseline($multiplier); +} + +// Some mixins that help us deal with browser scaling of text more consistently. +// Essentially, fonts across eui should scale against the root html element, not +// against parent inheritance. + +// Redoing this mixin mainly to remove the letter-spacing +@mixin euiFont { + font-family: $euiFontFamily; + font-weight: $euiFontWeightRegular; + letter-spacing: normal; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + font-kerning: normal; +} + +@mixin euiFontSizeXS { + @include fontSize($euiFontSizeXS); + @include lineHeightFromBaseline(2); +} + +@mixin euiFontSizeS { + @include fontSize($euiFontSizeS); + @include lineHeightFromBaseline(3); +} + +@mixin euiFontSize { + @include fontSize($euiFontSize); + @include lineHeightFromBaseline(3); +} + +@mixin euiFontSizeM { + @include fontSize($euiFontSizeM); + @include lineHeightFromBaseline(3); +} + +@mixin euiFontSizeL { + @include fontSize($euiFontSizeL); + @include lineHeightFromBaseline(4); +} + +@mixin euiFontSizeXL { + @include fontSize($euiFontSizeXL); + @include lineHeightFromBaseline(4); +} + +@mixin euiFontSizeXXL { + @include fontSize($euiFontSizeXXL); + @include lineHeightFromBaseline(5); +} diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/index.ts b/packages/eui/src/themes/new_theme/global_styling/mixins/index.ts new file mode 100644 index 00000000000..2041f2d9aca --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export * from './shadow'; diff --git a/packages/eui/src/themes/new_theme/global_styling/mixins/shadow.ts b/packages/eui/src/themes/new_theme/global_styling/mixins/shadow.ts new file mode 100644 index 00000000000..21a2360c96e --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/mixins/shadow.ts @@ -0,0 +1,190 @@ +/* + * 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 { useEuiTheme, UseEuiTheme } from '../../../../services/theme'; +import { getShadowColor } from '../functions'; +import { + _EuiThemeShadowSize, + _EuiThemeShadowCustomColor, +} from '../../../../global_styling/variables/shadow'; + +export interface EuiShadowCustomColor { + color?: string; +} + +/** + * euiSlightShadow + */ +export const euiShadowXSmall = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color }: _EuiThemeShadowCustomColor = {} +) => { + const color = _color || euiTheme.colors.shadow; + return ` +box-shadow: + 0 .8px .8px ${getShadowColor(color, 0.04, colorMode)}, + 0 2.3px 2px ${getShadowColor(color, 0.03, colorMode)}; +`; +}; + +/** + * bottomShadowSmall + */ +export const euiShadowSmall = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color }: _EuiThemeShadowCustomColor = {} +) => { + const color = _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)}; +`; +}; + +/** + * bottomShadowMedium + */ +export const euiShadowMedium = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color, property }: _EuiThemeShadowCustomColor = {} +) => { + const color = _color || euiTheme.colors.shadow; + + if (property === 'filter') { + // Using only one drop-shadow filter instead of multiple is more performant & prevents Safari bugs + return `filter: drop-shadow(0 5.7px 9px ${getShadowColor( + color, + 0.2, + 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)};`; + } +}; + +/** + * bottomShadow + */ +export const euiShadowLarge = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color }: _EuiThemeShadowCustomColor = {} +) => { + const color = _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)}; +`; +}; + +/** + * bottomShadowLarge + */ +export interface EuiShadowXLarge extends _EuiThemeShadowCustomColor { + reverse?: boolean; +} +export const euiShadowXLarge = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color, reverse }: EuiShadowXLarge = {} +) => { + const color = _color || euiTheme.colors.shadow; + 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)}; +`; +}; + +/** + * slightShadowHover + */ +export const euiSlightShadowHover = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color }: _EuiThemeShadowCustomColor = {} +) => { + const color = _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)}; +`; +}; +export const useEuiSlightShadowHover = ( + color?: _EuiThemeShadowCustomColor['color'] +) => { + const euiThemeContext = useEuiTheme(); + return euiSlightShadowHover(euiThemeContext, { color }); +}; + +/** + * bottomShadowFlat + * + * Similar to shadow medium but without the bottom depth. + * Useful for popovers that drop UP rather than DOWN. + */ +export const euiShadowFlat = ( + { euiTheme, colorMode }: UseEuiTheme, + { color: _color }: _EuiThemeShadowCustomColor = {} +) => { + const color = _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)}; +`; +}; +export const useEuiShadowFlat = ( + color?: _EuiThemeShadowCustomColor['color'] +) => { + const euiThemeContext = useEuiTheme(); + return euiShadowFlat(euiThemeContext, { color }); +}; + +export const euiShadow = ( + euiThemeContext: UseEuiTheme, + size: _EuiThemeShadowSize = 'l', + { color }: _EuiThemeShadowCustomColor = {} +) => { + switch (size) { + case 'xs': + return euiShadowXSmall(euiThemeContext, { color }); + case 's': + return euiShadowSmall(euiThemeContext, { color }); + case 'm': + return euiShadowMedium(euiThemeContext, { color }); + case 'l': + return euiShadowLarge(euiThemeContext, { color }); + case 'xl': + return euiShadowXLarge(euiThemeContext, { color }); + + default: + console.warn('Please provide a valid size option to useEuiShadow'); + return ''; + } +}; + +export const useEuiShadow = ( + size: _EuiThemeShadowSize = 'l', + color?: _EuiThemeShadowCustomColor['color'] +) => { + const euiThemeContext = useEuiTheme(); + return euiShadow(euiThemeContext, size, { color }); +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_animation.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_animation.ts new file mode 100644 index 00000000000..32b1f08479e --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_animation.ts @@ -0,0 +1,31 @@ +/* + * 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 { + _EuiThemeAnimationSpeeds, + _EuiThemeAnimationEasings, + _EuiThemeAnimation, +} from '../../../../global_styling/variables/animations'; + +export const animation_speed: _EuiThemeAnimationSpeeds = { + extraFast: '90ms', + fast: '150ms', + normal: '250ms', + slow: '350ms', + extraSlow: '500ms', +}; + +export const animation_ease: _EuiThemeAnimationEasings = { + bounce: 'cubic-bezier(.34, 1.61, .7, 1)', + resistance: 'cubic-bezier(.694, .0482, .335, 1)', +}; + +export const animation: _EuiThemeAnimation = { + ...animation_speed, + ...animation_ease, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_borders.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_borders.ts new file mode 100644 index 00000000000..6d04e95cb80 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_borders.ts @@ -0,0 +1,36 @@ +/* + * 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 { _EuiThemeBorder } from '../../../../global_styling/variables'; +import { sizeToPixel } from '../../../../global_styling/functions'; + +import { computed } from '../../../../services/theme/utils'; + +export const border: _EuiThemeBorder = { + color: computed(([lightShade]) => lightShade, ['colors.lightShade']), + width: { + thin: '1px', + thick: '2px', + }, + radius: { + medium: computed(sizeToPixel(0.375)), + small: computed(sizeToPixel(0.25)), + }, + thin: computed( + ([width, color]) => `${width.thin} solid ${color}`, + ['border.width', 'border.color'] + ), + thick: computed( + ([width, color]) => `${width.thick} solid ${color}`, + ['border.width', 'border.color'] + ), + editable: computed( + ([width, color]) => `${width.thick} dotted ${color}`, + ['border.width', 'border.color'] + ), +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_breakpoint.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_breakpoint.ts new file mode 100644 index 00000000000..97d59266d5a --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_breakpoint.ts @@ -0,0 +1,17 @@ +/* + * 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 { _EuiThemeBreakpoints } from '../../../../global_styling/variables'; + +export const breakpoint: _EuiThemeBreakpoints = { + xl: 1200, + l: 992, + m: 768, + s: 575, + xs: 0, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_buttons.scss b/packages/eui/src/themes/new_theme/global_styling/variables/_buttons.scss new file mode 100644 index 00000000000..f42b0c3264c --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_buttons.scss @@ -0,0 +1,4 @@ +$euiButtonColorDisabled: $euiColorDisabled; +$euiButtonColorDisabledText: $euiColorDisabledText; +$euiButtonDefaultTransparency: .8; +$euiButtonFontWeight: $euiFontWeightMedium; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_colors.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_colors.ts new file mode 100644 index 00000000000..d4d4f5c2a5e --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_colors.ts @@ -0,0 +1,18 @@ +/* + * 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 { _EuiThemeColors } from '../../../../global_styling/variables/colors'; +import { light_colors } from './_colors_light'; +import { dark_colors } from './_colors_dark'; + +export const colors: _EuiThemeColors = { + ghost: '#FFF', + ink: '#000', + LIGHT: light_colors, + DARK: dark_colors, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_colors_dark.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_colors_dark.ts new file mode 100644 index 00000000000..c8011abfd04 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_colors_dark.ts @@ -0,0 +1,211 @@ +/* + * 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 { + _EuiThemeBrandColors, + _EuiThemeBrandTextColors, + _EuiThemeShadeColors, + _EuiThemeSpecialColors, + _EuiThemeTextColors, + _EuiThemeColorsMode, + _EuiThemeBorderColors, + _EuiThemeTransparentBackgroundColors, + _EuiThemeBackgroundColors, + _EuiThemeButtonColors, +} from '../../../../global_styling/variables/colors'; +import { semanticColors } from '../../../../global_styling/variables/_color_matrix'; +import { hexToRgb, isColorDark } from '../../../../services'; + +/* + * LIGHT THEME + * Only split up in the light theme to access the keys by section in the docs + */ + +const semantic_colors = { + plain: '#fff', + ink: '#000', + developerBlue: '#080F21', + ...semanticColors, +}; + +const background_colors: _EuiThemeBackgroundColors = { + backgroundPrimary: semantic_colors.primary130, + backgroundAccent: semantic_colors.accent130, + backgroundSuccess: semantic_colors.success130, + backgroundWarning: semantic_colors.warning130, + backgroundDanger: semantic_colors.danger130, + backgroundSubdued: semantic_colors.shade140, + backgroundPlain: semantic_colors.plain, + backgroundDisabled: semantic_colors.shade135, +}; + +const transparent_background_colors: _EuiThemeTransparentBackgroundColors = { + backgroundPrimaryTransparent: semantic_colors.primary130, + backgroundAccentTransparent: semantic_colors.accent130, + backgroundSuccessTransparent: semantic_colors.success130, + backgroundWarningTransparent: semantic_colors.warning130, + backgroundDangerTransparent: semantic_colors.danger130, + backgroundSubduedTransparent: semantic_colors.shade130, + backgroundPlainTransparent: semantic_colors.shade130, +}; + +const border_colors: _EuiThemeBorderColors = { + borderPrimary: semantic_colors.primary100, + borderAccent: semantic_colors.primary100, + borderSuccess: semantic_colors.success100, + borderWarning: semantic_colors.warning100, + borderDanger: semantic_colors.danger100, + borderSubdued: semantic_colors.shade100, + borderPlain: semantic_colors.shade100, + borderDisabled: semantic_colors.shade100, + borderHollow: semantic_colors.shade100, +}; + +export const brand_colors: _EuiThemeBrandColors = { + primary: semantic_colors.primary60, + accent: semantic_colors.accent50, + success: semantic_colors.success40, + warning: semantic_colors.warning40, + danger: semantic_colors.danger60, +}; + +export const shade_colors: _EuiThemeShadeColors = { + emptyShade: semantic_colors.shade140, + lightestShade: semantic_colors.shade130, + lightShade: semantic_colors.shade120, + mediumShade: semantic_colors.shade100, + darkShade: semantic_colors.shade60, + darkestShade: semantic_colors.shade30, + fullShade: semantic_colors.plain, +}; + +export const text_colors: _EuiThemeTextColors = { + text: semantic_colors.shade20, + title: semantic_colors.shade20, + subduedText: semantic_colors.shade70, + link: semantic_colors.primary60, + + textHeading: semantic_colors.shade20, + textParagraph: semantic_colors.shade20, + textSubdued: semantic_colors.shade70, + textPrimary: semantic_colors.primary60, + textAccent: semantic_colors.accent50, + textSuccess: semantic_colors.success40, + textWarning: semantic_colors.warning40, + textDanger: semantic_colors.danger60, + textDisabled: semantic_colors.shade70, + textInverse: semantic_colors.plain, +}; + +export const brand_text_colors: _EuiThemeBrandTextColors = { + primaryText: text_colors.textPrimary, + accentText: text_colors.textAccent, + successText: text_colors.textSuccess, + warningText: text_colors.textWarning, + dangerText: text_colors.textDanger, +}; + +export const special_colors: _EuiThemeSpecialColors = { + body: '#080F21', + highlight: background_colors.backgroundWarning, + disabled: background_colors.backgroundDisabled, + disabledText: text_colors.textDisabled, + shadow: semantic_colors.ink, +}; + +const form_colors = { + formBackground: special_colors.body, + formBackgroundDisabled: semantic_colors.shade135, + formBackgroundFocused: special_colors.body, + formBorderColor: border_colors.borderPlain, + formAppendBackground: special_colors.body, + formControlPlaceholderColor: text_colors.textSubdued, + formControlBorder: border_colors.borderPlain, + formAutofillBackground: semantic_colors.primary130, + formAutofillBorderColor: border_colors.borderPlain, +}; + +const button_colors: _EuiThemeButtonColors = { + buttonBackgroundPrimary: brand_colors.primary, + buttonBackgroundAccent: brand_colors.accent, + buttonBackgroundSuccess: brand_colors.success, + buttonBackgroundWarning: brand_colors.warning, + buttonBackgroundDanger: brand_colors.danger, + buttonBackgroundText: shade_colors.darkestShade, + buttonBackgroundDisabled: background_colors.backgroundDisabled, + + buttonSecondaryBackgroundPrimary: semantic_colors.primary120, + buttonSecondaryBackgroundAccent: semantic_colors.accent120, + buttonSecondaryBackgroundSuccess: semantic_colors.success120, + buttonSecondaryBackgroundWarning: semantic_colors.warning120, + buttonSecondaryBackgroundDanger: semantic_colors.danger120, + buttonSecondaryBackgroundText: semantic_colors.shade120, + buttonSecondaryBackgroundDisabled: background_colors.backgroundDisabled, + + buttonEmptyBackgroundPrimary: background_colors.backgroundPrimary, + buttonEmptyBackgroundAccent: background_colors.backgroundAccent, + buttonEmptyBackgroundSuccess: background_colors.backgroundSuccess, + buttonEmptyBackgroundWarning: background_colors.backgroundWarning, + buttonEmptyBackgroundDanger: background_colors.backgroundDanger, + buttonEmptyBackgroundText: background_colors.backgroundSubdued, + buttonEmptyBackgroundDisabled: 'transparent', + + buttonColorPrimary: isColorDark(...hexToRgb(brand_colors.primary as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorAccent: isColorDark(...hexToRgb(brand_colors.accent as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorSuccess: isColorDark(...hexToRgb(brand_colors.success as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorWarning: isColorDark(...hexToRgb(brand_colors.warning as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDanger: isColorDark(...hexToRgb(brand_colors.danger as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorText: isColorDark(...hexToRgb(shade_colors.darkestShade as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDisabled: text_colors.textDisabled, + + buttonSecondaryColorPrimary: text_colors.textPrimary, + buttonSecondaryColorAccent: text_colors.textAccent, + buttonSecondaryColorSuccess: text_colors.textSuccess, + buttonSecondaryColorWarning: text_colors.textWarning, + buttonSecondaryColorDanger: text_colors.textDanger, + buttonSecondaryColorText: text_colors.textParagraph, + buttonSecondaryColorDisabled: text_colors.textDisabled, + + buttonEmptyColorPrimary: text_colors.textPrimary, + buttonEmptyColorAccent: text_colors.textAccent, + buttonEmptyColorSuccess: text_colors.textSuccess, + buttonEmptyColorWarning: text_colors.textWarning, + buttonEmptyColorDanger: text_colors.textDanger, + buttonEmptyColorText: text_colors.textParagraph, + buttonEmptyColorDisabled: text_colors.textDisabled, + + buttonBorderColorPrimary: 'transparent', +}; + +export const dark_colors: _EuiThemeColorsMode = { + ...semantic_colors, + ...brand_colors, + ...shade_colors, + ...special_colors, + // Need to come after special colors so they can react to `body` + ...brand_text_colors, + // experimental new tokens + ...text_colors, + ...background_colors, + ...transparent_background_colors, + ...border_colors, + ...form_colors, + ...button_colors, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_colors_light.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_colors_light.ts new file mode 100644 index 00000000000..707ad28c8a1 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_colors_light.ts @@ -0,0 +1,213 @@ +/* + * 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 { + _EuiThemeBrandColors, + _EuiThemeBrandTextColors, + _EuiThemeShadeColors, + _EuiThemeSpecialColors, + _EuiThemeTextColors, + _EuiThemeBackgroundColors, + _EuiThemeBorderColors, + _EuiThemeSemanticColors, + _EuiThemeColorsMode, + _EuiThemeFormColors, + _EuiThemeButtonColors, +} from '../../../../global_styling/variables/colors'; +import { semanticColors } from '../../../../global_styling/variables/_color_matrix'; +import { hexToRgb, isColorDark } from '../../../../services'; + +/* + * LIGHT THEME + * Only split up in the light theme to access the keys by section in the docs + */ + +// manual definition to ensure types? +const semantic_colors: _EuiThemeSemanticColors = { + plain: '#fff', + ink: '#000', + developerBlue: '#080F21', + ...semanticColors, +}; + +const background_colors: _EuiThemeBackgroundColors = { + backgroundPrimary: semantic_colors.primary10, + backgroundAccent: semantic_colors.accent10, + backgroundSuccess: semantic_colors.success10, + backgroundWarning: semantic_colors.warning10, + backgroundDanger: semantic_colors.danger10, + backgroundSubdued: semantic_colors.shade10, + backgroundPlain: semantic_colors.plain, + backgroundDisabled: semantic_colors.shade15, +}; + +const transparent_background_colors = { + backgroundPrimaryTransparent: semantic_colors.primary10, + backgroundAccentTransparent: semantic_colors.accent10, + backgroundSuccessTransparent: semantic_colors.success10, + backgroundWarningTransparent: semantic_colors.warning10, + backgroundDangerTransparent: semantic_colors.danger10, + backgroundSubduedTransparent: semantic_colors.shade10, + backgroundPlainTransparent: semantic_colors.shade10, +}; + +const border_colors: _EuiThemeBorderColors = { + borderPrimary: semantic_colors.primary100, + borderAccent: semantic_colors.primary100, + borderSuccess: semantic_colors.success100, + borderWarning: semantic_colors.warning100, + borderDanger: semantic_colors.danger100, + borderSubdued: semantic_colors.shade30, + borderPlain: semantic_colors.shade30, + borderDisabled: semantic_colors.shade30, + borderHollow: semantic_colors.shade30, +}; + +export const brand_colors: _EuiThemeBrandColors = { + primary: semantic_colors.primary90, + accent: semantic_colors.accent50, + success: semantic_colors.success40, + warning: semantic_colors.warning40, + danger: semantic_colors.danger90, +}; + +export const shade_colors: _EuiThemeShadeColors = { + emptyShade: semantic_colors.plain, + lightestShade: semantic_colors.shade10, + lightShade: semantic_colors.shade30, + mediumShade: semantic_colors.shade50, + darkShade: semantic_colors.shade90, + darkestShade: semantic_colors.shade120, + fullShade: semantic_colors.ink, +}; + +export const text_colors: _EuiThemeTextColors = { + text: semantic_colors.shade140, + title: semantic_colors.shade140, + subduedText: semantic_colors.shade100, + link: semantic_colors.primary100, + // new + textHeading: semantic_colors.shade140, + textParagraph: semantic_colors.shade140, + textSubdued: semantic_colors.shade100, + textPrimary: semantic_colors.primary100, + textAccent: semantic_colors.accent100, + textSuccess: semantic_colors.success100, + textWarning: semantic_colors.warning100, + textDanger: semantic_colors.danger100, + textDisabled: semantic_colors.shade80, + textInverse: semantic_colors.plain, +}; + +export const brand_text_colors: _EuiThemeBrandTextColors = { + primaryText: text_colors.textPrimary, + accentText: text_colors.textAccent, + successText: text_colors.textSuccess, + warningText: text_colors.textWarning, + dangerText: text_colors.textDanger, +}; + +export const special_colors: _EuiThemeSpecialColors = { + body: semantic_colors.shade10, + highlight: background_colors.backgroundWarning, + disabled: background_colors.backgroundDisabled, + disabledText: text_colors.textDisabled, + shadow: semantic_colors.ink, +}; + +const form_colors: _EuiThemeFormColors = { + formBackground: semantic_colors.plain, + formBackgroundDisabled: semantic_colors.shade15, + formBackgroundFocused: semantic_colors.plain, + formBorderColor: border_colors.borderPlain, + formAppendBackground: semantic_colors.plain, + formControlPlaceholderColor: text_colors.textSubdued, + formControlBorder: border_colors.borderPlain, + formAutofillBackground: semantic_colors.primary10, + formAutofillBorderColor: border_colors.borderPlain, +}; + +const button_colors: _EuiThemeButtonColors = { + buttonBackgroundPrimary: brand_colors.primary, + buttonBackgroundAccent: brand_colors.accent, + buttonBackgroundSuccess: brand_colors.success, + buttonBackgroundWarning: brand_colors.warning, + buttonBackgroundDanger: brand_colors.danger, + buttonBackgroundText: shade_colors.darkestShade, + buttonBackgroundDisabled: background_colors.backgroundDisabled, + + buttonSecondaryBackgroundPrimary: semantic_colors.primary20, + buttonSecondaryBackgroundAccent: semantic_colors.accent20, + buttonSecondaryBackgroundSuccess: semantic_colors.success20, + buttonSecondaryBackgroundWarning: semantic_colors.warning20, + buttonSecondaryBackgroundDanger: semantic_colors.danger20, + buttonSecondaryBackgroundText: semantic_colors.shade20, + buttonSecondaryBackgroundDisabled: background_colors.backgroundDisabled, + + buttonEmptyBackgroundPrimary: background_colors.backgroundPrimary, + buttonEmptyBackgroundAccent: background_colors.backgroundAccent, + buttonEmptyBackgroundSuccess: background_colors.backgroundSuccess, + buttonEmptyBackgroundWarning: background_colors.backgroundWarning, + buttonEmptyBackgroundDanger: background_colors.backgroundDanger, + buttonEmptyBackgroundText: background_colors.backgroundSubdued, + buttonEmptyBackgroundDisabled: 'transparent', + + buttonColorPrimary: isColorDark(...hexToRgb(brand_colors.primary as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorAccent: isColorDark(...hexToRgb(brand_colors.accent as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorSuccess: isColorDark(...hexToRgb(brand_colors.success as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorWarning: isColorDark(...hexToRgb(brand_colors.warning as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDanger: isColorDark(...hexToRgb(brand_colors.danger as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorText: isColorDark(...hexToRgb(shade_colors.darkShade as string)) + ? semantic_colors.plain + : semantic_colors.ink, + buttonColorDisabled: text_colors.textDisabled, + + buttonSecondaryColorPrimary: text_colors.textPrimary, + buttonSecondaryColorAccent: text_colors.textAccent, + buttonSecondaryColorSuccess: text_colors.textSuccess, + buttonSecondaryColorWarning: text_colors.textWarning, + buttonSecondaryColorDanger: text_colors.textDanger, + buttonSecondaryColorText: text_colors.textParagraph, + buttonSecondaryColorDisabled: text_colors.textDisabled, + + buttonEmptyColorPrimary: text_colors.textPrimary, + buttonEmptyColorAccent: text_colors.textAccent, + buttonEmptyColorSuccess: text_colors.textSuccess, + buttonEmptyColorWarning: text_colors.textWarning, + buttonEmptyColorDanger: text_colors.textDanger, + buttonEmptyColorText: text_colors.textParagraph, + buttonEmptyColorDisabled: text_colors.textDisabled, + + buttonBorderColorPrimary: 'transparent', +}; + +export const light_colors: _EuiThemeColorsMode = { + ...semantic_colors, + ...brand_colors, + ...shade_colors, + ...special_colors, + // Need to come after special colors so they can react to `body` + ...brand_text_colors, + // experimental new tokens + ...text_colors, + ...background_colors, + ...transparent_background_colors, + ...border_colors, + ...form_colors, + ...button_colors, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_index.scss b/packages/eui/src/themes/new_theme/global_styling/variables/_index.scss new file mode 100644 index 00000000000..eccda1f6d3b --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_index.scss @@ -0,0 +1,7 @@ +// Import base theme first, then override +@import '../../../../global_styling/variables/index'; +@import 'states'; + +@import 'buttons'; +@import 'page'; +@import 'typography'; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_levels.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_levels.ts new file mode 100644 index 00000000000..455bd877103 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_levels.ts @@ -0,0 +1,21 @@ +/* + * 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 { _EuiThemeLevels } from '../../../../global_styling/variables'; + +export const levels: _EuiThemeLevels = { + toast: 9000, + modal: 8000, + mask: 6000, + navigation: 6000, + menu: 2000, + header: 1000, + flyout: 1000, + maskBelowHeader: 1000, + content: 0, +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_page.scss b/packages/eui/src/themes/new_theme/global_styling/variables/_page.scss new file mode 100644 index 00000000000..318cae55681 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_page.scss @@ -0,0 +1 @@ +$euiPageDefaultMaxWidth: map-get($euiBreakpoints, 'xl'); diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_semantic_colors.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_semantic_colors.ts new file mode 100644 index 00000000000..267317a4c14 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_semantic_colors.ts @@ -0,0 +1,142 @@ +/* + * 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 { getColorMatrixValue } from '../../../../global_styling/variables/_color_matrix'; + +export const semantic_shade_colors = { + shade10: getColorMatrixValue('blueGrey', 10), + shade15: getColorMatrixValue('blueGrey', 15), + shade20: getColorMatrixValue('blueGrey', 20), + shade25: getColorMatrixValue('blueGrey', 25), + shade30: getColorMatrixValue('blueGrey', 30), + shade35: getColorMatrixValue('blueGrey', 35), + shade40: getColorMatrixValue('blueGrey', 40), + shade45: getColorMatrixValue('blueGrey', 45), + shade50: getColorMatrixValue('blueGrey', 50), + shade55: getColorMatrixValue('blueGrey', 55), + shade60: getColorMatrixValue('blueGrey', 60), + shade65: getColorMatrixValue('blueGrey', 65), + shade70: getColorMatrixValue('blueGrey', 70), + shade75: getColorMatrixValue('blueGrey', 75), + shade80: getColorMatrixValue('blueGrey', 80), + shade85: getColorMatrixValue('blueGrey', 85), + shade90: getColorMatrixValue('blueGrey', 90), + shade95: getColorMatrixValue('blueGrey', 95), + shade100: getColorMatrixValue('blueGrey', 100), + shade105: getColorMatrixValue('blueGrey', 105), + shade110: getColorMatrixValue('blueGrey', 110), + shade115: getColorMatrixValue('blueGrey', 115), + shade120: getColorMatrixValue('blueGrey', 120), + shade125: getColorMatrixValue('blueGrey', 125), + shade130: getColorMatrixValue('blueGrey', 130), + shade135: getColorMatrixValue('blueGrey', 135), + shade140: getColorMatrixValue('blueGrey', 140), + shade145: getColorMatrixValue('blueGrey', 145), +}; + +export const semantic_primary_colors = { + primary10: getColorMatrixValue('blue', 10), + primary20: getColorMatrixValue('blue', 20), + primary30: getColorMatrixValue('blue', 30), + primary40: getColorMatrixValue('blue', 40), + primary50: getColorMatrixValue('blue', 50), + primary60: getColorMatrixValue('blue', 60), + primary70: getColorMatrixValue('blue', 70), + primary80: getColorMatrixValue('blue', 80), + primary90: getColorMatrixValue('blue', 90), + primary100: getColorMatrixValue('blue', 100), + primary110: getColorMatrixValue('blue', 110), + primary120: getColorMatrixValue('blue', 120), + primary130: getColorMatrixValue('blue', 130), + primary140: getColorMatrixValue('blue', 140), +}; + +export const semantic_accent_colors = { + accent10: getColorMatrixValue('pink', 10), + accent20: getColorMatrixValue('pink', 20), + accent30: getColorMatrixValue('pink', 30), + accent40: getColorMatrixValue('pink', 40), + accent50: getColorMatrixValue('pink', 50), + accent60: getColorMatrixValue('pink', 60), + accent70: getColorMatrixValue('pink', 70), + accent80: getColorMatrixValue('pink', 80), + accent90: getColorMatrixValue('pink', 90), + accent100: getColorMatrixValue('pink', 100), + accent110: getColorMatrixValue('pink', 110), + accent120: getColorMatrixValue('pink', 120), + accent130: getColorMatrixValue('pink', 130), + accent140: getColorMatrixValue('pink', 140), +}; + +export const semantic_highlight_colors = { + highlight10: getColorMatrixValue('teal', 10), + highlight20: getColorMatrixValue('teal', 20), + highlight30: getColorMatrixValue('teal', 30), + highlight40: getColorMatrixValue('teal', 40), + highlight50: getColorMatrixValue('teal', 50), + highlight60: getColorMatrixValue('teal', 60), + highlight70: getColorMatrixValue('teal', 70), + highlight80: getColorMatrixValue('teal', 80), + highlight90: getColorMatrixValue('teal', 90), + highlight100: getColorMatrixValue('teal', 100), + highlight110: getColorMatrixValue('teal', 110), + highlight120: getColorMatrixValue('teal', 120), + highlight130: getColorMatrixValue('teal', 130), + highlight140: getColorMatrixValue('teal', 140), +}; + +export const semantic_success_colors = { + success10: getColorMatrixValue('green', 10), + success20: getColorMatrixValue('green', 20), + success30: getColorMatrixValue('green', 30), + success40: getColorMatrixValue('green', 40), + success50: getColorMatrixValue('green', 50), + success60: getColorMatrixValue('green', 60), + success70: getColorMatrixValue('green', 70), + success80: getColorMatrixValue('green', 80), + success90: getColorMatrixValue('green', 90), + success100: getColorMatrixValue('green', 100), + success110: getColorMatrixValue('green', 110), + success120: getColorMatrixValue('green', 120), + success130: getColorMatrixValue('green', 130), + success140: getColorMatrixValue('green', 140), +}; + +export const semantic_warning_colors = { + warning10: getColorMatrixValue('yellow', 10), + warning20: getColorMatrixValue('yellow', 20), + warning30: getColorMatrixValue('yellow', 30), + warning40: getColorMatrixValue('yellow', 40), + warning50: getColorMatrixValue('yellow', 50), + warning60: getColorMatrixValue('yellow', 60), + warning70: getColorMatrixValue('yellow', 70), + warning80: getColorMatrixValue('yellow', 80), + warning90: getColorMatrixValue('yellow', 90), + warning100: getColorMatrixValue('yellow', 100), + warning110: getColorMatrixValue('yellow', 110), + warning120: getColorMatrixValue('yellow', 120), + warning130: getColorMatrixValue('yellow', 130), + warning140: getColorMatrixValue('yellow', 140), +}; + +export const semantic_danger_colors = { + danger10: getColorMatrixValue('red', 10), + danger20: getColorMatrixValue('red', 20), + danger30: getColorMatrixValue('red', 30), + danger40: getColorMatrixValue('red', 40), + danger50: getColorMatrixValue('red', 50), + danger60: getColorMatrixValue('red', 60), + danger70: getColorMatrixValue('red', 70), + danger80: getColorMatrixValue('red', 80), + danger90: getColorMatrixValue('red', 90), + danger100: getColorMatrixValue('red', 100), + danger110: getColorMatrixValue('red', 110), + danger120: getColorMatrixValue('red', 120), + danger130: getColorMatrixValue('red', 130), + danger140: getColorMatrixValue('red', 140), +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_size.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_size.ts new file mode 100644 index 00000000000..99160540241 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_size.ts @@ -0,0 +1,30 @@ +/* + * 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 { + _EuiThemeBase, + _EuiThemeSizes, +} from '../../../../global_styling/variables'; +import { sizeToPixel } from '../../../../global_styling/functions'; + +import { computed } from '../../../../services/theme/utils'; + +export const base: _EuiThemeBase = 16; + +export const size: _EuiThemeSizes = { + xxs: computed(sizeToPixel(0.125)), + xs: computed(sizeToPixel(0.25)), + s: computed(sizeToPixel(0.5)), + m: computed(sizeToPixel(0.75)), + base: computed(sizeToPixel()), + l: computed(sizeToPixel(1.5)), + xl: computed(sizeToPixel(2)), + xxl: computed(sizeToPixel(2.5)), + xxxl: computed(sizeToPixel(3)), + xxxxl: computed(sizeToPixel(4)), +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_states.scss b/packages/eui/src/themes/new_theme/global_styling/variables/_states.scss new file mode 100644 index 00000000000..13e30784936 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_states.scss @@ -0,0 +1,11 @@ +// Color when not using currentColor +$euiFocusRingColor: $euiColorPrimaryText; + +// Sizing +$euiFocusRingAnimStartSize: 2px; +$euiFocusRingSize: 2px; + +// Transparency +$euiFocusTransparency: lightOrDarkTheme(.9, .8); +$euiFocusTransparencyPercent: lightOrDarkTheme(90%, 80%); +$euiFocusBackgroundColor: transparentize($euiColorPrimary, $euiFocusTransparency); diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_states.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_states.ts new file mode 100644 index 00000000000..6869e754a85 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_states.ts @@ -0,0 +1,23 @@ +/* + * 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 { computed } from '../../../../services/theme/utils'; +import { transparentize } from '../../../../services/color/manipulation'; +import { _EuiThemeFocus } from '../../../../global_styling/variables/states'; +import { sizeToPixel } from '../../../../global_styling/functions/size'; + +export const focus: _EuiThemeFocus = { + // Focus ring + color: 'currentColor', + width: computed(sizeToPixel(0.125)), + // Focus background + transparency: { LIGHT: 0.1, DARK: 0.2 }, + backgroundColor: computed(({ colors, focus }) => + transparentize(colors.primary, focus.transparency) + ), +}; diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_typography.scss b/packages/eui/src/themes/new_theme/global_styling/variables/_typography.scss new file mode 100644 index 00000000000..824f56b42da --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_typography.scss @@ -0,0 +1,64 @@ +// Finally start using the non-beta version of Inter +$euiFontFamily: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol' !default; + +// Font sizes -- scale is loosely based on Major Third (1.250) with a base of 14px +// Base list is an altered scale based on 16px to match the resulted values below +$euiTextScale: 2.125, 1.6875, 1.375, 1.125, 1, .875, .75 !default; + +$euiFontSize: $euiSize - 2; // 14px + +$euiFontSizeXS: floor($euiFontSize * .86); // 12px // h6 +$euiFontSizeS: floor($euiFontSize * 1); // 14px // h5 --> Now the same as the base $euiFontSize +$euiFontSizeM: ceil($euiFontSize * 1.14); // 16px // h4 +$euiFontSizeL: ceil($euiFontSize * 1.57); // 22px // h3 +$euiFontSizeXL: floor($euiFontSize * 1.93); // 27px // h2 +$euiFontSizeXXL: floor($euiFontSize * 2.43); // 34px // h1 + +$euiBodyLineHeight: 1.142857143 !default; // 16px from a 14px base font size to ensure it aligns to our 16px grid + +$euiCodeFontWeightRegular: 400; +$euiCodeFontWeightBold: 700; + +// Normally functions are imported before variables in `_index.scss` files +// But because they need to consume some typography variables they need to live here +@function convertToRem($size) { + @return #{$size / $euiFontSize}rem; +} + +// Use 8px increments for base gridline +@function lineHeightFromBaseline($multiplier: 3) { + @return convertToRem(($euiSize / 2) * $multiplier); +} + +$euiTitles: ( + 'xxxs': ( + 'font-size': $euiFontSizeXS, + 'line-height': lineHeightFromBaseline(2), + 'font-weight': $euiFontWeightBold, + ), + 'xxs': ( + 'font-size': $euiFontSizeS, + 'line-height': lineHeightFromBaseline(3), + 'font-weight': $euiFontWeightBold, + ), + 'xs': ( + 'font-size': $euiFontSizeM, + 'line-height': lineHeightFromBaseline(3), + 'font-weight': $euiFontWeightBold, + ), + 's': ( + 'font-size': $euiFontSizeL, + 'line-height': lineHeightFromBaseline(4), + 'font-weight': $euiFontWeightBold, + ), + 'm': ( + 'font-size': $euiFontSizeXL, + 'line-height': lineHeightFromBaseline(4), + 'font-weight': $euiFontWeightBold, + ), + 'l': ( + 'font-size': $euiFontSizeXXL, + 'line-height': lineHeightFromBaseline(5), + 'font-weight': $euiFontWeightBold, + ), +); diff --git a/packages/eui/src/themes/new_theme/global_styling/variables/_typography.ts b/packages/eui/src/themes/new_theme/global_styling/variables/_typography.ts new file mode 100644 index 00000000000..3a95f26a6c5 --- /dev/null +++ b/packages/eui/src/themes/new_theme/global_styling/variables/_typography.ts @@ -0,0 +1,62 @@ +/* + * 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 { computed } from '../../../../services/theme/utils'; +import { + _EuiThemeFont, + _EuiThemeFontBase, + _EuiThemeFontScales, + _EuiThemeFontWeights, +} from '../../../../global_styling/variables/typography'; + +// Typographic scale -- loosely based on Major Third (1.250) +export const fontScale: _EuiThemeFontScales = { + xxxs: 0.5625, + xxs: 0.6875, + xs: 0.75, + s: 0.875, + m: 1, + l: 1.375, + xl: 1.6875, + xxl: 2.125, +}; + +// Families & base font settings +export const fontBase: _EuiThemeFontBase = { + family: "'Inter', BlinkMacSystemFont, Helvetica, Arial, sans-serif", + familyCode: "'Roboto Mono', Menlo, Courier, monospace", + familySerif: 'Georgia, Times, Times New Roman, serif', + + // Careful using ligatures. Code editors like ACE will often error because of width calculations + featureSettings: "'calt' 1, 'kern' 1, 'liga' 1", + defaultUnits: 'rem', + + baseline: computed(([base]) => base / 4, ['base']), + lineHeightMultiplier: 1.5, +}; + +export const fontWeight: _EuiThemeFontWeights = { + light: 300, + regular: 400, + medium: 500, + semiBold: 600, + bold: 700, +}; + +export const font: _EuiThemeFont = { + ...fontBase, + scale: fontScale, + weight: fontWeight, + body: { + scale: 's', + weight: 'regular', + }, + title: { + weight: 'bold', + }, +}; diff --git a/packages/eui/src/themes/new_theme/index.ts b/packages/eui/src/themes/new_theme/index.ts new file mode 100644 index 00000000000..81ea9d264b0 --- /dev/null +++ b/packages/eui/src/themes/new_theme/index.ts @@ -0,0 +1,10 @@ +/* + * 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. + */ + +// Only globally export the mixins we allow consumers to re-use +export * from './global_styling/mixins/shadow'; diff --git a/packages/eui/src/themes/new_theme/overrides/_combo_box.scss b/packages/eui/src/themes/new_theme/overrides/_combo_box.scss new file mode 100644 index 00000000000..f1df5630b64 --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_combo_box.scss @@ -0,0 +1,50 @@ +// TODO: Address nesting during Emotion conversion, if possible +// stylelint-disable max-nesting-depth + +.euiComboBox { + // Round the left border when we append a label + &--appended { + .euiFormControlLayout__childrenWrapper { + border-top-left-radius: $euiFormControlBorderRadius; + border-bottom-left-radius: $euiFormControlBorderRadius; + } + + // Half size rounded left corners when compressed + .euiFormControlLayout--compressed { + .euiFormControlLayout__childrenWrapper { + border-top-left-radius: $euiFormControlCompressedBorderRadius; + border-bottom-left-radius: $euiFormControlCompressedBorderRadius; + } + } + + // No rounded corners when we have both appended and prepended labels. + // This includes full height and compressed height comboboxes. + &.euiComboBox--prepended { + .euiFormControlLayout__childrenWrapper { + border-radius: 0; + } + + .euiFormControlLayout--compressed { + .euiFormControlLayout__childrenWrapper { + border-radius: 0; + } + } + } + } + + // Round the right border when we prepend a label + &--prepended { + .euiFormControlLayout__childrenWrapper { + border-top-right-radius: $euiFormControlBorderRadius; + border-bottom-right-radius: $euiFormControlBorderRadius; + } + + // Half size rounded right corners when compressed + .euiFormControlLayout--compressed { + .euiFormControlLayout__childrenWrapper { + border-top-right-radius: $euiFormControlCompressedBorderRadius; + border-bottom-right-radius: $euiFormControlCompressedBorderRadius; + } + } + } +} diff --git a/packages/eui/src/themes/new_theme/overrides/_data_grid.scss b/packages/eui/src/themes/new_theme/overrides/_data_grid.scss new file mode 100644 index 00000000000..f885899ef9c --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_data_grid.scss @@ -0,0 +1,5 @@ +@include euiDataGridStyles(fontSizeLarge) { + @include euiDataGridRowCell { + @include euiFontSizeM; + } +} diff --git a/packages/eui/src/themes/new_theme/overrides/_form_control_layout.scss b/packages/eui/src/themes/new_theme/overrides/_form_control_layout.scss new file mode 100644 index 00000000000..56d8e0b05d9 --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_form_control_layout.scss @@ -0,0 +1,112 @@ +// TODO: Address nesting during Emotion conversion, if possible +// stylelint-disable max-nesting-depth + +.euiFormControlLayout--group { + border-radius: $euiFormControlBorderRadius; + background-color: $euiFormInputGroupLabelBackground; + + .euiFormControlLayout__prepend:first-child { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'left', $internal: true); + + [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'left', $internal: true); + } + } + + .euiFormControlLayout__append:last-child { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true); + + [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true); + } + } + + [class*='euiButton']:focus { + @include euiFocusRing(null, 'inner'); + } + + .euiToolTipAnchor > .euiIcon { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true); + } + + .euiToolTipAnchor:first-child [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'left', $internal: true); + } + + .euiToolTipAnchor:last-child { + [class*='euiButton'], + .euiText { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true); + } + } + + .euiFormControlLayout__childrenWrapper:nth-child(2) [class*='euiField'], + .euiFormControlLayout__childrenWrapper:nth-child(3) [class*='euiField'] { + border-radius: 0; + } + + .euiFormControlLayout__childrenWrapper:first-child .euiSelect, + .euiFormControlLayout__childrenWrapper:first-child .euiSuperSelectControl, + .euiFormControlLayout__childrenWrapper:first-child [class*='euiField'] { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'left'); + } + + .euiFormControlLayout__childrenWrapper:last-child .euiSelect, + .euiFormControlLayout__childrenWrapper:last-child .euiSuperSelectControl, + .euiFormControlLayout__childrenWrapper:last-child [class*='euiField'] { + @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right'); + } + + &.euiFormControlLayout--compressed { + border-radius: $euiFormControlCompressedBorderRadius; + background-color: $euiFormInputGroupLabelBackground; + + &.euiFormControlLayout--readOnly input { + background-color: $euiFormBackgroundReadOnlyColor; + } + + .euiFormControlLayout__prepend:first-child { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'left', $internal: true); + + [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'left'); + } + } + + .euiFormControlLayout__append:last-child { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'right', $internal: true); + + [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'right', $internal: true); + } + } + + .euiToolTipAnchor > .euiIcon { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'right', $internal: true); + } + + .euiToolTipAnchor:first-child [class*='euiButton'] { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'left', $internal: true); + } + + .euiToolTipAnchor:last-child [class*='euiButton'], + .euiToolTipAnchor:last-child .euiText { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'right', $internal: true); + } + + .euiFormControlLayout__childrenWrapper:nth-child(2) [class*='euiField'], + .euiFormControlLayout__childrenWrapper:nth-child(3) [class*='euiField'] { + border-radius: 0; + } + + .euiFormControlLayout__childrenWrapper:first-child .euiSelect, + .euiFormControlLayout__childrenWrapper:first-child [class*='euiField'] { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'left', $internal: true); + } + + .euiFormControlLayout__childrenWrapper:last-child .euiSelect, + .euiFormControlLayout__childrenWrapper:last-child [class*='euiField'] { + @include euiFormControlSideBorderRadius($euiFormControlCompressedBorderRadius, $side: 'right', $internal: true); + } + } +} diff --git a/packages/eui/src/themes/new_theme/overrides/_form_control_layout_delimited.scss b/packages/eui/src/themes/new_theme/overrides/_form_control_layout_delimited.scss new file mode 100644 index 00000000000..cbd87d08438 --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_form_control_layout_delimited.scss @@ -0,0 +1,42 @@ +// TODO: Address nesting during Emotion conversion, if possible +// stylelint-disable max-nesting-depth + +.euiFormControlLayoutDelimited { + border-radius: $euiFormControlBorderRadius; + + &.euiFormControlLayout--group { + .euiFormControlLayout__childrenWrapper:first-child { + border-radius: $euiFormControlBorderRadius 0 0 $euiFormControlBorderRadius; + } + } + + .euiFormControlLayout__childrenWrapper:only-child { + border-radius: $euiFormControlBorderRadius; + overflow: hidden; + } + + .euiFormControlLayout__prepend + .euiFormControlLayout__childrenWrapper { + &:last-child { + border-radius: 0 $euiFormControlBorderRadius $euiFormControlBorderRadius 0; + } + } + + &.euiFormControlLayout--compressed { + &.euiFormControlLayout--group { + .euiFormControlLayout__childrenWrapper:first-child { + border-radius: $euiFormControlCompressedBorderRadius 0 0 $euiFormControlCompressedBorderRadius; + } + } + + .euiFormControlLayout__childrenWrapper:only-child { + border-radius: $euiFormControlCompressedBorderRadius; + overflow: hidden; + } + + .euiFormControlLayout__prepend + .euiFormControlLayout__childrenWrapper { + &:last-child { + border-radius: 0 $euiFormControlCompressedBorderRadius $euiFormControlCompressedBorderRadius 0; + } + } + } +} diff --git a/packages/eui/src/themes/new_theme/overrides/_form_controls.scss b/packages/eui/src/themes/new_theme/overrides/_form_controls.scss new file mode 100644 index 00000000000..27780109657 --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_form_controls.scss @@ -0,0 +1,19 @@ +.euiRadio .euiRadio__input { + &:focus { + @include euiCustomControlFocused('.euiRadio__circle'); + } +} + +.euiCheckbox .euiCheckbox__input { + &:focus { + @include euiCustomControlFocused('.euiCheckbox__square'); + } +} + +.euiSwitch .euiSwitch__button:focus { + @include euiFocusRing(null, 'outer'); + + .euiSwitch__track { + outline: none; + } +} diff --git a/packages/eui/src/themes/new_theme/overrides/_index.scss b/packages/eui/src/themes/new_theme/overrides/_index.scss new file mode 100644 index 00000000000..ba2afa490fd --- /dev/null +++ b/packages/eui/src/themes/new_theme/overrides/_index.scss @@ -0,0 +1,5 @@ +@import 'combo_box'; +@import 'data_grid'; +@import 'form_control_layout'; +@import 'form_control_layout_delimited'; +@import 'form_controls'; diff --git a/packages/eui/src/themes/new_theme/theme.ts b/packages/eui/src/themes/new_theme/theme.ts new file mode 100644 index 00000000000..5ae3b60c1ab --- /dev/null +++ b/packages/eui/src/themes/new_theme/theme.ts @@ -0,0 +1,35 @@ +/* + * 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 { buildTheme } from '../../services/theme/utils'; +import { EuiThemeShape } from '../../services/theme/types'; + +import { colors } from './global_styling/variables/_colors'; +import { animation } from './global_styling/variables/_animation'; +import { breakpoint } from './global_styling/variables/_breakpoint'; +import { base, size } from './global_styling/variables/_size'; +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'; + +export const NEW_THEME_KEY = 'EUI_THEME_NEW'; + +export const euiThemeNew: EuiThemeShape = { + colors, + base, + size, + border, + font, + animation, + breakpoint, + levels, + focus, +}; + +export const EuiThemeNew = buildTheme(euiThemeNew, NEW_THEME_KEY); diff --git a/packages/eui/src/themes/new_theme/theme_dark.scss b/packages/eui/src/themes/new_theme/theme_dark.scss new file mode 100644 index 00000000000..ec8e0e97075 --- /dev/null +++ b/packages/eui/src/themes/new_theme/theme_dark.scss @@ -0,0 +1,12 @@ +// These are variable overwrites used only for this theme. +@import 'colors_dark'; + +// Global styling +@import './global_styling/index'; + +// Components +@import '../../components/index'; + +// Component overrides +// Comes after the component import and overrides via cascade +@import './overrides/index'; diff --git a/packages/eui/src/themes/new_theme/theme_light.scss b/packages/eui/src/themes/new_theme/theme_light.scss new file mode 100644 index 00000000000..27c77c31192 --- /dev/null +++ b/packages/eui/src/themes/new_theme/theme_light.scss @@ -0,0 +1,12 @@ +// This is the default theme. +@import 'colors_light'; + +// Global styling +@import './global_styling/index'; + +// Components +@import '../../components/index'; + +// Component overrides +// Comes after the component import and overrides via cascade +@import './overrides/index'; diff --git a/packages/eui/src/themes/themes.ts b/packages/eui/src/themes/themes.ts index d2f714092df..85037afc225 100644 --- a/packages/eui/src/themes/themes.ts +++ b/packages/eui/src/themes/themes.ts @@ -8,6 +8,7 @@ import { EuiThemeSystem } from '../services'; import { EuiThemeAmsterdam, AMSTERDAM_NAME_KEY } from './amsterdam/theme'; +import { EuiThemeNew } from './new_theme/theme'; export interface EUI_THEME { text: string; @@ -26,6 +27,16 @@ export const EUI_THEMES: EUI_THEME[] = [ value: 'dark', provider: EuiThemeAmsterdam, }, + { + text: 'New Theme: Light', + value: `new_light`, + provider: EuiThemeNew, + }, + { + text: 'New Theme: Dark', + value: `new_dark`, + provider: EuiThemeNew, + }, ]; export const isDefaultTheme = (name: string) => {