265 lines
9.5 KiB
JavaScript
265 lines
9.5 KiB
JavaScript
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
import classNames from 'classnames';
|
|
import CSSMotion from 'rc-motion';
|
|
import KeyCode from "rc-util/es/KeyCode";
|
|
import pickAttrs from "rc-util/es/pickAttrs";
|
|
import * as React from 'react';
|
|
import DrawerContext from "./context";
|
|
import DrawerPanel from "./DrawerPanel";
|
|
import { parseWidthHeight } from "./util";
|
|
var sentinelStyle = {
|
|
width: 0,
|
|
height: 0,
|
|
overflow: 'hidden',
|
|
outline: 'none',
|
|
position: 'absolute'
|
|
};
|
|
function DrawerPopup(props, ref) {
|
|
var _ref, _pushConfig$distance, _pushConfig, _classNames;
|
|
var prefixCls = props.prefixCls,
|
|
open = props.open,
|
|
placement = props.placement,
|
|
inline = props.inline,
|
|
push = props.push,
|
|
forceRender = props.forceRender,
|
|
autoFocus = props.autoFocus,
|
|
keyboard = props.keyboard,
|
|
rootClassName = props.rootClassName,
|
|
rootStyle = props.rootStyle,
|
|
zIndex = props.zIndex,
|
|
className = props.className,
|
|
id = props.id,
|
|
style = props.style,
|
|
motion = props.motion,
|
|
width = props.width,
|
|
height = props.height,
|
|
children = props.children,
|
|
contentWrapperStyle = props.contentWrapperStyle,
|
|
mask = props.mask,
|
|
maskClosable = props.maskClosable,
|
|
maskMotion = props.maskMotion,
|
|
maskClassName = props.maskClassName,
|
|
maskStyle = props.maskStyle,
|
|
afterOpenChange = props.afterOpenChange,
|
|
onClose = props.onClose,
|
|
onMouseEnter = props.onMouseEnter,
|
|
onMouseOver = props.onMouseOver,
|
|
onMouseLeave = props.onMouseLeave,
|
|
onClick = props.onClick,
|
|
onKeyDown = props.onKeyDown,
|
|
onKeyUp = props.onKeyUp;
|
|
|
|
// ================================ Refs ================================
|
|
var panelRef = React.useRef();
|
|
var sentinelStartRef = React.useRef();
|
|
var sentinelEndRef = React.useRef();
|
|
React.useImperativeHandle(ref, function () {
|
|
return panelRef.current;
|
|
});
|
|
var onPanelKeyDown = function onPanelKeyDown(event) {
|
|
var keyCode = event.keyCode,
|
|
shiftKey = event.shiftKey;
|
|
switch (keyCode) {
|
|
// Tab active
|
|
case KeyCode.TAB:
|
|
{
|
|
if (keyCode === KeyCode.TAB) {
|
|
if (!shiftKey && document.activeElement === sentinelEndRef.current) {
|
|
var _sentinelStartRef$cur;
|
|
(_sentinelStartRef$cur = sentinelStartRef.current) === null || _sentinelStartRef$cur === void 0 ? void 0 : _sentinelStartRef$cur.focus({
|
|
preventScroll: true
|
|
});
|
|
} else if (shiftKey && document.activeElement === sentinelStartRef.current) {
|
|
var _sentinelEndRef$curre;
|
|
(_sentinelEndRef$curre = sentinelEndRef.current) === null || _sentinelEndRef$curre === void 0 ? void 0 : _sentinelEndRef$curre.focus({
|
|
preventScroll: true
|
|
});
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Close
|
|
case KeyCode.ESC:
|
|
{
|
|
if (onClose && keyboard) {
|
|
event.stopPropagation();
|
|
onClose(event);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
// ========================== Control ===========================
|
|
// Auto Focus
|
|
React.useEffect(function () {
|
|
if (open && autoFocus) {
|
|
var _panelRef$current;
|
|
(_panelRef$current = panelRef.current) === null || _panelRef$current === void 0 ? void 0 : _panelRef$current.focus({
|
|
preventScroll: true
|
|
});
|
|
}
|
|
}, [open]);
|
|
|
|
// ============================ Push ============================
|
|
var _React$useState = React.useState(false),
|
|
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
pushed = _React$useState2[0],
|
|
setPushed = _React$useState2[1];
|
|
var parentContext = React.useContext(DrawerContext);
|
|
|
|
// Merge push distance
|
|
var pushConfig;
|
|
if (push === false) {
|
|
pushConfig = {
|
|
distance: 0
|
|
};
|
|
} else if (push === true) {
|
|
pushConfig = {};
|
|
} else {
|
|
pushConfig = push || {};
|
|
}
|
|
var pushDistance = (_ref = (_pushConfig$distance = (_pushConfig = pushConfig) === null || _pushConfig === void 0 ? void 0 : _pushConfig.distance) !== null && _pushConfig$distance !== void 0 ? _pushConfig$distance : parentContext === null || parentContext === void 0 ? void 0 : parentContext.pushDistance) !== null && _ref !== void 0 ? _ref : 180;
|
|
var mergedContext = React.useMemo(function () {
|
|
return {
|
|
pushDistance: pushDistance,
|
|
push: function push() {
|
|
setPushed(true);
|
|
},
|
|
pull: function pull() {
|
|
setPushed(false);
|
|
}
|
|
};
|
|
}, [pushDistance]);
|
|
|
|
// ========================= ScrollLock =========================
|
|
// Tell parent to push
|
|
React.useEffect(function () {
|
|
if (open) {
|
|
var _parentContext$push;
|
|
parentContext === null || parentContext === void 0 ? void 0 : (_parentContext$push = parentContext.push) === null || _parentContext$push === void 0 ? void 0 : _parentContext$push.call(parentContext);
|
|
} else {
|
|
var _parentContext$pull;
|
|
parentContext === null || parentContext === void 0 ? void 0 : (_parentContext$pull = parentContext.pull) === null || _parentContext$pull === void 0 ? void 0 : _parentContext$pull.call(parentContext);
|
|
}
|
|
}, [open]);
|
|
|
|
// Clean up
|
|
React.useEffect(function () {
|
|
return function () {
|
|
var _parentContext$pull2;
|
|
parentContext === null || parentContext === void 0 ? void 0 : (_parentContext$pull2 = parentContext.pull) === null || _parentContext$pull2 === void 0 ? void 0 : _parentContext$pull2.call(parentContext);
|
|
};
|
|
}, []);
|
|
|
|
// ============================ Mask ============================
|
|
var maskNode = mask && /*#__PURE__*/React.createElement(CSSMotion, _extends({
|
|
key: "mask"
|
|
}, maskMotion, {
|
|
visible: open
|
|
}), function (_ref2, maskRef) {
|
|
var motionMaskClassName = _ref2.className,
|
|
motionMaskStyle = _ref2.style;
|
|
return /*#__PURE__*/React.createElement("div", {
|
|
className: classNames("".concat(prefixCls, "-mask"), motionMaskClassName, maskClassName),
|
|
style: _objectSpread(_objectSpread({}, motionMaskStyle), maskStyle),
|
|
onClick: maskClosable && open ? onClose : undefined,
|
|
ref: maskRef
|
|
});
|
|
});
|
|
|
|
// =========================== Panel ============================
|
|
var motionProps = typeof motion === 'function' ? motion(placement) : motion;
|
|
var wrapperStyle = {};
|
|
if (pushed && pushDistance) {
|
|
switch (placement) {
|
|
case 'top':
|
|
wrapperStyle.transform = "translateY(".concat(pushDistance, "px)");
|
|
break;
|
|
case 'bottom':
|
|
wrapperStyle.transform = "translateY(".concat(-pushDistance, "px)");
|
|
break;
|
|
case 'left':
|
|
wrapperStyle.transform = "translateX(".concat(pushDistance, "px)");
|
|
break;
|
|
default:
|
|
wrapperStyle.transform = "translateX(".concat(-pushDistance, "px)");
|
|
break;
|
|
}
|
|
}
|
|
if (placement === 'left' || placement === 'right') {
|
|
wrapperStyle.width = parseWidthHeight(width);
|
|
} else {
|
|
wrapperStyle.height = parseWidthHeight(height);
|
|
}
|
|
var eventHandlers = {
|
|
onMouseEnter: onMouseEnter,
|
|
onMouseOver: onMouseOver,
|
|
onMouseLeave: onMouseLeave,
|
|
onClick: onClick,
|
|
onKeyDown: onKeyDown,
|
|
onKeyUp: onKeyUp
|
|
};
|
|
var panelNode = /*#__PURE__*/React.createElement(CSSMotion, _extends({
|
|
key: "panel"
|
|
}, motionProps, {
|
|
visible: open,
|
|
forceRender: forceRender,
|
|
onVisibleChanged: function onVisibleChanged(nextVisible) {
|
|
afterOpenChange === null || afterOpenChange === void 0 ? void 0 : afterOpenChange(nextVisible);
|
|
},
|
|
removeOnLeave: false,
|
|
leavedClassName: "".concat(prefixCls, "-content-wrapper-hidden")
|
|
}), function (_ref3, motionRef) {
|
|
var motionClassName = _ref3.className,
|
|
motionStyle = _ref3.style;
|
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
className: classNames("".concat(prefixCls, "-content-wrapper"), motionClassName),
|
|
style: _objectSpread(_objectSpread(_objectSpread({}, wrapperStyle), motionStyle), contentWrapperStyle)
|
|
}, pickAttrs(props, {
|
|
data: true
|
|
})), /*#__PURE__*/React.createElement(DrawerPanel, _extends({
|
|
id: id,
|
|
containerRef: motionRef,
|
|
prefixCls: prefixCls,
|
|
className: className,
|
|
style: style
|
|
}, eventHandlers), children));
|
|
});
|
|
|
|
// =========================== Render ===========================
|
|
var containerStyle = _objectSpread({}, rootStyle);
|
|
if (zIndex) {
|
|
containerStyle.zIndex = zIndex;
|
|
}
|
|
return /*#__PURE__*/React.createElement(DrawerContext.Provider, {
|
|
value: mergedContext
|
|
}, /*#__PURE__*/React.createElement("div", {
|
|
className: classNames(prefixCls, "".concat(prefixCls, "-").concat(placement), rootClassName, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-open"), open), _defineProperty(_classNames, "".concat(prefixCls, "-inline"), inline), _classNames)),
|
|
style: containerStyle,
|
|
tabIndex: -1,
|
|
ref: panelRef,
|
|
onKeyDown: onPanelKeyDown
|
|
}, maskNode, /*#__PURE__*/React.createElement("div", {
|
|
tabIndex: 0,
|
|
ref: sentinelStartRef,
|
|
style: sentinelStyle,
|
|
"aria-hidden": "true",
|
|
"data-sentinel": "start"
|
|
}), panelNode, /*#__PURE__*/React.createElement("div", {
|
|
tabIndex: 0,
|
|
ref: sentinelEndRef,
|
|
style: sentinelStyle,
|
|
"aria-hidden": "true",
|
|
"data-sentinel": "end"
|
|
})));
|
|
}
|
|
var RefDrawerPopup = /*#__PURE__*/React.forwardRef(DrawerPopup);
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
RefDrawerPopup.displayName = 'DrawerPopup';
|
|
}
|
|
export default RefDrawerPopup; |