@ioca/react 1.4.74 → 1.4.76

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.
Files changed (101) hide show
  1. package/lib/cjs/components/button/toggle.js +11 -18
  2. package/lib/cjs/components/button/toggle.js.map +1 -1
  3. package/lib/cjs/components/checkbox/checkbox.js +5 -8
  4. package/lib/cjs/components/checkbox/checkbox.js.map +1 -1
  5. package/lib/cjs/components/checkbox/item.js +15 -16
  6. package/lib/cjs/components/checkbox/item.js.map +1 -1
  7. package/lib/cjs/components/collapse/collapse.js +11 -13
  8. package/lib/cjs/components/collapse/collapse.js.map +1 -1
  9. package/lib/cjs/components/form/field.js +16 -20
  10. package/lib/cjs/components/form/field.js.map +1 -1
  11. package/lib/cjs/components/input/input.js +21 -18
  12. package/lib/cjs/components/input/input.js.map +1 -1
  13. package/lib/cjs/components/input/number.js +65 -19
  14. package/lib/cjs/components/input/number.js.map +1 -1
  15. package/lib/cjs/components/input/range.js +10 -13
  16. package/lib/cjs/components/input/range.js.map +1 -1
  17. package/lib/cjs/components/input/textarea.js +4 -7
  18. package/lib/cjs/components/input/textarea.js.map +1 -1
  19. package/lib/cjs/components/picker/colors/footer.js +7 -10
  20. package/lib/cjs/components/picker/colors/footer.js.map +1 -1
  21. package/lib/cjs/components/picker/colors/index.js +23 -21
  22. package/lib/cjs/components/picker/colors/index.js.map +1 -1
  23. package/lib/cjs/components/picker/dates/index.js +9 -12
  24. package/lib/cjs/components/picker/dates/index.js.map +1 -1
  25. package/lib/cjs/components/picker/dates/panel.js +29 -35
  26. package/lib/cjs/components/picker/dates/panel.js.map +1 -1
  27. package/lib/cjs/components/picker/time/index.js +8 -12
  28. package/lib/cjs/components/picker/time/index.js.map +1 -1
  29. package/lib/cjs/components/picker/time/panel.js +38 -21
  30. package/lib/cjs/components/picker/time/panel.js.map +1 -1
  31. package/lib/cjs/components/popconfirm/popconfirm.js +1 -1
  32. package/lib/cjs/components/popconfirm/popconfirm.js.map +1 -1
  33. package/lib/cjs/components/popup/content.js +5 -9
  34. package/lib/cjs/components/popup/content.js.map +1 -1
  35. package/lib/cjs/components/popup/popup.js +388 -157
  36. package/lib/cjs/components/popup/popup.js.map +1 -1
  37. package/lib/cjs/components/radio/radio.js +4 -7
  38. package/lib/cjs/components/radio/radio.js.map +1 -1
  39. package/lib/cjs/components/select/select.js +19 -24
  40. package/lib/cjs/components/select/select.js.map +1 -1
  41. package/lib/cjs/components/tabs/tabs.js +61 -54
  42. package/lib/cjs/components/tabs/tabs.js.map +1 -1
  43. package/lib/cjs/components/tree/tree.js +24 -26
  44. package/lib/cjs/components/tree/tree.js.map +1 -1
  45. package/lib/cjs/components/upload/upload.js +26 -33
  46. package/lib/cjs/components/upload/upload.js.map +1 -1
  47. package/lib/cjs/js/hooks.js +0 -4
  48. package/lib/cjs/js/hooks.js.map +1 -1
  49. package/lib/css/index.css +1 -1
  50. package/lib/css/index.css.map +1 -1
  51. package/lib/es/components/button/toggle.js +12 -19
  52. package/lib/es/components/button/toggle.js.map +1 -1
  53. package/lib/es/components/checkbox/checkbox.js +6 -9
  54. package/lib/es/components/checkbox/checkbox.js.map +1 -1
  55. package/lib/es/components/checkbox/item.js +16 -17
  56. package/lib/es/components/checkbox/item.js.map +1 -1
  57. package/lib/es/components/collapse/collapse.js +12 -14
  58. package/lib/es/components/collapse/collapse.js.map +1 -1
  59. package/lib/es/components/form/field.js +17 -21
  60. package/lib/es/components/form/field.js.map +1 -1
  61. package/lib/es/components/input/input.js +22 -19
  62. package/lib/es/components/input/input.js.map +1 -1
  63. package/lib/es/components/input/number.js +67 -21
  64. package/lib/es/components/input/number.js.map +1 -1
  65. package/lib/es/components/input/range.js +11 -14
  66. package/lib/es/components/input/range.js.map +1 -1
  67. package/lib/es/components/input/textarea.js +5 -8
  68. package/lib/es/components/input/textarea.js.map +1 -1
  69. package/lib/es/components/picker/colors/footer.js +8 -11
  70. package/lib/es/components/picker/colors/footer.js.map +1 -1
  71. package/lib/es/components/picker/colors/index.js +24 -22
  72. package/lib/es/components/picker/colors/index.js.map +1 -1
  73. package/lib/es/components/picker/dates/index.js +9 -12
  74. package/lib/es/components/picker/dates/index.js.map +1 -1
  75. package/lib/es/components/picker/dates/panel.js +30 -36
  76. package/lib/es/components/picker/dates/panel.js.map +1 -1
  77. package/lib/es/components/picker/time/index.js +8 -12
  78. package/lib/es/components/picker/time/index.js.map +1 -1
  79. package/lib/es/components/picker/time/panel.js +39 -22
  80. package/lib/es/components/picker/time/panel.js.map +1 -1
  81. package/lib/es/components/popconfirm/popconfirm.js +1 -1
  82. package/lib/es/components/popconfirm/popconfirm.js.map +1 -1
  83. package/lib/es/components/popup/content.js +6 -10
  84. package/lib/es/components/popup/content.js.map +1 -1
  85. package/lib/es/components/popup/popup.js +390 -159
  86. package/lib/es/components/popup/popup.js.map +1 -1
  87. package/lib/es/components/radio/radio.js +5 -8
  88. package/lib/es/components/radio/radio.js.map +1 -1
  89. package/lib/es/components/select/select.js +19 -24
  90. package/lib/es/components/select/select.js.map +1 -1
  91. package/lib/es/components/tabs/tabs.js +63 -56
  92. package/lib/es/components/tabs/tabs.js.map +1 -1
  93. package/lib/es/components/tree/tree.js +25 -27
  94. package/lib/es/components/tree/tree.js.map +1 -1
  95. package/lib/es/components/upload/upload.js +27 -34
  96. package/lib/es/components/upload/upload.js.map +1 -1
  97. package/lib/es/js/hooks.js +2 -5
  98. package/lib/es/js/hooks.js.map +1 -1
  99. package/lib/index.js +803 -541
  100. package/lib/types/components/popup/type.d.ts +0 -4
  101. package/package.json +100 -99
@@ -1,151 +1,322 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { useRef, useContext, useMemo, useEffect, useLayoutEffect, Children, isValidElement, cloneElement } from 'react';
3
- import { useReactive, useMouseUp, useCreation, useResizeObserver } from '../../js/hooks.js';
2
+ import { debounce } from 'radash';
3
+ import { useRef, useState, useMemo, useEffect, useLayoutEffect, Children, isValidElement, cloneElement } from 'react';
4
+ import { useResizeObserver, useMouseUp } from '../../js/hooks.js';
4
5
  import { getPosition, getPointPosition } from '../../js/utils.js';
5
- import ModalContext from '../modal/context.js';
6
6
  import Content from './content.js';
7
7
 
8
8
  function Popup(props) {
9
- const { visible = false, content, trigger = "hover", gap = 12, offset = 8, fixed, position = "top", showDelay = 16, hideDelay = 12, touchable, arrow = true, align, fitSize, watchResize, clickOutside = true, disabled, style, className, getContainer, children, onVisibleChange, } = props;
9
+ const { visible = false, content, trigger = "hover", gap = 12, offset = 8, position = "top", showDelay = 16, hideDelay = 12, touchable, arrow = true, align = "center", fitSize, disabled, style, className, children, onVisibleChange, } = props;
10
10
  const triggerRef = useRef(null);
11
11
  const contentRef = useRef(null);
12
12
  const timerRef = useRef(null);
13
- const statusRef = useRef("");
14
- const isInModal = useContext(ModalContext);
15
- const refWindow = isInModal || fixed;
16
- const state = useReactive({
17
- show: false,
18
- style: { position: refWindow ? "fixed" : "absolute" },
19
- arrowProps: {},
20
- });
21
- useMouseUp((e) => {
22
- if (!triggerRef.current || !contentRef.current || !clickOutside)
23
- return;
24
- const tar = e.target;
25
- const isContain = triggerRef.current.contains(tar) ||
26
- contentRef.current.contains(tar);
27
- if (!state.show || isContain)
28
- return;
29
- handleToggle(false);
13
+ const afterHideTimerRef = useRef(null);
14
+ const rafRef = useRef(null);
15
+ const [show, setShow] = useState(false);
16
+ const showRef = useRef(false);
17
+ showRef.current = show;
18
+ const latestRef = useRef({
19
+ disabled,
20
+ trigger,
21
+ touchable,
22
+ showDelay,
23
+ hideDelay,
24
+ position,
25
+ gap,
26
+ offset,
27
+ align,
28
+ fitSize,
29
+ onVisibleChange,
30
30
  });
31
+ latestRef.current = {
32
+ disabled,
33
+ trigger,
34
+ touchable,
35
+ showDelay,
36
+ hideDelay,
37
+ position,
38
+ gap,
39
+ offset,
40
+ align,
41
+ fitSize,
42
+ onVisibleChange,
43
+ };
44
+ const phaseRef = useRef("");
45
+ const lastPosRef = useRef(null);
46
+ const lastArrowRef = useRef(null);
47
+ const arrowElRef = useRef(null);
48
+ const pointRef = useRef(null);
31
49
  const clearTimer = () => {
32
50
  if (!timerRef.current)
33
51
  return;
34
52
  clearTimeout(timerRef.current);
35
53
  timerRef.current = null;
36
- statusRef.current = "";
54
+ phaseRef.current = "";
55
+ };
56
+ const clearAllTimers = () => {
57
+ clearTimer();
58
+ if (afterHideTimerRef.current) {
59
+ clearTimeout(afterHideTimerRef.current);
60
+ afterHideTimerRef.current = null;
61
+ }
62
+ if (rafRef.current !== null) {
63
+ cancelAnimationFrame(rafRef.current);
64
+ rafRef.current = null;
65
+ }
66
+ };
67
+ const setContentVisible = (visible) => {
68
+ const el = contentRef.current;
69
+ if (!el)
70
+ return;
71
+ el.style.opacity = visible ? "1" : "0";
72
+ el.style.transform = visible ? "none" : "translate(0, 2px)";
73
+ };
74
+ const ensureBaseStyle = () => {
75
+ const el = contentRef.current;
76
+ if (!el)
77
+ return;
78
+ const pos = "fixed";
79
+ if (el.style.position !== pos)
80
+ el.style.position = pos;
81
+ };
82
+ const applyFitSize = () => {
83
+ const o = latestRef.current;
84
+ const triggerEl = triggerRef.current;
85
+ const contentEl = contentRef.current;
86
+ if (!triggerEl || !contentEl)
87
+ return;
88
+ const vertical = ["top", "bottom"].includes(o.position);
89
+ const key = vertical ? "width" : "height";
90
+ if (!o.fitSize) {
91
+ contentEl.style[key] = "";
92
+ return;
93
+ }
94
+ const size = triggerEl[vertical ? "offsetWidth" : "offsetHeight"];
95
+ contentEl.style[key] =
96
+ typeof size === "number" ? `${size}px` : "";
97
+ };
98
+ const applyArrow = (arrowX, arrowY, arrowPos) => {
99
+ const contentEl = contentRef.current;
100
+ if (!contentEl)
101
+ return;
102
+ const arrowEl = arrowElRef.current ??
103
+ contentEl.querySelector(".i-popup-arrow");
104
+ arrowElRef.current = arrowEl;
105
+ if (!arrowEl)
106
+ return;
107
+ let left = arrowX ?? 0;
108
+ let top = arrowY ?? 0;
109
+ let transform = "";
110
+ switch (arrowPos) {
111
+ case "left":
112
+ left += 2;
113
+ transform = `translate(-100%, -50%) rotate(180deg)`;
114
+ break;
115
+ case "right":
116
+ left -= 2;
117
+ transform = `translate(0, -50%)`;
118
+ break;
119
+ case "top":
120
+ top -= 2;
121
+ transform = `translate(-50%, -50%) rotate(-90deg)`;
122
+ break;
123
+ case "bottom":
124
+ top += 2;
125
+ transform = `translate(-50%, -50%) rotate(90deg)`;
126
+ break;
127
+ }
128
+ const prev = lastArrowRef.current;
129
+ if (prev &&
130
+ prev.left === left &&
131
+ prev.top === top &&
132
+ prev.transform === transform) {
133
+ return;
134
+ }
135
+ lastArrowRef.current = { left, top, transform };
136
+ arrowEl.style.left = `${left}px`;
137
+ arrowEl.style.top = `${top}px`;
138
+ arrowEl.style.transform = transform;
139
+ };
140
+ const applyLeftTop = (left, top) => {
141
+ const contentEl = contentRef.current;
142
+ if (!contentEl)
143
+ return;
144
+ const prev = lastPosRef.current;
145
+ if (prev && prev.left === left && prev.top === top)
146
+ return;
147
+ lastPosRef.current = { left, top };
148
+ contentEl.style.left = `${left}px`;
149
+ contentEl.style.top = `${top}px`;
150
+ };
151
+ const computeRelativePosition = () => {
152
+ const triggerEl = triggerRef.current;
153
+ const contentEl = contentRef.current;
154
+ if (!triggerEl || !contentEl)
155
+ return;
156
+ const o = latestRef.current;
157
+ applyFitSize();
158
+ const [left, top, { arrowX, arrowY, arrowPos }] = getPosition(triggerEl, contentEl, {
159
+ position: o.position,
160
+ gap: o.gap,
161
+ offset: o.offset,
162
+ align: o.align,
163
+ refWindow: true,
164
+ });
165
+ applyLeftTop(left, top);
166
+ applyArrow(arrowX, arrowY, arrowPos);
167
+ };
168
+ const computePointPosition = () => {
169
+ const contentEl = contentRef.current;
170
+ if (!contentEl)
171
+ return;
172
+ const point = pointRef.current;
173
+ if (!point)
174
+ return;
175
+ const [left, top] = getPointPosition(point, contentEl);
176
+ applyLeftTop(left, top);
177
+ };
178
+ const scheduleComputePosition = () => {
179
+ if (!showRef.current)
180
+ return;
181
+ if (rafRef.current !== null)
182
+ return;
183
+ rafRef.current = requestAnimationFrame(() => {
184
+ rafRef.current = null;
185
+ if (!showRef.current)
186
+ return;
187
+ ensureBaseStyle();
188
+ if (latestRef.current.trigger === "contextmenu") {
189
+ computePointPosition();
190
+ return;
191
+ }
192
+ computeRelativePosition();
193
+ });
37
194
  };
38
195
  const handleShow = () => {
39
- if (disabled)
196
+ const opts = latestRef.current;
197
+ if (opts.disabled)
40
198
  return;
41
- if (state.show &&
42
- (trigger !== "hover" || (trigger === "hover" && !touchable))) {
199
+ clearAllTimers();
200
+ if (showRef.current &&
201
+ (opts.trigger !== "hover" ||
202
+ (opts.trigger === "hover" && !opts.touchable))) {
203
+ ensureBaseStyle();
204
+ computeRelativePosition();
205
+ setContentVisible(true);
43
206
  return;
44
207
  }
45
- statusRef.current = "showing";
46
- state.show = true;
208
+ phaseRef.current = "showing";
209
+ if (!showRef.current) {
210
+ lastPosRef.current = null;
211
+ lastArrowRef.current = null;
212
+ arrowElRef.current = null;
213
+ setShow(true);
214
+ }
47
215
  timerRef.current = setTimeout(() => {
48
- if (statusRef.current !== "showing")
216
+ if (phaseRef.current !== "showing")
49
217
  return;
50
- requestAnimationFrame(() => {
51
- if (statusRef.current !== "showing")
218
+ rafRef.current = requestAnimationFrame(() => {
219
+ rafRef.current = null;
220
+ if (phaseRef.current !== "showing")
52
221
  return;
53
- const [left, top, { arrowX, arrowY, arrowPos }] = getPosition(triggerRef.current, contentRef.current, {
54
- position,
55
- gap,
56
- offset,
57
- align,
58
- refWindow,
59
- });
60
- state.style = {
61
- ...state.style,
62
- opacity: 1,
63
- transform: "none",
64
- left,
65
- top,
66
- };
67
- state.arrowProps = {
68
- left: arrowX,
69
- top: arrowY,
70
- pos: arrowPos,
71
- };
72
- onVisibleChange?.(true);
222
+ if (!contentRef.current)
223
+ return;
224
+ ensureBaseStyle();
225
+ if (opts.trigger === "contextmenu") {
226
+ computePointPosition();
227
+ }
228
+ else {
229
+ computeRelativePosition();
230
+ }
231
+ setContentVisible(true);
232
+ opts.onVisibleChange?.(true);
73
233
  clearTimer();
74
- statusRef.current = "";
234
+ phaseRef.current = "";
75
235
  });
76
- }, showDelay);
236
+ }, opts.showDelay);
77
237
  };
78
238
  const handleHide = () => {
79
- if (!state.show)
239
+ if (!showRef.current)
80
240
  return;
81
- statusRef.current = "hiding";
241
+ clearAllTimers();
242
+ phaseRef.current = "hiding";
82
243
  timerRef.current = setTimeout(() => {
83
- if (statusRef.current !== "hiding") {
244
+ if (phaseRef.current !== "hiding") {
84
245
  clearTimer();
85
246
  return;
86
247
  }
87
- state.style = {
88
- ...state.style,
89
- opacity: 0,
90
- transform: "translate(0, 2px)",
91
- };
92
- setTimeout(() => {
93
- state.show = false;
94
- clearTimer();
95
- onVisibleChange?.(false);
96
- statusRef.current = "";
248
+ setContentVisible(false);
249
+ afterHideTimerRef.current = setTimeout(() => {
250
+ afterHideTimerRef.current = null;
251
+ setShow(false);
252
+ clearAllTimers();
253
+ latestRef.current.onVisibleChange?.(false);
254
+ phaseRef.current = "";
97
255
  }, 160);
98
- }, hideDelay);
256
+ }, latestRef.current.hideDelay);
99
257
  };
100
258
  const handleToggle = (action) => {
101
259
  if (action !== undefined) {
102
260
  action ? handleShow() : handleHide();
103
261
  return;
104
262
  }
105
- state.show ? handleHide() : handleShow();
106
- };
107
- const eventMaps = useCreation(() => ({
108
- click: {
109
- onClick: () => handleToggle(true),
110
- },
111
- hover: {
112
- onMouseEnter: () => handleToggle(true),
113
- onMouseLeave: () => handleToggle(false),
114
- },
115
- focus: {
116
- onFocus: () => handleToggle(true),
117
- onBlur: () => handleToggle(false),
118
- },
119
- contextmenu: {
120
- onContextMenu: (e) => {
121
- e.preventDefault();
122
- e.stopPropagation();
123
- if (state.show) {
124
- const [left, top] = getPointPosition(e, contentRef.current);
125
- state.style = {
126
- ...state.style,
127
- left,
128
- top,
129
- };
130
- return;
131
- }
132
- state.show = true;
133
- timerRef.current = setTimeout(() => {
134
- const [left, top] = getPointPosition(e, contentRef.current);
135
- state.style = {
136
- ...state.style,
137
- opacity: 1,
138
- transform: "none",
139
- left,
140
- top,
263
+ showRef.current ? handleHide() : handleShow();
264
+ };
265
+ const hideRef = useRef(handleHide);
266
+ const toggleRef = useRef(handleToggle);
267
+ hideRef.current = handleHide;
268
+ toggleRef.current = handleToggle;
269
+ const doHide = useMemo(() => () => hideRef.current(), []);
270
+ const doToggle = useMemo(() => (action) => toggleRef.current(action), []);
271
+ const eventMaps = useMemo(() => {
272
+ return {
273
+ click: {
274
+ onClick: () => doToggle(true),
275
+ },
276
+ hover: {
277
+ onMouseEnter: () => doToggle(true),
278
+ onMouseLeave: () => doToggle(false),
279
+ },
280
+ focus: {
281
+ onFocus: () => doToggle(true),
282
+ onBlur: () => doToggle(false),
283
+ },
284
+ contextmenu: {
285
+ onContextMenu: (e) => {
286
+ e.preventDefault();
287
+ e.stopPropagation();
288
+ pointRef.current = {
289
+ pageX: e.pageX,
290
+ pageY: e.pageY,
141
291
  };
142
- clearTimer();
143
- onVisibleChange?.(true);
144
- }, showDelay);
292
+ if (showRef.current) {
293
+ ensureBaseStyle();
294
+ computePointPosition();
295
+ return;
296
+ }
297
+ clearAllTimers();
298
+ phaseRef.current = "showing";
299
+ lastPosRef.current = null;
300
+ lastArrowRef.current = null;
301
+ arrowElRef.current = null;
302
+ setShow(true);
303
+ timerRef.current = setTimeout(() => {
304
+ if (phaseRef.current !== "showing")
305
+ return;
306
+ if (!contentRef.current)
307
+ return;
308
+ ensureBaseStyle();
309
+ computePointPosition();
310
+ setContentVisible(true);
311
+ clearTimer();
312
+ latestRef.current.onVisibleChange?.(true);
313
+ phaseRef.current = "";
314
+ }, latestRef.current.showDelay);
315
+ },
145
316
  },
146
- },
147
- none: {},
148
- }), []);
317
+ none: {},
318
+ };
319
+ }, [doToggle]);
149
320
  const contentTouch = useMemo(() => {
150
321
  if (!touchable)
151
322
  return {};
@@ -158,72 +329,132 @@ function Popup(props) {
158
329
  }
159
330
  return events;
160
331
  }, [touchable, trigger]);
161
- const computePosition = () => {
162
- if (!state.show)
163
- return;
164
- const [left, top, { arrowX, arrowY, arrowPos }] = getPosition(triggerRef.current, contentRef.current, {
165
- position,
166
- gap,
167
- offset,
168
- align,
169
- refWindow,
170
- });
171
- Object.assign(state, {
172
- style: { ...state.style, left, top },
173
- arrowProps: { left: arrowX, top: arrowY, pos: arrowPos },
174
- });
175
- };
176
332
  const { observe, unobserve, disconnect } = useResizeObserver();
177
333
  useEffect(() => {
178
- if (trigger === "contextmenu" || !observe)
179
- return;
180
- triggerRef.current && observe(triggerRef.current, computePosition);
181
- if (!watchResize || !contentRef.current)
334
+ if (!observe)
182
335
  return;
183
- observe(contentRef.current, computePosition);
336
+ const triggerEl = triggerRef.current;
337
+ const contentEl = contentRef.current;
338
+ if (triggerEl)
339
+ observe(triggerEl, scheduleComputePosition);
340
+ if (contentEl)
341
+ observe(contentEl, scheduleComputePosition);
184
342
  return () => {
185
- if (!watchResize || !contentRef.current)
186
- return;
187
- unobserve(contentRef.current);
188
- triggerRef.current && unobserve(triggerRef.current);
343
+ if (contentEl)
344
+ unobserve(contentEl);
345
+ if (triggerEl)
346
+ unobserve(triggerEl);
189
347
  disconnect();
190
348
  };
191
- }, [watchResize, contentRef.current, triggerRef.current]);
349
+ }, [trigger, observe, unobserve, disconnect, show]);
192
350
  useLayoutEffect(() => {
193
- if (!fitSize || !state.show)
351
+ if (!show)
194
352
  return;
195
- const vertical = ["top", "bottom"].includes(position);
196
- const size = triggerRef.current?.[vertical ? "offsetWidth" : "offsetHeight"];
197
- state.style = { ...state.style, [vertical ? "width" : "height"]: size };
198
- }, [state.show, fitSize]);
353
+ ensureBaseStyle();
354
+ if (latestRef.current.trigger === "contextmenu") {
355
+ computePointPosition();
356
+ }
357
+ else {
358
+ computeRelativePosition();
359
+ }
360
+ }, [show]);
199
361
  useLayoutEffect(() => {
200
- handleToggle(visible);
362
+ doToggle(visible);
201
363
  }, [visible]);
202
364
  useEffect(() => {
203
365
  return () => {
204
- clearTimer();
366
+ clearAllTimers();
205
367
  };
206
368
  }, []);
207
- return (jsxs(Fragment, { children: [Children.map(children, (child) => {
208
- if (!isValidElement(child))
209
- return;
210
- const { className, ...restProps } = child.props;
211
- Object.keys(eventMaps[trigger]).map((evt) => {
212
- if (!restProps[evt])
213
- return;
214
- const fn = eventMaps[trigger][evt];
215
- eventMaps[trigger][evt] = (e) => {
216
- fn();
217
- restProps[evt](e);
218
- };
219
- });
220
- return cloneElement(child, {
221
- ref: triggerRef,
222
- className,
223
- ...restProps,
224
- ...eventMaps[trigger],
369
+ const mouseUpHandlerRef = useRef(() => { });
370
+ mouseUpHandlerRef.current = (e) => {
371
+ if (!showRef.current)
372
+ return;
373
+ const triggerEl = triggerRef.current;
374
+ const contentEl = contentRef.current;
375
+ if (!triggerEl || !contentEl)
376
+ return;
377
+ const tar = e.target;
378
+ if (triggerEl.contains(tar) || contentEl.contains(tar))
379
+ return;
380
+ doHide();
381
+ };
382
+ const onGlobalMouseUp = useMemo(() => (e) => mouseUpHandlerRef.current(e), []);
383
+ useMouseUp(onGlobalMouseUp);
384
+ useEffect(() => {
385
+ if (!show)
386
+ return;
387
+ if (typeof window === "undefined")
388
+ return;
389
+ const onScrollOrResize = debounce({ delay: 160 }, () => {
390
+ scheduleComputePosition();
391
+ });
392
+ window.addEventListener("scroll", onScrollOrResize, {
393
+ passive: true,
394
+ capture: true,
395
+ });
396
+ return () => {
397
+ window.removeEventListener("scroll", onScrollOrResize, true);
398
+ };
399
+ }, [show]);
400
+ const mergeRefs = (...refs) => {
401
+ return (node) => {
402
+ for (const ref of refs) {
403
+ if (!ref)
404
+ continue;
405
+ if (typeof ref === "function") {
406
+ ref(node);
407
+ }
408
+ else {
409
+ ref.current = node;
410
+ }
411
+ }
412
+ };
413
+ };
414
+ return (jsxs(Fragment, { children: [(() => {
415
+ const events = eventMaps[trigger];
416
+ const items = Children.toArray(children);
417
+ const canAttachRef = (el) => {
418
+ if (!isValidElement(el))
419
+ return false;
420
+ const t = el.type;
421
+ if (typeof t === "string")
422
+ return true;
423
+ if (t?.prototype?.isReactComponent)
424
+ return true;
425
+ if (t?.$$typeof === Symbol.for("react.forward_ref"))
426
+ return true;
427
+ return false;
428
+ };
429
+ if (items.length !== 1) {
430
+ return (jsx("div", { ref: triggerRef, ...events, className: 'i-popup-trigger', style: { display: "inline-block" }, children: children }));
431
+ }
432
+ const only = items[0];
433
+ if (!isValidElement(only) || !canAttachRef(only)) {
434
+ return (jsx("div", { ref: triggerRef, ...events, className: 'i-popup-trigger', style: { display: "inline-block" }, children: only }));
435
+ }
436
+ const { className: childClassName, ...restProps } = only.props;
437
+ const nextProps = { ...restProps };
438
+ for (const evt of Object.keys(events)) {
439
+ const theirs = restProps[evt];
440
+ const ours = events[evt];
441
+ nextProps[evt] =
442
+ typeof theirs === "function"
443
+ ? (e) => {
444
+ ours(e);
445
+ theirs(e);
446
+ }
447
+ : ours;
448
+ }
449
+ return cloneElement(only, {
450
+ ref: mergeRefs(only.ref, triggerRef),
451
+ className: childClassName,
452
+ ...nextProps,
225
453
  });
226
- }), state.show && (jsx(Content, { ref: contentRef, arrow: arrow && trigger !== "contextmenu", style: { ...style, ...state.style }, arrowProps: state.arrowProps, className: className, ...contentTouch, trigger: triggerRef.current, getContainer: getContainer, children: content }))] }));
454
+ })(), show && (jsx(Content, { ref: contentRef, arrow: arrow && trigger !== "contextmenu", style: {
455
+ ...style,
456
+ position: "fixed",
457
+ }, className: className, ...contentTouch, trigger: triggerRef.current, children: content }))] }));
227
458
  }
228
459
 
229
460
  export { Popup as default };