@wordpress/block-editor
Version:
141 lines (139 loc) • 4.94 kB
JavaScript
/**
* WordPress dependencies
*/
import { BaseControl, __experimentalHStack as HStack, __experimentalVStack as VStack } from '@wordpress/components';
import { useState } from '@wordpress/element';
import { _x, sprintf } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import useSpacingSizes from './hooks/use-spacing-sizes';
import AxialInputControls from './input-controls/axial';
import SeparatedInputControls from './input-controls/separated';
import SingleInputControl from './input-controls/single';
import LinkedButton from './linked-button';
import { ALL_SIDES, DEFAULT_VALUES, LABELS, VIEWS, getInitialView } from './utils';
/**
* A flexible control for managing spacing values in the block editor. Supports single, axial,
* and separated input controls for different spacing configurations with automatic view selection
* based on current values and available sides.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/spacing-sizes-control/README.md
*
* @example
* ```jsx
* import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor';
* import { useState } from '@wordpress/element';
*
* function Example() {
* const [ sides, setSides ] = useState( {
* top: '0px',
* right: '0px',
* bottom: '0px',
* left: '0px',
* } );
*
* return (
* <SpacingSizesControl
* values={ sides }
* onChange={ setSides }
* label="Sides"
* />
* );
* }
* ```
*
* @param {Object} props Component props.
* @param {Object} props.inputProps Additional props for input controls.
* @param {string} props.label Label for the control.
* @param {number} props.minimumCustomValue Minimum value for custom input.
* @param {Function} props.onChange Called when spacing values change.
* @param {Function} props.onMouseOut Called when mouse leaves the control.
* @param {Function} props.onMouseOver Called when mouse enters the control.
* @param {boolean} props.showSideInLabel Show side in control label.
* @param {Array} props.sides Available sides for control.
* @param {boolean} props.useSelect Use select control for predefined values.
* @param {Object} props.values Current spacing values.
* @return {Element} Spacing sizes control component.
*/
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
export default function SpacingSizesControl({
inputProps,
label: labelProp,
minimumCustomValue = 0,
onChange,
onMouseOut,
onMouseOver,
showSideInLabel = true,
sides = ALL_SIDES,
useSelect,
values
}) {
const spacingSizes = useSpacingSizes();
const inputValues = values || DEFAULT_VALUES;
const hasOneSide = sides?.length === 1;
const hasOnlyAxialSides = sides?.includes('horizontal') && sides?.includes('vertical') && sides?.length === 2;
const [view, setView] = useState(getInitialView(inputValues, sides));
const toggleLinked = () => {
setView(view === VIEWS.axial ? VIEWS.custom : VIEWS.axial);
};
const handleOnChange = nextValue => {
const newValues = {
...values,
...nextValue
};
onChange(newValues);
};
const inputControlProps = {
...inputProps,
minimumCustomValue,
onChange: handleOnChange,
onMouseOut,
onMouseOver,
sides,
spacingSizes,
type: labelProp,
useSelect,
values: inputValues
};
const renderControls = () => {
if (view === VIEWS.axial) {
return /*#__PURE__*/_jsx(AxialInputControls, {
...inputControlProps
});
}
if (view === VIEWS.custom) {
return /*#__PURE__*/_jsx(SeparatedInputControls, {
...inputControlProps
});
}
return /*#__PURE__*/_jsx(SingleInputControl, {
side: view,
...inputControlProps,
showSideInLabel: showSideInLabel
});
};
const sideLabel = ALL_SIDES.includes(view) && showSideInLabel ? LABELS[view] : '';
const label = sprintf(
// translators: 1: The side of the block being modified (top, bottom, left etc.). 2. Type of spacing being modified (padding, margin, etc).
_x('%1$s %2$s', 'spacing'), labelProp, sideLabel).trim();
return /*#__PURE__*/_jsxs("fieldset", {
className: "spacing-sizes-control",
children: [/*#__PURE__*/_jsxs(HStack, {
className: "spacing-sizes-control__header",
children: [/*#__PURE__*/_jsx(BaseControl.VisualLabel, {
as: "legend",
className: "spacing-sizes-control__label",
children: label
}), !hasOneSide && !hasOnlyAxialSides && /*#__PURE__*/_jsx(LinkedButton, {
label: labelProp,
onClick: toggleLinked,
isLinked: view === VIEWS.axial
})]
}), /*#__PURE__*/_jsx(VStack, {
spacing: 0.5,
children: renderControls()
})]
});
}
//# sourceMappingURL=index.js.map