UNPKG

@wordpress/block-editor

Version:
394 lines (379 loc) 11.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.BORDER_SUPPORT_KEY = void 0; exports.BorderPanel = BorderPanel; exports.default = exports.SHADOW_SUPPORT_KEY = void 0; exports.getBorderClasses = getBorderClasses; exports.getMultiOriginColor = void 0; exports.hasBorderSupport = hasBorderSupport; exports.hasShadowSupport = hasShadowSupport; exports.removeBorderAttribute = removeBorderAttribute; exports.useBorderPanelLabel = useBorderPanelLabel; var _clsx = _interopRequireDefault(require("clsx")); var _blocks = require("@wordpress/blocks"); var _components = require("@wordpress/components"); var _element = require("@wordpress/element"); var _hooks = require("@wordpress/hooks"); var _data = require("@wordpress/data"); var _colors = require("../components/colors"); var _inspectorControls = _interopRequireDefault(require("../components/inspector-controls")); var _useMultipleOriginColorsAndGradients = _interopRequireDefault(require("../components/colors-gradients/use-multiple-origin-colors-and-gradients")); var _utils = require("./utils"); var _globalStyles = require("../components/global-styles"); var _store = require("../store"); var _i18n = require("@wordpress/i18n"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const BORDER_SUPPORT_KEY = exports.BORDER_SUPPORT_KEY = '__experimentalBorder'; const SHADOW_SUPPORT_KEY = exports.SHADOW_SUPPORT_KEY = 'shadow'; const getColorByProperty = (colors, property, value) => { let matchedColor; colors.some(origin => origin.colors.some(color => { if (color[property] === value) { matchedColor = color; return true; } return false; })); return matchedColor; }; const getMultiOriginColor = ({ colors, namedColor, customColor }) => { // Search each origin (default, theme, or user) for matching color by name. if (namedColor) { const colorObject = getColorByProperty(colors, 'slug', namedColor); if (colorObject) { return colorObject; } } // Skip if no custom color or matching named color. if (!customColor) { return { color: undefined }; } // Attempt to find color via custom color value or build new object. const colorObject = getColorByProperty(colors, 'color', customColor); return colorObject ? colorObject : { color: customColor }; }; exports.getMultiOriginColor = getMultiOriginColor; function getColorSlugFromVariable(value) { const namedColor = /var:preset\|color\|(.+)/.exec(value); if (namedColor && namedColor[1]) { return namedColor[1]; } return null; } function styleToAttributes(style) { if ((0, _components.__experimentalHasSplitBorders)(style?.border)) { return { style, borderColor: undefined }; } const borderColorValue = style?.border?.color; const borderColorSlug = borderColorValue?.startsWith('var:preset|color|') ? borderColorValue.substring('var:preset|color|'.length) : undefined; const updatedStyle = { ...style }; updatedStyle.border = { ...updatedStyle.border, color: borderColorSlug ? undefined : borderColorValue }; return { style: (0, _utils.cleanEmptyObject)(updatedStyle), borderColor: borderColorSlug }; } function attributesToStyle(attributes) { if ((0, _components.__experimentalHasSplitBorders)(attributes.style?.border)) { return attributes.style; } return { ...attributes.style, border: { ...attributes.style?.border, color: attributes.borderColor ? 'var:preset|color|' + attributes.borderColor : attributes.style?.border?.color } }; } function BordersInspectorControl({ label, children, resetAllFilter }) { const attributesResetAllFilter = (0, _element.useCallback)(attributes => { const existingStyle = attributesToStyle(attributes); const updatedStyle = resetAllFilter(existingStyle); return { ...attributes, ...styleToAttributes(updatedStyle) }; }, [resetAllFilter]); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_inspectorControls.default, { group: "border", resetAllFilter: attributesResetAllFilter, label: label, children: children }); } function BorderPanel({ clientId, name, setAttributes, settings }) { const isEnabled = (0, _globalStyles.useHasBorderPanel)(settings); function selector(select) { const { style, borderColor } = select(_store.store).getBlockAttributes(clientId) || {}; return { style, borderColor }; } const { style, borderColor } = (0, _data.useSelect)(selector, [clientId]); const value = (0, _element.useMemo)(() => { return attributesToStyle({ style, borderColor }); }, [style, borderColor]); const onChange = newStyle => { setAttributes(styleToAttributes(newStyle)); }; if (!isEnabled) { return null; } const defaultControls = { ...(0, _blocks.getBlockSupport)(name, [BORDER_SUPPORT_KEY, '__experimentalDefaultControls']), ...(0, _blocks.getBlockSupport)(name, [SHADOW_SUPPORT_KEY, '__experimentalDefaultControls']) }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_globalStyles.BorderPanel, { as: BordersInspectorControl, panelId: clientId, settings: settings, value: value, onChange: onChange, defaultControls: defaultControls }); } /** * Determine whether there is block support for border properties. * * @param {string} blockName Block name. * @param {string} feature Border feature to check support for. * * @return {boolean} Whether there is support. */ function hasBorderSupport(blockName, feature = 'any') { if (_element.Platform.OS !== 'web') { return false; } const support = (0, _blocks.getBlockSupport)(blockName, BORDER_SUPPORT_KEY); if (support === true) { return true; } if (feature === 'any') { return !!(support?.color || support?.radius || support?.width || support?.style); } return !!support?.[feature]; } /** * Determine whether there is block support for shadow properties. * * @param {string} blockName Block name. * * @return {boolean} Whether there is support. */ function hasShadowSupport(blockName) { return (0, _blocks.hasBlockSupport)(blockName, SHADOW_SUPPORT_KEY); } function useBorderPanelLabel({ blockName, hasBorderControl, hasShadowControl } = {}) { const settings = (0, _utils.useBlockSettings)(blockName); const controls = (0, _globalStyles.useHasBorderPanelControls)(settings); if (!hasBorderControl && !hasShadowControl && blockName) { hasBorderControl = controls?.hasBorderColor || controls?.hasBorderStyle || controls?.hasBorderWidth || controls?.hasBorderRadius; hasShadowControl = controls?.hasShadow; } if (hasBorderControl && hasShadowControl) { return (0, _i18n.__)('Border & Shadow'); } if (hasShadowControl) { return (0, _i18n.__)('Shadow'); } return (0, _i18n.__)('Border'); } /** * Returns a new style object where the specified border attribute has been * removed. * * @param {Object} style Styles from block attributes. * @param {string} attribute The border style attribute to clear. * * @return {Object} Style object with the specified attribute removed. */ function removeBorderAttribute(style, attribute) { return (0, _utils.cleanEmptyObject)({ ...style, border: { ...style?.border, [attribute]: undefined } }); } /** * Filters registered block settings, extending attributes to include * `borderColor` if needed. * * @param {Object} settings Original block settings. * * @return {Object} Updated block settings. */ function addAttributes(settings) { if (!hasBorderSupport(settings, 'color')) { return settings; } // Allow blocks to specify default value if needed. if (settings.attributes.borderColor) { return settings; } // Add new borderColor attribute to block settings. return { ...settings, attributes: { ...settings.attributes, borderColor: { type: 'string' } } }; } /** * Override props assigned to save component to inject border color. * * @param {Object} props Additional props applied to save element. * @param {Object|string} blockNameOrType Block type definition. * @param {Object} attributes Block's attributes. * * @return {Object} Filtered props to apply to save element. */ function addSaveProps(props, blockNameOrType, attributes) { if (!hasBorderSupport(blockNameOrType, 'color') || (0, _utils.shouldSkipSerialization)(blockNameOrType, BORDER_SUPPORT_KEY, 'color')) { return props; } const borderClasses = getBorderClasses(attributes); const newClassName = (0, _clsx.default)(props.className, borderClasses); // If we are clearing the last of the previous classes in `className` // set it to `undefined` to avoid rendering empty DOM attributes. props.className = newClassName ? newClassName : undefined; return props; } /** * Generates a CSS class name consisting of all the applicable border color * classes given the current block attributes. * * @param {Object} attributes Block's attributes. * * @return {string} CSS class name. */ function getBorderClasses(attributes) { const { borderColor, style } = attributes; const borderColorClass = (0, _colors.getColorClassName)('border-color', borderColor); return (0, _clsx.default)({ 'has-border-color': borderColor || style?.border?.color, [borderColorClass]: !!borderColorClass }); } function useBlockProps({ name, borderColor, style }) { const { colors } = (0, _useMultipleOriginColorsAndGradients.default)(); if (!hasBorderSupport(name, 'color') || (0, _utils.shouldSkipSerialization)(name, BORDER_SUPPORT_KEY, 'color')) { return {}; } const { color: borderColorValue } = getMultiOriginColor({ colors, namedColor: borderColor }); const { color: borderTopColor } = getMultiOriginColor({ colors, namedColor: getColorSlugFromVariable(style?.border?.top?.color) }); const { color: borderRightColor } = getMultiOriginColor({ colors, namedColor: getColorSlugFromVariable(style?.border?.right?.color) }); const { color: borderBottomColor } = getMultiOriginColor({ colors, namedColor: getColorSlugFromVariable(style?.border?.bottom?.color) }); const { color: borderLeftColor } = getMultiOriginColor({ colors, namedColor: getColorSlugFromVariable(style?.border?.left?.color) }); const extraStyles = { borderTopColor: borderTopColor || borderColorValue, borderRightColor: borderRightColor || borderColorValue, borderBottomColor: borderBottomColor || borderColorValue, borderLeftColor: borderLeftColor || borderColorValue }; return addSaveProps({ style: (0, _utils.cleanEmptyObject)(extraStyles) || {} }, name, { borderColor, style }); } var _default = exports.default = { useBlockProps, addSaveProps, attributeKeys: ['borderColor', 'style'], hasSupport(name) { return hasBorderSupport(name, 'color'); } }; (0, _hooks.addFilter)('blocks.registerBlockType', 'core/border/addAttributes', addAttributes); //# sourceMappingURL=border.js.map