Skip to content

Instantly share code, notes, and snippets.

@dburles
Created December 20, 2019 02:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dburles/4c8b53ae09408f7d34297ec7a8fd2e43 to your computer and use it in GitHub Desktop.
Save dburles/4c8b53ae09408f7d34297ec7a8fd2e43 to your computer and use it in GitHub Desktop.
import React, { useRef, useEffect, useState, useLayoutEffect } from 'react';
let globalIdentifier = 0;
const camelDash = string =>
string.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`);
const construct = object =>
Object.keys(object)
.map(key => `${camelDash(key)}:${object[key]};`)
.join('');
const Wrapper = ({ css, children }) => {
const styleElementRef = useRef();
const [className, setClassName] = useState();
useLayoutEffect(() => {
setClassName(`x${Date.now()}-${globalIdentifier}`);
globalIdentifier += 1;
}, []);
useLayoutEffect(() => {
if (className) {
const style = `.${className}{${construct(css)}}`;
styleElementRef.current.innerHTML = style;
}
}, [className, css]);
useEffect(() => {
styleElementRef.current = document.createElement('style');
document.head.appendChild(styleElementRef.current);
return () => {
styleElementRef.current.remove();
};
}, []);
return React.cloneElement(children, {
className:
children && children.props.className
? `${children.props.className} ${className}`
: className,
});
};
export const jsx = (type, props, ...children) => {
const { css, ...rest } = props || {};
const element = React.createElement(type, rest, ...children);
return css ? React.createElement(Wrapper, { css }, element) : element;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment