@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
JavaScript
;
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;