diff --git a/.changeset/weak-spies-help/changes.json b/.changeset/weak-spies-help/changes.json new file mode 100644 index 000000000..7fcb97c0f --- /dev/null +++ b/.changeset/weak-spies-help/changes.json @@ -0,0 +1,4 @@ +{ + "releases": [{ "name": "emotion-theming", "type": "patch" }], + "dependents": [] +} diff --git a/.changeset/weak-spies-help/changes.md b/.changeset/weak-spies-help/changes.md new file mode 100644 index 000000000..259f62789 --- /dev/null +++ b/.changeset/weak-spies-help/changes.md @@ -0,0 +1 @@ +Add useTheme React hook to emotion-theming \ No newline at end of file diff --git a/docs/theming.mdx b/docs/theming.mdx index ad8f9b70a..28c18dd5a 100644 --- a/docs/theming.mdx +++ b/docs/theming.mdx @@ -10,6 +10,33 @@ npm install -S emotion-theming Add `ThemeProvider` to the top level of your app and access the theme with `props.theme` in a styled component or provide a function that accepts the theme as the css prop. The api is laid out in detail [in the documentation](https://emotion.sh/docs/emotion-theming). +## Examples + +### css prop + +```jsx +// @live +/** @jsx jsx */ +import { jsx } from '@emotion/core' +import { ThemeProvider } from 'emotion-theming' + +const theme = { + colors: { + primary: 'hotpink' + } +} + +render( + +
({ color: theme.colors.primary })}> + some other text +
+
+) +``` + +### styled + ```jsx // @live /** @jsx jsx */ @@ -30,9 +57,38 @@ const SomeText = styled.div` render( some text -
({ color: theme.colors.primary })}> - some other text -
) ``` + +### useTheme hook + +```jsx +// @live +/** @jsx jsx */ +import { jsx } from '@emotion/core' +import { ThemeProvider, useTheme } from 'emotion-theming' + +const theme = { + colors: { + primary: 'hotpink' + } +} + +function SomeText (props) { + const theme = useTheme() + return ( +
+ ) +} + +render( + + some text + +) +``` + diff --git a/packages/emotion-theming/README.md b/packages/emotion-theming/README.md index 53dca4cba..37226d875 100644 --- a/packages/emotion-theming/README.md +++ b/packages/emotion-theming/README.md @@ -11,6 +11,7 @@ _`emotion-theming` is a theming library inspired by [styled-components](https:// - [API](#api) - [ThemeProvider](#themeprovider-reactcomponenttype) - [withTheme](#withthemecomponent-reactcomponenttype-reactcomponenttype) + - [useTheme](#usetheme) - [Credits](#credits) - [License](#license) @@ -149,6 +150,40 @@ TellMeTheColor.propTypes = { const TellMeTheColorWithTheme = withTheme(TellMeTheColor) ``` +### useTheme + +A React hook that provides the current theme as its value. If the theme is updated, the child component will be re-rendered accordingly. + +```jsx +// @live +/** @jsx jsx */ +import { jsx } from '@emotion/core' +import styled from '@emotion/styled' +import { ThemeProvider, useTheme } from 'emotion-theming' + +const theme = { + colors: { + primary: 'hotpink' + } +} + +function SomeText (props) { + const theme = useTheme() + return ( +
+ ) +} + +render( + + some text + +) +``` + ## Credits Thanks goes to the [styled-components team](https://github.com/styled-components/styled-components) and [their contributors](https://github.com/styled-components/styled-components/graphs/contributors) who designed this API. diff --git a/packages/emotion-theming/__tests__/__snapshots__/use-theme.js.snap b/packages/emotion-theming/__tests__/__snapshots__/use-theme.js.snap new file mode 100644 index 000000000..cd3ea966e --- /dev/null +++ b/packages/emotion-theming/__tests__/__snapshots__/use-theme.js.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Nested useTheme works 1`] = ` +.emotion-1 { + color: green; +} + +.emotion-1:hover { + color: darkgreen; +} + +.emotion-0 { + color: lawngreen; +} + +.emotion-0:hover { + color: seagreen; +} + +
+ Should be green +
+ Should be lawngreen +
+
+`; + +exports[`useTheme works 1`] = ` +.emotion-0 { + color: green; +} + +.emotion-0:hover { + color: darkgreen; +} + +
+ Should be green +
+`; diff --git a/packages/emotion-theming/__tests__/use-theme.js b/packages/emotion-theming/__tests__/use-theme.js new file mode 100644 index 000000000..c46c1fa9b --- /dev/null +++ b/packages/emotion-theming/__tests__/use-theme.js @@ -0,0 +1,77 @@ +// @flow +/** @jsx jsx */ +import 'test-utils/next-env' +import * as renderer from 'react-test-renderer' +import { jsx } from '@emotion/core' +import { useTheme, ThemeProvider } from 'emotion-theming' + +test('useTheme works', () => { + function TestComponent(props) { + const theme = useTheme() + return ( +
+ Should be green +
+ ) + } + + expect( + renderer + .create( + + + + ) + .toJSON() + ).toMatchSnapshot() +}) + +test('Nested useTheme works', () => { + function TestComponent1(props) { + const theme = useTheme() + return ( +
+ ) + } + + function NestedComponent(props) { + const theme = useTheme() + return ( +
+ ) + } + + function TestComponent2(props) { + return ( + + Should be green + + Should be lawngreen + + + ) + } + + expect( + renderer + .create( + + + + ) + .toJSON() + ).toMatchSnapshot() +}) diff --git a/packages/emotion-theming/src/index.js b/packages/emotion-theming/src/index.js index 8e3f83357..e4a1eddef 100644 --- a/packages/emotion-theming/src/index.js +++ b/packages/emotion-theming/src/index.js @@ -1,3 +1,4 @@ // @flow export { default as ThemeProvider } from './theme-provider' export { default as withTheme } from './with-theme' +export { default as useTheme } from './use-theme' diff --git a/packages/emotion-theming/src/use-theme.js b/packages/emotion-theming/src/use-theme.js new file mode 100644 index 000000000..11634273b --- /dev/null +++ b/packages/emotion-theming/src/use-theme.js @@ -0,0 +1,7 @@ +// @flow +import React from 'react' +import { ThemeContext } from '@emotion/core' + +export default function useTheme() { + return React.useContext(ThemeContext) +}