Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- Added `lettering` glyph to `EuiIcon` ([#5525](https://github.com/elastic/eui/pull/5525))
- Updated the outline color in `euiCustomControlFocused` mixin to use `$euiFocusRingColor` instead of `currentColor` ([#5479](https://github.com/elastic/eui/pull/5479))
- Added `betaBadgeTooltipProps` to `EuiKeyPadMenuItem` to extend the wrapping `EuiToolTip` ([#5541](https://github.com/elastic/eui/pull/5541))
- Added `globalStyles` prop to `EuiProvider` to allow for global style customization ([#5497](https://github.com/elastic/eui/pull/5497))
- Exported `EuiGlobalStyles` component ([#5497](https://github.com/elastic/eui/pull/5497))

**Bug fixes**

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@
"@elastic/charts": "^41.0.1",
"@elastic/datemath": "^5.0.3",
"@elastic/eslint-config-kibana": "^0.15.0",
"@emotion/babel-preset-css-prop": "^11.0.0",
"@emotion/cache": "^11.4.0",
"@emotion/eslint-plugin": "^11.0.0",
"@emotion/jest": "^11.1.0",
"@emotion/react": "^11.1.1",
"@emotion/babel-preset-css-prop": "^11.2.0",
"@emotion/cache": "^11.7.1",
"@emotion/eslint-plugin": "^11.7.0",
"@emotion/jest": "^11.7.1",
"@emotion/react": "^11.7.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
"@svgr/core": "5.5.0",
"@svgr/plugin-svgo": "^4.0.3",
Expand Down
66 changes: 0 additions & 66 deletions src-docs/src/views/provider/provider.md

This file was deleted.

98 changes: 94 additions & 4 deletions src-docs/src/views/provider/provider_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import React from 'react';
import { Link } from 'react-router-dom';

import {
EuiMarkdownFormat,
EuiText,
EuiProvider,
EuiCode,
EuiCodeBlock,
EuiLink,
EuiSpacer,
} from '../../../../src/components';

import { GuideSectionPropsTable } from '../../components/guide_section/guide_section_parts/guide_section_props_table';

const providerSource = require('!!raw-loader!./provider.md').default;
import Setup from './provider_setup';
import GlobalStyles from './provider_styles';

export const ProviderExample = {
title: 'Provider',
Expand All @@ -28,8 +33,93 @@ export const ProviderExample = {
),
sections: [
{
wrapText: false,
text: <EuiMarkdownFormat>{providerSource}</EuiMarkdownFormat>,
title: 'Basic setup',
text: (
<EuiText>
<p>
For EUI to work correctly, set up <strong>EuiProvider</strong> at
the root of your application.
</p>

<Setup />

<p>
See{' '}
<EuiLink href="/#/theming/theme-provider">
<strong>EuiThemeProvider</strong>
</EuiLink>{' '}
for full documentation as all relevant props will pass through. For
instance, it&apos;s likely that you will want to implement color
mode switching at this level:
</p>

<EuiCodeBlock language="tsx" fontSize="m" isCopyable>
{"<EuiProvider colorMode={isDark ? 'dark' : 'light'} />"}
</EuiCodeBlock>

<EuiSpacer size="s" />

<p>
It is not recommended to recreate the functionality of{' '}
<strong>EuiProvider</strong> by composing its constituent parts.
More context, functionality, and configurations will be added to{' '}
<strong>EuiProvider</strong> in future releases. Nested instances of{' '}
<EuiLink href="/#/theming/theme-provider">
<strong>EuiThemeProvider</strong>
</EuiLink>
, however, are valid.
</p>
</EuiText>
),
},
{
title: 'Global styles',
text: (
<EuiText>
<p>
The provider includes general reset and global styles, applied via
Emotion. These only need to be applied <strong>once</strong> so to
prevent these styles from loading in nested instances of the
provider, pass
<EuiCode>{'globalStyles={false}'}</EuiCode>.
</p>

<h3>
<EuiCode>@emotion/cache</EuiCode> and style injection location
</h3>
<p>
In the case that your app has its own static stylesheet, the global
styles may not be injected into the correct location in the{' '}
<EuiCode>{'<head>'}</EuiCode>, causing unintentional overrides or
unapplied styles.{' '}
<EuiLink href="https://emotion.sh/docs/@emotion/cache" external>
The <strong>@emotion/cache</strong> library
</EuiLink>{' '}
provides configuration options that help with specifying the
injection location. We recommend using a{' '}
<EuiCode>{'<meta>'}</EuiCode> tag to achieve this.
</p>

<GlobalStyles />

<p>
Any other options available with{' '}
<EuiLink
href="https://emotion.sh/docs/@emotion/cache#createcache"
external
>
the <strong>createCache</strong> API
</EuiLink>{' '}
will be respected by EUI.
</p>

<p>
Note that EUI does not include the <EuiCode>@emotion/cache</EuiCode>{' '}
library, so you will need to add it to your application
dependencies.
</p>
</EuiText>
),
},
{
title: 'EuiProvider props',
Expand Down
22 changes: 22 additions & 0 deletions src-docs/src/views/provider/provider_setup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

import { EuiCodeBlock, useEuiTheme, isLegacyTheme } from '../../../../src';

export default () => {
const { euiTheme, colorMode } = useEuiTheme();
const isLegacy = isLegacyTheme(euiTheme.themeName);

return (
<EuiCodeBlock language="tsx" fontSize="m" isCopyable>
{`import { EuiProvider } from '@elastic/eui';

const MyApp = () => (
<EuiProvider${isLegacy ? ' theme={null}' : ''}${
colorMode === 'DARK' ? ' colorMode="dark"' : ''
}>
{/* Content */}
</EuiProvider>
);`}
</EuiCodeBlock>
);
};
58 changes: 58 additions & 0 deletions src-docs/src/views/provider/provider_styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';

import {
EuiCodeBlock,
EuiSpacer,
useEuiTheme,
isLegacyTheme,
} from '../../../../src';

export default () => {
const { euiTheme, colorMode } = useEuiTheme();
const isLegacy = isLegacyTheme(euiTheme.themeName);

return (
<>
<EuiCodeBlock language="html" fontSize="m" isCopyable>
{!isLegacy
? `<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My App</title>
<meta name="global-style-insert">
</head>
<body>
<div id="root"></div>
</body>
</html>`
: `<!-- index.html -->
<!-- No template modifications necessary when using the Legacy theme -->`}
</EuiCodeBlock>

<EuiSpacer size="s" />

<EuiCodeBlock language="jsx" fontSize="m" isCopyable>
{`// App.js
import { EuiProvider } from '@elastic/eui'
${
!isLegacy
? `import createCache from '@emotion/cache';

const cache = createCache({
key: 'myApp',
container: document.querySelector('meta[name="global-style-insert"]'),
});
`
: ''
}
<EuiProvider${isLegacy ? ' theme={null}' : ''}${
colorMode === 'DARK' ? ' colorMode="dark"' : ''
}${!isLegacy ? ' cache={cache}' : ''}>
{/* Content */}
</EuiProvider>
`}
</EuiCodeBlock>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@ exports[`EuiProvider providing an @emotion cache config applies the cache to glo
"before": null,
"container": <head />,
"ctr": 0,
"insertionPoint": undefined,
"isSpeedy": false,
"key": "testing",
"nonce": undefined,
Expand Down
20 changes: 13 additions & 7 deletions src/components/provider/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import React, { PropsWithChildren } from 'react';
import { CacheProvider, EmotionCache } from '@emotion/react';

import {
EuiGlobalStyles,
EuiGlobalStylesProps,
} from '../../global_styling/reset/global_styles';
import { EuiGlobalStyles, EuiGlobalStylesProps } from '../../global_styling';
import {
EuiThemeProvider,
EuiThemeProviderProps,
Expand All @@ -28,24 +25,33 @@ export interface EuiProviderProps<T>
* Pass `null` to remove all theming including global reset
*/
theme?: EuiThemeSystem | null;
/**
* Provide global styles via `@emotion/react` `Global` for your custom theme.
* Pass `false` to remove the default EUI global styles.
*/
globalStyles?: false | ((params: any) => JSX.Element | null);
/**
* Provide a cache configuration from `@emotion/cache`
*/
cache?: EmotionCache;
}

export const EuiProvider = <T extends {} = {}>({
cache,
theme = EuiThemeAmsterdam,
globalStyles: GlobalStyles = EuiGlobalStyles,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the default be undefined instead? My guess is that most consumer's of multiple providers won't realize they need to remove the global styles. But likely, they'll notice they need to add it in order to fix the base styles.


Or should we be recommending two different providers. For instance this is just the theme provider, so should Kibana's multiple instances just switch to using the theme provider?

Copy link
Contributor Author

@thompsongl thompsongl Jan 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The summary might be overly concerned with multiple providers. The reasons for having default global styles but allowing for their removal are that:

  • Custom themes need to remove default global styles
  • With the exception of Kibana, apps will only have one EuiProvider instance
  • In the future, EuiProvider will likely also include i18n and other features
    • The Kibana provider that wraps EuiProvider will need access to all that data
    • That is, EuiThemeProvider isn't enough, but we need a way to prevent duplicate global styles (again, this very likely only affect Kibana)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very likely only affect Kibana

This is specifically where I worry that Kibana engineers will not know that they need to remove the global styles, making them compound or override. What is your plan to educate those engineers about this workaround?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All instances of EuiProvider (4 right now; unlikely to increase) are in mount-point components maintained by the core team. They all use the same pattern and I can leave comments in the 3 that do not need global styles explaining the difference.

colorMode,
modify,
children,
}: PropsWithChildren<EuiProviderProps<T>>) => {
return theme !== null ? (
return theme !== null && GlobalStyles !== false ? (
<EuiThemeProvider theme={theme} colorMode={colorMode} modify={modify}>
{cache ? (
<CacheProvider value={cache}>
<EuiGlobalStyles />
<GlobalStyles />
</CacheProvider>
) : (
<EuiGlobalStyles />
<GlobalStyles />
)}
{children}
</EuiThemeProvider>
Expand Down
9 changes: 9 additions & 0 deletions src/global_styling/index.ts
Original file line number Diff line number Diff line change
@@ -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 './reset/global_styles';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './components';
export * from './services';
export * from './utils';
export * from './themes';
export * from './global_styling';
Loading