@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
323 lines (322 loc) • 14.1 kB
JavaScript
"use client";
require("../../../_virtual/_rolldown/runtime.cjs");
const require_rem = require("../../../core/utils/units-converters/rem.cjs");
const require_get_size = require("../../../core/utils/get-size/get-size.cjs");
const require_find_closest_number = require("../../../core/utils/find-closest-number/find-closest-number.cjs");
const require_create_vars_resolver = require("../../../core/styles-api/create-vars-resolver/create-vars-resolver.cjs");
const require_get_theme_color = require("../../../core/MantineProvider/color-functions/get-theme-color/get-theme-color.cjs");
const require_use_props = require("../../../core/MantineProvider/use-props/use-props.cjs");
const require_use_styles = require("../../../core/styles-api/use-styles/use-styles.cjs");
const require_factory = require("../../../core/factory/factory.cjs");
const require_DirectionProvider = require("../../../core/DirectionProvider/DirectionProvider.cjs");
const require_Slider_context = require("../Slider.context.cjs");
const require_SliderRoot = require("../SliderRoot/SliderRoot.cjs");
const require_Thumb = require("../Thumb/Thumb.cjs");
const require_get_position = require("../utils/get-position/get-position.cjs");
const require_Track = require("../Track/Track.cjs");
const require_get_change_value = require("../utils/get-change-value/get-change-value.cjs");
const require_get_floating_value = require("../utils/get-floating-value/get-floating-value.cjs");
const require_get_precision = require("../utils/get-precision/get-precision.cjs");
const require_get_step_mark_value = require("../utils/get-step-mark-value/get-step-mark-value.cjs");
const require_Slider_module = require("../Slider.module.cjs");
const require_get_client_position = require("../utils/get-client-position/get-client-position.cjs");
let react = require("react");
let _mantine_hooks = require("@mantine/hooks");
let react_jsx_runtime = require("react/jsx-runtime");
//#region packages/@mantine/core/src/components/Slider/RangeSlider/RangeSlider.tsx
const varsResolver = require_create_vars_resolver.createVarsResolver((theme, { size, color, thumbSize, radius }) => ({ root: {
"--slider-size": require_get_size.getSize(size, "slider-size"),
"--slider-color": color ? require_get_theme_color.getThemeColor(color, theme) : void 0,
"--slider-radius": radius === void 0 ? void 0 : require_get_size.getRadius(radius),
"--slider-thumb-size": thumbSize !== void 0 ? require_rem.rem(thumbSize) : "calc(var(--slider-size) * 2)"
} }));
const defaultProps = {
min: 0,
max: 100,
minRange: 10,
step: 1,
marks: [],
label: (f) => f,
labelTransitionProps: {
transition: "fade",
duration: 0
},
labelAlwaysOn: false,
showLabelOnHover: true,
disabled: false,
pushOnOverlap: true,
scale: (v) => v,
size: "md",
maxRange: Infinity
};
const RangeSlider = require_factory.factory((_props) => {
const props = require_use_props.useProps("RangeSlider", defaultProps, _props);
const { classNames, styles, value, onChange, onChangeEnd, size, min, max, domain, minRange, maxRange, step, precision: _precision, defaultValue, name, marks, label, labelTransitionProps, labelAlwaysOn, thumbFromLabel, thumbToLabel, showLabelOnHover, thumbChildren, disabled, unstyled, scale, inverted, orientation, className, style, vars, hiddenInputProps, restrictToMarks, thumbProps, pushOnOverlap, attributes, ref, ...others } = props;
const getStyles = require_use_styles.useStyles({
name: "RangeSlider",
props,
classes: require_Slider_module.default,
classNames,
className,
styles,
style,
attributes,
vars,
varsResolver,
unstyled
});
const containerRef = (0, react.useRef)(null);
const { dir } = require_DirectionProvider.useDirection();
const [focused, setFocused] = (0, react.useState)(-1);
const [hovered, setHovered] = (0, react.useState)(false);
const [_value, setValue] = (0, _mantine_hooks.useUncontrolled)({
value,
defaultValue,
finalValue: [min, max],
onChange
});
const valueRef = (0, react.useRef)(_value);
const thumbs = (0, react.useRef)([]);
const root = (0, react.useRef)(null);
const thumbIndex = (0, react.useRef)(void 0);
const [domainMin, domainMax] = domain || [min, max];
const positions = [require_get_position.getPosition({
value: _value[0],
min: domainMin,
max: domainMax
}), require_get_position.getPosition({
value: _value[1],
min: domainMin,
max: domainMax
})];
const precision = _precision ?? require_get_precision.getPrecision(step);
const _setValue = (val) => {
setValue(val);
valueRef.current = val;
};
(0, react.useEffect)(() => {
if (Array.isArray(value)) valueRef.current = value;
}, Array.isArray(value) ? [value[0], value[1]] : [null, null]);
const setRangedValue = (val, index, triggerChangeEnd) => {
if (index === -1) return;
const clone = [...valueRef.current];
if (restrictToMarks && marks) {
const closest = require_find_closest_number.findClosestNumber(val, marks.map((m) => m.value));
const current = clone[index];
clone[index] = closest;
const otherIndex = index === 0 ? 1 : 0;
const lastMarkValue = require_get_step_mark_value.getLastMarkValue(marks);
const firstMarkValue = require_get_step_mark_value.getFirstMarkValue(marks);
if (closest === lastMarkValue && clone[otherIndex] === lastMarkValue) clone[index] = current;
else if (closest === firstMarkValue && clone[otherIndex] === firstMarkValue) clone[index] = current;
else if (closest === clone[otherIndex]) if (current > clone[otherIndex]) clone[otherIndex] = require_get_step_mark_value.getPreviousMarkValue(closest, marks);
else clone[otherIndex] = require_get_step_mark_value.getNextMarkValue(closest, marks);
} else {
const clampedVal = (0, _mantine_hooks.clamp)(val, min, max);
clone[index] = clampedVal;
if (index === 0) {
if (clampedVal > clone[1] - (minRange - 1e-9)) if (pushOnOverlap) clone[1] = Math.min(val + minRange, max);
else clone[index] = valueRef.current[index];
if (clampedVal > (max - (minRange - 1e-9) || min)) clone[index] = valueRef.current[index];
if (clone[1] - val > maxRange) if (pushOnOverlap) clone[1] = val + maxRange;
else clone[index] = valueRef.current[index];
}
if (index === 1) {
if (clampedVal < clone[0] + minRange) if (pushOnOverlap) clone[0] = Math.max(val - minRange, min);
else clone[index] = valueRef.current[index];
if (clampedVal < clone[0] + minRange) clone[index] = valueRef.current[index];
if (clampedVal - clone[0] > maxRange) if (pushOnOverlap) clone[0] = val - maxRange;
else clone[index] = valueRef.current[index];
}
}
clone[0] = require_get_floating_value.getFloatingValue(clone[0], precision);
clone[1] = require_get_floating_value.getFloatingValue(clone[1], precision);
if (clone[0] > clone[1]) {
const temp = clone[0];
clone[0] = clone[1];
clone[1] = temp;
}
_setValue(clone);
if (triggerChangeEnd) onChangeEnd?.(valueRef.current);
};
const handleChange = (val) => {
if (!disabled && thumbIndex.current !== void 0) setRangedValue(require_get_change_value.getChangeValue({
value: val,
min: domainMin,
max: domainMax,
step,
precision
}), thumbIndex.current, false);
};
const { ref: useMoveRef, active } = (0, _mantine_hooks.useMove)(({ x, y }) => handleChange(orientation === "vertical" ? 1 - y : x), { onScrubEnd: () => !disabled && onChangeEnd?.(valueRef.current) }, dir);
function handleThumbMouseDown(index) {
thumbIndex.current = index;
}
const handleTrackMouseDownCapture = (event) => {
if (containerRef.current) {
containerRef.current.focus();
const rect = containerRef.current.getBoundingClientRect();
const changePosition = require_get_client_position.getClientPosition(event.nativeEvent, orientation);
const changeValue = orientation === "vertical" ? require_get_change_value.getChangeValue({
value: rect.bottom - changePosition,
max,
min,
step,
containerWidth: rect.height
}) : require_get_change_value.getChangeValue({
value: changePosition - rect.left,
max,
min,
step,
containerWidth: rect.width
});
const nearestHandle = Math.abs(_value[0] - changeValue) > Math.abs(_value[1] - changeValue) ? 1 : 0;
thumbIndex.current = orientation === "vertical" ? nearestHandle : dir === "ltr" ? nearestHandle : nearestHandle === 1 ? 0 : 1;
}
};
const getFocusedThumbIndex = () => {
if (focused !== 1 && focused !== 0) {
setFocused(0);
return 0;
}
return focused;
};
const handleTrackKeydownCapture = (event) => {
if (!disabled) switch (event.key) {
case "ArrowUp": {
event.preventDefault();
const focusedIndex = getFocusedThumbIndex();
thumbs.current[focusedIndex].focus();
setRangedValue(require_get_floating_value.getFloatingValue(restrictToMarks && marks ? require_get_step_mark_value.getNextMarkValue(valueRef.current[focusedIndex], marks) : Math.min(Math.max(valueRef.current[focusedIndex] + step, domainMin), domainMax), precision), focusedIndex, true);
break;
}
case "ArrowRight": {
event.preventDefault();
const focusedIndex = getFocusedThumbIndex();
thumbs.current[focusedIndex].focus();
setRangedValue(require_get_floating_value.getFloatingValue(restrictToMarks && marks ? (dir === "rtl" ? require_get_step_mark_value.getPreviousMarkValue : require_get_step_mark_value.getNextMarkValue)(valueRef.current[focusedIndex], marks) : Math.min(Math.max(dir === "rtl" ? valueRef.current[focusedIndex] - step : valueRef.current[focusedIndex] + step, domainMin), domainMax), precision), focusedIndex, true);
break;
}
case "ArrowDown": {
event.preventDefault();
const focusedIndex = getFocusedThumbIndex();
thumbs.current[focusedIndex].focus();
setRangedValue(require_get_floating_value.getFloatingValue(restrictToMarks && marks ? require_get_step_mark_value.getPreviousMarkValue(valueRef.current[focusedIndex], marks) : Math.min(Math.max(valueRef.current[focusedIndex] - step, domainMin), domainMax), precision), focusedIndex, true);
break;
}
case "ArrowLeft": {
event.preventDefault();
const focusedIndex = getFocusedThumbIndex();
thumbs.current[focusedIndex].focus();
setRangedValue(require_get_floating_value.getFloatingValue(restrictToMarks && marks ? (dir === "rtl" ? require_get_step_mark_value.getNextMarkValue : require_get_step_mark_value.getPreviousMarkValue)(valueRef.current[focusedIndex], marks) : Math.min(Math.max(dir === "rtl" ? valueRef.current[focusedIndex] + step : valueRef.current[focusedIndex] - step, domainMin), domainMax), precision), focusedIndex, true);
break;
}
default: break;
}
};
const sharedThumbProps = {
max,
min,
size,
labelTransitionProps,
labelAlwaysOn,
orientation,
onBlur: () => setFocused(-1)
};
const hasArrayThumbChildren = Array.isArray(thumbChildren);
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Slider_context.SliderProvider, {
value: { getStyles },
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_SliderRoot.SliderRoot, {
...others,
size,
ref: (0, _mantine_hooks.useMergedRef)(ref, root),
disabled,
orientation,
onMouseDownCapture: () => root.current?.focus(),
onKeyDownCapture: () => {
if (thumbs.current[0]?.parentElement?.contains(document.activeElement)) return;
thumbs.current[0]?.focus();
},
children: [
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Track.Track, {
offset: positions[0],
marksOffset: _value[0],
filled: positions[1] - positions[0],
marks,
inverted,
min: domainMin,
max: domainMax,
value: _value[1],
disabled,
containerProps: {
ref: (0, _mantine_hooks.useMergedRef)(containerRef, useMoveRef),
onMouseEnter: showLabelOnHover ? () => setHovered(true) : void 0,
onMouseLeave: showLabelOnHover ? () => setHovered(false) : void 0,
onTouchStartCapture: handleTrackMouseDownCapture,
onTouchEndCapture: () => {
thumbIndex.current = -1;
},
onMouseDownCapture: handleTrackMouseDownCapture,
onMouseUpCapture: () => {
thumbIndex.current = -1;
},
onKeyDownCapture: handleTrackKeydownCapture
},
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Thumb.Thumb, {
...sharedThumbProps,
value: scale(_value[0]),
position: positions[0],
dragging: active,
label: typeof label === "function" ? label(require_get_floating_value.getFloatingValue(scale(_value[0]), precision)) : label,
ref: (node) => {
if (node) thumbs.current[0] = node;
},
thumbLabel: thumbFromLabel,
onMouseDown: () => handleThumbMouseDown(0),
onFocus: () => setFocused(0),
showLabelOnHover,
isHovered: hovered,
disabled,
...thumbProps?.(0),
children: hasArrayThumbChildren ? thumbChildren[0] : thumbChildren
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Thumb.Thumb, {
...sharedThumbProps,
thumbLabel: thumbToLabel,
value: scale(_value[1]),
position: positions[1],
dragging: active,
label: typeof label === "function" ? label(require_get_floating_value.getFloatingValue(scale(_value[1]), precision)) : label,
ref: (node) => {
if (node) thumbs.current[1] = node;
},
onMouseDown: () => handleThumbMouseDown(1),
onFocus: () => setFocused(1),
showLabelOnHover,
isHovered: hovered,
disabled,
...thumbProps?.(1),
children: hasArrayThumbChildren ? thumbChildren[1] : thumbChildren
})]
}),
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
type: "hidden",
name: `${name}_from`,
value: _value[0],
...hiddenInputProps
}),
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
type: "hidden",
name: `${name}_to`,
value: _value[1],
...hiddenInputProps
})
]
})
});
});
RangeSlider.classes = require_Slider_module.default;
RangeSlider.varsResolver = varsResolver;
RangeSlider.displayName = "@mantine/core/RangeSlider";
//#endregion
exports.RangeSlider = RangeSlider;
//# sourceMappingURL=RangeSlider.cjs.map