Skip to content

Commit

Permalink
Update things
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed May 22, 2019
1 parent 70118b7 commit 7e9b819
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 173 deletions.
2 changes: 1 addition & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[version]
0.89.0
0.98.1

[ignore]
.*/node_modules/config-chain/.*
Expand Down
2 changes: 1 addition & 1 deletion .flowconfig-ci
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[version]
0.89.0
0.98.1

[ignore]
.*/node_modules/config-chain/.*
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-react": "^7.3.0",
"eslint-plugin-standard": "^3.0.1",
"flow-bin": "^0.89.0",
"flow-bin": "^0.98.1",
"hoist-non-react-statics": "^3.3.0",
"husky": "^1.1.3",
"jest": "^24.1.0",
Expand All @@ -93,7 +93,7 @@
"react-native": "^0.57.0",
"react-primitives": "^0.7.0",
"react-router-dom": "^4.2.2",
"react-test-renderer": "16.7.0-alpha.0",
"react-test-renderer": "16.8.6",
"react-testing-library": "^5.2.0"
},
"author": "Kye Hohenberger",
Expand Down
97 changes: 49 additions & 48 deletions packages/core/src/class-names.js
Original file line number Diff line number Diff line change
@@ -1,8 +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, useContext } from './context'
import { withEmotionCache, ThemeContext } from './context'
import { isBrowser } from './utils'

type ClassNameArg =
Expand Down Expand Up @@ -77,57 +78,57 @@ type Props = {
}) => React.Node
}

export const ClassNames: React.StatelessFunctionalComponent<
Props
> = withEmotionCache((props, context) => {
let rules = ''
let serializedHashes = ''
let hasRendered = false
export const ClassNames: React.AbstractComponent<Props> = withEmotionCache(
(props, context) => {
let rules = ''
let serializedHashes = ''
let hasRendered = false

let css = (...args: Array<any>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('css can only be used during render')
let css = (...args: Array<any>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('css can only be used during render')
}
let serialized = serializeStyles(args, context.registered)
if (isBrowser) {
insertStyles(context, serialized, false)
} else {
let res = insertStyles(context, serialized, false)
if (res !== undefined) {
rules += res
}
}
if (!isBrowser) {
serializedHashes += ` ${serialized.name}`
}
return `${context.key}-${serialized.name}`
}
let serialized = serializeStyles(args, context.registered)
if (isBrowser) {
insertStyles(context, serialized, false)
} else {
let res = insertStyles(context, serialized, false)
if (res !== undefined) {
rules += res
let cx = (...args: Array<ClassNameArg>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('cx can only be used during render')
}
return merge(context.registered, css, classnames(args))
}
if (!isBrowser) {
serializedHashes += ` ${serialized.name}`
let content = {
css,
cx,
theme: useContext(ThemeContext)
}
return `${context.key}-${serialized.name}`
}
let cx = (...args: Array<ClassNameArg>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('cx can only be used during render')
let ele = props.children(content)
hasRendered = true
if (!isBrowser && rules.length !== 0) {
return (
<React.Fragment>
<style
{...{
[`data-emotion-${context.key}`]: serializedHashes.substring(1),
dangerouslySetInnerHTML: { __html: rules },
nonce: context.sheet.nonce
}}
/>
{ele}
</React.Fragment>
)
}
return merge(context.registered, css, classnames(args))
}
let content = {
css,
cx,
theme: useContext(ThemeContext)
}
let ele = props.children(content)
hasRendered = true
if (!isBrowser && rules.length !== 0) {
return (
<React.Fragment>
<style
{...{
[`data-emotion-${context.key}`]: serializedHashes.substring(1),
dangerouslySetInnerHTML: { __html: rules },
nonce: context.sheet.nonce
}}
/>
{ele}
</React.Fragment>
)
return ele
}
return ele
})
)
21 changes: 5 additions & 16 deletions packages/core/src/context.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,24 @@
// @flow
import { type EmotionCache } from '@emotion/utils'
import * as React from 'react'
import { useContext, forwardRef } from 'react'
import createCache from '@emotion/cache'
import { isBrowser } from './utils'

let EmotionCacheContext: React.Context<EmotionCache | null> = React.createContext(
isBrowser ? createCache() : null
)

export let useContext: <Value>(
context: React$Context<Value>
) => Value = (React: any).useContext

export let useState: <State>(
initialState: (() => State) | State
) => [State, (State) => void] = (React: any).useState

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

export let useTheme = () => useContext(ThemeContext)

let forwardRef: <Props>(
render: (props: Props, ref: any) => React.Node
) => React.StatelessFunctionalComponent<Props> = (React: any).forwardRef

let withEmotionCache = function withEmotionCache<Props, Ref: React.Ref<*>>(
func: (props: Props, cache: EmotionCache, ref: Ref) => React.Node
): React.StatelessFunctionalComponent<Props> {
): React.AbstractComponent<Props> {
// $FlowFixMe
return forwardRef((props: Props, ref: Ref) => {
let cache = useContext(EmotionCacheContext)
// the cache will never be null in the browser
let cache = ((useContext(EmotionCacheContext): any): EmotionCache)

return func(props, cache, ref)
})
Expand Down
114 changes: 57 additions & 57 deletions packages/core/src/global.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import { withEmotionCache, ThemeContext, useContext } from './context'
import { useLayoutEffect, useContext, useRef } from 'react'
import { withEmotionCache, ThemeContext } from './context'
import { insertStyles } from '@emotion/utils'
import { isBrowser } from './utils'

Expand All @@ -13,18 +14,13 @@ type GlobalProps = {
+styles: Styles | (Object => Styles)
}

let useRef: <Val>(Val) => { current: Val } = (React: any).useRef

let useMutationEffect: (() => mixed, mem?: Array<any>) => void = (React: any)
.useMutationEffect

let warnedAboutCssPropForGlobal = false

// maintain place over rerenders.
// initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn't been inserted there yet, appendChild
// initial client-side render from SSR, use place of hydrating tag

export let Global: React.StatelessFunctionalComponent<
export let Global: React.AbstractComponent<
GlobalProps
> = /* #__PURE__ */ withEmotionCache((props: GlobalProps, cache) => {
if (
Expand All @@ -47,56 +43,7 @@ export let Global: React.StatelessFunctionalComponent<
typeof styles === 'function' ? styles(useContext(ThemeContext)) : styles
])

if (isBrowser) {
let sheetRef = useRef(null)
useMutationEffect(
() => {
let sheet = new StyleSheet({
key: `${cache.key}-global`,
nonce: cache.sheet.nonce,
container: cache.sheet.container
})
// $FlowFixMe
let node: HTMLStyleElement | null = document.querySelector(
`style[data-emotion-${cache.key}="${serialized.name}"]`
)

if (node !== null) {
sheet.tags.push(node)
}
if (cache.sheet.tags.length) {
sheet.before = cache.sheet.tags[0]
}
sheetRef.current = sheet
},
[cache]
)
useMutationEffect(
() => {
let sheet: StyleSheet = (sheetRef.current: any)
if (serialized.next !== undefined) {
// insert keyframes
insertStyles(cache, serialized.next, true)
}
cache.insert(``, serialized, sheet, false)
return () => {
// if this doesn't exist then it will be null so the style element will be appended
// $FlowFixMe
sheet.before = sheet.tags[0].nextElementSibling
sheet.flush()
}
},
[
serialized,
// we don't use the cache in this but we use the sheet
// which is determined by the cache
// and we don't have a reference to the sheet in render so
// we use the cache instead
cache
]
)
return null
} else {
if (!isBrowser) {
let serializedNames = serialized.name
let serializedStyles = serialized.styles
let next = serialized.next
Expand All @@ -123,4 +70,57 @@ export let Global: React.StatelessFunctionalComponent<
/>
)
}

// yes, i know these hooks are used conditionally
// but it is based on a constant that will never change at runtime
// it's effectively like having two implementations and switching them out
// so it's not actually breaking anything

let sheetRef = useRef()

useLayoutEffect(
() => {
let sheet = new StyleSheet({
key: `${cache.key}-global`,
nonce: cache.sheet.nonce,
container: cache.sheet.container
})
// $FlowFixMe
let node: HTMLStyleElement | null = document.querySelector(
`style[data-emotion-${cache.key}="${serialized.name}"]`
)

if (node !== null) {
sheet.tags.push(node)
}
if (cache.sheet.tags.length) {
sheet.before = cache.sheet.tags[0]
}
sheetRef.current = sheet
return () => {
sheet.flush()
}
},
[cache]
)

useLayoutEffect(
() => {
if (serialized.next !== undefined) {
// insert keyframes
insertStyles(cache, serialized.next, true)
}
let sheet: StyleSheet = ((sheetRef.current: any): StyleSheet)
if (sheet.tags.length) {
// if this doesn't exist then it will be null so the style element will be appended
let element = sheet.tags[sheet.tags.length - 1].nextElementSibling
sheet.before = ((element: any): Element | null)
sheet.flush()
}
cache.insert(``, serialized, sheet, false)
},
[cache, serialized]
)

return null
})
7 changes: 1 addition & 6 deletions packages/core/src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
// @flow
export {
withEmotionCache,
CacheProvider,
ThemeContext,
useTheme
} from './context'
export { withEmotionCache, CacheProvider, ThemeContext } from './context'
export { jsx } from './jsx'
export { Global } from './global'
export { keyframes } from './keyframes'
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/jsx.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import { withEmotionCache, ThemeContext, useContext } from './context'
import { useContext } from 'react'
import { withEmotionCache, ThemeContext } from './context'
import { getRegisteredStyles, insertStyles } from '@emotion/utils'
import { isBrowser } from './utils'
import { serializeStyles } from '@emotion/serialize'
Expand Down
5 changes: 1 addition & 4 deletions packages/styled-base/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,7 @@ let createStyled: CreateStyled = (tag: any, options?: StyledOptions) => {

for (let key in props) {
if (shouldUseAs && key === 'as') continue
if (
// $FlowFixMe
finalShouldForwardProp(key)
) {
if (finalShouldForwardProp(key)) {
newProps[key] = props[key]
}
}
Expand Down
2 changes: 1 addition & 1 deletion site/src/templates/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type Props = {
}

if (typeof window !== 'undefined') {
document.addEventListener('DOMContentLoaded', function(event) {
document.addEventListener('DOMContentLoaded', function() {
var hash = window.decodeURI(window.location.hash)
if (hash !== '' && hash !== '#') {
var element = document.getElementById(`.docSearch-content ${hash} a`)
Expand Down
Loading

0 comments on commit 7e9b819

Please sign in to comment.