@alifd/overlay
Version:
overlay base component
199 lines (195 loc) • 10.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = require("react-dom");
var _overlay = _interopRequireWildcard(require("./overlay"));
var _utils = require("./utils");
var _excluded = ["overlay", "triggerType", "triggerClickKeyCode", "children", "defaultVisible", "className", "onVisibleChange", "container", "style", "placement", "canCloseByTrigger", "delay", "mouseEnterDelay", "mouseLeaveDelay", "overlayProps", "safeNode", "followTrigger", "target", "disabled"];
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
var Popup = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
var body = function body() {
return document.body;
};
var overlay = props.overlay,
_props$triggerType = props.triggerType,
triggerType = _props$triggerType === void 0 ? 'click' : _props$triggerType,
triggerClickKeyCode = props.triggerClickKeyCode,
children = props.children,
defaultVisible = props.defaultVisible,
className = props.className,
_props$onVisibleChang = props.onVisibleChange,
onVisibleChange = _props$onVisibleChang === void 0 ? function () {} : _props$onVisibleChang,
_props$container = props.container,
container = _props$container === void 0 ? body : _props$container,
_props$style = props.style,
style = _props$style === void 0 ? {} : _props$style,
_props$placement = props.placement,
placement = _props$placement === void 0 ? 'bl' : _props$placement,
_props$canCloseByTrig = props.canCloseByTrigger,
canCloseByTrigger = _props$canCloseByTrig === void 0 ? true : _props$canCloseByTrig,
_props$delay = props.delay,
delay = _props$delay === void 0 ? 200 : _props$delay,
mouseEnterDelay = props.mouseEnterDelay,
mouseLeaveDelay = props.mouseLeaveDelay,
_props$overlayProps = props.overlayProps,
overlayProps = _props$overlayProps === void 0 ? {} : _props$overlayProps,
safeNode = props.safeNode,
_props$followTrigger = props.followTrigger,
followTrigger = _props$followTrigger === void 0 ? false : _props$followTrigger,
otarget = props.target,
_props$disabled = props.disabled,
disabled = _props$disabled === void 0 ? false : _props$disabled,
others = (0, _objectWithoutPropertiesLoose2["default"])(props, _excluded);
var _useState = (0, _react.useState)(defaultVisible || props.visible),
visible = _useState[0],
setVisible = _useState[1];
var triggerRef = (0, _react.useRef)(null);
var overlayRef = (0, _react.useRef)(null);
var mouseLeaveTimer = (0, _react.useRef)(null);
var mouseEnterTimer = (0, _react.useRef)(null);
var overlayClick = (0, _react.useRef)(false);
var child = children && _react["default"].Children.only(children);
var overlayChild = _react["default"].Children.only(overlay);
(0, _react.useEffect)(function () {
if ('visible' in props) {
setVisible(props.visible);
}
}, [props.visible]);
var handleVisibleChange = function handleVisibleChange(visible, e, triggerType) {
if (triggerType === void 0) {
triggerType = 'fromTrigger';
}
if (disabled) {
return;
}
if (!('visible' in props)) {
if (visible || overlayRef.current) {
setVisible(visible);
}
}
onVisibleChange(visible, triggerType, e);
};
var handleClick = function handleClick(e) {
if (visible && !canCloseByTrigger) {
return;
}
handleVisibleChange(!visible, e); // todo: rename to trigger in 1.x
};
var handleKeyDown = function handleKeyDown(e) {
var keycodes = Array.isArray(triggerClickKeyCode) ? triggerClickKeyCode : [triggerClickKeyCode];
if (keycodes.includes(e.keyCode)) {
handleVisibleChange(!visible, e); // todo: rename to trigger in 1.x
}
};
var handleMouseEnter = function handleMouseEnter(targetType) {
return function (e) {
if (mouseLeaveTimer.current && visible) {
clearTimeout(mouseLeaveTimer.current);
mouseLeaveTimer.current = null;
return;
}
if (!mouseEnterTimer.current && !visible) {
mouseEnterTimer.current = setTimeout(function () {
handleVisibleChange(true, e, targetType);
mouseEnterTimer.current = null;
}, mouseEnterDelay !== null && mouseEnterDelay !== void 0 ? mouseEnterDelay : delay);
}
};
};
var handleMouseLeave = function handleMouseLeave(targetType) {
return function (e) {
if (!mouseLeaveTimer.current && visible) {
mouseLeaveTimer.current = setTimeout(function () {
handleVisibleChange(false, e, targetType);
mouseLeaveTimer.current = null;
}, mouseLeaveDelay !== null && mouseLeaveDelay !== void 0 ? mouseLeaveDelay : delay);
}
if (mouseEnterTimer.current && !visible) {
clearTimeout(mouseEnterTimer.current);
mouseEnterTimer.current = null;
}
};
};
var handleFocus = function handleFocus(e) {
handleVisibleChange(true, e);
};
var handleBlur = function handleBlur(e) {
if (overlayClick.current) {
overlayClick.current = false;
return;
}
handleVisibleChange(false, e);
};
// 点击弹窗的时候不能被 onBlur 关闭
var handleOverlayClick = function handleOverlayClick(e) {
overlayClick.current = true;
};
var handleRequestClose = function handleRequestClose(targetType, e) {
handleVisibleChange(false, e, targetType);
};
var triggerProps = {};
var overlayOtherProps = {};
var safeNodes = Array.isArray(safeNode) ? safeNode : [safeNode];
if (child && !disabled) {
var triggerTypeList = typeof triggerType === 'string' ? [triggerType] : triggerType;
triggerTypeList.forEach(function (t) {
var _child$props, _child$props2, _child$props3, _child$props4, _child$props5, _child$props6;
switch (t) {
case 'click':
triggerProps.onClick = (0, _utils.makeChain)(handleClick, (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.onClick);
triggerProps.onKeyDown = (0, _utils.makeChain)(handleKeyDown, (_child$props2 = child.props) === null || _child$props2 === void 0 ? void 0 : _child$props2.onKeyDown);
break;
case 'hover':
triggerProps.onMouseEnter = (0, _utils.makeChain)(handleMouseEnter('fromTrigger'), (_child$props3 = child.props) === null || _child$props3 === void 0 ? void 0 : _child$props3.onMouseEnter);
triggerProps.onMouseLeave = (0, _utils.makeChain)(handleMouseLeave('fromTrigger'), (_child$props4 = child.props) === null || _child$props4 === void 0 ? void 0 : _child$props4.onMouseLeave);
overlayOtherProps.onMouseEnter = (0, _utils.makeChain)(handleMouseEnter('overlay'), overlayProps.onMouseEnter);
overlayOtherProps.onMouseLeave = (0, _utils.makeChain)(handleMouseLeave('overlay'), overlayProps.onMouseLeave);
break;
case 'focus':
triggerProps.onFocus = (0, _utils.makeChain)(handleFocus, (_child$props5 = child.props) === null || _child$props5 === void 0 ? void 0 : _child$props5.onFocus);
triggerProps.onBlur = (0, _utils.makeChain)(handleBlur, (_child$props6 = child.props) === null || _child$props6 === void 0 ? void 0 : _child$props6.onBlur);
overlayOtherProps.onMouseDown = (0, _utils.makeChain)(handleOverlayClick, overlayProps.onMouseDown);
break;
}
});
// trigger 是安全节点
safeNodes.push(function () {
return (0, _reactDom.findDOMNode)(triggerRef.current);
});
}
var target = otarget || (child ? function () {
return (0, _reactDom.findDOMNode)(triggerRef.current);
} : body);
var getContainer = typeof container === 'string' ? function () {
return document.getElementById(container);
} : typeof container !== 'function' ? function () {
return container;
} : function () {
return container((0, _reactDom.findDOMNode)(triggerRef.current));
};
var overlayContainer = followTrigger ? function () {
var _findDOMNode;
return (_findDOMNode = (0, _reactDom.findDOMNode)(triggerRef.current)) === null || _findDOMNode === void 0 ? void 0 : _findDOMNode.parentNode;
} : getContainer;
// triggerRef 可能会更新,等计算的时候再通过 findDOMNode 取真实值
var refWrapperRef = (0, _react.useCallback)(function (ref) {
triggerRef.current = ref;
}, []);
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, child && /*#__PURE__*/_react["default"].createElement(_overlay.RefWrapper, {
ref: refWrapperRef
}, /*#__PURE__*/_react["default"].cloneElement(child, triggerProps)), /*#__PURE__*/_react["default"].createElement(_overlay["default"], (0, _extends2["default"])({}, others, overlayOtherProps, {
placement: placement,
container: overlayContainer,
safeNode: safeNodes,
visible: visible,
target: target,
onRequestClose: handleRequestClose,
ref: (0, _react.useCallback)((0, _utils.makeChain)((0, _utils.saveRef)(overlayRef), (0, _utils.saveRef)(ref)), [])
}), overlayChild));
});
var _default = exports["default"] = Popup;