UNPKG

@yamada-ui/slider

Version:

Yamada UI slider components

1,319 lines (1,316 loc) • 44.1 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/range-slider.tsx var range_slider_exports = {}; __export(range_slider_exports, { RangeSlider: () => RangeSlider, RangeSliderEndThumb: () => RangeSliderEndThumb, RangeSliderFilledTrack: () => RangeSliderFilledTrack, RangeSliderMark: () => RangeSliderMark, RangeSliderStartThumb: () => RangeSliderStartThumb, RangeSliderTrack: () => RangeSliderTrack, useRangeSlider: () => useRangeSlider }); module.exports = __toCommonJS(range_slider_exports); var import_core2 = require("@yamada-ui/core"); var import_form_control2 = require("@yamada-ui/form-control"); var import_use_controllable_state2 = require("@yamada-ui/use-controllable-state"); var import_use_latest_ref2 = require("@yamada-ui/use-latest-ref"); var import_use_pan_event2 = require("@yamada-ui/use-pan-event"); var import_use_size2 = require("@yamada-ui/use-size"); var import_utils2 = require("@yamada-ui/utils"); var import_react2 = require("react"); // src/slider.tsx var import_core = require("@yamada-ui/core"); var import_form_control = require("@yamada-ui/form-control"); var import_use_controllable_state = require("@yamada-ui/use-controllable-state"); var import_use_latest_ref = require("@yamada-ui/use-latest-ref"); var import_use_pan_event = require("@yamada-ui/use-pan-event"); var import_use_size = require("@yamada-ui/use-size"); var import_utils = require("@yamada-ui/utils"); var import_react = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var getThumbSize = (thumbSize, styles) => { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t; return (_t = (_s = (_q = (_o = (_m = (_k = (_i = (_g = (_e = (_c = thumbSize != null ? thumbSize : (_a = styles.thumb) == null ? void 0 : _a.boxSize) != null ? _c : (_b = styles.thumb) == null ? void 0 : _b.minBoxSize) != null ? _e : (_d = styles.thumb) == null ? void 0 : _d.width) != null ? _g : (_f = styles.thumb) == null ? void 0 : _f.w) != null ? _i : (_h = styles.thumb) == null ? void 0 : _h.minWidth) != null ? _k : (_j = styles.thumb) == null ? void 0 : _j.minW) != null ? _m : (_l = styles.thumb) == null ? void 0 : _l.height) != null ? _o : (_n = styles.thumb) == null ? void 0 : _n.h) != null ? _q : (_p = styles.thumb) == null ? void 0 : _p.minHeight) != null ? _s : (_r = styles.thumb) == null ? void 0 : _r.minH) != null ? _t : "3.5"; }; var useSlider = ({ focusThumbOnChange = true, ...props }) => { if (!focusThumbOnChange) props.isReadOnly = true; const { id, name, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-valuetext": ariaValueText, defaultValue, getAriaValueText: getAriaValueTextProp, isReversed, max = 100, min = 0, orientation = "horizontal", reversed = isReversed, step = 1, thumbSize: thumbSizeProp, value: valueProp, onChange, onChangeEnd: onChangeEndProp, onChangeStart: onChangeStartProp, ...rest } = (0, import_form_control.useFormControlProps)(props); if (max < min) throw new Error("Do not assign a number less than 'min' to 'max'"); const { "aria-readonly": ariaReadonly, disabled, readOnly, required, onBlur, onFocus, ...formControlProps } = (0, import_utils.pickObject)(rest, import_form_control.formControlProperties); const [computedValue, setValue] = (0, import_use_controllable_state.useControllableState)({ defaultValue: defaultValue != null ? defaultValue : min + (max - min) / 2, value: valueProp, onChange }); const [dragging, setDragging] = (0, import_react.useState)(false); const [focused, setFocused] = (0, import_react.useState)(false); const interactive = !(disabled || readOnly); const tenStep = (max - min) / 10; const oneStep = step || (max - min) / 100; const value = (0, import_utils.clampNumber)(computedValue, min, max); const reversedValue = max - value + min; const thumbValue = reversed ? reversedValue : value; const thumbPercent = (0, import_utils.valueToPercent)(thumbValue, min, max); const vertical = orientation === "vertical"; const latestRef = (0, import_use_latest_ref.useLatestRef)({ focusThumbOnChange, interactive, max, min, step, value }); const eventSourceRef = (0, import_react.useRef)(null); const containerRef = (0, import_react.useRef)(null); const trackRef = (0, import_react.useRef)(null); const thumbRef = (0, import_react.useRef)(null); const thumbSize = (0, import_use_size.useSize)(thumbRef); const onChangeStart = (0, import_utils.useCallbackRef)(onChangeStartProp); const onChangeEnd = (0, import_utils.useCallbackRef)(onChangeEndProp); const getAriaValueText = (0, import_utils.useCallbackRef)(getAriaValueTextProp); (0, import_use_pan_event.usePanEvent)(containerRef, { onMove: (ev) => { const { interactive: interactive2 } = latestRef.current; if (!interactive2) return; setValueFromPointer(ev); }, onSessionEnd: () => { const { interactive: interactive2, value: value2 } = latestRef.current; if (!interactive2) return; setDragging(false); onChangeEnd(value2); }, onSessionStart: (ev) => { const { interactive: interactive2, value: value2 } = latestRef.current; if (!interactive2) return; setDragging(true); focusThumb(); setValueFromPointer(ev); onChangeStart(value2); } }); const getValueFromPointer = (0, import_react.useCallback)( (ev) => { var _a, _b; if (!trackRef.current) return; const { max: max2, min: min2, step: step2 } = latestRef.current; eventSourceRef.current = "pointer"; const { bottom, height, left, width } = trackRef.current.getBoundingClientRect(); const { clientX, clientY } = (_b = (_a = ev.touches) == null ? void 0 : _a[0]) != null ? _b : ev; const diff = vertical ? bottom - clientY : clientX - left; const length = vertical ? height : width; let percent = diff / length; if (reversed) percent = 1 - percent; let nextValue = (0, import_utils.percentToValue)(percent, min2, max2); if (step2) nextValue = parseFloat((0, import_utils.roundNumberToStep)(nextValue, min2, step2)); nextValue = (0, import_utils.clampNumber)(nextValue, min2, max2); return nextValue; }, [vertical, reversed, latestRef] ); const setValueFromPointer = (ev) => { const { value: value2 } = latestRef.current; const nextValue = getValueFromPointer(ev); if (nextValue != null && nextValue !== value2) setValue(nextValue); }; const focusThumb = (0, import_react.useCallback)(() => { const { focusThumbOnChange: focusThumbOnChange2 } = latestRef.current; if (focusThumbOnChange2) setTimeout(() => { var _a; return (_a = thumbRef.current) == null ? void 0 : _a.focus(); }); }, [latestRef]); const constrain = (0, import_react.useCallback)( (value2) => { const { interactive: interactive2, max: max2, min: min2 } = latestRef.current; if (!interactive2) return; value2 = parseFloat((0, import_utils.roundNumberToStep)(value2, min2, oneStep)); value2 = (0, import_utils.clampNumber)(value2, min2, max2); setValue(value2); }, [oneStep, setValue, latestRef] ); const stepUp = (0, import_react.useCallback)( (step2 = oneStep) => constrain(reversed ? value - step2 : value + step2), [constrain, reversed, oneStep, value] ); const stepDown = (0, import_react.useCallback)( (step2 = oneStep) => constrain(reversed ? value + step2 : value - step2), [constrain, reversed, oneStep, value] ); const reset = (0, import_react.useCallback)( () => constrain(defaultValue || 0), [constrain, defaultValue] ); const stepTo = (0, import_react.useCallback)((value2) => constrain(value2), [constrain]); const onKeyDown = (0, import_react.useCallback)( (ev) => { const { max: max2, min: min2 } = latestRef.current; const actions = { ArrowDown: () => stepDown(), ArrowLeft: () => stepDown(), ArrowRight: () => stepUp(), ArrowUp: () => stepUp(), End: () => constrain(max2), Home: () => constrain(min2), PageDown: () => stepDown(tenStep), PageUp: () => stepUp(tenStep) }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); ev.stopPropagation(); action(ev); eventSourceRef.current = "keyboard"; }, [constrain, latestRef, stepDown, stepUp, tenStep] ); (0, import_utils.useUpdateEffect)(() => { const { value: value2 } = latestRef.current; focusThumb(); if (eventSourceRef.current === "keyboard") onChangeEnd(value2); }, [value, onChangeEnd]); const getContainerProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { let { height: h, width: w } = thumbSize != null ? thumbSize : { height: "var(--ui-thumb-size)", width: "var(--ui-thumb-size)" }; if ((0, import_utils.isNumber)(w)) w = `${w}px`; if ((0, import_utils.isNumber)(h)) h = `${h}px`; const paddingStyle = vertical ? { paddingLeft: `calc(${w} / 2)`, paddingRight: `calc(${w} / 2)` } : { paddingBottom: `calc(${h} / 2)`, paddingTop: `calc(${h} / 2)` }; const style = { ...props2.style, outline: 0, position: "relative", touchAction: "none", userSelect: "none", WebkitTapHighlightColor: "rgba(0, 0, 0, 0)", ...paddingStyle }; return { ...rest, ...props2, ref: (0, import_utils.mergeRefs)(ref, containerRef), style, tabIndex: -1, vars: (0, import_core.mergeVars)(rest.vars, [ { name: "thumb-size", token: "sizes", value: thumbSizeProp, __prefix: "ui" } ]) }; }, [vertical, rest, thumbSize, thumbSizeProp] ); const getInputProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ "aria-readonly": ariaReadonly, ...formControlProps, ...props2, id, ref, type: "hidden", name, disabled, readOnly, required, value }), [ ariaReadonly, disabled, formControlProps, id, name, readOnly, required, value ] ); const getTrackProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { const style = { ...props2.style, position: "absolute", ...vertical ? { height: "100%", left: "50%", transform: "translateX(-50%)" } : { top: "50%", transform: "translateY(-50%)", width: "100%" } }; return { ...formControlProps, ...props2, ref: (0, import_utils.mergeRefs)(ref, trackRef), style }; }, [vertical, formControlProps] ); const getFilledTrackProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { const n = Math.abs(reversed ? 100 - thumbPercent : thumbPercent); const style = { ...props2.style, position: "absolute", ...vertical ? { height: `${n}%`, left: "50%", transform: "translateX(-50%)", ...reversed ? { top: "0%" } : { bottom: "0%" } } : { top: "50%", transform: "translateY(-50%)", width: `${n}%`, ...reversed ? { right: "0%" } : { left: "0%" } } }; return { ...formControlProps, ...props2, ref, style }; }, [reversed, vertical, formControlProps, thumbPercent] ); const getMarkProps = (0, import_react.useCallback)( (props2, ref = null) => { let n = (0, import_utils.valueToPercent)(props2.value, min, max); n = reversed ? 100 - n : n; const style = { ...props2.style, pointerEvents: "none", position: "absolute", ...vertical ? { bottom: `${n}%` } : { left: `${n}%` } }; return { ...formControlProps, ...props2, ref, style, "aria-hidden": true, "data-highlighted": (0, import_utils.dataAttr)(props2.value <= value), "data-invalid": (0, import_utils.dataAttr)(props2.value < min || max < props2.value) }; }, [reversed, vertical, max, min, formControlProps, value] ); const getThumbProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { var _a; const n = thumbPercent; let w = "var(--ui-thumb-size)"; let h = "var(--ui-thumb-size)"; if (thumbSize) { w = `${thumbSize.width}px`; h = `${thumbSize.height}px`; } const bottom = `calc(${n}% - (${h} / 2))`; const left = `calc(${n}% - (${w} / 2))`; const style = { ...props2.style, position: "absolute", touchAction: "none", userSelect: "none", ...vertical ? { bottom } : { left } }; return { "aria-label": ariaLabel != null ? ariaLabel : "Slider thumb", "aria-labelledby": ariaLabelledBy, "aria-readonly": ariaReadonly, ...formControlProps, ...props2, ref: (0, import_utils.mergeRefs)(ref, thumbRef), style, "aria-orientation": orientation, "aria-valuemax": max, "aria-valuemin": min, "aria-valuenow": value, "aria-valuetext": (_a = ariaValueText != null ? ariaValueText : getAriaValueText(value)) != null ? _a : value.toString(), "data-active": (0, import_utils.dataAttr)(dragging && focusThumbOnChange), role: "slider", tabIndex: interactive && focusThumbOnChange ? 0 : void 0, onBlur: (0, import_utils.handlerAll)(props2.onBlur, onBlur, () => setFocused(false)), onFocus: (0, import_utils.handlerAll)(props2.onFocus, onFocus, () => setFocused(true)), onKeyDown: (0, import_utils.handlerAll)(props2.onKeyDown, onKeyDown) }; }, [ thumbPercent, thumbSize, vertical, ariaLabel, ariaLabelledBy, ariaReadonly, formControlProps, orientation, max, min, value, ariaValueText, getAriaValueText, dragging, focusThumbOnChange, interactive, onBlur, onFocus, onKeyDown ] ); return { dragging, focused, /** * @deprecated Use `dragging` instead. */ isDragging: dragging, /** * @deprecated Use `focused` instead. */ isFocused: focused, /** * @deprecated Use `vertical` instead. */ isVertical: vertical, reset, stepDown, stepTo, stepUp, value, vertical, getContainerProps, getFilledTrackProps, getInputProps, getMarkProps, getThumbProps, getTrackProps }; }; var [SliderProvider, useSliderContext] = (0, import_utils.createContext)({ name: "SliderContext", errorMessage: `useSliderContext returned is 'undefined'. Seems you forgot to wrap the components in "<Slider />" ` }); var Slider = (0, import_core.forwardRef)((props, ref) => { const [styles, mergedProps] = (0, import_core.useComponentMultiStyle)("Slider", props); const { className, children, filledTrackColor, thumbColor, thumbSize, trackColor, trackSize, filledTrackProps, inputProps, thumbProps, trackProps, ...rest } = (0, import_core.omitThemeProps)(mergedProps); const { isVertical, getContainerProps, getFilledTrackProps, getInputProps, getMarkProps, getThumbProps, getTrackProps } = useSlider({ ...rest, thumbSize: getThumbSize(thumbSize, styles) }); const css = { ...styles.container }; const validChildren = (0, import_utils.getValidChildren)(children); const customSliderTrack = (0, import_utils.findChild)(validChildren, SliderTrack); const customSliderThumb = (0, import_utils.findChild)(validChildren, SliderThumb); const hasSliderThumb = (0, import_utils.includesChildren)(validChildren, SliderThumb); const cloneChildren = !(0, import_utils.isEmpty)(validChildren) ? (0, import_utils.omitChildren)(validChildren, SliderTrack, SliderThumb) : children; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( SliderProvider, { value: { filledTrackColor, isVertical, styles, thumbColor, thumbSize, trackColor, trackSize, filledTrackProps, getFilledTrackProps, getMarkProps, getThumbProps, getTrackProps, thumbProps, trackProps }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_core.ui.div, { className: (0, import_utils.cx)("ui-slider", className), __css: css, ...getContainerProps(), children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.input, { ...getInputProps(inputProps, ref) }), customSliderTrack != null ? customSliderTrack : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderTrack, {}), cloneChildren, customSliderThumb != null ? customSliderThumb : !hasSliderThumb ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderThumb, {}) : null ] } ) } ); }); Slider.displayName = "Slider"; Slider.__ui__ = "Slider"; var SliderTrack = (0, import_core.forwardRef)( ({ className, children, filledTrackProps, ...rest }, ref) => { const { isVertical, styles, trackColor, trackSize, getTrackProps, trackProps } = useSliderContext(); const css = { ...styles.track }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: (0, import_utils.cx)("ui-slider__track", className), __css: css, ...getTrackProps( { ...trackColor ? { bg: trackColor } : {}, ...trackSize ? isVertical ? { w: trackSize } : { h: trackSize } : {}, ...trackProps, ...rest }, ref ), children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderFilledTrack, { ...filledTrackProps }) } ); } ); SliderTrack.displayName = "SliderTrack"; SliderTrack.__ui__ = "SliderTrack"; var SliderFilledTrack = (0, import_core.forwardRef)( ({ className, ...rest }, ref) => { const { filledTrackColor, styles, filledTrackProps, getFilledTrackProps } = useSliderContext(); const css = { ...styles.filledTrack }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: (0, import_utils.cx)("ui-slider__track-filled", className), __css: css, ...getFilledTrackProps( { ...filledTrackColor ? { bg: filledTrackColor } : {}, ...filledTrackProps, ...rest }, ref ) } ); } ); SliderFilledTrack.displayName = "SliderFilledTrack"; SliderFilledTrack.__ui__ = "SliderFilledTrack"; var SliderMark = (0, import_core.forwardRef)( ({ className, ...rest }, ref) => { const { styles, getMarkProps } = useSliderContext(); const css = { alignItems: "center", display: "inline-flex", justifyContent: "center", ...styles.mark }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: (0, import_utils.cx)("ui-slider__mark", className), __css: css, ...getMarkProps(rest, ref) } ); } ); SliderMark.displayName = "SliderMark"; SliderMark.__ui__ = "SliderMark"; var SliderThumb = (0, import_core.forwardRef)( ({ className, ...rest }, ref) => { const { styles, thumbColor, thumbSize, getThumbProps, thumbProps } = useSliderContext(); const css = { ...styles.thumb }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: (0, import_utils.cx)("ui-slider__thumb", className), __css: css, ...getThumbProps( { ...thumbColor ? { bg: thumbColor } : {}, ...thumbSize ? { boxSize: thumbSize } : {}, ...thumbProps, ...rest }, ref ) } ); } ); SliderThumb.displayName = "SliderThumb"; SliderThumb.__ui__ = "SliderThumb"; // src/range-slider.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var useRangeSlider = ({ focusThumbOnChange = true, ...props }) => { if (!focusThumbOnChange) props.isReadOnly = true; const uuid = (0, import_react2.useId)(); const { id = uuid, name = id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-valuetext": ariaValueText, betweenThumbs = 0, max = 100, min = 0, defaultValue = [min + (max - min) / 4, max - (max - min) / 4], getAriaValueText: getAriaValueTextProp, isReversed, orientation = "horizontal", reversed = isReversed, step = 1, thumbSize: thumbSizeProp, value: valueProp, onChange, onChangeEnd: onChangeEndProp, onChangeStart: onChangeStartProp, ...rest } = (0, import_form_control2.useFormControlProps)(props); if (max < min) throw new Error("Do not assign a number less than 'min' to 'max'"); const { "aria-readonly": ariaReadonly, disabled, readOnly, required, onBlur, onFocus, ...formControlProps } = (0, import_utils2.pickObject)(rest, import_form_control2.formControlProperties); const [computedValues, setValues] = (0, import_use_controllable_state2.useControllableState)({ defaultValue, value: valueProp, onChange }); const [dragging, setDragging] = (0, import_react2.useState)(false); const [focused, setFocused] = (0, import_react2.useState)(false); const interactive = !(disabled || readOnly); const tenStep = (max - min) / 10; const oneStep = step || (max - min) / 100; const spacing = betweenThumbs * step; const values = computedValues.map( (value) => (0, import_utils2.clampNumber)(value, min, max) ); const [startValue, endValue] = values; const reversedValues = values.map((value) => max - value + min); const thumbValues = reversed ? reversedValues : values; const thumbPercents = thumbValues.map( (value) => (0, import_utils2.valueToPercent)(value, min, max) ); const valueBounds = [ { max: endValue - spacing, min }, { max, min: startValue + spacing } ]; const vertical = orientation === "vertical"; const latestRef = (0, import_use_latest_ref2.useLatestRef)({ betweenThumbs, disabled, focusThumbOnChange, interactive, max, min, orientation, reversed, step, valueBounds, values, vertical }); const activeIndexRef = (0, import_react2.useRef)(-1); const eventSourceRef = (0, import_react2.useRef)(null); const containerRef = (0, import_react2.useRef)(null); const trackRef = (0, import_react2.useRef)(null); const thumbSizes = (0, import_use_size2.useSizes)({ getNodes: () => { var _a; const nodes = (_a = containerRef.current) == null ? void 0 : _a.querySelectorAll("[role=slider]"); return nodes ? Array.from(nodes) : []; } }); const onChangeStart = (0, import_utils2.useCallbackRef)(onChangeStartProp); const onChangeEnd = (0, import_utils2.useCallbackRef)(onChangeEndProp); const getAriaValueText = (0, import_utils2.useCallbackRef)(getAriaValueTextProp); const getThumbId = (0, import_react2.useCallback)((i) => `slider-thumb-${id}-${i}`, [id]); const getInputId = (0, import_react2.useCallback)((i) => `slider-input-${id}-${i}`, [id]); const getMarkerId = (0, import_react2.useCallback)( (i) => `slider-marker-${id}-${i}`, [id] ); (0, import_use_pan_event2.usePanEvent)(containerRef, { onMove: (ev) => { const activeIndex = activeIndexRef.current; const { interactive: interactive2 } = latestRef.current; if (!interactive2 || activeIndex == -1) return; const pointValue = getValueFromPointer(ev) || 0; constrain(activeIndex, pointValue); focusThumb(activeIndex); }, onSessionEnd: () => { const { interactive: interactive2, values: values2 } = latestRef.current; if (!interactive2) return; setDragging(false); onChangeEnd(values2); }, onSessionStart: (ev) => { const { interactive: interactive2, values: values2 } = latestRef.current; if (!interactive2) return; setDragging(true); const pointValue = getValueFromPointer(ev) || 0; const distances = values2.map((value) => Math.abs(value - pointValue)); const closest = Math.min(...distances); let i = distances.indexOf(closest); const thumbsPosition = distances.filter( (distance) => distance === closest ); const isThumbStacked = thumbsPosition.length > 1; if (isThumbStacked && pointValue > values2[i]) i = i + thumbsPosition.length - 1; activeIndexRef.current = i; constrain(i, pointValue); focusThumb(i); onChangeStart(values2); } }); const getValueFromPointer = (0, import_react2.useCallback)( (ev) => { var _a, _b; if (!trackRef.current) return; const { max: max2, min: min2 } = latestRef.current; eventSourceRef.current = "pointer"; const { bottom, height, left, width } = trackRef.current.getBoundingClientRect(); const { clientX, clientY } = (_b = (_a = ev.touches) == null ? void 0 : _a[0]) != null ? _b : ev; const diff = vertical ? bottom - clientY : clientX - left; const length = vertical ? height : width; let percent = diff / length; if (reversed) percent = 1 - percent; let nextValue = (0, import_utils2.percentToValue)(percent, min2, max2); return nextValue; }, [latestRef, vertical, reversed] ); const focusThumb = (0, import_react2.useCallback)( (i) => { var _a; if (i === -1 || !focusThumbOnChange) return; const id2 = getThumbId(i); const el = (_a = containerRef.current) == null ? void 0 : _a.ownerDocument.getElementById(id2); if (el) setTimeout(() => el.focus()); }, [focusThumbOnChange, getThumbId] ); const constrain = (0, import_react2.useCallback)( (i, value) => { var _a; const { interactive: interactive2, valueBounds: valueBounds2, values: values2 } = latestRef.current; if (!interactive2) return; const { max: max2 = 100, min: min2 = 0 } = (_a = valueBounds2[i]) != null ? _a : {}; value = parseFloat((0, import_utils2.roundNumberToStep)(value, min2, oneStep)); value = (0, import_utils2.clampNumber)(value, min2, max2); const nextValues = [...values2]; nextValues[i] = value; setValues(nextValues); }, [latestRef, oneStep, setValues] ); const stepUp = (0, import_react2.useCallback)( (i, step2 = oneStep) => { const { values: values2 } = latestRef.current; const value = values2[i]; constrain(i, reversed ? value - step2 : value + step2); }, [constrain, reversed, latestRef, oneStep] ); const stepDown = (0, import_react2.useCallback)( (i, step2 = oneStep) => { const { values: values2 } = latestRef.current; const value = values2[i]; constrain(i, reversed ? value + step2 : value - step2); }, [constrain, reversed, latestRef, oneStep] ); const reset = (0, import_react2.useCallback)( () => setValues(defaultValue), [defaultValue, setValues] ); const onKeyDown = (0, import_react2.useCallback)( (ev) => { var _a; const activeIndex = activeIndexRef.current; const { valueBounds: valueBounds2 } = latestRef.current; const { max: max2 = 100, min: min2 = 0 } = (_a = valueBounds2[activeIndex]) != null ? _a : {}; const actions = { ArrowDown: () => stepDown(activeIndex), ArrowLeft: () => stepDown(activeIndex), ArrowRight: () => stepUp(activeIndex), ArrowUp: () => stepUp(activeIndex), End: () => constrain(activeIndex, max2), Home: () => constrain(activeIndex, min2), PageDown: () => stepDown(activeIndex, tenStep), PageUp: () => stepUp(activeIndex, tenStep) }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); ev.stopPropagation(); action(ev); eventSourceRef.current = "keyboard"; }, [constrain, latestRef, stepDown, stepUp, tenStep] ); (0, import_utils2.useUpdateEffect)(() => { const { values: values2 } = latestRef.current; if (eventSourceRef.current === "keyboard") onChangeEnd(values2); }, [startValue, endValue, onChangeEnd]); const getContainerProps = (0, import_react2.useCallback)( (props2 = {}, ref = null) => { var _a; let w = "var(--ui-thumb-size)"; let h = "var(--ui-thumb-size)"; if (thumbSizes.length) { const p = vertical ? "height" : "width"; const z = { height: 0, width: 0 }; const { height, width } = (_a = thumbSizes.reduce((a = z, b = z) => a[p] > b[p] ? a : b, z)) != null ? _a : {}; if (width) w = `${width}px`; if (height) h = `${height}px`; } const paddingStyle = vertical ? { paddingLeft: `calc(${w} / 2)`, paddingRight: `calc(${w} / 2)` } : { paddingBottom: `calc(${h} / 2)`, paddingTop: `calc(${h} / 2)` }; const style = { ...props2.style, outline: 0, position: "relative", touchAction: "none", userSelect: "none", WebkitTapHighlightColor: "rgba(0, 0, 0, 0)", ...paddingStyle }; return { ...rest, ...props2, id: `slider-container-${id}`, ref: (0, import_utils2.mergeRefs)(ref, containerRef), style, tabIndex: -1, vars: (0, import_core2.mergeVars)(rest.vars, [ { name: "thumb-size", token: "sizes", value: thumbSizeProp, __prefix: "ui" } ]) }; }, [id, vertical, rest, thumbSizeProp, thumbSizes] ); const getInputProps = (0, import_react2.useCallback)( ({ index: i, ...props2 }, ref = null) => ({ "aria-readonly": ariaReadonly, ...formControlProps, ...props2, id: getInputId(i), ref, type: "hidden", name: (0, import_utils2.isArray)(name) ? name[i] : `${name}-${i}`, disabled, readOnly, required, value: values[i] }), [ ariaReadonly, disabled, getInputId, name, readOnly, required, formControlProps, values ] ); const getTrackProps = (0, import_react2.useCallback)( (props2 = {}, ref = null) => { const style = { ...props2.style, position: "absolute", ...vertical ? { height: "100%", left: "50%", transform: "translateX(-50%)" } : { top: "50%", transform: "translateY(-50%)", width: "100%" } }; return { ...formControlProps, ...props2, id: `slider-track-${id}`, ref: (0, import_utils2.mergeRefs)(ref, trackRef), style }; }, [id, vertical, formControlProps] ); const getFilledTrackProps = (0, import_react2.useCallback)( (props2 = {}, ref = null) => { const n = Math.abs(thumbPercents[1] - thumbPercents[0]); const s = reversed ? 100 - thumbPercents[0] : thumbPercents[0]; const style = { ...props2.style, position: "absolute", ...vertical ? { height: `${n}%`, left: "50%", transform: "translateX(-50%)", ...reversed ? { top: `${s}%` } : { bottom: `${s}%` } } : { top: "50%", transform: "translateY(-50%)", width: `${n}%`, ...reversed ? { right: `${s}%` } : { left: `${s}%` } } }; return { ...formControlProps, ...props2, id: `slider-filled-track-${id}`, ref, style }; }, [id, reversed, vertical, formControlProps, thumbPercents] ); const getMarkProps = (0, import_react2.useCallback)( (props2, ref = null) => { let n = (0, import_utils2.valueToPercent)(props2.value, min, max); n = reversed ? 100 - n : n; const style = { ...props2.style, pointerEvents: "none", position: "absolute", ...vertical ? { bottom: `${n}%` } : { left: `${n}%` } }; return { ...formControlProps, ...props2, id: getMarkerId(props2.value), ref, style, "aria-hidden": true, "data-highlighted": (0, import_utils2.dataAttr)( values[0] <= props2.value && props2.value <= values[1] ), "data-invalid": (0, import_utils2.dataAttr)(props2.value < min || max < props2.value) }; }, [getMarkerId, reversed, vertical, max, min, formControlProps, values] ); const getThumbProps = (0, import_react2.useCallback)( ({ index: i, ...props2 }, ref = null) => { var _a, _b, _c; const n = thumbPercents[i]; let w = "var(--ui-thumb-size)"; let h = "var(--ui-thumb-size)"; if (thumbSizes[i]) { w = `${(_a = thumbSizes[i]) == null ? void 0 : _a.width}px`; h = `${(_b = thumbSizes[i]) == null ? void 0 : _b.height}px`; } const bottom = `calc(${n}% - (${h} / 2))`; const left = `calc(${n}% - (${w} / 2))`; const style = { ...props2.style, position: "absolute", touchAction: "none", userSelect: "none", ...vertical ? { bottom } : { left } }; const value = values[i]; if (value == null) throw new Error( `Cannot find value at index '${i}'. The 'value' or 'defaultValue'` ); return { "aria-label": ariaLabel != null ? ariaLabel : "Slider thumb", "aria-labelledby": ariaLabelledBy, "aria-readonly": ariaReadonly, ...formControlProps, ...props2, id: getThumbId(i), ref, style, "aria-orientation": orientation, "aria-valuemax": max, "aria-valuemin": min, "aria-valuenow": value, "aria-valuetext": (_c = ariaValueText != null ? ariaValueText : getAriaValueText(value)) != null ? _c : value.toString(), "data-active": (0, import_utils2.dataAttr)( dragging && focusThumbOnChange && activeIndexRef.current === i ), role: "slider", tabIndex: interactive && focusThumbOnChange ? 0 : void 0, onBlur: (0, import_utils2.handlerAll)(props2.onBlur, onBlur, () => { activeIndexRef.current = -1; setFocused(false); }), onFocus: (0, import_utils2.handlerAll)(props2.onFocus, onFocus, () => { activeIndexRef.current = i; setFocused(true); }), onKeyDown: (0, import_utils2.handlerAll)(props2.onKeyDown, onKeyDown) }; }, [ thumbPercents, thumbSizes, vertical, values, ariaLabel, ariaLabelledBy, ariaReadonly, formControlProps, getThumbId, orientation, max, min, ariaValueText, getAriaValueText, dragging, focusThumbOnChange, interactive, onBlur, onFocus, onKeyDown ] ); return { dragging, focused, getInputId, getMarkerId, getThumbId, reset, stepDown, stepUp, values, vertical, getContainerProps, getFilledTrackProps, getInputProps, getMarkProps, getThumbProps, getTrackProps }; }; var [RangeSliderProvider, useRangeSliderContext] = (0, import_utils2.createContext)({ name: "RangeSliderContext", errorMessage: `useRangeSliderContext returned is 'undefined'. Seems you forgot to wrap the components in "<RangeSlider />" ` }); var RangeSlider = (0, import_core2.forwardRef)((props, ref) => { const [styles, mergedProps] = (0, import_core2.useComponentMultiStyle)("RangeSlider", props); const { className, children, filledTrackColor, thumbColor, thumbSize, trackColor, trackSize, filledTrackProps, inputProps, thumbProps, trackProps, ...rest } = (0, import_core2.omitThemeProps)(mergedProps); const { vertical, getContainerProps, getFilledTrackProps, getInputProps, getMarkProps, getThumbProps, getTrackProps } = useRangeSlider({ ...rest, thumbSize: getThumbSize(thumbSize, styles) }); const css = { ...styles.container }; const validChildren = (0, import_utils2.getValidChildren)(children); const customRangeSliderTrack = (0, import_utils2.findChild)(validChildren, RangeSliderTrack); const customRangeSliderStartThumb = (0, import_utils2.findChild)( validChildren, RangeSliderStartThumb ); const customRangeSliderEndThumb = (0, import_utils2.findChild)( validChildren, RangeSliderEndThumb ); const hasRangeSliderStartThumb = (0, import_utils2.includesChildren)( validChildren, RangeSliderStartThumb ); const hasRangeSliderEndThumb = (0, import_utils2.includesChildren)( validChildren, RangeSliderEndThumb ); const cloneChildren = !(0, import_utils2.isEmpty)(validChildren) ? (0, import_utils2.omitChildren)( validChildren, RangeSliderTrack, RangeSliderStartThumb, RangeSliderEndThumb ) : children; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( RangeSliderProvider, { value: { filledTrackColor, styles, thumbColor, thumbSize, trackColor, trackSize, vertical, filledTrackProps, getFilledTrackProps, getInputProps, getMarkProps, getThumbProps, getTrackProps, inputProps, thumbProps, trackProps }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)( import_core2.ui.div, { className: (0, import_utils2.cx)("ui-slider", className), __css: css, ...getContainerProps({}, ref), children: [ customRangeSliderTrack != null ? customRangeSliderTrack : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderTrack, {}), cloneChildren, customRangeSliderStartThumb != null ? customRangeSliderStartThumb : !hasRangeSliderStartThumb ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderStartThumb, {}) : null, customRangeSliderEndThumb != null ? customRangeSliderEndThumb : !hasRangeSliderEndThumb ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderEndThumb, {}) : null ] } ) } ); }); RangeSlider.displayName = "RangeSlider"; RangeSlider.__ui__ = "RangeSlider"; var RangeSliderTrack = (0, import_core2.forwardRef)( ({ className, children, filledTrackProps, ...rest }, ref) => { const { styles, trackColor, trackSize, vertical, getTrackProps, trackProps } = useRangeSliderContext(); const css = { ...styles.track }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_core2.ui.div, { className: (0, import_utils2.cx)("ui-slider__track", className), __css: css, ...getTrackProps( { ...trackColor ? { bg: trackColor } : {}, ...trackSize ? vertical ? { w: trackSize } : { h: trackSize } : {}, ...trackProps, ...rest }, ref ), children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderFilledTrack, { ...filledTrackProps }) } ); } ); RangeSliderTrack.displayName = "RangeSliderTrack"; RangeSliderTrack.__ui__ = "RangeSliderTrack"; var RangeSliderFilledTrack = (0, import_core2.forwardRef)(({ className, ...rest }, ref) => { const { filledTrackColor, styles, filledTrackProps, getFilledTrackProps } = useRangeSliderContext(); const css = { ...styles.filledTrack }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_core2.ui.div, { className: (0, import_utils2.cx)("ui-slider__track-filled", className), __css: css, ...getFilledTrackProps( { ...filledTrackColor ? { bg: filledTrackColor } : {}, ...filledTrackProps, ...rest }, ref ) } ); }); RangeSliderFilledTrack.displayName = "RangeSliderFilledTrack"; RangeSliderFilledTrack.__ui__ = "RangeSliderFilledTrack"; var RangeSliderMark = (0, import_core2.forwardRef)( ({ className, ...rest }, ref) => { const { styles, getMarkProps } = useRangeSliderContext(); const css = { alignItems: "center", display: "inline-flex", justifyContent: "center", ...styles.mark }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_core2.ui.div, { className: (0, import_utils2.cx)("ui-slider__mark", className), __css: css, ...getMarkProps(rest, ref) } ); } ); RangeSliderMark.displayName = "RangeSliderMark"; RangeSliderMark.__ui__ = "RangeSliderMark"; var RangeSliderThumb = (0, import_core2.forwardRef)(({ className, children, index, ...rest }, ref) => { const { styles, thumbColor, thumbSize, getInputProps, getThumbProps, inputProps, thumbProps } = useRangeSliderContext(); const css = { ...styles.thumb }; const { children: propChildren } = thumbProps != null ? thumbProps : {}; return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)( import_core2.ui.div, { className: (0, import_utils2.cx)("ui-slider__thumb", className), __css: css, ...getThumbProps( { index, ...thumbColor ? { bg: thumbColor } : {}, ...thumbSize ? { boxSize: thumbSize } : {}, ...thumbProps, ...rest }, ref ), children: [ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core2.ui.input, { ...getInputProps({ ...inputProps, index }, ref) }), children != null ? children : propChildren ] } ); }); RangeSliderThumb.displayName = "RangeSliderThumb"; RangeSliderThumb.__ui__ = "RangeSliderThumb"; var RangeSliderStartThumb = (0, import_core2.forwardRef)( (rest, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderThumb, { ref, index: 0, ...rest }); } ); RangeSliderStartThumb.displayName = "RangeSliderStartThumb"; RangeSliderStartThumb.__ui__ = "RangeSliderStartThumb"; var RangeSliderEndThumb = (0, import_core2.forwardRef)( (rest, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RangeSliderThumb, { ref, index: 1, ...rest }); } ); RangeSliderEndThumb.displayName = "RangeSliderEndThumb"; RangeSliderEndThumb.__ui__ = "RangeSliderEndThumb"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RangeSlider, RangeSliderEndThumb, RangeSliderFilledTrack, RangeSliderMark, RangeSliderStartThumb, RangeSliderTrack, useRangeSlider }); //# sourceMappingURL=range-slider.js.map