@gluestack-ui-nightly/core
Version:
Universal UI components for React Native, Expo, and Next.js
176 lines • 7.58 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { clamp, mergeProps, useGlobalListeners } from '@react-aria/utils';
import { getSliderThumbId, sliderIds } from './utils';
import { useRef } from 'react';
import { setInteractionModality } from '@react-aria/interactions';
import { useLabel } from '@react-aria/label';
import { mapDomPropsToRN, isRTL } from '@gluestack-ui-nightly/utils/aria';
import { useMove } from './useMove';
function useSliderWeb(props, state, trackLayout, isReversed) {
var _a;
let { labelProps, fieldProps } = useLabel(props);
let isVertical = props.orientation === 'vertical';
sliderIds.set(state, (_a = labelProps.id) !== null && _a !== void 0 ? _a : fieldProps.id);
const direction = isRTL() ? 'rtl' : undefined;
let { addGlobalListener, removeGlobalListener } = useGlobalListeners();
const realTimeTrackDraggingIndex = useRef(null);
const stateRef = useRef(null);
stateRef.current = state;
const reverseX = isReversed || direction === 'rtl';
const currentPosition = useRef(null);
const { moveProps } = useMove({
onMoveStart() {
currentPosition.current = null;
},
onMove({ deltaX, deltaY }) {
let size = isVertical ? trackLayout.height : trackLayout.width;
if (currentPosition.current == null) {
currentPosition.current =
stateRef.current.getThumbPercent(realTimeTrackDraggingIndex.current) *
size;
}
let delta = isVertical ? deltaY : deltaX;
if (reverseX) {
if (!isVertical) {
delta = -delta;
}
}
else {
if (isVertical) {
delta = -delta;
}
}
currentPosition.current += delta;
if (realTimeTrackDraggingIndex.current != null) {
const percent = clamp(currentPosition.current / size, 0, 1);
stateRef.current.setThumbPercent(realTimeTrackDraggingIndex.current, percent);
}
},
onMoveEnd() {
if (realTimeTrackDraggingIndex.current != null) {
stateRef.current.setThumbDragging(realTimeTrackDraggingIndex.current, false);
realTimeTrackDraggingIndex.current = null;
}
},
});
let currentPointer = useRef(undefined);
let onDownTrack = (e, id, clientX, clientY) => {
if (!props.isDisabled &&
state.values.every((_, i) => !state.isThumbDragging(i))) {
let size = isVertical ? trackLayout.height : trackLayout.width;
const trackPosition = trackLayout[isVertical ? 'top' : 'left'];
const clickPosition = isVertical ? clientY : clientX;
const offset = clickPosition - trackPosition;
let percent = offset / size;
if (reverseX) {
if (!isVertical) {
percent = 1 - percent;
}
}
else {
if (isVertical) {
percent = 1 - percent;
}
}
let value = state.getPercentValue(percent);
let closestThumb;
let split = state.values.findIndex((v) => value - v < 0);
if (split === 0) {
closestThumb = split;
}
else if (split === -1) {
closestThumb = state.values.length - 1;
}
else {
let lastLeft = state.values[split - 1];
let firstRight = state.values[split];
if (Math.abs(lastLeft - value) < Math.abs(firstRight - value)) {
closestThumb = split - 1;
}
else {
closestThumb = split;
}
}
if (closestThumb >= 0 && state.isThumbEditable(closestThumb)) {
e.preventDefault();
realTimeTrackDraggingIndex.current = closestThumb;
state.setFocusedThumb(closestThumb);
currentPointer.current = id;
state.setThumbDragging(realTimeTrackDraggingIndex.current, true);
state.setThumbValue(closestThumb, value);
addGlobalListener(window, 'mouseup', onUpTrack, false);
addGlobalListener(window, 'touchend', onUpTrack, false);
addGlobalListener(window, 'pointerup', onUpTrack, false);
}
else {
realTimeTrackDraggingIndex.current = null;
}
}
};
let onUpTrack = (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) {
if (realTimeTrackDraggingIndex.current != null) {
state.setThumbDragging(realTimeTrackDraggingIndex.current, false);
realTimeTrackDraggingIndex.current = null;
}
removeGlobalListener(window, 'mouseup', onUpTrack, false);
removeGlobalListener(window, 'touchend', onUpTrack, false);
removeGlobalListener(window, 'pointerup', onUpTrack, false);
}
};
if (labelProps.htmlFor !== undefined) {
delete labelProps.htmlFor;
labelProps.onClick = () => {
var _a;
(_a = document.getElementById(getSliderThumbId(state, 0))) === null || _a === void 0 ? void 0 : _a.focus();
setInteractionModality('keyboard');
};
}
return {
labelProps,
groupProps: Object.assign({ role: 'group' }, fieldProps),
trackProps: mergeProps({
onMouseDown(e) {
if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {
return;
}
onDownTrack(e, undefined, e.clientX, e.clientY);
},
onPointerDown(e) {
if (e.pointerType === 'mouse' &&
(e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey)) {
return;
}
onDownTrack(e, e.pointerId, e.clientX, e.clientY);
},
onTouchStart(e) {
onDownTrack(e, e.changedTouches[0].identifier, e.changedTouches[0].clientX, e.changedTouches[0].clientY);
},
}, moveProps),
outputProps: {
'htmlFor': state.values
.map((_, index) => getSliderThumbId(state, index))
.join(' '),
'aria-live': 'off',
},
};
}
export const useSlider = (props, state, ref, isReversed) => {
let _a = useSliderWeb(props, state, ref, isReversed), { groupProps: webGroupProps } = _a, rest = __rest(_a, ["groupProps"]);
let groupProps = mapDomPropsToRN(webGroupProps);
let labelProps = mapDomPropsToRN(rest.labelProps);
return Object.assign(Object.assign({ groupProps }, rest), { labelProps });
};
//# sourceMappingURL=useSlider.web.js.map