forked from react-component/menu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInlineSubMenuList.tsx
More file actions
89 lines (76 loc) · 2.49 KB
/
InlineSubMenuList.tsx
File metadata and controls
89 lines (76 loc) · 2.49 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
import * as React from 'react';
import CSSMotion from '@rc-component/motion';
import { getMotion } from '../utils/motionUtil';
import MenuContextProvider, { MenuContext } from '../context/MenuContext';
import SubMenuList from './SubMenuList';
import type { MenuMode } from '../interface';
export interface InlineSubMenuListProps {
id?: string;
open: boolean;
keyPath: string[];
children: React.ReactNode;
}
export default function InlineSubMenuList({
id,
open,
keyPath,
children,
}: InlineSubMenuListProps) {
const fixedMode: MenuMode = 'inline';
const { prefixCls, forceSubMenuRender, motion, defaultMotions, mode } =
React.useContext(MenuContext);
// Always use latest mode check
const sameModeRef = React.useRef(false);
sameModeRef.current = mode === fixedMode;
// We record `destroy` mark here since when mode change from `inline` to others.
// The inline list should remove when motion end.
const [destroy, setDestroy] = React.useState(!sameModeRef.current);
const mergedOpen = sameModeRef.current ? open : false;
// ================================= Effect =================================
// Reset destroy state when mode change back
React.useEffect(() => {
if (sameModeRef.current) {
setDestroy(false);
}
}, [mode]);
// ================================= Render =================================
const mergedMotion = { ...getMotion(fixedMode, motion, defaultMotions) };
// No need appear since nest inlineCollapse changed
if (keyPath.length > 1) {
mergedMotion.motionAppear = false;
}
// Hide inline list when mode changed and motion end
const originOnVisibleChanged = mergedMotion.onVisibleChanged;
mergedMotion.onVisibleChanged = newVisible => {
if (!sameModeRef.current && !newVisible) {
setDestroy(true);
}
return originOnVisibleChanged?.(newVisible);
};
if (destroy) {
return null;
}
return (
<MenuContextProvider mode={fixedMode} locked={!sameModeRef.current}>
<CSSMotion
visible={mergedOpen}
{...mergedMotion}
forceRender={forceSubMenuRender}
removeOnLeave={false}
leavedClassName={`${prefixCls}-hidden`}
>
{({ className: motionClassName, style: motionStyle }) => {
return (
<SubMenuList
id={id}
className={motionClassName}
style={motionStyle}
>
{children}
</SubMenuList>
);
}}
</CSSMotion>
</MenuContextProvider>
);
}