Skip to content

Commit d093e7f

Browse files
authored
fix(emotion): fix interpolation usage (#184)
1 parent 3fb9239 commit d093e7f

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

packages/emotion/src/css.test.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,34 @@ describe('#css', () => {
6363
expect(container.firstChild).toHaveStyle('margin: 4px 8px;')
6464
})
6565

66+
it('accepts object', () => {
67+
const Dummy = styled.div`
68+
${css({
69+
margin: '1 2',
70+
})}
71+
`
72+
const { container } = render(
73+
<SpaceTheme>
74+
<Dummy />
75+
</SpaceTheme>,
76+
)
77+
expect(container.firstChild).toHaveStyle('margin: 4px 8px;')
78+
})
79+
80+
it('accepts function', () => {
81+
const Dummy = styled.div`
82+
${css((p) => ({
83+
margin: '1 2',
84+
}))}
85+
`
86+
const { container } = render(
87+
<SpaceTheme>
88+
<Dummy />
89+
</SpaceTheme>,
90+
)
91+
expect(container.firstChild).toHaveStyle('margin: 4px 8px;')
92+
})
93+
6694
it('transforms babel-plugin-emotion output', () => {
6795
const Dummy = styled.div`
6896
${css({

packages/emotion/src/css.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { css as emCss } from '@emotion/react'
1+
import { css as emCss, SerializedStyles, Theme } from '@emotion/react'
22
import { CSSInterpolation } from '@emotion/serialize'
33
import { transform } from '@xstyled/core'
44

@@ -9,15 +9,36 @@ function styleToString(style: any, props: any): any {
99
return style
1010
}
1111

12-
// @ts-ignore
13-
export const css: typeof emCss = (
12+
interface Props {
13+
theme?: Theme
14+
}
15+
16+
interface CSSInterpolationFn {
17+
(props: Props): CSSInterpolation
18+
}
19+
20+
interface SerializedStylesFn {
21+
(props: Props): SerializedStyles
22+
}
23+
24+
export function css(fn: CSSInterpolationFn): SerializedStylesFn
25+
export function css(...args: CSSInterpolation[]): SerializedStylesFn
26+
export function css(
1427
strings: TemplateStringsArray,
15-
...rawArgs: Array<CSSInterpolation>
16-
) => {
17-
const emCssArgs = emCss(strings, ...rawArgs)
18-
const transformedStyles = transform(emCssArgs.styles)
19-
return (props: any) => ({
20-
...emCssArgs,
21-
styles: styleToString(transformedStyles, props),
22-
})
28+
...rawArgs: CSSInterpolation[]
29+
): SerializedStylesFn
30+
export function css(
31+
strings: TemplateStringsArray | CSSInterpolation | CSSInterpolationFn,
32+
...rawArgs: CSSInterpolation[]
33+
): SerializedStylesFn {
34+
return (props: Props): SerializedStyles => {
35+
const emCssArgs =
36+
typeof strings === 'function'
37+
? emCss(strings(props))
38+
: emCss(strings as TemplateStringsArray, ...rawArgs)
39+
return {
40+
...emCssArgs,
41+
styles: styleToString(transform(emCssArgs.styles), props),
42+
}
43+
}
2344
}

packages/emotion/src/styled.test.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ describe('#styled', () => {
118118
expect(container.firstChild).toHaveStyle('margin: 8px;')
119119
})
120120

121+
it('works with css as object and function prop', () => {
122+
const Dummy = styled.div(() => ({
123+
margin: '2',
124+
}))
125+
const { container } = render(
126+
<SpaceTheme>
127+
<Dummy />
128+
</SpaceTheme>,
129+
)
130+
expect(container.firstChild).toHaveStyle('margin: 8px;')
131+
})
132+
121133
it('transforms first class interpolations', () => {
122134
const Dummy = styled.div`
123135
${() => [

0 commit comments

Comments
 (0)