Skip to content

Commit d3b55b8

Browse files
emmatownKye Hohenberger
authored and
Kye Hohenberger
committed
Throw a nice error when using the styled shorthand without babel-plugin-emotion and remove duplication in component selector code (#516)
* Throw a nice error when using the styled shorthand with babel-plugin-emotion and remove duplication in component selector stuff * Remove more useless stuff
1 parent 993b27f commit d3b55b8

File tree

12 files changed

+43
-71
lines changed

12 files changed

+43
-71
lines changed

packages/create-emotion-styled/src/index.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @flow
2-
import { STYLES_KEY, TARGET_KEY } from 'emotion-utils'
2+
import { STYLES_KEY } from 'emotion-utils'
33
import type { Emotion, Interpolations } from 'create-emotion'
44
import { channel, contextTypes } from '../../emotion-theming/src/utils'
55
import type { ElementType } from 'react'
@@ -14,7 +14,7 @@ import {
1414
} from './utils'
1515

1616
function createEmotionStyled(emotion: Emotion, view: ReactType) {
17-
const createStyled: CreateStyled = (tag, options) => {
17+
let createStyled: CreateStyled = (tag, options) => {
1818
if (process.env.NODE_ENV !== 'production') {
1919
if (tag === undefined) {
2020
throw new Error(
@@ -133,7 +133,6 @@ function createEmotionStyled(emotion: Emotion, view: ReactType) {
133133
Styled[STYLES_KEY] = styles
134134
Styled.__emotion_base = baseTag
135135
Styled.__emotion_real = Styled
136-
Styled[TARGET_KEY] = stableClassName
137136
Object.defineProperty(Styled, 'toString', {
138137
enumerable: false,
139138
value() {
@@ -165,6 +164,16 @@ function createEmotionStyled(emotion: Emotion, view: ReactType) {
165164
return Styled
166165
}
167166
}
167+
if (process.env.NODE_ENV !== 'production' && typeof Proxy !== 'undefined') {
168+
createStyled = new Proxy(createStyled, {
169+
get(target, property) {
170+
throw new Error(
171+
`You're trying to use the styled shorthand without babel-plugin-emotion.` +
172+
`\nPlease install and setup babel-plugin-emotion or use the function call syntax(\`styled('${property}')\` instead of \`styled.${property}\`)`
173+
)
174+
}
175+
})
176+
}
168177
return createStyled
169178
}
170179

packages/create-emotion/src/index.js

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @flow
2-
import { hashString, Stylis, STYLES_KEY, TARGET_KEY } from 'emotion-utils'
2+
import { hashString, Stylis, STYLES_KEY } from 'emotion-utils'
33
import stylisRuleSheet from 'stylis-rule-sheet'
44
import {
55
processStyleName,
@@ -132,16 +132,7 @@ function createEmotion(
132132
return ''
133133
case 'function':
134134
if (interpolation[STYLES_KEY] !== undefined) {
135-
if (
136-
process.env.NODE_ENV !== 'production' &&
137-
interpolation[TARGET_KEY] === undefined
138-
) {
139-
throw new Error(
140-
'Component selectors can only be used in conjunction with babel-plugin-emotion.'
141-
)
142-
}
143-
144-
return `.${interpolation[TARGET_KEY]}`
135+
return interpolation.toString()
145136
}
146137
return handleInterpolation.call(
147138
this,

packages/create-emotion/test/__snapshots__/styled.test.js.snap

-6
Original file line numberDiff line numberDiff line change
@@ -766,12 +766,6 @@ exports[`styled with higher order component that hoists statics 1`] = `
766766
/>
767767
`;
768768

769-
exports[`styled withComponent creates a new, unique stable class per invocation 1`] = `"e1x6erbc54"`;
770-
771-
exports[`styled withComponent creates a new, unique stable class per invocation 2`] = `"e1x6erbc55"`;
772-
773-
exports[`styled withComponent creates a new, unique stable class per invocation 3`] = `"e1x6erbc56"`;
774-
775769
exports[`styled withComponent will replace tags but keep styling classes 1`] = `
776770
.emotion-0 {
777771
color: green;

packages/create-emotion/test/styled.test.js

+3-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import * as emotion from './emotion-instance'
88
import { createSerializer } from 'jest-emotion'
99
import { ThemeProvider } from 'emotion-theming'
1010
import hoistNonReactStatics from 'hoist-non-react-statics'
11-
import { TARGET_KEY } from 'emotion-utils'
1211
import { mount } from 'enzyme'
1312
import enzymeToJson from 'enzyme-to-json'
1413

@@ -1070,13 +1069,9 @@ describe('styled', () => {
10701069
const Subtitle = Title.withComponent('h2')
10711070
const Byline = Title.withComponent('span')
10721071

1073-
expect(Subtitle[TARGET_KEY]).not.toBe(Title[TARGET_KEY])
1074-
expect(Byline[TARGET_KEY]).not.toBe(Title[TARGET_KEY])
1075-
expect(Byline[TARGET_KEY]).not.toBe(Subtitle[TARGET_KEY])
1076-
1077-
expect(Title[TARGET_KEY]).toMatchSnapshot()
1078-
expect(Subtitle[TARGET_KEY]).toMatchSnapshot()
1079-
expect(Byline[TARGET_KEY]).toMatchSnapshot()
1072+
expect(Subtitle.toString()).not.toBe(Title.toString())
1073+
expect(Byline.toString()).not.toBe(Title.toString())
1074+
expect(Byline.toString()).not.toBe(Subtitle.toString())
10801075
})
10811076
test('name with class component', () => {
10821077
class SomeComponent extends React.Component<{ className: string }> {

packages/emotion-utils/src/index.js

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export const memoize = (fn: string => any) => {
99
}
1010

1111
export const STYLES_KEY = '__emotion_styles'
12-
export const TARGET_KEY = '__emotion_target'
1312

1413
export const unitless: { [string]: 1 } = {
1514
animationIterationCount: 1,

packages/emotion/test/__snapshots__/component-selector.test.js.snap

-2
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,3 @@ exports[`component selector should be converted to use the emotion target classN
2727
color: blue;
2828
}"
2929
`;
30-
31-
exports[`component selector should throw if the missing the static targeting property 1`] = `"Component selectors can only be used in conjunction with babel-plugin-emotion."`;

packages/emotion/test/component-selector.test.js

-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react'
22
import styled from 'react-emotion'
33
import renderer from 'react-test-renderer'
44
import { css, flush, sheet } from 'emotion'
5-
import { TARGET_KEY } from 'emotion-utils'
65

76
describe('component selector', () => {
87
afterEach(() => flush())
@@ -27,20 +26,4 @@ describe('component selector', () => {
2726
expect(tree).toMatchSnapshot()
2827
expect(sheet).toMatchSnapshot()
2928
})
30-
31-
test('should throw if the missing the static targeting property', () => {
32-
const FakeComponent = styled.div`
33-
color: blue;
34-
`
35-
36-
delete FakeComponent[TARGET_KEY]
37-
38-
expect(() => {
39-
css`
40-
${FakeComponent} {
41-
color: red;
42-
}
43-
`
44-
}).toThrowErrorMatchingSnapshot()
45-
})
4629
})

packages/emotion/test/no-babel/__snapshots__/index.test.js.snap

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ exports[`css @supports 1`] = `
1414

1515
exports[`css component as selectors (object syntax) 1`] = `"Component selectors can only be used in conjunction with babel-plugin-emotion."`;
1616

17+
exports[`css component selectors without target 1`] = `"Component selectors can only be used in conjunction with babel-plugin-emotion."`;
18+
1719
exports[`css composition 1`] = `
1820
.emotion-0 {
1921
display: -webkit-box;
@@ -229,3 +231,8 @@ exports[`css random expressions undefined return 1`] = `
229231
hello world
230232
</h1>
231233
`;
234+
235+
exports[`css styled throws a nice error when using the styled shorthand without babel-plugin-emotion 1`] = `
236+
"You're trying to use the styled shorthand without babel-plugin-emotion.
237+
Please install and setup babel-plugin-emotion or use the function call syntax(\`styled('div')\` instead of \`styled.div\`)"
238+
`;

packages/emotion/test/no-babel/index.test.js

+18
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ describe('css', () => {
146146
)
147147
}).toThrowErrorMatchingSnapshot()
148148
})
149+
test('component selectors without target', () => {
150+
const SomeComponent = styled('div')`
151+
color: blue;
152+
`
153+
154+
expect(() => {
155+
css`
156+
${SomeComponent} {
157+
color: red;
158+
}
159+
`
160+
}).toThrowErrorMatchingSnapshot()
161+
})
149162
test('glamorous style api & composition', () => {
150163
const H1 = styled('h1')(props => ({ fontSize: props.fontSize }))
151164
const H2 = styled(H1)(props => ({ flex: props.flex }), { display: 'flex' })
@@ -197,4 +210,9 @@ describe('css', () => {
197210

198211
expect(tree).toMatchSnapshot()
199212
})
213+
test('styled throws a nice error when using the styled shorthand without babel-plugin-emotion', () => {
214+
expect(() => {
215+
styled.div``
216+
}).toThrowErrorMatchingSnapshot()
217+
})
200218
})

packages/react-emotion/test/__snapshots__/index.test.js.snap

-6
Original file line numberDiff line numberDiff line change
@@ -796,12 +796,6 @@ exports[`styled with higher order component that hoists statics 1`] = `
796796
/>
797797
`;
798798

799-
exports[`styled withComponent creates a new, unique stable class per invocation 1`] = `"eldhy9955"`;
800-
801-
exports[`styled withComponent creates a new, unique stable class per invocation 2`] = `"eldhy9956"`;
802-
803-
exports[`styled withComponent creates a new, unique stable class per invocation 3`] = `"eldhy9957"`;
804-
805799
exports[`styled withComponent does not carry styles from flattened component 1`] = `
806800
.emotion-0 {
807801
color: hotpink;

packages/react-emotion/test/component-selectors/component-selector.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ test('component as selector (object syntax)', () => {
7777
})
7878

7979
test('component as selector function interpolation (object syntax)', () => {
80-
const H1 = styled('h1')({}, props => ({
80+
const H1 = styled('h1')(props => ({
8181
fontSize: `${props.fontSize}px`
8282
}))
8383

packages/react-emotion/test/index.test.js

-16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import renderer from 'react-test-renderer'
44
import styled, { css, flush } from 'react-emotion'
55
import { ThemeProvider } from 'emotion-theming'
66
import hoistNonReactStatics from 'hoist-non-react-statics'
7-
import { TARGET_KEY } from 'emotion-utils'
87
import { mount } from 'enzyme'
98
import enzymeToJson from 'enzyme-to-json'
109

@@ -1072,21 +1071,6 @@ describe('styled', () => {
10721071
expect(enzymeToJson(wrapper)).toMatchSnapshot()
10731072
})
10741073

1075-
test('withComponent creates a new, unique stable class per invocation', () => {
1076-
const Title = styled('h1')`
1077-
color: ${props => props.color || 'green'};
1078-
`
1079-
const Subtitle = Title.withComponent('h2')
1080-
const Byline = Title.withComponent('span')
1081-
1082-
expect(Subtitle[TARGET_KEY]).not.toBe(Title[TARGET_KEY])
1083-
expect(Byline[TARGET_KEY]).not.toBe(Title[TARGET_KEY])
1084-
expect(Byline[TARGET_KEY]).not.toBe(Subtitle[TARGET_KEY])
1085-
1086-
expect(Title[TARGET_KEY]).toMatchSnapshot()
1087-
expect(Subtitle[TARGET_KEY]).toMatchSnapshot()
1088-
expect(Byline[TARGET_KEY]).toMatchSnapshot()
1089-
})
10901074
test('name with class component', () => {
10911075
class SomeComponent extends React.Component<{ className: string }> {
10921076
render() {

0 commit comments

Comments
 (0)