UNPKG

@ozen-ui/kit

Version:

React component library

90 lines (89 loc) 3.89 kB
import { __read } from "tslib"; import { rubberbandIfOutOfBounds, useDrag } from '@use-gesture/react'; import { clamp } from '../../../utils/math'; import { isNaN } from '../../../utils/number'; import { BOTTOM_SHEET_BASE_CSS_VARIABLE } from '../constants'; import { useBottomSheetBaseContext } from '../context'; import { useBottomSheetBaseCSSValue } from './useBottomSheetBaseCSSValue'; var rubberbandIfOutOfBoundsConstant = 0.55; export var useBottomSheetBaseDrag = function (target, options) { var _a = options !== null && options !== void 0 ? options : {}, _b = _a.isCloseOnTap, isCloseOnTap = _b === void 0 ? false : _b, _c = _a.isDraggable, isDraggable = _c === void 0 ? true : _c; var _d = useBottomSheetBaseContext(), minSnap = _d.minSnap, onCloseContext = _d.onClose, canDrag = _d.canDrag, maxSnap = _d.maxSnap, isClosable = _d.isClosable, snapsControl = _d.snapsControl, findClosestSnap = _d.findClosestSnap, rootRef = _d.rootRef; var userSelect = useBottomSheetBaseCSSValue({ rootRef: rootRef, defaultValue: 'auto', variableName: BOTTOM_SHEET_BASE_CSS_VARIABLE.USER_SELECT, }); var onClose = function () { snapsControl.toClosed(true); onCloseContext === null || onCloseContext === void 0 ? void 0 : onCloseContext(); }; var calculateAnimationTime = function (pxChange, velocity) { var rawTime = Math.abs(pxChange / velocity); if (isNaN(rawTime)) { return 0; } return clamp(rawTime, 200, 500); }; var onDragStart = function () { userSelect.setValue('none'); }; var onDragFinish = function () { userSelect.setValue('auto'); }; useDrag(function (params) { var cancel = params.cancel, down = params.down, first = params.first, last = params.last, _a = params.memo, memo = _a === void 0 ? snapsControl.point.current : _a, _b = __read(params.movement, 2), _my = _b[1], tap = params.tap, _c = __read(params.velocity, 2), velocity = _c[1]; var my = _my * -1; if (!canDrag.current) { cancel(); return memo; } if (isClosable && isCloseOnTap && tap) { cancel(); setTimeout(function () { return onClose(); }, 0); return memo; } if (tap) { return memo; } if (first) { onDragStart(); } var rawOffset = memo + my; var predictedDistance = my * velocity; var predictedPoint = Math.max(minSnap, Math.min(maxSnap, rawOffset + predictedDistance * 2)); if (last && isClosable && rawOffset + predictedDistance < minSnap / 2) { onDragFinish(); onClose(); return memo; } var newOffset = (function () { if (!down) { return predictedPoint; } if (!isClosable && minSnap === maxSnap) { if (rawOffset < minSnap) { return rubberbandIfOutOfBounds(rawOffset, minSnap, maxSnap * 1.5, rubberbandIfOutOfBoundsConstant); } return rubberbandIfOutOfBounds(rawOffset, minSnap / 1.5, maxSnap, rubberbandIfOutOfBoundsConstant); } return rubberbandIfOutOfBounds(rawOffset, isClosable ? 0 : minSnap, maxSnap, rubberbandIfOutOfBoundsConstant); })(); if (last) { var closestSnap = findClosestSnap.current(newOffset); snapsControl.toAnimated(closestSnap, { duration: calculateAnimationTime(Math.abs(closestSnap - snapsControl.point.current), velocity), }); onDragFinish(); return memo; } snapsControl.to(newOffset); return memo; }, { target: isDraggable ? target : { current: null, }, }); };