@wordpress/components
Version:
UI components for WordPress.
263 lines (262 loc) • 8.74 kB
JavaScript
import clsx from "clsx";
import { __, isRTL } from "@wordpress/i18n";
import { useRef, useState, forwardRef } from "@wordpress/element";
import { useInstanceId, useMergeRefs } from "@wordpress/compose";
import BaseControl from "../base-control";
import Button from "../button";
import Icon from "../icon";
import { COLORS } from "../utils";
import { floatClamp, useControlledRangeValue } from "./utils";
import { clamp } from "../utils/math";
import InputRange from "./input-range";
import RangeRail from "./rail";
import SimpleTooltip from "./tooltip";
import { ActionRightWrapper, AfterIconWrapper, BeforeIconWrapper, InputNumber, Root, Track, ThumbWrapper, Thumb, Wrapper } from "./styles/range-control-styles";
import { space } from "../utils/space";
import { maybeWarnDeprecated36pxSize } from "../utils/deprecated-36px-size";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const noop = () => {
};
function computeResetValue({
resetFallbackValue,
initialPosition
}) {
if (resetFallbackValue !== void 0) {
return !Number.isNaN(resetFallbackValue) ? resetFallbackValue : null;
}
if (initialPosition !== void 0) {
return !Number.isNaN(initialPosition) ? initialPosition : null;
}
return null;
}
function UnforwardedRangeControl(props, forwardedRef) {
const {
__nextHasNoMarginBottom = false,
afterIcon,
allowReset = false,
beforeIcon,
className,
color: colorProp = COLORS.theme.accent,
currentInput,
disabled = false,
help,
hideLabelFromVision = false,
initialPosition,
isShiftStepEnabled = true,
label,
marks = false,
max = 100,
min = 0,
onBlur = noop,
onChange = noop,
onFocus = noop,
onMouseLeave = noop,
onMouseMove = noop,
railColor,
renderTooltipContent = (v) => v,
resetFallbackValue,
__next40pxDefaultSize = false,
shiftStep = 10,
showTooltip: showTooltipProp,
step = 1,
trackColor,
value: valueProp,
withInputField = true,
__shouldNotWarnDeprecated36pxSize,
...otherProps
} = props;
const [value, setValue] = useControlledRangeValue({
min,
max,
value: valueProp !== null && valueProp !== void 0 ? valueProp : null,
initial: initialPosition
});
const isResetPendent = useRef(false);
let hasTooltip = showTooltipProp;
let hasInputField = withInputField;
if (step === "any") {
hasTooltip = false;
hasInputField = false;
}
const [showTooltip, setShowTooltip] = useState(hasTooltip);
const [isFocused, setIsFocused] = useState(false);
const inputRef = useRef();
const isCurrentlyFocused = inputRef.current?.matches(":focus");
const isThumbFocused = !disabled && isFocused;
const isValueReset = value === null;
const currentValue = value !== void 0 ? value : currentInput;
const inputSliderValue = isValueReset ? "" : currentValue;
const rangeFillValue = isValueReset ? (max - min) / 2 + min : value;
const fillValue = isValueReset ? 50 : (value - min) / (max - min) * 100;
const fillValueOffset = `${clamp(fillValue, 0, 100)}%`;
const classes = clsx("components-range-control", className);
const wrapperClasses = clsx("components-range-control__wrapper", !!marks && "is-marked");
const id = useInstanceId(UnforwardedRangeControl, "inspector-range-control");
const describedBy = !!help ? `${id}__help` : void 0;
const enableTooltip = hasTooltip !== false && Number.isFinite(value);
const handleOnRangeChange = (event) => {
const nextValue = parseFloat(event.target.value);
setValue(nextValue);
onChange(nextValue);
};
const handleOnChange = (next) => {
let nextValue = parseFloat(next);
setValue(nextValue);
if (!isNaN(nextValue)) {
if (nextValue < min || nextValue > max) {
nextValue = floatClamp(nextValue, min, max);
}
onChange(nextValue);
isResetPendent.current = false;
} else if (allowReset) {
isResetPendent.current = true;
}
};
const handleOnInputNumberBlur = () => {
if (isResetPendent.current) {
handleOnReset();
isResetPendent.current = false;
}
};
const handleOnReset = () => {
const resetValue = Number.isNaN(resetFallbackValue) ? null : resetFallbackValue !== null && resetFallbackValue !== void 0 ? resetFallbackValue : null;
setValue(resetValue);
onChange(resetValue !== null && resetValue !== void 0 ? resetValue : void 0);
};
const handleShowTooltip = () => setShowTooltip(true);
const handleHideTooltip = () => setShowTooltip(false);
const handleOnBlur = (event) => {
onBlur(event);
setIsFocused(false);
handleHideTooltip();
};
const handleOnFocus = (event) => {
onFocus(event);
setIsFocused(true);
handleShowTooltip();
};
const offsetStyle = {
[isRTL() ? "right" : "left"]: fillValueOffset
};
maybeWarnDeprecated36pxSize({
componentName: "RangeControl",
__next40pxDefaultSize,
size: void 0,
__shouldNotWarnDeprecated36pxSize
});
return /* @__PURE__ */ _jsx(BaseControl, {
__nextHasNoMarginBottom,
__associatedWPComponentName: "RangeControl",
className: classes,
label,
hideLabelFromVision,
id: `${id}`,
help,
children: /* @__PURE__ */ _jsxs(Root, {
className: "components-range-control__root",
__next40pxDefaultSize,
children: [beforeIcon && /* @__PURE__ */ _jsx(BeforeIconWrapper, {
children: /* @__PURE__ */ _jsx(Icon, {
icon: beforeIcon
})
}), /* @__PURE__ */ _jsxs(Wrapper, {
__nextHasNoMarginBottom,
className: wrapperClasses,
color: colorProp,
marks: !!marks,
children: [/* @__PURE__ */ _jsx(InputRange, {
...otherProps,
className: "components-range-control__slider",
describedBy,
disabled,
id: `${id}`,
label,
max,
min,
onBlur: handleOnBlur,
onChange: handleOnRangeChange,
onFocus: handleOnFocus,
onMouseMove,
onMouseLeave,
ref: useMergeRefs([inputRef, forwardedRef]),
step,
value: inputSliderValue !== null && inputSliderValue !== void 0 ? inputSliderValue : void 0
}), /* @__PURE__ */ _jsx(RangeRail, {
"aria-hidden": true,
disabled,
marks,
max,
min,
railColor,
step,
value: rangeFillValue
}), /* @__PURE__ */ _jsx(Track, {
"aria-hidden": true,
className: "components-range-control__track",
disabled,
style: {
width: fillValueOffset
},
trackColor
}), /* @__PURE__ */ _jsx(ThumbWrapper, {
className: "components-range-control__thumb-wrapper",
style: offsetStyle,
disabled,
children: /* @__PURE__ */ _jsx(Thumb, {
"aria-hidden": true,
isFocused: isThumbFocused,
disabled
})
}), enableTooltip && /* @__PURE__ */ _jsx(SimpleTooltip, {
className: "components-range-control__tooltip",
inputRef,
tooltipPlacement: "bottom",
renderTooltipContent,
show: isCurrentlyFocused || showTooltip,
style: offsetStyle,
value
})]
}), afterIcon && /* @__PURE__ */ _jsx(AfterIconWrapper, {
children: /* @__PURE__ */ _jsx(Icon, {
icon: afterIcon
})
}), hasInputField && /* @__PURE__ */ _jsx(InputNumber, {
"aria-label": label,
className: "components-range-control__number",
disabled,
inputMode: "decimal",
isShiftStepEnabled,
max,
min,
onBlur: handleOnInputNumberBlur,
onChange: handleOnChange,
shiftStep,
size: __next40pxDefaultSize ? "__unstable-large" : "default",
__unstableInputWidth: __next40pxDefaultSize ? space(20) : space(16),
step,
value: inputSliderValue,
__shouldNotWarnDeprecated36pxSize: true
}), allowReset && /* @__PURE__ */ _jsx(ActionRightWrapper, {
children: /* @__PURE__ */ _jsx(Button, {
className: "components-range-control__reset",
accessibleWhenDisabled: !disabled,
disabled: disabled || value === computeResetValue({
resetFallbackValue,
initialPosition
}),
variant: "secondary",
size: "small",
onClick: handleOnReset,
children: __("Reset")
})
})]
})
});
}
const RangeControl = forwardRef(UnforwardedRangeControl);
var range_control_default = RangeControl;
export {
RangeControl,
range_control_default as default
};
//# sourceMappingURL=index.js.map