Skip to content

Commit

Permalink
Move theming APIs to core
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Nov 17, 2019
1 parent 843bfb1 commit 8c62518
Show file tree
Hide file tree
Showing 46 changed files with 101 additions and 270 deletions.
3 changes: 1 addition & 2 deletions docs/theming.mdx
Expand Up @@ -17,8 +17,7 @@ Add `ThemeProvider` to the top level of your app and access the theme with `prop
```jsx
// @live
/** @jsx jsx */
import { jsx } from '@emotion/core'
import { ThemeProvider } from 'emotion-theming'
import { jsx, ThemeProvider } from '@emotion/core'

const theme = {
colors: {
Expand Down
8 changes: 4 additions & 4 deletions docs/typescript.mdx
Expand Up @@ -254,7 +254,7 @@ _styled.tsx_

```tsx
import styled, { CreateStyled } from '@emotion/styled'
import * as emotionTheming from 'emotion-theming'
import { useTheme, ThemeProvider, EmotionTheming } from '@emotion/core'

type Theme = {
color: {
Expand All @@ -268,8 +268,8 @@ type Theme = {
export default styled as CreateStyled<Theme>

// You can also create themed versions of all the other theme helpers and hooks
const { ThemeProvider, withTheme, useTheme } = emotionTheming as emotionTheming.EmotionTheming<Theme>
export { ThemeProvider, withTheme, useTheme }
const { ThemeProvider, useTheme } = { ThemeProvider, useTheme } as EmotionTheming<Theme>
export { ThemeProvider, useTheme }
```

_Button.tsx_
Expand Down Expand Up @@ -308,4 +308,4 @@ const StyledComponent0 = styled(Component)`
background: ${(props: StyledComponentProps & ComponentProps) =>
props.bgColor};
`
```
```
3 changes: 1 addition & 2 deletions packages/core/__tests__/class-names.js
@@ -1,8 +1,7 @@
// @flow
import * as React from 'react'
import 'test-utils/next-env'
import { ClassNames } from '@emotion/core'
import { ThemeProvider } from 'emotion-theming'
import { ClassNames, ThemeProvider } from '@emotion/core'
import renderer from 'react-test-renderer'

test('css', () => {
Expand Down
3 changes: 1 addition & 2 deletions packages/core/__tests__/css.js
Expand Up @@ -2,8 +2,7 @@
/** @jsx jsx */
import 'test-utils/next-env'
import * as React from 'react'
import { jsx, css, CacheProvider } from '@emotion/core'
import { ThemeProvider } from 'emotion-theming'
import { jsx, css, CacheProvider, ThemeProvider } from '@emotion/core'
import { render } from '@testing-library/react'
import renderer from 'react-test-renderer'
import createCache from '@emotion/cache'
Expand Down
3 changes: 1 addition & 2 deletions packages/core/__tests__/global-with-theme.js
@@ -1,9 +1,8 @@
// @flow
import 'test-utils/dev-mode'
import * as React from 'react'
import { ThemeProvider } from 'emotion-theming'
import { render, unmountComponentAtNode } from 'react-dom'
import { Global } from '@emotion/core'
import { Global, ThemeProvider } from '@emotion/core'

beforeEach(() => {
// $FlowFixMe
Expand Down
Expand Up @@ -4,8 +4,7 @@ import 'test-utils/next-env'
import 'test-utils/dev-mode'
import { throwIfFalsy, safeQuerySelector } from 'test-utils'
import * as React from 'react'
import { ThemeProvider } from 'emotion-theming'
import { jsx } from '@emotion/core'
import { jsx, ThemeProvider } from '@emotion/core'
import { render } from 'react-dom'

test('provider with theme value that changes', () => {
Expand Down
Expand Up @@ -2,8 +2,7 @@
/** @jsx jsx */
import 'test-utils/next-env'
import { ignoreConsoleErrors } from 'test-utils'
import { ThemeProvider } from 'emotion-theming'
import { jsx } from '@emotion/core'
import { jsx, ThemeProvider } from '@emotion/core'
import renderer from 'react-test-renderer'
import cases from 'jest-in-case'

Expand Down
Expand Up @@ -2,8 +2,7 @@
/** @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'
import { jsx, useTheme, ThemeProvider } from '@emotion/core'

test('useTheme works', () => {
function TestComponent(props) {
Expand Down
@@ -1,7 +1,7 @@
// @flow
import * as React from 'react'
import * as renderer from 'react-test-renderer'
import { withTheme, ThemeProvider } from 'emotion-theming'
import { withTheme, ThemeProvider } from '@emotion/core'

test('withTheme works', () => {
class SomeComponent extends React.Component<{ theme: Object }> {
Expand Down
4 changes: 3 additions & 1 deletion packages/core/package.json
Expand Up @@ -27,7 +27,9 @@
"@emotion/css": "^11.0.0-next.3",
"@emotion/serialize": "^0.11.15-next.1",
"@emotion/sheet": "0.9.3",
"@emotion/utils": "0.11.2"
"@emotion/utils": "0.11.2",
"@emotion/weak-memoize": "0.2.4",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
"@babel/core": "^7.0.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/class-names.js
@@ -1,9 +1,9 @@
// @flow
import * as React from 'react'
import { useContext } from 'react'
import { getRegisteredStyles, insertStyles } from '@emotion/utils'
import { serializeStyles } from '@emotion/serialize'
import { withEmotionCache, ThemeContext } from './context'
import { withEmotionCache } from './context'
import { ThemeContext } from './theming'
import { isBrowser } from './utils'

type ClassNameArg =
Expand Down Expand Up @@ -112,7 +112,7 @@ export const ClassNames: React.AbstractComponent<
let content = {
css,
cx,
theme: useContext(ThemeContext)
theme: React.useContext(ThemeContext)
}
let ele = props.children(content)
hasRendered = true
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/context.js
Expand Up @@ -15,7 +15,6 @@ let EmotionCacheContext: React.Context<EmotionCache | null> = React.createContex
typeof HTMLElement !== 'undefined' ? createCache() : null
)

export let ThemeContext = React.createContext<Object>({})
export let CacheProvider = EmotionCacheContext.Provider

let withEmotionCache = function withEmotionCache<Props, Ref: React.Ref<*>>(
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/global.js
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import { withEmotionCache, ThemeContext } from './context'
import { withEmotionCache } from './context'
import { ThemeContext } from './theming'
import { insertStyles } from '@emotion/utils'
import { isBrowser } from './utils'

Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.js
@@ -1,7 +1,9 @@
// @flow
export { withEmotionCache, CacheProvider, ThemeContext } from './context'
export { withEmotionCache, CacheProvider } from './context'
export { jsx } from './jsx'
export { Global } from './global'
export { keyframes } from './keyframes'
export { ClassNames } from './class-names'
// TODO: should we export ThemeContext?
export { useTheme, ThemeProvider, withTheme } from './theming'
export { default as css } from './css'
3 changes: 2 additions & 1 deletion packages/core/src/jsx.js
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import { withEmotionCache, ThemeContext } from './context'
import { withEmotionCache } from './context'
import { ThemeContext } from './theming'
import { getRegisteredStyles, insertStyles } from '@emotion/utils'
import { isBrowser } from './utils'
import { serializeStyles } from '@emotion/serialize'
Expand Down
@@ -1,9 +1,13 @@
// @flow
import * as React from 'react'
import { ThemeContext } from '@emotion/core'
import weakMemoize from '@emotion/weak-memoize'
import hoistNonReactStatics from 'hoist-non-react-statics'

let getTheme = (outerTheme: Object, theme: Object | (Object => Object)) => {
export const ThemeContext = React.createContext<Object>({})

export const useTheme = () => React.useContext(ThemeContext)

const getTheme = (outerTheme: Object, theme: Object | (Object => Object)) => {
if (typeof theme === 'function') {
const mergedTheme = theme(outerTheme)
if (
Expand Down Expand Up @@ -36,12 +40,12 @@ let createCacheWithTheme = weakMemoize(outerTheme => {
})
})

type Props = {
type ThemeProviderProps = {
theme: Object | (Object => Object),
children: React.Node
}

let ThemeProvider = (props: Props) => {
export const ThemeProvider = (props: ThemeProviderProps) => {
let theme = React.useContext(ThemeContext)

if (props.theme !== theme) {
Expand All @@ -54,4 +58,19 @@ let ThemeProvider = (props: Props) => {
)
}

export default ThemeProvider
export function withTheme<Config: {}>(
Component: React.AbstractComponent<Config>
): React.AbstractComponent<$Diff<Config, { theme: Object }>> {
const componentName = Component.displayName || Component.name || 'Component'
let render = (props, ref) => {
let theme = React.useContext(ThemeContext)

return <Component theme={theme} ref={ref} {...props} />
}
// $FlowFixMe
let WithTheme = React.forwardRef(render)

WithTheme.displayName = `WithTheme(${componentName})`

return hoistNonReactStatics(WithTheme, Component)
}
File renamed without changes.
3 changes: 3 additions & 0 deletions packages/core/types/index.d.ts
Expand Up @@ -36,6 +36,9 @@ export {
SerializedStyles
}

export * from './theming'
export * from './helper'

export const ThemeContext: Context<object>
export const CacheProvider: Provider<EmotionCache>
export function withEmotionCache<Props, RefType = any>(
Expand Down
@@ -1,10 +1,14 @@
import * as emotionTheming from 'emotion-theming'
import * as React from 'react'
import {
useTheme,
ThemeProvider,
withTheme,
EmotionTheming,
WithTheme
} from '@emotion/core'
import styled, { CreateStyled } from '@emotion/styled'
import { Interpolation, ObjectInterpolation } from '@emotion/styled/base'

const { ThemeProvider, withTheme, useTheme } = emotionTheming

interface Theme {
primary: string
secondary: string
Expand Down Expand Up @@ -53,10 +57,10 @@ const ThemedCompWithDefault = withTheme(CompCWithDefault)
;<ThemedCompWithDefault />
;<ThemedCompWithDefault theme={theme} />

const {
ThemeProvider: TypedThemeProvider,
withTheme: typedWithTheme
} = emotionTheming as emotionTheming.EmotionTheming<Theme>
const { ThemeProvider: TypedThemeProvider, withTheme: typedWithTheme } = {
ThemeProvider,
withTheme
} as EmotionTheming<Theme>
;<TypedThemeProvider theme={theme} />
// $ExpectError
;<TypedThemeProvider theme={{ primary: 5 }} />
Expand All @@ -67,6 +71,7 @@ typedWithTheme(CompFC)
* @todo
* Following line should report an error.
*/

typedWithTheme((props: { value: number }) => null)

{
Expand Down Expand Up @@ -118,11 +123,9 @@ const StyledDiv2 = themedStyled.div({})
// $ExpectError
;<StyledDiv2 theme={{ primary: 0, secondary: 0 }} />

export type StyleDefinition<T = {}> = Interpolation<
emotionTheming.WithTheme<T, Theme>
>
export type StyleDefinition<T = {}> = Interpolation<WithTheme<T, Theme>>
export type ObjectStyleDefinition<T = {}> = ObjectInterpolation<
emotionTheming.WithTheme<T, Theme>
WithTheme<T, Theme>
>

const style: StyleDefinition = ({ theme }) => ({
Expand Down
Expand Up @@ -2,15 +2,7 @@
// TypeScript Version: 3.1

import * as React from 'react'

import {
StyledComponent,
StyledOptions,
CreateStyledComponent,
StyledTags,
PropsOf,
DistributiveOmit
} from '@emotion/styled'
import { DistributiveOmit, PropsOf } from './helper'

export interface ThemeProviderProps<Theme> {
theme: Partial<Theme> | ((outerTheme: Theme) => Theme)
Expand All @@ -21,24 +13,24 @@ export interface ThemeProvider<Theme extends {} = any> {
(props: ThemeProviderProps<Theme>): React.ReactElement
}

export type useTheme<Theme extends {} = any> = <T extends Theme = Theme>() => T

export type withTheme<Theme extends {} = any> = <
C extends React.ComponentType<React.ComponentProps<C>>
>(
component: C
) => React.FC<DistributiveOmit<PropsOf<C>, 'theme'> & { theme?: Theme }>

export type useTheme<Theme extends {} = any> = <T extends Theme = Theme>() => T

export const ThemeProvider: ThemeProvider

export const withTheme: withTheme

export const useTheme: useTheme

export const withTheme: withTheme

export interface EmotionTheming<Theme> {
ThemeProvider: ThemeProvider<Theme>
withTheme: withTheme<Theme>
useTheme: useTheme<Theme>
withTheme: withTheme<Theme>
}

export type WithTheme<P, T> = P extends { theme: infer Theme }
Expand Down
9 changes: 1 addition & 8 deletions packages/css/package.json
Expand Up @@ -3,8 +3,6 @@
"version": "11.0.0-next.3",
"description": "a function to serialize css and object styless",
"main": "dist/css.cjs.js",
"module": "dist/css.esm.js",
"types": "types/index.d.ts",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/master/packages/css",
"scripts": {
Expand All @@ -14,11 +12,6 @@
"access": "public"
},
"files": [
"src",
"dist"
],
"browser": {
"./dist/css.cjs.js": "./dist/css.browser.cjs.js",
"./dist/css.esm.js": "./dist/css.browser.esm.js"
}
]
}
13 changes: 0 additions & 13 deletions packages/emotion-theming/__tests__/__snapshots__/index.js.snap

This file was deleted.

This file was deleted.

0 comments on commit 8c62518

Please sign in to comment.