@wordpress/block-editor
Version:
394 lines (379 loc) • 11.4 kB
JavaScript
"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