UNPKG

substyle

Version:

Universal styling for reusable React components

106 lines (81 loc) 5.89 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _invariant = _interopRequireDefault(require("invariant")); var _coerceSelection = _interopRequireDefault(require("./coerceSelection")); var _defaultPropsDecorator = _interopRequireDefault(require("./defaultPropsDecorator")); var _filterKeys = require("./filterKeys"); var _memoize = _interopRequireDefault(require("./memoize")); var _pickStyles = require("./pickStyles"); var _utils = require("./utils"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var guessBaseClassName = function guessBaseClassName(classNames) { // all class names must start with the same prefix: the component's base class name // which will finally go to the container element var firstKey = classNames && (0, _utils.keys)(classNames)[0]; return firstKey && firstKey.split('__')[0].split('--')[0]; }; var deriveClassNames = function deriveClassNames(className, elementKeys, modifierKeys) { // do not derive class names, if the user did not specify any class name if (!className) { return undefined; } // derive class names based using the passed modifier/element keys var firstClassName = className.split(' ')[0]; var derivedClassNames = [].concat((0, _toConsumableArray2.default)(elementKeys.length === 0 ? modifierKeys.map(function (key) { return "".concat(firstClassName, "--").concat(key.substring(1)); }) : []), (0, _toConsumableArray2.default)(elementKeys.map(function (key) { return "".concat(firstClassName, "__").concat(key); }))); // also use the provided `className` if there is no sub-element selection return elementKeys.length === 0 ? [className].concat((0, _toConsumableArray2.default)(derivedClassNames)) : derivedClassNames; }; function createSubstyle(_ref) { var style = _ref.style, className = _ref.className, classNames = _ref.classNames; var propsDecorator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _defaultPropsDecorator.default; var baseClassName = className || guessBaseClassName(classNames) || (style === null || style === void 0 ? void 0 : style.className); var substyle = typeof style === 'function' ? style : (0, _memoize.default)(function (select, defaultStyle) { var selectedKeys = (0, _coerceSelection.default)(select); (0, _invariant.default)(Array.isArray(selectedKeys), 'First parameter must be a string, an array of strings, ' + 'a plain object with boolean values, or a falsy value.'); (0, _invariant.default)(!defaultStyle || (0, _utils.isPlainObject)(defaultStyle), 'Optional second parameter must be a plain object.'); var modifierKeys = selectedKeys.filter(_filterKeys.isModifier); var elementKeys = selectedKeys.filter(_filterKeys.isElement); var collectElementStyles = elementKeys.length > 0 ? function (fromStyle) { return (0, _utils.values)((0, _pickStyles.pickNestedStyles)(fromStyle, elementKeys)); } : function (fromStyle) { return [fromStyle]; }; var collectSelectedStyles = function collectSelectedStyles() { var fromStyle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return collectElementStyles((0, _pickStyles.hoistModifierStylesRecursive)(fromStyle, modifierKeys)); }; var derivedClassNames = deriveClassNames(baseClassName, elementKeys, modifierKeys); return createSubstyle(_objectSpread(_objectSpread(_objectSpread({}, (style || defaultStyle) && { style: _utils.merge.apply(void 0, [{}].concat((0, _toConsumableArray2.default)(collectSelectedStyles(defaultStyle)), (0, _toConsumableArray2.default)(collectSelectedStyles(style)))) }), derivedClassNames && { className: derivedClassNames.join(' ') }), classNames && { classNames: classNames }), propsDecorator); }); var styleProps = _objectSpread({}, typeof style === 'function' ? style : { style: style }); var classNameSplit = (0, _toConsumableArray2.default)(new Set([].concat((0, _toConsumableArray2.default)(styleProps.className ? styleProps.className.split(' ') : []), (0, _toConsumableArray2.default)(baseClassName ? baseClassName.split(' ') : [])))); var mappedClassNames = classNames ? (0, _utils.compact)(classNameSplit.map(function (singleClassName) { return classNames[singleClassName]; })) : classNameSplit; var propsForSpread = propsDecorator(_objectSpread(_objectSpread({}, styleProps), mappedClassNames.length > 0 ? { className: mappedClassNames.join(' ') } : {})); // assign `style`, `className`, and/or any props added by the decorator to the return function object Object.assign(substyle, propsForSpread); return substyle; } var _default = createSubstyle; exports.default = _default;