You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
14 KiB
JavaScript
329 lines
14 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = createStyled;
|
|
exports.shouldForwardProp = shouldForwardProp;
|
|
exports.systemDefaultTheme = void 0;
|
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
var _styledEngine = _interopRequireWildcard(require("@mui/styled-engine"));
|
|
var _utils = require("@mui/utils");
|
|
var _createTheme = _interopRequireDefault(require("./createTheme"));
|
|
var _propsToClassKey = _interopRequireDefault(require("./propsToClassKey"));
|
|
var _styleFunctionSx = _interopRequireDefault(require("./styleFunctionSx"));
|
|
const _excluded = ["name", "slot", "skipVariantsResolver", "skipSx", "overridesResolver"];
|
|
/* eslint-disable no-underscore-dangle */
|
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
function isEmpty(obj) {
|
|
return Object.keys(obj).length === 0;
|
|
}
|
|
|
|
// https://github.com/emotion-js/emotion/blob/26ded6109fcd8ca9875cc2ce4564fee678a3f3c5/packages/styled/src/utils.js#L40
|
|
function isStringTag(tag) {
|
|
return typeof tag === 'string' &&
|
|
// 96 is one less than the char code
|
|
// for "a" so this is checking that
|
|
// it's a lowercase character
|
|
tag.charCodeAt(0) > 96;
|
|
}
|
|
const getStyleOverrides = (name, theme) => {
|
|
if (theme.components && theme.components[name] && theme.components[name].styleOverrides) {
|
|
return theme.components[name].styleOverrides;
|
|
}
|
|
return null;
|
|
};
|
|
const transformVariants = variants => {
|
|
let numOfCallbacks = 0;
|
|
const variantsStyles = {};
|
|
if (variants) {
|
|
variants.forEach(definition => {
|
|
let key = '';
|
|
if (typeof definition.props === 'function') {
|
|
key = `callback${numOfCallbacks}`;
|
|
numOfCallbacks += 1;
|
|
} else {
|
|
key = (0, _propsToClassKey.default)(definition.props);
|
|
}
|
|
variantsStyles[key] = definition.style;
|
|
});
|
|
}
|
|
return variantsStyles;
|
|
};
|
|
const getVariantStyles = (name, theme) => {
|
|
let variants = [];
|
|
if (theme && theme.components && theme.components[name] && theme.components[name].variants) {
|
|
variants = theme.components[name].variants;
|
|
}
|
|
return transformVariants(variants);
|
|
};
|
|
const variantsResolver = (props, styles, variants) => {
|
|
const {
|
|
ownerState = {}
|
|
} = props;
|
|
const variantsStyles = [];
|
|
let numOfCallbacks = 0;
|
|
if (variants) {
|
|
variants.forEach(variant => {
|
|
let isMatch = true;
|
|
if (typeof variant.props === 'function') {
|
|
const propsToCheck = (0, _extends2.default)({}, props, ownerState);
|
|
isMatch = variant.props(propsToCheck);
|
|
} else {
|
|
Object.keys(variant.props).forEach(key => {
|
|
if (ownerState[key] !== variant.props[key] && props[key] !== variant.props[key]) {
|
|
isMatch = false;
|
|
}
|
|
});
|
|
}
|
|
if (isMatch) {
|
|
if (typeof variant.props === 'function') {
|
|
variantsStyles.push(styles[`callback${numOfCallbacks}`]);
|
|
} else {
|
|
variantsStyles.push(styles[(0, _propsToClassKey.default)(variant.props)]);
|
|
}
|
|
}
|
|
if (typeof variant.props === 'function') {
|
|
numOfCallbacks += 1;
|
|
}
|
|
});
|
|
}
|
|
return variantsStyles;
|
|
};
|
|
const themeVariantsResolver = (props, styles, theme, name) => {
|
|
var _theme$components;
|
|
const themeVariants = theme == null || (_theme$components = theme.components) == null || (_theme$components = _theme$components[name]) == null ? void 0 : _theme$components.variants;
|
|
return variantsResolver(props, styles, themeVariants);
|
|
};
|
|
|
|
// Update /system/styled/#api in case if this changes
|
|
function shouldForwardProp(prop) {
|
|
return prop !== 'ownerState' && prop !== 'theme' && prop !== 'sx' && prop !== 'as';
|
|
}
|
|
const systemDefaultTheme = exports.systemDefaultTheme = (0, _createTheme.default)();
|
|
const lowercaseFirstLetter = string => {
|
|
if (!string) {
|
|
return string;
|
|
}
|
|
return string.charAt(0).toLowerCase() + string.slice(1);
|
|
};
|
|
function resolveTheme({
|
|
defaultTheme,
|
|
theme,
|
|
themeId
|
|
}) {
|
|
return isEmpty(theme) ? defaultTheme : theme[themeId] || theme;
|
|
}
|
|
function defaultOverridesResolver(slot) {
|
|
if (!slot) {
|
|
return null;
|
|
}
|
|
return (props, styles) => styles[slot];
|
|
}
|
|
const muiStyledFunctionResolver = ({
|
|
styledArg,
|
|
props,
|
|
defaultTheme,
|
|
themeId
|
|
}) => {
|
|
const resolvedStyles = styledArg((0, _extends2.default)({}, props, {
|
|
theme: resolveTheme((0, _extends2.default)({}, props, {
|
|
defaultTheme,
|
|
themeId
|
|
}))
|
|
}));
|
|
let optionalVariants;
|
|
if (resolvedStyles && resolvedStyles.variants) {
|
|
optionalVariants = resolvedStyles.variants;
|
|
delete resolvedStyles.variants;
|
|
}
|
|
if (optionalVariants) {
|
|
const variantsStyles = variantsResolver(props, transformVariants(optionalVariants), optionalVariants);
|
|
return [resolvedStyles, ...variantsStyles];
|
|
}
|
|
return resolvedStyles;
|
|
};
|
|
function createStyled(input = {}) {
|
|
const {
|
|
themeId,
|
|
defaultTheme = systemDefaultTheme,
|
|
rootShouldForwardProp = shouldForwardProp,
|
|
slotShouldForwardProp = shouldForwardProp
|
|
} = input;
|
|
const systemSx = props => {
|
|
return (0, _styleFunctionSx.default)((0, _extends2.default)({}, props, {
|
|
theme: resolveTheme((0, _extends2.default)({}, props, {
|
|
defaultTheme,
|
|
themeId
|
|
}))
|
|
}));
|
|
};
|
|
systemSx.__mui_systemSx = true;
|
|
return (tag, inputOptions = {}) => {
|
|
// Filter out the `sx` style function from the previous styled component to prevent unnecessary styles generated by the composite components.
|
|
(0, _styledEngine.internal_processStyles)(tag, styles => styles.filter(style => !(style != null && style.__mui_systemSx)));
|
|
const {
|
|
name: componentName,
|
|
slot: componentSlot,
|
|
skipVariantsResolver: inputSkipVariantsResolver,
|
|
skipSx: inputSkipSx,
|
|
// TODO v6: remove `lowercaseFirstLetter()` in the next major release
|
|
// For more details: https://github.com/mui/material-ui/pull/37908
|
|
overridesResolver = defaultOverridesResolver(lowercaseFirstLetter(componentSlot))
|
|
} = inputOptions,
|
|
options = (0, _objectWithoutPropertiesLoose2.default)(inputOptions, _excluded);
|
|
|
|
// if skipVariantsResolver option is defined, take the value, otherwise, true for root and false for other slots.
|
|
const skipVariantsResolver = inputSkipVariantsResolver !== undefined ? inputSkipVariantsResolver :
|
|
// TODO v6: remove `Root` in the next major release
|
|
// For more details: https://github.com/mui/material-ui/pull/37908
|
|
componentSlot && componentSlot !== 'Root' && componentSlot !== 'root' || false;
|
|
const skipSx = inputSkipSx || false;
|
|
let label;
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (componentName) {
|
|
// TODO v6: remove `lowercaseFirstLetter()` in the next major release
|
|
// For more details: https://github.com/mui/material-ui/pull/37908
|
|
label = `${componentName}-${lowercaseFirstLetter(componentSlot || 'Root')}`;
|
|
}
|
|
}
|
|
let shouldForwardPropOption = shouldForwardProp;
|
|
|
|
// TODO v6: remove `Root` in the next major release
|
|
// For more details: https://github.com/mui/material-ui/pull/37908
|
|
if (componentSlot === 'Root' || componentSlot === 'root') {
|
|
shouldForwardPropOption = rootShouldForwardProp;
|
|
} else if (componentSlot) {
|
|
// any other slot specified
|
|
shouldForwardPropOption = slotShouldForwardProp;
|
|
} else if (isStringTag(tag)) {
|
|
// for string (html) tag, preserve the behavior in emotion & styled-components.
|
|
shouldForwardPropOption = undefined;
|
|
}
|
|
const defaultStyledResolver = (0, _styledEngine.default)(tag, (0, _extends2.default)({
|
|
shouldForwardProp: shouldForwardPropOption,
|
|
label
|
|
}, options));
|
|
const muiStyledResolver = (styleArg, ...expressions) => {
|
|
const expressionsWithDefaultTheme = expressions ? expressions.map(stylesArg => {
|
|
// On the server Emotion doesn't use React.forwardRef for creating components, so the created
|
|
// component stays as a function. This condition makes sure that we do not interpolate functions
|
|
// which are basically components used as a selectors.
|
|
if (typeof stylesArg === 'function' && stylesArg.__emotion_real !== stylesArg) {
|
|
return props => muiStyledFunctionResolver({
|
|
styledArg: stylesArg,
|
|
props,
|
|
defaultTheme,
|
|
themeId
|
|
});
|
|
}
|
|
if ((0, _utils.isPlainObject)(stylesArg)) {
|
|
let transformedStylesArg = stylesArg;
|
|
let styledArgVariants;
|
|
if (stylesArg && stylesArg.variants) {
|
|
styledArgVariants = stylesArg.variants;
|
|
delete transformedStylesArg.variants;
|
|
transformedStylesArg = props => {
|
|
let result = stylesArg;
|
|
const variantStyles = variantsResolver(props, transformVariants(styledArgVariants), styledArgVariants);
|
|
variantStyles.forEach(variantStyle => {
|
|
result = (0, _utils.deepmerge)(result, variantStyle);
|
|
});
|
|
return result;
|
|
};
|
|
}
|
|
return transformedStylesArg;
|
|
}
|
|
return stylesArg;
|
|
}) : [];
|
|
let transformedStyleArg = styleArg;
|
|
if ((0, _utils.isPlainObject)(styleArg)) {
|
|
let styledArgVariants;
|
|
if (styleArg && styleArg.variants) {
|
|
styledArgVariants = styleArg.variants;
|
|
delete transformedStyleArg.variants;
|
|
transformedStyleArg = props => {
|
|
let result = styleArg;
|
|
const variantStyles = variantsResolver(props, transformVariants(styledArgVariants), styledArgVariants);
|
|
variantStyles.forEach(variantStyle => {
|
|
result = (0, _utils.deepmerge)(result, variantStyle);
|
|
});
|
|
return result;
|
|
};
|
|
}
|
|
} else if (typeof styleArg === 'function' &&
|
|
// On the server Emotion doesn't use React.forwardRef for creating components, so the created
|
|
// component stays as a function. This condition makes sure that we do not interpolate functions
|
|
// which are basically components used as a selectors.
|
|
styleArg.__emotion_real !== styleArg) {
|
|
// If the type is function, we need to define the default theme.
|
|
transformedStyleArg = props => muiStyledFunctionResolver({
|
|
styledArg: styleArg,
|
|
props,
|
|
defaultTheme,
|
|
themeId
|
|
});
|
|
}
|
|
if (componentName && overridesResolver) {
|
|
expressionsWithDefaultTheme.push(props => {
|
|
const theme = resolveTheme((0, _extends2.default)({}, props, {
|
|
defaultTheme,
|
|
themeId
|
|
}));
|
|
const styleOverrides = getStyleOverrides(componentName, theme);
|
|
if (styleOverrides) {
|
|
const resolvedStyleOverrides = {};
|
|
Object.entries(styleOverrides).forEach(([slotKey, slotStyle]) => {
|
|
resolvedStyleOverrides[slotKey] = typeof slotStyle === 'function' ? slotStyle((0, _extends2.default)({}, props, {
|
|
theme
|
|
})) : slotStyle;
|
|
});
|
|
return overridesResolver(props, resolvedStyleOverrides);
|
|
}
|
|
return null;
|
|
});
|
|
}
|
|
if (componentName && !skipVariantsResolver) {
|
|
expressionsWithDefaultTheme.push(props => {
|
|
const theme = resolveTheme((0, _extends2.default)({}, props, {
|
|
defaultTheme,
|
|
themeId
|
|
}));
|
|
return themeVariantsResolver(props, getVariantStyles(componentName, theme), theme, componentName);
|
|
});
|
|
}
|
|
if (!skipSx) {
|
|
expressionsWithDefaultTheme.push(systemSx);
|
|
}
|
|
const numOfCustomFnsApplied = expressionsWithDefaultTheme.length - expressions.length;
|
|
if (Array.isArray(styleArg) && numOfCustomFnsApplied > 0) {
|
|
const placeholders = new Array(numOfCustomFnsApplied).fill('');
|
|
// If the type is array, than we need to add placeholders in the template for the overrides, variants and the sx styles.
|
|
transformedStyleArg = [...styleArg, ...placeholders];
|
|
transformedStyleArg.raw = [...styleArg.raw, ...placeholders];
|
|
}
|
|
const Component = defaultStyledResolver(transformedStyleArg, ...expressionsWithDefaultTheme);
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
let displayName;
|
|
if (componentName) {
|
|
displayName = `${componentName}${(0, _utils.unstable_capitalize)(componentSlot || '')}`;
|
|
}
|
|
if (displayName === undefined) {
|
|
displayName = `Styled(${(0, _utils.getDisplayName)(tag)})`;
|
|
}
|
|
Component.displayName = displayName;
|
|
}
|
|
if (tag.muiName) {
|
|
Component.muiName = tag.muiName;
|
|
}
|
|
return Component;
|
|
};
|
|
if (defaultStyledResolver.withConfig) {
|
|
muiStyledResolver.withConfig = defaultStyledResolver.withConfig;
|
|
}
|
|
return muiStyledResolver;
|
|
};
|
|
} |