@wordpress/block-editor
Version:
263 lines (247 loc) • 8.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.VIEWS = exports.RANGE_CONTROL_MAX_SIZE = exports.LABELS = exports.ICONS = exports.DEFAULT_VALUES = exports.ALL_SIDES = void 0;
exports.getCustomValueFromPreset = getCustomValueFromPreset;
exports.getInitialView = getInitialView;
exports.getPresetValueFromCustomValue = getPresetValueFromCustomValue;
exports.getSliderValueFromPreset = getSliderValueFromPreset;
exports.getSpacingPresetCssVar = getSpacingPresetCssVar;
exports.getSpacingPresetSlug = getSpacingPresetSlug;
exports.hasAxisSupport = hasAxisSupport;
exports.hasBalancedSidesSupport = hasBalancedSidesSupport;
exports.isValueSpacingPreset = isValueSpacingPreset;
var _i18n = require("@wordpress/i18n");
var _icons = require("@wordpress/icons");
/**
* WordPress dependencies
*/
const RANGE_CONTROL_MAX_SIZE = exports.RANGE_CONTROL_MAX_SIZE = 8;
const ALL_SIDES = exports.ALL_SIDES = ['top', 'right', 'bottom', 'left'];
const DEFAULT_VALUES = exports.DEFAULT_VALUES = {
top: undefined,
right: undefined,
bottom: undefined,
left: undefined
};
const ICONS = exports.ICONS = {
custom: _icons.sidesAll,
axial: _icons.sidesAll,
horizontal: _icons.sidesHorizontal,
vertical: _icons.sidesVertical,
top: _icons.sidesTop,
right: _icons.sidesRight,
bottom: _icons.sidesBottom,
left: _icons.sidesLeft
};
const LABELS = exports.LABELS = {
default: (0, _i18n.__)('Spacing control'),
top: (0, _i18n.__)('Top'),
bottom: (0, _i18n.__)('Bottom'),
left: (0, _i18n.__)('Left'),
right: (0, _i18n.__)('Right'),
mixed: (0, _i18n.__)('Mixed'),
vertical: (0, _i18n.__)('Vertical'),
horizontal: (0, _i18n.__)('Horizontal'),
axial: (0, _i18n.__)('Horizontal & vertical'),
custom: (0, _i18n.__)('Custom')
};
const VIEWS = exports.VIEWS = {
axial: 'axial',
top: 'top',
right: 'right',
bottom: 'bottom',
left: 'left',
custom: 'custom'
};
/**
* Checks is given value is a spacing preset.
*
* @param {string} value Value to check
*
* @return {boolean} Return true if value is string in format var:preset|spacing|.
*/
function isValueSpacingPreset(value) {
if (!value?.includes) {
return false;
}
return value === '0' || value.includes('var:preset|spacing|');
}
/**
* Converts a spacing preset into a custom value.
*
* @param {string} value Value to convert
* @param {Array} spacingSizes Array of the current spacing preset objects
*
* @return {string} Mapping of the spacing preset to its equivalent custom value.
*/
function getCustomValueFromPreset(value, spacingSizes) {
if (!isValueSpacingPreset(value)) {
return value;
}
const slug = getSpacingPresetSlug(value);
const spacingSize = spacingSizes.find(size => String(size.slug) === slug);
return spacingSize?.size;
}
/**
* Converts a custom value to preset value if one can be found.
*
* Returns value as-is if no match is found.
*
* @param {string} value Value to convert
* @param {Array} spacingSizes Array of the current spacing preset objects
*
* @return {string} The preset value if it can be found.
*/
function getPresetValueFromCustomValue(value, spacingSizes) {
// Return value as-is if it is undefined or is already a preset, or '0';
if (!value || isValueSpacingPreset(value) || value === '0') {
return value;
}
const spacingMatch = spacingSizes.find(size => String(size.size) === String(value));
if (spacingMatch?.slug) {
return `var:preset|spacing|${spacingMatch.slug}`;
}
return value;
}
/**
* Converts a spacing preset into a custom value.
*
* @param {string} value Value to convert.
*
* @return {string | undefined} CSS var string for given spacing preset value.
*/
function getSpacingPresetCssVar(value) {
if (!value) {
return;
}
const slug = value.match(/var:preset\|spacing\|(.+)/);
if (!slug) {
return value;
}
return `var(--wp--preset--spacing--${slug[1]})`;
}
/**
* Returns the slug section of the given spacing preset string.
*
* @param {string} value Value to extract slug from.
*
* @return {string|undefined} The int value of the slug from given spacing preset.
*/
function getSpacingPresetSlug(value) {
if (!value) {
return;
}
if (value === '0' || value === 'default') {
return value;
}
const slug = value.match(/var:preset\|spacing\|(.+)/);
return slug ? slug[1] : undefined;
}
/**
* Converts spacing preset value into a Range component value .
*
* @param {string} presetValue Value to convert to Range value.
* @param {Array} spacingSizes Array of current spacing preset value objects.
*
* @return {number} The int value for use in Range control.
*/
function getSliderValueFromPreset(presetValue, spacingSizes) {
if (presetValue === undefined) {
return 0;
}
const slug = parseFloat(presetValue, 10) === 0 ? '0' : getSpacingPresetSlug(presetValue);
const sliderValue = spacingSizes.findIndex(spacingSize => {
return String(spacingSize.slug) === slug;
});
// Returning NaN rather than undefined as undefined makes range control thumb sit in center
return sliderValue !== -1 ? sliderValue : NaN;
}
/**
* Determines whether a particular axis has support. If no axis is
* specified, this function checks if either axis is supported.
*
* @param {Array} sides Supported sides.
* @param {string} axis Which axis to check.
*
* @return {boolean} Whether there is support for the specified axis or both axes.
*/
function hasAxisSupport(sides, axis) {
if (!sides || !sides.length) {
return false;
}
const hasHorizontalSupport = sides.includes('horizontal') || sides.includes('left') && sides.includes('right');
const hasVerticalSupport = sides.includes('vertical') || sides.includes('top') && sides.includes('bottom');
if (axis === 'horizontal') {
return hasHorizontalSupport;
}
if (axis === 'vertical') {
return hasVerticalSupport;
}
return hasHorizontalSupport || hasVerticalSupport;
}
/**
* Checks if the supported sides are balanced for each axis.
* - Horizontal - both left and right sides are supported.
* - Vertical - both top and bottom are supported.
*
* @param {Array} sides The supported sides which may be axes as well.
*
* @return {boolean} Whether or not the supported sides are balanced.
*/
function hasBalancedSidesSupport(sides = []) {
const counts = {
top: 0,
right: 0,
bottom: 0,
left: 0
};
sides.forEach(side => counts[side] += 1);
return (counts.top + counts.bottom) % 2 === 0 && (counts.left + counts.right) % 2 === 0;
}
/**
* Determines which view the SpacingSizesControl should default to on its
* first render; Axial, Custom, or Single side.
*
* @param {Object} values Current side values.
* @param {Array} sides Supported sides.
*
* @return {string} View to display.
*/
function getInitialView(values = {}, sides) {
const {
top,
right,
bottom,
left
} = values;
const sideValues = [top, right, bottom, left].filter(Boolean);
// Axial ( Horizontal & vertical ).
// - Has axial side support
// - Has axial side values which match
// - Has no values and the supported sides are balanced
const hasMatchingAxialValues = top === bottom && left === right && (!!top || !!left);
const hasNoValuesAndBalancedSides = !sideValues.length && hasBalancedSidesSupport(sides);
const hasOnlyAxialSides = sides?.includes('horizontal') && sides?.includes('vertical') && sides?.length === 2;
if (hasAxisSupport(sides) && (hasMatchingAxialValues || hasNoValuesAndBalancedSides)) {
return VIEWS.axial;
}
// Only axial sides are supported and single value defined.
// - Ensure the side returned is the first side that has a value.
if (hasOnlyAxialSides && sideValues.length === 1) {
let side;
Object.entries(values).some(([key, value]) => {
side = key;
return value !== undefined;
});
return side;
}
// Only single side supported and no value defined.
if (sides?.length === 1 && !sideValues.length) {
return sides[0];
}
// Default to the Custom (separated sides) view.
return VIEWS.custom;
}
//# sourceMappingURL=utils.js.map