Skip to content

Instantly share code, notes, and snippets.

@joshblack
Created September 30, 2015 20:43
Show Gist options
  • Save joshblack/c3fe30dc6f07b9dfe63c to your computer and use it in GitHub Desktop.
Save joshblack/c3fe30dc6f07b9dfe63c to your computer and use it in GitHub Desktop.
window.styles = [];
window.formatStyles = function () {
return styles.map(({ className, properties }) => {
const props = properties.map(
(prop) => `${prop.key.name}: ${prop.value.value};`).join('\n');
return '.' + className + ' {' + '\n' + props + '\n}\n';
}).join('\n');
};
export default function ({Plugin, types: t}) {
return new Plugin('ast-transform', {
visitor: {
JSXAttribute(node, parent) {
exit: {
if (node.name.name === 'style') {
const className = parent.name.name.toLowerCase();
styles.push({ className, properties: node.value.expression.properties });
return t.JSXAttribute(t.identifier('className'), t.literal(className));
}
}
}
}
});
}
window.styles = [];
window.formatStyles = function () {
return styles.map(({ className, properties }) => {
const props = Object.keys(properties).map(
(prop) => `${prop}: ${properties[prop]};`).join('\n');
return '.' + className + ' {' + '\n' + props + '\n}\n';
}).join('\n');
};
function getStyle(t, path) {
return path.get('properties').reduce((acc, prop) => {
const key = prop.toComputedKey();
const value = prop.get('value').resolve();
return {
...acc,
[key.value]: value.node.value
};
}, {});
}
export default function ({Plugin, types: t}) {
return new Plugin('ast-transform', {
metadata: { group: 'builtin-pre' },
visitor: {
JSXAttribute(node, parent, scope) {
enter: {
if (node.name.name === 'style') {
// parent.name.name.toLowerCase() + '__' + is the name of the JSX Element
const className = scope.path.scope.parent.block.id.name + '__' + node.value.expression.property.name;
styles.push({ className, properties: getStyle(t, this.get('value.expression').resolve(true)) });
return t.JSXAttribute(t.identifier('className'), t.literal(className));
}
}
}
}
});
}
class Foo extends React.Component {
render() {
return (
<Foobar style={styles.container}>
<Title style={styles.title}>Hello World</Title>
</Foobar>
);
}
}
class Bar extends React.Component {
render() {
return <Button style={styles.button} />;
}
}
var styles = {
container: {
background: 'black',
color: 'white'
},
title: {
fontSize: 12
},
button: {
border: '1px solid black'
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment