Skip to content

Commit

Permalink
fix(emotion): fix array handling used in breakpoints utilities
Browse files Browse the repository at this point in the history
Closes #29
  • Loading branch information
gregberge committed Jun 22, 2019
1 parent 6d23d73 commit e34d576
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 127 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"eslint-plugin-react-hooks": "^1.6.0",
"jest": "^24.8.0",
"jest-dom": "^3.4.0",
"jest-emotion": "^10.0.11",
"jest-styled-components": "^6.3.1",
"lerna": "^3.15.0",
"prettier": "^1.18.2",
Expand Down
18 changes: 11 additions & 7 deletions packages/emotion/src/css.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { css as emCss } from '@emotion/core'
import { transform } from '@xstyled/core'

export function css(...rawArgs) {
const emCssArgs = emCss(...rawArgs)
function styleToString(style, props) {
if (Array.isArray(style))
return style.reduce((str, style) => str + styleToString(style, props), '')
if (typeof style === 'function') return styleToString(style(props), props)
return style
}

export function css(strings, ...rawArgs) {
const emCssArgs = emCss(strings, ...rawArgs)
const transformedStyles = transform(emCssArgs.styles)
return p => ({
return props => ({
...emCssArgs,
styles: transformedStyles.reduce((str, style) => {
const value = typeof style === 'function' ? style(p) : style
return str + value
}, ''),
styles: styleToString(transformedStyles, props),
})
}
15 changes: 10 additions & 5 deletions packages/emotion/src/styled.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
/* eslint-disable no-continue, no-loop-func, no-cond-assign */
import emStyled from '@emotion/styled'
import { cascade } from '@xstyled/core'
import { Box } from './Box'
import { css } from './css'

function flattenArgs(arg, props) {
if (typeof arg === 'function') return flattenArgs(arg(props), props)
if (Array.isArray(arg)) return arg.map(arg => flattenArgs(arg, props))
return arg
}

function getCreateStyle(baseCreateStyle) {
return (...args) =>
baseCreateStyle(p => {
const flattenedArgs = args.map(arg => cascade(arg, p))
const result = css(...flattenedArgs)(p)
return (strings, ...args) =>
baseCreateStyle(props => {
const flattenedArgs = flattenArgs(args, props)
const result = css(strings, ...flattenedArgs)(props)
return result
})
}
Expand Down
13 changes: 13 additions & 0 deletions packages/emotion/src/styled.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ describe('#styled', () => {
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyle('margin: 8px;')
})

it('transforms first class interpolations', () => {
const Dummy = styled.div`
${() => [
'color: red;',
css`
margin: 1;
`,
]}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyle('color: red; margin: 4px;')
})
})

describe('#styled.xxx', () => {
Expand Down
117 changes: 117 additions & 0 deletions packages/system/tests/common/breakpoints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import React from 'react'
import { render, cleanup } from '@testing-library/react'
import { breakpoints, up, down, between } from '../../src'

afterEach(cleanup)

export function testBreakpoints({ styled, css }) {
describe('#breakpoints', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${breakpoints({
md: css`
color: red;
`,
})}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${breakpoints({
md: { color: 'red' },
})}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})
})

describe('#up', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${up(
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${up('md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})
})

describe('#down', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${down(
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(max-width: 767.98px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${down('md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(max-width: 767.98px)',
})
})
})

describe('#between', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${between(
'sm',
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 576px) and (max-width: 767.98px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${between('sm', 'md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 576px) and (max-width: 767.98px)',
})
})
})
}
8 changes: 8 additions & 0 deletions packages/system/tests/emotion/breakpoints.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { matchers } from 'jest-emotion'
import styled from '@emotion/styled'
import { css } from '@emotion/core'
import { testBreakpoints } from '../common/breakpoints'

expect.extend(matchers)

testBreakpoints({ styled, css })
116 changes: 2 additions & 114 deletions packages/system/tests/styled-components/breakpoints.test.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,5 @@
import React from 'react'
import 'jest-styled-components'
import { render, cleanup } from '@testing-library/react'
import styled, { css } from 'styled-components'
import { breakpoints, up, down, between } from '../../src'
import { testBreakpoints } from '../common/breakpoints'

afterEach(cleanup)

describe('#breakpoints', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${breakpoints({
md: css`
color: red;
`,
})}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${breakpoints({
md: { color: 'red' },
})}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})
})

describe('#up', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${up(
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${up('md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 768px)',
})
})
})

describe('#down', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${down(
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(max-width: 767.98px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${down('md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(max-width: 767.98px)',
})
})
})

describe('#between', () => {
it('should work with `css`', () => {
const Dummy = styled.div`
${between(
'sm',
'md',
css`
color: red;
`,
)}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 576px) and (max-width: 767.98px)',
})
})

it('should work with object style', () => {
const Dummy = styled.div`
${between('sm', 'md', { color: 'red' })}
`
const { container } = render(<Dummy />)
expect(container.firstChild).toHaveStyleRule('color', 'red', {
media: '(min-width: 576px) and (max-width: 767.98px)',
})
})
})
testBreakpoints({ styled, css })
7 changes: 7 additions & 0 deletions packages/system/tests/xstyled-emotion/breakpoints.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { matchers } from 'jest-emotion'
import styled, { css } from '@xstyled/emotion'
import { testBreakpoints } from '../common/breakpoints'

expect.extend(matchers)

testBreakpoints({ styled, css })
17 changes: 16 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,11 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"

"@types/jest@^23.0.2":
version "23.3.14"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a"
integrity sha512-Q5hTcfdudEL2yOmluA1zaSyPbzWPmJ3XfSWeP3RyoYvS9hnje1ZyagrZOuQ6+1nQC1Gw+7gap3pLNL3xL6UBug==

"@types/node@*", "@types/node@^12.0.8":
version "12.0.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.8.tgz#551466be11b2adc3f3d47156758f610bd9f6b1d8"
Expand Down Expand Up @@ -3481,7 +3486,7 @@ css.escape@^1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=

css@^2.2.3, css@^2.2.4:
css@^2.2.1, css@^2.2.3, css@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==
Expand Down Expand Up @@ -5562,6 +5567,16 @@ jest-each@^24.8.0:
jest-util "^24.8.0"
pretty-format "^24.8.0"

jest-emotion@^10.0.11:
version "10.0.11"
resolved "https://registry.yarnpkg.com/jest-emotion/-/jest-emotion-10.0.11.tgz#7d75e2675f36c4c8a30333e5b8e405f11c1a0638"
integrity sha512-gSlcRwDq5A6RCK+9vnQ3was3W3wTcQ1Jl+MbS6A4F9yvhT+YKHC4T1W7l+iqmGGNGiqFtJ7nXL6f0Q0En6o2ew==
dependencies:
"@babel/runtime" "^7.4.3"
"@types/jest" "^23.0.2"
chalk "^2.4.1"
css "^2.2.1"

jest-environment-jsdom@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857"
Expand Down

0 comments on commit e34d576

Please sign in to comment.