@rc-component/trigger 2.2.5 → 3.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/es/Popup/Arrow.js +23 -20
- package/es/Popup/Mask.d.ts +1 -1
- package/es/Popup/Mask.js +17 -16
- package/es/Popup/PopupContent.js +3 -6
- package/es/Popup/index.d.ts +1 -1
- package/es/Popup/index.js +83 -78
- package/es/TriggerWrapper.js +9 -7
- package/es/context.js +1 -1
- package/es/hooks/useAction.js +5 -5
- package/es/hooks/useAlign.js +205 -215
- package/es/hooks/useWatch.js +11 -12
- package/es/hooks/useWinClick.js +14 -16
- package/es/index.d.ts +2 -14
- package/es/index.js +167 -244
- package/es/interface.d.ts +1 -1
- package/es/mock.js +10 -13
- package/es/util.d.ts +1 -4
- package/es/util.js +57 -75
- package/lib/Popup/Arrow.js +26 -22
- package/lib/Popup/Mask.d.ts +1 -1
- package/lib/Popup/Mask.js +21 -19
- package/lib/Popup/PopupContent.js +5 -7
- package/lib/Popup/index.d.ts +1 -1
- package/lib/Popup/index.js +89 -83
- package/lib/TriggerWrapper.js +11 -8
- package/lib/context.js +3 -2
- package/lib/hooks/useAction.js +7 -6
- package/lib/hooks/useAlign.js +208 -217
- package/lib/hooks/useWatch.js +12 -13
- package/lib/hooks/useWinClick.js +16 -17
- package/lib/index.d.ts +2 -14
- package/lib/index.js +172 -248
- package/lib/interface.d.ts +1 -1
- package/lib/mock.js +12 -15
- package/lib/util.d.ts +1 -4
- package/lib/util.js +57 -77
- package/package.json +10 -11
package/es/index.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
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", "fresh", "alignPoint", "onPopupClick", "onPopupAlign", "arrow", "popupMotion", "maskMotion", "popupTransitionName", "popupAnimation", "maskTransitionName", "maskAnimation", "className", "getTriggerDOMNode"];
|
|
5
1
|
import Portal from '@rc-component/portal';
|
|
6
2
|
import classNames from 'classnames';
|
|
7
|
-
import ResizeObserver from 'rc-resize-observer';
|
|
8
|
-
import { isDOM } from "rc-util/es/Dom/findDOMNode";
|
|
9
|
-
import { getShadowRoot } from "rc-util/es/Dom/shadow";
|
|
10
|
-
import useEvent from "rc-util/es/hooks/useEvent";
|
|
11
|
-
import useId from "rc-util/es/hooks/useId";
|
|
12
|
-
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
|
13
|
-
import isMobile from "rc-util/es/isMobile";
|
|
3
|
+
import ResizeObserver from '@rc-component/resize-observer';
|
|
4
|
+
import { isDOM } from "@rc-component/util/es/Dom/findDOMNode";
|
|
5
|
+
import { getShadowRoot } from "@rc-component/util/es/Dom/shadow";
|
|
6
|
+
import useEvent from "@rc-component/util/es/hooks/useEvent";
|
|
7
|
+
import useId from "@rc-component/util/es/hooks/useId";
|
|
8
|
+
import useLayoutEffect from "@rc-component/util/es/hooks/useLayoutEffect";
|
|
9
|
+
import isMobile from "@rc-component/util/es/isMobile";
|
|
14
10
|
import * as React from 'react';
|
|
15
11
|
import Popup from "./Popup";
|
|
16
12
|
import TriggerWrapper from "./TriggerWrapper";
|
|
@@ -19,7 +15,7 @@ import useAction from "./hooks/useAction";
|
|
|
19
15
|
import useAlign from "./hooks/useAlign";
|
|
20
16
|
import useWatch from "./hooks/useWatch";
|
|
21
17
|
import useWinClick from "./hooks/useWinClick";
|
|
22
|
-
import { getAlignPopupClassName
|
|
18
|
+
import { getAlignPopupClassName } from "./util";
|
|
23
19
|
|
|
24
20
|
// Removed Props List
|
|
25
21
|
// Seems this can be auto
|
|
@@ -27,106 +23,96 @@ import { getAlignPopupClassName, getMotion } from "./util";
|
|
|
27
23
|
|
|
28
24
|
// New version will not wrap popup with `rc-trigger-popup-content` when multiple children
|
|
29
25
|
|
|
30
|
-
export function generateTrigger() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
popupVisible
|
|
41
|
-
defaultPopupVisible
|
|
42
|
-
onPopupVisibleChange
|
|
43
|
-
afterPopupVisibleChange
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
mouseLeaveDelay =
|
|
47
|
-
focusDelay
|
|
48
|
-
blurDelay
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
maskClosable =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
builtinPlacements =
|
|
62
|
-
popupAlign
|
|
63
|
-
zIndex
|
|
64
|
-
stretch
|
|
65
|
-
getPopupClassNameFromAlign
|
|
66
|
-
fresh
|
|
67
|
-
alignPoint
|
|
68
|
-
onPopupClick
|
|
69
|
-
onPopupAlign
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
var mergedAutoDestroy = autoDestroy || destroyPopupOnHide || false;
|
|
26
|
+
export function generateTrigger(PortalComponent = Portal) {
|
|
27
|
+
const Trigger = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
28
|
+
const {
|
|
29
|
+
prefixCls = 'rc-trigger-popup',
|
|
30
|
+
children,
|
|
31
|
+
// Action
|
|
32
|
+
action = 'hover',
|
|
33
|
+
showAction,
|
|
34
|
+
hideAction,
|
|
35
|
+
// Open
|
|
36
|
+
popupVisible,
|
|
37
|
+
defaultPopupVisible,
|
|
38
|
+
onPopupVisibleChange,
|
|
39
|
+
afterPopupVisibleChange,
|
|
40
|
+
// Delay
|
|
41
|
+
mouseEnterDelay,
|
|
42
|
+
mouseLeaveDelay = 0.1,
|
|
43
|
+
focusDelay,
|
|
44
|
+
blurDelay,
|
|
45
|
+
// Mask
|
|
46
|
+
mask,
|
|
47
|
+
maskClosable = true,
|
|
48
|
+
// Portal
|
|
49
|
+
getPopupContainer,
|
|
50
|
+
forceRender,
|
|
51
|
+
autoDestroy,
|
|
52
|
+
// Popup
|
|
53
|
+
popup,
|
|
54
|
+
popupClassName,
|
|
55
|
+
popupStyle,
|
|
56
|
+
popupPlacement,
|
|
57
|
+
builtinPlacements = {},
|
|
58
|
+
popupAlign,
|
|
59
|
+
zIndex,
|
|
60
|
+
stretch,
|
|
61
|
+
getPopupClassNameFromAlign,
|
|
62
|
+
fresh,
|
|
63
|
+
alignPoint,
|
|
64
|
+
onPopupClick,
|
|
65
|
+
onPopupAlign,
|
|
66
|
+
// Arrow
|
|
67
|
+
arrow,
|
|
68
|
+
// Motion
|
|
69
|
+
popupMotion,
|
|
70
|
+
maskMotion,
|
|
71
|
+
// Private
|
|
72
|
+
getTriggerDOMNode,
|
|
73
|
+
...restProps
|
|
74
|
+
} = props;
|
|
75
|
+
const mergedAutoDestroy = autoDestroy || false;
|
|
81
76
|
|
|
82
77
|
// =========================== Mobile ===========================
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
mobile = _React$useState2[0],
|
|
86
|
-
setMobile = _React$useState2[1];
|
|
87
|
-
useLayoutEffect(function () {
|
|
78
|
+
const [mobile, setMobile] = React.useState(false);
|
|
79
|
+
useLayoutEffect(() => {
|
|
88
80
|
setMobile(isMobile());
|
|
89
81
|
}, []);
|
|
90
82
|
|
|
91
83
|
// ========================== Context ===========================
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
const subPopupElements = React.useRef({});
|
|
85
|
+
const parentContext = React.useContext(TriggerContext);
|
|
86
|
+
const context = React.useMemo(() => {
|
|
95
87
|
return {
|
|
96
|
-
registerSubPopup:
|
|
88
|
+
registerSubPopup: (id, subPopupEle) => {
|
|
97
89
|
subPopupElements.current[id] = subPopupEle;
|
|
98
|
-
parentContext
|
|
90
|
+
parentContext?.registerSubPopup(id, subPopupEle);
|
|
99
91
|
}
|
|
100
92
|
};
|
|
101
93
|
}, [parentContext]);
|
|
102
94
|
|
|
103
95
|
// =========================== Popup ============================
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
107
|
-
popupEle = _React$useState4[0],
|
|
108
|
-
setPopupEle = _React$useState4[1];
|
|
96
|
+
const id = useId();
|
|
97
|
+
const [popupEle, setPopupEle] = React.useState(null);
|
|
109
98
|
|
|
110
99
|
// Used for forwardRef popup. Not use internal
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
const externalPopupRef = React.useRef(null);
|
|
101
|
+
const setPopupRef = useEvent(node => {
|
|
113
102
|
externalPopupRef.current = node;
|
|
114
103
|
if (isDOM(node) && popupEle !== node) {
|
|
115
104
|
setPopupEle(node);
|
|
116
105
|
}
|
|
117
|
-
parentContext
|
|
106
|
+
parentContext?.registerSubPopup(id, node);
|
|
118
107
|
});
|
|
119
108
|
|
|
120
109
|
// =========================== Target ===========================
|
|
121
110
|
// Use state to control here since `useRef` update not trigger render
|
|
122
|
-
|
|
123
|
-
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
|
124
|
-
targetEle = _React$useState6[0],
|
|
125
|
-
setTargetEle = _React$useState6[1];
|
|
111
|
+
const [targetEle, setTargetEle] = React.useState(null);
|
|
126
112
|
|
|
127
113
|
// Used for forwardRef target. Not use internal
|
|
128
|
-
|
|
129
|
-
|
|
114
|
+
const externalForwardRef = React.useRef(null);
|
|
115
|
+
const setTargetRef = useEvent(node => {
|
|
130
116
|
if (isDOM(node) && targetEle !== node) {
|
|
131
117
|
setTargetEle(node);
|
|
132
118
|
externalForwardRef.current = node;
|
|
@@ -134,191 +120,141 @@ export function generateTrigger() {
|
|
|
134
120
|
});
|
|
135
121
|
|
|
136
122
|
// ========================== Children ==========================
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return (childDOM === null || childDOM === void 0 ? void 0 : childDOM.contains(ele)) || ((_getShadowRoot = getShadowRoot(childDOM)) === null || _getShadowRoot === void 0 ? void 0 : _getShadowRoot.host) === ele || ele === childDOM || (popupEle === null || popupEle === void 0 ? void 0 : popupEle.contains(ele)) || ((_getShadowRoot2 = getShadowRoot(popupEle)) === null || _getShadowRoot2 === void 0 ? void 0 : _getShadowRoot2.host) === ele || ele === popupEle || Object.values(subPopupElements.current).some(function (subPopupEle) {
|
|
144
|
-
return (subPopupEle === null || subPopupEle === void 0 ? void 0 : subPopupEle.contains(ele)) || ele === subPopupEle;
|
|
145
|
-
});
|
|
123
|
+
const child = React.Children.only(children);
|
|
124
|
+
const originChildProps = child?.props || {};
|
|
125
|
+
const cloneProps = {};
|
|
126
|
+
const inPopupOrChild = useEvent(ele => {
|
|
127
|
+
const childDOM = targetEle;
|
|
128
|
+
return childDOM?.contains(ele) || getShadowRoot(childDOM)?.host === ele || ele === childDOM || popupEle?.contains(ele) || getShadowRoot(popupEle)?.host === ele || ele === popupEle || Object.values(subPopupElements.current).some(subPopupEle => subPopupEle?.contains(ele) || ele === subPopupEle);
|
|
146
129
|
});
|
|
147
130
|
|
|
148
|
-
// =========================== Motion ===========================
|
|
149
|
-
var mergePopupMotion = getMotion(prefixCls, popupMotion, popupAnimation, popupTransitionName);
|
|
150
|
-
var mergeMaskMotion = getMotion(prefixCls, maskMotion, maskAnimation, maskTransitionName);
|
|
151
|
-
|
|
152
131
|
// ============================ Open ============================
|
|
153
|
-
|
|
154
|
-
_React$useState8 = _slicedToArray(_React$useState7, 2),
|
|
155
|
-
internalOpen = _React$useState8[0],
|
|
156
|
-
setInternalOpen = _React$useState8[1];
|
|
132
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultPopupVisible || false);
|
|
157
133
|
|
|
158
134
|
// Render still use props as first priority
|
|
159
|
-
|
|
135
|
+
const mergedOpen = popupVisible ?? internalOpen;
|
|
160
136
|
|
|
161
137
|
// We use effect sync here in case `popupVisible` back to `undefined`
|
|
162
|
-
|
|
138
|
+
const setMergedOpen = useEvent(nextOpen => {
|
|
163
139
|
if (popupVisible === undefined) {
|
|
164
140
|
setInternalOpen(nextOpen);
|
|
165
141
|
}
|
|
166
142
|
});
|
|
167
|
-
useLayoutEffect(
|
|
143
|
+
useLayoutEffect(() => {
|
|
168
144
|
setInternalOpen(popupVisible || false);
|
|
169
145
|
}, [popupVisible]);
|
|
170
|
-
|
|
146
|
+
const openRef = React.useRef(mergedOpen);
|
|
171
147
|
openRef.current = mergedOpen;
|
|
172
|
-
|
|
148
|
+
const lastTriggerRef = React.useRef([]);
|
|
173
149
|
lastTriggerRef.current = [];
|
|
174
|
-
|
|
175
|
-
var _lastTriggerRef$curre;
|
|
150
|
+
const internalTriggerOpen = useEvent(nextOpen => {
|
|
176
151
|
setMergedOpen(nextOpen);
|
|
177
152
|
|
|
178
153
|
// Enter or Pointer will both trigger open state change
|
|
179
154
|
// We only need take one to avoid duplicated change event trigger
|
|
180
155
|
// Use `lastTriggerRef` to record last open type
|
|
181
|
-
if ((
|
|
156
|
+
if ((lastTriggerRef.current[lastTriggerRef.current.length - 1] ?? mergedOpen) !== nextOpen) {
|
|
182
157
|
lastTriggerRef.current.push(nextOpen);
|
|
183
|
-
onPopupVisibleChange
|
|
158
|
+
onPopupVisibleChange?.(nextOpen);
|
|
184
159
|
}
|
|
185
160
|
});
|
|
186
161
|
|
|
187
162
|
// Trigger for delay
|
|
188
|
-
|
|
189
|
-
|
|
163
|
+
const delayRef = React.useRef();
|
|
164
|
+
const clearDelay = () => {
|
|
190
165
|
clearTimeout(delayRef.current);
|
|
191
166
|
};
|
|
192
|
-
|
|
193
|
-
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
167
|
+
const triggerOpen = (nextOpen, delay = 0) => {
|
|
194
168
|
clearDelay();
|
|
195
169
|
if (delay === 0) {
|
|
196
170
|
internalTriggerOpen(nextOpen);
|
|
197
171
|
} else {
|
|
198
|
-
delayRef.current = setTimeout(
|
|
172
|
+
delayRef.current = setTimeout(() => {
|
|
199
173
|
internalTriggerOpen(nextOpen);
|
|
200
174
|
}, delay * 1000);
|
|
201
175
|
}
|
|
202
176
|
};
|
|
203
|
-
React.useEffect(
|
|
204
|
-
return clearDelay;
|
|
205
|
-
}, []);
|
|
177
|
+
React.useEffect(() => clearDelay, []);
|
|
206
178
|
|
|
207
179
|
// ========================== Motion ============================
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
inMotion = _React$useState10[0],
|
|
211
|
-
setInMotion = _React$useState10[1];
|
|
212
|
-
useLayoutEffect(function (firstMount) {
|
|
180
|
+
const [inMotion, setInMotion] = React.useState(false);
|
|
181
|
+
useLayoutEffect(firstMount => {
|
|
213
182
|
if (!firstMount || mergedOpen) {
|
|
214
183
|
setInMotion(true);
|
|
215
184
|
}
|
|
216
185
|
}, [mergedOpen]);
|
|
217
|
-
|
|
218
|
-
_React$useState12 = _slicedToArray(_React$useState11, 2),
|
|
219
|
-
motionPrepareResolve = _React$useState12[0],
|
|
220
|
-
setMotionPrepareResolve = _React$useState12[1];
|
|
186
|
+
const [motionPrepareResolve, setMotionPrepareResolve] = React.useState(null);
|
|
221
187
|
|
|
222
188
|
// =========================== Align ============================
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
mousePos = _React$useState14[0],
|
|
226
|
-
setMousePos = _React$useState14[1];
|
|
227
|
-
var setMousePosByEvent = function setMousePosByEvent(event) {
|
|
189
|
+
const [mousePos, setMousePos] = React.useState(null);
|
|
190
|
+
const setMousePosByEvent = event => {
|
|
228
191
|
setMousePos([event.clientX, event.clientY]);
|
|
229
192
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
offsetR = _useAlign2[3],
|
|
236
|
-
offsetB = _useAlign2[4],
|
|
237
|
-
arrowX = _useAlign2[5],
|
|
238
|
-
arrowY = _useAlign2[6],
|
|
239
|
-
scaleX = _useAlign2[7],
|
|
240
|
-
scaleY = _useAlign2[8],
|
|
241
|
-
alignInfo = _useAlign2[9],
|
|
242
|
-
onAlign = _useAlign2[10];
|
|
243
|
-
var _useAction = useAction(mobile, action, showAction, hideAction),
|
|
244
|
-
_useAction2 = _slicedToArray(_useAction, 2),
|
|
245
|
-
showActions = _useAction2[0],
|
|
246
|
-
hideActions = _useAction2[1];
|
|
247
|
-
var clickToShow = showActions.has('click');
|
|
248
|
-
var clickToHide = hideActions.has('click') || hideActions.has('contextMenu');
|
|
249
|
-
var triggerAlign = useEvent(function () {
|
|
193
|
+
const [ready, offsetX, offsetY, offsetR, offsetB, arrowX, arrowY, scaleX, scaleY, alignInfo, onAlign] = useAlign(mergedOpen, popupEle, alignPoint && mousePos !== null ? mousePos : targetEle, popupPlacement, builtinPlacements, popupAlign, onPopupAlign);
|
|
194
|
+
const [showActions, hideActions] = useAction(mobile, action, showAction, hideAction);
|
|
195
|
+
const clickToShow = showActions.has('click');
|
|
196
|
+
const clickToHide = hideActions.has('click') || hideActions.has('contextMenu');
|
|
197
|
+
const triggerAlign = useEvent(() => {
|
|
250
198
|
if (!inMotion) {
|
|
251
199
|
onAlign();
|
|
252
200
|
}
|
|
253
201
|
});
|
|
254
|
-
|
|
202
|
+
const onScroll = () => {
|
|
255
203
|
if (openRef.current && alignPoint && clickToHide) {
|
|
256
204
|
triggerOpen(false);
|
|
257
205
|
}
|
|
258
206
|
};
|
|
259
207
|
useWatch(mergedOpen, targetEle, popupEle, triggerAlign, onScroll);
|
|
260
|
-
useLayoutEffect(
|
|
208
|
+
useLayoutEffect(() => {
|
|
261
209
|
triggerAlign();
|
|
262
210
|
}, [mousePos, popupPlacement]);
|
|
263
211
|
|
|
264
212
|
// When no builtinPlacements and popupAlign changed
|
|
265
|
-
useLayoutEffect(
|
|
266
|
-
if (mergedOpen && !
|
|
213
|
+
useLayoutEffect(() => {
|
|
214
|
+
if (mergedOpen && !builtinPlacements?.[popupPlacement]) {
|
|
267
215
|
triggerAlign();
|
|
268
216
|
}
|
|
269
217
|
}, [JSON.stringify(popupAlign)]);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return classNames(baseClassName, getPopupClassNameFromAlign
|
|
218
|
+
const alignedClassName = React.useMemo(() => {
|
|
219
|
+
const baseClassName = getAlignPopupClassName(builtinPlacements, prefixCls, alignInfo, alignPoint);
|
|
220
|
+
return classNames(baseClassName, getPopupClassNameFromAlign?.(alignInfo));
|
|
273
221
|
}, [alignInfo, getPopupClassNameFromAlign, builtinPlacements, prefixCls, alignPoint]);
|
|
274
222
|
|
|
275
223
|
// ============================ Refs ============================
|
|
276
|
-
React.useImperativeHandle(ref,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
};
|
|
282
|
-
});
|
|
224
|
+
React.useImperativeHandle(ref, () => ({
|
|
225
|
+
nativeElement: externalForwardRef.current,
|
|
226
|
+
popupElement: externalPopupRef.current,
|
|
227
|
+
forceAlign: triggerAlign
|
|
228
|
+
}));
|
|
283
229
|
|
|
284
230
|
// ========================== Stretch ===========================
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
setTargetWidth = _React$useState16[1];
|
|
289
|
-
var _React$useState17 = React.useState(0),
|
|
290
|
-
_React$useState18 = _slicedToArray(_React$useState17, 2),
|
|
291
|
-
targetHeight = _React$useState18[0],
|
|
292
|
-
setTargetHeight = _React$useState18[1];
|
|
293
|
-
var syncTargetSize = function syncTargetSize() {
|
|
231
|
+
const [targetWidth, setTargetWidth] = React.useState(0);
|
|
232
|
+
const [targetHeight, setTargetHeight] = React.useState(0);
|
|
233
|
+
const syncTargetSize = () => {
|
|
294
234
|
if (stretch && targetEle) {
|
|
295
|
-
|
|
235
|
+
const rect = targetEle.getBoundingClientRect();
|
|
296
236
|
setTargetWidth(rect.width);
|
|
297
237
|
setTargetHeight(rect.height);
|
|
298
238
|
}
|
|
299
239
|
};
|
|
300
|
-
|
|
240
|
+
const onTargetResize = () => {
|
|
301
241
|
syncTargetSize();
|
|
302
242
|
triggerAlign();
|
|
303
243
|
};
|
|
304
244
|
|
|
305
245
|
// ========================== Motion ============================
|
|
306
|
-
|
|
246
|
+
const onVisibleChanged = visible => {
|
|
307
247
|
setInMotion(false);
|
|
308
248
|
onAlign();
|
|
309
|
-
afterPopupVisibleChange
|
|
249
|
+
afterPopupVisibleChange?.(visible);
|
|
310
250
|
};
|
|
311
251
|
|
|
312
252
|
// We will trigger align when motion is in prepare
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
};
|
|
321
|
-
useLayoutEffect(function () {
|
|
253
|
+
const onPrepare = () => new Promise(resolve => {
|
|
254
|
+
syncTargetSize();
|
|
255
|
+
setMotionPrepareResolve(() => resolve);
|
|
256
|
+
});
|
|
257
|
+
useLayoutEffect(() => {
|
|
322
258
|
if (motionPrepareResolve) {
|
|
323
259
|
onAlign();
|
|
324
260
|
motionPrepareResolve();
|
|
@@ -331,23 +267,18 @@ export function generateTrigger() {
|
|
|
331
267
|
* Util wrapper for trigger action
|
|
332
268
|
*/
|
|
333
269
|
function wrapperAction(eventName, nextOpen, delay, preEvent) {
|
|
334
|
-
cloneProps[eventName] =
|
|
335
|
-
|
|
336
|
-
preEvent === null || preEvent === void 0 || preEvent(event);
|
|
270
|
+
cloneProps[eventName] = (event, ...args) => {
|
|
271
|
+
preEvent?.(event);
|
|
337
272
|
triggerOpen(nextOpen, delay);
|
|
338
273
|
|
|
339
274
|
// Pass to origin
|
|
340
|
-
|
|
341
|
-
args[_key - 1] = arguments[_key];
|
|
342
|
-
}
|
|
343
|
-
(_originChildProps$eve = originChildProps[eventName]) === null || _originChildProps$eve === void 0 || _originChildProps$eve.call.apply(_originChildProps$eve, [originChildProps, event].concat(args));
|
|
275
|
+
originChildProps[eventName]?.(event, ...args);
|
|
344
276
|
};
|
|
345
277
|
}
|
|
346
278
|
|
|
347
279
|
// ======================= Action: Click ========================
|
|
348
280
|
if (clickToShow || clickToHide) {
|
|
349
|
-
cloneProps.onClick =
|
|
350
|
-
var _originChildProps$onC;
|
|
281
|
+
cloneProps.onClick = (event, ...args) => {
|
|
351
282
|
if (openRef.current && clickToHide) {
|
|
352
283
|
triggerOpen(false);
|
|
353
284
|
} else if (!openRef.current && clickToShow) {
|
|
@@ -356,49 +287,45 @@ export function generateTrigger() {
|
|
|
356
287
|
}
|
|
357
288
|
|
|
358
289
|
// Pass to origin
|
|
359
|
-
|
|
360
|
-
args[_key2 - 1] = arguments[_key2];
|
|
361
|
-
}
|
|
362
|
-
(_originChildProps$onC = originChildProps.onClick) === null || _originChildProps$onC === void 0 || _originChildProps$onC.call.apply(_originChildProps$onC, [originChildProps, event].concat(args));
|
|
290
|
+
originChildProps.onClick?.(event, ...args);
|
|
363
291
|
};
|
|
364
292
|
}
|
|
365
293
|
|
|
366
294
|
// Click to hide is special action since click popup element should not hide
|
|
367
|
-
|
|
295
|
+
const onPopupPointerDown = useWinClick(mergedOpen, clickToHide, targetEle, popupEle, mask, maskClosable, inPopupOrChild, triggerOpen);
|
|
368
296
|
|
|
369
297
|
// ======================= Action: Hover ========================
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
298
|
+
const hoverToShow = showActions.has('hover');
|
|
299
|
+
const hoverToHide = hideActions.has('hover');
|
|
300
|
+
let onPopupMouseEnter;
|
|
301
|
+
let onPopupMouseLeave;
|
|
374
302
|
if (hoverToShow) {
|
|
375
303
|
// Compatible with old browser which not support pointer event
|
|
376
|
-
wrapperAction('onMouseEnter', true, mouseEnterDelay,
|
|
304
|
+
wrapperAction('onMouseEnter', true, mouseEnterDelay, event => {
|
|
377
305
|
setMousePosByEvent(event);
|
|
378
306
|
});
|
|
379
|
-
wrapperAction('onPointerEnter', true, mouseEnterDelay,
|
|
307
|
+
wrapperAction('onPointerEnter', true, mouseEnterDelay, event => {
|
|
380
308
|
setMousePosByEvent(event);
|
|
381
309
|
});
|
|
382
|
-
onPopupMouseEnter =
|
|
310
|
+
onPopupMouseEnter = event => {
|
|
383
311
|
// Only trigger re-open when popup is visible
|
|
384
|
-
if ((mergedOpen || inMotion) && popupEle
|
|
312
|
+
if ((mergedOpen || inMotion) && popupEle?.contains(event.target)) {
|
|
385
313
|
triggerOpen(true, mouseEnterDelay);
|
|
386
314
|
}
|
|
387
315
|
};
|
|
388
316
|
|
|
389
317
|
// Align Point
|
|
390
318
|
if (alignPoint) {
|
|
391
|
-
cloneProps.onMouseMove =
|
|
392
|
-
var _originChildProps$onM;
|
|
319
|
+
cloneProps.onMouseMove = event => {
|
|
393
320
|
// setMousePosByEvent(event);
|
|
394
|
-
|
|
321
|
+
originChildProps.onMouseMove?.(event);
|
|
395
322
|
};
|
|
396
323
|
}
|
|
397
324
|
}
|
|
398
325
|
if (hoverToHide) {
|
|
399
326
|
wrapperAction('onMouseLeave', false, mouseLeaveDelay);
|
|
400
327
|
wrapperAction('onPointerLeave', false, mouseLeaveDelay);
|
|
401
|
-
onPopupMouseLeave =
|
|
328
|
+
onPopupMouseLeave = () => {
|
|
402
329
|
triggerOpen(false, mouseLeaveDelay);
|
|
403
330
|
};
|
|
404
331
|
}
|
|
@@ -413,8 +340,7 @@ export function generateTrigger() {
|
|
|
413
340
|
|
|
414
341
|
// ==================== Action: ContextMenu =====================
|
|
415
342
|
if (showActions.has('contextMenu')) {
|
|
416
|
-
cloneProps.onContextMenu =
|
|
417
|
-
var _originChildProps$onC2;
|
|
343
|
+
cloneProps.onContextMenu = (event, ...args) => {
|
|
418
344
|
if (openRef.current && hideActions.has('contextMenu')) {
|
|
419
345
|
triggerOpen(false);
|
|
420
346
|
} else {
|
|
@@ -424,44 +350,41 @@ export function generateTrigger() {
|
|
|
424
350
|
event.preventDefault();
|
|
425
351
|
|
|
426
352
|
// Pass to origin
|
|
427
|
-
|
|
428
|
-
args[_key3 - 1] = arguments[_key3];
|
|
429
|
-
}
|
|
430
|
-
(_originChildProps$onC2 = originChildProps.onContextMenu) === null || _originChildProps$onC2 === void 0 || _originChildProps$onC2.call.apply(_originChildProps$onC2, [originChildProps, event].concat(args));
|
|
353
|
+
originChildProps.onContextMenu?.(event, ...args);
|
|
431
354
|
};
|
|
432
355
|
}
|
|
433
356
|
|
|
434
|
-
// ========================= ClassName ==========================
|
|
435
|
-
if (className) {
|
|
436
|
-
cloneProps.className = classNames(originChildProps.className, className);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
357
|
// =========================== Render ===========================
|
|
440
|
-
|
|
358
|
+
const mergedChildrenProps = {
|
|
359
|
+
...originChildProps,
|
|
360
|
+
...cloneProps
|
|
361
|
+
};
|
|
441
362
|
|
|
442
363
|
// Pass props into cloneProps for nest usage
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
passedEventList.forEach(
|
|
364
|
+
const passedProps = {};
|
|
365
|
+
const passedEventList = ['onContextMenu', 'onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur'];
|
|
366
|
+
passedEventList.forEach(eventName => {
|
|
446
367
|
if (restProps[eventName]) {
|
|
447
|
-
passedProps[eventName] =
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
args[_key4] = arguments[_key4];
|
|
451
|
-
}
|
|
452
|
-
(_mergedChildrenProps$ = mergedChildrenProps[eventName]) === null || _mergedChildrenProps$ === void 0 || _mergedChildrenProps$.call.apply(_mergedChildrenProps$, [mergedChildrenProps].concat(args));
|
|
453
|
-
restProps[eventName].apply(restProps, args);
|
|
368
|
+
passedProps[eventName] = (...args) => {
|
|
369
|
+
mergedChildrenProps[eventName]?.(...args);
|
|
370
|
+
restProps[eventName](...args);
|
|
454
371
|
};
|
|
455
372
|
}
|
|
456
373
|
});
|
|
457
374
|
|
|
458
375
|
// Child Node
|
|
459
|
-
|
|
460
|
-
|
|
376
|
+
const triggerNode = /*#__PURE__*/React.cloneElement(child, {
|
|
377
|
+
...mergedChildrenProps,
|
|
378
|
+
...passedProps
|
|
379
|
+
});
|
|
380
|
+
const arrowPos = {
|
|
461
381
|
x: arrowX,
|
|
462
382
|
y: arrowY
|
|
463
383
|
};
|
|
464
|
-
|
|
384
|
+
const innerArrow = arrow ? {
|
|
385
|
+
// true and Object likely
|
|
386
|
+
...(arrow !== true ? arrow : {})
|
|
387
|
+
} : null;
|
|
465
388
|
|
|
466
389
|
// Render
|
|
467
390
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ResizeObserver, {
|
|
@@ -500,8 +423,8 @@ export function generateTrigger() {
|
|
|
500
423
|
mask: mask
|
|
501
424
|
// Motion
|
|
502
425
|
,
|
|
503
|
-
motion:
|
|
504
|
-
maskMotion:
|
|
426
|
+
motion: popupMotion,
|
|
427
|
+
maskMotion: maskMotion,
|
|
505
428
|
onVisibleChanged: onVisibleChanged,
|
|
506
429
|
onPrepare: onPrepare
|
|
507
430
|
// Portal
|
package/es/interface.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { CSSMotionProps } from 'rc-motion';
|
|
2
|
+
import type { CSSMotionProps } from '@rc-component/motion';
|
|
3
3
|
export type Placement = 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
|
|
4
4
|
export type AlignPointTopBottom = 't' | 'b' | 'c';
|
|
5
5
|
export type AlignPointLeftRight = 'l' | 'r' | 'c';
|