Skip to content

Instantly share code, notes, and snippets.

@dburles
Last active April 2, 2020 05:07
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/56cf8af6fc8171c46216e540013193ce to your computer and use it in GitHub Desktop.
Save dburles/56cf8af6fc8171c46216e540013193ce to your computer and use it in GitHub Desktop.
import hashSum from 'hash-sum';
import React from 'react';
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 rules = Object.create(null);
const element = document.createElement('style');
document.head.appendChild(element);
const mountStyle = (className, css) => {
if (rules[className] === undefined) {
rules[className] = { count: 0 };
}
if (rules[className].count === 0) {
element.sheet.insertRule(
`.${className}{${construct(css)}}`,
element.sheet.cssRules.length,
);
}
rules[className].count += 1;
};
const unmountStyle = (className) => {
rules[className].count -= 1;
if (rules[className].count === 0) {
const index = Object.keys(element.sheet.cssRules).findIndex(
(key) => element.sheet.cssRules[key].selectorText === '.' + className,
);
element.sheet.deleteRule(index);
delete rules[className];
}
};
const Wrapper = ({ css, children }) => {
const hash = hashSum(css);
const className = 's' + hash;
React.useLayoutEffect(() => {
mountStyle(className, css);
return () => {
unmountStyle(className);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [className]);
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