antd-mobile-taro-ui
Version:
以antd-mobile为设计标准,基于taro框架的微信小程序组件库
110 lines (98 loc) • 3.52 kB
JavaScript
import { View } from '@tarojs/components';
import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react';
import { withNativeProps } from 'antd-mobile/es/utils/native-props';
import { mergeProps } from 'antd-mobile/es/utils/with-default-props';
import { CloseIcon } from 'antd-mobile-taro-icons';
import { withStopPropagation } from 'antd-mobile/es/utils/with-stop-propagation';
import { ShouldRender } from 'antd-mobile/es/utils/should-render';
import { useUnmountedRef } from 'ahooks';
import Mask from '../mask';
import { defaultPopupBaseProps } from './popup-base-props';
const classPrefix = `adm-popup`;
const defaultProps = Object.assign(Object.assign({}, defaultPopupBaseProps), {
position: 'bottom'
});
export const Popup = p => {
const props = mergeProps(defaultProps, p);
const bodyCls = classNames(`${classPrefix}-body`, props.bodyClassName, `${classPrefix}-body-position-${props.position}`);
const percent = v => {
if (props.visible) {
return `translate(0, 0%)`;
}
if (props.position === 'bottom') {
return `translate(0, ${v}%)`;
}
if (props.position === 'top') {
return `translate(0, -${v}%)`;
}
if (props.position === 'left') {
return `translate(-${v}%, 0)`;
}
if (props.position === 'right') {
return `translate(${v}%, 0)`;
}
return 'none';
};
const [active, setActive] = useState(props.visible);
const unmountedRef = useUnmountedRef();
const init = useRef(true);
useEffect(() => {
if (init.current) return;
if (unmountedRef.current) return;
setActive(props.visible);
}, [props.visible]);
useEffect(() => {
if (init.current) {
setActive(true);
init.current = false;
}
}, []);
const node = withStopPropagation(props.stopPropagation, withNativeProps(props, React.createElement(View, {
className: classPrefix,
onClick: props.onClick,
style: {
opacity: props.visible ? '1' : '0',
zIndex: props.visible ? 'var(--z-index)' : '-1'
}
}, props.mask && React.createElement(Mask, {
visible: props.visible,
forceRender: props.forceRender,
destroyOnClose: props.destroyOnClose,
onMaskClick: e => {
var _a, _b;
(_a = props.onMaskClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
if (props.closeOnMaskClick) {
(_b = props.onClose) === null || _b === void 0 ? void 0 : _b.call(props);
}
},
className: props.maskClassName,
style: props.maskStyle,
disableBodyScroll: false,
stopPropagation: props.stopPropagation,
afterClose: () => {
var _a;
(_a = props.afterClose) === null || _a === void 0 ? void 0 : _a.call(props);
},
afterShow: () => {
var _a;
(_a = props.afterShow) === null || _a === void 0 ? void 0 : _a.call(props);
}
}), React.createElement(View, {
className: bodyCls,
style: Object.assign(Object.assign({}, props.bodyStyle), {
transform: percent(100)
})
}, props.showCloseButton && withStopPropagation(['click'], React.createElement(View, {
className: classNames(`${classPrefix}-close-icon`, 'adm-plain-anchor'),
onClick: () => {
var _a;
(_a = props.onClose) === null || _a === void 0 ? void 0 : _a.call(props);
}
}, React.createElement(CloseIcon, null))), props.children))));
return React.createElement(ShouldRender, {
active: active,
forceRender: props.forceRender,
destroyOnClose: props.destroyOnClose
}, node);
};