-
-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathPopupTrigger.tsx
More file actions
124 lines (111 loc) · 3.16 KB
/
Copy pathPopupTrigger.tsx
File metadata and controls
124 lines (111 loc) · 3.16 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
113
114
115
116
117
118
119
120
121
122
123
124
import * as React from 'react';
import Trigger from '@rc-component/trigger';
import { clsx } from 'clsx';
import { raf } from '@rc-component/util';
import type { CSSMotionProps } from '@rc-component/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;
popupStyle?: React.CSSProperties;
popupClassName?: string;
popupOffset?: number[];
disabled: boolean;
onVisibleChange: (visible: boolean) => void;
}
export default function PopupTrigger({
prefixCls,
visible,
children,
popup,
popupStyle,
popupClassName,
popupOffset,
disabled,
mode,
onVisibleChange,
}: PopupTriggerProps) {
const {
getPopupContainer,
rtl,
subMenuOpenDelay,
subMenuCloseDelay,
builtinPlacements,
triggerSubMenuAction,
forceSubMenuRender,
rootClassName,
// 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 targetMotionRef = React.useRef(targetMotion);
if (mode !== 'inline') {
/**
* PopupTrigger is only used for vertical and horizontal types.
* When collapsed is unfolded, the inline animation will destroy the vertical animation.
*/
targetMotionRef.current = targetMotion;
}
const mergedMotion: CSSMotionProps = {
...targetMotionRef.current,
leavedClassName: `${prefixCls}-hidden`,
removeOnLeave: false,
motionAppear: true,
};
// Delay to change visible
const visibleRef = React.useRef<number | undefined>(undefined);
React.useEffect(() => {
visibleRef.current = raf(() => {
setInnerVisible(visible);
});
return () => {
raf.cancel(visibleRef.current);
};
}, [visible]);
return (
<Trigger
prefixCls={prefixCls}
popupClassName={clsx(
`${prefixCls}-popup`,
{ [`${prefixCls}-rtl`]: rtl },
popupClassName,
rootClassName,
)}
stretch={mode === 'horizontal' ? 'minWidth' : null}
getPopupContainer={getPopupContainer}
builtinPlacements={placement}
popupPlacement={popupPlacement}
popupVisible={innerVisible}
popup={popup}
popupStyle={popupStyle}
popupAlign={popupOffset && { offset: popupOffset }}
action={disabled ? [] : [triggerSubMenuAction]}
mouseEnterDelay={subMenuOpenDelay}
mouseLeaveDelay={subMenuCloseDelay}
onPopupVisibleChange={onVisibleChange}
forceRender={forceSubMenuRender}
popupMotion={mergedMotion}
fresh
>
{children}
</Trigger>
);
}