@gechiui/block-editor
Version:
230 lines (198 loc) • 8.83 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createCustomColorsHOC = createCustomColorsHOC;
exports.default = withColors;
var _element = require("@gechiui/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _lodash = require("lodash");
var _compose = require("@gechiui/compose");
var _utils = require("./utils");
var _useSetting = _interopRequireDefault(require("../use-setting"));
/**
* External dependencies
*/
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
/**
* Higher order component factory for injecting the `colorsArray` argument as
* the colors prop in the `withCustomColors` HOC.
*
* @param {Array} colorsArray An array of color objects.
*
* @return {Function} The higher order component.
*/
const withCustomColorPalette = colorsArray => (0, _compose.createHigherOrderComponent)(WrappedComponent => props => (0, _element.createElement)(WrappedComponent, (0, _extends2.default)({}, props, {
colors: colorsArray
})), 'withCustomColorPalette');
/**
* Higher order component factory for injecting the editor colors as the
* `colors` prop in the `withColors` HOC.
*
* @return {Function} The higher order component.
*/
const withEditorColorPalette = () => (0, _compose.createHigherOrderComponent)(WrappedComponent => props => {
// Some color settings have a special handling for deprecated flags in `useSetting`,
// so we can't unwrap them by doing const { ... } = useSetting('color')
// until https://github.com/GeChiUI/gutenberg/issues/37094 is fixed.
const userPalette = (0, _useSetting.default)('color.palette.custom');
const themePalette = (0, _useSetting.default)('color.palette.theme');
const defaultPalette = (0, _useSetting.default)('color.palette.default');
const allColors = (0, _element.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]);
return (0, _element.createElement)(WrappedComponent, (0, _extends2.default)({}, props, {
colors: allColors
}));
}, 'withEditorColorPalette');
/**
* Helper function used with `createHigherOrderComponent` to create
* higher order components for managing color logic.
*
* @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor).
* @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent.
*
* @return {GCComponent} The component that can be used as a HOC.
*/
function createColorHOC(colorTypes, withColorPalette) {
const colorMap = (0, _lodash.reduce)(colorTypes, (colorObject, colorType) => {
return { ...colorObject,
...((0, _lodash.isString)(colorType) ? {
[colorType]: (0, _lodash.kebabCase)(colorType)
} : colorType)
};
}, {});
return (0, _compose.compose)([withColorPalette, WrappedComponent => {
return class extends _element.Component {
constructor(props) {
super(props);
this.setters = this.createSetters();
this.colorUtils = {
getMostReadableColor: this.getMostReadableColor.bind(this)
};
this.state = {};
}
getMostReadableColor(colorValue) {
const {
colors
} = this.props;
return (0, _utils.getMostReadableColor)(colors, colorValue);
}
createSetters() {
return (0, _lodash.reduce)(colorMap, (settersAccumulator, colorContext, colorAttributeName) => {
const upperFirstColorAttributeName = (0, _lodash.upperFirst)(colorAttributeName);
const customColorAttributeName = `custom${upperFirstColorAttributeName}`;
settersAccumulator[`set${upperFirstColorAttributeName}`] = this.createSetColor(colorAttributeName, customColorAttributeName);
return settersAccumulator;
}, {});
}
createSetColor(colorAttributeName, customColorAttributeName) {
return colorValue => {
const colorObject = (0, _utils.getColorObjectByColorValue)(this.props.colors, colorValue);
this.props.setAttributes({
[colorAttributeName]: colorObject && colorObject.slug ? colorObject.slug : undefined,
[customColorAttributeName]: colorObject && colorObject.slug ? undefined : colorValue
});
};
}
static getDerivedStateFromProps(_ref, previousState) {
let {
attributes,
colors
} = _ref;
return (0, _lodash.reduce)(colorMap, (newState, colorContext, colorAttributeName) => {
const colorObject = (0, _utils.getColorObjectByAttributeValues)(colors, attributes[colorAttributeName], attributes[`custom${(0, _lodash.upperFirst)(colorAttributeName)}`]);
const previousColorObject = previousState[colorAttributeName];
const previousColor = previousColorObject === null || previousColorObject === void 0 ? void 0 : previousColorObject.color;
/**
* The "and previousColorObject" condition checks that a previous color object was already computed.
* At the start previousColorObject and colorValue are both equal to undefined
* bus as previousColorObject does not exist we should compute the object.
*/
if (previousColor === colorObject.color && previousColorObject) {
newState[colorAttributeName] = previousColorObject;
} else {
newState[colorAttributeName] = { ...colorObject,
class: (0, _utils.getColorClassName)(colorContext, colorObject.slug)
};
}
return newState;
}, {});
}
render() {
return (0, _element.createElement)(WrappedComponent, (0, _extends2.default)({}, this.props, {
colors: undefined
}, this.state, this.setters, {
colorUtils: this.colorUtils
}));
}
};
}]);
}
/**
* A higher-order component factory for creating a 'withCustomColors' HOC, which handles color logic
* for class generation color value, retrieval and color attribute setting.
*
* Use this higher-order component to work with a custom set of colors.
*
* @example
*
* ```jsx
* const CUSTOM_COLORS = [ { name: 'Red', slug: 'red', color: '#ff0000' }, { name: 'Blue', slug: 'blue', color: '#0000ff' } ];
* const withCustomColors = createCustomColorsHOC( CUSTOM_COLORS );
* // ...
* export default compose(
* withCustomColors( 'backgroundColor', 'borderColor' ),
* MyColorfulComponent,
* );
* ```
*
* @param {Array} colorsArray The array of color objects (name, slug, color, etc... ).
*
* @return {Function} Higher-order component.
*/
function createCustomColorsHOC(colorsArray) {
return function () {
const withColorPalette = withCustomColorPalette(colorsArray);
for (var _len = arguments.length, colorTypes = new Array(_len), _key = 0; _key < _len; _key++) {
colorTypes[_key] = arguments[_key];
}
return (0, _compose.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withCustomColors');
};
}
/**
* A higher-order component, which handles color logic for class generation color value, retrieval and color attribute setting.
*
* For use with the default editor/theme color palette.
*
* @example
*
* ```jsx
* export default compose(
* withColors( 'backgroundColor', { textColor: 'color' } ),
* MyColorfulComponent,
* );
* ```
*
* @param {...(Object|string)} colorTypes The arguments can be strings or objects. If the argument is an object,
* it should contain the color attribute name as key and the color context as value.
* If the argument is a string the value should be the color attribute name,
* the color context is computed by applying a kebab case transform to the value.
* Color context represents the context/place where the color is going to be used.
* The class name of the color is generated using 'has' followed by the color name
* and ending with the color context all in kebab case e.g: has-green-background-color.
*
* @return {Function} Higher-order component.
*/
function withColors() {
const withColorPalette = withEditorColorPalette();
for (var _len2 = arguments.length, colorTypes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
colorTypes[_key2] = arguments[_key2];
}
return (0, _compose.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withColors');
}
//# sourceMappingURL=with-colors.js.map