UNPKG

@wordpress/block-editor

Version:
368 lines (305 loc) 14.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.COLOR_SUPPORT_KEY = void 0; exports.ColorEdit = ColorEdit; exports.addEditProps = addEditProps; exports.addSaveProps = addSaveProps; exports.addTransforms = addTransforms; exports.withColorPaletteStyles = void 0; var _element = require("@wordpress/element"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classnames = _interopRequireDefault(require("classnames")); var _hooks = require("@wordpress/hooks"); var _blocks = require("@wordpress/blocks"); var _compose = require("@wordpress/compose"); var _colors = require("../components/colors"); var _gradients = require("../components/gradients"); var _utils = require("./utils"); var _useSetting = _interopRequireDefault(require("../components/use-setting")); var _inspectorControls = _interopRequireDefault(require("../components/inspector-controls")); var _colorPanel = _interopRequireWildcard(require("../components/global-styles/color-panel")); var _contrastChecker = _interopRequireDefault(require("./contrast-checker")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const COLOR_SUPPORT_KEY = 'color'; exports.COLOR_SUPPORT_KEY = COLOR_SUPPORT_KEY; const hasColorSupport = blockType => { const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false); }; const hasLinkColorSupport = blockType => { if (_element.Platform.OS !== 'web') { return false; } const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link; }; const hasGradientSupport = blockType => { const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients; }; const hasBackgroundColorSupport = blockType => { const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); return colorSupport && colorSupport.background !== false; }; const hasTextColorSupport = blockType => { const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); return colorSupport && colorSupport.text !== false; }; /** * Filters registered block settings, extending attributes to include * `backgroundColor` and `textColor` attribute. * * @param {Object} settings Original block settings. * * @return {Object} Filtered block settings. */ function addAttributes(settings) { if (!hasColorSupport(settings)) { return settings; } // Allow blocks to specify their own attribute definition with default values if needed. if (!settings.attributes.backgroundColor) { Object.assign(settings.attributes, { backgroundColor: { type: 'string' } }); } if (!settings.attributes.textColor) { Object.assign(settings.attributes, { textColor: { type: 'string' } }); } if (hasGradientSupport(settings) && !settings.attributes.gradient) { Object.assign(settings.attributes, { gradient: { type: 'string' } }); } return settings; } /** * Override props assigned to save component to inject colors classnames. * * @param {Object} props Additional props applied to save element. * @param {Object} blockType Block type. * @param {Object} attributes Block attributes. * * @return {Object} Filtered props applied to save element. */ function addSaveProps(props, blockType, attributes) { if (!hasColorSupport(blockType) || (0, _utils.shouldSkipSerialization)(blockType, COLOR_SUPPORT_KEY)) { return props; } const hasGradient = hasGradientSupport(blockType); // I'd have preferred to avoid the "style" attribute usage here const { backgroundColor, textColor, gradient, style } = attributes; const shouldSerialize = feature => !(0, _utils.shouldSkipSerialization)(blockType, COLOR_SUPPORT_KEY, feature); // Primary color classes must come before the `has-text-color`, // `has-background` and `has-link-color` classes to maintain backwards // compatibility and avoid block invalidations. const textClass = shouldSerialize('text') ? (0, _colors.getColorClassName)('color', textColor) : undefined; const gradientClass = shouldSerialize('gradients') ? (0, _gradients.__experimentalGetGradientClass)(gradient) : undefined; const backgroundClass = shouldSerialize('background') ? (0, _colors.getColorClassName)('background-color', backgroundColor) : undefined; const serializeHasBackground = shouldSerialize('background') || shouldSerialize('gradients'); const hasBackground = backgroundColor || style?.color?.background || hasGradient && (gradient || style?.color?.gradient); const newClassName = (0, _classnames.default)(props.className, textClass, gradientClass, { // Don't apply the background class if there's a custom gradient. [backgroundClass]: (!hasGradient || !style?.color?.gradient) && !!backgroundClass, 'has-text-color': shouldSerialize('text') && (textColor || style?.color?.text), 'has-background': serializeHasBackground && hasBackground, 'has-link-color': shouldSerialize('link') && style?.elements?.link?.color }); props.className = newClassName ? newClassName : undefined; return props; } /** * Filters registered block settings to extend the block edit wrapper * to apply the desired styles and classnames properly. * * @param {Object} settings Original block settings. * * @return {Object} Filtered block settings. */ function addEditProps(settings) { if (!hasColorSupport(settings) || (0, _utils.shouldSkipSerialization)(settings, COLOR_SUPPORT_KEY)) { return settings; } const existingGetEditWrapperProps = settings.getEditWrapperProps; settings.getEditWrapperProps = attributes => { let props = {}; if (existingGetEditWrapperProps) { props = existingGetEditWrapperProps(attributes); } return addSaveProps(props, settings, attributes); }; return settings; } function styleToAttributes(style) { const textColorValue = style?.color?.text; const textColorSlug = textColorValue?.startsWith('var:preset|color|') ? textColorValue.substring('var:preset|color|'.length) : undefined; const backgroundColorValue = style?.color?.background; const backgroundColorSlug = backgroundColorValue?.startsWith('var:preset|color|') ? backgroundColorValue.substring('var:preset|color|'.length) : undefined; const gradientValue = style?.color?.gradient; const gradientSlug = gradientValue?.startsWith('var:preset|gradient|') ? gradientValue.substring('var:preset|gradient|'.length) : undefined; const updatedStyle = { ...style }; updatedStyle.color = { ...updatedStyle.color, text: textColorSlug ? undefined : textColorValue, background: backgroundColorSlug ? undefined : backgroundColorValue, gradient: gradientSlug ? undefined : gradientValue }; return { style: (0, _utils.cleanEmptyObject)(updatedStyle), textColor: textColorSlug, backgroundColor: backgroundColorSlug, gradient: gradientSlug }; } function attributesToStyle(attributes) { return { ...attributes.style, color: { ...attributes.style?.color, text: attributes.textColor ? 'var:preset|color|' + attributes.textColor : attributes.style?.color?.text, background: attributes.backgroundColor ? 'var:preset|color|' + attributes.backgroundColor : attributes.style?.color?.background, gradient: attributes.gradient ? 'var:preset|gradient|' + attributes.gradient : attributes.style?.color?.gradient } }; } function ColorInspectorControl({ children, resetAllFilter }) { const attributesResetAllFilter = (0, _element.useCallback)(attributes => { const existingStyle = attributesToStyle(attributes); const updatedStyle = resetAllFilter(existingStyle); return { ...attributes, ...styleToAttributes(updatedStyle) }; }, [resetAllFilter]); return (0, _element.createElement)(_inspectorControls.default, { group: "color", resetAllFilter: attributesResetAllFilter }, children); } function ColorEdit(props) { const { clientId, name, attributes, setAttributes } = props; const settings = (0, _utils.useBlockSettings)(name); const isEnabled = (0, _colorPanel.useHasColorPanel)(settings); const value = (0, _element.useMemo)(() => { return attributesToStyle({ style: attributes.style, textColor: attributes.textColor, backgroundColor: attributes.backgroundColor, gradient: attributes.gradient }); }, [attributes.style, attributes.textColor, attributes.backgroundColor, attributes.gradient]); const onChange = newStyle => { setAttributes(styleToAttributes(newStyle)); }; if (!isEnabled) { return null; } const defaultControls = (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, '__experimentalDefaultControls']); const enableContrastChecking = _element.Platform.OS === 'web' && !value?.color?.gradient && (settings?.color?.text || settings?.color?.link) && // Contrast checking is enabled by default. // Deactivating it requires `enableContrastChecker` to have // an explicit value of `false`. false !== (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']); return (0, _element.createElement)(_colorPanel.default, { as: ColorInspectorControl, panelId: clientId, settings: settings, value: value, onChange: onChange, defaultControls: defaultControls, enableContrastChecker: false !== (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']) }, enableContrastChecking && (0, _element.createElement)(_contrastChecker.default, { clientId: clientId })); } /** * This adds inline styles for color palette colors. * Ideally, this is not needed and themes should load their palettes on the editor. * * @param {Function} BlockListBlock Original component. * * @return {Function} Wrapped component. */ const withColorPaletteStyles = (0, _compose.createHigherOrderComponent)(BlockListBlock => props => { const { name, attributes } = props; const { backgroundColor, textColor } = attributes; 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 colors = (0, _element.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); if (!hasColorSupport(name) || (0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY)) { return (0, _element.createElement)(BlockListBlock, props); } const extraStyles = {}; if (textColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'text')) { extraStyles.color = (0, _colors.getColorObjectByAttributeValues)(colors, textColor)?.color; } if (backgroundColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'background')) { extraStyles.backgroundColor = (0, _colors.getColorObjectByAttributeValues)(colors, backgroundColor)?.color; } let wrapperProps = props.wrapperProps; wrapperProps = { ...props.wrapperProps, style: { ...extraStyles, ...props.wrapperProps?.style } }; return (0, _element.createElement)(BlockListBlock, (0, _extends2.default)({}, props, { wrapperProps: wrapperProps })); }, 'withColorPaletteStyles'); exports.withColorPaletteStyles = withColorPaletteStyles; const MIGRATION_PATHS = { linkColor: [['style', 'elements', 'link', 'color', 'text']], textColor: [['textColor'], ['style', 'color', 'text']], backgroundColor: [['backgroundColor'], ['style', 'color', 'background']], gradient: [['gradient'], ['style', 'color', 'gradient']] }; function addTransforms(result, source, index, results) { const destinationBlockType = result.name; const activeSupports = { linkColor: hasLinkColorSupport(destinationBlockType), textColor: hasTextColorSupport(destinationBlockType), backgroundColor: hasBackgroundColorSupport(destinationBlockType), gradient: hasGradientSupport(destinationBlockType) }; return (0, _utils.transformStyles)(activeSupports, MIGRATION_PATHS, result, source, index, results); } (0, _hooks.addFilter)('blocks.registerBlockType', 'core/color/addAttribute', addAttributes); (0, _hooks.addFilter)('blocks.getSaveContent.extraProps', 'core/color/addSaveProps', addSaveProps); (0, _hooks.addFilter)('blocks.registerBlockType', 'core/color/addEditProps', addEditProps); (0, _hooks.addFilter)('editor.BlockListBlock', 'core/color/with-color-palette-styles', withColorPaletteStyles); (0, _hooks.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms); //# sourceMappingURL=color.js.map