Skip to content

Commit

Permalink
Merge pull request #1 from tkh44/add-glamor
Browse files Browse the repository at this point in the history
Add glamor
  • Loading branch information
Kye Hohenberger authored May 28, 2017
2 parents 2b29d5f + 0f44f10 commit a05ae1a
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,31 @@ const Name = ({ color, name }) => <h1 className={css`color: ${color};`}>{name}</

**Similar to importing React when using jsx, `import css from 'glam'` must be at the top of your source files.**

## `emotion/glamor`

```bash
npm install -S glamor
```

**.babelrc**
```json
{
"plugins": [
"emotion/glamor",
]
}
```

```jsx harmony
const Name = ({ color, name }) => <h1 css={{ color: 'red' }}>{name}</h1>
```

is converted to

```jsx harmony
const Name = ({ color, name }) => <h1 {...css({color: 'red' })}>{name}</h1>
```


**Similar to importing React when using jsx, `import {css} from 'glamor'` must be at the top of your source files.**

1 change: 1 addition & 0 deletions glamor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/glamor/babel')
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"glam": "^4.0.3",
"glamor": "^2.20.25",
"jest": "^20.0.1",
"jest-glamor-react": "^1.3.0",
"react": "^15.5.4",
Expand Down
10 changes: 10 additions & 0 deletions src/glamor/__tests__/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"presets": [
"env",
"stage-0",
"react"
],
"plugins": [
["../babel.js"],
]
}
91 changes: 91 additions & 0 deletions src/glamor/__tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`emotion/glamor babel basic 1`] = `"<div className=\\"a\\" {...css({ color: 'brown' })}></div>;"`;

exports[`emotion/glamor babel className as expression 1`] = `"<div className={props.className} {...css({ color: 'brown' })}></div>;"`;

exports[`emotion/glamor babel className as expression string 1`] = `"<div className={\`test__class\`} {...css({ color: 'brown' })} this={\`hello\`}></div>;"`;
exports[`emotion/glamor babel css empty 1`] = `"<div {...css({})}></div>;"`;
exports[`emotion/glamor babel emptyClassName 1`] = `"<div className=\\"\\" {...css({ color: 'brown' })}></div>;"`;
exports[`emotion/glamor babel no className 1`] = `"<div {...css({ color: 'brown' })}></div>;"`;
exports[`emotion/glamor babel no css attr 1`] = `"<div></div>;"`;
exports[`emotion/glamor babel wrong value type 1`] = `"<div {...css(5)}></div>;"`;
exports[`emotion/glamor real basic 1`] = `
.css-1ezp9xe,
[data-css-1ezp9xe] {
color: red;
}
<p
data-css-1ezp9xe=""
>
hello world
</p>
`;
exports[`emotion/glamor real kitchen sink 1`] = `
.css-icjsl7,
[data-css-icjsl7] {
color: blue;
}
.css-gvvg5g,
[data-css-gvvg5g] {
color: gray;
}
.css-16ywyew,
[data-css-16ywyew] {
border: 1px solid blue;
}
.css-1cqgl9p,
[data-css-1cqgl9p] {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@media (min-width: 420px) {
.css-198yaui,
[data-css-198yaui] {
font-size: 48px;
}
}
<div
className="css__legacy-stuff"
data-css-icjsl7=""
>
<h1
data-css-198yaui=""
>
BOOM
</h1>
<p
className="test_class1"
data-css-gvvg5g=""
>
Hello
</p>
<p
className="test_class1 test___class45"
data-css-16ywyew=""
>
World
</p>
<p
data-css-1cqgl9p=""
>
hello world
</p>
</div>
`;
104 changes: 104 additions & 0 deletions src/glamor/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* eslint-disable jsx-quotes,no-useless-escape */
/* eslint-env jest */
import React from 'react'
import renderer from 'react-test-renderer'
import plugin from '../babel'
import { matcher, serializer } from 'jest-glamor-react'
import { css } from 'glamor'

expect.addSnapshotSerializer(serializer)
expect.extend(matcher)

const babel = require('babel-core')

describe('emotion/glamor', () => {
describe('babel', () => {
test('basic', () => {
const basic = `(<div className="a" css={{ color: 'brown' }}></div>)`
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('no css attr', () => {
const basic = '(<div></div>)'
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('css empty', () => {
const basic = '(<div css={{}}></div>)'
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('wrong value type', () => {
const basic = '(<div css={5}></div>)'
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('no className', () => {
const basic = `(<div css={{ color: 'brown' }}></div>)`
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('emptyClassName', () => {
const basic = `(<div className="" css={{ color: 'brown' }}></div>)`
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('className as expression', () => {
const basic = `(<div className={props.className} css={{ color: 'brown' }}></div>)`
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})

test('className as expression string', () => {
const basic =
"(<div className={`test__class\`} css={{ color: 'brown'}} this={`hello\`}></div>)"
const {code} = babel.transform(basic, {plugins: [plugin]})
expect(code).toMatchSnapshot()
})
})

describe('real', () => {
test('basic', () => {
const tree = renderer
.create(
<p css={{color: 'red'}}>
hello world
</p>
)
.toJSON()

expect(tree).toMatchSnapshotWithGlamor()
})

test('kitchen sink', () => {
const tree = renderer
.create(
<div className="css__legacy-stuff" css={{color: 'blue'}}>
<h1 css={{'@media(min-width: 420px)': {fontSize: 48}}}>
BOOM
</h1>
<p className="test_class1" css={{color: 'gray'}}>Hello</p>
<p
className="test_class1 test___class45"
css={{border: '1px solid blue'}}
>
World
</p>
<p css={{display: 'flex'}}>
hello world
</p>

</div>
)
.toJSON()

expect(tree).toMatchSnapshotWithGlamor()
})
})
})
37 changes: 37 additions & 0 deletions src/glamor/babel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module.exports = function (babel) {
const {types: t} = babel

return {
name: 'emotion-for-glam', // not required
inherits: require('babel-plugin-syntax-jsx'),
visitor: {
JSXOpeningElement (path, state) {
let cssPath

path.get('attributes').forEach(openElPath => {
const attrPath = openElPath.get('name')
const name = attrPath.node.name

if (name === 'css') {
cssPath = attrPath
}
})

if (!cssPath) return

let cssPropValue = cssPath.container && cssPath.container.value

if (t.isJSXExpressionContainer(cssPropValue)) {
cssPropValue = cssPropValue.expression
}

let glamorCssFunction = t.callExpression(t.identifier('css'), [
cssPropValue
])

cssPath.parentPath.insertAfter(t.jSXSpreadAttribute(glamorCssFunction))
cssPath.parentPath.remove()
}
}
}
}

0 comments on commit a05ae1a

Please sign in to comment.