Skip to content

Commit

Permalink
Better way to detect dynamic styles (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
a-ignatov-parc authored and giuseppeg committed Feb 4, 2018
1 parent a6aaa73 commit d018577
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,24 @@ export const validateExpressionVisitor = {
return
}

if (scope.hasOwnBinding(name) || path.scope.hasOwnBinding(name)) {
let targetScope = path.scope
let isDynamicBinding = false

// Traversing scope chain in order to find current variable.
// If variable has no parent scope and it's `const` then we can interp. it
// as static in order to optimize styles.
// `let` and `var` can be changed during runtime.
while (targetScope) {
if (targetScope.hasOwnBinding(name)) {
const binding = targetScope.bindings[name]
isDynamicBinding =
binding.scope.parent !== null || binding.kind !== 'const'
break
}
targetScope = targetScope.parent
}

if (isDynamicBinding) {
throw path.buildCodeFrameError(
`Expected \`${name}\` ` +
`to not come from the closest scope.\n` +
Expand Down
12 changes: 11 additions & 1 deletion test/__snapshots__/attribute.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,17 @@ const foo = 'red';
export const Test10 = () => <div className={\\"jsx-461505126\\"}>
<p className={\\"jsx-461505126\\"}>dynamic with constant variable</p>
<_JSXStyle styleId={\\"461505126\\"} css={\`p.jsx-461505126{color:\${foo};}\`} />
</div>;"
</div>;
// dynamic with complex scope
export const Test11 = ({ color }) => {
const items = Array.from({ length: 5 }).map((item, i) => <li key={i} className={_JSXStyle.dynamic([['2172653867', [color]]]) + ' ' + 'item'}>
<_JSXStyle styleId={\\"2172653867\\"} css={\`.item.__jsx-style-dynamic-selector{color:\${color};}\`} dynamic={[color]} />
Item #{i + 1}
</li>);
return <ul className=\\"items\\">{items}</ul>;
};"
`;
exports[`rewrites className 1`] = `
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/attribute-generation-modes.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,19 @@ export const Test10 = () => (
`}</style>
</div>
)

// dynamic with complex scope
export const Test11 = ({ color }) => {
const items = Array.from({ length: 5 }).map((item, i) => (
<li className="item" key={i}>
<style jsx>{`
.item {
color: ${color};
}
`}</style>
Item #{i + 1}
</li>
))

return <ul className="items">{items}</ul>
}

0 comments on commit d018577

Please sign in to comment.