UNPKG

@wordpress/block-editor

Version:
543 lines (457 loc) 18.9 kB
"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