UNPKG

@wordpress/block-editor

Version:
205 lines (185 loc) 6.73 kB
/** * WordPress dependencies */ import { useState } from '@wordpress/element'; /** * Internal dependencies */ import AspectRatioTool from './aspect-ratio-tool'; import ScaleTool from './scale-tool'; import WidthHeightTool from './width-height-tool'; /** * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps */ /** * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit */ /** * @typedef {Object} Dimensions * @property {string} [width] CSS width property. * @property {string} [height] CSS height property. * @property {string} [scale] CSS object-fit property. * @property {string} [aspectRatio] CSS aspect-ratio property. */ /** * @callback DimensionsControlsOnChange * @param {Dimensions} nextValue * @return {void} */ /** * @typedef {Object} DimensionsControlsProps * @property {string} [panelId] ID of the panel that contains the controls. * @property {Dimensions} [value] Current dimensions values. * @property {DimensionsControlsOnChange} [onChange] Callback to update the dimensions values. * @property {SelectControlProps[]} [aspectRatioOptions] Aspect ratio options. * @property {SelectControlProps[]} [scaleOptions] Scale options. * @property {WPUnitControlUnit[]} [unitsOptions] Units options. */ /** * Component that renders controls to edit the dimensions of an image or container. * * @param {DimensionsControlsProps} props The component props. * * @return {Element} The dimensions controls. */ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; function DimensionsTool({ panelId, value = {}, onChange = () => {}, aspectRatioOptions, // Default options handled by AspectRatioTool. defaultAspectRatio = 'auto', // Match CSS default value for aspect-ratio. scaleOptions, // Default options handled by ScaleTool. defaultScale = 'fill', // Match CSS default value for object-fit. unitsOptions, // Default options handled by UnitControl. tools = ['aspectRatio', 'widthHeight', 'scale'] }) { // Coerce undefined and CSS default values to be null. const width = value.width === undefined || value.width === 'auto' ? null : value.width; const height = value.height === undefined || value.height === 'auto' ? null : value.height; const aspectRatio = value.aspectRatio === undefined || value.aspectRatio === 'auto' ? null : value.aspectRatio; const scale = value.scale === undefined || value.scale === 'fill' ? null : value.scale; // Keep track of state internally, so when the value is cleared by means // other than directly editing that field, it's easier to restore the // previous value. const [lastScale, setLastScale] = useState(scale); const [lastAspectRatio, setLastAspectRatio] = useState(aspectRatio); // 'custom' is not a valid value for CSS aspect-ratio, but it is used in the // dropdown to indicate that setting both the width and height is the same // as a custom aspect ratio. const aspectRatioValue = width && height ? 'custom' : lastAspectRatio; const showScaleControl = aspectRatio || width && height; return /*#__PURE__*/_jsxs(_Fragment, { children: [tools.includes('aspectRatio') && /*#__PURE__*/_jsx(AspectRatioTool, { panelId: panelId, options: aspectRatioOptions, defaultValue: defaultAspectRatio, value: aspectRatioValue, onChange: nextAspectRatio => { const nextValue = { ...value }; // 'auto' is CSS default, so it gets treated as null. nextAspectRatio = nextAspectRatio === 'auto' ? null : nextAspectRatio; setLastAspectRatio(nextAspectRatio); // Update aspectRatio. if (!nextAspectRatio) { delete nextValue.aspectRatio; } else { nextValue.aspectRatio = nextAspectRatio; } // Auto-update scale. if (!nextAspectRatio) { delete nextValue.scale; } else if (lastScale) { nextValue.scale = lastScale; } else { nextValue.scale = defaultScale; setLastScale(defaultScale); } // Auto-update width and height. if ('custom' !== nextAspectRatio && width && height) { delete nextValue.height; } onChange(nextValue); } }), tools.includes('widthHeight') && /*#__PURE__*/_jsx(WidthHeightTool, { panelId: panelId, units: unitsOptions, value: { width, height }, onChange: ({ width: nextWidth, height: nextHeight }) => { const nextValue = { ...value }; // 'auto' is CSS default, so it gets treated as null. nextWidth = nextWidth === 'auto' ? null : nextWidth; nextHeight = nextHeight === 'auto' ? null : nextHeight; // Update width. if (!nextWidth) { delete nextValue.width; } else { nextValue.width = nextWidth; } // Update height. if (!nextHeight) { delete nextValue.height; } else { nextValue.height = nextHeight; } // Auto-update aspectRatio. if (nextWidth && nextHeight) { delete nextValue.aspectRatio; } else if (lastAspectRatio) { nextValue.aspectRatio = lastAspectRatio; } else { // No setting defaultAspectRatio here, because // aspectRatio is optional in this scenario, // unlike scale. } // Auto-update scale. if (!lastAspectRatio && !!nextWidth !== !!nextHeight) { delete nextValue.scale; } else if (lastScale) { nextValue.scale = lastScale; } else { nextValue.scale = defaultScale; setLastScale(defaultScale); } onChange(nextValue); } }), tools.includes('scale') && showScaleControl && /*#__PURE__*/_jsx(ScaleTool, { panelId: panelId, options: scaleOptions, defaultValue: defaultScale, value: lastScale, onChange: nextScale => { const nextValue = { ...value }; // 'fill' is CSS default, so it gets treated as null. nextScale = nextScale === 'fill' ? null : nextScale; setLastScale(nextScale); // Update scale. if (!nextScale) { delete nextValue.scale; } else { nextValue.scale = nextScale; } onChange(nextValue); } })] }); } export default DimensionsTool; //# sourceMappingURL=index.js.map