@gluestack-ui/core
Version:
Universal UI components for React Native, Expo, and Next.js
134 lines • 5.67 kB
JavaScript
import { clamp, focusWithoutScrolling, mergeProps, useGlobalListeners, } from '@react-aria/utils';
import { getSliderThumbId, sliderIds } from './utils';
import { useCallback, useEffect, useRef, } from 'react';
import { useFocusable } from '@react-aria/focus';
import { useLabel } from '@react-aria/label';
import { useMove } from './useMove';
import { isRTL } from '@gluestack-ui-nightly/utils/aria';
export function useSliderThumb(opts, state, isReversed) {
var _a;
let { index, isRequired, isDisabled, validationState, trackLayout, inputRef, } = opts;
let isVertical = opts.orientation === 'vertical';
let direction = isRTL() ? 'rtl' : undefined;
let { addGlobalListener, removeGlobalListener } = useGlobalListeners();
let labelId = sliderIds.get(state);
const { labelProps, fieldProps } = useLabel(Object.assign(Object.assign({}, opts), { 'id': getSliderThumbId(state, index), 'aria-labelledby': `${labelId} ${(_a = opts['aria-labelledby']) !== null && _a !== void 0 ? _a : ''}`.trim() }));
const value = state.values[index];
const focusInput = useCallback(() => {
if (inputRef.current) {
focusWithoutScrolling(inputRef.current);
}
}, [inputRef]);
const isFocused = state.focusedThumb === index;
useEffect(() => {
if (isFocused) {
focusInput();
}
}, [isFocused, focusInput]);
const stateRef = useRef(null);
stateRef.current = state;
let reverseX = isReversed || direction === 'rtl';
let currentPosition = useRef(null);
let { moveProps } = useMove({
onMoveStart() {
currentPosition.current = null;
state.setThumbDragging(index, true);
},
onMove({ deltaX, deltaY, pointerType }) {
let size = isVertical ? trackLayout.height : trackLayout.width;
if (currentPosition.current == null) {
currentPosition.current =
stateRef.current.getThumbPercent(index) * size;
}
if (pointerType === 'keyboard') {
let delta = ((reverseX ? -deltaX : deltaX) + (reverseX ? deltaY : -deltaY)) *
stateRef.current.step;
currentPosition.current += delta * size;
stateRef.current.setThumbValue(index, stateRef.current.getThumbValue(index) + delta);
}
else {
let delta = isVertical ? deltaY : deltaX;
if (reverseX) {
if (!isVertical) {
delta = -delta;
}
}
else {
if (isVertical) {
delta = -delta;
}
}
currentPosition.current += delta;
stateRef.current.setThumbPercent(index, clamp(currentPosition.current / size, 0, 1));
}
},
onMoveEnd() {
state.setThumbDragging(index, false);
},
});
state.setThumbEditable(index, !isDisabled);
const { focusableProps } = useFocusable(mergeProps(opts, {
onFocus: () => state.setFocusedThumb(index),
onBlur: () => state.setFocusedThumb(undefined),
}), inputRef);
let currentPointer = useRef(undefined);
let onDown = (id) => {
focusInput();
currentPointer.current = id;
state.setThumbDragging(index, true);
addGlobalListener(window, 'mouseup', onUp, false);
addGlobalListener(window, 'touchend', onUp, false);
addGlobalListener(window, 'pointerup', onUp, false);
};
let onUp = (e) => {
var _a, _b;
let id = (_a = e.pointerId) !== null && _a !== void 0 ? _a : (_b = e.changedTouches) === null || _b === void 0 ? void 0 : _b[0].identifier;
if (id === currentPointer.current) {
focusInput();
state.setThumbDragging(index, false);
removeGlobalListener(window, 'mouseup', onUp, false);
removeGlobalListener(window, 'touchend', onUp, false);
removeGlobalListener(window, 'pointerup', onUp, false);
}
};
return {
inputProps: mergeProps(focusableProps, fieldProps, {
'type': 'range',
'tabIndex': !isDisabled ? 0 : undefined,
'min': state.getThumbMinValue(index),
'max': state.getThumbMaxValue(index),
'step': state.step,
'value': value,
'disabled': isDisabled,
'aria-orientation': opts.orientation,
'aria-valuetext': state.getThumbValueLabel(index),
'aria-required': isRequired || undefined,
'aria-invalid': validationState === 'invalid' || undefined,
'aria-errormessage': opts['aria-errormessage'],
'onChange': (e) => {
state.setThumbValue(index, parseFloat(e.target.value));
},
}),
thumbProps: !isDisabled
? mergeProps(moveProps, {
onMouseDown: (e) => {
if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {
return;
}
onDown();
},
onPointerDown: (e) => {
if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {
return;
}
onDown(e.pointerId);
},
onTouchStart: (e) => {
onDown(e.changedTouches[0].identifier);
},
})
: {},
labelProps,
};
}
//# sourceMappingURL=useSliderThumb.web.js.map