@wordpress/components
Version:
UI components for WordPress.
192 lines (187 loc) • 6.45 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "applyValueToSides", {
enumerable: true,
get: function () {
return _utils2.applyValueToSides;
}
});
exports.default = void 0;
var _compose = require("@wordpress/compose");
var _element = require("@wordpress/element");
var _i18n = require("@wordpress/i18n");
var _warning = _interopRequireDefault(require("@wordpress/warning"));
var _baseControl = require("../base-control");
var _inputControl = _interopRequireDefault(require("./input-control"));
var _linkedButton = _interopRequireDefault(require("./linked-button"));
var _grid = require("../grid");
var _boxControlStyles = require("./styles/box-control-styles");
var _utils = require("../unit-control/utils");
var _utils2 = require("./utils");
var _hooks = require("../utils/hooks");
var _deprecated36pxSize = require("../utils/deprecated-36px-size");
var _jsxRuntime = require("react/jsx-runtime");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const defaultInputProps = {
min: 0
};
const noop = () => {};
function useUniqueId(idProp) {
const instanceId = (0, _compose.useInstanceId)(BoxControl, 'inspector-box-control');
return idProp || instanceId;
}
/**
* A control that lets users set values for top, right, bottom, and left. Can be
* used as an input control for values like `padding` or `margin`.
*
* ```jsx
* import { useState } from 'react';
* import { BoxControl } from '@wordpress/components';
*
* function Example() {
* const [ values, setValues ] = useState( {
* top: '50px',
* left: '10%',
* right: '10%',
* bottom: '50px',
* } );
*
* return (
* <BoxControl
* __next40pxDefaultSize
* values={ values }
* onChange={ setValues }
* />
* );
* };
* ```
*/
function BoxControl({
__next40pxDefaultSize = false,
id: idProp,
inputProps = defaultInputProps,
onChange = noop,
label = (0, _i18n.__)('Box Control'),
values: valuesProp,
units,
sides,
splitOnAxis = false,
allowReset = true,
resetValues = _utils2.DEFAULT_VALUES,
presets,
presetKey,
onMouseOver,
onMouseOut
}) {
const [values, setValues] = (0, _hooks.useControlledState)(valuesProp, {
fallback: _utils2.DEFAULT_VALUES
});
const inputValues = values || _utils2.DEFAULT_VALUES;
const hasInitialValue = (0, _utils2.isValuesDefined)(valuesProp);
const hasOneSide = sides?.length === 1;
const [isDirty, setIsDirty] = (0, _element.useState)(hasInitialValue);
const [isLinked, setIsLinked] = (0, _element.useState)(!hasInitialValue || !(0, _utils2.isValueMixed)(inputValues) || hasOneSide);
const [side, setSide] = (0, _element.useState)((0, _utils2.getInitialSide)(isLinked, splitOnAxis));
// Tracking selected units via internal state allows filtering of CSS unit
// only values from being saved while maintaining preexisting unit selection
// behaviour. Filtering CSS only values prevents invalid style values.
const [selectedUnits, setSelectedUnits] = (0, _element.useState)({
top: (0, _utils.parseQuantityAndUnitFromRawValue)(valuesProp?.top)[1],
right: (0, _utils.parseQuantityAndUnitFromRawValue)(valuesProp?.right)[1],
bottom: (0, _utils.parseQuantityAndUnitFromRawValue)(valuesProp?.bottom)[1],
left: (0, _utils.parseQuantityAndUnitFromRawValue)(valuesProp?.left)[1]
});
const id = useUniqueId(idProp);
const headingId = `${id}-heading`;
const toggleLinked = () => {
setIsLinked(!isLinked);
setSide((0, _utils2.getInitialSide)(!isLinked, splitOnAxis));
};
const handleOnFocus = (_event, {
side: nextSide
}) => {
setSide(nextSide);
};
const handleOnChange = nextValues => {
onChange(nextValues);
setValues(nextValues);
setIsDirty(true);
};
const handleOnReset = () => {
onChange(resetValues);
setValues(resetValues);
setSelectedUnits(resetValues);
setIsDirty(false);
};
const inputControlProps = {
onMouseOver,
onMouseOut,
...inputProps,
onChange: handleOnChange,
onFocus: handleOnFocus,
isLinked,
units,
selectedUnits,
setSelectedUnits,
sides,
values: inputValues,
__next40pxDefaultSize,
presets,
presetKey
};
(0, _deprecated36pxSize.maybeWarnDeprecated36pxSize)({
componentName: 'BoxControl',
__next40pxDefaultSize,
size: undefined
});
const sidesToRender = (0, _utils2.getAllowedSides)(sides);
if (presets && !presetKey || !presets && presetKey) {
const definedProp = presets ? 'presets' : 'presetKey';
const missingProp = presets ? 'presetKey' : 'presets';
globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)(`wp.components.BoxControl: the '${missingProp}' prop is required when the '${definedProp}' prop is defined.`) : void 0;
}
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_grid.Grid, {
id: id,
columns: 3,
templateColumns: "1fr min-content min-content",
role: "group",
"aria-labelledby": headingId,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_baseControl.BaseControl.VisualLabel, {
id: headingId,
children: label
}), isLinked && /*#__PURE__*/(0, _jsxRuntime.jsx)(_boxControlStyles.InputWrapper, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_inputControl.default, {
side: "all",
...inputControlProps
})
}), !hasOneSide && /*#__PURE__*/(0, _jsxRuntime.jsx)(_boxControlStyles.LinkedButtonWrapper, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_linkedButton.default, {
onClick: toggleLinked,
isLinked: isLinked
})
}), !isLinked && splitOnAxis && ['vertical', 'horizontal'].map(axis => /*#__PURE__*/(0, _jsxRuntime.jsx)(_inputControl.default, {
side: axis,
...inputControlProps
}, axis)), !isLinked && !splitOnAxis && Array.from(sidesToRender).map(axis => /*#__PURE__*/(0, _jsxRuntime.jsx)(_inputControl.default, {
side: axis,
...inputControlProps
}, axis)), allowReset && /*#__PURE__*/(0, _jsxRuntime.jsx)(_boxControlStyles.ResetButton, {
className: "component-box-control__reset-button",
variant: "secondary",
size: "small",
onClick: handleOnReset,
disabled: !isDirty,
children: (0, _i18n.__)('Reset')
})]
});
}
var _default = exports.default = BoxControl;
//# sourceMappingURL=index.js.map