Styled Component Base
by ordette
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/react-with-addons.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
CSS
body {
background: white;
margin: 0;
padding: 0;
}
Babel + JSX
const compileCss = (id, props, strings, ...fns) => {
let css = strings[0];
if (fns.length) {
const lastString = strings[strings.length - 1];
css = fns.reduce((str, fn, index) => {
str += strings[index];
if (typeof fn === 'function') {
str += fn(props);
} else {
str += fn;
}
return str;
}, '') + lastString;
}
return `.${id} { ${css} }`;
}
const genId = (() => {
let count = 0;
return type => `${type}${++count}`;
})();
const generateElement = (ElementType) => {
return (strings, ...fns) => {
return (props) => {
const id = genId(ElementType);
const cssJson = compileCss(id, props, strings, ...fns);
const style = document.createElement('style');
style.textContent = cssJson;
style.setAttribute('data-styles', id);
document.head.appendChild(style);
return (
<ElementType className={id} {...props}>{props.children}</ElementType>
);
}
};
}
const elementTypes = [
'a',
'abbr',
'address',
'area',
'article',
'aside',
'audio',
'b',
'base',
'bdi',
'bdo',
'big',
'blockquote',
'body',
'br',
'button',
'canvas',
'caption',
'cite',
'code',
'col',
'colgroup',
'data',
'datalist',
'dd',
'del',
'details',
'dfn',
'dialog',
'div',
'dl',
'dt',
'em',
'embed',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hgroup',
'hr',
'html',
'i',
'iframe',
'img',
'input',
'ins',
'kbd',
'keygen',
'label',
'legend',
'li',
'link',
'main',
'map',
'mark',
'menu',
'menuitem',
'meta',
'meter',
'nav',
'noscript',
'object',
'ol',
'optgroup',
'option',
'output',
'p',
'param',
'picture',
'pre',
'progress',
...