@rc-component/trigger 3.5.2 → 3.6.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.
Files changed (39) hide show
  1. package/assets/index.css +35 -0
  2. package/assets/index.less +48 -0
  3. package/es/Popup/index.d.ts +3 -0
  4. package/es/Popup/index.js +18 -37
  5. package/es/UniqueProvider/FloatBg.d.ts +21 -0
  6. package/es/UniqueProvider/FloatBg.js +62 -0
  7. package/es/UniqueProvider/MotionContent.d.ts +11 -0
  8. package/es/UniqueProvider/MotionContent.js +32 -0
  9. package/es/UniqueProvider/index.d.ts +6 -0
  10. package/es/UniqueProvider/index.js +144 -0
  11. package/es/UniqueProvider/useTargetState.d.ts +16 -0
  12. package/es/UniqueProvider/useTargetState.js +55 -0
  13. package/es/context.d.ts +27 -0
  14. package/es/context.js +8 -1
  15. package/es/hooks/useDelay.d.ts +1 -0
  16. package/es/hooks/useDelay.js +28 -0
  17. package/es/hooks/useOffsetStyle.d.ts +3 -0
  18. package/es/hooks/useOffsetStyle.js +35 -0
  19. package/es/index.d.ts +5 -0
  20. package/es/index.js +71 -18
  21. package/lib/Popup/index.d.ts +3 -0
  22. package/lib/Popup/index.js +18 -37
  23. package/lib/UniqueProvider/FloatBg.d.ts +21 -0
  24. package/lib/UniqueProvider/FloatBg.js +69 -0
  25. package/lib/UniqueProvider/MotionContent.d.ts +11 -0
  26. package/lib/UniqueProvider/MotionContent.js +41 -0
  27. package/lib/UniqueProvider/index.d.ts +6 -0
  28. package/lib/UniqueProvider/index.js +153 -0
  29. package/lib/UniqueProvider/useTargetState.d.ts +16 -0
  30. package/lib/UniqueProvider/useTargetState.js +62 -0
  31. package/lib/context.d.ts +27 -0
  32. package/lib/context.js +5 -2
  33. package/lib/hooks/useDelay.d.ts +1 -0
  34. package/lib/hooks/useDelay.js +36 -0
  35. package/lib/hooks/useOffsetStyle.d.ts +3 -0
  36. package/lib/hooks/useOffsetStyle.js +41 -0
  37. package/lib/index.d.ts +5 -0
  38. package/lib/index.js +77 -18
  39. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ export default function useOffsetStyle(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY) {
2
+ // >>>>> Offset
3
+ const AUTO = 'auto';
4
+ const offsetStyle = isMobile ? {} : {
5
+ left: '-1000vw',
6
+ top: '-1000vh',
7
+ right: AUTO,
8
+ bottom: AUTO
9
+ };
10
+
11
+ // Set align style
12
+ if (!isMobile && (ready || !open)) {
13
+ const {
14
+ points
15
+ } = align;
16
+ const dynamicInset = align.dynamicInset || align._experimental?.dynamicInset;
17
+ const alignRight = dynamicInset && points[0][1] === 'r';
18
+ const alignBottom = dynamicInset && points[0][0] === 'b';
19
+ if (alignRight) {
20
+ offsetStyle.right = offsetR;
21
+ offsetStyle.left = AUTO;
22
+ } else {
23
+ offsetStyle.left = offsetX;
24
+ offsetStyle.right = AUTO;
25
+ }
26
+ if (alignBottom) {
27
+ offsetStyle.bottom = offsetB;
28
+ offsetStyle.top = AUTO;
29
+ } else {
30
+ offsetStyle.top = offsetY;
31
+ offsetStyle.bottom = AUTO;
32
+ }
33
+ }
34
+ return offsetStyle;
35
+ }
package/es/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  import { type MobileConfig } from './Popup';
4
4
  import type { ActionType, AlignType, ArrowTypeOuter, BuildInPlacements } from './interface';
5
5
  export type { ActionType, AlignType, ArrowTypeOuter as ArrowType, BuildInPlacements, };
6
+ export { default as UniqueProvider } from './UniqueProvider';
6
7
  export interface TriggerRef {
7
8
  nativeElement: HTMLElement;
8
9
  popupElement: HTMLDivElement;
@@ -53,6 +54,10 @@ export interface TriggerProps {
53
54
  * Set `fresh` to `false` will always keep update.
54
55
  */
55
56
  fresh?: boolean;
57
+ /**
58
+ * Config with UniqueProvider to shared the floating popup.
59
+ */
60
+ unique?: boolean;
56
61
  arrow?: boolean | ArrowTypeOuter;
57
62
  /**
58
63
  * @private Bump fixed position at bottom in mobile.
package/es/index.js CHANGED
@@ -8,12 +8,14 @@ import useId from "@rc-component/util/es/hooks/useId";
8
8
  import useLayoutEffect from "@rc-component/util/es/hooks/useLayoutEffect";
9
9
  import * as React from 'react';
10
10
  import Popup from "./Popup";
11
- import TriggerContext from "./context";
11
+ import TriggerContext, { UniqueContext } from "./context";
12
12
  import useAction from "./hooks/useAction";
13
13
  import useAlign from "./hooks/useAlign";
14
+ import useDelay from "./hooks/useDelay";
14
15
  import useWatch from "./hooks/useWatch";
15
16
  import useWinClick from "./hooks/useWinClick";
16
17
  import { getAlignPopupClassName } from "./util";
18
+ export { default as UniqueProvider } from "./UniqueProvider";
17
19
 
18
20
  // Removed Props List
19
21
  // Seems this can be auto
@@ -60,6 +62,7 @@ export function generateTrigger(PortalComponent = Portal) {
60
62
  stretch,
61
63
  getPopupClassNameFromAlign,
62
64
  fresh,
65
+ unique,
63
66
  alignPoint,
64
67
  onPopupClick,
65
68
  onPopupAlign,
@@ -73,6 +76,7 @@ export function generateTrigger(PortalComponent = Portal) {
73
76
  ...restProps
74
77
  } = props;
75
78
  const mergedAutoDestroy = autoDestroy || false;
79
+ const openUncontrolled = popupVisible === undefined;
76
80
 
77
81
  // =========================== Mobile ===========================
78
82
  const isMobile = !!mobile;
@@ -89,6 +93,9 @@ export function generateTrigger(PortalComponent = Portal) {
89
93
  };
90
94
  }, [parentContext]);
91
95
 
96
+ // ======================== UniqueContext =========================
97
+ const uniqueContext = React.useContext(UniqueContext);
98
+
92
99
  // =========================== Popup ============================
93
100
  const id = useId();
94
101
  const [popupEle, setPopupEle] = React.useState(null);
@@ -125,6 +132,12 @@ export function generateTrigger(PortalComponent = Portal) {
125
132
  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);
126
133
  });
127
134
 
135
+ // =========================== Arrow ============================
136
+ const innerArrow = arrow ? {
137
+ // true and Object likely
138
+ ...(arrow !== true ? arrow : {})
139
+ } : null;
140
+
128
141
  // ============================ Open ============================
129
142
  const [internalOpen, setInternalOpen] = React.useState(defaultPopupVisible || false);
130
143
 
@@ -133,13 +146,48 @@ export function generateTrigger(PortalComponent = Portal) {
133
146
 
134
147
  // We use effect sync here in case `popupVisible` back to `undefined`
135
148
  const setMergedOpen = useEvent(nextOpen => {
136
- if (popupVisible === undefined) {
149
+ if (openUncontrolled) {
137
150
  setInternalOpen(nextOpen);
138
151
  }
139
152
  });
140
153
  useLayoutEffect(() => {
141
154
  setInternalOpen(popupVisible || false);
142
155
  }, [popupVisible]);
156
+
157
+ // Extract common options for UniqueProvider
158
+ const getUniqueOptions = useEvent((delay = 0) => ({
159
+ popup,
160
+ target: targetEle,
161
+ delay,
162
+ prefixCls,
163
+ popupClassName,
164
+ popupStyle,
165
+ popupPlacement,
166
+ builtinPlacements,
167
+ popupAlign,
168
+ zIndex,
169
+ mask,
170
+ maskClosable,
171
+ popupMotion,
172
+ maskMotion,
173
+ arrow: innerArrow,
174
+ getPopupContainer,
175
+ id
176
+ }));
177
+
178
+ // Handle controlled state changes for UniqueProvider
179
+ // Only sync to UniqueProvider when it's controlled mode
180
+ useLayoutEffect(() => {
181
+ if (uniqueContext && unique && targetEle && !openUncontrolled) {
182
+ if (mergedOpen) {
183
+ Promise.resolve().then(() => {
184
+ uniqueContext.show(getUniqueOptions(0));
185
+ });
186
+ } else {
187
+ uniqueContext.hide(0);
188
+ }
189
+ }
190
+ }, [mergedOpen]);
143
191
  const openRef = React.useRef(mergedOpen);
144
192
  openRef.current = mergedOpen;
145
193
  const lastTriggerRef = React.useRef([]);
@@ -158,21 +206,30 @@ export function generateTrigger(PortalComponent = Portal) {
158
206
  });
159
207
 
160
208
  // Trigger for delay
161
- const delayRef = React.useRef(null);
162
- const clearDelay = () => {
163
- clearTimeout(delayRef.current);
164
- };
209
+ const delayInvoke = useDelay();
165
210
  const triggerOpen = (nextOpen, delay = 0) => {
166
- clearDelay();
167
- if (delay === 0) {
168
- internalTriggerOpen(nextOpen);
169
- } else {
170
- delayRef.current = setTimeout(() => {
211
+ // If it's controlled mode, always use internal trigger logic
212
+ // UniqueProvider will be synced through useLayoutEffect
213
+ if (popupVisible !== undefined) {
214
+ delayInvoke(() => {
171
215
  internalTriggerOpen(nextOpen);
172
- }, delay * 1000);
216
+ }, delay);
217
+ return;
173
218
  }
219
+
220
+ // If UniqueContext exists and not controlled, pass delay to Provider instead of handling it internally
221
+ if (uniqueContext && unique && openUncontrolled) {
222
+ if (nextOpen) {
223
+ uniqueContext.show(getUniqueOptions(delay));
224
+ } else {
225
+ uniqueContext.hide(delay);
226
+ }
227
+ return;
228
+ }
229
+ delayInvoke(() => {
230
+ internalTriggerOpen(nextOpen);
231
+ }, delay);
174
232
  };
175
- React.useEffect(() => clearDelay, []);
176
233
 
177
234
  // ========================== Motion ============================
178
235
  const [inMotion, setInMotion] = React.useState(false);
@@ -408,10 +465,6 @@ export function generateTrigger(PortalComponent = Portal) {
408
465
  x: arrowX,
409
466
  y: arrowY
410
467
  };
411
- const innerArrow = arrow ? {
412
- // true and Object likely
413
- ...(arrow !== true ? arrow : {})
414
- } : null;
415
468
 
416
469
  // Child Node
417
470
  const triggerNode = /*#__PURE__*/React.cloneElement(child, {
@@ -424,7 +477,7 @@ export function generateTrigger(PortalComponent = Portal) {
424
477
  disabled: !mergedOpen,
425
478
  ref: setTargetRef,
426
479
  onResize: onTargetResize
427
- }, triggerNode), rendedRef.current && /*#__PURE__*/React.createElement(TriggerContext.Provider, {
480
+ }, triggerNode), rendedRef.current && (!uniqueContext || !unique) && /*#__PURE__*/React.createElement(TriggerContext.Provider, {
428
481
  value: context
429
482
  }, /*#__PURE__*/React.createElement(Popup, {
430
483
  portal: PortalComponent,
@@ -1,4 +1,5 @@
1
1
  import type { CSSMotionProps } from '@rc-component/motion';
2
+ import { type ResizeObserverProps } from '@rc-component/resize-observer';
2
3
  import * as React from 'react';
3
4
  import type { TriggerProps } from '../';
4
5
  import type { AlignType, ArrowPos, ArrowTypeOuter } from '../interface';
@@ -36,6 +37,7 @@ export interface PopupProps {
36
37
  getPopupContainer?: TriggerProps['getPopupContainer'];
37
38
  autoDestroy?: boolean;
38
39
  portal: React.ComponentType<any>;
40
+ children?: React.ReactElement;
39
41
  ready: boolean;
40
42
  offsetX: number;
41
43
  offsetY: number;
@@ -46,6 +48,7 @@ export interface PopupProps {
46
48
  stretch?: string;
47
49
  targetWidth?: number;
48
50
  targetHeight?: number;
51
+ onResize?: ResizeObserverProps['onResize'];
49
52
  mobile?: MobileConfig;
50
53
  }
51
54
  declare const Popup: React.ForwardRefExoticComponent<PopupProps & React.RefAttributes<HTMLDivElement>>;
@@ -13,6 +13,8 @@ var React = _interopRequireWildcard(require("react"));
13
13
  var _Arrow = _interopRequireDefault(require("./Arrow"));
14
14
  var _Mask = _interopRequireDefault(require("./Mask"));
15
15
  var _PopupContent = _interopRequireDefault(require("./PopupContent"));
16
+ var _useOffsetStyle = _interopRequireDefault(require("../hooks/useOffsetStyle"));
17
+ var _util = require("@rc-component/util");
16
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
19
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -47,6 +49,7 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
47
49
  getPopupContainer,
48
50
  autoDestroy,
49
51
  portal: Portal,
52
+ children,
50
53
  zIndex,
51
54
  onMouseEnter,
52
55
  onMouseLeave,
@@ -59,11 +62,13 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
59
62
  offsetB,
60
63
  onAlign,
61
64
  onPrepare,
65
+ // Resize
66
+ onResize,
62
67
  stretch,
63
68
  targetWidth,
64
69
  targetHeight
65
70
  } = props;
66
- const childNode = typeof popup === 'function' ? popup() : popup;
71
+ const popupContent = typeof popup === 'function' ? popup() : popup;
67
72
 
68
73
  // We can not remove holder only when motion finished.
69
74
  const isNodeVisible = open || keepDom;
@@ -90,44 +95,20 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
90
95
  }
91
96
  }, [show, getPopupContainerNeedParams, target]);
92
97
 
98
+ // ========================= Resize =========================
99
+ const onInternalResize = (0, _util.useEvent)((size, ele) => {
100
+ onResize?.(size, ele);
101
+ onAlign();
102
+ });
103
+
104
+ // ========================= Styles =========================
105
+ const offsetStyle = (0, _useOffsetStyle.default)(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY);
106
+
93
107
  // ========================= Render =========================
94
108
  if (!show) {
95
109
  return null;
96
110
  }
97
111
 
98
- // >>>>> Offset
99
- const AUTO = 'auto';
100
- const offsetStyle = isMobile ? {} : {
101
- left: '-1000vw',
102
- top: '-1000vh',
103
- right: AUTO,
104
- bottom: AUTO
105
- };
106
-
107
- // Set align style
108
- if (!isMobile && (ready || !open)) {
109
- const {
110
- points
111
- } = align;
112
- const dynamicInset = align.dynamicInset || align._experimental?.dynamicInset;
113
- const alignRight = dynamicInset && points[0][1] === 'r';
114
- const alignBottom = dynamicInset && points[0][0] === 'b';
115
- if (alignRight) {
116
- offsetStyle.right = offsetR;
117
- offsetStyle.left = AUTO;
118
- } else {
119
- offsetStyle.left = offsetX;
120
- offsetStyle.right = AUTO;
121
- }
122
- if (alignBottom) {
123
- offsetStyle.bottom = offsetB;
124
- offsetStyle.top = AUTO;
125
- } else {
126
- offsetStyle.top = offsetY;
127
- offsetStyle.bottom = AUTO;
128
- }
129
- }
130
-
131
112
  // >>>>> Misc
132
113
  const miscStyle = {};
133
114
  if (stretch) {
@@ -157,7 +138,7 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
157
138
  motion: mergedMaskMotion,
158
139
  mobile: isMobile
159
140
  }), /*#__PURE__*/React.createElement(_resizeObserver.default, {
160
- onResize: onAlign,
141
+ onResize: onInternalResize,
161
142
  disabled: !open
162
143
  }, resizeObserverRef => {
163
144
  return /*#__PURE__*/React.createElement(_motion.default, _extends({
@@ -207,9 +188,9 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
207
188
  align: align
208
189
  }), /*#__PURE__*/React.createElement(_PopupContent.default, {
209
190
  cache: !open && !fresh
210
- }, childNode));
191
+ }, popupContent));
211
192
  });
212
- }));
193
+ }), children);
213
194
  });
214
195
  if (process.env.NODE_ENV !== 'production') {
215
196
  Popup.displayName = 'Popup';
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import type { CSSMotionProps } from '@rc-component/motion';
3
+ import type { AlignType } from '../interface';
4
+ export interface FloatBgProps {
5
+ prefixCls: string;
6
+ isMobile: boolean;
7
+ ready: boolean;
8
+ open: boolean;
9
+ align: AlignType;
10
+ offsetR: number;
11
+ offsetB: number;
12
+ offsetX: number;
13
+ offsetY: number;
14
+ popupSize?: {
15
+ width: number;
16
+ height: number;
17
+ };
18
+ motion?: CSSMotionProps;
19
+ }
20
+ declare const FloatBg: (props: FloatBgProps) => React.JSX.Element;
21
+ export default FloatBg;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _useOffsetStyle = _interopRequireDefault(require("../hooks/useOffsetStyle"));
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ var _motion = _interopRequireDefault(require("@rc-component/motion"));
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
13
+ const FloatBg = props => {
14
+ const {
15
+ prefixCls,
16
+ isMobile,
17
+ ready,
18
+ open,
19
+ align,
20
+ offsetR,
21
+ offsetB,
22
+ offsetX,
23
+ offsetY,
24
+ popupSize,
25
+ motion
26
+ } = props;
27
+ const floatBgCls = `${prefixCls}-float-bg`;
28
+ const [motionVisible, setMotionVisible] = _react.default.useState(false);
29
+
30
+ // ========================= Styles =========================
31
+ const offsetStyle = (0, _useOffsetStyle.default)(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY);
32
+
33
+ // Apply popup size if available
34
+ const sizeStyle = {};
35
+ if (popupSize) {
36
+ sizeStyle.width = popupSize.width;
37
+ sizeStyle.height = popupSize.height;
38
+ }
39
+
40
+ // ========================= Render =========================
41
+ return /*#__PURE__*/_react.default.createElement(_motion.default, _extends({
42
+ motionAppear: true,
43
+ motionEnter: true,
44
+ motionLeave: true,
45
+ removeOnLeave: false,
46
+ leavedClassName: `${floatBgCls}-hidden`
47
+ }, motion, {
48
+ visible: open,
49
+ onVisibleChanged: nextVisible => {
50
+ setMotionVisible(nextVisible);
51
+ }
52
+ }), ({
53
+ className: motionClassName,
54
+ style: motionStyle
55
+ }) => {
56
+ const cls = (0, _classnames.default)(floatBgCls, motionClassName, {
57
+ [`${floatBgCls}-visible`]: motionVisible
58
+ });
59
+ return /*#__PURE__*/_react.default.createElement("div", {
60
+ className: cls,
61
+ style: {
62
+ ...offsetStyle,
63
+ ...sizeStyle,
64
+ ...motionStyle
65
+ }
66
+ });
67
+ });
68
+ };
69
+ var _default = exports.default = FloatBg;
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import type { TriggerProps } from '..';
3
+ export interface MotionContentProps {
4
+ prefixCls: string;
5
+ children: TriggerProps['popup'];
6
+ }
7
+ declare const MotionContent: {
8
+ (props: MotionContentProps): React.JSX.Element;
9
+ displayName: string;
10
+ };
11
+ export default MotionContent;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _motion = _interopRequireDefault(require("@rc-component/motion"));
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ const MotionContent = props => {
14
+ const {
15
+ prefixCls,
16
+ children
17
+ } = props;
18
+ const childNode = typeof children === 'function' ? children() : children;
19
+
20
+ // motion name: `${prefixCls}-motion-content-fade`, apply in index.less
21
+ const motionName = `${prefixCls}-motion-content-fade`;
22
+ return /*#__PURE__*/React.createElement(_motion.default, {
23
+ motionAppear: true,
24
+ motionLeave: false,
25
+ visible: true,
26
+ motionName: motionName
27
+ }, ({
28
+ className: motionClassName,
29
+ style: motionStyle
30
+ }) => {
31
+ const cls = (0, _classnames.default)(`${prefixCls}-motion-content`, motionClassName);
32
+ return /*#__PURE__*/React.createElement("div", {
33
+ className: cls,
34
+ style: motionStyle
35
+ }, childNode);
36
+ });
37
+ };
38
+ if (process.env.NODE_ENV !== 'production') {
39
+ MotionContent.displayName = 'MotionContent';
40
+ }
41
+ var _default = exports.default = MotionContent;
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export interface UniqueProviderProps {
3
+ children: React.ReactNode;
4
+ }
5
+ declare const UniqueProvider: ({ children }: UniqueProviderProps) => React.JSX.Element;
6
+ export default UniqueProvider;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _portal = _interopRequireDefault(require("@rc-component/portal"));
9
+ var _context = _interopRequireWildcard(require("../context"));
10
+ var _useDelay = _interopRequireDefault(require("../hooks/useDelay"));
11
+ var _useAlign = _interopRequireDefault(require("../hooks/useAlign"));
12
+ var _Popup = _interopRequireDefault(require("../Popup"));
13
+ var _util = require("@rc-component/util");
14
+ var _useTargetState = _interopRequireDefault(require("./useTargetState"));
15
+ var _findDOMNode = require("@rc-component/util/lib/Dom/findDOMNode");
16
+ var _FloatBg = _interopRequireDefault(require("./FloatBg"));
17
+ var _classnames = _interopRequireDefault(require("classnames"));
18
+ var _MotionContent = _interopRequireDefault(require("./MotionContent"));
19
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
22
+ const UniqueProvider = ({
23
+ children
24
+ }) => {
25
+ const [trigger, open, options, onTargetVisibleChanged] = (0, _useTargetState.default)();
26
+
27
+ // =========================== Popup ============================
28
+ const [popupEle, setPopupEle] = React.useState(null);
29
+ const [popupSize, setPopupSize] = React.useState(null);
30
+
31
+ // Used for forwardRef popup. Not use internal
32
+ const externalPopupRef = React.useRef(null);
33
+ const setPopupRef = (0, _util.useEvent)(node => {
34
+ externalPopupRef.current = node;
35
+ if ((0, _findDOMNode.isDOM)(node) && popupEle !== node) {
36
+ setPopupEle(node);
37
+ }
38
+ });
39
+
40
+ // ========================== Register ==========================
41
+ const [popupId, setPopupId] = React.useState(0);
42
+ const delayInvoke = (0, _useDelay.default)();
43
+ const show = (0, _util.useEvent)(showOptions => {
44
+ delayInvoke(() => {
45
+ if (showOptions.id !== options?.id) {
46
+ setPopupId(i => i + 1);
47
+ }
48
+ trigger(showOptions);
49
+ }, showOptions.delay);
50
+ });
51
+ const hide = delay => {
52
+ delayInvoke(() => {
53
+ trigger(false);
54
+ // Don't clear target, currentNode, options immediately, wait until animation completes
55
+ }, delay);
56
+ };
57
+
58
+ // Callback after animation completes
59
+ const onVisibleChanged = (0, _util.useEvent)(visible => {
60
+ // Call useTargetState callback to handle animation state
61
+ onTargetVisibleChanged(visible);
62
+ });
63
+
64
+ // =========================== Align ============================
65
+ const [ready, offsetX, offsetY, offsetR, offsetB, arrowX, arrowY,
66
+
67
+ // scaleX - not used in UniqueProvider
68
+ ,,
69
+ // scaleY - not used in UniqueProvider
70
+ alignInfo, onAlign] = (0, _useAlign.default)(open, popupEle, options?.target, options?.popupPlacement, options?.builtinPlacements || {}, options?.popupAlign, undefined,
71
+ // onPopupAlign
72
+ false // isMobile
73
+ );
74
+ const contextValue = React.useMemo(() => ({
75
+ show,
76
+ hide
77
+ }), []);
78
+
79
+ // =========================== Motion ===========================
80
+ const onPrepare = (0, _util.useEvent)(() => {
81
+ onAlign();
82
+ return Promise.resolve();
83
+ });
84
+
85
+ // ======================== Trigger Context =====================
86
+ const subPopupElements = React.useRef({});
87
+ const parentContext = React.useContext(_context.default);
88
+ const triggerContextValue = React.useMemo(() => ({
89
+ registerSubPopup: (id, subPopupEle) => {
90
+ subPopupElements.current[id] = subPopupEle;
91
+ parentContext?.registerSubPopup(id, subPopupEle);
92
+ }
93
+ }), [parentContext]);
94
+
95
+ // =========================== Render ===========================
96
+ const prefixCls = options?.prefixCls;
97
+ return /*#__PURE__*/React.createElement(_context.UniqueContext.Provider, {
98
+ value: contextValue
99
+ }, children, options && /*#__PURE__*/React.createElement(_context.default.Provider, {
100
+ value: triggerContextValue
101
+ }, /*#__PURE__*/React.createElement(_Popup.default, {
102
+ ref: setPopupRef,
103
+ portal: _portal.default,
104
+ prefixCls: prefixCls,
105
+ popup: /*#__PURE__*/React.createElement(_MotionContent.default, {
106
+ prefixCls: prefixCls,
107
+ key: popupId
108
+ }, options.popup),
109
+ className: (0, _classnames.default)(options.popupClassName, `${prefixCls}-unique-controlled`),
110
+ style: options.popupStyle,
111
+ target: options.target,
112
+ open: open,
113
+ keepDom: true,
114
+ fresh: true,
115
+ autoDestroy: false,
116
+ onVisibleChanged: onVisibleChanged,
117
+ ready: ready,
118
+ offsetX: offsetX,
119
+ offsetY: offsetY,
120
+ offsetR: offsetR,
121
+ offsetB: offsetB,
122
+ onAlign: onAlign,
123
+ onPrepare: onPrepare,
124
+ onResize: size => setPopupSize({
125
+ width: size.offsetWidth,
126
+ height: size.offsetHeight
127
+ }),
128
+ arrowPos: {
129
+ x: arrowX,
130
+ y: arrowY
131
+ },
132
+ align: alignInfo,
133
+ zIndex: options.zIndex,
134
+ mask: options.mask,
135
+ arrow: options.arrow,
136
+ motion: options.popupMotion,
137
+ maskMotion: options.maskMotion,
138
+ getPopupContainer: options.getPopupContainer
139
+ }, /*#__PURE__*/React.createElement(_FloatBg.default, {
140
+ prefixCls: prefixCls,
141
+ isMobile: false,
142
+ ready: ready,
143
+ open: open,
144
+ align: alignInfo,
145
+ offsetR: offsetR,
146
+ offsetB: offsetB,
147
+ offsetX: offsetX,
148
+ offsetY: offsetY,
149
+ popupSize: popupSize,
150
+ motion: options.popupMotion
151
+ }))));
152
+ };
153
+ var _default = exports.default = UniqueProvider;
@@ -0,0 +1,16 @@
1
+ import type { UniqueShowOptions } from '../context';
2
+ /**
3
+ * Control the state of popup bind target:
4
+ * 1. When set `target`. Do show the popup.
5
+ * 2. When `target` is removed. Do hide the popup.
6
+ * 3. When `target` change to another one:
7
+ * a. We wait motion finish of previous popup.
8
+ * b. Then we set new target and show the popup.
9
+ * 4. During appear/enter animation, cache new options and apply after animation completes.
10
+ */
11
+ export default function useTargetState(): [
12
+ trigger: (options: UniqueShowOptions | false) => void,
13
+ open: boolean,
14
+ cacheOptions: UniqueShowOptions | null,
15
+ onVisibleChanged: (visible: boolean) => void
16
+ ];