-
-
Notifications
You must be signed in to change notification settings - Fork 262
Expand file tree
/
Copy pathPopupTrigger.tsx
More file actions
112 lines (100 loc) · 2.73 KB
/
PopupTrigger.tsx
File metadata and controls
112 lines (100 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import * as React from 'react';
import Trigger from 'rc-trigger';
import classNames from 'classnames';
import raf from 'rc-util/lib/raf';
import type { CSSMotionProps } from 'rc-motion';
import { MenuContext } from '../context/MenuContext';
import { placements, placementsRtl } from '../placements';
import type { MenuMode } from '../interface';
import { getMotion } from '../utils/motionUtil';
const popupPlacementMap = {
horizontal: 'bottomLeft',
vertical: 'rightTop',
'vertical-left': 'rightTop',
'vertical-right': 'leftTop',
};
export interface PopupTriggerProps {
prefixCls: string;
mode: MenuMode;
visible: boolean;
children: React.ReactElement;
popup: React.ReactNode;
popupClassName?: string;
popupOffset?: number[];
disabled: boolean;
onVisibleChange: (visible: boolean) => void;
}
export default function PopupTrigger({
prefixCls,
visible,
children,
popup,
popupClassName,
popupOffset,
disabled,
mode,
onVisibleChange,
}: PopupTriggerProps) {
const {
getPopupContainer,
rtl,
subMenuOpenDelay,
subMenuCloseDelay,
builtinPlacements,
triggerSubMenuAction,
forceSubMenuRender,
// Motion
motion,
defaultMotions,
} = React.useContext(MenuContext);
const [innerVisible, setInnerVisible] = React.useState(false);
const placement = rtl
? { ...placementsRtl, ...builtinPlacements }
: { ...placements, ...builtinPlacements };
const popupPlacement = popupPlacementMap[mode];
const targetMotion = getMotion(mode, motion, defaultMotions);
const mergedMotion: CSSMotionProps = {
...targetMotion,
leavedClassName: `${prefixCls}-hidden`,
removeOnLeave: false,
motionAppear: true,
};
// Delay to change visible
const visibleRef = React.useRef<number>();
React.useEffect(() => {
visibleRef.current = raf(() => {
setInnerVisible(visible);
});
return () => {
raf.cancel(visibleRef.current);
};
}, [visible]);
return (
<Trigger
prefixCls={prefixCls}
popupClassName={classNames(
`${prefixCls}-popup`,
{
[`${prefixCls}-rtl`]: rtl,
},
popupClassName,
)}
stretch={mode === 'horizontal' ? 'minWidth' : null}
getPopupContainer={getPopupContainer}
builtinPlacements={placement}
popupPlacement={popupPlacement}
popupVisible={innerVisible}
popup={popup}
popupAlign={popupOffset && { offset: popupOffset }}
action={disabled ? [] : [triggerSubMenuAction]}
mouseEnterDelay={subMenuOpenDelay}
mouseLeaveDelay={subMenuCloseDelay}
onPopupVisibleChange={onVisibleChange}
forceRender={forceSubMenuRender}
popupMotion={mergedMotion}
destroyPopupOnHide={true}
>
{children}
</Trigger>
);
}