UNPKG

@nutui/nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

324 lines (323 loc) 16.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "Popup", { enumerable: true, get: function() { return Popup; } }); var _interop_require_default = require("@swc/helpers/_/_interop_require_default"); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _async_to_generator = require("@swc/helpers/_/_async_to_generator"); var _define_property = require("@swc/helpers/_/_define_property"); var _object_spread = require("@swc/helpers/_/_object_spread"); var _object_spread_props = require("@swc/helpers/_/_object_spread_props"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _ts_generator = require("@swc/helpers/_/_ts_generator"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _taro = require("@tarojs/taro"); var _reactdom = require("react-dom"); var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames")); var _iconsreacttaro = require("@nutui/icons-react-taro"); var _components = require("@tarojs/components"); var _getrect = require("../../utils/taro/get-rect"); var _overlay = require("../overlay/overlay"); var _index = /*#__PURE__*/ _interop_require_default._(require("../overlay/index")); var _uselockscoll = require("../../hooks/taro/use-lock-scoll"); var _platform = require("../../utils/taro/platform"); var _pxtransform = require("../../utils/taro/px-transform"); var _configprovider = require("../configprovider/configprovider"); var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _overlay.defaultOverlayProps), { position: 'center', transition: '', overlayStyle: {}, overlayClassName: '', closeable: false, closeIconPosition: 'top-right', closeIcon: 'close', destroyOnClose: false, portal: null, overlay: true, round: false, resizable: false, minHeight: '', onOpen: function onOpen() {}, onClose: function onClose() {}, onOverlayClick: function onOverlayClick() { return true; }, onCloseIconClick: function onCloseIconClick() { return true; }, onTouchStart: function onTouchStart() {}, onTouchMove: function onTouchMove() {}, onTouchEnd: function onTouchEnd() {} }); // 默认1000,参看variables var _zIndex = 1100; var Popup = function Popup(props) { var _$_object_spread = (0, _object_spread._)({}, defaultProps, props), children = _$_object_spread.children, visible = _$_object_spread.visible, overlay = _$_object_spread.overlay, closeOnOverlayClick = _$_object_spread.closeOnOverlayClick, overlayStyle = _$_object_spread.overlayStyle, overlayClassName = _$_object_spread.overlayClassName, zIndex = _$_object_spread.zIndex, lockScroll = _$_object_spread.lockScroll, duration = _$_object_spread.duration, closeable = _$_object_spread.closeable, closeIconPosition = _$_object_spread.closeIconPosition, closeIcon = _$_object_spread.closeIcon, left = _$_object_spread.left, title = _$_object_spread.title, top = _$_object_spread.top, description = _$_object_spread.description, style = _$_object_spread.style, transition = _$_object_spread.transition, round = _$_object_spread.round, position = _$_object_spread.position, className = _$_object_spread.className, destroyOnClose = _$_object_spread.destroyOnClose, portal = _$_object_spread.portal, resizable = _$_object_spread.resizable, minHeight = _$_object_spread.minHeight, onOpen = _$_object_spread.onOpen, onClose = _$_object_spread.onClose, onOverlayClick = _$_object_spread.onOverlayClick, onCloseIconClick = _$_object_spread.onCloseIconClick, afterShow = _$_object_spread.afterShow, afterClose = _$_object_spread.afterClose, onClick = _$_object_spread.onClick, onTouchStart = _$_object_spread.onTouchStart, onTouchMove = _$_object_spread.onTouchMove, onTouchEnd = _$_object_spread.onTouchEnd, closeAriaLabel = _$_object_spread.closeAriaLabel; var innerIndex = zIndex || _zIndex; var _useState = (0, _sliced_to_array._)((0, _react.useState)(innerIndex), 2), index = _useState[0], setIndex = _useState[1]; var _useState1 = (0, _sliced_to_array._)((0, _react.useState)(visible), 2), innerVisible = _useState1[0], setInnerVisible = _useState1[1]; var _useState2 = (0, _sliced_to_array._)((0, _react.useState)(true), 2), showChildren = _useState2[0], setShowChildren = _useState2[1]; var _useState3 = (0, _sliced_to_array._)((0, _react.useState)(''), 2), transitionName = _useState3[0], setTransitionName = _useState3[1]; var nodeRef = (0, _uselockscoll.useLockScrollTaro)(innerVisible && lockScroll); var topNodeRef = _react.default.useRef(null); var rootRect = (0, _react.useRef)(null); var touchStartRef = (0, _react.useRef)(0); var touchMoveDistanceRef = (0, _react.useRef)(0); var heightRef = (0, _react.useRef)(0); var defaultHeightRef = (0, _react.useRef)(0); var isTouching = (0, _react.useRef)(false); var locale = (0, _configprovider.useConfig)().locale; var classPrefix = 'nut-popup'; var overlayStyles = (0, _object_spread._)({}, overlayStyle); var contentZIndex = (0, _platform.harmony)() ? index + 1 : index // 解决harmony层级问题 ; var popStyles = (0, _object_spread._)({ zIndex: contentZIndex, minHeight: minHeight }, style); var _obj; var popClassName = (0, _classnames.default)(classPrefix, (_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-round"), round || position === 'bottom'), (0, _define_property._)(_obj, "".concat(classPrefix, "-").concat(position), true), _obj), className); var _useState4 = (0, _sliced_to_array._)((0, _react.useState)(''), 2), popupHeight = _useState4[0], setPopupHeight = _useState4[1]; var _useState5 = (0, _sliced_to_array._)((0, _react.useState)(''), 2), topBottom = _useState5[0], setTopBottom = _useState5[1]; var resizeStyles = function resizeStyles() { if (popupHeight !== '') { return { height: popupHeight }; } }; var open = function open() { if (!innerVisible) { // 当高度改变后,再次打开时,将高度置为初始高度 if (position === 'bottom' && resizable && nodeRef.current && heightRef.current) { setPopupHeight((0, _pxtransform.pxTransform)(defaultHeightRef.current)); } setInnerVisible(true); setIndex(++innerIndex); } if (destroyOnClose) { setShowChildren(true); } onOpen && onOpen(); }; var getPopupHeight = function getPopupHeight() { return (0, _async_to_generator._)(function() { var _nodeRef_current, rect, height; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: return [ 4, (0, _getrect.getRectInMultiPlatformWithoutCache)(nodeRef.current) ]; case 1: rect = _state.sent(); height = ((_nodeRef_current = nodeRef.current) === null || _nodeRef_current === void 0 ? void 0 : _nodeRef_current.offsetHeight) || (rect === null || rect === void 0 ? void 0 : rect.height); setTopBottom((0, _pxtransform.pxTransform)(height)); return [ 2 ]; } }); })(); }; (0, _react.useEffect)(function() { if (innerVisible && topNodeRef.current && nodeRef.current) { (0, _taro.nextTick)(function() { (0, _taro.nextTick)(function() { getPopupHeight(); }); }); } }, [ innerVisible ]); var close = function close() { if (innerVisible) { setInnerVisible(false); if (destroyOnClose) { setTimeout(function() { setShowChildren(false); }, Number(duration)); } onClose && onClose(); } }; var handleOverlayClick = function handleOverlayClick(e) { e.stopPropagation(); if (closeOnOverlayClick && onOverlayClick(e)) { close(); } }; var handleCloseIconClick = function handleCloseIconClick(e) { onCloseIconClick(e) && close(); }; var renderCloseIcon = function renderCloseIcon() { var closeClasses = (0, _classnames.default)("".concat(classPrefix, "-title-right"), "".concat(classPrefix, "-title-right-").concat(closeIconPosition)); return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, closeable && /*#__PURE__*/ _react.default.createElement(_components.View, { className: closeClasses, onClick: handleCloseIconClick, ariaRole: "button", ariaLabel: closeAriaLabel || locale.close }, /*#__PURE__*/ _react.default.isValidElement(closeIcon) ? closeIcon : /*#__PURE__*/ _react.default.createElement(_iconsreacttaro.Close, null))); }; var renderTop = function renderTop() { if (!top) return null; return /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-bottom-top"), ref: topNodeRef, style: { bottom: topBottom } }, top); }; var renderTitle = function renderTitle() { if (left || title || description) { return /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-title") }, position === 'bottom' && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, left && /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-title-left") }, left), (title || description) && /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-title-wrapper") }, title && /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-title-title") }, title), description && /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-title-description ").concat(title ? "".concat(classPrefix, "-title-description-gap") : '') }, description))), renderCloseIcon()); } if (closeable) { return renderCloseIcon(); } }; var handleTouchStart = function handleTouchStart(event) { return (0, _async_to_generator._)(function() { var _nodeRef_current, _rootRect_current, e, rect; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: if (position !== 'bottom' || !resizable || !nodeRef.current) return [ 2 ]; e = event; // 开始touch,记录下touch的pageY,用以判断是向上滑动还是向下滑动 touchStartRef.current = e.touches[0].pageY; // 标记开始滑动 isTouching.current = true; return [ 4, (0, _getrect.getRectInMultiPlatformWithoutCache)(nodeRef.current) ]; case 1: rect = _state.sent(); rootRect.current = rect; heightRef.current = ((_nodeRef_current = nodeRef.current) === null || _nodeRef_current === void 0 ? void 0 : _nodeRef_current.offsetHeight) || ((_rootRect_current = rootRect.current) === null || _rootRect_current === void 0 ? void 0 : _rootRect_current.height) || 0; if (!defaultHeightRef.current) defaultHeightRef.current = heightRef.current; onTouchStart === null || onTouchStart === void 0 ? void 0 : onTouchStart(heightRef.current, e); return [ 2 ]; } }); })(); }; var handleTouchMove = function handleTouchMove(event) { if (position !== 'bottom' || !resizable || !nodeRef.current || !rootRect.current) return; var e = event; e.stopPropagation(); // 计算位移:move过程中,当前的pageY 与 start值比较 touchMoveDistanceRef.current = e.touches[0].pageY - touchStartRef.current; var handleMove = function handleMove() { var min = typeof minHeight === 'number' ? minHeight : parseInt(String(minHeight || 0), 10) || 0; var currentHeight = Math.max(min, heightRef.current - touchMoveDistanceRef.current); setPopupHeight((0, _pxtransform.pxTransform)(currentHeight)); if (touchMoveDistanceRef.current > 0 && isTouching.current) { // 向下滑动 onTouchMove === null || onTouchMove === void 0 ? void 0 : onTouchMove(currentHeight, e, 'down'); } else { // 向上滑动 onTouchMove === null || onTouchMove === void 0 ? void 0 : onTouchMove(currentHeight, e, 'up'); } }; requestAnimationFrame(handleMove); }; var handleTouchEnd = function handleTouchEnd(event) { if (position !== 'bottom' || !resizable || !nodeRef.current || !rootRect.current) return; var e = event; isTouching.current = false; var min = typeof minHeight === 'number' ? minHeight : parseInt(String(minHeight || 0), 10) || 0; var currentHeight = Math.max(min, heightRef.current - touchMoveDistanceRef.current); onTouchEnd === null || onTouchEnd === void 0 ? void 0 : onTouchEnd(currentHeight, e); }; var renderPop = function renderPop() { return /*#__PURE__*/ _react.default.createElement(_components.View, { ref: nodeRef, style: (0, _object_spread._)((0, _object_spread_props._)((0, _object_spread._)({}, popStyles), { display: innerVisible ? (popStyles === null || popStyles === void 0 ? void 0 : popStyles.display) || 'block' : 'none' }), resizeStyles()), className: popClassName, onClick: onClick, catchMove: lockScroll, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, onTouchCancel: handleTouchEnd }, renderTop(), renderTitle(), showChildren ? children : null); }; // const renderPop = () => { // return ( // <CSSTransition // nodeRef={nodeRef} // classNames={transitionName} // mountOnEnter // unmountOnExit={destroyOnClose} // timeout={duration} // in={innerVisible} // onEntered={afterShow} // onExited={afterClose} // > // {renderContent()} // </CSSTransition> // ) // } var renderNode = function renderNode() { return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, overlay ? /*#__PURE__*/ _react.default.createElement(_index.default, { zIndex: index, style: overlayStyles, className: overlayClassName, visible: innerVisible, closeOnOverlayClick: closeOnOverlayClick, lockScroll: lockScroll, duration: duration, onClick: handleOverlayClick }) : null, renderPop()); }; (0, _react.useEffect)(function() { visible ? open() : close(); }, [ visible ]); (0, _react.useEffect)(function() { setTransitionName(transition || "".concat(classPrefix, "-slide-").concat(position)); }, [ position, transition ]); var resolveContainer = function resolveContainer(getContainer) { return (typeof getContainer === 'function' ? getContainer() : getContainer) || document.body; }; var renderToContainer = function renderToContainer(getContainer, node) { if (getContainer) { var container = resolveContainer(getContainer); return /*#__PURE__*/ (0, _reactdom.createPortal)(node, container); } return node; }; return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, renderToContainer(portal, renderNode())); }; Popup.displayName = 'NutPopup';