@@ -4,7 +4,7 @@ import { isNull, isNumber, isUndefined, nth } from 'lodash';
44import React , { useImperativeHandle , useRef , useState } from 'react' ;
55import ReactDOM from 'react-dom' ;
66
7- import { useEvent , useEventCallback , useId , useRefExtra } from '@react-devui/hooks' ;
7+ import { useEvent , useEventCallback , useId , useImmer , useRefExtra } from '@react-devui/hooks' ;
88import { getClassName , getVerticalSidePosition , scrollToView } from '@react-devui/utils' ;
99
1010import { useMaxIndex , useDValue } from '../../hooks' ;
@@ -42,10 +42,9 @@ export interface DDropdownProps<ID extends DId, T extends DDropdownItem<ID>>
4242 dPlacement ?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' ;
4343 dTrigger ?: 'hover' | 'click' ;
4444 dArrow ?: boolean ;
45- dCloseOnClick ?: boolean ;
4645 dZIndex ?: number | string ;
4746 onVisibleChange ?: ( visible : boolean ) => void ;
48- onItemClick ?: ( id : T [ 'id' ] , item : T ) => void ;
47+ onItemClick ?: ( id : T [ 'id' ] , item : T ) => void | boolean | Promise < void > ;
4948 afterVisibleChange ?: ( visible : boolean ) => void ;
5049}
5150
@@ -61,7 +60,6 @@ function Dropdown<ID extends DId, T extends DDropdownItem<ID>>(
6160 dPlacement = 'bottom-right' ,
6261 dTrigger = 'hover' ,
6362 dArrow = false ,
64- dCloseOnClick = true ,
6563 dZIndex,
6664 onVisibleChange,
6765 onItemClick,
@@ -103,6 +101,8 @@ function Dropdown<ID extends DId, T extends DDropdownItem<ID>>(
103101 const triggerId = children . props . id ?? `${ dPrefix } dropdown-trigger-${ uniqueId } ` ;
104102 const getItemId = ( id : ID ) => `${ dPrefix } dropdown-item-${ id } -${ uniqueId } ` ;
105103
104+ const [ loadingIds , setLoadingIds ] = useImmer ( new Set < ID > ( ) ) ;
105+
106106 const { popupIds, setPopupIds, addPopupId, removePopupId } = useNestedPopup < ID > ( ) ;
107107 const [ focusIds , setFocusIds ] = useState < ID [ ] > ( [ ] ) ;
108108 const [ isFocus , setIsFocus ] = useState ( false ) ;
@@ -237,10 +237,19 @@ function Dropdown<ID extends DId, T extends DDropdownItem<ID>>(
237237 const popupState = popupIds . find ( ( v ) => v . id === itemId ) ;
238238
239239 const handleItemClick = ( ) => {
240- onItemClick ?.( itemId , item ) ;
240+ const shouldClose = onItemClick ?.( itemId , item ) ;
241241
242242 setFocusIds ( subParents . map ( ( parentItem ) => parentItem . id ) . concat ( [ itemId ] ) ) ;
243- if ( dCloseOnClick ) {
243+ if ( shouldClose instanceof Promise ) {
244+ setLoadingIds ( ( draft ) => {
245+ draft . add ( itemId ) ;
246+ } ) ;
247+ shouldClose . then ( ( ) => {
248+ setLoadingIds ( ( draft ) => {
249+ draft . delete ( itemId ) ;
250+ } ) ;
251+ } ) ;
252+ } else if ( shouldClose !== false ) {
244253 changeVisible ( false ) ;
245254 }
246255 } ;
@@ -350,6 +359,7 @@ function Dropdown<ID extends DId, T extends DDropdownItem<ID>>(
350359 dLevel = { level }
351360 dIcon = { itemIcon }
352361 dFocusVisible = { focusVisible && isFocus }
362+ dLoading = { loadingIds . has ( itemId ) }
353363 dDisabled = { itemDisabled }
354364 onItemClick = { handleItemClick }
355365 >
0 commit comments