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

Emotion Primitives #658

Merged
merged 102 commits into from
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
ec93579
Init commit
nitin42 May 14, 2018
3404e55
remove unused dependencies
nitin42 May 16, 2018
f989ea1
added new tests
nitin42 May 16, 2018
a886b94
refactored core
nitin42 May 16, 2018
775917e
prettir 🎉
nitin42 May 16, 2018
a06d8aa
use getPrimitive(primitive) in withComponent
nitin42 May 16, 2018
281b64e
Tweaked emotion-primitives package.json & rollup build
Andarist May 17, 2018
231e581
refactored convertStyles to not to use filter and map
nitin42 May 17, 2018
4694063
remove unneeded options from emotion
nitin42 May 17, 2018
97f5ac6
guard Proxy usage
nitin42 May 17, 2018
8772f90
updated tests
nitin42 May 17, 2018
2b49c02
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
nitin42 May 17, 2018
74492fd
added test for theme
nitin42 May 17, 2018
879e5eb
added emotion-theming and react-primitives to dev depend.
nitin42 May 17, 2018
7a0bdc8
updated snapshots
nitin42 May 17, 2018
21ce603
Tweaked externals list in rollup.config.js
Andarist May 18, 2018
608134b
don't forward ref to stateless comp.
nitin42 May 18, 2018
3059db8
added tests for innerRef and style composition
nitin42 May 18, 2018
9018019
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
nitin42 May 18, 2018
01f25cf
added tests for createRef()
nitin42 May 20, 2018
43f823a
don't use proxy in Sketch or Native
nitin42 May 20, 2018
3f1e514
use createRef() api for innerRef
nitin42 May 20, 2018
93f89af
remove primitive props check
nitin42 May 20, 2018
fca98c6
fix(emotion-primitives): put back missing dependency for tests
DavideDaniel May 21, 2018
989c582
Merge pull request #1 from DavideDaniel/emotion-primitives
nitin42 May 21, 2018
3ccc32e
updated tests to use .Text and etc
nitin42 May 21, 2018
7ff2302
forward children prop
nitin42 May 21, 2018
372a94e
update primitive API
nitin42 May 21, 2018
ff42dda
added get-lerna-packages depen.
nitin42 May 21, 2018
2a915b3
remove unnecessary properties from styled constructor
nitin42 May 21, 2018
d61b23e
Pass innerRef down directly
emmatown May 21, 2018
a670594
use ':' when splitting the css properties
nitin42 May 25, 2018
290e250
remove convertRuleOptions
nitin42 May 25, 2018
21c98fb
move React to peerDepend.
nitin42 May 25, 2018
6a40c31
Update package.json
emmatown May 25, 2018
d6f458f
Merge branch 'master' into emotion-primitives
emmatown May 25, 2018
3f665fc
omit styles array and use theme context
nitin42 May 25, 2018
34f1e42
use this.mergedProps in interpolations
nitin42 May 25, 2018
dc918d7
fixed failing tests
nitin42 May 25, 2018
d9eeac7
Init commit
nitin42 May 25, 2018
4a645c0
refactored
nitin42 May 25, 2018
e22c152
cleanup
nitin42 May 25, 2018
3e332c1
remove test for .styles property
nitin42 May 29, 2018
747acb3
remove unnecessary space
nitin42 Jun 6, 2018
b27ceb8
updated
nitin42 Jun 6, 2018
0fa0929
formatted
nitin42 Jun 6, 2018
49c8172
docs
nitin42 Jun 6, 2018
51eecab
Update docs.yaml
emmatown Jun 7, 2018
e05a360
Optimized splitProps a little bit
Andarist Jun 14, 2018
a0c8a79
Tweaked getPrimitive implementation
Andarist Jun 14, 2018
801c69d
Optimized isValidStyleProp implementation a little bit
Andarist Jun 14, 2018
1632b26
added test case for withComponent
nitin42 Jun 17, 2018
9c0b724
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
nitin42 Jun 17, 2018
6df7787
fixed grid layout
nitin42 Jun 17, 2018
99434b7
Revert "fixed grid layout"
nitin42 Jun 17, 2018
be28620
remove proxy
nitin42 Jun 26, 2018
841a01a
updated test case for invalid primitive
nitin42 Jun 26, 2018
b010d10
Merge branch 'master' of https://github.com/emotion-js/emotion into e…
tkh44 Jun 27, 2018
00c5108
Merge branch 'master' into emotion-primitives
tkh44 Jun 28, 2018
e5408dd
Merge branch 'master' into emotion-primitives
tkh44 Jun 28, 2018
1e5519f
basic example
nitin42 Jun 29, 2018
b67bab7
updated example
nitin42 Jun 29, 2018
c7bab6b
added link to react-sketchapp
nitin42 Jun 29, 2018
e91ab38
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
nitin42 Jun 29, 2018
633761f
use styled in import
nitin42 Jun 30, 2018
0ffcb92
Merge branch 'master' into emotion-primitives
tkh44 Jul 2, 2018
5f9b040
Update lock file... again
tkh44 Jul 2, 2018
75c57c9
Test against src and not dist file.
tkh44 Jul 2, 2018
0c5eb89
Remove style overrides as props, simplify some stuff, remove StyleShe…
emmatown Jul 6, 2018
8a84d7c
Remove props as css overrides from README example
emmatown Jul 6, 2018
53b984d
Merge branch 'master' into emotion-primitives
emmatown Jul 6, 2018
779c8c0
A WIP css function
emmatown Jul 6, 2018
b6d4c17
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
emmatown Jul 6, 2018
a912bff
Make interleave use for loop and add prop-types as peerDependency
emmatown Jul 6, 2018
b3b5e93
Use css in styled in emotion-primitives
emmatown Jul 6, 2018
437a9ab
Don't transform styled.View to styled('View')
emmatown Jul 6, 2018
477b0e2
Use @emotion/is-prop-valid
emmatown Jul 6, 2018
2cfe87a
Change interleave implementation
emmatown Jul 6, 2018
9b1920a
Mention peerDep on prop-types in README
emmatown Jul 6, 2018
c46233c
Add emotion-primitives to .flowconfig
emmatown Jul 6, 2018
d8f9810
Fix a thing
emmatown Jul 6, 2018
33d236f
Add test for composition
emmatown Jul 6, 2018
67fd321
Use css in README.md
emmatown Jul 6, 2018
e3a2055
Avoid creating an extra object in some cases
emmatown Jul 6, 2018
38a0243
Add a comment explaining a thing
emmatown Jul 6, 2018
d2fe4c4
Remove on* properties from list since @emotion/is-prop-valid allows a…
emmatown Jul 6, 2018
04e4bb3
Merge branch 'master' into emotion-primitives
emmatown Jul 6, 2018
cbdbf0f
Rename a variable
emmatown Jul 6, 2018
b97b54e
Hoist handleInterpolation and rename pick to pickTest
emmatown Jul 6, 2018
e41ce0f
Hoist iteratee in convertStyles
emmatown Jul 6, 2018
2254dd2
Fix flow types for styled and change no babel test
emmatown Jul 6, 2018
79ba84f
Fix eslint comment
emmatown Jul 6, 2018
d2d17a2
100% statement coverage for emotion-primitives 🎉
emmatown Jul 6, 2018
30349a7
Add a comment
emmatown Jul 6, 2018
6538b79
Add another comment
emmatown Jul 6, 2018
f8e6958
Improved documentation
nitin42 Jul 6, 2018
e572f96
Merge branch 'emotion-primitives' of https://github.com/nitin42/emoti…
nitin42 Jul 6, 2018
feeda5f
fix stuff
emmatown Jul 6, 2018
bab8aec
Rename to @emotion/primitives
emmatown Jul 6, 2018
5714031
Fix site
emmatown Jul 6, 2018
eb4b4fa
Remove incorrect comment
emmatown Jul 6, 2018
aa41a29
Remove old rollup config and dependencies in top level package.json
emmatown Jul 6, 2018
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
15 changes: 15 additions & 0 deletions packages/emotion-primitives/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "emotion-primitives",
"version": "1.0.0-beta.1",
"main": "src/index.js",
"license": "MIT",
"dependencies": {
"css-to-react-native": "^2.2.0",
"prop-types": "^15.6.1",
"react-primitives": "^0.5.1"
},
"devDependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1"
}
}
109 changes: 109 additions & 0 deletions packages/emotion-primitives/src/convertToRNStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { StyleSheet } from 'react-primitives'
import transform from 'css-to-react-native'

// Copied and edited from @emotion/css
// Cannot use css from @emotion/css directly because of unnecessary checks, __emotion_styles, and registering interpolations in cache.
function handleInterpolation(interpolation, couldBeSelectorInterpolation) {
if (interpolation == null) {
return ''
}

switch (typeof interpolation) {
case 'boolean':
return ''
case 'function':
return handleInterpolation.call(
this,
this === undefined ? interpolation() : interpolation(this.props),
couldBeSelectorInterpolation
)

default:
return interpolation
}
}

// Return evaluated css string
function createStyles(strings, ...interpolations) {
let stringMode = true
let styles = ''

if (strings == null || strings.raw === undefined) {
stringMode = false
styles += handleInterpolation.call(this, strings, false)
} else {
styles += strings[0]
}

interpolations.forEach(function(interpolation, i) {
styles += handleInterpolation.call(
this,
interpolation,
styles.charCodeAt(styles.length - 1) === 46
)

if (stringMode === true && strings[i + 1] !== undefined) {
styles += strings[i + 1]
}
}, this)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldnt arrow function be good enough here? passing this like that is a little bit surprising for the reader at the first moment

Copy link
Contributor Author

@nitin42 nitin42 May 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was to me too when I first referenced this with emotion/css. We can change this, no issues.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this to save a few bytes so that Babel didn’t need to add var _this = this. It won’t make a big difference but it helps. I’m fine with changing it though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if that's the case I'm fine with keeping it here too


return styles
}

function convertStyles(str) {
if (typeof str === 'string' && str.length === 0) return str
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could return '' here, i doubt it is any different than returning str here which is an empty string in that case and making it more explicit would help recognizing the intention a little bit sooner (not that it's particularly hard to see it in current form, but still 🤷‍♂️ )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, sure!


const styleObj = []

const parsedString = str.split(';')

parsedString.forEach(style => {
if (typeof style === 'string') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this if statement seems unnecessary, style has to be a string because it's outcome of str.split(';')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! Makes sense.

// Get prop name and prop value
const ar = style.split(': ')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we split here by ':'?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more precise!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt width:100px; supported?


if (ar[0] && ar[1]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both need to be coerced to booleans, we could make this more explicit by checking ar.length === 2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Earlier I was checking if both were not undefined!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how those elements could be undefined? checking against .length here is preferable as we should avoid out of bounds accesses

styleObj.push([ar[0].trim(), ar[1].trim()])
}
}
})

return styleObj
}

export function convertToRNStyles(styles) {
if (styles[0][0] !== undefined) {
let arr = []

arr.push(styles[0][0])
let len = styles.length
let i = 1
for (; i < len; i++) {
arr.push(styles[i], styles[0][i])
}

let css = createStyles.apply(this, arr)

let parsedCSS = convertStyles(css)

// Convert css styles to react native
let rnStyles = Array.isArray(parsedCSS) ? transform(parsedCSS) : {}

return [StyleSheet.create({ style: rnStyles }).style]
} else if (styles[0] == null || styles[0].raw === undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit picking: this else is redundant as previous block is terminated with return anyway, this is equivalent to:

if (a) {
  return val
}

if (b) {
  return val2
}

return styles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while I prefer this style emotion is aiming for high perf so it would probably be better to rewrite this to a for loop or forEach to avoid double iteration with filter + map combination

.filter(style => {
if (typeof style === 'object') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style[0] == null in here and unfortunately typeof null is an 'object' so this one might crash here

return Object.keys(style).length > 0
}
return true
})
.map(style => {
if (typeof style === 'object') {
return StyleSheet.create({ style }).style
}

return style
})
}
}
109 changes: 109 additions & 0 deletions packages/emotion-primitives/src/createEmotion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as React from 'react'
import reactPrimitives from 'react-primitives'
import PropTypes from 'prop-types'

import { getStyles } from './getStyles'
import { convertToRNStyles } from './convertToRNStyles'

const isValidPrimitive = primitive =>
['Text', 'View', 'Image'].indexOf(primitive) > -1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe hoist this constant array above the function to avoid unnecessary garbage collection on this, although probably modern engines should recognize it's constant and hoist it on their own, but it's hard to tell - so I would argue it's better to do that manually


const getPrimitive = primitive => {
if (typeof primitive === 'string' && isValidPrimitive(primitive)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of doing this, we could change babel-plugin-emotion to not change the dot syntax if the first character is uppercase?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we can but I am not sure that babel-plugin-emotion will work in other environment. Tweaking this here may work on web but not on other platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I really like this idea though 🤔

return reactPrimitives[primitive]
} else if (typeof primitive === 'string' && !isValidPrimitive(primitive)) {
throw new Error(
`Cannot style invalid primitive ${primitive}. Expected primitive to be one of ['Text', 'View', 'Image']`
)
} else if (typeof primitive === 'function') {
return primitive
}
}

function evalStyles(context, Comp, styles, styleOverrides) {
// Assign static property so that the styles can be reused (like in withComponent)
Comp.styles = convertToRNStyles.call(context, styles)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be called on each render so the styles assigned as statics on the component will change depending on the props. Maybe the styles array created at the start of createStyledComponent should be assigned as a static on the component instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do that but, using this has an advantage. We can use reuse the converted styles like -

const Text = emotion.text`color: red; padding: 10px;`

// After calling convertToRNStyles, styles get converted to RN
// like this -> [73]

// If we decide to assign the styles array then we won't be able to
// reuse the styles on another component because styles array
// would be like this [['color: red; padding: 10px;', raw: [...]]].

const Author = emotion.text`${Text.styles} position: absolute; right: 0;` 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good when composing the styles like using css on Web.


return getStyles.call(context, Comp.styles, context.props, styleOverrides)
}

/**
* Creates a function that renders the styles on multiple targets with same code.
*/
export function createEmotionPrimitive(splitProps) {
/*
* Returns styled component
*/
return function emotion(primitive, { displayName } = {}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passing displayName like that is not part of react-emotion's API, do we have to do it here?

return createStyledComponent

/**
* Create emotion styled component
*/
function createStyledComponent() {
let styles = []

styles.push.apply(styles, arguments)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this should be an equivalent of function createStyledComponent(...styles) { ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. This here makes sure that we receive interpolation array when using string template literal or a valid object when used object style notation. But if you've an alternate approach to this, you can alter this 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what do u mean, u basically spread arguments into styles array with that push.apply, it seems to me that function createStyledComponent(...styles) { ... } is 100% the same, only might be more performant (i have no data to back this up though)

could u explain how they might not be the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll test and see if it works (doesn't break other things) without using styles array.


class Styled extends React.Component {
static propTypes = {
innerRef: PropTypes.func
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prop type won't work with createRef.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea.. I'll fix this!

}

onRef = innerComponent => {
this.innerComponent = innerComponent

if (this.props.innerRef) {
this.props.innerRef(innerComponent)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we support the new createRef api like this? Also, is there a reason to get the ref at all since it doesn't seem like it's used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, we can! I already had this thing in my mind.

}

render() {
const { toForward, styleOverrides } = splitProps(
primitive,
this.props
)

const emotionStyles = evalStyles(this, Styled, styles, styleOverrides)

return React.createElement(
getPrimitive(primitive),
{
...toForward,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toForward is a fresh object, it would be good to avoid making additional copy here by just mutating this object with ref and style props

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we go that way then children should get attached to that object too instead of passed as 3rd argument

Copy link
Contributor Author

@nitin42 nitin42 May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any perf. cost to this ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to the first one - yeah, to the second one (children) there is not, u can disregard my comment, this one doesn't have to be attached to toForward. I've checked react's source code and for a single child react will do it by itself so it doesnt really matter if it's done here or on react's side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I'll tweak this in next commits!

ref: this.onRef,
style: emotionStyles.length > 0 ? emotionStyles : null
},
this.props.children || null
)
}
}

Styled.primitive = primitive

Styled.withComponent = (newPrimitive, options = {}) =>
emotion(getPrimitive(newPrimitive), {
...options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is making a copy here needed? (im not sure, it might be)

})(...Styled.styles)

Object.assign(
Styled,
getStyledMetadata({
primitive,
styles,
displayName
})
)

return Styled
}
}
}

const getStyledMetadata = ({ primitive, styles, displayName }) => ({
styles: primitive.styles ? primitive.styles.concat(styles) : styles,
primitive: primitive.primitive ? primitive.primitive : primitive,
displayName: displayName || `emotion(${getDisplayName(primitive)})`
})

const getDisplayName = primitive =>
typeof primitive === 'string' ? primitive : primitive.displayName || 'Styled'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should also consider reading primitive.name here (taking lower priority than .displayName ofc)

23 changes: 23 additions & 0 deletions packages/emotion-primitives/src/getStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function evaluateStyles(styles, props) {
return styles.map(style => {
if (typeof style === 'function') {
return style(props)
}

return style
})
}

export function getStyles(styles, props, styleOverrides) {
const emotionStyles = evaluateStyles(styles, props)

if (props.style) {
emotionStyles.push(props.style)
}

if (styleOverrides && Object.keys(styleOverrides).length > 0) {
emotionStyles.push(styleOverrides)
}

return emotionStyles
}
50 changes: 50 additions & 0 deletions packages/emotion-primitives/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import reactPrimitives from 'react-primitives'

import { createEmotionPrimitive } from './createEmotion'
import { splitProps } from './splitProps'

const primitives = ['Text', 'View', 'Image']

const assignPrimitives = styled => {
Object.assign(
styled,
primitives.reduce((getters, alias) => {
getters[alias.toLowerCase()] = styled(reactPrimitives[alias])
return getters
}, {})
)

Object.assign(
styled,
primitives.reduce((getters, alias) => {
const tag = alias.toLowerCase()
getters[alias] = styled[tag]()
getters[alias].tag = reactPrimitives[alias]
getters[alias].displayName = `emotion.${tag}`
return getters
}, {})
)

return styled
}

const emotion = createEmotionPrimitive(splitProps)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will it be possible to createEmotionPrimitive with other splitProps implementation? are there use cases for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use case is -

To split component props, style props and style overrides so that we can forward them without logging any warnings.


// Validate primitives accessed using the emotion function directly like emotion.TEXT`` or emotion.VIEW``
const validate = target => {
const handler = {
get: (obj, prop) => {
if (prop in obj) {
return obj[prop]
} else {
throw new Error(
`Cannot style invalid primitive ${prop}. Expected primitive to be one of ['Text', 'View', 'Image']`
)
}
}
}

return new Proxy(target, handler)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proxy is not supported by all environments - this should be guarded like here

}

export default validate(assignPrimitives(emotion))
Loading