From ca9b4d0f352621115ed3d3f7c843bc661f658d0d Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:37:29 -0700 Subject: [PATCH] [Emotion] Order EUI's CSS utilities after Sass styles (#162365) ## Summary Follow up to https://github.com/elastic/kibana/pull/161592 Some remaining EUI components that are still in Sass unfortunately need to respect EUI's global CSS utilities (e.g. `.eui-yScroll`, `.eui-textTruncate` - [full list here](https://elastic.github.io/eui/#/utilities/css-utility-classes)). Creating a separate utilities cache and insertion point should solve the CSS order/specificity issues. ### Checklist - [x] Confirm Emotion output order is expected in head (EUI globals, All Emotion styles, Sass styles, then utilities last) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/core/base/core-base-common/index.ts | 2 +- packages/core/base/core-base-common/src/eui.ts | 1 + .../src/views/template.tsx | 4 +++- .../src/core_theme_provider.tsx | 14 ++++++++++---- packages/kbn-storybook/src/lib/decorators.tsx | 18 ++++++++++++++---- packages/kbn-storybook/tsconfig.json | 1 + .../public/theme/kibana_theme_provider.tsx | 15 +++++++++++---- src/plugins/interactive_setup/tsconfig.json | 1 + .../public/theme/kibana_theme_provider.tsx | 15 +++++++++++---- src/plugins/kibana_react/tsconfig.json | 1 + .../public/theme/kibana_theme_provider.tsx | 15 +++++++++++---- src/plugins/kibana_utils/tsconfig.json | 1 + 12 files changed, 66 insertions(+), 22 deletions(-) diff --git a/packages/core/base/core-base-common/index.ts b/packages/core/base/core-base-common/index.ts index d2f7daafb3341..7a89b3990d888 100644 --- a/packages/core/base/core-base-common/index.ts +++ b/packages/core/base/core-base-common/index.ts @@ -8,4 +8,4 @@ export type { PluginOpaqueId, PluginName, DiscoveredPlugin } from './src/plugins'; export { PluginType } from './src/plugins'; -export { EUI_STYLES_GLOBAL } from './src/eui'; +export { EUI_STYLES_GLOBAL, EUI_STYLES_UTILS } from './src/eui'; diff --git a/packages/core/base/core-base-common/src/eui.ts b/packages/core/base/core-base-common/src/eui.ts index 8f8ec8585dc1d..dc3740ad82a1a 100644 --- a/packages/core/base/core-base-common/src/eui.ts +++ b/packages/core/base/core-base-common/src/eui.ts @@ -7,3 +7,4 @@ */ export const EUI_STYLES_GLOBAL = 'eui-global'; +export const EUI_STYLES_UTILS = 'eui-utilities'; diff --git a/packages/core/rendering/core-rendering-server-internal/src/views/template.tsx b/packages/core/rendering/core-rendering-server-internal/src/views/template.tsx index bac48c88e1b23..569c8968a6c3a 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/views/template.tsx +++ b/packages/core/rendering/core-rendering-server-internal/src/views/template.tsx @@ -8,7 +8,7 @@ import React, { FunctionComponent, createElement } from 'react'; -import { EUI_STYLES_GLOBAL } from '@kbn/core-base-common'; +import { EUI_STYLES_GLOBAL, EUI_STYLES_UTILS } from '@kbn/core-base-common'; import { RenderingMetadata } from '../types'; import { Fonts } from './fonts'; import { Styles } from './styles'; @@ -59,6 +59,8 @@ export const Template: FunctionComponent = ({ {/* Inject stylesheets into the before scripts so that KP plugins with bundled styles will override them */} + {/* Inject EUI CSS utilties after all other styles for CSS specificity */} + {createElement('kbn-csp', { diff --git a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx index 1b39d6125e0d1..a0b0d903d999e 100644 --- a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx +++ b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx @@ -11,7 +11,7 @@ import { Observable } from 'rxjs'; import useObservable from 'react-use/lib/useObservable'; import createCache from '@emotion/cache'; import { EuiProvider } from '@elastic/eui'; -import { EUI_STYLES_GLOBAL } from '@kbn/core-base-common'; +import { EUI_STYLES_GLOBAL, EUI_STYLES_UTILS } from '@kbn/core-base-common'; import type { CoreTheme } from '@kbn/core-theme-browser'; import { convertCoreTheme } from './convert_core_theme'; @@ -25,12 +25,18 @@ interface CoreThemeProviderProps { } const globalCache = createCache({ - key: 'eui', + key: EUI_STYLES_GLOBAL, container: document.querySelector(`meta[name="${EUI_STYLES_GLOBAL}"]`) as HTMLElement, }); +globalCache.compat = true; +const utilitiesCache = createCache({ + key: EUI_STYLES_UTILS, + container: document.querySelector(`meta[name="${EUI_STYLES_UTILS}"]`) as HTMLElement, +}); +utilitiesCache.compat = true; const emotionCache = createCache({ key: 'css', - container: document.querySelector(`meta[name="emotion"]`) as HTMLElement, + container: document.querySelector('meta[name="emotion"]') as HTMLElement, }); emotionCache.compat = true; @@ -52,7 +58,7 @@ export const CoreThemeProvider: FC = ({ utilityClasses={includeGlobalStyles} colorMode={euiTheme.colorMode} theme={euiTheme.euiThemeSystem} - cache={{ default: emotionCache, global: globalCache }} + cache={{ default: emotionCache, global: globalCache, utility: utilitiesCache }} > {children} diff --git a/packages/kbn-storybook/src/lib/decorators.tsx b/packages/kbn-storybook/src/lib/decorators.tsx index 39bfcf6c75e31..80aa6304e2669 100644 --- a/packages/kbn-storybook/src/lib/decorators.tsx +++ b/packages/kbn-storybook/src/lib/decorators.tsx @@ -7,6 +7,7 @@ */ import React from 'react'; +import { EUI_STYLES_GLOBAL, EUI_STYLES_UTILS } from '@kbn/core-base-common'; import { EuiProvider } from '@elastic/eui'; import createCache from '@emotion/cache'; import type { DecoratorFn } from '@storybook/react'; @@ -20,17 +21,26 @@ import 'core_styles'; const EuiProviderDecorator: DecoratorFn = (storyFn, { globals }) => { const colorMode = globals.euiTheme === 'v8.dark' ? 'dark' : 'light'; const globalCache = createCache({ - key: 'eui', - container: document.querySelector(`meta[name="eui-global"]`) as HTMLElement, + key: EUI_STYLES_GLOBAL, + container: document.querySelector(`meta[name="${EUI_STYLES_GLOBAL}"]`) as HTMLElement, }); + globalCache.compat = true; + const utilitiesCache = createCache({ + key: EUI_STYLES_UTILS, + container: document.querySelector(`meta[name="${EUI_STYLES_UTILS}"]`) as HTMLElement, + }); + utilitiesCache.compat = true; const emotionCache = createCache({ key: 'css', - container: document.querySelector(`meta[name="emotion"]`) as HTMLElement, + container: document.querySelector('meta[name="emotion"]') as HTMLElement, }); emotionCache.compat = true; return ( - + {storyFn()} ); diff --git a/packages/kbn-storybook/tsconfig.json b/packages/kbn-storybook/tsconfig.json index 765dd18aee082..922f21f90d08c 100644 --- a/packages/kbn-storybook/tsconfig.json +++ b/packages/kbn-storybook/tsconfig.json @@ -16,6 +16,7 @@ "@kbn/ui-shared-deps-src", "@kbn/repo-info", "@kbn/dev-cli-runner", + "@kbn/core-base-common", ], "exclude": [ "target/**/*", diff --git a/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx b/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx index 29d2bd893a87d..e5390fc9393ef 100644 --- a/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx +++ b/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx @@ -14,6 +14,7 @@ import React, { useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; import type { Observable } from 'rxjs'; +import { EUI_STYLES_GLOBAL, EUI_STYLES_UTILS } from '@kbn/core-base-common'; import type { CoreTheme } from '@kbn/core/public'; import { getColorMode } from './utils'; @@ -28,12 +29,18 @@ const defaultTheme: CoreTheme = { }; const globalCache = createCache({ - key: 'eui', - container: document.querySelector(`meta[name="eui-styles"]`) as HTMLElement, + key: EUI_STYLES_GLOBAL, + container: document.querySelector(`meta[name="${EUI_STYLES_GLOBAL}"]`) as HTMLElement, }); +globalCache.compat = true; +const utilitiesCache = createCache({ + key: EUI_STYLES_UTILS, + container: document.querySelector(`meta[name="${EUI_STYLES_UTILS}"]`) as HTMLElement, +}); +utilitiesCache.compat = true; const emotionCache = createCache({ key: 'css', - container: document.querySelector(`meta[name="emotion"]`) as HTMLElement, + container: document.querySelector('meta[name="emotion"]') as HTMLElement, }); emotionCache.compat = true; @@ -46,7 +53,7 @@ export const KibanaThemeProvider: FC = ({ theme$, modi return ( = ({ theme$, modi return ( = ({ theme$, modi return (