Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert @theme-ui/theme-provider to TypeScript #708

Merged
merged 7 commits into from
May 11, 2020
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Make ThemeProvider `theme` prop required
- Removes overriding property on editor combobox
- Adjust media query sort logic #600
- Fixed link to Gatsby Plugin page in `getting-started` page. Issue #602
Expand Down
2 changes: 1 addition & 1 deletion examples/codesandbox-starter/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { jsx, Layout, Styled } from 'theme-ui'

function App() {
return (
<ThemeProvider>
<ThemeProvider theme={{}}>
<Layout sx={{ p: 3 }}>
<Reset />
<Styled.h1 sx={{ color: 'primary', mb: 3 }}>Hello Theme UI</Styled.h1>
Expand Down
12 changes: 6 additions & 6 deletions packages/color-modes/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test('useColorMode updates color mode state', () => {
)
}
const tree = render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Button />
</ColorModeProvider>
Expand Down Expand Up @@ -182,7 +182,7 @@ test('uses default mode', () => {
return <button children="test" />
}
const tree = render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Button />
</ColorModeProvider>
Expand All @@ -200,7 +200,7 @@ test('initializes mode based on localStorage', () => {
return <button children="test" />
}
const tree = render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Button />
</ColorModeProvider>
Expand Down Expand Up @@ -237,7 +237,7 @@ test('retains initial context', () => {
return false
}
render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Consumer />
</ColorModeProvider>
Expand Down Expand Up @@ -340,7 +340,7 @@ test('does not initialize mode from prefers-color-scheme media query when useCol
return false
}
render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Consumer />
</ColorModeProvider>
Expand Down Expand Up @@ -606,7 +606,7 @@ test('warns when localStorage is disabled', () => {
}

render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<ColorModeProvider>
<Consumer />
</ColorModeProvider>
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ export const jsx: typeof React.createElement = (type, props, ...children) =>

export interface ContextValue {
__EMOTION_VERSION__: string
theme: Theme | null
theme: Theme
colorMode?: string
setColorMode?: () => void
}
export const Context = React.createContext<ContextValue>({
__EMOTION_VERSION__,
theme: null,
theme: {},
})

export const useThemeUI = () => React.useContext(Context)
Expand Down Expand Up @@ -76,7 +78,7 @@ interface BaseProviderProps {
const BaseProvider: React.FC<BaseProviderProps> = ({ context, children }) =>
jsx(
EmotionContext.Provider,
{ value: context.theme! },
{ value: context.theme },
jsx(Context.Provider, {
value: context,
children,
Expand All @@ -103,7 +105,7 @@ export function ThemeProvider({ theme, children }: ThemeProviderProps) {

const context =
typeof theme === 'function'
? { ...outer, theme: theme(outer.theme!) }
? { ...outer, theme: theme(outer.theme) }
: merge.all<ContextValue>({}, outer, { theme })

return jsx(BaseProvider, { context }, children)
Expand Down
42 changes: 19 additions & 23 deletions packages/core/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import renderer from 'react-test-renderer'
import { render, fireEvent, cleanup, act } from '@testing-library/react'
import { matchers } from 'jest-emotion'
import mockConsole from 'jest-mock-console'
import {
jsx,
Context,
useThemeUI,
merge,
ThemeProvider,
} from '../src'
import { jsx, Context, useThemeUI, merge, ThemeProvider } from '../src'

afterEach(cleanup)

Expand All @@ -21,7 +15,7 @@ const renderJSON = el => renderer.create(el).toJSON()
describe('ThemeProvider', () => {
test('renders', () => {
const json = renderJSON(
<ThemeProvider>
<ThemeProvider theme={{}}>
<h1>Hello</h1>
</ThemeProvider>
)
Expand All @@ -35,7 +29,7 @@ describe('ThemeProvider', () => {
value={{
emotionVersion: '9.0.0',
}}>
<ThemeProvider>Conflicting versions</ThemeProvider>
<ThemeProvider theme={{}}>Conflicting versions</ThemeProvider>
</Context.Provider>
)
expect(console.warn).toBeCalled()
Expand Down Expand Up @@ -104,20 +98,21 @@ describe('ThemeProvider', () => {
cards: {
default: {
border: t => `1px solid ${t.colors.primary}`,
}
}
},
},
}
const json = renderJSON(
jsx(ThemeProvider, { theme },
jsx(
ThemeProvider,
{ theme },
jsx('div', {
sx: {
variant: 'cards.default',
}
},
})
)
)
expect(json).toHaveStyleRule('border', '1px solid tomato')

})
})

Expand Down Expand Up @@ -151,13 +146,15 @@ describe('jsx', () => {

test('css prop accepts functions', () => {
const json = renderJSON(
jsx(ThemeProvider, {
theme: {
colors: {
primary: 'tomato',
}
}
},
jsx(
ThemeProvider,
{
theme: {
colors: {
primary: 'tomato',
},
},
},
jsx('div', {
css: t => ({
color: t.colors.primary,
Expand Down Expand Up @@ -338,7 +335,7 @@ describe('useThemeUI', () => {
theme={{
colors: {
text: 'tomato',
}
},
}}>
<GetContext />
</ThemeProvider>
Expand All @@ -347,4 +344,3 @@ describe('useThemeUI', () => {
expect(context.theme.colors.text).toBe('tomato')
})
})

4 changes: 2 additions & 2 deletions packages/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"prepare": "microbundle --no-compress",
"watch": "microbundle watch --no-compress"
"prepare": "microbundle --no-compress --tsconfig tsconfig.json",
"watch": "microbundle watch --no-compress --tsconfig tsconfig.json"
},
"author": "Brent Jackson",
"license": "MIT",
Expand Down
6 changes: 2 additions & 4 deletions packages/css/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import * as CSS from 'csstype'

import { SystemStyleObject, UseThemeFunction, Theme } from './types'
import { CSSObject, SystemStyleObject, UseThemeFunction, Theme } from './types'

export * from './types'

Expand Down Expand Up @@ -256,7 +254,7 @@ type CssPropsArgument = { theme: Theme } | Theme

export const css = (args: SystemStyleObject = {}) => (
props: CssPropsArgument = {}
): CSS.Properties => {
): CSSObject => {
const theme: Theme = {
...defaultTheme,
...('theme' in props ? props.theme : props),
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/pages/guides/mdx-layout-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ As an example, create a new component with the `ThemeProvider` and a wrapping `<
import { jsx, ThemeProvider } from 'theme-ui'

export default props => (
<ThemeProvider>
<ThemeProvider theme={{}}>
<div {...props} />
</ThemeProvider>
)
Expand Down
6 changes: 4 additions & 2 deletions packages/theme-provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"version": "0.4.0-alpha.1",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"source": "src/index.ts",
"types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"prepare": "microbundle --no-compress",
"watch": "microbundle watch --no-compress"
"prepare": "microbundle --no-compress --tsconfig tsconfig.json",
"watch": "microbundle watch --no-compress --tsconfig tsconfig.json"
},
"dependencies": {
"@emotion/core": "^10.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import { jsx, useThemeUI, ThemeProvider as CoreProvider } from '@theme-ui/core'
import { css } from '@theme-ui/css'
import {
jsx,
useThemeUI,
ThemeProvider as CoreProvider,
IntrinsicSxElements,
} from '@theme-ui/core'
import { css, Theme } from '@theme-ui/css'
import { ColorModeProvider } from '@theme-ui/color-modes'
import { MDXProvider } from '@theme-ui/mdx'
import { Global } from '@emotion/core'

const BodyStyles = () =>
jsx(Global, {
styles: theme => {
if (theme.useBodyStyles === false || (theme.styles && !theme.styles.root))
styles: emotionTheme => {
const theme = emotionTheme as Theme
if (
theme.useBodyStyles === false ||
(theme.styles && !theme.styles.root)
) {
return false
const boxSizing = theme.useBorderBox === false ? null : 'border-box'
}
const boxSizing = theme.useBorderBox === false ? undefined : 'border-box'

return css({
'*': {
Expand All @@ -23,7 +33,17 @@ const BodyStyles = () =>
},
})

export const ThemeProvider = ({ theme, components, children }) => {
interface ThemeProviderProps {
theme: Theme
children?: React.ReactNode
components?: { [key in keyof IntrinsicSxElements]?: React.ReactNode }
}

export const ThemeProvider: React.FC<ThemeProviderProps> = ({
theme,
components,
children,
}) => {
const outer = useThemeUI()

if (typeof outer.setColorMode === 'function') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @jsx jsx */
import React from 'react'
import { jsx } from '@theme-ui/core'
import { mdx } from '@mdx-js/react'
import renderer from 'react-test-renderer'
Expand All @@ -15,7 +14,7 @@ const renderJSON = el => renderer.create(el).toJSON()

test('renders', () => {
const json = renderJSON(
<ThemeProvider>
<ThemeProvider theme={{}}>
hasparus marked this conversation as resolved.
Show resolved Hide resolved
<h1>Hello</h1>
</ThemeProvider>
)
Expand All @@ -29,6 +28,8 @@ test('renders with theme', () => {
useCustomProperties: false,
colors: {
primary: 'tomato',
background: 'white',
text: 'black',
},
}}>
<h1 sx={{ color: 'primary' }}>Hello</h1>
Expand Down Expand Up @@ -82,7 +83,7 @@ test('renders with nested provider', () => {
})

test('renders with custom components', () => {
const h1 = props => <pre {...props} />
const h1 = (props: any) => <pre {...props} />

const json = renderJSON(
<ThemeProvider
Expand Down Expand Up @@ -136,7 +137,7 @@ test('renders global styles', () => {

test('resets body margin', () => {
const root = render(
<ThemeProvider>
<ThemeProvider theme={{}}>
<h1>Hello</h1>
</ThemeProvider>
)
Expand Down
4 changes: 4 additions & 0 deletions packages/theme-provider/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../core/tsconfig.json",
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
Loading