@rc-component/trigger 3.5.2 → 3.6.1

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 +73 -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 +79 -18
  39. package/package.json +1 -1
package/assets/index.css CHANGED
@@ -62,6 +62,41 @@
62
62
  opacity: 0;
63
63
  }
64
64
  }
65
+ .rc-trigger-popup-float-bg {
66
+ position: absolute;
67
+ z-index: 0;
68
+ box-sizing: border-box;
69
+ border: 1px solid red;
70
+ background: green;
71
+ }
72
+ .rc-trigger-popup-float-bg-hidden {
73
+ display: none;
74
+ }
75
+ .rc-trigger-popup-float-bg-visible {
76
+ transition: all 0.1s;
77
+ }
78
+ .rc-trigger-popup-unique-controlled {
79
+ border-color: rgba(0, 0, 0, 0.01) !important;
80
+ background: transparent !important;
81
+ z-index: 1;
82
+ }
83
+ .rc-trigger-popup-motion-content-fade-appear {
84
+ opacity: 0;
85
+ animation-duration: 0.3s;
86
+ animation-fill-mode: both;
87
+ animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
88
+ }
89
+ .rc-trigger-popup-motion-content-fade-appear.rc-trigger-popup-motion-content-fade-appear-active {
90
+ animation-name: rcTriggerFadeIn;
91
+ }
92
+ @keyframes rcTriggerFadeIn {
93
+ 0% {
94
+ opacity: 0;
95
+ }
96
+ 100% {
97
+ opacity: 1;
98
+ }
99
+ }
65
100
  .rc-trigger-popup-mask {
66
101
  position: fixed;
67
102
  top: 0;
package/assets/index.less CHANGED
@@ -73,6 +73,54 @@
73
73
  opacity: 0;
74
74
  }
75
75
  }
76
+
77
+ // =============== Float BG ===============
78
+ &-float-bg {
79
+ position: absolute;
80
+ z-index: 0;
81
+ box-sizing: border-box;
82
+ border: 1px solid red;
83
+ background: green;
84
+
85
+ &-hidden {
86
+ display: none;
87
+ }
88
+
89
+ &-visible {
90
+ transition: all 0.1s;
91
+ }
92
+ }
93
+
94
+ // Debug
95
+ &-unique-controlled {
96
+ border-color: rgba(0, 0, 0, 0.01) !important;
97
+ background: transparent !important;
98
+ z-index: 1;
99
+ }
100
+
101
+ // Motion Content
102
+ &-motion-content {
103
+ // Fade motion
104
+ &-fade-appear {
105
+ opacity: 0;
106
+ animation-duration: 0.3s;
107
+ animation-fill-mode: both;
108
+ animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
109
+ }
110
+
111
+ &-fade-appear&-fade-appear-active {
112
+ animation-name: rcTriggerFadeIn;
113
+ }
114
+
115
+ @keyframes rcTriggerFadeIn {
116
+ 0% {
117
+ opacity: 0;
118
+ }
119
+ 100% {
120
+ opacity: 1;
121
+ }
122
+ }
123
+ }
76
124
  }
77
125
 
78
126
  @import './index/Mask';
@@ -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>>;
package/es/Popup/index.js CHANGED
@@ -8,6 +8,8 @@ import * as React from 'react';
8
8
  import Arrow from "./Arrow";
9
9
  import Mask from "./Mask";
10
10
  import PopupContent from "./PopupContent";
11
+ import useOffsetStyle from "../hooks/useOffsetStyle";
12
+ import { useEvent } from '@rc-component/util';
11
13
  const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
12
14
  const {
13
15
  popup,
@@ -38,6 +40,7 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
38
40
  getPopupContainer,
39
41
  autoDestroy,
40
42
  portal: Portal,
43
+ children,
41
44
  zIndex,
42
45
  onMouseEnter,
43
46
  onMouseLeave,
@@ -50,11 +53,13 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
50
53
  offsetB,
51
54
  onAlign,
52
55
  onPrepare,
56
+ // Resize
57
+ onResize,
53
58
  stretch,
54
59
  targetWidth,
55
60
  targetHeight
56
61
  } = props;
57
- const childNode = typeof popup === 'function' ? popup() : popup;
62
+ const popupContent = typeof popup === 'function' ? popup() : popup;
58
63
 
59
64
  // We can not remove holder only when motion finished.
60
65
  const isNodeVisible = open || keepDom;
@@ -81,44 +86,20 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
81
86
  }
82
87
  }, [show, getPopupContainerNeedParams, target]);
83
88
 
89
+ // ========================= Resize =========================
90
+ const onInternalResize = useEvent((size, ele) => {
91
+ onResize?.(size, ele);
92
+ onAlign();
93
+ });
94
+
95
+ // ========================= Styles =========================
96
+ const offsetStyle = useOffsetStyle(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY);
97
+
84
98
  // ========================= Render =========================
85
99
  if (!show) {
86
100
  return null;
87
101
  }
88
102
 
89
- // >>>>> Offset
90
- const AUTO = 'auto';
91
- const offsetStyle = isMobile ? {} : {
92
- left: '-1000vw',
93
- top: '-1000vh',
94
- right: AUTO,
95
- bottom: AUTO
96
- };
97
-
98
- // Set align style
99
- if (!isMobile && (ready || !open)) {
100
- const {
101
- points
102
- } = align;
103
- const dynamicInset = align.dynamicInset || align._experimental?.dynamicInset;
104
- const alignRight = dynamicInset && points[0][1] === 'r';
105
- const alignBottom = dynamicInset && points[0][0] === 'b';
106
- if (alignRight) {
107
- offsetStyle.right = offsetR;
108
- offsetStyle.left = AUTO;
109
- } else {
110
- offsetStyle.left = offsetX;
111
- offsetStyle.right = AUTO;
112
- }
113
- if (alignBottom) {
114
- offsetStyle.bottom = offsetB;
115
- offsetStyle.top = AUTO;
116
- } else {
117
- offsetStyle.top = offsetY;
118
- offsetStyle.bottom = AUTO;
119
- }
120
- }
121
-
122
103
  // >>>>> Misc
123
104
  const miscStyle = {};
124
105
  if (stretch) {
@@ -148,7 +129,7 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
148
129
  motion: mergedMaskMotion,
149
130
  mobile: isMobile
150
131
  }), /*#__PURE__*/React.createElement(ResizeObserver, {
151
- onResize: onAlign,
132
+ onResize: onInternalResize,
152
133
  disabled: !open
153
134
  }, resizeObserverRef => {
154
135
  return /*#__PURE__*/React.createElement(CSSMotion, _extends({
@@ -198,9 +179,9 @@ const Popup = /*#__PURE__*/React.forwardRef((props, ref) => {
198
179
  align: align
199
180
  }), /*#__PURE__*/React.createElement(PopupContent, {
200
181
  cache: !open && !fresh
201
- }, childNode));
182
+ }, popupContent));
202
183
  });
203
- }));
184
+ }), children);
204
185
  });
205
186
  if (process.env.NODE_ENV !== 'production') {
206
187
  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,62 @@
1
+ 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); }
2
+ import React from 'react';
3
+ import useOffsetStyle from "../hooks/useOffsetStyle";
4
+ import classNames from 'classnames';
5
+ import CSSMotion from '@rc-component/motion';
6
+ const FloatBg = props => {
7
+ const {
8
+ prefixCls,
9
+ isMobile,
10
+ ready,
11
+ open,
12
+ align,
13
+ offsetR,
14
+ offsetB,
15
+ offsetX,
16
+ offsetY,
17
+ popupSize,
18
+ motion
19
+ } = props;
20
+ const floatBgCls = `${prefixCls}-float-bg`;
21
+ const [motionVisible, setMotionVisible] = React.useState(false);
22
+
23
+ // ========================= Styles =========================
24
+ const offsetStyle = useOffsetStyle(isMobile, ready, open, align, offsetR, offsetB, offsetX, offsetY);
25
+
26
+ // Apply popup size if available
27
+ const sizeStyle = {};
28
+ if (popupSize) {
29
+ sizeStyle.width = popupSize.width;
30
+ sizeStyle.height = popupSize.height;
31
+ }
32
+
33
+ // ========================= Render =========================
34
+ return /*#__PURE__*/React.createElement(CSSMotion, _extends({
35
+ motionAppear: true,
36
+ motionEnter: true,
37
+ motionLeave: true,
38
+ removeOnLeave: false,
39
+ leavedClassName: `${floatBgCls}-hidden`
40
+ }, motion, {
41
+ visible: open,
42
+ onVisibleChanged: nextVisible => {
43
+ setMotionVisible(nextVisible);
44
+ }
45
+ }), ({
46
+ className: motionClassName,
47
+ style: motionStyle
48
+ }) => {
49
+ const cls = classNames(floatBgCls, motionClassName, {
50
+ [`${floatBgCls}-visible`]: motionVisible
51
+ });
52
+ return /*#__PURE__*/React.createElement("div", {
53
+ className: cls,
54
+ style: {
55
+ ...offsetStyle,
56
+ ...sizeStyle,
57
+ ...motionStyle
58
+ }
59
+ });
60
+ });
61
+ };
62
+ export 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,32 @@
1
+ import * as React from 'react';
2
+ import CSSMotion from '@rc-component/motion';
3
+ import classNames from 'classnames';
4
+ const MotionContent = props => {
5
+ const {
6
+ prefixCls,
7
+ children
8
+ } = props;
9
+ const childNode = typeof children === 'function' ? children() : children;
10
+
11
+ // motion name: `${prefixCls}-motion-content-fade`, apply in index.less
12
+ const motionName = `${prefixCls}-motion-content-fade`;
13
+ return /*#__PURE__*/React.createElement(CSSMotion, {
14
+ motionAppear: true,
15
+ motionLeave: false,
16
+ visible: true,
17
+ motionName: motionName
18
+ }, ({
19
+ className: motionClassName,
20
+ style: motionStyle
21
+ }) => {
22
+ const cls = classNames(`${prefixCls}-motion-content`, motionClassName);
23
+ return /*#__PURE__*/React.createElement("div", {
24
+ className: cls,
25
+ style: motionStyle
26
+ }, childNode);
27
+ });
28
+ };
29
+ if (process.env.NODE_ENV !== 'production') {
30
+ MotionContent.displayName = 'MotionContent';
31
+ }
32
+ export 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,144 @@
1
+ import * as React from 'react';
2
+ import Portal from '@rc-component/portal';
3
+ import TriggerContext, { UniqueContext } from "../context";
4
+ import useDelay from "../hooks/useDelay";
5
+ import useAlign from "../hooks/useAlign";
6
+ import Popup from "../Popup";
7
+ import { useEvent } from '@rc-component/util';
8
+ import useTargetState from "./useTargetState";
9
+ import { isDOM } from "@rc-component/util/es/Dom/findDOMNode";
10
+ import FloatBg from "./FloatBg";
11
+ import classNames from 'classnames';
12
+ import MotionContent from "./MotionContent";
13
+ const UniqueProvider = ({
14
+ children
15
+ }) => {
16
+ const [trigger, open, options, onTargetVisibleChanged] = useTargetState();
17
+
18
+ // =========================== Popup ============================
19
+ const [popupEle, setPopupEle] = React.useState(null);
20
+ const [popupSize, setPopupSize] = React.useState(null);
21
+
22
+ // Used for forwardRef popup. Not use internal
23
+ const externalPopupRef = React.useRef(null);
24
+ const setPopupRef = useEvent(node => {
25
+ externalPopupRef.current = node;
26
+ if (isDOM(node) && popupEle !== node) {
27
+ setPopupEle(node);
28
+ }
29
+ });
30
+
31
+ // ========================== Register ==========================
32
+ const [popupId, setPopupId] = React.useState(0);
33
+ const delayInvoke = useDelay();
34
+ const show = useEvent(showOptions => {
35
+ delayInvoke(() => {
36
+ if (showOptions.id !== options?.id) {
37
+ setPopupId(i => i + 1);
38
+ }
39
+ trigger(showOptions);
40
+ }, showOptions.delay);
41
+ });
42
+ const hide = delay => {
43
+ delayInvoke(() => {
44
+ trigger(false);
45
+ // Don't clear target, currentNode, options immediately, wait until animation completes
46
+ }, delay);
47
+ };
48
+
49
+ // Callback after animation completes
50
+ const onVisibleChanged = useEvent(visible => {
51
+ // Call useTargetState callback to handle animation state
52
+ onTargetVisibleChanged(visible);
53
+ });
54
+
55
+ // =========================== Align ============================
56
+ const [ready, offsetX, offsetY, offsetR, offsetB, arrowX, arrowY,
57
+
58
+ // scaleX - not used in UniqueProvider
59
+ ,,
60
+ // scaleY - not used in UniqueProvider
61
+ alignInfo, onAlign] = useAlign(open, popupEle, options?.target, options?.popupPlacement, options?.builtinPlacements || {}, options?.popupAlign, undefined,
62
+ // onPopupAlign
63
+ false // isMobile
64
+ );
65
+ const contextValue = React.useMemo(() => ({
66
+ show,
67
+ hide
68
+ }), []);
69
+
70
+ // =========================== Motion ===========================
71
+ const onPrepare = useEvent(() => {
72
+ onAlign();
73
+ return Promise.resolve();
74
+ });
75
+
76
+ // ======================== Trigger Context =====================
77
+ const subPopupElements = React.useRef({});
78
+ const parentContext = React.useContext(TriggerContext);
79
+ const triggerContextValue = React.useMemo(() => ({
80
+ registerSubPopup: (id, subPopupEle) => {
81
+ subPopupElements.current[id] = subPopupEle;
82
+ parentContext?.registerSubPopup(id, subPopupEle);
83
+ }
84
+ }), [parentContext]);
85
+
86
+ // =========================== Render ===========================
87
+ const prefixCls = options?.prefixCls;
88
+ return /*#__PURE__*/React.createElement(UniqueContext.Provider, {
89
+ value: contextValue
90
+ }, children, options && /*#__PURE__*/React.createElement(TriggerContext.Provider, {
91
+ value: triggerContextValue
92
+ }, /*#__PURE__*/React.createElement(Popup, {
93
+ ref: setPopupRef,
94
+ portal: Portal,
95
+ prefixCls: prefixCls,
96
+ popup: /*#__PURE__*/React.createElement(MotionContent, {
97
+ prefixCls: prefixCls,
98
+ key: popupId
99
+ }, options.popup),
100
+ className: classNames(options.popupClassName, `${prefixCls}-unique-controlled`),
101
+ style: options.popupStyle,
102
+ target: options.target,
103
+ open: open,
104
+ keepDom: true,
105
+ fresh: true,
106
+ autoDestroy: false,
107
+ onVisibleChanged: onVisibleChanged,
108
+ ready: ready,
109
+ offsetX: offsetX,
110
+ offsetY: offsetY,
111
+ offsetR: offsetR,
112
+ offsetB: offsetB,
113
+ onAlign: onAlign,
114
+ onPrepare: onPrepare,
115
+ onResize: size => setPopupSize({
116
+ width: size.offsetWidth,
117
+ height: size.offsetHeight
118
+ }),
119
+ arrowPos: {
120
+ x: arrowX,
121
+ y: arrowY
122
+ },
123
+ align: alignInfo,
124
+ zIndex: options.zIndex,
125
+ mask: options.mask,
126
+ arrow: options.arrow,
127
+ motion: options.popupMotion,
128
+ maskMotion: options.maskMotion
129
+ // getPopupContainer={options.getPopupContainer}
130
+ }, /*#__PURE__*/React.createElement(FloatBg, {
131
+ prefixCls: prefixCls,
132
+ isMobile: false,
133
+ ready: ready,
134
+ open: open,
135
+ align: alignInfo,
136
+ offsetR: offsetR,
137
+ offsetB: offsetB,
138
+ offsetX: offsetX,
139
+ offsetY: offsetY,
140
+ popupSize: popupSize,
141
+ motion: options.popupMotion
142
+ }))));
143
+ };
144
+ export 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
+ ];
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { useEvent } from '@rc-component/util';
3
+ /**
4
+ * Control the state of popup bind target:
5
+ * 1. When set `target`. Do show the popup.
6
+ * 2. When `target` is removed. Do hide the popup.
7
+ * 3. When `target` change to another one:
8
+ * a. We wait motion finish of previous popup.
9
+ * b. Then we set new target and show the popup.
10
+ * 4. During appear/enter animation, cache new options and apply after animation completes.
11
+ */
12
+ export default function useTargetState() {
13
+ const [options, setOptions] = React.useState(null);
14
+ const [open, setOpen] = React.useState(false);
15
+ const [isAnimating, setIsAnimating] = React.useState(false);
16
+ const pendingOptionsRef = React.useRef(null);
17
+ const trigger = useEvent(nextOptions => {
18
+ if (nextOptions === false) {
19
+ // Clear pending options when hiding
20
+ pendingOptionsRef.current = null;
21
+ setOpen(false);
22
+ } else {
23
+ if (isAnimating && open) {
24
+ // If animating (appear or enter), cache new options
25
+ pendingOptionsRef.current = nextOptions;
26
+ } else {
27
+ setOpen(true);
28
+ // Set new options
29
+ setOptions(nextOptions);
30
+ pendingOptionsRef.current = null;
31
+
32
+ // Only mark as animating when transitioning from closed to open
33
+ if (!open) {
34
+ setIsAnimating(true);
35
+ }
36
+ }
37
+ }
38
+ });
39
+ const onVisibleChanged = useEvent(visible => {
40
+ if (visible) {
41
+ // Animation enter completed, check if there are pending options
42
+ setIsAnimating(false);
43
+ if (pendingOptionsRef.current) {
44
+ // Apply pending options
45
+ setOptions(pendingOptionsRef.current);
46
+ pendingOptionsRef.current = null;
47
+ }
48
+ } else {
49
+ // Animation leave completed
50
+ setIsAnimating(false);
51
+ pendingOptionsRef.current = null;
52
+ }
53
+ });
54
+ return [trigger, open, options, onVisibleChanged];
55
+ }
package/es/context.d.ts CHANGED
@@ -1,6 +1,33 @@
1
1
  import * as React from 'react';
2
+ import type { CSSMotionProps } from '@rc-component/motion';
3
+ import type { TriggerProps } from './index';
4
+ import type { AlignType, ArrowTypeOuter, BuildInPlacements } from './interface';
2
5
  export interface TriggerContextProps {
3
6
  registerSubPopup: (id: string, node: HTMLElement) => void;
4
7
  }
5
8
  declare const TriggerContext: React.Context<TriggerContextProps>;
6
9
  export default TriggerContext;
10
+ export interface UniqueShowOptions {
11
+ id: string;
12
+ popup: TriggerProps['popup'];
13
+ target: HTMLElement;
14
+ delay: number;
15
+ prefixCls?: string;
16
+ popupClassName?: string;
17
+ popupStyle?: React.CSSProperties;
18
+ popupPlacement?: string;
19
+ builtinPlacements?: BuildInPlacements;
20
+ popupAlign?: AlignType;
21
+ zIndex?: number;
22
+ mask?: boolean;
23
+ maskClosable?: boolean;
24
+ popupMotion?: CSSMotionProps;
25
+ maskMotion?: CSSMotionProps;
26
+ arrow?: ArrowTypeOuter;
27
+ getPopupContainer?: TriggerProps['getPopupContainer'];
28
+ }
29
+ export interface UniqueContextProps {
30
+ show: (options: UniqueShowOptions) => void;
31
+ hide: (delay: number) => void;
32
+ }
33
+ export declare const UniqueContext: React.Context<UniqueContextProps>;
package/es/context.js CHANGED
@@ -1,3 +1,10 @@
1
1
  import * as React from 'react';
2
+
3
+ // ===================== Nest =====================
4
+
2
5
  const TriggerContext = /*#__PURE__*/React.createContext(null);
3
- export default TriggerContext;
6
+ export default TriggerContext;
7
+
8
+ // ==================== Unique ====================
9
+
10
+ export const UniqueContext = /*#__PURE__*/React.createContext(null);
@@ -0,0 +1 @@
1
+ export default function useDelay(): (callback: VoidFunction, delay: number) => void;
@@ -0,0 +1,28 @@
1
+ import * as React from 'react';
2
+ export default function useDelay() {
3
+ const delayRef = React.useRef(null);
4
+ const clearDelay = () => {
5
+ if (delayRef.current) {
6
+ clearTimeout(delayRef.current);
7
+ delayRef.current = null;
8
+ }
9
+ };
10
+ const delayInvoke = (callback, delay) => {
11
+ clearDelay();
12
+ if (delay === 0) {
13
+ callback();
14
+ } else {
15
+ delayRef.current = setTimeout(() => {
16
+ callback();
17
+ }, delay * 1000);
18
+ }
19
+ };
20
+
21
+ // Clean up on unmount
22
+ React.useEffect(() => {
23
+ return () => {
24
+ clearDelay();
25
+ };
26
+ }, []);
27
+ return delayInvoke;
28
+ }
@@ -0,0 +1,3 @@
1
+ import type * as React from 'react';
2
+ import type { AlignType } from '../interface';
3
+ export default function useOffsetStyle(isMobile: boolean, ready: boolean, open: boolean, align: AlignType, offsetR: number, offsetB: number, offsetX: number, offsetY: number): React.CSSProperties;