UNPKG

react-native-epic-slider

Version:

![NPM Version](https://img.shields.io/npm/v/react-native-epic-slider) ![NPM Downloads](https://img.shields.io/npm/dw/react-native-epic-slider) [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/)

256 lines (236 loc) 9.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _reactNative = require("react-native"); const useSlider = ({ value, min, max, orientation, step, allowDecimal, onChange, thumbSize }) => { const [sliderCoordinate, setSliderCoordinate] = (0, _react.useState)({ x: 0, y: 0, height: 0, width: 0 }); const [currentValue, setCurrentValue] = (0, _react.useState)(value); const [isDragging, setIsDragging] = (0, _react.useState)(false); const sliderContainerRef = (0, _react.useRef)({ width: null }); const customThumbRef = (0, _react.useRef)({ width: null, height: null }); const selectionRange = (0, _react.useRef)({ min: min, max: max }); const trackContainerRef = (0, _react.useRef)(null); const sliderRef = (0, _react.useRef)({ x: 0, y: 0, width: 0, height: 0 }); const progressAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; const thumbAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; // const isVertical = orientation === 'vertical'; // Reset value when min or max changes (0, _react.useEffect)(() => { selectionRange.current = { min: min, max: max }; // Reset to min value when range changes setCurrentValue(min); onChange?.(min); }, [min, max]); (0, _react.useEffect)(() => { if (trackContainerRef.current) { trackContainerRef.current.measureInWindow((x, y, width, height) => { setSliderCoordinate({ ...sliderCoordinate, x, y, width, height }); sliderRef.current = { x, y, width, height }; }); } }, [trackContainerRef.current]); const panResponder = (0, _react.useRef)(_reactNative.PanResponder.create({ onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, onPanResponderGrant: (_, gestureState) => { setIsDragging(true); }, onPanResponderMove: (_, gestureState) => { if (sliderRef.current.width === 0) return; const startX = sliderRef.current.x; const endX = startX + sliderRef.current.width; const touchX = gestureState.moveX; // Calculate the percentage of touch position relative to slider width const percentage = Math.max(0, Math.min(1, (touchX - startX) / (endX - startX))); // Map the percentage to the min-max range const range = selectionRange.current.max - selectionRange.current.min; let newValue = selectionRange.current.min + range * percentage; // Apply step if needed if (!allowDecimal) { const stepCount = Math.round((newValue - selectionRange.current.min) / (step || 1)); newValue = selectionRange.current.min + stepCount * (step || 1); } else { newValue = parseFloat(newValue.toFixed(2)); } // Ensure value is within bounds newValue = Math.min(selectionRange.current.max, Math.max(selectionRange.current.min, newValue)); if (value === undefined) { setCurrentValue(newValue); } onChange?.(newValue); // Update animated values directly const newPosition = getPositionFromValue(newValue); const newProgressWidth = Math.max(0, Math.min(sliderRef.current.width, newPosition)); const newThumbLeft = Math.max(0, Math.min(sliderRef.current.width - (customThumbRef.current.width || thumbSize || 0), newPosition - (customThumbRef.current.width || thumbSize || 0))); progressAnim.setValue(newProgressWidth); thumbAnim.setValue(newThumbLeft); }, onPanResponderRelease: () => { setIsDragging(false); } })).current; // const getPositionFromTouch = (evt: any) => { // if (sliderRef.current.width === 0) return 0; // const touch = isVertical ? evt.nativeEvent.pageY : evt.nativeEvent.pageX; // const start = isVertical ? sliderRef.current.y : sliderRef.current.x; // const length = isVertical ? sliderRef.current.height : sliderRef.current.width; // const end = start + length; // // For vertical slider, we need to invert the percentage calculation // let percentage = (touch - start) / (end - start); // if (isVertical) { // percentage = 1 - percentage; // Invert for vertical // } // percentage = Math.max(0, Math.min(1, percentage)); // return percentage; // }; const calculateValueFromTouch = touchPosition => { // const startPosition = isVertical ? sliderRef.current.y : sliderRef.current.x; // const sliderLength = isVertical ? sliderRef.current.height : sliderRef.current.width; const startPosition = sliderRef.current.x; const sliderLength = sliderRef.current.width; const endPosition = startPosition + sliderLength; // Calculate the percentage of touch position relative to slider length let percentage = Math.max(0, Math.min(1, (touchPosition - startPosition) / (endPosition - startPosition))); // Invert percentage for vertical slider // if (isVertical) { // percentage = 1 - percentage; // } // Map the percentage to the min-max range const range = selectionRange.current.max - selectionRange.current.min; let newValue = selectionRange.current.min + range * percentage; // Apply step if needed if (!allowDecimal) { const stepCount = Math.round((newValue - selectionRange.current.min) / (step || 0)); newValue = selectionRange.current.min + stepCount * (step || 0); } else { newValue = parseFloat(newValue.toFixed(2)); } // Ensure value is within bounds return Math.min(selectionRange.current.max, Math.max(selectionRange.current.min, newValue)); }; const trackPanResponder = (0, _react.useRef)(_reactNative.PanResponder.create({ onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, onPanResponderGrant: (evt, gestureState) => { setIsDragging(true); // Handle initial touch const newValue = calculateValueFromTouch(evt.nativeEvent.pageX); if (value === undefined) { setCurrentValue(newValue); } onChange?.(newValue); // Update animated values const newPosition = getPositionFromValue(newValue); const newProgressWidth = Math.max(0, Math.min(sliderRef.current.width, newPosition)); const newThumbLeft = Math.max(0, Math.min(sliderRef.current.width - (customThumbRef.current.width || thumbSize || 0), newPosition - (customThumbRef.current.width || thumbSize || 0))); progressAnim.setValue(newProgressWidth); thumbAnim.setValue(newThumbLeft); }, onPanResponderMove: (evt, gestureState) => { if (sliderRef.current.width === 0) return; const newValue = calculateValueFromTouch(gestureState.moveX); if (value === undefined) { setCurrentValue(newValue); } onChange?.(newValue); // Update animated values const newPosition = getPositionFromValue(newValue); const newProgressWidth = Math.max(0, Math.min(sliderRef.current.width, newPosition)); const newThumbLeft = Math.max(0, Math.min(sliderRef.current.width - (customThumbRef.current.width || thumbSize || 0), newPosition - (customThumbRef.current.width || thumbSize || 0))); progressAnim.setValue(newProgressWidth); thumbAnim.setValue(newThumbLeft); }, onPanResponderRelease: () => { setIsDragging(false); } })).current; const getPositionFromValue = val => { if (sliderRef.current.width === 0) return 0; const range = selectionRange.current.max - selectionRange.current.min; const percentage = (val - selectionRange.current.min) / range; const position = percentage * sliderRef.current.width; return isNaN(position) ? 0 : position; }; const displayValue = value !== undefined ? value : currentValue; const position = getPositionFromValue(displayValue || min); const progressWidth = Math.max(0, Math.min(sliderRef.current.width, position)); const thumbLeft = Math.max(0, Math.min(sliderRef.current.width - (customThumbRef.current.width || thumbSize || 0), position - (customThumbRef.current.width || thumbSize || 0))); // Initialize animated values (0, _react.useEffect)(() => { _reactNative.Animated.parallel([_reactNative.Animated.spring(progressAnim, { toValue: progressWidth, useNativeDriver: false, bounciness: 0 }), _reactNative.Animated.spring(thumbAnim, { toValue: thumbLeft, useNativeDriver: false, bounciness: 0 })]).start(); }, [progressWidth, thumbLeft]); return { sliderCoordinate, currentValue: displayValue, isDragging, progressAnim, displayValue, trackPanResponder, thumbAnim, panResponder, sliderRef, customThumbRef, selectionRange, getPositionFromValue, calculateValueFromTouch, setCurrentValue, setSliderCoordinate, sliderContainerRef, trackContainerRef, thumbSize: customThumbRef.current.width || thumbSize || 0 }; }; var _default = exports.default = useSlider; //# sourceMappingURL=useSlider.js.map