substyle
Version:
Universal styling for reusable React components
106 lines (81 loc) • 5.89 kB
JavaScript
;
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;