1- import React , { FC , useContext , useState , ReactElement , useMemo , useRef } from 'react' ;
21import classNames from 'classnames' ;
2+ import React , { FC , ReactElement , useContext , useMemo , useRef } from 'react' ;
33import { CSSTransition } from 'react-transition-group' ;
4- import { StyledProps } from '../common' ;
5- import type { TdSubmenuProps } from './type' ;
4+
5+ import parseTNode from '../_util/parseTNode' ;
6+ import FakeArrow from '../common/FakeArrow' ;
67import useConfig from '../hooks/useConfig' ;
7- import { MenuContext } from './MenuContext ' ;
8+ import useControlled from '../hooks/useControlled ' ;
89import useDomRefCallback from '../hooks/useDomRefCallback' ;
910import useRipple from '../hooks/useRipple' ;
10- import { getSubMenuMaxHeight } from './_util/getSubMenuChildStyle' ;
11+ import { Popup , type PopupPlacement } from '../popup' ;
12+ import { calculatePaddingLeft } from './_util/calculatePaddingLeft' ;
13+ import { checkIsMenuGroup , checkIsSubMenu } from './_util/checkMenuType' ;
1114import checkSubMenuChildrenActive from './_util/checkSubMenuChildrenActive' ;
12- import FakeArrow from '../common/FakeArrow ' ;
13- import { checkIsSubMenu , checkIsMenuGroup } from './_util/checkMenuType ' ;
14- import { cacularPaddingLeft } from './_util/cacularPaddingLeft' ;
15- import { Popup , PopupPlacement } from '../popup ' ;
16- import parseTNode from '../_util/parseTNode ' ;
15+ import { getSubMenuMaxHeight } from './_util/getSubMenuChildStyle ' ;
16+ import { MenuContext } from './MenuContext ' ;
17+
18+ import type { StyledProps } from '../common ' ;
19+ import type { TdSubmenuProps } from './type ' ;
1720
1821export interface SubMenuProps extends TdSubmenuProps , StyledProps { }
1922
@@ -25,25 +28,24 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
2528 const { content, children = content , disabled, icon, title, value, className, style, level = 1 , popupProps } = props ;
2629 const { overlayClassName, overlayInnerClassName, ...restPopupProps } = popupProps || { } ;
2730
31+ const [ open , setOpen ] = useControlled ( popupProps , 'visible' , restPopupProps . onVisibleChange ) ;
32+
2833 const { classPrefix } = useConfig ( ) ;
2934
30- // popup 状态下控制开关
31- const [ open , setOpen ] = useState ( false ) ;
3235 const { expanded = [ ] , onExpand, active, expandType, theme = 'light' } = useContext ( MenuContext ) ;
3336
3437 const isPopUp = expandType === 'popup' ;
35-
3638 // 非 popup 展开
3739 const isExpand = expanded . includes ( value ) && ! disabled && ! isPopUp ;
3840
3941 const handleClick = ( e : React . MouseEvent < HTMLDivElement , MouseEvent > ) => {
4042 e . stopPropagation ( ) ;
4143 onExpand ( value , expanded ) ;
42- setOpen ( false ) ;
44+ setOpen ( false , { } ) ;
4345 } ;
4446
45- const handleVisibleChange = ( visible : boolean ) => {
46- setOpen ( visible ) ;
47+ const handleVisibleChange = ( visible : boolean , ctx ) => {
48+ setOpen ( visible , ctx ) ;
4749 } ;
4850
4951 const popupChildren = React . Children . map ( children , ( child ) =>
@@ -70,7 +72,7 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
7072 } , [ disabled , isPopUp , open , isExpand ] ) ;
7173
7274 // 计算左边距,兼容多层级子菜单
73- const menuPaddingLeft = cacularPaddingLeft ( level - 1 ) ;
75+ const menuPaddingLeft = calculatePaddingLeft ( level - 1 ) ;
7476
7577 const fakeArrowStyle = isPopUp && level > 1 ? { transform : 'rotate(-90deg)' } : { } ;
7678
@@ -160,9 +162,9 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
160162 { [ `${ classPrefix } -menu-is-nested` ] : level > 1 } ,
161163 overlayClassName ,
162164 ] }
163- visible = { open }
164165 placement = "right-top"
165166 content = { pupContent }
167+ visible = { open }
166168 onVisibleChange = { handleVisibleChange }
167169 >
168170 { submenu }
@@ -175,17 +177,16 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
175177
176178const SubTitleMenu : FC < SubMenuWithCustomizeProps > = ( props ) => {
177179 const { className, style, children, disabled, icon, title, value, level = 1 , popupProps } = props ;
178-
179180 const { overlayClassName, overlayInnerClassName, ...restPopupProps } = popupProps || { } ;
180181
182+ const [ open , setOpen ] = useControlled ( popupProps , 'visible' , restPopupProps . onVisibleChange ) ;
181183 const { active, onChange, expandType, theme = 'light' } = useContext ( MenuContext ) ;
182184 const { classPrefix } = useConfig ( ) ;
183- const [ open , setOpen ] = useState ( false ) ;
184185
185186 const handleClick = ( ) => onChange ( value ) ;
186187
187- const handleVisibleChange = ( visible : boolean ) => {
188- setOpen ( visible ) ;
188+ const handleVisibleChange = ( visible : boolean , ctx ) => {
189+ setOpen ( visible , ctx ) ;
189190 } ;
190191
191192 // 斜八角动画
@@ -262,9 +263,9 @@ const SubTitleMenu: FC<SubMenuWithCustomizeProps> = (props) => {
262263 { [ `${ classPrefix } -menu-is-nested` ] : level > 1 } ,
263264 overlayClassName ,
264265 ] }
265- visible = { open }
266266 placement = { placement as PopupPlacement }
267267 content = { pupContent }
268+ visible = { open }
268269 onVisibleChange = { handleVisibleChange }
269270 >
270271 { submenu }
0 commit comments