Skip to content

Commit

Permalink
<style> as a top-level component (#75)
Browse files Browse the repository at this point in the history
* <style> as a top-level component

* pass path to findStyles instead of its children
  • Loading branch information
giuseppeg authored and nkzawa committed Jan 18, 2017
1 parent 47dbd09 commit f251e1c
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 34 deletions.
53 changes: 30 additions & 23 deletions src/babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,30 @@ const STYLE_COMPONENT_ID = 'styleId'
const STYLE_COMPONENT_CSS = 'css'

export default function ({types: t}) {
const findStyles = children => (
children.filter(el => (
t.isJSXElement(el) &&
el.openingElement.name.name === 'style' &&
el.openingElement.attributes.some(attr => (
attr.name.name === STYLE_ATTRIBUTE
))
const isGlobalEl = el => el.attributes.some(attr => (
attr.name.name === GLOBAL_ATTRIBUTE
))

const isStyledJsx = ({node: el}) => (
t.isJSXElement(el) &&
el.openingElement.name.name === 'style' &&
el.openingElement.attributes.some(attr => (
attr.name.name === STYLE_ATTRIBUTE
))
)

const findStyles = path => {
if (isStyledJsx(path)) {
const {node} = path
return isGlobalEl(node.openingElement) ?
[node] : []
}

return path.get('children')
.filter(isStyledJsx)
.map(({node}) => node)
}

const getExpressionText = expr => (
t.isTemplateLiteral(expr) ?
expr.quasis[0].value.raw :
Expand Down Expand Up @@ -57,6 +71,9 @@ export default function ({types: t}) {
inherits: jsx,
visitor: {
JSXOpeningElement(path, state) {
const el = path.node
const {name} = el.name || {}

if (!state.hasJSXStyle) {
return
}
Expand All @@ -70,9 +87,6 @@ export default function ({types: t}) {
state.ignoreClosing = 0
}

const el = path.node
const {name} = el.name || {}

if (
name &&
name !== 'style' &&
Expand Down Expand Up @@ -102,7 +116,7 @@ export default function ({types: t}) {
return
}

const styles = findStyles(path.node.children)
const styles = findStyles(path)

if (styles.length === 0) {
return
Expand Down Expand Up @@ -158,27 +172,20 @@ export default function ({types: t}) {
// next visit will be: JSXOpeningElement
},
exit(path, state) {
if (state.hasJSXStyle && !--state.ignoreClosing) {
state.hasJSXStyle = null
}
const el = path.node.openingElement
const isGlobal = isGlobalEl(el)

if (!state.hasJSXStyle) {
return
if (state.hasJSXStyle && (!--state.ignoreClosing && !isGlobal)) {
state.hasJSXStyle = null
}

const el = path.node.openingElement

if (!el.name || el.name.name !== 'style') {
if (!state.hasJSXStyle || !el.name || el.name.name !== 'style') {
return
}

// we replace styles with the function call
const [id, css, loc] = state.styles.shift()

const isGlobal = el.attributes.some(attr => (
attr.name.name === GLOBAL_ATTRIBUTE
))

if (isGlobal) {
path.replaceWith(makeStyledJsxTag(id, css))
return
Expand Down
18 changes: 11 additions & 7 deletions test/fixtures/global.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<div>
<style jsx global>{`
body {
color: red
}
`}</style>
</div>
const Test = () => (
<div>
<style jsx global>{`
body {
color: red
}
`}</style>
</div>
)

const Test2 = () => <style global jsx>{'p { color: red }'}</style>
10 changes: 6 additions & 4 deletions test/fixtures/global.out.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import _JSXStyle from "styled-jsx/style";
<div data-jsx={3367785191}>
<_JSXStyle styleId={3367785191} css={"\n body {\n color: red\n }\n "} />
</div>;
import _JSXStyle from 'styled-jsx/style';
const Test = () => <div data-jsx={733744743}>
<_JSXStyle styleId={733744743} css={"\n body {\n color: red\n }\n "} />
</div>;

const Test2 = () => <_JSXStyle styleId={188072295} css={"p { color: red }"} />;
2 changes: 2 additions & 0 deletions test/fixtures/mixed-global-scoped.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const Test = () => <style global jsx>{'p { color: red }'}</style>

export default () => (
<div>
<p>test</p>
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/mixed-global-scoped.out.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import _JSXStyle from 'styled-jsx/style';
const Test = () => <_JSXStyle styleId={188072295} css={"p { color: red }"} />;

export default (() => <div data-jsx={793889750}>
<p data-jsx={793889750}>test</p>
<_JSXStyle styleId={3149549172} css={"body { background: red }"} />
Expand Down

0 comments on commit f251e1c

Please sign in to comment.