464 lines
13 KiB
JavaScript
464 lines
13 KiB
JavaScript
import { createContext, createElement, forwardRef, Component, Fragment } from 'react';
|
|
import createCache from '@emotion/cache';
|
|
import { getRegisteredStyles, insertStyles } from '@emotion/utils';
|
|
import { serializeStyles } from '@emotion/serialize';
|
|
import { StyleSheet } from '@emotion/sheet';
|
|
import css from '@emotion/css';
|
|
export { default as css } from '@emotion/css';
|
|
|
|
function _inheritsLoose(subClass, superClass) {
|
|
subClass.prototype = Object.create(superClass.prototype);
|
|
subClass.prototype.constructor = subClass;
|
|
subClass.__proto__ = superClass;
|
|
}
|
|
|
|
var isBrowser = typeof document !== 'undefined';
|
|
|
|
var EmotionCacheContext = createContext(isBrowser ? createCache() : null);
|
|
var ThemeContext = createContext({});
|
|
var CacheProvider = EmotionCacheContext.Provider;
|
|
|
|
var withEmotionCache = function withEmotionCache(func) {
|
|
var render = function render(props, ref) {
|
|
return createElement(EmotionCacheContext.Consumer, null, function ( // $FlowFixMe we know it won't be null
|
|
cache) {
|
|
return func(props, cache, ref);
|
|
});
|
|
}; // $FlowFixMe
|
|
|
|
|
|
return forwardRef(render);
|
|
};
|
|
|
|
if (!isBrowser) {
|
|
var BasicProvider =
|
|
/*#__PURE__*/
|
|
function (_React$Component) {
|
|
_inheritsLoose(BasicProvider, _React$Component);
|
|
|
|
function BasicProvider(props, context, updater) {
|
|
var _this;
|
|
|
|
_this = _React$Component.call(this, props, context, updater) || this;
|
|
_this.state = {
|
|
value: createCache()
|
|
};
|
|
return _this;
|
|
}
|
|
|
|
var _proto = BasicProvider.prototype;
|
|
|
|
_proto.render = function render() {
|
|
return createElement(EmotionCacheContext.Provider, this.state, this.props.children(this.state.value));
|
|
};
|
|
|
|
return BasicProvider;
|
|
}(Component);
|
|
|
|
withEmotionCache = function withEmotionCache(func) {
|
|
return function (props) {
|
|
return createElement(EmotionCacheContext.Consumer, null, function (context) {
|
|
if (context === null) {
|
|
return createElement(BasicProvider, null, function (newContext) {
|
|
return func(props, newContext);
|
|
});
|
|
} else {
|
|
return func(props, context);
|
|
}
|
|
});
|
|
};
|
|
};
|
|
}
|
|
|
|
var typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__';
|
|
var labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__';
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
|
var render = function render(cache, props, theme, ref) {
|
|
var type = props[typePropName];
|
|
var registeredStyles = [];
|
|
var className = '';
|
|
var cssProp = theme === null ? props.css : props.css(theme); // so that using `css` from `emotion` and passing the result to the css prop works
|
|
// not passing the registered cache to serializeStyles because it would
|
|
// make certain babel optimisations not possible
|
|
|
|
if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) {
|
|
cssProp = cache.registered[cssProp];
|
|
}
|
|
|
|
registeredStyles.push(cssProp);
|
|
|
|
if (props.className !== undefined) {
|
|
className = getRegisteredStyles(cache.registered, registeredStyles, props.className);
|
|
}
|
|
|
|
var serialized = serializeStyles(registeredStyles);
|
|
|
|
if (process.env.NODE_ENV !== 'production' && serialized.name.indexOf('-') === -1) {
|
|
var labelFromStack = props[labelPropName];
|
|
|
|
if (labelFromStack) {
|
|
serialized = serializeStyles([serialized, 'label:' + labelFromStack + ';']);
|
|
}
|
|
}
|
|
|
|
var rules = insertStyles(cache, serialized, typeof type === 'string');
|
|
className += cache.key + "-" + serialized.name;
|
|
var newProps = {};
|
|
|
|
for (var key in props) {
|
|
if (hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && (process.env.NODE_ENV === 'production' || key !== labelPropName)) {
|
|
newProps[key] = props[key];
|
|
}
|
|
}
|
|
|
|
newProps.ref = ref;
|
|
newProps.className = className;
|
|
var ele = createElement(type, newProps);
|
|
|
|
if (!isBrowser && rules !== undefined) {
|
|
var _ref;
|
|
|
|
var serializedNames = serialized.name;
|
|
var next = serialized.next;
|
|
|
|
while (next !== undefined) {
|
|
serializedNames += ' ' + next.name;
|
|
next = next.next;
|
|
}
|
|
|
|
return createElement(Fragment, null, createElement("style", (_ref = {}, _ref["data-emotion-" + cache.key] = serializedNames, _ref.dangerouslySetInnerHTML = {
|
|
__html: rules
|
|
}, _ref.nonce = cache.sheet.nonce, _ref)), ele);
|
|
}
|
|
|
|
return ele;
|
|
};
|
|
|
|
var Emotion = withEmotionCache(function (props, cache, ref) {
|
|
// use Context.read for the theme when it's stable
|
|
if (typeof props.css === 'function') {
|
|
return createElement(ThemeContext.Consumer, null, function (theme) {
|
|
return render(cache, props, theme, ref);
|
|
});
|
|
}
|
|
|
|
return render(cache, props, null, ref);
|
|
}); // $FlowFixMe
|
|
|
|
var jsx = function jsx(type, props) {
|
|
var args = arguments;
|
|
|
|
if (props == null || props.css == null) {
|
|
// $FlowFixMe
|
|
return createElement.apply(undefined, args);
|
|
}
|
|
|
|
if (process.env.NODE_ENV !== 'production' && typeof props.css === 'string' && // check if there is a css declaration
|
|
props.css.indexOf(':') !== -1) {
|
|
throw new Error("Strings are not allowed as css prop values, please wrap it in a css template literal from '@emotion/css' like this: css`" + props.css + "`");
|
|
}
|
|
|
|
var argsLength = args.length;
|
|
var createElementArgArray = new Array(argsLength);
|
|
createElementArgArray[0] = Emotion;
|
|
var newProps = {};
|
|
|
|
for (var key in props) {
|
|
if (hasOwnProperty.call(props, key)) {
|
|
newProps[key] = props[key];
|
|
}
|
|
}
|
|
|
|
newProps[typePropName] = type;
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
var error = new Error();
|
|
|
|
if (error.stack) {
|
|
// chrome
|
|
var match = error.stack.match(/at jsx.*\n\s+at ([A-Z][A-Za-z]+) /);
|
|
|
|
if (!match) {
|
|
// safari and firefox
|
|
match = error.stack.match(/^.*\n([A-Z][A-Za-z]+)@/);
|
|
}
|
|
|
|
if (match) {
|
|
newProps[labelPropName] = match[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
createElementArgArray[1] = newProps;
|
|
|
|
for (var i = 2; i < argsLength; i++) {
|
|
createElementArgArray[i] = args[i];
|
|
} // $FlowFixMe
|
|
|
|
|
|
return createElement.apply(null, createElementArgArray);
|
|
};
|
|
|
|
var warnedAboutCssPropForGlobal = false;
|
|
var Global =
|
|
/* #__PURE__ */
|
|
withEmotionCache(function (props, cache) {
|
|
if (process.env.NODE_ENV !== 'production' && !warnedAboutCssPropForGlobal && ( // check for className as well since the user is
|
|
// probably using the custom createElement which
|
|
// means it will be turned into a className prop
|
|
// $FlowFixMe I don't really want to add it to the type since it shouldn't be used
|
|
props.className || props.css)) {
|
|
console.error("It looks like you're using the css prop on Global, did you mean to use the styles prop instead?");
|
|
warnedAboutCssPropForGlobal = true;
|
|
}
|
|
|
|
var styles = props.styles;
|
|
|
|
if (typeof styles === 'function') {
|
|
return createElement(ThemeContext.Consumer, null, function (theme) {
|
|
var serialized = serializeStyles([styles(theme)]);
|
|
return createElement(InnerGlobal, {
|
|
serialized: serialized,
|
|
cache: cache
|
|
});
|
|
});
|
|
}
|
|
|
|
var serialized = serializeStyles([styles]);
|
|
return createElement(InnerGlobal, {
|
|
serialized: serialized,
|
|
cache: cache
|
|
});
|
|
});
|
|
|
|
// maintain place over rerenders.
|
|
// initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn't been inserted there yet, appendChild
|
|
// initial client-side render from SSR, use place of hydrating tag
|
|
var InnerGlobal =
|
|
/*#__PURE__*/
|
|
function (_React$Component) {
|
|
_inheritsLoose(InnerGlobal, _React$Component);
|
|
|
|
function InnerGlobal(props, context, updater) {
|
|
return _React$Component.call(this, props, context, updater) || this;
|
|
}
|
|
|
|
var _proto = InnerGlobal.prototype;
|
|
|
|
_proto.componentDidMount = function componentDidMount() {
|
|
this.sheet = new StyleSheet({
|
|
key: this.props.cache.key + "-global",
|
|
nonce: this.props.cache.sheet.nonce,
|
|
container: this.props.cache.sheet.container
|
|
}); // $FlowFixMe
|
|
|
|
var node = document.querySelector("style[data-emotion-" + this.props.cache.key + "=\"" + this.props.serialized.name + "\"]");
|
|
|
|
if (node !== null) {
|
|
this.sheet.tags.push(node);
|
|
}
|
|
|
|
if (this.props.cache.sheet.tags.length) {
|
|
this.sheet.before = this.props.cache.sheet.tags[0];
|
|
}
|
|
|
|
this.insertStyles();
|
|
};
|
|
|
|
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
|
|
if (prevProps.serialized.name !== this.props.serialized.name) {
|
|
this.insertStyles();
|
|
}
|
|
};
|
|
|
|
_proto.insertStyles = function insertStyles$$1() {
|
|
if (this.props.serialized.next !== undefined) {
|
|
// insert keyframes
|
|
insertStyles(this.props.cache, this.props.serialized.next, true);
|
|
}
|
|
|
|
if (this.sheet.tags.length) {
|
|
// if this doesn't exist then it will be null so the style element will be appended
|
|
var element = this.sheet.tags[this.sheet.tags.length - 1].nextElementSibling;
|
|
this.sheet.before = element;
|
|
this.sheet.flush();
|
|
}
|
|
|
|
this.props.cache.insert("", this.props.serialized, this.sheet, false);
|
|
};
|
|
|
|
_proto.componentWillUnmount = function componentWillUnmount() {
|
|
this.sheet.flush();
|
|
};
|
|
|
|
_proto.render = function render() {
|
|
if (!isBrowser) {
|
|
var _ref;
|
|
|
|
var serialized = this.props.serialized;
|
|
var serializedNames = serialized.name;
|
|
var serializedStyles = serialized.styles;
|
|
var next = serialized.next;
|
|
|
|
while (next !== undefined) {
|
|
serializedNames += ' ' + next.name;
|
|
serializedStyles += next.styles;
|
|
next = next.next;
|
|
}
|
|
|
|
var rules = this.props.cache.insert("", {
|
|
name: serializedNames,
|
|
styles: serializedStyles
|
|
}, this.sheet, false);
|
|
return createElement("style", (_ref = {}, _ref["data-emotion-" + this.props.cache.key] = serializedNames, _ref.dangerouslySetInnerHTML = {
|
|
__html: rules
|
|
}, _ref.nonce = this.props.cache.sheet.nonce, _ref));
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
return InnerGlobal;
|
|
}(Component);
|
|
|
|
var keyframes = function keyframes() {
|
|
var insertable = css.apply(void 0, arguments);
|
|
var name = "animation-" + insertable.name; // $FlowFixMe
|
|
|
|
return {
|
|
name: name,
|
|
styles: "@keyframes " + name + "{" + insertable.styles + "}",
|
|
anim: 1,
|
|
toString: function toString() {
|
|
return "_EMO_" + this.name + "_" + this.styles + "_EMO_";
|
|
}
|
|
};
|
|
};
|
|
|
|
var classnames = function classnames(args) {
|
|
var len = args.length;
|
|
var i = 0;
|
|
var cls = '';
|
|
|
|
for (; i < len; i++) {
|
|
var arg = args[i];
|
|
if (arg == null) continue;
|
|
var toAdd = void 0;
|
|
|
|
switch (typeof arg) {
|
|
case 'boolean':
|
|
break;
|
|
|
|
case 'object':
|
|
{
|
|
if (Array.isArray(arg)) {
|
|
toAdd = classnames(arg);
|
|
} else {
|
|
toAdd = '';
|
|
|
|
for (var k in arg) {
|
|
if (arg[k] && k) {
|
|
toAdd && (toAdd += ' ');
|
|
toAdd += k;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
toAdd = arg;
|
|
}
|
|
}
|
|
|
|
if (toAdd) {
|
|
cls && (cls += ' ');
|
|
cls += toAdd;
|
|
}
|
|
}
|
|
|
|
return cls;
|
|
};
|
|
|
|
function merge(registered, css$$1, className) {
|
|
var registeredStyles = [];
|
|
var rawClassName = getRegisteredStyles(registered, registeredStyles, className);
|
|
|
|
if (registeredStyles.length < 2) {
|
|
return className;
|
|
}
|
|
|
|
return rawClassName + css$$1(registeredStyles);
|
|
}
|
|
|
|
var ClassNames = withEmotionCache(function (props, context) {
|
|
return createElement(ThemeContext.Consumer, null, function (theme) {
|
|
var rules = '';
|
|
var serializedHashes = '';
|
|
var hasRendered = false;
|
|
|
|
var css$$1 = function css$$1() {
|
|
if (hasRendered && process.env.NODE_ENV !== 'production') {
|
|
throw new Error('css can only be used during render');
|
|
}
|
|
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
var serialized = serializeStyles(args, context.registered);
|
|
|
|
if (isBrowser) {
|
|
insertStyles(context, serialized, false);
|
|
} else {
|
|
var res = insertStyles(context, serialized, false);
|
|
|
|
if (res !== undefined) {
|
|
rules += res;
|
|
}
|
|
}
|
|
|
|
if (!isBrowser) {
|
|
serializedHashes += " " + serialized.name;
|
|
}
|
|
|
|
return context.key + "-" + serialized.name;
|
|
};
|
|
|
|
var cx = function cx() {
|
|
if (hasRendered && process.env.NODE_ENV !== 'production') {
|
|
throw new Error('cx can only be used during render');
|
|
}
|
|
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
args[_key2] = arguments[_key2];
|
|
}
|
|
|
|
return merge(context.registered, css$$1, classnames(args));
|
|
};
|
|
|
|
var content = {
|
|
css: css$$1,
|
|
cx: cx,
|
|
theme: theme
|
|
};
|
|
var ele = props.children(content);
|
|
hasRendered = true;
|
|
|
|
if (!isBrowser && rules.length !== 0) {
|
|
var _ref;
|
|
|
|
return createElement(Fragment, null, createElement("style", (_ref = {}, _ref["data-emotion-" + context.key] = serializedHashes.substring(1), _ref.dangerouslySetInnerHTML = {
|
|
__html: rules
|
|
}, _ref.nonce = context.sheet.nonce, _ref)), ele);
|
|
}
|
|
|
|
return ele;
|
|
});
|
|
});
|
|
|
|
export { withEmotionCache, CacheProvider, ThemeContext, jsx, Global, keyframes, ClassNames };
|