@ozen-ui/kit
Version:
React component library
100 lines (99 loc) • 3.84 kB
JavaScript
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,
};
};