| "use strict"; |
| "use client"; |
| var __create = Object.create; |
| var __defProp = Object.defineProperty; |
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
| var __getOwnPropNames = Object.getOwnPropertyNames; |
| var __getProtoOf = Object.getPrototypeOf; |
| 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
| |
| |
| |
| |
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
| mod |
| )); |
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
|
|
| |
| var src_exports = {}; |
| __export(src_exports, { |
| Range: () => Range, |
| Root: () => Root, |
| Slider: () => Slider, |
| SliderRange: () => SliderRange, |
| SliderThumb: () => SliderThumb, |
| SliderTrack: () => SliderTrack, |
| Thumb: () => Thumb, |
| Track: () => Track, |
| createSliderScope: () => createSliderScope |
| }); |
| module.exports = __toCommonJS(src_exports); |
|
|
| |
| var React = __toESM(require("react")); |
| var import_number = require("@radix-ui/number"); |
| var import_primitive = require("@radix-ui/primitive"); |
| var import_react_compose_refs = require("@radix-ui/react-compose-refs"); |
| var import_react_context = require("@radix-ui/react-context"); |
| var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state"); |
| var import_react_direction = require("@radix-ui/react-direction"); |
| var import_react_use_previous = require("@radix-ui/react-use-previous"); |
| var import_react_use_size = require("@radix-ui/react-use-size"); |
| var import_react_primitive = require("@radix-ui/react-primitive"); |
| var import_react_collection = require("@radix-ui/react-collection"); |
| var import_jsx_runtime = require("react/jsx-runtime"); |
| var PAGE_KEYS = ["PageUp", "PageDown"]; |
| var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]; |
| var BACK_KEYS = { |
| "from-left": ["Home", "PageDown", "ArrowDown", "ArrowLeft"], |
| "from-right": ["Home", "PageDown", "ArrowDown", "ArrowRight"], |
| "from-bottom": ["Home", "PageDown", "ArrowDown", "ArrowLeft"], |
| "from-top": ["Home", "PageDown", "ArrowUp", "ArrowLeft"] |
| }; |
| var SLIDER_NAME = "Slider"; |
| var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.createCollection)(SLIDER_NAME); |
| var [createSliderContext, createSliderScope] = (0, import_react_context.createContextScope)(SLIDER_NAME, [ |
| createCollectionScope |
| ]); |
| var [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME); |
| var Slider = React.forwardRef( |
| (props, forwardedRef) => { |
| const { |
| name, |
| min = 0, |
| max = 100, |
| step = 1, |
| orientation = "horizontal", |
| disabled = false, |
| minStepsBetweenThumbs = 0, |
| defaultValue = [min], |
| value, |
| onValueChange = () => { |
| }, |
| onValueCommit = () => { |
| }, |
| inverted = false, |
| form, |
| ...sliderProps |
| } = props; |
| const thumbRefs = React.useRef( new Set()); |
| const valueIndexToChangeRef = React.useRef(0); |
| const isHorizontal = orientation === "horizontal"; |
| const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical; |
| const [values = [], setValues] = (0, import_react_use_controllable_state.useControllableState)({ |
| prop: value, |
| defaultProp: defaultValue, |
| onChange: (value2) => { |
| const thumbs = [...thumbRefs.current]; |
| thumbs[valueIndexToChangeRef.current]?.focus(); |
| onValueChange(value2); |
| } |
| }); |
| const valuesBeforeSlideStartRef = React.useRef(values); |
| function handleSlideStart(value2) { |
| const closestIndex = getClosestValueIndex(values, value2); |
| updateValues(value2, closestIndex); |
| } |
| function handleSlideMove(value2) { |
| updateValues(value2, valueIndexToChangeRef.current); |
| } |
| function handleSlideEnd() { |
| const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current]; |
| const nextValue = values[valueIndexToChangeRef.current]; |
| const hasChanged = nextValue !== prevValue; |
| if (hasChanged) onValueCommit(values); |
| } |
| function updateValues(value2, atIndex, { commit } = { commit: false }) { |
| const decimalCount = getDecimalCount(step); |
| const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount); |
| const nextValue = (0, import_number.clamp)(snapToStep, [min, max]); |
| setValues((prevValues = []) => { |
| const nextValues = getNextSortedValues(prevValues, nextValue, atIndex); |
| if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) { |
| valueIndexToChangeRef.current = nextValues.indexOf(nextValue); |
| const hasChanged = String(nextValues) !== String(prevValues); |
| if (hasChanged && commit) onValueCommit(nextValues); |
| return hasChanged ? nextValues : prevValues; |
| } else { |
| return prevValues; |
| } |
| }); |
| } |
| return (0, import_jsx_runtime.jsx)( |
| SliderProvider, |
| { |
| scope: props.__scopeSlider, |
| name, |
| disabled, |
| min, |
| max, |
| valueIndexToChangeRef, |
| thumbs: thumbRefs.current, |
| values, |
| orientation, |
| form, |
| children: (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: props.__scopeSlider, children: (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime.jsx)( |
| SliderOrientation, |
| { |
| "aria-disabled": disabled, |
| "data-disabled": disabled ? "" : void 0, |
| ...sliderProps, |
| ref: forwardedRef, |
| onPointerDown: (0, import_primitive.composeEventHandlers)(sliderProps.onPointerDown, () => { |
| if (!disabled) valuesBeforeSlideStartRef.current = values; |
| }), |
| min, |
| max, |
| inverted, |
| onSlideStart: disabled ? void 0 : handleSlideStart, |
| onSlideMove: disabled ? void 0 : handleSlideMove, |
| onSlideEnd: disabled ? void 0 : handleSlideEnd, |
| onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }), |
| onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }), |
| onStepKeyDown: ({ event, direction: stepDirection }) => { |
| if (!disabled) { |
| const isPageKey = PAGE_KEYS.includes(event.key); |
| const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key); |
| const multiplier = isSkipKey ? 10 : 1; |
| const atIndex = valueIndexToChangeRef.current; |
| const value2 = values[atIndex]; |
| const stepInDirection = step * multiplier * stepDirection; |
| updateValues(value2 + stepInDirection, atIndex, { commit: true }); |
| } |
| } |
| } |
| ) }) }) |
| } |
| ); |
| } |
| ); |
| Slider.displayName = SLIDER_NAME; |
| var [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, { |
| startEdge: "left", |
| endEdge: "right", |
| size: "width", |
| direction: 1 |
| }); |
| var SliderHorizontal = React.forwardRef( |
| (props, forwardedRef) => { |
| const { |
| min, |
| max, |
| dir, |
| inverted, |
| onSlideStart, |
| onSlideMove, |
| onSlideEnd, |
| onStepKeyDown, |
| ...sliderProps |
| } = props; |
| const [slider, setSlider] = React.useState(null); |
| const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node) => setSlider(node)); |
| const rectRef = React.useRef(void 0); |
| const direction = (0, import_react_direction.useDirection)(dir); |
| const isDirectionLTR = direction === "ltr"; |
| const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted; |
| function getValueFromPointer(pointerPosition) { |
| const rect = rectRef.current || slider.getBoundingClientRect(); |
| const input = [0, rect.width]; |
| const output = isSlidingFromLeft ? [min, max] : [max, min]; |
| const value = linearScale(input, output); |
| rectRef.current = rect; |
| return value(pointerPosition - rect.left); |
| } |
| return (0, import_jsx_runtime.jsx)( |
| SliderOrientationProvider, |
| { |
| scope: props.__scopeSlider, |
| startEdge: isSlidingFromLeft ? "left" : "right", |
| endEdge: isSlidingFromLeft ? "right" : "left", |
| direction: isSlidingFromLeft ? 1 : -1, |
| size: "width", |
| children: (0, import_jsx_runtime.jsx)( |
| SliderImpl, |
| { |
| dir: direction, |
| "data-orientation": "horizontal", |
| ...sliderProps, |
| ref: composedRefs, |
| style: { |
| ...sliderProps.style, |
| ["--radix-slider-thumb-transform"]: "translateX(-50%)" |
| }, |
| onSlideStart: (event) => { |
| const value = getValueFromPointer(event.clientX); |
| onSlideStart?.(value); |
| }, |
| onSlideMove: (event) => { |
| const value = getValueFromPointer(event.clientX); |
| onSlideMove?.(value); |
| }, |
| onSlideEnd: () => { |
| rectRef.current = void 0; |
| onSlideEnd?.(); |
| }, |
| onStepKeyDown: (event) => { |
| const slideDirection = isSlidingFromLeft ? "from-left" : "from-right"; |
| const isBackKey = BACK_KEYS[slideDirection].includes(event.key); |
| onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 }); |
| } |
| } |
| ) |
| } |
| ); |
| } |
| ); |
| var SliderVertical = React.forwardRef( |
| (props, forwardedRef) => { |
| const { |
| min, |
| max, |
| inverted, |
| onSlideStart, |
| onSlideMove, |
| onSlideEnd, |
| onStepKeyDown, |
| ...sliderProps |
| } = props; |
| const sliderRef = React.useRef(null); |
| const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, sliderRef); |
| const rectRef = React.useRef(void 0); |
| const isSlidingFromBottom = !inverted; |
| function getValueFromPointer(pointerPosition) { |
| const rect = rectRef.current || sliderRef.current.getBoundingClientRect(); |
| const input = [0, rect.height]; |
| const output = isSlidingFromBottom ? [max, min] : [min, max]; |
| const value = linearScale(input, output); |
| rectRef.current = rect; |
| return value(pointerPosition - rect.top); |
| } |
| return (0, import_jsx_runtime.jsx)( |
| SliderOrientationProvider, |
| { |
| scope: props.__scopeSlider, |
| startEdge: isSlidingFromBottom ? "bottom" : "top", |
| endEdge: isSlidingFromBottom ? "top" : "bottom", |
| size: "height", |
| direction: isSlidingFromBottom ? 1 : -1, |
| children: (0, import_jsx_runtime.jsx)( |
| SliderImpl, |
| { |
| "data-orientation": "vertical", |
| ...sliderProps, |
| ref, |
| style: { |
| ...sliderProps.style, |
| ["--radix-slider-thumb-transform"]: "translateY(50%)" |
| }, |
| onSlideStart: (event) => { |
| const value = getValueFromPointer(event.clientY); |
| onSlideStart?.(value); |
| }, |
| onSlideMove: (event) => { |
| const value = getValueFromPointer(event.clientY); |
| onSlideMove?.(value); |
| }, |
| onSlideEnd: () => { |
| rectRef.current = void 0; |
| onSlideEnd?.(); |
| }, |
| onStepKeyDown: (event) => { |
| const slideDirection = isSlidingFromBottom ? "from-bottom" : "from-top"; |
| const isBackKey = BACK_KEYS[slideDirection].includes(event.key); |
| onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 }); |
| } |
| } |
| ) |
| } |
| ); |
| } |
| ); |
| var SliderImpl = React.forwardRef( |
| (props, forwardedRef) => { |
| const { |
| __scopeSlider, |
| onSlideStart, |
| onSlideMove, |
| onSlideEnd, |
| onHomeKeyDown, |
| onEndKeyDown, |
| onStepKeyDown, |
| ...sliderProps |
| } = props; |
| const context = useSliderContext(SLIDER_NAME, __scopeSlider); |
| return (0, import_jsx_runtime.jsx)( |
| import_react_primitive.Primitive.span, |
| { |
| ...sliderProps, |
| ref: forwardedRef, |
| onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => { |
| if (event.key === "Home") { |
| onHomeKeyDown(event); |
| event.preventDefault(); |
| } else if (event.key === "End") { |
| onEndKeyDown(event); |
| event.preventDefault(); |
| } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) { |
| onStepKeyDown(event); |
| event.preventDefault(); |
| } |
| }), |
| onPointerDown: (0, import_primitive.composeEventHandlers)(props.onPointerDown, (event) => { |
| const target = event.target; |
| target.setPointerCapture(event.pointerId); |
| event.preventDefault(); |
| if (context.thumbs.has(target)) { |
| target.focus(); |
| } else { |
| onSlideStart(event); |
| } |
| }), |
| onPointerMove: (0, import_primitive.composeEventHandlers)(props.onPointerMove, (event) => { |
| const target = event.target; |
| if (target.hasPointerCapture(event.pointerId)) onSlideMove(event); |
| }), |
| onPointerUp: (0, import_primitive.composeEventHandlers)(props.onPointerUp, (event) => { |
| const target = event.target; |
| if (target.hasPointerCapture(event.pointerId)) { |
| target.releasePointerCapture(event.pointerId); |
| onSlideEnd(event); |
| } |
| }) |
| } |
| ); |
| } |
| ); |
| var TRACK_NAME = "SliderTrack"; |
| var SliderTrack = React.forwardRef( |
| (props, forwardedRef) => { |
| const { __scopeSlider, ...trackProps } = props; |
| const context = useSliderContext(TRACK_NAME, __scopeSlider); |
| return (0, import_jsx_runtime.jsx)( |
| import_react_primitive.Primitive.span, |
| { |
| "data-disabled": context.disabled ? "" : void 0, |
| "data-orientation": context.orientation, |
| ...trackProps, |
| ref: forwardedRef |
| } |
| ); |
| } |
| ); |
| SliderTrack.displayName = TRACK_NAME; |
| var RANGE_NAME = "SliderRange"; |
| var SliderRange = React.forwardRef( |
| (props, forwardedRef) => { |
| const { __scopeSlider, ...rangeProps } = props; |
| const context = useSliderContext(RANGE_NAME, __scopeSlider); |
| const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider); |
| const ref = React.useRef(null); |
| const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref); |
| const valuesCount = context.values.length; |
| const percentages = context.values.map( |
| (value) => convertValueToPercentage(value, context.min, context.max) |
| ); |
| const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0; |
| const offsetEnd = 100 - Math.max(...percentages); |
| return (0, import_jsx_runtime.jsx)( |
| import_react_primitive.Primitive.span, |
| { |
| "data-orientation": context.orientation, |
| "data-disabled": context.disabled ? "" : void 0, |
| ...rangeProps, |
| ref: composedRefs, |
| style: { |
| ...props.style, |
| [orientation.startEdge]: offsetStart + "%", |
| [orientation.endEdge]: offsetEnd + "%" |
| } |
| } |
| ); |
| } |
| ); |
| SliderRange.displayName = RANGE_NAME; |
| var THUMB_NAME = "SliderThumb"; |
| var SliderThumb = React.forwardRef( |
| (props, forwardedRef) => { |
| const getItems = useCollection(props.__scopeSlider); |
| const [thumb, setThumb] = React.useState(null); |
| const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node) => setThumb(node)); |
| const index = React.useMemo( |
| () => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1, |
| [getItems, thumb] |
| ); |
| return (0, import_jsx_runtime.jsx)(SliderThumbImpl, { ...props, ref: composedRefs, index }); |
| } |
| ); |
| var SliderThumbImpl = React.forwardRef( |
| (props, forwardedRef) => { |
| const { __scopeSlider, index, name, ...thumbProps } = props; |
| const context = useSliderContext(THUMB_NAME, __scopeSlider); |
| const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider); |
| const [thumb, setThumb] = React.useState(null); |
| const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node) => setThumb(node)); |
| const isFormControl = thumb ? context.form || !!thumb.closest("form") : true; |
| const size = (0, import_react_use_size.useSize)(thumb); |
| const value = context.values[index]; |
| const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max); |
| const label = getLabel(index, context.values.length); |
| const orientationSize = size?.[orientation.size]; |
| const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0; |
| React.useEffect(() => { |
| if (thumb) { |
| context.thumbs.add(thumb); |
| return () => { |
| context.thumbs.delete(thumb); |
| }; |
| } |
| }, [thumb, context.thumbs]); |
| return (0, import_jsx_runtime.jsxs)( |
| "span", |
| { |
| style: { |
| transform: "var(--radix-slider-thumb-transform)", |
| position: "absolute", |
| [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)` |
| }, |
| children: [ |
| (0, import_jsx_runtime.jsx)(Collection.ItemSlot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime.jsx)( |
| import_react_primitive.Primitive.span, |
| { |
| role: "slider", |
| "aria-label": props["aria-label"] || label, |
| "aria-valuemin": context.min, |
| "aria-valuenow": value, |
| "aria-valuemax": context.max, |
| "aria-orientation": context.orientation, |
| "data-orientation": context.orientation, |
| "data-disabled": context.disabled ? "" : void 0, |
| tabIndex: context.disabled ? void 0 : 0, |
| ...thumbProps, |
| ref: composedRefs, |
| style: value === void 0 ? { display: "none" } : props.style, |
| onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, () => { |
| context.valueIndexToChangeRef.current = index; |
| }) |
| } |
| ) }), |
| isFormControl && (0, import_jsx_runtime.jsx)( |
| BubbleInput, |
| { |
| name: name ?? (context.name ? context.name + (context.values.length > 1 ? "[]" : "") : void 0), |
| form: context.form, |
| value |
| }, |
| index |
| ) |
| ] |
| } |
| ); |
| } |
| ); |
| SliderThumb.displayName = THUMB_NAME; |
| var BubbleInput = (props) => { |
| const { value, ...inputProps } = props; |
| const ref = React.useRef(null); |
| const prevValue = (0, import_react_use_previous.usePrevious)(value); |
| React.useEffect(() => { |
| const input = ref.current; |
| const inputProto = window.HTMLInputElement.prototype; |
| const descriptor = Object.getOwnPropertyDescriptor(inputProto, "value"); |
| const setValue = descriptor.set; |
| if (prevValue !== value && setValue) { |
| const event = new Event("input", { bubbles: true }); |
| setValue.call(input, value); |
| input.dispatchEvent(event); |
| } |
| }, [prevValue, value]); |
| return (0, import_jsx_runtime.jsx)("input", { style: { display: "none" }, ...inputProps, ref, defaultValue: value }); |
| }; |
| function getNextSortedValues(prevValues = [], nextValue, atIndex) { |
| const nextValues = [...prevValues]; |
| nextValues[atIndex] = nextValue; |
| return nextValues.sort((a, b) => a - b); |
| } |
| function convertValueToPercentage(value, min, max) { |
| const maxSteps = max - min; |
| const percentPerStep = 100 / maxSteps; |
| const percentage = percentPerStep * (value - min); |
| return (0, import_number.clamp)(percentage, [0, 100]); |
| } |
| function getLabel(index, totalValues) { |
| if (totalValues > 2) { |
| return `Value ${index + 1} of ${totalValues}`; |
| } else if (totalValues === 2) { |
| return ["Minimum", "Maximum"][index]; |
| } else { |
| return void 0; |
| } |
| } |
| function getClosestValueIndex(values, nextValue) { |
| if (values.length === 1) return 0; |
| const distances = values.map((value) => Math.abs(value - nextValue)); |
| const closestDistance = Math.min(...distances); |
| return distances.indexOf(closestDistance); |
| } |
| function getThumbInBoundsOffset(width, left, direction) { |
| const halfWidth = width / 2; |
| const halfPercent = 50; |
| const offset = linearScale([0, halfPercent], [0, halfWidth]); |
| return (halfWidth - offset(left) * direction) * direction; |
| } |
| function getStepsBetweenValues(values) { |
| return values.slice(0, -1).map((value, index) => values[index + 1] - value); |
| } |
| function hasMinStepsBetweenValues(values, minStepsBetweenValues) { |
| if (minStepsBetweenValues > 0) { |
| const stepsBetweenValues = getStepsBetweenValues(values); |
| const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues); |
| return actualMinStepsBetweenValues >= minStepsBetweenValues; |
| } |
| return true; |
| } |
| function linearScale(input, output) { |
| return (value) => { |
| if (input[0] === input[1] || output[0] === output[1]) return output[0]; |
| const ratio = (output[1] - output[0]) / (input[1] - input[0]); |
| return output[0] + ratio * (value - input[0]); |
| }; |
| } |
| function getDecimalCount(value) { |
| return (String(value).split(".")[1] || "").length; |
| } |
| function roundValue(value, decimalCount) { |
| const rounder = Math.pow(10, decimalCount); |
| return Math.round(value * rounder) / rounder; |
| } |
| var Root = Slider; |
| var Track = SliderTrack; |
| var Range = SliderRange; |
| var Thumb = SliderThumb; |
| |
|
|