UNPKG

@ozen-ui/kit

Version:

React component library

100 lines (99 loc) 3.84 kB
import { useEffect } from 'react'; import { useEventListener } from '../../../../hooks/useEventListener'; import { useStoredValue } from '../../../../hooks/useStoredValue'; import { animateNumberValue } from '../../../../utils/animateProperty'; import { clamp } from '../../../../utils/math'; import { BOTTOM_SHEET_BASE_CSS_VARIABLE } from '../../constants'; import { useBottomSheetBaseCSSValue } from '../../hooks'; export var useBottomSheetBaseSnaps = function (_a) { var minSnap = _a.minSnap, maxSnap = _a.maxSnap, defaultSnap = _a.defaultSnap, rootRef = _a.rootRef, onAnimationStart = _a.onAnimationStart, onAnimationFinish = _a.onAnimationFinish, isReady = _a.isReady, findClosestSnap = _a.findClosestSnap; var y = useBottomSheetBaseCSSValue({ defaultValue: -defaultSnap, variableName: BOTTOM_SHEET_BASE_CSS_VARIABLE.Y, rootRef: rootRef, formatValue: function (value) { return "".concat(value, "px"); }, }); var height = useBottomSheetBaseCSSValue({ defaultValue: defaultSnap, variableName: BOTTOM_SHEET_BASE_CSS_VARIABLE.HEIGHT, rootRef: rootRef, formatValue: function (value) { return "".concat(value, "px"); }, }); var openPercent = useBottomSheetBaseCSSValue({ defaultValue: 0, variableName: BOTTOM_SHEET_BASE_CSS_VARIABLE.OPEN_PERCENT, rootRef: rootRef, }); var point = useStoredValue(function () { return height.value.current + y.value.current; }); var setSnapPoint = function (newPoint) { if (newPoint === point.current) { return; } point.current = newPoint; height.setValue(clamp(newPoint, minSnap, maxSnap)); y.setValue(newPoint - height.value.current); var newOpenPercent = (function () { if (newPoint === 0 && minSnap === 0) { return 0; } return clamp((newPoint / minSnap) * 100, 0, 100); })(); openPercent.setValue(newOpenPercent); }; var snapTo = function (newPoint) { setSnapPoint(newPoint); }; var snapToAnimated = function (newPoint, options) { onAnimationStart === null || onAnimationStart === void 0 ? void 0 : onAnimationStart(); animateNumberValue(function (value) { snapTo(value); }, point.current, newPoint, { onFinish: function () { var _a; (_a = options === null || options === void 0 ? void 0 : options.onFinish) === null || _a === void 0 ? void 0 : _a.call(options); onAnimationFinish === null || onAnimationFinish === void 0 ? void 0 : onAnimationFinish(); }, }); }; var snapToClosed = function (isAnimated) { if (isAnimated) { snapToAnimated(0); } else { snapTo(0); } }; var snapToDefault = function (isAnimated) { if (isAnimated) { snapToAnimated(defaultSnap); } else { snapTo(defaultSnap); } }; var previousReady = useStoredValue(isReady); // Перерасчет текущей точки при изменении minSnap, maxSnap useEffect(function () { if (!isReady) { return; } if (previousReady.current) { snapTo(findClosestSnap.current(point.current)); } previousReady.current = isReady; }, [minSnap, maxSnap, isReady]); useEventListener({ eventName: 'resize', handler: function () { var closestSnap = findClosestSnap.current(point.current); snapTo(closestSnap); }, }); return { to: snapTo, point: point, toAnimated: snapToAnimated, toClosed: snapToClosed, toDefault: snapToDefault, }; };