@twstyled/core
Version:
twstyled -- the full-featured Tailwind CSS + CSS in JS solution with blazing fast build times and no runtime overhead
115 lines (114 loc) • 5.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* This file contains an runtime version of `styled` component. Responsibilities of the component are:
* - returns ReactElement based on HTML tag used with `styled` or custom React Component
* - injects classNames for the returned component
* - injects CSS variables used to define dynamic styles based on props
*/
var react_1 = require("react");
var is_prop_valid_1 = __importDefault(require("@emotion/is-prop-valid"));
var clsx_1 = __importDefault(require("clsx"));
// Workaround for rest operator
var restOp = function (obj, keysToExclude) {
return Object.keys(obj)
.filter(function (prop) { return !keysToExclude.includes(prop); })
.reduce(function (acc, curr) {
var _a;
return Object.assign(acc, (_a = {}, _a[curr] = obj[curr], _a));
}, {});
}; // rest operator workaround
var warnIfInvalid = function (value, componentName) {
if (process.env.NODE_ENV !== 'production') {
if (typeof value === 'string' ||
// eslint-disable-next-line no-self-compare
(typeof value === 'number' && isFinite(value))) {
return;
}
var stringified = typeof value === 'object' ? JSON.stringify(value) : String(value);
// eslint-disable-next-line no-console
console.warn("An interpolation evaluated to '" + stringified + "' in the component '" + componentName + "', which is probably a mistake. You should explicitly cast or transform the value to a string.");
}
};
function styled(tag) {
return function (options) {
if (process.env.NODE_ENV !== 'production') {
if (Array.isArray(options)) {
// We received a strings array since it's used as a tag
throw new Error('Using the "styled" tag in runtime is not supported. Make sure you have set up the Babel plugin correctly. See https://github.com/callstack/linaria#setup');
}
}
var render = function (props, ref) {
var _a = props.as, component = _a === void 0 ? tag : _a, className = props.class;
var rest = restOp(props, ['as', 'class']);
var filteredProps;
// Check if it's an HTML tag and not a custom element
if (typeof component === 'string' && component.indexOf('-') === -1) {
filteredProps = {};
// eslint-disable-next-line guard-for-in
for (var key in rest) {
if (key === 'as' || is_prop_valid_1.default(key)) {
// Don't pass through invalid attributes to HTML elements
filteredProps[key] = rest[key];
}
}
}
else {
filteredProps = rest;
}
filteredProps.ref = ref;
var vars = options.vars, twvars = options.twvars;
var classnames = options.class;
if (vars) {
var style = {};
// eslint-disable-next-line guard-for-in
for (var name_1 in vars) {
var variable = vars[name_1];
var result = variable[0];
var value = typeof result === 'function' ? result(props) : result;
warnIfInvalid(value, options.name);
if (twvars && twvars.indexOf(name_1) !== -1) {
classnames += " " + value;
}
else {
var unit = variable[1] || '';
style["--" + name_1] = "" + value + unit;
}
}
filteredProps.style = Object.assign(style, filteredProps.style);
}
filteredProps.className = clsx_1.default(filteredProps.className || className, classnames);
if (tag.__linaria && tag !== component) {
// If the underlying tag is a styled component, forward the `as` prop
// Otherwise the styles from the underlying component will be ignored
filteredProps.as = component;
return react_1.createElement(tag, filteredProps);
}
return react_1.createElement(component, filteredProps);
};
var Result = react_1.forwardRef
? react_1.forwardRef(render)
: // React.forwardRef won't available on older React versions and in Preact
// Fallback to a innerRef prop in that case
function (props) {
var rest = restOp(props, ['innerRef']);
return render(rest, props.innerRef);
};
Result.displayName = options.name;
Result.__linaria = {
className: options.class,
extends: tag
};
return Result;
};
}
exports.default = (process.env.NODE_ENV !== 'production'
? new Proxy(styled, {
get: function (o, prop) {
return o(prop);
}
})
: styled);