UNPKG

@julo-ui/sliders

Version:

A React Slider component that implements input[type='range']

898 lines (876 loc) 30.1 kB
"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/RangeSlider.tsx var RangeSlider_exports = {}; __export(RangeSlider_exports, { default: () => RangeSlider_default }); module.exports = __toCommonJS(RangeSlider_exports); var import_system = require("@julo-ui/system"); // src/range-slider/styles.ts var import_react = require("@emotion/react"); var rangeSliderCx = import_react.css``; // src/range-slider/use-range-slider.ts var import_react7 = require("react"); var import_use_callback_ref = require("@julo-ui/use-callback-ref"); var import_number_utils3 = require("@julo-ui/number-utils"); var import_use_controllable_state = require("@julo-ui/use-controllable-state"); var import_use_watch_element_size = require("@julo-ui/use-watch-element-size"); // src/usecase/use-handle-dragging.ts var import_react2 = require("react"); function useHandleDragging() { const [isDragging, setIsDragging] = (0, import_react2.useState)(false); const onDraggingStart = (0, import_react2.useCallback)(() => { setIsDragging(true); }, []); const onDraggingEnd = (0, import_react2.useCallback)(() => { setIsDragging(false); }, []); return { isDragging, onDraggingStart, onDraggingEnd }; } var use_handle_dragging_default = useHandleDragging; // src/usecase/use-handle-focus.ts var import_react3 = require("react"); function useHandleFocus() { const [isFocused, setIsFocused] = (0, import_react3.useState)(false); const onFocus = (0, import_react3.useCallback)(() => { setIsFocused(true); }, []); const onBlur = (0, import_react3.useCallback)(() => { setIsFocused(false); }, []); return { isFocused, onFocus, onBlur }; } var use_handle_focus_default = useHandleFocus; // src/usecase/use-handle-reversed.ts function useHandleReversed(options) { const { isReversed = false, direction, orientation } = options; if (direction === "ltr" || orientation === "vertical") { return isReversed; } return !isReversed; } var use_handle_reversed_default = useHandleReversed; // src/usecase/use-handle-style.ts var import_react4 = require("react"); var defaultSize = { width: 0, height: 0 }; var normalizeSize = (size) => size || defaultSize; function useHandleStyle(options) { const { thumbSizes: thumbRects, orientation, isReversed, thumbPercents } = options; const getThumbStyle = (0, import_react4.useCallback)( (i) => { var _a; const rect = (_a = thumbRects[i]) != null ? _a : defaultSize; return { position: "absolute", userSelect: "none", WebkitUserSelect: "none", MozUserSelect: "none", msUserSelect: "none", touchAction: "none", ...orientation === "vertical" ? { bottom: `calc(${thumbPercents[i]}% - ${rect.height / 2}px)` } : { left: `calc(${thumbPercents[i]}% - ${rect.width / 2}px)` } }; }, [orientation, thumbPercents, thumbRects] ); const getMarkerStyle = (0, import_react4.useCallback)( (percent) => { return { position: "absolute", pointerEvents: "none", ...orientation === "vertical" ? { bottom: `${percent}%`, transform: `translateY(-50%)` } : { left: `${percent}%`, transform: `translateX(-50%)` } }; }, [orientation] ); const rootStyle = (0, import_react4.useMemo)(() => { const size = normalizeSize( orientation === "vertical" ? thumbRects.reduce( (a, b) => normalizeSize(a).height > normalizeSize(b).height ? a : b, defaultSize ) : thumbRects.reduce( (a, b) => normalizeSize(a).width > normalizeSize(b).width ? a : b, defaultSize ) ); return { position: "relative", touchAction: "none", WebkitTapHighlightColor: "rgba(0,0,0,0)", userSelect: "none", outline: 0, ...orientation === "vertical" ? { paddingLeft: size.width / 2, paddingRight: size.width / 2, height: "100%" } : { paddingTop: size.height / 2, paddingBottom: size.height / 2, width: "100%" } }; }, [orientation, thumbRects]); const trackStyle = (0, import_react4.useMemo)( () => ({ position: "absolute", ...orientation === "vertical" ? { left: "50%", transform: "translateX(-50%)", height: "100%" } : { top: "50%", transform: "translateY(-50%)", width: "100%" } }), [orientation] ); const innerTrackStyle = (0, import_react4.useMemo)(() => { const isSingleThumb = thumbPercents.length === 1; const fallback = [ 0, isReversed ? 100 - thumbPercents[0] : thumbPercents[0] ]; const range = isSingleThumb ? fallback : thumbPercents; let start = range[0]; if (!isSingleThumb && isReversed) { start = 100 - start; } const percent = Math.abs(range[range.length - 1] - range[0]); return { ...trackStyle, ...orientation === "vertical" ? isReversed ? { height: `${percent}%`, top: `${start}%` } : { height: `${percent}%`, bottom: `${start}%` } : isReversed ? { width: `${percent}%`, right: `${start}%` } : { width: `${percent}%`, left: `${start}%` } }; }, [isReversed, orientation, thumbPercents, trackStyle]); return { getThumbStyle, rootStyle, trackStyle, innerTrackStyle, getMarkerStyle }; } var use_handle_style_default = useHandleStyle; // src/range-slider/constants.ts var RANGE_SLIDER_DEFAULT_VALUE = [25, 75]; // src/range-slider/utils.ts var import_number_utils2 = require("@julo-ui/number-utils"); // src/utils.ts var import_number_utils = require("@julo-ui/number-utils"); function valueToPercent(value, min, max) { return (value - min) * 100 / (max - min); } function percentToValue(percent, min, max) { return (max - min) * percent + min; } function isMouseEvent(event) { return !("touches" in event); } function roundValueToStep(value, from, step) { const nextValue = Math.round((value - from) / step) * step + from; const precision = (0, import_number_utils.countDecimalPlaces)(step); return (0, import_number_utils.toPreciseDecimal)(nextValue, precision); } // src/range-slider/utils.ts function getValueBounds(value, min, max, spacing) { return value.map((_v, i) => { const _min = i === 0 ? min : value[i - 1] + spacing; const _max = i === value.length - 1 ? max : value[i + 1] - spacing; return { min: _min, max: _max }; }); } function getIds(id) { return { root: `slider-root-${id}`, getThumb: (i) => `slider-thumb-${id}-${i}`, getInput: (i) => `slider-input-${id}-${i}`, track: `slider-track-${id}`, innerTrack: `slider-filled-track-${id}`, getMarker: (i) => `slider-marker-${id}-${i}`, output: `slider-output-${id}` }; } function getThumbStateOnChange({ bounds, index, values, pointerValue, prevValue, step, isDisableSwap, distanceBetweenThumbs }) { const prevValueAtIndex = prevValue[index]; const boundsAtIndex = bounds[index]; let valueAtIndex = (0, import_number_utils2.clampValue)( parseFloat(roundValueToStep(pointerValue, boundsAtIndex.min, step)), isDisableSwap ? boundsAtIndex.min : bounds[0].min, isDisableSwap ? boundsAtIndex.max : bounds[bounds.length - 1].max ); const isDecreasing = pointerValue < prevValueAtIndex; const isValueExceedBoundedValue = !isDisableSwap && (isDecreasing ? valueAtIndex <= boundsAtIndex.min - distanceBetweenThumbs : valueAtIndex >= boundsAtIndex.max + distanceBetweenThumbs); if (isValueExceedBoundedValue) { const totalThumb = prevValue.length; let isFoundNewThumb = false; let isNoMoreThumb = false; values[index] = isDecreasing ? boundsAtIndex.min : boundsAtIndex.max; for (let i = isDecreasing ? index - 1 : index + 1; !isFoundNewThumb && !isNoMoreThumb; isDecreasing ? i-- : i++) { if (i >= totalThumb || i < 0) { isNoMoreThumb = true; if (isDecreasing ? valueAtIndex < boundsAtIndex.min : valueAtIndex > boundsAtIndex.max) { valueAtIndex = isDecreasing ? boundsAtIndex.min : boundsAtIndex.max; } continue; } if (!isDecreasing ? valueAtIndex >= bounds[i].min && valueAtIndex < bounds[i].max + distanceBetweenThumbs : valueAtIndex > bounds[i].min - distanceBetweenThumbs && valueAtIndex <= bounds[i].max) { isFoundNewThumb = true; index = i; } } } else { if (!isDecreasing && pointerValue > boundsAtIndex.max) { valueAtIndex = boundsAtIndex.max; } if (isDecreasing && pointerValue < boundsAtIndex.min) { valueAtIndex = boundsAtIndex.min; } } values[index] = valueAtIndex; return { index, value: values }; } // src/range-slider/usecase/use-handle-focus-thumb.ts var import_react5 = require("react"); function useHandleFocusThumb(options) { const { focusThumbOnChange, rootRef, ids, activeIndex } = options; const onFocusThumb = (0, import_react5.useCallback)( (index) => { var _a; const targetIndex = index != null ? index : activeIndex; if (targetIndex === -1 || !focusThumbOnChange) return; const id = ids.getThumb(targetIndex); const thumb = (_a = rootRef.current) == null ? void 0 : _a.ownerDocument.getElementById(id); if (thumb) { setTimeout(() => thumb.focus()); } }, [activeIndex, focusThumbOnChange, ids, rootRef] ); return { onFocusThumb }; } var use_handle_focus_thumb_default = useHandleFocusThumb; // src/range-slider/usecase/use-handle-pan-event.ts var import_react6 = require("react"); var import_react_use_pan_event = require("@chakra-ui/react-use-pan-event"); var import_function_utils = require("@julo-ui/function-utils"); function useHandlePanEvent(options) { const { rootRef, trackRef, sliderStates, activeIndex, actions, onFocusThumb, onDraggingStart, onDraggingEnd, onChangeStart = import_function_utils._noop, onChangeEnd = import_function_utils._noop, isDisableSwap, prevValue, distanceBetweenThumbs } = options; const getValueFromPointer = (0, import_react6.useCallback)( (event) => { var _a; if (!trackRef.current) return; sliderStates.eventSource = "pointer"; const trackRect = trackRef.current.getBoundingClientRect(); const { clientX, clientY } = !isMouseEvent(event) ? (_a = event.touches) == null ? void 0 : _a[0] : event; const diff = sliderStates.isVertical ? trackRect.bottom - clientY : clientX - trackRect.left; const length = sliderStates.isVertical ? trackRect.height : trackRect.width; let percent = diff / length; if (sliderStates.isReversed) percent = 1 - percent; return percentToValue(percent, sliderStates.min, sliderStates.max); }, [trackRef, sliderStates] ); const onPanSessionStart = (0, import_react6.useCallback)( (event) => { var _a; if (!sliderStates.isInteractive) return; onDraggingStart(); const pointValue = (_a = getValueFromPointer(event)) != null ? _a : 0; const distances = sliderStates.value.map( (value) => Math.abs(value - pointValue) ); const closest = Math.min(...distances); let targetIndex = distances.indexOf(closest); const thumbsPosition = distances.filter( (distance) => distance === closest ); const isThumbStacked = thumbsPosition.length > 1; if (isThumbStacked && pointValue > sliderStates.value[targetIndex]) { targetIndex = targetIndex + thumbsPosition.length - 1; } actions.setActiveIndex(targetIndex); actions.setValueAtIndex(targetIndex, pointValue); onFocusThumb(targetIndex); onChangeStart(sliderStates.value); }, [ actions, getValueFromPointer, onChangeStart, onDraggingStart, onFocusThumb, sliderStates.isInteractive, sliderStates.value ] ); const onPan = (0, import_react6.useCallback)( (event) => { var _a; if (!sliderStates.isInteractive || activeIndex === -1) return; const pointerValue = (_a = getValueFromPointer(event)) != null ? _a : 0; const values = [...sliderStates.value]; const bounds = [...sliderStates.valueBounds]; const { index, value } = getThumbStateOnChange({ pointerValue, values, bounds, isDisableSwap, index: activeIndex, prevValue: prevValue.current, step: sliderStates.step, distanceBetweenThumbs }); actions.setActiveIndex(index); actions.setValue(value); onFocusThumb(index); }, [ actions, activeIndex, distanceBetweenThumbs, getValueFromPointer, isDisableSwap, onFocusThumb, prevValue, sliderStates.isInteractive, sliderStates.step, sliderStates.value, sliderStates.valueBounds ] ); (0, import_react_use_pan_event.usePanEvent)(rootRef, { onPanSessionStart, onPanSessionEnd() { if (!sliderStates.isInteractive) return; onDraggingEnd(); prevValue.current = sliderStates.value; onChangeEnd(sliderStates.value); }, onPan }); } var use_handle_pan_event_default = useHandlePanEvent; // src/range-slider/use-range-slider.ts var import_dom_utils = require("@julo-ui/dom-utils"); var import_function_utils2 = require("@julo-ui/function-utils"); function useRangeSlider(props) { const { min = 0, max = 100, onChange, value: valueProp, defaultValue, isReversed: isReversedProp, direction = "ltr", orientation = "horizontal", id: idProp, isDisabled = false, isReadOnly, onChangeStart: onChangeStartProp, onChangeEnd: onChangeEndProp, step = 1, getAriaValueText: getAriaValueTextProp, "aria-valuetext": ariaValueText, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, name, focusThumbOnChange = true, minStepsBetweenThumbs = 0, isDisableSwap = false, ...resRootProps } = props; const onChangeStart = (0, import_use_callback_ref.useCallbackRef)(onChangeStartProp); const onChangeEnd = (0, import_use_callback_ref.useCallbackRef)(onChangeEndProp); const getAriaValueText = (0, import_use_callback_ref.useCallbackRef)(getAriaValueTextProp); const isReversed = use_handle_reversed_default({ isReversed: isReversedProp, direction, orientation }); const [computedValue, setComputedValue] = (0, import_use_controllable_state.useControllableState)({ value: valueProp, defaultValue: defaultValue != null ? defaultValue : RANGE_SLIDER_DEFAULT_VALUE, onChange }); if (!Array.isArray(computedValue)) { throw new TypeError( `[range-slider] You passed an invalid value for \`value\` or \`defaultValue\`, expected \`Array\` but got \`${typeof computedValue}\`` ); } const [activeIndex, setActiveIndex] = (0, import_react7.useState)(-1); const initialValue = (0, import_react7.useRef)(computedValue); const isInteractive = !(isDisabled || isReadOnly); const tenSteps = (max - min) / 10; const oneStep = step || (max - min) / 100; const value = computedValue.map((val) => (0, import_number_utils3.clampValue)(val, min, max)); const prevValue = (0, import_react7.useRef)(value); const distanceBetweenThumbs = minStepsBetweenThumbs * step; const valueBounds = getValueBounds(value, min, max, distanceBetweenThumbs); const reversedValue = value.map((val) => max - val + min); const thumbValues = isReversed ? reversedValue : value; const thumbPercents = thumbValues.map((val) => valueToPercent(val, min, max)); const isVertical = orientation === "vertical"; const trackRef = (0, import_react7.useRef)(null); const rootRef = (0, import_react7.useRef)(null); const reactId = (0, import_react7.useId)(); const uuid = idProp != null ? idProp : reactId; const ids = getIds(uuid); const thumbSizes = (0, import_use_watch_element_size.useWatchElementsSize)({ getNodes() { const rootNode = rootRef.current; const thumbNodes = rootNode == null ? void 0 : rootNode.querySelectorAll("[role=slider]"); return thumbNodes ? Array.from(thumbNodes) : []; } }); const { isDragging, onDraggingStart, onDraggingEnd } = use_handle_dragging_default(); const { isFocused, onBlur: onInputBlur, onFocus: onInputFocus } = use_handle_focus_default(); const sliderStates = (0, import_react7.useMemo)( () => ({ eventSource: null, value, valueBounds, getThumbMaxValue: (index) => valueBounds[index].max, getThumbMinValue: (index) => valueBounds[index].min, getThumbPercent: (index) => thumbPercents[index], isFocused, isDragging, focusThumbOnChange, isDisabled, isInteractive, isReversed, isVertical, max, min, orientation, step: oneStep, tenSteps, distanceBetweenThumbs }), [ distanceBetweenThumbs, focusThumbOnChange, isDisabled, isDragging, isFocused, isInteractive, isReversed, isVertical, max, min, oneStep, orientation, tenSteps, thumbPercents, value, valueBounds ] ); const { onFocusThumb } = use_handle_focus_thumb_default({ activeIndex, focusThumbOnChange, ids, rootRef }); const actions = (0, import_react7.useMemo)( () => ({ setValueAtIndex(index, value2) { if (!sliderStates.isInteractive) return; const bounds = sliderStates.valueBounds[index]; value2 = parseFloat(roundValueToStep(value2, bounds.min, oneStep)); value2 = (0, import_number_utils3.clampValue)(value2, bounds.min, bounds.max); const next = [...sliderStates.value]; next[index] = value2; setComputedValue(next); }, setActiveIndex, stepUp(index, step2 = oneStep) { const bounds = [...sliderStates.valueBounds]; const values = [...sliderStates.value]; const valueAtIndex = sliderStates.value[index]; const next = sliderStates.isReversed ? valueAtIndex - step2 : valueAtIndex + step2; const { index: newIndex, value: value2 } = getThumbStateOnChange({ bounds, values, pointerValue: next, index, isDisableSwap, prevValue: prevValue.current, step: sliderStates.step, distanceBetweenThumbs }); actions.setValue(value2); setActiveIndex(newIndex); onFocusThumb(newIndex); }, stepDown(index, step2 = oneStep) { const bounds = [...sliderStates.valueBounds]; const values = [...sliderStates.value]; const valueAtIndex = sliderStates.value[index]; const next = sliderStates.isReversed ? valueAtIndex + step2 : valueAtIndex - step2; const { index: newIndex, value: value2 } = getThumbStateOnChange({ bounds, values, pointerValue: next, index, isDisableSwap, prevValue: prevValue.current, step: sliderStates.step, distanceBetweenThumbs }); actions.setValue(value2); setActiveIndex(newIndex); onFocusThumb(newIndex); }, setValue: setComputedValue, reset() { setComputedValue(initialValue.current); } }), [ distanceBetweenThumbs, isDisableSwap, onFocusThumb, oneStep, setComputedValue, sliderStates.isInteractive, sliderStates.isReversed, sliderStates.step, sliderStates.value, sliderStates.valueBounds ] ); const { getThumbStyle, innerTrackStyle, getMarkerStyle, rootStyle, trackStyle } = use_handle_style_default({ isReversed: sliderStates.isReversed, orientation: sliderStates.orientation, thumbPercents, thumbSizes }); use_handle_pan_event_default({ onChangeEnd, onChangeStart, onDraggingEnd, onDraggingStart, onFocusThumb, rootRef, sliderStates, activeIndex, trackRef, actions, isDisableSwap, prevValue, distanceBetweenThumbs }); const onThumbKeyUp = (0, import_react7.useCallback)(() => { prevValue.current = sliderStates.value; }, [sliderStates.value]); const onThumbKeyDown = (0, import_react7.useCallback)( (event) => { const keyMap = { ArrowRight: () => actions.stepUp(activeIndex), ArrowUp: () => actions.stepUp(activeIndex), ArrowLeft: () => actions.stepDown(activeIndex), ArrowDown: () => actions.stepDown(activeIndex), PageUp: () => actions.stepUp(activeIndex, tenSteps), PageDown: () => actions.stepDown(activeIndex, tenSteps), Home: () => { const { min: value2 } = valueBounds[activeIndex]; actions.setValueAtIndex(activeIndex, value2); }, End: () => { const { max: value2 } = valueBounds[activeIndex]; actions.setValueAtIndex(activeIndex, value2); } }; const action = keyMap[event.key]; if (action) { event.preventDefault(); event.stopPropagation(); action(event); sliderStates.eventSource = "keyboard"; } }, [actions, activeIndex, sliderStates, tenSteps, valueBounds] ); const getRootProps = (0, import_react7.useCallback)( (props2 = {}, forwardedRef = null) => ({ ...resRootProps, ...props2, id: ids.root, ref: (0, import_dom_utils.mergeRefs)(forwardedRef, rootRef), tabIndex: -1, style: { ...props2.style, ...rootStyle }, "aria-disabled": (0, import_dom_utils.ariaAttr)(isDisabled), "data-focused": (0, import_dom_utils.dataAttr)(isFocused) }), [ids.root, isDisabled, isFocused, resRootProps, rootStyle] ); const getTrackProps = (0, import_react7.useCallback)( (props2 = {}, forwardedRef = null) => ({ ...props2, ref: (0, import_dom_utils.mergeRefs)(forwardedRef, trackRef), id: ids.track, "data-disabled": (0, import_dom_utils.dataAttr)(isDisabled), style: { ...props2.style, ...trackStyle } }), [ids.track, isDisabled, trackStyle] ); const getInnerTrackProps = (0, import_react7.useCallback)( (props2 = {}, forwardedRef = null) => ({ ...props2, ref: forwardedRef, id: ids.innerTrack, style: { ...props2.style, ...innerTrackStyle } }), [ids.innerTrack, innerTrackStyle] ); const getThumbProps = (0, import_react7.useCallback)( (props2, forwardedRef = null) => { var _a; const { index, style, onKeyDown, onKeyUp, onFocus, onBlur, ...resProps } = props2; const valueAtIndex = sliderStates.value[index]; const bounds = sliderStates.valueBounds[index]; if ((0, import_function_utils2.isTrullyEmpty)(valueAtIndex)) throw new TypeError( `[range-slider > thumb] Cannot find value at index \`${index}\`. The \`value\` or \`defaultValue\` length is : ${sliderStates.value.length}` ); return { ...resProps, ref: forwardedRef, role: "slider", ...isInteractive && { tabIndex: 0 }, id: ids.getThumb(index), "data-active": (0, import_dom_utils.dataAttr)(isDragging && activeIndex === index), "aria-valuetext": (_a = getAriaValueText == null ? void 0 : getAriaValueText(valueAtIndex)) != null ? _a : ariaValueText == null ? void 0 : ariaValueText[index], "aria-valuemin": bounds.min, "aria-valuemax": bounds.max, "aria-valuenow": valueAtIndex, "aria-orientation": orientation, "aria-disabled": (0, import_dom_utils.ariaAttr)(isDisabled), "aria-readonly": (0, import_dom_utils.ariaAttr)(isReadOnly), "aria-label": ariaLabel == null ? void 0 : ariaLabel[index], ...!(ariaLabel == null ? void 0 : ariaLabel[index]) && { "aria-labelledby": ariaLabelledBy == null ? void 0 : ariaLabelledBy[index] }, style: { ...style, ...getThumbStyle(index) }, onKeyUp: (0, import_function_utils2.callAllFn)(onThumbKeyUp, onKeyUp), onKeyDown: (0, import_function_utils2.callAllFn)(onThumbKeyDown, onKeyDown), onFocus: (0, import_function_utils2.callAllFn)(onInputFocus, () => setActiveIndex(index), onFocus), onBlur: (0, import_function_utils2.callAllFn)(onInputBlur, () => setActiveIndex(-1), onBlur) }; }, [ activeIndex, ariaLabel, ariaLabelledBy, ariaValueText, getAriaValueText, getThumbStyle, ids, isDisabled, isDragging, isInteractive, isReadOnly, onInputBlur, onInputFocus, onThumbKeyDown, onThumbKeyUp, orientation, sliderStates.value, sliderStates.valueBounds ] ); const getOutputProps = (0, import_react7.useCallback)( (props2 = {}, forwardedRef = null) => ({ ...props2, ref: forwardedRef, id: ids.output, htmlFor: value.map((_v, i) => ids.getThumb(i)).join(" "), "aria-live": "off" }), [ids, value] ); const getMarkerProps = (0, import_react7.useCallback)( (props2, forwardedRef = null) => { const { value: markerValue, style, ...resProps } = props2; const isInRange = !(markerValue < sliderStates.min || markerValue || sliderStates.max); const isHighlighted = markerValue >= sliderStates.value[0] && markerValue <= sliderStates.value[sliderStates.value.length - 1]; const markerPercent = valueToPercent(markerValue, min, max); const percent = isReversed ? 100 - markerPercent : markerPercent; return { ...resProps, ref: forwardedRef, role: "presentation", "aria-hidden": true, "data-disabled": (0, import_dom_utils.dataAttr)(isDisabled), "data-invalid": (0, import_dom_utils.dataAttr)(!isInRange), "data-highlighted": (0, import_dom_utils.dataAttr)(isHighlighted), style: { ...style, ...getMarkerStyle(percent) } }; }, [ getMarkerStyle, isDisabled, isReversed, max, min, sliderStates.max, sliderStates.min, sliderStates.value ] ); const getInputProps = (0, import_react7.useCallback)( (props2, forwardedRef = null) => { const { index, ...resProps } = props2; return { ...resProps, ref: forwardedRef, id: ids.getInput(index), type: "hidden", value: sliderStates.value[index], name: name ? Array.isArray(name) ? name[index] : `${name}-${index}` : `${ids.getInput(index)}-${index}` }; }, [ids, name, sliderStates.value] ); (0, import_react7.useEffect)(() => { if (sliderStates.eventSource === "keyboard") { onChangeEnd == null ? void 0 : onChangeEnd(sliderStates.value); } }, [value, onChangeEnd, sliderStates.eventSource, sliderStates.value]); return { state: sliderStates, actions, getRootProps, getTrackProps, getInnerTrackProps, getThumbProps, getMarkerProps, getInputProps, getOutputProps }; } // src/styles.ts var import_react8 = require("@emotion/react"); var rootSliderCx = import_react8.css` --slider-track-size: 0.5rem; --slider-thumb-size: 1rem; width: fit-content; `; var rootSliderVerticalTrackCx = import_react8.css` width: var(--slider-track-size); `; var rootSliderHorizontalTrackCx = import_react8.css` height: var(--slider-track-size); `; var rootSliderTrackCx = import_react8.css` overflow: hidden; border-radius: var(--corner-3xl); background-color: var(--colors-neutrals-40); `; var rootSliderThumbCx = import_react8.css` z-index: 1; width: var(--slider-thumb-size); height: var(--slider-thumb-size); border-radius: var(--corner-3xl); background-color: var(--colors-neutrals-10); box-shadow: var(--shadows-md); display: flex; align-items: center; justify-content: center; `; var rootSliderInnerTrackCx = import_react8.css` background-color: var(--colors-primary-30); height: inherit; width: inherit; `; // src/range-slider/RangeSliderProvider.tsx var import_context = require("@julo-ui/context"); var [RangeSliderProvider, useRangeSliderContext] = (0, import_context.createContext)({ name: "SliderContext", hookName: "useRangeSliderContext", providerName: "<RangeSliderProvider />" }); // src/range-slider/RangeSlider.tsx var import_jsx_runtime = require("react/jsx-runtime"); var RangeSlider = (0, import_system.forwardRef)((props, ref) => { const { children, className, orientation = "horizontal", ...resProps } = props; const { getRootProps, ...rangeSliderContext } = useRangeSlider({ direction: "ltr", orientation, ...resProps }); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RangeSliderProvider, { value: rangeSliderContext, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_system.julo.div, { className: (0, import_system.cx)("julo-range-slider", className), ...getRootProps({}, ref), __css: [rootSliderCx, rangeSliderCx], children } ) }); }); RangeSlider.displayName = "RangeSlider"; var RangeSlider_default = RangeSlider; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = {});