11import * as React from 'react' ;
22import { useRef , useState } from 'react' ;
33import Align from 'rc-align' ;
4+ import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect' ;
45import type { RefAlign } from 'rc-align/lib/Align' ;
56import type { CSSMotionProps , MotionEndEventHandler } from 'rc-motion' ;
67import CSSMotion from 'rc-motion' ;
@@ -101,6 +102,7 @@ const PopupInner = React.forwardRef<PopupInnerRef, PopupInnerProps>(
101102 const [ status , goNextStatus ] = useVisibleStatus ( visible , doMeasure ) ;
102103
103104 // ======================== Aligns ========================
105+ const [ alignInfo , setAlignInfo ] = useState < AlignType > ( null ) ;
104106 const prepareResolveRef = useRef < ( value ?: unknown ) => void > ( ) ;
105107
106108 // `target` on `rc-align` can accept as a function to get the bind element or a point.
@@ -121,21 +123,29 @@ const PopupInner = React.forwardRef<PopupInnerRef, PopupInnerProps>(
121123 if ( alignedClassName !== nextAlignedClassName ) {
122124 setAlignedClassName ( nextAlignedClassName ) ;
123125 }
126+
127+ setAlignInfo ( matchAlign ) ;
128+
124129 if ( status === 'align' ) {
130+ onAlign ?.( popupDomNode , matchAlign ) ;
131+ }
132+ }
133+
134+ // Delay to go to next status
135+ useLayoutEffect ( ( ) => {
136+ if ( alignInfo && status === 'align' ) {
137+ const nextAlignedClassName = getClassNameFromAlign ( alignInfo ) ;
138+
125139 // Repeat until not more align needed
126140 if ( alignedClassName !== nextAlignedClassName ) {
127- Promise . resolve ( ) . then ( ( ) => {
128- forceAlign ( ) ;
129- } ) ;
141+ forceAlign ( ) ;
130142 } else {
131- goNextStatus ( ( ) => {
143+ goNextStatus ( function ( ) {
132144 prepareResolveRef . current ?.( ) ;
133145 } ) ;
134146 }
135-
136- onAlign ?.( popupDomNode , matchAlign ) ;
137147 }
138- }
148+ } , [ alignInfo ] ) ;
139149
140150 // ======================== Motion ========================
141151 const motion = { ...getMotion ( props ) } ;
0 commit comments