UNPKG

@react-native-assets/slider

Version:

Lightweight slider for React-Native and React-Native-Web. A Range slider is included

74 lines (73 loc) 4.09 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importDefault(require("react")); const useEvent_1 = require("./useEvent"); const useThumb_1 = __importDefault(require("./useThumb")); /** Handle the state of a range slider */ const useRange = ({ step, range: propValue, minimumRange, minimumValue, maximumValue, slideOnTap, onValueChange, crossingAllowed }) => { const [minProp, maxProp] = propValue; const minRef = react_1.default.useRef(minProp); const maxRef = react_1.default.useRef(maxProp); // When updating the props, we immediately apply the change to the refs in order to have the correct values in useThumb minRef.current = react_1.default.useMemo(() => Math.max(minimumValue, minProp), [minProp, minimumValue]); maxRef.current = react_1.default.useMemo(() => Math.min(maximumValue, maxProp), [maxProp, maximumValue]); const onMinChange = (0, useEvent_1.useEvent)((min) => { minRef.current = min; onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange([min, maxRef.current].sort((a, b) => a - b)); }); const onMaxChange = (0, useEvent_1.useEvent)((max) => { maxRef.current = max; onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange([minRef.current, max].sort((a, b) => a - b)); }); // Min value thumb const { updateValue: updateMinValue, canMove: canMoveMin, value: minValue } = (0, useThumb_1.default)({ minimumValue, maximumValue: Math.max(minimumValue, maxRef.current - minimumRange), value: minProp, step, slideOnTap, onValueChange: onMinChange }); // Max value thumb const { updateValue: updateMaxValue, canMove: canMoveMax, value: maxValue } = (0, useThumb_1.default)({ minimumValue: Math.min(maximumValue, minRef.current + minimumRange), maximumValue, value: maxProp, step, slideOnTap, onValueChange: onMaxChange }); const range = react_1.default.useMemo(() => [minValue, maxValue].sort((a, b) => a - b), [maxValue, minValue]); const currentThumb = react_1.default.useRef(); // Method to update the lower or higher bound according to which one is the closest const updateClosestValue = (0, useEvent_1.useEvent)((value, state) => { let isMinClosest = false; // When moving a thumb, we don't want to let it cross the other thumb if (currentThumb.current && !crossingAllowed) isMinClosest = currentThumb.current === 'min'; else if (!currentThumb.current) isMinClosest = Math.abs(value - minValue) < Math.abs(value - maxValue) || (minValue === maxValue && value < minValue); // if the current thumb is the min, we keep it as long as it's below the max else if (currentThumb.current === 'min') isMinClosest = value <= maxValue; // Otherwise, if we hold the max thumb, we switch only if the value is below the min else isMinClosest = value < minValue; // We update the state accordingly isMinClosest ? updateMinValue(value) : updateMaxValue(value); const newThumb = isMinClosest ? 'min' : 'max'; // We set the thumb being currently moved // When the 2 thumbs cross, we set the other thumb to the max possible value if (state === 'drag' && newThumb !== currentThumb.current) isMinClosest ? updateMaxValue(minValue) : updateMinValue(maxValue); currentThumb.current = state === 'release' ? undefined : newThumb; // We release the thumb, or keep maintaining it return isMinClosest ? [value, maxValue] : [minValue, value]; }); const canMove = (0, useEvent_1.useEvent)((value) => { return canMoveMax(value) || canMoveMin(value); }); return { updateMinValue, updateMaxValue, updateClosestValue, canMove, range }; }; exports.default = useRange;