@rc-component/trigger 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +321 -0
- package/assets/index/Mask.less +63 -0
- package/assets/index/Mobile.less +25 -0
- package/assets/index.css +133 -0
- package/assets/index.less +79 -0
- package/es/Popup/Arrow.d.ts +9 -0
- package/es/Popup/Arrow.js +47 -0
- package/es/Popup/Mask.d.ts +10 -0
- package/es/Popup/Mask.js +26 -0
- package/es/Popup/index.d.ts +39 -0
- package/es/Popup/index.js +149 -0
- package/es/TriggerWrapper.d.ts +8 -0
- package/es/TriggerWrapper.js +19 -0
- package/es/context.d.ts +6 -0
- package/es/context.js +3 -0
- package/es/hooks/useAction.d.ts +4 -0
- package/es/hooks/useAction.js +8 -0
- package/es/hooks/useAlign.d.ts +12 -0
- package/es/hooks/useAlign.js +275 -0
- package/es/hooks/useWatch.d.ts +1 -0
- package/es/hooks/useWatch.js +50 -0
- package/es/index.d.ts +61 -0
- package/es/index.js +448 -0
- package/es/interface.d.ts +122 -0
- package/es/interface.js +1 -0
- package/es/util.d.ts +7 -0
- package/es/util.js +47 -0
- package/lib/Popup/Arrow.d.ts +9 -0
- package/lib/Popup/Arrow.js +54 -0
- package/lib/Popup/Mask.d.ts +10 -0
- package/lib/Popup/Mask.js +33 -0
- package/lib/Popup/index.d.ts +39 -0
- package/lib/Popup/index.js +158 -0
- package/lib/TriggerWrapper.d.ts +8 -0
- package/lib/TriggerWrapper.js +27 -0
- package/lib/context.d.ts +6 -0
- package/lib/context.js +11 -0
- package/lib/hooks/useAction.d.ts +4 -0
- package/lib/hooks/useAction.js +14 -0
- package/lib/hooks/useAlign.d.ts +12 -0
- package/lib/hooks/useAlign.js +283 -0
- package/lib/hooks/useWatch.d.ts +1 -0
- package/lib/hooks/useWatch.js +57 -0
- package/lib/index.d.ts +61 -0
- package/lib/index.js +457 -0
- package/lib/interface.d.ts +122 -0
- package/lib/interface.js +5 -0
- package/lib/util.d.ts +7 -0
- package/lib/util.js +57 -0
- package/package.json +79 -0
package/es/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { CSSMotionProps } from 'rc-motion';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { ActionType, AlignType, AnimationType, BuildInPlacements, TransitionNameType } from './interface';
|
|
4
|
+
export interface TriggerRef {
|
|
5
|
+
forceAlign: VoidFunction;
|
|
6
|
+
}
|
|
7
|
+
export interface TriggerProps {
|
|
8
|
+
children: React.ReactElement;
|
|
9
|
+
action?: ActionType | ActionType[];
|
|
10
|
+
showAction?: ActionType[];
|
|
11
|
+
hideAction?: ActionType[];
|
|
12
|
+
prefixCls?: string;
|
|
13
|
+
zIndex?: number;
|
|
14
|
+
stretch?: string;
|
|
15
|
+
popupVisible?: boolean;
|
|
16
|
+
defaultPopupVisible?: boolean;
|
|
17
|
+
onPopupVisibleChange?: (visible: boolean) => void;
|
|
18
|
+
afterPopupVisibleChange?: (visible: boolean) => void;
|
|
19
|
+
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
|
20
|
+
forceRender?: boolean;
|
|
21
|
+
autoDestroy?: boolean;
|
|
22
|
+
/** @deprecated Please use `autoDestroy` instead */
|
|
23
|
+
destroyPopupOnHide?: boolean;
|
|
24
|
+
mask?: boolean;
|
|
25
|
+
maskClosable?: boolean;
|
|
26
|
+
/** Set popup motion. You can ref `rc-motion` for more info. */
|
|
27
|
+
popupMotion?: CSSMotionProps;
|
|
28
|
+
/** Set mask motion. You can ref `rc-motion` for more info. */
|
|
29
|
+
maskMotion?: CSSMotionProps;
|
|
30
|
+
/** @deprecated Please us `popupMotion` instead. */
|
|
31
|
+
popupTransitionName?: TransitionNameType;
|
|
32
|
+
/** @deprecated Please us `popupMotion` instead. */
|
|
33
|
+
popupAnimation?: AnimationType;
|
|
34
|
+
/** @deprecated Please us `maskMotion` instead. */
|
|
35
|
+
maskTransitionName?: TransitionNameType;
|
|
36
|
+
/** @deprecated Please us `maskMotion` instead. */
|
|
37
|
+
maskAnimation?: AnimationType;
|
|
38
|
+
mouseEnterDelay?: number;
|
|
39
|
+
mouseLeaveDelay?: number;
|
|
40
|
+
focusDelay?: number;
|
|
41
|
+
blurDelay?: number;
|
|
42
|
+
popup: React.ReactNode | (() => React.ReactNode);
|
|
43
|
+
popupPlacement?: string;
|
|
44
|
+
builtinPlacements?: BuildInPlacements;
|
|
45
|
+
popupAlign?: AlignType;
|
|
46
|
+
popupClassName?: string;
|
|
47
|
+
popupStyle?: React.CSSProperties;
|
|
48
|
+
getPopupClassNameFromAlign?: (align: AlignType) => string;
|
|
49
|
+
onPopupClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
50
|
+
alignPoint?: boolean;
|
|
51
|
+
arrow?: boolean;
|
|
52
|
+
/** @deprecated Add `className` on `children`. Please add `className` directly instead. */
|
|
53
|
+
className?: string;
|
|
54
|
+
/**
|
|
55
|
+
* @private Get trigger DOM node.
|
|
56
|
+
* Used for some component is function component which can not access by `findDOMNode`
|
|
57
|
+
*/
|
|
58
|
+
getTriggerDOMNode?: (node: React.ReactInstance) => HTMLElement;
|
|
59
|
+
}
|
|
60
|
+
declare const Trigger: React.ForwardRefExoticComponent<TriggerProps & React.RefAttributes<TriggerRef>>;
|
|
61
|
+
export default Trigger;
|
package/es/index.js
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
4
|
+
var _excluded = ["prefixCls", "children", "action", "showAction", "hideAction", "popupVisible", "defaultPopupVisible", "onPopupVisibleChange", "afterPopupVisibleChange", "mouseEnterDelay", "mouseLeaveDelay", "focusDelay", "blurDelay", "mask", "maskClosable", "getPopupContainer", "forceRender", "autoDestroy", "destroyPopupOnHide", "popup", "popupClassName", "popupStyle", "popupPlacement", "builtinPlacements", "popupAlign", "zIndex", "stretch", "getPopupClassNameFromAlign", "alignPoint", "onPopupClick", "arrow", "popupMotion", "maskMotion", "popupTransitionName", "popupAnimation", "maskTransitionName", "maskAnimation", "className", "getTriggerDOMNode"];
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
import ResizeObserver from 'rc-resize-observer';
|
|
7
|
+
import useEvent from "rc-util/es/hooks/useEvent";
|
|
8
|
+
import useId from "rc-util/es/hooks/useId";
|
|
9
|
+
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
|
10
|
+
import useMergedState from "rc-util/es/hooks/useMergedState";
|
|
11
|
+
import * as React from 'react';
|
|
12
|
+
import TriggerContext from "./context";
|
|
13
|
+
import useAction from "./hooks/useAction";
|
|
14
|
+
import useAlign from "./hooks/useAlign";
|
|
15
|
+
import useWatch from "./hooks/useWatch";
|
|
16
|
+
import Popup from "./Popup";
|
|
17
|
+
import TriggerWrapper from "./TriggerWrapper";
|
|
18
|
+
import { getAlignPopupClassName, getMotion, getWin } from "./util";
|
|
19
|
+
var Trigger = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
20
|
+
var _props$prefixCls = props.prefixCls,
|
|
21
|
+
prefixCls = _props$prefixCls === void 0 ? 'rc-trigger-popup' : _props$prefixCls,
|
|
22
|
+
children = props.children,
|
|
23
|
+
_props$action = props.action,
|
|
24
|
+
action = _props$action === void 0 ? 'hover' : _props$action,
|
|
25
|
+
showAction = props.showAction,
|
|
26
|
+
hideAction = props.hideAction,
|
|
27
|
+
popupVisible = props.popupVisible,
|
|
28
|
+
defaultPopupVisible = props.defaultPopupVisible,
|
|
29
|
+
onPopupVisibleChange = props.onPopupVisibleChange,
|
|
30
|
+
afterPopupVisibleChange = props.afterPopupVisibleChange,
|
|
31
|
+
mouseEnterDelay = props.mouseEnterDelay,
|
|
32
|
+
_props$mouseLeaveDela = props.mouseLeaveDelay,
|
|
33
|
+
mouseLeaveDelay = _props$mouseLeaveDela === void 0 ? 0.1 : _props$mouseLeaveDela,
|
|
34
|
+
focusDelay = props.focusDelay,
|
|
35
|
+
blurDelay = props.blurDelay,
|
|
36
|
+
mask = props.mask,
|
|
37
|
+
_props$maskClosable = props.maskClosable,
|
|
38
|
+
maskClosable = _props$maskClosable === void 0 ? true : _props$maskClosable,
|
|
39
|
+
getPopupContainer = props.getPopupContainer,
|
|
40
|
+
forceRender = props.forceRender,
|
|
41
|
+
autoDestroy = props.autoDestroy,
|
|
42
|
+
destroyPopupOnHide = props.destroyPopupOnHide,
|
|
43
|
+
popup = props.popup,
|
|
44
|
+
popupClassName = props.popupClassName,
|
|
45
|
+
popupStyle = props.popupStyle,
|
|
46
|
+
popupPlacement = props.popupPlacement,
|
|
47
|
+
_props$builtinPlaceme = props.builtinPlacements,
|
|
48
|
+
builtinPlacements = _props$builtinPlaceme === void 0 ? {} : _props$builtinPlaceme,
|
|
49
|
+
popupAlign = props.popupAlign,
|
|
50
|
+
zIndex = props.zIndex,
|
|
51
|
+
stretch = props.stretch,
|
|
52
|
+
getPopupClassNameFromAlign = props.getPopupClassNameFromAlign,
|
|
53
|
+
alignPoint = props.alignPoint,
|
|
54
|
+
onPopupClick = props.onPopupClick,
|
|
55
|
+
arrow = props.arrow,
|
|
56
|
+
popupMotion = props.popupMotion,
|
|
57
|
+
maskMotion = props.maskMotion,
|
|
58
|
+
popupTransitionName = props.popupTransitionName,
|
|
59
|
+
popupAnimation = props.popupAnimation,
|
|
60
|
+
maskTransitionName = props.maskTransitionName,
|
|
61
|
+
maskAnimation = props.maskAnimation,
|
|
62
|
+
className = props.className,
|
|
63
|
+
getTriggerDOMNode = props.getTriggerDOMNode,
|
|
64
|
+
restProps = _objectWithoutProperties(props, _excluded);
|
|
65
|
+
var mergedAutoDestroy = autoDestroy || destroyPopupOnHide || false;
|
|
66
|
+
|
|
67
|
+
// ========================== Context ===========================
|
|
68
|
+
var subPopupElements = React.useRef({});
|
|
69
|
+
var parentContext = React.useContext(TriggerContext);
|
|
70
|
+
var context = React.useMemo(function () {
|
|
71
|
+
return {
|
|
72
|
+
registerSubPopup: function registerSubPopup(id, subPopupEle) {
|
|
73
|
+
subPopupElements.current[id] = subPopupEle;
|
|
74
|
+
parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, subPopupEle);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}, [parentContext]);
|
|
78
|
+
|
|
79
|
+
// =========================== Popup ============================
|
|
80
|
+
var id = useId();
|
|
81
|
+
var _React$useState = React.useState(null),
|
|
82
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
83
|
+
popupEle = _React$useState2[0],
|
|
84
|
+
setPopupEle = _React$useState2[1];
|
|
85
|
+
var setPopupRef = React.useCallback(function (node) {
|
|
86
|
+
if (node instanceof HTMLElement) {
|
|
87
|
+
setPopupEle(node);
|
|
88
|
+
}
|
|
89
|
+
parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, node);
|
|
90
|
+
}, []);
|
|
91
|
+
|
|
92
|
+
// =========================== Target ===========================
|
|
93
|
+
// Use state to control here since `useRef` update not trigger render
|
|
94
|
+
var _React$useState3 = React.useState(null),
|
|
95
|
+
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
96
|
+
targetEle = _React$useState4[0],
|
|
97
|
+
setTargetEle = _React$useState4[1];
|
|
98
|
+
var setTargetRef = React.useCallback(function (node) {
|
|
99
|
+
if (node instanceof HTMLElement) {
|
|
100
|
+
setTargetEle(node);
|
|
101
|
+
}
|
|
102
|
+
}, []);
|
|
103
|
+
|
|
104
|
+
// ========================== Children ==========================
|
|
105
|
+
var child = React.Children.only(children);
|
|
106
|
+
var originChildProps = (child === null || child === void 0 ? void 0 : child.props) || {};
|
|
107
|
+
var cloneProps = {};
|
|
108
|
+
var inPopupOrChild = useEvent(function (ele) {
|
|
109
|
+
var childDOM = targetEle;
|
|
110
|
+
return (childDOM === null || childDOM === void 0 ? void 0 : childDOM.contains(ele)) || ele === childDOM || (popupEle === null || popupEle === void 0 ? void 0 : popupEle.contains(ele)) || ele === popupEle || Object.values(subPopupElements.current).some(function (subPopupEle) {
|
|
111
|
+
return subPopupEle.contains(ele) || ele === subPopupEle;
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// =========================== Motion ===========================
|
|
116
|
+
var mergePopupMotion = getMotion(prefixCls, popupMotion, popupAnimation, popupTransitionName);
|
|
117
|
+
var mergeMaskMotion = getMotion(prefixCls, maskMotion, maskAnimation, maskTransitionName);
|
|
118
|
+
|
|
119
|
+
// ============================ Open ============================
|
|
120
|
+
var _useMergedState = useMergedState(defaultPopupVisible || false, {
|
|
121
|
+
value: popupVisible
|
|
122
|
+
}),
|
|
123
|
+
_useMergedState2 = _slicedToArray(_useMergedState, 2),
|
|
124
|
+
mergedOpen = _useMergedState2[0],
|
|
125
|
+
setMergedOpen = _useMergedState2[1];
|
|
126
|
+
var openRef = React.useRef(mergedOpen);
|
|
127
|
+
openRef.current = mergedOpen;
|
|
128
|
+
var internalTriggerOpen = useEvent(function (nextOpen) {
|
|
129
|
+
if (mergedOpen !== nextOpen) {
|
|
130
|
+
setMergedOpen(nextOpen);
|
|
131
|
+
onPopupVisibleChange === null || onPopupVisibleChange === void 0 ? void 0 : onPopupVisibleChange(nextOpen);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Trigger for delay
|
|
136
|
+
var delayRef = React.useRef();
|
|
137
|
+
var clearDelay = function clearDelay() {
|
|
138
|
+
clearTimeout(delayRef.current);
|
|
139
|
+
};
|
|
140
|
+
var triggerOpen = function triggerOpen(nextOpen) {
|
|
141
|
+
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
142
|
+
clearDelay();
|
|
143
|
+
if (delay === 0) {
|
|
144
|
+
internalTriggerOpen(nextOpen);
|
|
145
|
+
} else {
|
|
146
|
+
delayRef.current = setTimeout(function () {
|
|
147
|
+
internalTriggerOpen(nextOpen);
|
|
148
|
+
}, delay * 1000);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
React.useEffect(function () {
|
|
152
|
+
return clearDelay;
|
|
153
|
+
}, []);
|
|
154
|
+
|
|
155
|
+
// ========================== Motion ============================
|
|
156
|
+
var _React$useState5 = React.useState(false),
|
|
157
|
+
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
|
158
|
+
inMotion = _React$useState6[0],
|
|
159
|
+
setInMotion = _React$useState6[1];
|
|
160
|
+
useLayoutEffect(function () {
|
|
161
|
+
setInMotion(true);
|
|
162
|
+
}, [mergedOpen]);
|
|
163
|
+
var _React$useState7 = React.useState(null),
|
|
164
|
+
_React$useState8 = _slicedToArray(_React$useState7, 2),
|
|
165
|
+
motionPrepareResolve = _React$useState8[0],
|
|
166
|
+
setMotionPrepareResolve = _React$useState8[1];
|
|
167
|
+
|
|
168
|
+
// =========================== Align ============================
|
|
169
|
+
var _React$useState9 = React.useState([0, 0]),
|
|
170
|
+
_React$useState10 = _slicedToArray(_React$useState9, 2),
|
|
171
|
+
mousePos = _React$useState10[0],
|
|
172
|
+
setMousePos = _React$useState10[1];
|
|
173
|
+
var setMousePosByEvent = function setMousePosByEvent(event) {
|
|
174
|
+
setMousePos([event.clientX, event.clientY]);
|
|
175
|
+
};
|
|
176
|
+
var _useAlign = useAlign(mergedOpen, popupEle, alignPoint ? mousePos : targetEle, popupPlacement, builtinPlacements, popupAlign),
|
|
177
|
+
_useAlign2 = _slicedToArray(_useAlign, 9),
|
|
178
|
+
ready = _useAlign2[0],
|
|
179
|
+
offsetX = _useAlign2[1],
|
|
180
|
+
offsetY = _useAlign2[2],
|
|
181
|
+
arrowX = _useAlign2[3],
|
|
182
|
+
arrowY = _useAlign2[4],
|
|
183
|
+
scaleX = _useAlign2[5],
|
|
184
|
+
scaleY = _useAlign2[6],
|
|
185
|
+
alignInfo = _useAlign2[7],
|
|
186
|
+
onAlign = _useAlign2[8];
|
|
187
|
+
var triggerAlign = useEvent(function () {
|
|
188
|
+
if (!inMotion) {
|
|
189
|
+
onAlign();
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
useWatch(mergedOpen, targetEle, popupEle, triggerAlign);
|
|
193
|
+
useLayoutEffect(function () {
|
|
194
|
+
triggerAlign();
|
|
195
|
+
}, [mousePos]);
|
|
196
|
+
var alignedClassName = React.useMemo(function () {
|
|
197
|
+
var baseClassName = getAlignPopupClassName(builtinPlacements, prefixCls, alignInfo, alignPoint);
|
|
198
|
+
return classNames(baseClassName, getPopupClassNameFromAlign === null || getPopupClassNameFromAlign === void 0 ? void 0 : getPopupClassNameFromAlign(alignInfo));
|
|
199
|
+
}, [alignInfo, getPopupClassNameFromAlign, builtinPlacements, prefixCls, alignPoint]);
|
|
200
|
+
React.useImperativeHandle(ref, function () {
|
|
201
|
+
return {
|
|
202
|
+
forceAlign: triggerAlign
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// ========================== Motion ============================
|
|
207
|
+
var onVisibleChanged = function onVisibleChanged(visible) {
|
|
208
|
+
setInMotion(false);
|
|
209
|
+
onAlign();
|
|
210
|
+
afterPopupVisibleChange === null || afterPopupVisibleChange === void 0 ? void 0 : afterPopupVisibleChange(visible);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// We will trigger align when motion is in prepare
|
|
214
|
+
var onPrepare = function onPrepare() {
|
|
215
|
+
return new Promise(function (resolve) {
|
|
216
|
+
setMotionPrepareResolve(function () {
|
|
217
|
+
return resolve;
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
useLayoutEffect(function () {
|
|
222
|
+
if (motionPrepareResolve) {
|
|
223
|
+
onAlign();
|
|
224
|
+
motionPrepareResolve();
|
|
225
|
+
setMotionPrepareResolve(null);
|
|
226
|
+
}
|
|
227
|
+
}, [motionPrepareResolve]);
|
|
228
|
+
|
|
229
|
+
// ========================== Stretch ===========================
|
|
230
|
+
var _React$useState11 = React.useState(0),
|
|
231
|
+
_React$useState12 = _slicedToArray(_React$useState11, 2),
|
|
232
|
+
targetWidth = _React$useState12[0],
|
|
233
|
+
setTargetWidth = _React$useState12[1];
|
|
234
|
+
var _React$useState13 = React.useState(0),
|
|
235
|
+
_React$useState14 = _slicedToArray(_React$useState13, 2),
|
|
236
|
+
targetHeight = _React$useState14[0],
|
|
237
|
+
setTargetHeight = _React$useState14[1];
|
|
238
|
+
var onTargetResize = function onTargetResize(_, ele) {
|
|
239
|
+
triggerAlign();
|
|
240
|
+
if (stretch) {
|
|
241
|
+
var rect = ele.getBoundingClientRect();
|
|
242
|
+
setTargetWidth(rect.width);
|
|
243
|
+
setTargetHeight(rect.height);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// =========================== Action ===========================
|
|
248
|
+
var _useAction = useAction(action, showAction, hideAction),
|
|
249
|
+
_useAction2 = _slicedToArray(_useAction, 2),
|
|
250
|
+
showActions = _useAction2[0],
|
|
251
|
+
hideActions = _useAction2[1];
|
|
252
|
+
|
|
253
|
+
// Util wrapper for trigger action
|
|
254
|
+
var wrapperAction = function wrapperAction(eventName, nextOpen, delay, preEvent) {
|
|
255
|
+
cloneProps[eventName] = function (event) {
|
|
256
|
+
var _originChildProps$eve;
|
|
257
|
+
preEvent === null || preEvent === void 0 ? void 0 : preEvent(event);
|
|
258
|
+
triggerOpen(nextOpen, delay);
|
|
259
|
+
|
|
260
|
+
// Pass to origin
|
|
261
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
262
|
+
args[_key - 1] = arguments[_key];
|
|
263
|
+
}
|
|
264
|
+
(_originChildProps$eve = originChildProps[eventName]) === null || _originChildProps$eve === void 0 ? void 0 : _originChildProps$eve.call.apply(_originChildProps$eve, [originChildProps, event].concat(args));
|
|
265
|
+
};
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// ======================= Action: Click ========================
|
|
269
|
+
var clickToShow = showActions.has('click');
|
|
270
|
+
var clickToHide = hideActions.has('click') || hideActions.has('contextMenu');
|
|
271
|
+
if (clickToShow || clickToHide) {
|
|
272
|
+
cloneProps.onClick = function (event) {
|
|
273
|
+
var _originChildProps$onC;
|
|
274
|
+
if (openRef.current && clickToHide) {
|
|
275
|
+
triggerOpen(false);
|
|
276
|
+
} else if (!openRef.current && clickToShow) {
|
|
277
|
+
setMousePosByEvent(event);
|
|
278
|
+
triggerOpen(true);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Pass to origin
|
|
282
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
283
|
+
args[_key2 - 1] = arguments[_key2];
|
|
284
|
+
}
|
|
285
|
+
(_originChildProps$onC = originChildProps.onClick) === null || _originChildProps$onC === void 0 ? void 0 : _originChildProps$onC.call.apply(_originChildProps$onC, [originChildProps, event].concat(args));
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Click to hide is special action since click popup element should not hide
|
|
290
|
+
React.useEffect(function () {
|
|
291
|
+
if (clickToHide && popupEle && (!mask || maskClosable)) {
|
|
292
|
+
var onWindowClick = function onWindowClick(_ref) {
|
|
293
|
+
var target = _ref.target;
|
|
294
|
+
if (openRef.current && !inPopupOrChild(target)) {
|
|
295
|
+
triggerOpen(false);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
var win = getWin(popupEle);
|
|
299
|
+
win.addEventListener('click', onWindowClick);
|
|
300
|
+
return function () {
|
|
301
|
+
win.removeEventListener('click', onWindowClick);
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}, [clickToHide, popupEle, mask, maskClosable]);
|
|
305
|
+
|
|
306
|
+
// ======================= Action: Hover ========================
|
|
307
|
+
var hoverToShow = showActions.has('hover');
|
|
308
|
+
var hoverToHide = hideActions.has('hover');
|
|
309
|
+
var onPopupMouseEnter;
|
|
310
|
+
var onPopupMouseLeave;
|
|
311
|
+
if (hoverToShow) {
|
|
312
|
+
wrapperAction('onMouseEnter', true, mouseEnterDelay, function (event) {
|
|
313
|
+
setMousePosByEvent(event);
|
|
314
|
+
});
|
|
315
|
+
onPopupMouseEnter = function onPopupMouseEnter() {
|
|
316
|
+
triggerOpen(true, mouseEnterDelay);
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Align Point
|
|
320
|
+
if (alignPoint) {
|
|
321
|
+
cloneProps.onMouseMove = function (event) {
|
|
322
|
+
var _originChildProps$onM;
|
|
323
|
+
// setMousePosByEvent(event);
|
|
324
|
+
(_originChildProps$onM = originChildProps.onMouseMove) === null || _originChildProps$onM === void 0 ? void 0 : _originChildProps$onM.call(originChildProps, event);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (hoverToHide) {
|
|
329
|
+
wrapperAction('onMouseLeave', false, mouseLeaveDelay);
|
|
330
|
+
onPopupMouseLeave = function onPopupMouseLeave() {
|
|
331
|
+
triggerOpen(false, mouseLeaveDelay);
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ======================= Action: Focus ========================
|
|
336
|
+
if (showActions.has('focus')) {
|
|
337
|
+
wrapperAction('onFocus', true, focusDelay);
|
|
338
|
+
}
|
|
339
|
+
if (hideActions.has('focus')) {
|
|
340
|
+
wrapperAction('onBlur', false, blurDelay);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ==================== Action: ContextMenu =====================
|
|
344
|
+
if (showActions.has('contextMenu')) {
|
|
345
|
+
cloneProps.onContextMenu = function (event) {
|
|
346
|
+
var _originChildProps$onC2;
|
|
347
|
+
setMousePosByEvent(event);
|
|
348
|
+
triggerOpen(true);
|
|
349
|
+
event.preventDefault();
|
|
350
|
+
|
|
351
|
+
// Pass to origin
|
|
352
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
353
|
+
args[_key3 - 1] = arguments[_key3];
|
|
354
|
+
}
|
|
355
|
+
(_originChildProps$onC2 = originChildProps.onContextMenu) === null || _originChildProps$onC2 === void 0 ? void 0 : _originChildProps$onC2.call.apply(_originChildProps$onC2, [originChildProps, event].concat(args));
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ========================= ClassName ==========================
|
|
360
|
+
if (className) {
|
|
361
|
+
cloneProps.className = classNames(originChildProps.className, className);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// =========================== Render ===========================
|
|
365
|
+
var mergedChildrenProps = _objectSpread(_objectSpread({}, originChildProps), cloneProps);
|
|
366
|
+
|
|
367
|
+
// Pass props into cloneProps for nest usage
|
|
368
|
+
var passedProps = {};
|
|
369
|
+
var passedEventList = ['onContextMenu', 'onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur'];
|
|
370
|
+
passedEventList.forEach(function (eventName) {
|
|
371
|
+
if (restProps[eventName]) {
|
|
372
|
+
passedProps[eventName] = function () {
|
|
373
|
+
var _mergedChildrenProps$;
|
|
374
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
375
|
+
args[_key4] = arguments[_key4];
|
|
376
|
+
}
|
|
377
|
+
(_mergedChildrenProps$ = mergedChildrenProps[eventName]) === null || _mergedChildrenProps$ === void 0 ? void 0 : _mergedChildrenProps$.call.apply(_mergedChildrenProps$, [mergedChildrenProps].concat(args));
|
|
378
|
+
restProps[eventName].apply(restProps, args);
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
// Child Node
|
|
384
|
+
var triggerNode = /*#__PURE__*/React.cloneElement(child, _objectSpread(_objectSpread({}, mergedChildrenProps), passedProps));
|
|
385
|
+
|
|
386
|
+
// Render
|
|
387
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TriggerContext.Provider, {
|
|
388
|
+
value: context
|
|
389
|
+
}, /*#__PURE__*/React.createElement(Popup, {
|
|
390
|
+
ref: setPopupRef,
|
|
391
|
+
prefixCls: prefixCls,
|
|
392
|
+
popup: popup,
|
|
393
|
+
className: classNames(popupClassName, alignedClassName),
|
|
394
|
+
style: popupStyle,
|
|
395
|
+
target: targetEle,
|
|
396
|
+
onMouseEnter: onPopupMouseEnter,
|
|
397
|
+
onMouseLeave: onPopupMouseLeave,
|
|
398
|
+
zIndex: zIndex
|
|
399
|
+
// Open
|
|
400
|
+
,
|
|
401
|
+
open: mergedOpen,
|
|
402
|
+
keepDom: inMotion
|
|
403
|
+
// Click
|
|
404
|
+
,
|
|
405
|
+
onClick: onPopupClick
|
|
406
|
+
// Mask
|
|
407
|
+
,
|
|
408
|
+
mask: mask
|
|
409
|
+
// Motion
|
|
410
|
+
,
|
|
411
|
+
motion: mergePopupMotion,
|
|
412
|
+
maskMotion: mergeMaskMotion,
|
|
413
|
+
onVisibleChanged: onVisibleChanged,
|
|
414
|
+
onPrepare: onPrepare
|
|
415
|
+
// Portal
|
|
416
|
+
,
|
|
417
|
+
forceRender: forceRender,
|
|
418
|
+
autoDestroy: mergedAutoDestroy,
|
|
419
|
+
getPopupContainer: getPopupContainer
|
|
420
|
+
// Arrow
|
|
421
|
+
,
|
|
422
|
+
align: alignInfo,
|
|
423
|
+
arrow: arrow
|
|
424
|
+
// Align
|
|
425
|
+
,
|
|
426
|
+
ready: ready,
|
|
427
|
+
offsetX: offsetX,
|
|
428
|
+
offsetY: offsetY,
|
|
429
|
+
arrowX: arrowX,
|
|
430
|
+
arrowY: arrowY,
|
|
431
|
+
onAlign: triggerAlign
|
|
432
|
+
// Stretch
|
|
433
|
+
,
|
|
434
|
+
stretch: stretch,
|
|
435
|
+
targetWidth: targetWidth / scaleX,
|
|
436
|
+
targetHeight: targetHeight / scaleY
|
|
437
|
+
})), /*#__PURE__*/React.createElement(ResizeObserver, {
|
|
438
|
+
disabled: !mergedOpen,
|
|
439
|
+
ref: setTargetRef,
|
|
440
|
+
onResize: onTargetResize
|
|
441
|
+
}, /*#__PURE__*/React.createElement(TriggerWrapper, {
|
|
442
|
+
getTriggerDOMNode: getTriggerDOMNode
|
|
443
|
+
}, triggerNode)));
|
|
444
|
+
});
|
|
445
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
446
|
+
Trigger.displayName = 'Trigger';
|
|
447
|
+
}
|
|
448
|
+
export default Trigger;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { CSSMotionProps } from 'rc-motion';
|
|
3
|
+
export declare type Placement = 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
|
|
4
|
+
export interface TriggerProps {
|
|
5
|
+
children: React.ReactElement;
|
|
6
|
+
action?: ActionType | ActionType[];
|
|
7
|
+
showAction?: ActionType[];
|
|
8
|
+
hideAction?: ActionType[];
|
|
9
|
+
getPopupClassNameFromAlign?: (align: AlignType) => string;
|
|
10
|
+
onPopupVisibleChange?: (visible: boolean) => void;
|
|
11
|
+
onPopupClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
12
|
+
afterPopupVisibleChange?: (visible: boolean) => void;
|
|
13
|
+
popup: React.ReactNode | (() => React.ReactNode);
|
|
14
|
+
popupStyle?: React.CSSProperties;
|
|
15
|
+
prefixCls?: string;
|
|
16
|
+
popupClassName?: string;
|
|
17
|
+
className?: string;
|
|
18
|
+
popupPlacement?: string;
|
|
19
|
+
builtinPlacements?: BuildInPlacements;
|
|
20
|
+
mouseEnterDelay?: number;
|
|
21
|
+
mouseLeaveDelay?: number;
|
|
22
|
+
zIndex?: number;
|
|
23
|
+
focusDelay?: number;
|
|
24
|
+
blurDelay?: number;
|
|
25
|
+
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
|
26
|
+
getDocument?: (element?: HTMLElement) => HTMLDocument;
|
|
27
|
+
forceRender?: boolean;
|
|
28
|
+
destroyPopupOnHide?: boolean;
|
|
29
|
+
mask?: boolean;
|
|
30
|
+
maskClosable?: boolean;
|
|
31
|
+
onPopupAlign?: (element: HTMLElement, align: AlignType) => void;
|
|
32
|
+
popupAlign?: AlignType;
|
|
33
|
+
popupVisible?: boolean;
|
|
34
|
+
defaultPopupVisible?: boolean;
|
|
35
|
+
autoDestroy?: boolean;
|
|
36
|
+
stretch?: string;
|
|
37
|
+
alignPoint?: boolean;
|
|
38
|
+
/** Set popup motion. You can ref `rc-motion` for more info. */
|
|
39
|
+
popupMotion?: CSSMotionProps;
|
|
40
|
+
/** Set mask motion. You can ref `rc-motion` for more info. */
|
|
41
|
+
maskMotion?: CSSMotionProps;
|
|
42
|
+
/** @deprecated Please us `popupMotion` instead. */
|
|
43
|
+
popupTransitionName?: TransitionNameType;
|
|
44
|
+
/** @deprecated Please us `popupMotion` instead. */
|
|
45
|
+
popupAnimation?: AnimationType;
|
|
46
|
+
/** @deprecated Please us `maskMotion` instead. */
|
|
47
|
+
maskTransitionName?: TransitionNameType;
|
|
48
|
+
/** @deprecated Please us `maskMotion` instead. */
|
|
49
|
+
maskAnimation?: string;
|
|
50
|
+
/**
|
|
51
|
+
* @private Get trigger DOM node.
|
|
52
|
+
* Used for some component is function component which can not access by `findDOMNode`
|
|
53
|
+
*/
|
|
54
|
+
getTriggerDOMNode?: (node: React.ReactInstance) => HTMLElement;
|
|
55
|
+
/** @private Bump fixed position at bottom in mobile.
|
|
56
|
+
* This is internal usage currently, do not use in your prod */
|
|
57
|
+
mobile?: MobileConfig;
|
|
58
|
+
}
|
|
59
|
+
export declare type AlignPointTopBottom = 't' | 'b' | 'c';
|
|
60
|
+
export declare type AlignPointLeftRight = 'l' | 'r' | 'c';
|
|
61
|
+
/** Two char of 't' 'b' 'c' 'l' 'r'. Example: 'lt' */
|
|
62
|
+
export declare type AlignPoint = `${AlignPointTopBottom}${AlignPointLeftRight}`;
|
|
63
|
+
export interface AlignType {
|
|
64
|
+
/**
|
|
65
|
+
* move point of source node to align with point of target node.
|
|
66
|
+
* Such as ['tr','cc'], align top right point of source node with center point of target node.
|
|
67
|
+
* Point can be 't'(top), 'b'(bottom), 'c'(center), 'l'(left), 'r'(right) */
|
|
68
|
+
points?: (string | AlignPoint)[];
|
|
69
|
+
/**
|
|
70
|
+
* offset source node by offset[0] in x and offset[1] in y.
|
|
71
|
+
* If offset contains percentage string value, it is relative to sourceNode region.
|
|
72
|
+
*/
|
|
73
|
+
offset?: number[];
|
|
74
|
+
/**
|
|
75
|
+
* offset target node by offset[0] in x and offset[1] in y.
|
|
76
|
+
* If targetOffset contains percentage string value, it is relative to targetNode region.
|
|
77
|
+
*/
|
|
78
|
+
targetOffset?: number[];
|
|
79
|
+
/**
|
|
80
|
+
* If adjustX field is true, will adjust source node in x direction if source node is invisible.
|
|
81
|
+
* If adjustY field is true, will adjust source node in y direction if source node is invisible.
|
|
82
|
+
*/
|
|
83
|
+
overflow?: {
|
|
84
|
+
adjustX?: boolean | number;
|
|
85
|
+
adjustY?: boolean | number;
|
|
86
|
+
shiftX?: boolean | number;
|
|
87
|
+
shiftY?: boolean | number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Whether use css right instead of left to position
|
|
91
|
+
*/
|
|
92
|
+
useCssRight?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Whether use css bottom instead of top to position
|
|
95
|
+
*/
|
|
96
|
+
useCssBottom?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Whether use css transform instead of left/top/right/bottom to position if browser supports.
|
|
99
|
+
* Defaults to false.
|
|
100
|
+
*/
|
|
101
|
+
useCssTransform?: boolean;
|
|
102
|
+
ignoreShake?: boolean;
|
|
103
|
+
}
|
|
104
|
+
export declare type BuildInPlacements = Record<string, AlignType>;
|
|
105
|
+
export declare type StretchType = string;
|
|
106
|
+
export declare type ActionType = 'hover' | 'focus' | 'click' | 'contextMenu';
|
|
107
|
+
export declare type AnimationType = string;
|
|
108
|
+
export declare type TransitionNameType = string;
|
|
109
|
+
export interface Point {
|
|
110
|
+
pageX: number;
|
|
111
|
+
pageY: number;
|
|
112
|
+
}
|
|
113
|
+
export interface CommonEventHandler {
|
|
114
|
+
remove: () => void;
|
|
115
|
+
}
|
|
116
|
+
export interface MobileConfig {
|
|
117
|
+
/** Set popup motion. You can ref `rc-motion` for more info. */
|
|
118
|
+
popupMotion?: CSSMotionProps;
|
|
119
|
+
popupClassName?: string;
|
|
120
|
+
popupStyle?: React.CSSProperties;
|
|
121
|
+
popupRender?: (originNode: React.ReactNode) => React.ReactNode;
|
|
122
|
+
}
|
package/es/interface.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/es/util.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CSSMotionProps } from 'rc-motion';
|
|
2
|
+
import type { AlignType, AnimationType, BuildInPlacements, TransitionNameType } from './interface';
|
|
3
|
+
export declare function getAlignFromPlacement(builtinPlacements: BuildInPlacements, placementStr: string, align: AlignType): AlignType;
|
|
4
|
+
export declare function getAlignPopupClassName(builtinPlacements: BuildInPlacements, prefixCls: string, align: AlignType, isAlignPoint: boolean): string;
|
|
5
|
+
/** @deprecated We should not use this if we can refactor all deps */
|
|
6
|
+
export declare function getMotion(prefixCls: string, motion: CSSMotionProps, animation: AnimationType, transitionName: TransitionNameType): CSSMotionProps;
|
|
7
|
+
export declare function getWin(ele: HTMLElement): Window & typeof globalThis;
|
package/es/util.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
function isPointsEq() {
|
|
3
|
+
var a1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
4
|
+
var a2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
5
|
+
var isAlignPoint = arguments.length > 2 ? arguments[2] : undefined;
|
|
6
|
+
if (isAlignPoint) {
|
|
7
|
+
return a1[0] === a2[0];
|
|
8
|
+
}
|
|
9
|
+
return a1[0] === a2[0] && a1[1] === a2[1];
|
|
10
|
+
}
|
|
11
|
+
export function getAlignFromPlacement(builtinPlacements, placementStr, align) {
|
|
12
|
+
var baseAlign = builtinPlacements[placementStr] || {};
|
|
13
|
+
return _objectSpread(_objectSpread({}, baseAlign), align);
|
|
14
|
+
}
|
|
15
|
+
export function getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) {
|
|
16
|
+
var points = align.points;
|
|
17
|
+
var placements = Object.keys(builtinPlacements);
|
|
18
|
+
for (var i = 0; i < placements.length; i += 1) {
|
|
19
|
+
var _builtinPlacements$pl;
|
|
20
|
+
var placement = placements[i];
|
|
21
|
+
if (isPointsEq((_builtinPlacements$pl = builtinPlacements[placement]) === null || _builtinPlacements$pl === void 0 ? void 0 : _builtinPlacements$pl.points, points, isAlignPoint)) {
|
|
22
|
+
return "".concat(prefixCls, "-placement-").concat(placement);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @deprecated We should not use this if we can refactor all deps */
|
|
29
|
+
export function getMotion(prefixCls, motion, animation, transitionName) {
|
|
30
|
+
if (motion) {
|
|
31
|
+
return motion;
|
|
32
|
+
}
|
|
33
|
+
if (animation) {
|
|
34
|
+
return {
|
|
35
|
+
motionName: "".concat(prefixCls, "-").concat(animation)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (transitionName) {
|
|
39
|
+
return {
|
|
40
|
+
motionName: transitionName
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
export function getWin(ele) {
|
|
46
|
+
return ele.ownerDocument.defaultView;
|
|
47
|
+
}
|