@fluentui/styles
Version:
A set of styling utilities for CSS-in-JS.
412 lines (396 loc) • 17.7 kB
JavaScript
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _forEach from "lodash/forEach";
import _keys from "lodash/keys";
import _map from "lodash/map";
import _union from "lodash/union";
import _merge from "lodash/merge";
var _excluded = ["_debug"],
_excluded2 = ["_debug"],
_excluded3 = ["_debug"],
_excluded4 = ["_debug"],
_excluded5 = ["_debug"],
_excluded6 = ["_debug", "_debugId"],
_excluded7 = ["_debug"],
_excluded8 = ["_debug", "_invertedKeys", "_debugId"];
import { callable } from './callable';
import { isEnabled as isDebugEnabled } from './debugEnabled';
import { deepmerge } from './deepmerge';
import { objectKeyToValues } from './objectKeysToValues';
import { withDebugId } from './withDebugId';
export var emptyTheme = {
siteVariables: {
fontSizes: {}
},
componentVariables: {},
componentStyles: {},
fontFaces: [],
staticStyles: [],
animations: {}
};
// ----------------------------------------
// Component level merge functions
// ----------------------------------------
/**
* Merges a single component's styles (keyed by component part) with another component's styles.
*/
export var mergeComponentStyles__PROD = function mergeComponentStyles__PROD(stylesA, stylesB) {
var result = {};
if (stylesA) {
Object.keys(stylesA).forEach(function (partName) {
var slotA = stylesA[partName];
var slotB = stylesB == null ? void 0 : stylesB[partName];
// if there is no source, merging is a no-op, skip it
if (typeof slotA === 'undefined' || slotA === null) {
return;
}
// no target means source doesn't need to merge onto anything
// just ensure source is callable (prepared format)
if (typeof slotB === 'undefined' || slotB === null) {
result[partName] = typeof slotA === 'function' ? slotA : function () {
return slotA;
};
return;
}
if (slotA === slotB) {
result[partName] = typeof slotA === 'function' ? slotA : function () {
return slotA;
};
}
});
}
if (stylesB) {
Object.keys(stylesB).forEach(function (partName) {
var slotA = stylesA == null ? void 0 : stylesA[partName];
var slotB = stylesB[partName];
// if there is no source, merging is a no-op, skip it
if (typeof slotB === 'undefined' || slotB === null) {
return;
}
// no target means source doesn't need to merge onto anything
// just ensure source is callable (prepared format)
if (typeof slotA === 'undefined' || slotA === null) {
result[partName] = typeof slotB === 'function' ? slotB : function () {
return slotB;
};
return;
}
if (slotA === slotB) {
return;
}
// We have both target and source, replace with merge fn
result[partName] = function mergedStyleFunction(styleParam) {
// originalTarget is always prepared, fn is guaranteed
return _merge(typeof slotA === 'function' ? slotA(styleParam) : slotA, typeof slotB === 'function' ? slotB(styleParam) : slotB);
};
});
}
return result;
};
export var mergeComponentStyles__DEV = function mergeComponentStyles__DEV(stylesA, stylesB) {
if (!isDebugEnabled) {
return mergeComponentStyles__PROD(stylesA, stylesB);
}
var mergedKeys = [].concat(stylesA ? Object.keys(stylesA) : [], stylesB ? Object.keys(stylesB) : []);
var result = {};
mergedKeys.forEach(function (slotName) {
var slotA = function slotA(styleParam) {
var _ref = callable(stylesA == null ? void 0 : stylesA[slotName])(styleParam) || {},
_ref$_debug = _ref._debug,
_debug = _ref$_debug === void 0 ? undefined : _ref$_debug,
styles = _objectWithoutPropertiesLoose(_ref, _excluded);
// new object required to prevent circular JSON structure error in <Debug />
return Object.assign({}, styles, {
_debug: _debug || [{
styles: Object.assign({}, styles),
debugId: stylesA == null ? void 0 : stylesA._debugId
}]
});
};
var slotB = function slotB(styleParam) {
var _ref2 = callable(stylesB == null ? void 0 : stylesB[slotName])(styleParam) || {},
_ref2$_debug = _ref2._debug,
_debug = _ref2$_debug === void 0 ? undefined : _ref2$_debug,
styles = _objectWithoutPropertiesLoose(_ref2, _excluded2);
// new object required to prevent circular JSON structure error in <Debug />
return Object.assign({}, styles, {
_debug: _debug || [{
styles: Object.assign({}, styles),
debugId: stylesB == null ? void 0 : stylesB._debugId
}]
});
};
if (stylesA != null && stylesA[slotName] && stylesB != null && stylesB[slotName]) {
// We have both, replace with merge fn
result[slotName] = function (styleParam) {
// slot* are always prepared, fn is guaranteed, _debug always exists
var _slotA = slotA(styleParam),
debugA = _slotA._debug,
resolvedStylesA = _objectWithoutPropertiesLoose(_slotA, _excluded3);
var _slotB = slotB(styleParam),
debugB = _slotB._debug,
resolvedStylesB = _objectWithoutPropertiesLoose(_slotB, _excluded4);
var merged = _merge(resolvedStylesA, resolvedStylesB);
merged._debug = debugA.concat(debugB || {
styles: resolvedStylesB,
debugId: resolvedStylesB._debugId
});
return merged;
};
} else if (stylesA != null && stylesA[slotName]) {
result[slotName] = slotA;
} else if (stylesB != null && stylesB[slotName]) {
result[slotName] = slotB;
}
});
return result;
};
export var mergeComponentStyles = process.env.NODE_ENV === 'production' ? mergeComponentStyles__PROD : mergeComponentStyles__DEV;
/**
* Merges a single component's variables with another component's variables.
*/
export var mergeComponentVariables__PROD = function mergeComponentVariables__PROD(variablesA, variablesB) {
if (variablesA && variablesB) {
return function mergedComponentVariables(siteVariables) {
var resolvedVariablesA = typeof variablesA === 'function' ? variablesA(siteVariables) : variablesA || {};
var resolvedVariablesB = typeof variablesB === 'function' ? variablesB(siteVariables) : variablesB || {};
return deepmerge(resolvedVariablesA, resolvedVariablesB);
};
}
if (variablesA) {
return typeof variablesA === 'function' ? variablesA : function () {
return variablesA || {};
};
}
if (variablesB) {
return typeof variablesB === 'function' ? variablesB : function () {
return variablesB || {};
};
}
return function () {
return {};
};
};
export var mergeComponentVariables__DEV = function mergeComponentVariables__DEV(variablesA, variablesB) {
if (!isDebugEnabled) {
return mergeComponentVariables__PROD(variablesA, variablesB);
}
var initial = function initial() {
return {};
};
return [variablesA, variablesB].reduce(function (acc, next) {
return function (siteVariables) {
var _acc = acc(siteVariables),
_acc$_debug = _acc._debug,
_debug = _acc$_debug === void 0 ? [] : _acc$_debug,
accumulatedVariables = _objectWithoutPropertiesLoose(_acc, _excluded5);
var _ref3 = callable(next)(siteVariables) || {},
_ref3$_debug = _ref3._debug,
computedDebug = _ref3$_debug === void 0 ? undefined : _ref3$_debug,
_ref3$_debugId = _ref3._debugId,
_debugId = _ref3$_debugId === void 0 ? undefined : _ref3$_debugId,
computedComponentVariables = _objectWithoutPropertiesLoose(_ref3, _excluded6);
var merged = deepmerge(accumulatedVariables, computedComponentVariables);
merged._debug = _debug.concat(computedDebug || {
resolved: computedComponentVariables,
debugId: _debugId,
input: siteVariables ? siteVariables._invertedKeys && callable(next)(siteVariables._invertedKeys) : callable(next)()
});
return merged;
};
}, initial);
};
export var mergeComponentVariables = process.env.NODE_ENV === 'production' ? mergeComponentVariables__PROD : mergeComponentVariables__DEV;
// ----------------------------------------
// Theme level merge functions
// ----------------------------------------
/**
* Site variables can safely be merged at each Provider in the tree.
* They are flat objects and do not depend on render-time values, such as props.
*/
export var mergeSiteVariables__PROD = function mergeSiteVariables__PROD(siteVariablesA, siteVariablesB) {
var initial = {
fontSizes: {}
};
if (siteVariablesA && siteVariablesB) {
return deepmerge(initial, siteVariablesA, siteVariablesB);
}
if (siteVariablesA) {
return Object.assign({}, initial, siteVariablesA);
}
return Object.assign({}, initial, siteVariablesB);
};
export var mergeSiteVariables__DEV = function mergeSiteVariables__DEV(siteVariablesA, siteVariablesB) {
if (!isDebugEnabled) {
return mergeSiteVariables__PROD(siteVariablesA, siteVariablesB);
}
var initial = {
fontSizes: {}
};
return [siteVariablesA, siteVariablesB].reduce(function (acc, next) {
var _acc$_debug2 = acc._debug,
_debug = _acc$_debug2 === void 0 ? [] : _acc$_debug2,
accumulatedSiteVariables = _objectWithoutPropertiesLoose(acc, _excluded7);
var _ref4 = next || {},
_ref4$_debug = _ref4._debug,
computedDebug = _ref4$_debug === void 0 ? undefined : _ref4$_debug,
_ref4$_invertedKeys = _ref4._invertedKeys,
_invertedKeys = _ref4$_invertedKeys === void 0 ? undefined : _ref4$_invertedKeys,
_ref4$_debugId = _ref4._debugId,
_debugId = _ref4$_debugId === void 0 ? undefined : _ref4$_debugId,
nextSiteVariables = _objectWithoutPropertiesLoose(_ref4, _excluded8);
var merged = deepmerge(Object.assign({}, accumulatedSiteVariables, {
_invertedKeys: undefined
}), nextSiteVariables);
merged._debug = _debug.concat(computedDebug || {
resolved: nextSiteVariables,
debugId: _debugId
});
merged._invertedKeys = _invertedKeys || objectKeyToValues(merged, function (key) {
return "siteVariables." + key;
});
return merged;
}, initial);
};
export var mergeSiteVariables = process.env.NODE_ENV === 'production' ? mergeSiteVariables__PROD : mergeSiteVariables__DEV;
/**
* Component variables can be objects, functions, or an array of these.
* The functions must be called with the final result of siteVariables, otherwise
* the component variable objects would have no ability to apply siteVariables.
* Therefore, componentVariables must be resolved by the component at render time.
* We instead pass down call stack of component variable functions to be resolved later.
*/
export var mergeThemeVariables__PROD = function mergeThemeVariables__PROD(themeComponentVariablesA, themeComponentVariablesB) {
if (themeComponentVariablesA && themeComponentVariablesB) {
var displayNames = _union.apply(void 0, _map([themeComponentVariablesA, themeComponentVariablesB], _keys));
return displayNames.reduce(function (componentVariables, displayName) {
componentVariables[displayName] = mergeComponentVariables(themeComponentVariablesA[displayName], themeComponentVariablesB[displayName]);
return componentVariables;
}, {});
}
if (themeComponentVariablesA) {
return Object.fromEntries(Object.entries(themeComponentVariablesA).map(function (_ref5) {
var displayName = _ref5[0],
variables = _ref5[1];
return [displayName, mergeComponentVariables(undefined, variables)];
}));
}
if (themeComponentVariablesB) {
return Object.fromEntries(Object.entries(themeComponentVariablesB).map(function (_ref6) {
var displayName = _ref6[0],
variables = _ref6[1];
return [displayName, mergeComponentVariables(undefined, variables)];
}));
}
return {};
};
export var mergeThemeVariables__DEV = function mergeThemeVariables__DEV(themeComponentVariablesA, themeComponentVariablesB) {
if (!isDebugEnabled) {
return mergeThemeVariables__PROD(themeComponentVariablesA, themeComponentVariablesB);
}
var displayNames = _union.apply(void 0, _map([themeComponentVariablesA, themeComponentVariablesB], _keys));
return displayNames.reduce(function (componentVariables, displayName) {
componentVariables[displayName] = mergeComponentVariables(themeComponentVariablesA && withDebugId(themeComponentVariablesA[displayName], themeComponentVariablesA._debugId), themeComponentVariablesB && withDebugId(themeComponentVariablesB[displayName], themeComponentVariablesB._debugId));
return componentVariables;
}, {});
};
export var mergeThemeVariables = process.env.NODE_ENV === 'production' ? mergeThemeVariables__PROD : mergeThemeVariables__DEV;
/**
* See mergeThemeVariables() description.
* Component styles adhere to the same pattern as component variables, except
* that they return style objects.
*/
var mergeThemeStyles__PROD = function mergeThemeStyles__PROD(themeComponentStylesA, themeComponentStylesB) {
if (themeComponentStylesA && themeComponentStylesB) {
var displayNames = _union.apply(void 0, _map([themeComponentStylesA, themeComponentStylesB], _keys));
return displayNames.reduce(function (themeComponentStyles, displayName) {
themeComponentStyles[displayName] = mergeComponentStyles(themeComponentStylesA[displayName], themeComponentStylesB[displayName]);
return themeComponentStyles;
}, {});
}
if (themeComponentStylesA) {
return Object.fromEntries(Object.entries(themeComponentStylesA).map(function (_ref7) {
var displayName = _ref7[0],
styles = _ref7[1];
return [displayName, mergeComponentStyles(undefined, styles)];
}));
}
if (themeComponentStylesB) {
return Object.fromEntries(Object.entries(themeComponentStylesB).map(function (_ref8) {
var displayName = _ref8[0],
styles = _ref8[1];
return [displayName, mergeComponentStyles(undefined, styles)];
}));
}
return {};
};
var mergeThemeStyles__DEV = function mergeThemeStyles__DEV(componentStylesA, componentStylesB) {
if (!isDebugEnabled) {
return mergeThemeStyles__PROD(componentStylesA, componentStylesB);
}
var initial = {};
return [componentStylesA, componentStylesB].reduce(function (themeComponentStyles, next) {
_forEach(next, function (stylesByPart, displayName) {
themeComponentStyles[displayName] = mergeComponentStyles(themeComponentStyles[displayName], withDebugId(stylesByPart, next._debugId));
});
return themeComponentStyles;
}, initial);
};
export var mergeThemeStyles = process.env.NODE_ENV === 'production' ? mergeThemeStyles__PROD : mergeThemeStyles__DEV;
export var mergeFontFaces = function mergeFontFaces(fontFacesA, fontFacesB) {
return [].concat(fontFacesA || [], fontFacesB || []);
};
export var mergeStaticStyles = function mergeStaticStyles(staticStylesA, staticStylesB) {
return [].concat(staticStylesA || [], staticStylesB || []);
};
export var mergeAnimations = function mergeAnimations(animationsA, animationsB) {
return Object.assign({}, animationsA, animationsB);
};
export var mergeStyles = function mergeStyles() {
for (var _len = arguments.length, sources = new Array(_len), _key = 0; _key < _len; _key++) {
sources[_key] = arguments[_key];
}
return function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return sources.reduce(function (acc, next) {
return _merge(acc, callable(next).apply(void 0, args));
}, {});
};
};
export var mergeThemes = function mergeThemes(themeA, themeB) {
var debugIdA = themeA == null ? void 0 : themeA['_debugId'];
var debugIdB = themeB == null ? void 0 : themeB['_debugId'];
if (themeA && themeB) {
return {
animations: mergeAnimations(themeA.animations, themeB.animations),
componentVariables: mergeThemeVariables(withDebugId(themeA.componentVariables, debugIdA), withDebugId(themeB.componentVariables, debugIdB)),
componentStyles: mergeThemeStyles(withDebugId(themeA.componentStyles, debugIdA), withDebugId(themeB.componentStyles, debugIdB)),
fontFaces: mergeFontFaces(themeA.fontFaces, themeB.fontFaces),
siteVariables: mergeSiteVariables(withDebugId(themeA.siteVariables, debugIdA), withDebugId(themeB.siteVariables, debugIdB)),
staticStyles: mergeStaticStyles(themeA.staticStyles, themeB.staticStyles)
};
}
if (themeA) {
return {
animations: mergeAnimations(undefined, themeA.animations),
componentVariables: mergeThemeVariables(undefined, withDebugId(themeA.componentVariables, debugIdA)),
componentStyles: mergeThemeStyles(undefined, withDebugId(themeA.componentStyles, debugIdA)),
fontFaces: mergeFontFaces(undefined, themeA.fontFaces),
siteVariables: mergeSiteVariables(undefined, withDebugId(themeA.siteVariables, debugIdA)),
staticStyles: mergeStaticStyles(undefined, themeA.staticStyles)
};
}
if (themeB) {
return {
animations: mergeAnimations(undefined, themeB.animations),
componentVariables: mergeThemeVariables(undefined, withDebugId(themeB.componentVariables, debugIdB)),
componentStyles: mergeThemeStyles(undefined, withDebugId(themeB.componentStyles, debugIdB)),
fontFaces: mergeFontFaces(undefined, themeB.fontFaces),
siteVariables: mergeSiteVariables(undefined, withDebugId(themeB.siteVariables, debugIdB)),
staticStyles: mergeStaticStyles(undefined, themeB.staticStyles)
};
}
return Object.assign({}, emptyTheme);
};
//# sourceMappingURL=mergeThemes.js.map