UNPKG

@wordpress/components

Version:
213 lines (212 loc) 8.26 kB
/** * WordPress dependencies */ import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; import { settings } from '@wordpress/icons'; /** * Internal dependencies */ import Tooltip from '../tooltip'; import { parseQuantityAndUnitFromRawValue } from '../unit-control/utils'; import { CUSTOM_VALUE_SETTINGS, getMergedValue, getAllowedSides, getPresetIndexFromValue, getPresetValueFromIndex, isValuePreset, isValuesDefined, isValueMixed, LABELS } from './utils'; import { FlexedBoxControlIcon, FlexedRangeControl, InputWrapper, StyledUnitControl } from './styles/box-control-styles'; import Button from '../button'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const noop = () => {}; function getSidesToModify(side, sides, isAlt) { const allowedSides = getAllowedSides(sides); let modifiedSides = []; switch (side) { case 'all': modifiedSides = ['top', 'bottom', 'left', 'right']; break; case 'horizontal': modifiedSides = ['left', 'right']; break; case 'vertical': modifiedSides = ['top', 'bottom']; break; default: modifiedSides = [side]; } if (isAlt) { switch (side) { case 'top': modifiedSides.push('bottom'); break; case 'bottom': modifiedSides.push('top'); break; case 'left': modifiedSides.push('left'); break; case 'right': modifiedSides.push('right'); break; } } return modifiedSides.filter(s => allowedSides.has(s)); } export default function BoxInputControl({ __next40pxDefaultSize, onChange = noop, onFocus = noop, values, selectedUnits, setSelectedUnits, sides, side, min = 0, presets, presetKey, ...props }) { var _CUSTOM_VALUE_SETTING, _CUSTOM_VALUE_SETTING2; const defaultValuesToModify = getSidesToModify(side, sides); const handleOnFocus = event => { onFocus(event, { side }); }; const handleOnChange = nextValues => { onChange(nextValues); }; const handleRawOnValueChange = next => { const nextValues = { ...values }; defaultValuesToModify.forEach(modifiedSide => { nextValues[modifiedSide] = next; }); handleOnChange(nextValues); }; const handleOnValueChange = (next, extra) => { const nextValues = { ...values }; const isNumeric = next !== undefined && !isNaN(parseFloat(next)); const nextValue = isNumeric ? next : undefined; const modifiedSides = getSidesToModify(side, sides, /** * Supports changing pair sides. For example, holding the ALT key * when changing the TOP will also update BOTTOM. */ // @ts-expect-error - TODO: event.altKey is only present when the change event was // triggered by a keyboard event. Should this feature be implemented differently so // it also works with drag events? !!extra?.event.altKey); modifiedSides.forEach(modifiedSide => { nextValues[modifiedSide] = nextValue; }); handleOnChange(nextValues); }; const handleOnUnitChange = next => { const newUnits = { ...selectedUnits }; defaultValuesToModify.forEach(modifiedSide => { newUnits[modifiedSide] = next; }); setSelectedUnits(newUnits); }; const mergedValue = getMergedValue(values, defaultValuesToModify); const hasValues = isValuesDefined(values); const isMixed = hasValues && defaultValuesToModify.length > 1 && isValueMixed(values, defaultValuesToModify); const [parsedQuantity, parsedUnit] = parseQuantityAndUnitFromRawValue(mergedValue); const computedUnit = hasValues ? parsedUnit : selectedUnits[defaultValuesToModify[0]]; const generatedId = useInstanceId(BoxInputControl, 'box-control-input'); const inputId = [generatedId, side].join('-'); const isMixedUnit = defaultValuesToModify.length > 1 && mergedValue === undefined && defaultValuesToModify.some(s => selectedUnits[s] !== computedUnit); const usedValue = mergedValue === undefined && computedUnit ? computedUnit : mergedValue; const mixedPlaceholder = isMixed || isMixedUnit ? __('Mixed') : undefined; const hasPresets = presets && presets.length > 0 && presetKey; const hasPresetValue = hasPresets && mergedValue !== undefined && !isMixed && isValuePreset(mergedValue, presetKey); const [showCustomValueControl, setShowCustomValueControl] = useState(!hasPresets || !hasPresetValue && !isMixed && mergedValue !== undefined); const presetIndex = hasPresetValue ? getPresetIndexFromValue(mergedValue, presetKey, presets) : undefined; const marks = hasPresets ? [{ value: 0, label: '', tooltip: __('None') }, ...presets.map((preset, index) => { var _preset$name; return { value: index + 1, label: '', tooltip: (_preset$name = preset.name) !== null && _preset$name !== void 0 ? _preset$name : preset.slug }; })] : []; return /*#__PURE__*/_jsxs(InputWrapper, { expanded: true, children: [/*#__PURE__*/_jsx(FlexedBoxControlIcon, { side: side, sides: sides }), showCustomValueControl && /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(Tooltip, { placement: "top-end", text: LABELS[side], children: /*#__PURE__*/_jsx(StyledUnitControl, { ...props, min: min, __shouldNotWarnDeprecated36pxSize: true, __next40pxDefaultSize: __next40pxDefaultSize, className: "component-box-control__unit-control", id: inputId, isPressEnterToChange: true, disableUnits: isMixed || isMixedUnit, value: usedValue, onChange: handleOnValueChange, onUnitChange: handleOnUnitChange, onFocus: handleOnFocus, label: LABELS[side], placeholder: mixedPlaceholder, hideLabelFromVision: true }) }), /*#__PURE__*/_jsx(FlexedRangeControl, { __nextHasNoMarginBottom: true, __next40pxDefaultSize: __next40pxDefaultSize, __shouldNotWarnDeprecated36pxSize: true, "aria-controls": inputId, label: LABELS[side], hideLabelFromVision: true, onChange: newValue => { handleOnValueChange(newValue !== undefined ? [newValue, computedUnit].join('') : undefined); }, min: isFinite(min) ? min : 0, max: (_CUSTOM_VALUE_SETTING = CUSTOM_VALUE_SETTINGS[computedUnit !== null && computedUnit !== void 0 ? computedUnit : 'px']?.max) !== null && _CUSTOM_VALUE_SETTING !== void 0 ? _CUSTOM_VALUE_SETTING : 10, step: (_CUSTOM_VALUE_SETTING2 = CUSTOM_VALUE_SETTINGS[computedUnit !== null && computedUnit !== void 0 ? computedUnit : 'px']?.step) !== null && _CUSTOM_VALUE_SETTING2 !== void 0 ? _CUSTOM_VALUE_SETTING2 : 0.1, value: parsedQuantity !== null && parsedQuantity !== void 0 ? parsedQuantity : 0, withInputField: false })] }), hasPresets && !showCustomValueControl && /*#__PURE__*/_jsx(FlexedRangeControl, { __next40pxDefaultSize: true, className: "spacing-sizes-control__range-control", value: presetIndex !== undefined ? presetIndex + 1 : 0, onChange: newIndex => { const newValue = newIndex === 0 || newIndex === undefined ? undefined : getPresetValueFromIndex(newIndex - 1, presetKey, presets); handleRawOnValueChange(newValue); }, withInputField: false, "aria-valuenow": presetIndex !== undefined ? presetIndex + 1 : 0, "aria-valuetext": marks[presetIndex !== undefined ? presetIndex + 1 : 0].tooltip, renderTooltipContent: index => marks[!index ? 0 : index].tooltip, min: 0, max: marks.length - 1, marks: marks, label: LABELS[side], hideLabelFromVision: true, __nextHasNoMarginBottom: true }), hasPresets && /*#__PURE__*/_jsx(Button, { label: showCustomValueControl ? __('Use size preset') : __('Set custom size'), icon: settings, onClick: () => { setShowCustomValueControl(!showCustomValueControl); }, isPressed: showCustomValueControl, size: "small", iconSize: 24 })] }, `box-control-${side}`); } //# sourceMappingURL=input-control.js.map