@wordpress/block-editor
Version:
177 lines (171 loc) • 5.79 kB
JavaScript
/**
* External dependencies
*/
import clsx from 'clsx';
/**
* WordPress dependencies
*/
import { Platform, useState, useEffect, useCallback } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { getBlockSupport } from '@wordpress/blocks';
import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
*/
import InspectorControls from '../components/inspector-controls';
import { DimensionsPanel as StylesDimensionsPanel, useHasDimensionsPanel } from '../components/global-styles';
import { MarginVisualizer, PaddingVisualizer } from './spacing-visualizer';
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';
import { cleanEmptyObject, shouldSkipSerialization } from './utils';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
export const DIMENSIONS_SUPPORT_KEY = 'dimensions';
export const SPACING_SUPPORT_KEY = 'spacing';
export const ALL_SIDES = ['top', 'right', 'bottom', 'left'];
export const AXIAL_SIDES = ['vertical', 'horizontal'];
function useVisualizer() {
const [property, setProperty] = useState(false);
const {
hideBlockInterface,
showBlockInterface
} = unlock(useDispatch(blockEditorStore));
useEffect(() => {
if (!property) {
showBlockInterface();
} else {
hideBlockInterface();
}
}, [property, showBlockInterface, hideBlockInterface]);
return [property, setProperty];
}
function DimensionsInspectorControl({
children,
resetAllFilter
}) {
const attributesResetAllFilter = useCallback(attributes => {
const existingStyle = attributes.style;
const updatedStyle = resetAllFilter(existingStyle);
return {
...attributes,
style: updatedStyle
};
}, [resetAllFilter]);
return /*#__PURE__*/_jsx(InspectorControls, {
group: "dimensions",
resetAllFilter: attributesResetAllFilter,
children: children
});
}
export function DimensionsPanel({
clientId,
name,
setAttributes,
settings
}) {
const isEnabled = useHasDimensionsPanel(settings);
const value = useSelect(select => select(blockEditorStore).getBlockAttributes(clientId)?.style, [clientId]);
const [visualizedProperty, setVisualizedProperty] = useVisualizer();
const onChange = newStyle => {
setAttributes({
style: cleanEmptyObject(newStyle)
});
};
if (!isEnabled) {
return null;
}
const defaultDimensionsControls = getBlockSupport(name, [DIMENSIONS_SUPPORT_KEY, '__experimentalDefaultControls']);
const defaultSpacingControls = getBlockSupport(name, [SPACING_SUPPORT_KEY, '__experimentalDefaultControls']);
const defaultControls = {
...defaultDimensionsControls,
...defaultSpacingControls
};
return /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(StylesDimensionsPanel, {
as: DimensionsInspectorControl,
panelId: clientId,
settings: settings,
value: value,
onChange: onChange,
defaultControls: defaultControls,
onVisualize: setVisualizedProperty
}), !!settings?.spacing?.padding && /*#__PURE__*/_jsx(PaddingVisualizer, {
forceShow: visualizedProperty === 'padding',
clientId: clientId,
value: value
}), !!settings?.spacing?.margin && /*#__PURE__*/_jsx(MarginVisualizer, {
forceShow: visualizedProperty === 'margin',
clientId: clientId,
value: value
})]
});
}
/**
* Determine whether there is block support for dimensions.
*
* @param {string} blockName Block name.
* @param {string} feature Background image feature to check for.
*
* @return {boolean} Whether there is support.
*/
export function hasDimensionsSupport(blockName, feature = 'any') {
if (Platform.OS !== 'web') {
return false;
}
const support = getBlockSupport(blockName, DIMENSIONS_SUPPORT_KEY);
if (support === true) {
return true;
}
if (feature === 'any') {
return !!(support?.aspectRatio || !!support?.minHeight);
}
return !!support?.[feature];
}
export default {
useBlockProps,
attributeKeys: ['minHeight', 'style'],
hasSupport(name) {
return hasDimensionsSupport(name, 'aspectRatio');
}
};
function useBlockProps({
name,
minHeight,
style
}) {
if (!hasDimensionsSupport(name, 'aspectRatio') || shouldSkipSerialization(name, DIMENSIONS_SUPPORT_KEY, 'aspectRatio')) {
return {};
}
const className = clsx({
'has-aspect-ratio': !!style?.dimensions?.aspectRatio
});
// Allow dimensions-based inline style overrides to override any global styles rules that
// might be set for the block, and therefore affect the display of the aspect ratio.
const inlineStyleOverrides = {};
// Apply rules to unset incompatible styles.
// Note that a set `aspectRatio` will win out if both an aspect ratio and a minHeight are set.
// This is because the aspect ratio is a newer block support, so (in theory) any aspect ratio
// that is set should be intentional and should override any existing minHeight. The Cover block
// and dimensions controls have logic that will manually clear the aspect ratio if a minHeight
// is set.
if (style?.dimensions?.aspectRatio) {
// To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule.
inlineStyleOverrides.minHeight = 'unset';
} else if (minHeight || style?.dimensions?.minHeight) {
// To ensure the minHeight does not get overridden by `aspectRatio` unset any existing rule.
inlineStyleOverrides.aspectRatio = 'unset';
}
return {
className,
style: inlineStyleOverrides
};
}
/**
* @deprecated
*/
export function useCustomSides() {
deprecated('wp.blockEditor.__experimentalUseCustomSides', {
since: '6.3',
version: '6.4'
});
}
//# sourceMappingURL=dimensions.js.map