@wordpress/block-editor
Version:
543 lines (457 loc) • 18.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = DimensionsPanel;
exports.useHasDimensionsPanel = useHasDimensionsPanel;
var _element = require("@wordpress/element");
var _classnames = _interopRequireDefault(require("classnames"));
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _icons = require("@wordpress/icons");
var _utils = require("./utils");
var _spacingSizesControl = _interopRequireDefault(require("../spacing-sizes-control"));
var _heightControl = _interopRequireDefault(require("../height-control"));
var _childLayoutControl = _interopRequireDefault(require("../child-layout-control"));
var _utils2 = require("../../hooks/utils");
var _object = require("../../utils/object");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const AXIAL_SIDES = ['horizontal', 'vertical'];
function useHasDimensionsPanel(settings) {
const hasContentSize = useHasContentSize(settings);
const hasWideSize = useHasWideSize(settings);
const hasPadding = useHasPadding(settings);
const hasMargin = useHasMargin(settings);
const hasGap = useHasGap(settings);
const hasMinHeight = useHasMinHeight(settings);
const hasChildLayout = useHasChildLayout(settings);
return _element.Platform.OS === 'web' && (hasContentSize || hasWideSize || hasPadding || hasMargin || hasGap || hasMinHeight || hasChildLayout);
}
function useHasContentSize(settings) {
return settings?.layout?.contentSize;
}
function useHasWideSize(settings) {
return settings?.layout?.wideSize;
}
function useHasPadding(settings) {
return settings?.spacing?.padding;
}
function useHasMargin(settings) {
return settings?.spacing?.margin;
}
function useHasGap(settings) {
return settings?.spacing?.blockGap;
}
function useHasMinHeight(settings) {
return settings?.dimensions?.minHeight;
}
function useHasChildLayout(settings) {
var _settings$parentLayou;
const {
type: parentLayoutType = 'default',
default: {
type: defaultParentLayoutType = 'default'
} = {},
allowSizingOnChildren = false
} = (_settings$parentLayou = settings?.parentLayout) !== null && _settings$parentLayou !== void 0 ? _settings$parentLayou : {};
const support = (defaultParentLayoutType === 'flex' || parentLayoutType === 'flex') && allowSizingOnChildren;
return !!settings?.layout && support;
}
function useHasSpacingPresets(settings) {
var _ref, _ref2;
const {
custom,
theme,
default: defaultPresets
} = settings?.spacing?.spacingSizes || {};
const presets = (_ref = (_ref2 = custom !== null && custom !== void 0 ? custom : theme) !== null && _ref2 !== void 0 ? _ref2 : defaultPresets) !== null && _ref !== void 0 ? _ref : [];
return presets.length > 0;
}
function filterValuesBySides(values, sides) {
// If no custom side configuration, all sides are opted into by default.
// Without any values, we have nothing to filter either.
if (!sides || !values) {
return values;
} // Only include sides opted into within filtered values.
const filteredValues = {};
sides.forEach(side => {
if (side === 'vertical') {
filteredValues.top = values.top;
filteredValues.bottom = values.bottom;
}
if (side === 'horizontal') {
filteredValues.left = values.left;
filteredValues.right = values.right;
}
filteredValues[side] = values?.[side];
});
return filteredValues;
}
function splitStyleValue(value) {
// Check for shorthand value (a string value).
if (value && typeof value === 'string') {
// Convert to value for individual sides for BoxControl.
return {
top: value,
right: value,
bottom: value,
left: value
};
}
return value;
}
function splitGapValue(value) {
// Check for shorthand value (a string value).
if (value && typeof value === 'string') {
// If the value is a string, treat it as a single side (top) for the spacing controls.
return {
top: value
};
}
if (value) {
return { ...value,
right: value?.left,
bottom: value?.top
};
}
return value;
}
function DimensionsToolsPanel({
resetAllFilter,
onChange,
value,
panelId,
children
}) {
const resetAll = () => {
const updatedValue = resetAllFilter(value);
onChange(updatedValue);
};
return (0, _element.createElement)(_components.__experimentalToolsPanel, {
label: (0, _i18n.__)('Dimensions'),
resetAll: resetAll,
panelId: panelId
}, children);
}
const DEFAULT_CONTROLS = {
contentSize: true,
wideSize: true,
padding: true,
margin: true,
blockGap: true,
minHeight: true,
childLayout: true
};
function DimensionsPanel({
as: Wrapper = DimensionsToolsPanel,
value,
onChange,
inheritedValue = value,
settings,
panelId,
defaultControls = DEFAULT_CONTROLS,
onVisualize = () => {},
// Special case because the layout controls are not part of the dimensions panel
// in global styles but not in block inspector.
includeLayoutControls = false
}) {
var _settings$parentLayou2, _defaultControls$cont, _defaultControls$wide, _defaultControls$padd, _defaultControls$marg, _defaultControls$bloc, _defaultControls$minH, _defaultControls$chil;
const decodeValue = rawValue => {
if (rawValue && typeof rawValue === 'object') {
return Object.keys(rawValue).reduce((acc, key) => {
acc[key] = (0, _utils.getValueFromVariable)({
settings
}, '', rawValue[key]);
return acc;
}, {});
}
return (0, _utils.getValueFromVariable)({
settings
}, '', rawValue);
};
const showSpacingPresetsControl = useHasSpacingPresets(settings);
const units = (0, _components.__experimentalUseCustomUnits)({
availableUnits: settings?.spacing?.units || ['%', 'px', 'em', 'rem', 'vw']
}); // Content Size
const showContentSizeControl = useHasContentSize(settings) && includeLayoutControls;
const contentSizeValue = decodeValue(inheritedValue?.layout?.contentSize);
const setContentSizeValue = newValue => {
onChange((0, _object.setImmutably)(value, ['layout', 'contentSize'], newValue || undefined));
};
const hasUserSetContentSizeValue = () => !!value?.layout?.contentSize;
const resetContentSizeValue = () => setContentSizeValue(undefined); // Wide Size
const showWideSizeControl = useHasWideSize(settings) && includeLayoutControls;
const wideSizeValue = decodeValue(inheritedValue?.layout?.wideSize);
const setWideSizeValue = newValue => {
onChange((0, _object.setImmutably)(value, ['layout', 'wideSize'], newValue || undefined));
};
const hasUserSetWideSizeValue = () => !!value?.layout?.wideSize;
const resetWideSizeValue = () => setWideSizeValue(undefined); // Padding
const showPaddingControl = useHasPadding(settings);
const rawPadding = decodeValue(inheritedValue?.spacing?.padding);
const paddingValues = splitStyleValue(rawPadding);
const paddingSides = Array.isArray(settings?.spacing?.padding) ? settings?.spacing?.padding : settings?.spacing?.padding?.sides;
const isAxialPadding = paddingSides && paddingSides.some(side => AXIAL_SIDES.includes(side));
const setPaddingValues = newPaddingValues => {
const padding = filterValuesBySides(newPaddingValues, paddingSides);
onChange((0, _object.setImmutably)(value, ['spacing', 'padding'], padding));
};
const hasPaddingValue = () => !!value?.spacing?.padding && Object.keys(value?.spacing?.padding).length;
const resetPaddingValue = () => setPaddingValues(undefined);
const onMouseOverPadding = () => onVisualize('padding'); // Margin
const showMarginControl = useHasMargin(settings);
const rawMargin = decodeValue(inheritedValue?.spacing?.margin);
const marginValues = splitStyleValue(rawMargin);
const marginSides = Array.isArray(settings?.spacing?.margin) ? settings?.spacing?.margin : settings?.spacing?.margin?.sides;
const isAxialMargin = marginSides && marginSides.some(side => AXIAL_SIDES.includes(side));
const setMarginValues = newMarginValues => {
const margin = filterValuesBySides(newMarginValues, marginSides);
onChange((0, _object.setImmutably)(value, ['spacing', 'margin'], margin));
};
const hasMarginValue = () => !!value?.spacing?.margin && Object.keys(value?.spacing?.margin).length;
const resetMarginValue = () => setMarginValues(undefined);
const onMouseOverMargin = () => onVisualize('margin'); // Block Gap
const showGapControl = useHasGap(settings);
const gapValue = decodeValue(inheritedValue?.spacing?.blockGap);
const gapValues = splitGapValue(gapValue);
const gapSides = Array.isArray(settings?.spacing?.blockGap) ? settings?.spacing?.blockGap : settings?.spacing?.blockGap?.sides;
const isAxialGap = gapSides && gapSides.some(side => AXIAL_SIDES.includes(side));
const setGapValue = newGapValue => {
onChange((0, _object.setImmutably)(value, ['spacing', 'blockGap'], newGapValue));
};
const setGapValues = nextBoxGapValue => {
if (!nextBoxGapValue) {
setGapValue(null);
} // If axial gap is not enabled, treat the 'top' value as the shorthand gap value.
if (!isAxialGap && nextBoxGapValue?.hasOwnProperty('top')) {
setGapValue(nextBoxGapValue.top);
} else {
setGapValue({
top: nextBoxGapValue?.top,
left: nextBoxGapValue?.left
});
}
};
const resetGapValue = () => setGapValue(undefined);
const hasGapValue = () => !!value?.spacing?.blockGap; // Min Height
const showMinHeightControl = useHasMinHeight(settings);
const minHeightValue = decodeValue(inheritedValue?.dimensions?.minHeight);
const setMinHeightValue = newValue => {
onChange((0, _object.setImmutably)(value, ['dimensions', 'minHeight'], newValue));
};
const resetMinHeightValue = () => {
setMinHeightValue(undefined);
};
const hasMinHeightValue = () => !!value?.dimensions?.minHeight; // Child Layout
const showChildLayoutControl = useHasChildLayout(settings);
const childLayout = inheritedValue?.layout;
const {
orientation = 'horizontal'
} = (_settings$parentLayou2 = settings?.parentLayout) !== null && _settings$parentLayou2 !== void 0 ? _settings$parentLayou2 : {};
const childLayoutOrientationLabel = orientation === 'horizontal' ? (0, _i18n.__)('Width') : (0, _i18n.__)('Height');
const setChildLayout = newChildLayout => {
onChange({ ...value,
layout: { ...value?.layout,
...newChildLayout
}
});
};
const resetChildLayoutValue = () => {
setChildLayout({
selfStretch: undefined,
flexSize: undefined
});
};
const hasChildLayoutValue = () => !!value?.layout;
const resetAllFilter = (0, _element.useCallback)(previousValue => {
return { ...previousValue,
layout: (0, _utils2.cleanEmptyObject)({ ...previousValue?.layout,
contentSize: undefined,
wideSize: undefined,
selfStretch: undefined,
flexSize: undefined
}),
spacing: { ...previousValue?.spacing,
padding: undefined,
margin: undefined,
blockGap: undefined
},
dimensions: { ...previousValue?.dimensions,
minHeight: undefined
}
};
}, []);
const onMouseLeaveControls = () => onVisualize(false);
return (0, _element.createElement)(Wrapper, {
resetAllFilter: resetAllFilter,
value: value,
onChange: onChange,
panelId: panelId
}, (showContentSizeControl || showWideSizeControl) && (0, _element.createElement)("span", {
className: "span-columns"
}, (0, _i18n.__)('Set the width of the main content area.')), showContentSizeControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
className: "single-column",
label: (0, _i18n.__)('Content size'),
hasValue: hasUserSetContentSizeValue,
onDeselect: resetContentSizeValue,
isShownByDefault: (_defaultControls$cont = defaultControls.contentSize) !== null && _defaultControls$cont !== void 0 ? _defaultControls$cont : DEFAULT_CONTROLS.contentSize,
panelId: panelId
}, (0, _element.createElement)(_components.__experimentalHStack, {
alignment: "flex-end",
justify: "flex-start"
}, (0, _element.createElement)(_components.__experimentalUnitControl, {
label: (0, _i18n.__)('Content'),
labelPosition: "top",
__unstableInputWidth: "80px",
value: contentSizeValue || '',
onChange: nextContentSize => {
setContentSizeValue(nextContentSize);
},
units: units
}), (0, _element.createElement)(_components.__experimentalView, null, (0, _element.createElement)(_icons.Icon, {
icon: _icons.positionCenter
})))), showWideSizeControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
className: "single-column",
label: (0, _i18n.__)('Wide size'),
hasValue: hasUserSetWideSizeValue,
onDeselect: resetWideSizeValue,
isShownByDefault: (_defaultControls$wide = defaultControls.wideSize) !== null && _defaultControls$wide !== void 0 ? _defaultControls$wide : DEFAULT_CONTROLS.wideSize,
panelId: panelId
}, (0, _element.createElement)(_components.__experimentalHStack, {
alignment: "flex-end",
justify: "flex-start"
}, (0, _element.createElement)(_components.__experimentalUnitControl, {
label: (0, _i18n.__)('Wide'),
labelPosition: "top",
__unstableInputWidth: "80px",
value: wideSizeValue || '',
onChange: nextWideSize => {
setWideSizeValue(nextWideSize);
},
units: units
}), (0, _element.createElement)(_components.__experimentalView, null, (0, _element.createElement)(_icons.Icon, {
icon: _icons.stretchWide
})))), showPaddingControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
hasValue: hasPaddingValue,
label: (0, _i18n.__)('Padding'),
onDeselect: resetPaddingValue,
isShownByDefault: (_defaultControls$padd = defaultControls.padding) !== null && _defaultControls$padd !== void 0 ? _defaultControls$padd : DEFAULT_CONTROLS.padding,
className: (0, _classnames.default)({
'tools-panel-item-spacing': showSpacingPresetsControl
}),
panelId: panelId
}, !showSpacingPresetsControl && (0, _element.createElement)(_components.__experimentalBoxControl, {
values: paddingValues,
onChange: setPaddingValues,
label: (0, _i18n.__)('Padding'),
sides: paddingSides,
units: units,
allowReset: false,
splitOnAxis: isAxialPadding,
onMouseOver: onMouseOverPadding,
onMouseOut: onMouseLeaveControls
}), showSpacingPresetsControl && (0, _element.createElement)(_spacingSizesControl.default, {
values: paddingValues,
onChange: setPaddingValues,
label: (0, _i18n.__)('Padding'),
sides: paddingSides,
units: units,
allowReset: false,
onMouseOver: onMouseOverPadding,
onMouseOut: onMouseLeaveControls
})), showMarginControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
hasValue: hasMarginValue,
label: (0, _i18n.__)('Margin'),
onDeselect: resetMarginValue,
isShownByDefault: (_defaultControls$marg = defaultControls.margin) !== null && _defaultControls$marg !== void 0 ? _defaultControls$marg : DEFAULT_CONTROLS.margin,
className: (0, _classnames.default)({
'tools-panel-item-spacing': showSpacingPresetsControl
}),
panelId: panelId
}, !showSpacingPresetsControl && (0, _element.createElement)(_components.__experimentalBoxControl, {
values: marginValues,
onChange: setMarginValues,
label: (0, _i18n.__)('Margin'),
sides: marginSides,
units: units,
allowReset: false,
splitOnAxis: isAxialMargin,
onMouseOver: onMouseOverMargin,
onMouseOut: onMouseLeaveControls
}), showSpacingPresetsControl && (0, _element.createElement)(_spacingSizesControl.default, {
values: marginValues,
onChange: setMarginValues,
label: (0, _i18n.__)('Margin'),
sides: marginSides,
units: units,
allowReset: false,
onMouseOver: onMouseOverMargin,
onMouseOut: onMouseLeaveControls
})), showGapControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
hasValue: hasGapValue,
label: (0, _i18n.__)('Block spacing'),
onDeselect: resetGapValue,
isShownByDefault: (_defaultControls$bloc = defaultControls.blockGap) !== null && _defaultControls$bloc !== void 0 ? _defaultControls$bloc : DEFAULT_CONTROLS.blockGap,
className: (0, _classnames.default)({
'tools-panel-item-spacing': showSpacingPresetsControl
}),
panelId: panelId
}, !showSpacingPresetsControl && (isAxialGap ? (0, _element.createElement)(_components.__experimentalBoxControl, {
label: (0, _i18n.__)('Block spacing'),
min: 0,
onChange: setGapValues,
units: units,
sides: gapSides,
values: gapValues,
allowReset: false,
splitOnAxis: isAxialGap
}) : (0, _element.createElement)(_components.__experimentalUnitControl, {
label: (0, _i18n.__)('Block spacing'),
__unstableInputWidth: "80px",
min: 0,
onChange: setGapValue,
units: units,
value: gapValue
})), showSpacingPresetsControl && (0, _element.createElement)(_spacingSizesControl.default, {
label: (0, _i18n.__)('Block spacing'),
min: 0,
onChange: setGapValues,
showSideInLabel: false,
sides: isAxialGap ? gapSides : ['top'] // Use 'top' as the shorthand property in non-axial configurations.
,
values: gapValues,
allowReset: false
})), showMinHeightControl && (0, _element.createElement)(_components.__experimentalToolsPanelItem, {
hasValue: hasMinHeightValue,
label: (0, _i18n.__)('Min. height'),
onDeselect: resetMinHeightValue,
isShownByDefault: (_defaultControls$minH = defaultControls.minHeight) !== null && _defaultControls$minH !== void 0 ? _defaultControls$minH : DEFAULT_CONTROLS.minHeight,
panelId: panelId
}, (0, _element.createElement)(_heightControl.default, {
label: (0, _i18n.__)('Min. height'),
value: minHeightValue,
onChange: setMinHeightValue
})), showChildLayoutControl && (0, _element.createElement)(_components.__experimentalVStack, {
as: _components.__experimentalToolsPanelItem,
spacing: 2,
hasValue: hasChildLayoutValue,
label: childLayoutOrientationLabel,
onDeselect: resetChildLayoutValue,
isShownByDefault: (_defaultControls$chil = defaultControls.childLayout) !== null && _defaultControls$chil !== void 0 ? _defaultControls$chil : DEFAULT_CONTROLS.childLayout,
panelId: panelId
}, (0, _element.createElement)(_childLayoutControl.default, {
value: childLayout,
onChange: setChildLayout,
parentLayout: settings?.parentLayout
})));
}
//# sourceMappingURL=dimensions-panel.js.map