mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-03 07:47:18 +00:00
774 lines
25 KiB
JavaScript
774 lines
25 KiB
JavaScript
import _extends from 'babel-runtime/helpers/extends';
|
||
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
||
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
||
import _inherits from 'babel-runtime/helpers/inherits';
|
||
|
||
var _class, _temp;
|
||
|
||
import React, { Children, Component } from 'react';
|
||
import { findDOMNode } from 'react-dom';
|
||
import PropTypes from 'prop-types';
|
||
import classnames from 'classnames';
|
||
import { dom, events, focus, func, guid, KEYCODE, support } from '../util';
|
||
import overlayManager from './manager';
|
||
import Gateway from './gateway';
|
||
import Position from './position';
|
||
import findNode from './utils/find-node';
|
||
|
||
var saveLastFocusNode = focus.saveLastFocusNode,
|
||
getFocusNodeList = focus.getFocusNodeList,
|
||
backLastFocusNode = focus.backLastFocusNode;
|
||
var makeChain = func.makeChain,
|
||
noop = func.noop,
|
||
bindCtx = func.bindCtx;
|
||
|
||
|
||
var isScrollDisplay = function isScrollDisplay(element) {
|
||
try {
|
||
var scrollbarStyle = window.getComputedStyle(element, '::-webkit-scrollbar');
|
||
return !scrollbarStyle || scrollbarStyle.getPropertyValue('display') !== 'none';
|
||
} catch (e) {
|
||
// ignore error for firefox
|
||
}
|
||
|
||
return true;
|
||
};
|
||
var hasScroll = function hasScroll() {
|
||
var doc = document.documentElement;
|
||
return doc.scrollHeight > doc.clientHeight && dom.scrollbar().width > 0 && isScrollDisplay(document.documentElement) && isScrollDisplay(document.body);
|
||
};
|
||
var prefixes = ['-webkit-', '-moz-', '-o-', 'ms-', ''];
|
||
var getStyleProperty = function getStyleProperty(node, name) {
|
||
var style = window.getComputedStyle(node);
|
||
var ret = '';
|
||
for (var i = 0; i < prefixes.length; i++) {
|
||
ret = style.getPropertyValue(prefixes[i] + name);
|
||
if (ret) {
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
};
|
||
|
||
var modals = [];
|
||
var bodyOverflowY = void 0,
|
||
bodyPaddingRight = void 0;
|
||
|
||
/**
|
||
* Overlay
|
||
* */
|
||
var Overlay = (_temp = _class = function (_Component) {
|
||
_inherits(Overlay, _Component);
|
||
|
||
function Overlay(props) {
|
||
_classCallCheck(this, Overlay);
|
||
|
||
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
|
||
|
||
_this.saveContentRef = function (ref) {
|
||
_this.contentRef = ref;
|
||
};
|
||
|
||
_this.saveGatewayRef = function (ref) {
|
||
_this.gatewayRef = ref;
|
||
};
|
||
|
||
_this.state = {
|
||
visible: props.visible,
|
||
status: 'none',
|
||
animation: _this.getAnimation(props)
|
||
};
|
||
|
||
_this.lastAlign = props.align;
|
||
|
||
bindCtx(_this, ['handlePosition', 'handleAnimateEnd', 'handleDocumentKeyDown', 'handleDocumentClick', 'handleMaskClick', 'beforeOpen', 'beforeClose']);
|
||
|
||
_this.timeoutMap = {};
|
||
return _this;
|
||
}
|
||
|
||
Overlay.prototype.componentWillMount = function componentWillMount() {
|
||
if (this.props.visible) {
|
||
this.beforeOpen();
|
||
this.props.beforeOpen();
|
||
|
||
if (this.state.animation && support.animation) {
|
||
this.enter();
|
||
}
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.componentDidMount = function componentDidMount() {
|
||
this.componentDidUpdate({ visible: false });
|
||
this.addDocumentEvents();
|
||
|
||
overlayManager.addOverlay(this);
|
||
|
||
if (this.state.visible) {
|
||
this._isMounted = true;
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
|
||
if (!this._isMounted && nextProps.visible) {
|
||
this._isMounted = true;
|
||
}
|
||
|
||
var willOpen = !this.props.visible && nextProps.visible;
|
||
var willClose = this.props.visible && !nextProps.visible;
|
||
|
||
if (nextProps.align !== this.props.align) {
|
||
this.lastAlign = this.props.align;
|
||
}
|
||
|
||
if (willOpen) {
|
||
this.beforeOpen();
|
||
nextProps.beforeOpen();
|
||
} else if (willClose) {
|
||
this.beforeClose();
|
||
nextProps.beforeClose();
|
||
}
|
||
|
||
if (nextProps.animation || nextProps.animation === false) {
|
||
this.setState({
|
||
animation: nextProps.animation
|
||
});
|
||
}
|
||
|
||
if (nextProps.animation !== false && support.animation) {
|
||
if (willOpen) {
|
||
this.enter();
|
||
} else if (willClose) {
|
||
this.leave();
|
||
}
|
||
} else {
|
||
this.setState({
|
||
visible: nextProps.visible
|
||
});
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {
|
||
var _this2 = this;
|
||
|
||
var open = !prevProps.visible && this.props.visible;
|
||
var close = prevProps.visible && !this.props.visible;
|
||
if (this.state.animation && support.animation) {
|
||
if (open || close) {
|
||
this.addAnimationEvents();
|
||
}
|
||
} else {
|
||
var wrapperNode = this.getWrapperNode();
|
||
if (open) {
|
||
setTimeout(function () {
|
||
_this2.props.onOpen();
|
||
_this2.props.afterOpen();
|
||
dom.addClass(wrapperNode, 'opened');
|
||
overlayManager.addOverlay(_this2);
|
||
});
|
||
} else if (close) {
|
||
this.props.onClose();
|
||
this.props.afterClose();
|
||
dom.removeClass(wrapperNode, 'opened');
|
||
overlayManager.removeOverlay(this);
|
||
}
|
||
this.setFocusNode();
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.componentWillUnmount = function componentWillUnmount() {
|
||
this._isDestroyed = true;
|
||
this._isMounted = false;
|
||
overlayManager.removeOverlay(this);
|
||
this.removeDocumentEvents();
|
||
if (this.focusTimeout) {
|
||
clearTimeout(this.focusTimeout);
|
||
}
|
||
if (this._animation) {
|
||
this._animation.off();
|
||
this._animation = null;
|
||
}
|
||
this.beforeClose();
|
||
};
|
||
|
||
Overlay.prototype.getAnimation = function getAnimation(props) {
|
||
if (props.animation === false) {
|
||
return false;
|
||
}
|
||
|
||
if (props.animation) {
|
||
return props.animation;
|
||
}
|
||
|
||
return this.getAnimationByAlign(props.align);
|
||
};
|
||
|
||
Overlay.prototype.getAnimationByAlign = function getAnimationByAlign(align) {
|
||
switch (align[0]) {
|
||
case 't':
|
||
return {
|
||
in: 'expandInDown',
|
||
out: 'expandOutUp'
|
||
};
|
||
case 'b':
|
||
return {
|
||
in: 'expandInUp',
|
||
out: 'expandOutDown'
|
||
};
|
||
default:
|
||
return {
|
||
in: 'expandInDown',
|
||
out: 'expandOutUp'
|
||
};
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.addAnimationEvents = function addAnimationEvents() {
|
||
var _this3 = this;
|
||
|
||
setTimeout(function () {
|
||
var node = _this3.getContentNode();
|
||
if (node) {
|
||
var id = guid();
|
||
|
||
_this3._animation = events.on(node, support.animation.end, _this3.handleAnimateEnd.bind(_this3, id));
|
||
|
||
var animationDelay = parseFloat(getStyleProperty(node, 'animation-delay')) || 0;
|
||
var animationDuration = parseFloat(getStyleProperty(node, 'animation-duration')) || 0;
|
||
var time = animationDelay + animationDuration;
|
||
if (time) {
|
||
_this3.timeoutMap[id] = setTimeout(function () {
|
||
_this3.handleAnimateEnd(id);
|
||
}, time * 1000 + 200);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
Overlay.prototype.handlePosition = function handlePosition(config) {
|
||
var align = config.align.join(' ');
|
||
|
||
if (!('animation' in this.props) && this.props.needAdjust && this.lastAlign !== align) {
|
||
this.setState({
|
||
animation: this.getAnimationByAlign(align)
|
||
});
|
||
}
|
||
|
||
var status = this.state.status;
|
||
|
||
if (status === 'mounting') {
|
||
this.setState({
|
||
status: 'entering'
|
||
});
|
||
}
|
||
|
||
this.lastAlign = align;
|
||
};
|
||
|
||
Overlay.prototype.handleAnimateEnd = function handleAnimateEnd(id) {
|
||
if (this.timeoutMap[id]) {
|
||
clearTimeout(this.timeoutMap[id]);
|
||
}
|
||
delete this.timeoutMap[id];
|
||
|
||
if (this._animation) {
|
||
this._animation.off();
|
||
this._animation = null;
|
||
}
|
||
|
||
if (!this._isMounted) {
|
||
return;
|
||
}
|
||
|
||
if (this.state.status === 'leaving') {
|
||
this.setState({
|
||
visible: false,
|
||
status: 'none'
|
||
});
|
||
|
||
this.onLeaved();
|
||
} else if (this.state.status === 'entering') {
|
||
this.setState({
|
||
status: 'none'
|
||
});
|
||
|
||
this.onEntered();
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.enter = function enter() {
|
||
var _this4 = this;
|
||
|
||
this.setState({
|
||
visible: true,
|
||
status: 'mounting'
|
||
}, function () {
|
||
// NOTE: setState callback (second argument) now fires immediately after componentDidMount / componentDidUpdate instead of after all components have rendered.
|
||
setTimeout(function () {
|
||
if (!_this4._isDestroyed) {
|
||
_this4.onEntering();
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
Overlay.prototype.leave = function leave() {
|
||
this.setState({
|
||
status: 'leaving'
|
||
});
|
||
|
||
this.onLeaving();
|
||
};
|
||
|
||
Overlay.prototype.onEntering = function onEntering() {
|
||
var wrapperNode = this.getWrapperNode();
|
||
dom.addClass(wrapperNode, 'opened');
|
||
this.props.onOpen();
|
||
};
|
||
|
||
Overlay.prototype.onLeaving = function onLeaving() {
|
||
var wrapperNode = this.getWrapperNode();
|
||
dom.removeClass(wrapperNode, 'opened');
|
||
this.props.onClose();
|
||
};
|
||
|
||
Overlay.prototype.onEntered = function onEntered() {
|
||
overlayManager.addOverlay(this);
|
||
this.setFocusNode();
|
||
this.props.afterOpen();
|
||
};
|
||
|
||
Overlay.prototype.onLeaved = function onLeaved() {
|
||
overlayManager.removeOverlay(this);
|
||
this.setFocusNode();
|
||
this.props.afterClose();
|
||
};
|
||
|
||
Overlay.prototype.beforeOpen = function beforeOpen() {
|
||
if (this.props.disableScroll) {
|
||
if (modals.length === 0) {
|
||
var style = {
|
||
overflowY: 'hidden'
|
||
};
|
||
var body = document.body;
|
||
bodyOverflowY = body.style.overflowY;
|
||
if (hasScroll()) {
|
||
bodyPaddingRight = body.style.paddingRight;
|
||
style.paddingRight = dom.getStyle(body, 'paddingRight') + dom.scrollbar().width + 'px';
|
||
}
|
||
|
||
dom.setStyle(body, style);
|
||
}
|
||
modals.push(this);
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.beforeClose = function beforeClose() {
|
||
if (this.props.disableScroll) {
|
||
var index = modals.indexOf(this);
|
||
if (index > -1) {
|
||
if (modals.length === 1) {
|
||
var style = {
|
||
overflowY: bodyOverflowY
|
||
};
|
||
if (hasScroll()) {
|
||
style.paddingRight = bodyPaddingRight;
|
||
}
|
||
|
||
dom.setStyle(document.body, style);
|
||
|
||
bodyOverflowY = undefined;
|
||
bodyPaddingRight = undefined;
|
||
}
|
||
|
||
modals.splice(index, 1);
|
||
}
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.setFocusNode = function setFocusNode() {
|
||
var _this5 = this;
|
||
|
||
if (!this.props.autoFocus) {
|
||
return;
|
||
}
|
||
|
||
if (this.state.visible && !this._hasFocused) {
|
||
saveLastFocusNode();
|
||
// 这个时候很可能上一个弹层的关闭事件还未触发,导致焦点已经回到触发的元素
|
||
// 这里延时处理一下,延时的时间为 document.click 捕获触发的延时时间
|
||
this.focusTimeout = setTimeout(function () {
|
||
var node = _this5.getContentNode();
|
||
if (node) {
|
||
var focusNodeList = getFocusNodeList(node);
|
||
if (focusNodeList.length) {
|
||
focusNodeList[0].focus();
|
||
}
|
||
_this5._hasFocused = true;
|
||
}
|
||
}, 100);
|
||
} else if (!this.state.visible && this._hasFocused) {
|
||
backLastFocusNode();
|
||
this._hasFocused = false;
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.getContent = function getContent() {
|
||
return this.contentRef;
|
||
};
|
||
|
||
Overlay.prototype.getContentNode = function getContentNode() {
|
||
try {
|
||
return findDOMNode(this.contentRef);
|
||
} catch (err) {
|
||
return null;
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.getWrapperNode = function getWrapperNode() {
|
||
return this.gatewayRef ? this.gatewayRef.getChildNode() : null;
|
||
};
|
||
|
||
Overlay.prototype.addDocumentEvents = function addDocumentEvents() {
|
||
if (this.props.canCloseByEsc) {
|
||
this._keydownEvents = events.on(document, 'keydown', this.handleDocumentKeyDown);
|
||
}
|
||
if (this.props.canCloseByOutSideClick) {
|
||
this._clickEvents = events.on(document, 'click', this.handleDocumentClick);
|
||
|
||
this._touchEvents = events.on(document, 'touchend', this.handleDocumentClick);
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.removeDocumentEvents = function removeDocumentEvents() {
|
||
if (this._keydownEvents) {
|
||
this._keydownEvents.off();
|
||
this._keydownEvents = null;
|
||
}
|
||
if (this._clickEvents) {
|
||
this._clickEvents.off();
|
||
this._clickEvents = null;
|
||
}
|
||
|
||
if (this._touchEvents) {
|
||
this._touchEvents.off();
|
||
this._touchEvents = null;
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.handleDocumentKeyDown = function handleDocumentKeyDown(e) {
|
||
if (this.state.visible && e.keyCode === KEYCODE.ESC && overlayManager.isCurrentOverlay(this)) {
|
||
this.props.onRequestClose('keyboard', e);
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.handleDocumentClick = function handleDocumentClick(e) {
|
||
var _this6 = this;
|
||
|
||
if (this.state.visible) {
|
||
var safeNode = this.props.safeNode;
|
||
|
||
var safeNodes = Array.isArray(safeNode) ? [].concat(safeNode) : [safeNode];
|
||
safeNodes.unshift(function () {
|
||
return _this6.getWrapperNode();
|
||
});
|
||
|
||
for (var i = 0; i < safeNodes.length; i++) {
|
||
var node = findNode(safeNodes[i], this.props);
|
||
// HACK: 如果触发点击的节点是弹层内部的节点,并且在被点击后立即销毁,那么此时无法使用 node.contains(e.target)
|
||
// 来判断此时点击的节点是否是弹层内部的节点,额外判断
|
||
if (node && (node === e.target || node.contains(e.target) || e.target !== document && !document.documentElement.contains(e.target))) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
this.props.onRequestClose('docClick', e);
|
||
}
|
||
};
|
||
|
||
Overlay.prototype.handleMaskClick = function handleMaskClick(e) {
|
||
if (this.props.canCloseByMask) {
|
||
this.props.onRequestClose('maskClick', e);
|
||
}
|
||
};
|
||
|
||
// 兼容过去的用法: this.popupRef.getInstance().overlay.getInstance().getContentNode()
|
||
Overlay.prototype.getInstance = function getInstance() {
|
||
return this;
|
||
};
|
||
|
||
Overlay.prototype.render = function render() {
|
||
var _props = this.props,
|
||
prefix = _props.prefix,
|
||
className = _props.className,
|
||
style = _props.style,
|
||
propChildren = _props.children,
|
||
target = _props.target,
|
||
align = _props.align,
|
||
offset = _props.offset,
|
||
container = _props.container,
|
||
hasMask = _props.hasMask,
|
||
needAdjust = _props.needAdjust,
|
||
autoFit = _props.autoFit,
|
||
beforePosition = _props.beforePosition,
|
||
onPosition = _props.onPosition,
|
||
wrapperStyle = _props.wrapperStyle,
|
||
rtl = _props.rtl,
|
||
propShouldUpdatePosition = _props.shouldUpdatePosition,
|
||
cache = _props.cache,
|
||
wrapperClassName = _props.wrapperClassName,
|
||
onMaskMouseEnter = _props.onMaskMouseEnter,
|
||
onMaskMouseLeave = _props.onMaskMouseLeave,
|
||
maskClass = _props.maskClass,
|
||
isChildrenInMask = _props.isChildrenInMask;
|
||
var _state = this.state,
|
||
stateVisible = _state.visible,
|
||
status = _state.status,
|
||
animation = _state.animation;
|
||
|
||
|
||
var children = stateVisible || cache && this._isMounted ? propChildren : null;
|
||
if (children) {
|
||
var _classnames, _classnames2;
|
||
|
||
var child = Children.only(children);
|
||
// if chlild is a functional component wrap in a component to allow a ref to be set
|
||
if (typeof child.type === 'function' && !(child.type.prototype instanceof Component)) {
|
||
child = React.createElement(
|
||
'div',
|
||
{ role: 'none' },
|
||
child
|
||
);
|
||
}
|
||
var childClazz = classnames((_classnames = {}, _classnames[prefix + 'overlay-inner'] = true, _classnames[animation.in] = status === 'entering' || status === 'mounting', _classnames[animation.out] = status === 'leaving', _classnames[child.props.className] = !!child.props.className, _classnames[className] = !!className, _classnames));
|
||
if (typeof child.ref === 'string') {
|
||
throw new Error('Can not set ref by string in Overlay, use function instead.');
|
||
}
|
||
|
||
children = React.cloneElement(child, {
|
||
className: childClazz,
|
||
style: _extends({}, child.props.style, style),
|
||
ref: makeChain(this.saveContentRef, child.ref),
|
||
'aria-hidden': !stateVisible && cache && this._isMounted,
|
||
onClick: this.props.onClick
|
||
});
|
||
|
||
if (align) {
|
||
var shouldUpdatePosition = status === 'leaving' ? false : propShouldUpdatePosition;
|
||
children = React.createElement(Position, {
|
||
children: children,
|
||
target: target,
|
||
align: align,
|
||
offset: offset,
|
||
autoFit: autoFit,
|
||
container: container,
|
||
needAdjust: needAdjust,
|
||
beforePosition: beforePosition,
|
||
onPosition: makeChain(this.handlePosition, onPosition),
|
||
shouldUpdatePosition: shouldUpdatePosition,
|
||
rtl: rtl
|
||
});
|
||
}
|
||
|
||
var wrapperClazz = classnames([prefix + 'overlay-wrapper', wrapperClassName]);
|
||
var newWrapperStyle = _extends({}, {
|
||
display: stateVisible ? '' : 'none'
|
||
}, wrapperStyle);
|
||
|
||
var maskClazz = classnames((_classnames2 = {}, _classnames2[prefix + 'overlay-backdrop'] = true, _classnames2[maskClass] = !!maskClass, _classnames2));
|
||
|
||
children = React.createElement(
|
||
'div',
|
||
{
|
||
className: wrapperClazz,
|
||
style: newWrapperStyle,
|
||
dir: rtl ? 'rtl' : undefined
|
||
},
|
||
hasMask ? React.createElement(
|
||
'div',
|
||
{
|
||
className: maskClazz,
|
||
onClick: this.handleMaskClick,
|
||
onMouseEnter: onMaskMouseEnter,
|
||
onMouseLeave: onMaskMouseLeave,
|
||
dir: rtl ? 'rtl' : undefined
|
||
},
|
||
isChildrenInMask && children
|
||
) : null,
|
||
!isChildrenInMask && children
|
||
);
|
||
}
|
||
|
||
return React.createElement(Gateway, _extends({ container: container, target: target, children: children }, {
|
||
ref: this.saveGatewayRef
|
||
}));
|
||
};
|
||
|
||
return Overlay;
|
||
}(Component), _class.propTypes = {
|
||
prefix: PropTypes.string,
|
||
pure: PropTypes.bool,
|
||
rtl: PropTypes.bool,
|
||
className: PropTypes.string,
|
||
style: PropTypes.object,
|
||
/**
|
||
* 弹层内容
|
||
*/
|
||
children: PropTypes.any,
|
||
/**
|
||
* 是否显示弹层
|
||
*/
|
||
visible: PropTypes.bool,
|
||
/**
|
||
* 弹层请求关闭时触发事件的回调函数
|
||
* @param {String} type 弹层关闭的来源
|
||
* @param {Object} e DOM 事件
|
||
*/
|
||
onRequestClose: PropTypes.func,
|
||
/**
|
||
* 弹层定位的参照元素
|
||
*/
|
||
target: PropTypes.any,
|
||
/**
|
||
* 弹层相对于参照元素的定位, 详见开发指南的[定位部分](#定位)
|
||
*/
|
||
align: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||
/**
|
||
* 弹层相对于trigger的定位的微调, 接收数组[hoz, ver], 表示弹层在 left / top 上的增量
|
||
* e.g. [100, 100] 表示往右(RTL 模式下是往左) 、下分布偏移100px
|
||
*/
|
||
offset: PropTypes.array,
|
||
/**
|
||
* 渲染组件的容器,如果是函数需要返回 ref,如果是字符串则是该 DOM 的 id,也可以直接传入 DOM 节点
|
||
*/
|
||
container: PropTypes.any,
|
||
/**
|
||
* 是否显示遮罩
|
||
*/
|
||
hasMask: PropTypes.bool,
|
||
/**
|
||
* 是否支持 esc 按键关闭弹层
|
||
*/
|
||
canCloseByEsc: PropTypes.bool,
|
||
/**
|
||
* 点击弹层外的区域是否关闭弹层,不显示遮罩时生效
|
||
*/
|
||
canCloseByOutSideClick: PropTypes.bool,
|
||
/**
|
||
* 点击遮罩区域是否关闭弹层,显示遮罩时生效
|
||
*/
|
||
canCloseByMask: PropTypes.bool,
|
||
/**
|
||
* 弹层打开前触发事件的回调函数
|
||
*/
|
||
beforeOpen: PropTypes.func,
|
||
/**
|
||
* 弹层打开时触发事件的回调函数
|
||
*/
|
||
onOpen: PropTypes.func,
|
||
/**
|
||
* 弹层打开后触发事件的回调函数, 如果有动画,则在动画结束后触发
|
||
*/
|
||
afterOpen: PropTypes.func,
|
||
/**
|
||
* 弹层关闭前触发事件的回调函数
|
||
*/
|
||
beforeClose: PropTypes.func,
|
||
/**
|
||
* 弹层关闭时触发事件的回调函数
|
||
*/
|
||
onClose: PropTypes.func,
|
||
/**
|
||
* 弹层关闭后触发事件的回调函数, 如果有动画,则在动画结束后触发
|
||
*/
|
||
afterClose: PropTypes.func,
|
||
/**
|
||
* 弹层定位完成前触发的事件
|
||
*/
|
||
beforePosition: PropTypes.func,
|
||
/**
|
||
* 弹层定位完成时触发的事件
|
||
* @param {Object} config 定位的参数
|
||
* @param {Array} config.align 对齐方式,如 ['cc', 'cc'](如果开启 needAdjust,可能和预先设置的 align 不同)
|
||
* @param {Number} config.top 距离视口顶部距离
|
||
* @param {Number} config.left 距离视口左侧距离
|
||
* @param {Object} node 定位参照的容器节点
|
||
*/
|
||
onPosition: PropTypes.func,
|
||
/**
|
||
* 是否在每次弹层重新渲染后强制更新定位信息,一般用于弹层内容区域大小发生变化时,仍需保持原来的定位方式
|
||
*/
|
||
shouldUpdatePosition: PropTypes.bool,
|
||
/**
|
||
* 弹层打开时是否让其中的元素自动获取焦点
|
||
*/
|
||
autoFocus: PropTypes.bool,
|
||
/**
|
||
* 当弹层由于页面滚动等情况不在可视区域时,是否自动调整定位以出现在可视区域
|
||
*/
|
||
needAdjust: PropTypes.bool,
|
||
/**
|
||
* 是否禁用页面滚动
|
||
*/
|
||
disableScroll: PropTypes.bool,
|
||
/**
|
||
* 隐藏时是否保留子节点
|
||
*/
|
||
cache: PropTypes.bool,
|
||
/**
|
||
* 安全节点,当点击 document 的时候,如果包含该节点则不会关闭弹层,如果是函数需要返回 ref,如果是字符串则是该 DOM 的 id,也可以直接传入 DOM 节点,或者以上值组成的数组
|
||
*/
|
||
safeNode: PropTypes.any,
|
||
/**
|
||
* 弹层的根节点的样式类
|
||
*/
|
||
wrapperClassName: PropTypes.string,
|
||
/**
|
||
* 弹层的根节点的内联样式
|
||
*/
|
||
wrapperStyle: PropTypes.object,
|
||
/**
|
||
* 配置动画的播放方式,支持 { in: 'enter-class', out: 'leave-class' } 的对象参数,如果设置为 false,则不播放动画。 请参考 Animate 组件的文档获取可用的动画名
|
||
* @default { in: 'expandInDown', out: 'expandOutUp' }
|
||
*/
|
||
animation: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
||
onMaskMouseEnter: PropTypes.func,
|
||
onMaskMouseLeave: PropTypes.func,
|
||
onClick: PropTypes.func,
|
||
maskClass: PropTypes.string,
|
||
isChildrenInMask: PropTypes.bool
|
||
}, _class.defaultProps = {
|
||
prefix: 'next-',
|
||
pure: false,
|
||
visible: false,
|
||
onRequestClose: noop,
|
||
target: Position.VIEWPORT,
|
||
align: 'tl bl',
|
||
offset: [0, 0],
|
||
hasMask: false,
|
||
canCloseByEsc: true,
|
||
canCloseByOutSideClick: true,
|
||
canCloseByMask: true,
|
||
beforeOpen: noop,
|
||
onOpen: noop,
|
||
afterOpen: noop,
|
||
beforeClose: noop,
|
||
onClose: noop,
|
||
afterClose: noop,
|
||
beforePosition: noop,
|
||
onPosition: noop,
|
||
onMaskMouseEnter: noop,
|
||
onMaskMouseLeave: noop,
|
||
shouldUpdatePosition: false,
|
||
autoFocus: false,
|
||
needAdjust: true,
|
||
disableScroll: false,
|
||
cache: false,
|
||
isChildrenInMask: false,
|
||
onClick: function onClick(e) {
|
||
return e.stopPropagation();
|
||
},
|
||
maskClass: ''
|
||
}, _temp);
|
||
Overlay.displayName = 'Overlay';
|
||
export { Overlay as default }; |