1
1
import * as React from 'react' ;
2
2
import { useRef , useState } from 'react' ;
3
3
import Align from 'rc-align' ;
4
+ import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect' ;
4
5
import type { RefAlign } from 'rc-align/lib/Align' ;
5
6
import type { CSSMotionProps , MotionEndEventHandler } from 'rc-motion' ;
6
7
import CSSMotion from 'rc-motion' ;
@@ -101,6 +102,7 @@ const PopupInner = React.forwardRef<PopupInnerRef, PopupInnerProps>(
101
102
const [ status , goNextStatus ] = useVisibleStatus ( visible , doMeasure ) ;
102
103
103
104
// ======================== Aligns ========================
105
+ const [ alignInfo , setAlignInfo ] = useState < AlignType > ( null ) ;
104
106
const prepareResolveRef = useRef < ( value ?: unknown ) => void > ( ) ;
105
107
106
108
// `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>(
121
123
if ( alignedClassName !== nextAlignedClassName ) {
122
124
setAlignedClassName ( nextAlignedClassName ) ;
123
125
}
126
+
127
+ setAlignInfo ( matchAlign ) ;
128
+
124
129
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
+
125
139
// Repeat until not more align needed
126
140
if ( alignedClassName !== nextAlignedClassName ) {
127
- Promise . resolve ( ) . then ( ( ) => {
128
- forceAlign ( ) ;
129
- } ) ;
141
+ forceAlign ( ) ;
130
142
} else {
131
- goNextStatus ( ( ) => {
143
+ goNextStatus ( function ( ) {
132
144
prepareResolveRef . current ?.( ) ;
133
145
} ) ;
134
146
}
135
-
136
- onAlign ?.( popupDomNode , matchAlign ) ;
137
147
}
138
- }
148
+ } , [ alignInfo ] ) ;
139
149
140
150
// ======================== Motion ========================
141
151
const motion = { ...getMotion ( props ) } ;
0 commit comments