-
Notifications
You must be signed in to change notification settings - Fork 841
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Emotion] Add Emotion theming support (#6913)
* [setup] Move dev provider warnings to its own file - this is necessary to prevent webpack circular dependency errors when trying to call `useEuiTheme()` from anything imported by `provider.tsx` (even though it's valid usage) * Set up Emotion ThemeProvider + types * Add unit tests * Add documentation warning against internal usage * Add consumer-facing documentation * changelog * [PR feedback] Copy Co-authored-by: Trevor Pierce <1Copenut@users.noreply.github.com> --------- Co-authored-by: Trevor Pierce <1Copenut@users.noreply.github.com>
- Loading branch information
Showing
12 changed files
with
245 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React from 'react'; | ||
import { ThemeProvider, css } from '@emotion/react'; | ||
import { EuiIcon, EuiText } from '../../../../src'; | ||
|
||
export default () => { | ||
return ( | ||
<EuiText> | ||
<p | ||
css={({ euiTheme }) => css` | ||
background-color: ${euiTheme.colors.lightestShade}; | ||
padding: ${euiTheme.size.l}; | ||
`} | ||
> | ||
<EuiIcon | ||
type="faceHappy" | ||
// The current `colorMode` is also available in the passed Emotion theme | ||
// which may be useful for certain conditional styles | ||
css={({ euiTheme, colorMode }) => ({ | ||
color: | ||
colorMode === 'LIGHT' | ||
? euiTheme.colors.primary | ||
: euiTheme.colors.accent, | ||
})} | ||
/>{' '} | ||
This box sets its icon color, background color, and padding via Emotion | ||
theme context | ||
</p> | ||
|
||
<ThemeProvider | ||
theme={{ | ||
// @ts-ignore - if providing your own Emotion theme, create your own emotion.d.ts - see https://emotion.sh/docs/typescript#define-a-theme | ||
brandColor: 'pink', | ||
backgroundColor: 'black', | ||
padding: '1rem', | ||
}} | ||
> | ||
<p | ||
css={(theme: any) => css` | ||
color: ${theme.brandColor}; | ||
background-color: ${theme.backgroundColor}; | ||
padding: ${theme.padding}; | ||
`} | ||
> | ||
This box sets its own Emotion ThemeProvider and theme variables | ||
</p> | ||
</ThemeProvider> | ||
</EuiText> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 '@emotion/react'; | ||
import { UseEuiTheme } from '../services/theme'; | ||
|
||
/** | ||
* @see https://emotion.sh/docs/typescript#define-a-theme | ||
*/ | ||
declare module '@emotion/react' { | ||
export interface Theme extends UseEuiTheme {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* 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 React from 'react'; | ||
import { ThemeProvider } from '@emotion/react'; | ||
import { render } from '../../test/rtl'; | ||
|
||
import { EuiTextColor } from '../../components/text'; | ||
import { EuiEmotionThemeProvider } from './emotion'; | ||
|
||
describe('EuiEmotionThemeProvider', () => { | ||
it("allows consumers to use Emotion's theme context by default", () => { | ||
const { container, getByTestSubject } = render( | ||
<EuiEmotionThemeProvider> | ||
<div | ||
css={({ euiTheme }) => ({ color: euiTheme.colors.primary })} | ||
data-test-subj="consumer" | ||
> | ||
hello world | ||
</div> | ||
</EuiEmotionThemeProvider> | ||
); | ||
|
||
expect(getByTestSubject('consumer')).toHaveStyleRule('color', '#07C'); | ||
|
||
expect(container.firstChild).toMatchInlineSnapshot(` | ||
<div | ||
class="css-cs4x42" | ||
data-test-subj="consumer" | ||
> | ||
hello world | ||
</div> | ||
`); | ||
}); | ||
|
||
it("allows consumers to override EUI's ThemeProvider with their own theme", () => { | ||
const customTheme = { | ||
brandColor: 'pink', | ||
}; | ||
|
||
const { container, getByTestSubject } = render( | ||
<EuiEmotionThemeProvider> | ||
{/* @ts-ignore - consumers would set their own emotion.d.ts */} | ||
<ThemeProvider theme={customTheme}> | ||
<div | ||
css={(theme: any) => ({ color: theme.brandColor })} | ||
data-test-subj="consumer" | ||
> | ||
hello | ||
</div> | ||
{/* Custom Emotion themes should not break EUI's own Emotion styles */} | ||
<EuiTextColor color="accent" data-test-subj="eui"> | ||
world | ||
</EuiTextColor> | ||
</ThemeProvider> | ||
</EuiEmotionThemeProvider> | ||
); | ||
|
||
expect(getByTestSubject('consumer')).toHaveStyleRule('color', 'pink'); | ||
expect(getByTestSubject('eui')).toHaveStyleRule('color', '#ba3d76'); | ||
|
||
expect(container).toMatchInlineSnapshot(` | ||
<div> | ||
<div | ||
class="css-18ry2co" | ||
data-test-subj="consumer" | ||
> | ||
hello | ||
</div> | ||
<span | ||
class="emotion-euiTextColor-accent" | ||
data-test-subj="eui" | ||
> | ||
world | ||
</span> | ||
</div> | ||
`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* 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 React, { FunctionComponent, PropsWithChildren } from 'react'; | ||
import { ThemeProvider } from '@emotion/react'; | ||
|
||
import { useEuiTheme } from './hooks'; | ||
|
||
/** | ||
* @see https://emotion.sh/docs/theming | ||
* This Emotion theme provider is added for *consumer usage* & convenience only. | ||
* | ||
* EUI should stick to using our own context/`useEuiTheme` internally | ||
* instead of Emotion's shorthand `css={theme => {}}` API. If consumers | ||
* set their own theme via <ThemeProvider>; EUI's styles should continue | ||
* working as-is. | ||
*/ | ||
export const EuiEmotionThemeProvider: FunctionComponent< | ||
PropsWithChildren<{}> | ||
> = ({ children }) => { | ||
const euiThemeContext = useEuiTheme(); | ||
return <ThemeProvider theme={euiThemeContext}>{children}</ThemeProvider>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
type LEVELS = 'log' | 'warn' | 'error'; | ||
|
||
let providerWarning: LEVELS | undefined = undefined; | ||
|
||
export const setEuiDevProviderWarning = (level: LEVELS | undefined) => | ||
(providerWarning = level); | ||
|
||
export const getEuiDevProviderWarning = () => providerWarning; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
- Updated `EuiThemeProvider` to set an Emotion theme context that returns the values of `useEuiTheme()` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters