UNPKG

@yandex/ui

Version:

Yandex UI components

99 lines (98 loc) 5.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DrawerContent = void 0; var tslib_1 = require("tslib"); var react_1 = tslib_1.__importStar(require("react")); var Drawer_utils_1 = require("../Drawer.utils"); var Drawer_const_1 = require("../Drawer.const"); /** * Компонент содержимого шторки. * * При использовании Popup мы не знаем в какой конкретно * момент содержимое монтируется/размонтируется, если * прокидывать его напрямую без обёрток. */ var DrawerContent = function (_a) { var dragDisabled = _a.dragDisabled, visible = _a.visible, _b = _a.onClose, onClose = _b === void 0 ? Drawer_utils_1.noop : _b, springValue = _a.springValue, _c = _a.direction, direction = _c === void 0 ? 'bottom' : _c, maxSize = _a.maxSize, titleComponent = _a.titleComponent, children = _a.children, setSpringDisabled = _a.setSpringDisabled, setProgress = _a.setProgress; var dragObserverRef = react_1.useRef(null); var contentRef = react_1.useRef(null); var axis = direction === 'bottom' ? 'y' : 'x'; var inverted = direction === 'left' ? -1 : 1; var springOpacity = Math.max(springValue, 0); var springTransform = axis === 'x' ? "translate3d(" + (1 - springValue) * 100 * inverted + "%,0,0)" : "translate3d(0," + (1 - springValue) * 100 * inverted + "%,0)"; var curtainStyle = react_1.useMemo(function () { var _a; return (tslib_1.__assign({ transform: springTransform }, (maxSize && (_a = {}, _a[axis === 'x' ? 'maxWidth' : 'maxHeight'] = maxSize, _a)))); }, [springTransform, maxSize, axis]); /** * Обработчик drag событий с корневого DOM элемента шторки */ Drawer_utils_1.useDrag(dragObserverRef, function (dragState) { if (!visible || !contentRef.current) return; var _a = dragState.velocity, vx = _a.x, vy = _a.y, _b = dragState.movement, mx = _b.x, my = _b.y, first = dragState.first, last = dragState.last, data = dragState.data, event = dragState.event; var drawerSize = axis === 'x' ? contentRef.current.clientWidth : contentRef.current.clientHeight; var movement = inverted * (axis === 'x' ? mx : my); var velocity = inverted * (axis === 'x' ? vx : vy); if (first) { data.isTargetUnderContent = contentRef.current.contains(event.target); data.initialScrollPosition = contentRef.current.scrollTop; data.isScrolled = data.initialScrollPosition !== 0; } else { data.isScrolled = data.isScrolled || data.initialScrollPosition - contentRef.current.scrollTop < 0; } // предотвращает инерционный проскролл родительских элементов, если это возможно if (event.cancelable && event.type === 'touchmove') { if (data.isTargetUnderContent) { // элемент проскроллен до верхней границы if (contentRef.current.scrollTop <= 0 && my > 0) { event.preventDefault(); } // элемент проскроллен до нижней границы if (contentRef.current.scrollHeight - contentRef.current.scrollTop <= contentRef.current.clientHeight && my < 0) { event.preventDefault(); } } else { event.preventDefault(); } } // ничего не делаем когда жест происходит одновременно с проскроллом // или если шторка в статичном состоянии // @see SERP-107544 if (dragDisabled || (data.isTargetUnderContent && data.isScrolled)) { return; } // жест завершен, возвращаем шторку в открытое положение, если // скорость была недостаточной и, закрываем если наоборот if (last) { setSpringDisabled(false); if (Math.abs(velocity) >= 0.1) { return velocity > 0 ? onClose() : setProgress(1); } else if (movement / drawerSize >= 0.3) { return onClose(); } return setProgress(1); } if (movement > 0) { setSpringDisabled(true); var progress = Math.max(0, 1 - movement / drawerSize); if (progress === 0) { return onClose(); } return setProgress(progress); } }); return (react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerDragObserver, ref: dragObserverRef }, react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerOverlay, style: { opacity: springOpacity }, onClick: onClose }), react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerCurtain, style: curtainStyle }, react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerHandle, style: { opacity: springOpacity } }), titleComponent && react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerTitle }, titleComponent), react_1.default.createElement("div", { className: Drawer_const_1.cnDrawerContent, ref: contentRef }, children)))); }; exports.DrawerContent = DrawerContent;