|
1 | 1 | /* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */ |
2 | 2 | import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode'; |
3 | | -import { composeRef, getNodeRef, supportRef } from '@rc-component/util/lib/ref'; |
| 3 | +import { |
| 4 | + getNodeRef, |
| 5 | + supportRef, |
| 6 | + useComposeRef, |
| 7 | +} from '@rc-component/util/lib/ref'; |
4 | 8 | import { clsx } from 'clsx'; |
5 | 9 | import * as React from 'react'; |
6 | 10 | import { useRef } from 'react'; |
@@ -189,7 +193,7 @@ export function genCSSMotion(config: CSSMotionConfig) { |
189 | 193 | } |
190 | 194 |
|
191 | 195 | // We should render children when motionStyle is sync with stepStatus |
192 | | - return React.useMemo(() => { |
| 196 | + const motionChildren = React.useMemo(() => { |
193 | 197 | if (styleReady === 'NONE') { |
194 | 198 | return null; |
195 | 199 | } |
@@ -246,23 +250,27 @@ export function genCSSMotion(config: CSSMotionConfig) { |
246 | 250 | ); |
247 | 251 | } |
248 | 252 |
|
249 | | - // Auto inject ref if child node not have `ref` props |
250 | | - if ( |
251 | | - React.isValidElement(motionChildren) && |
252 | | - supportRef(motionChildren) |
253 | | - ) { |
254 | | - const originNodeRef = getNodeRef(motionChildren); |
255 | | - |
256 | | - motionChildren = React.cloneElement( |
257 | | - motionChildren as React.ReactElement, |
258 | | - { |
259 | | - ref: originNodeRef ? composeRef(originNodeRef, nodeRef) : nodeRef, |
260 | | - }, |
261 | | - ); |
262 | | - } |
263 | | - |
264 | 253 | return motionChildren; |
265 | 254 | }, [idRef.current]) as React.ReactElement; |
| 255 | + |
| 256 | + const canHoldRef = |
| 257 | + React.isValidElement(motionChildren) && supportRef(motionChildren); |
| 258 | + const originNodeRef = canHoldRef ? getNodeRef(motionChildren) : null; |
| 259 | + const shouldInjectRef = canHoldRef && originNodeRef !== nodeRef; |
| 260 | + const mergedNodeRef = useComposeRef( |
| 261 | + shouldInjectRef ? originNodeRef : null, |
| 262 | + nodeRef, |
| 263 | + ); |
| 264 | + |
| 265 | + // Preserve original behavior when child already uses motion's ref directly. |
| 266 | + // Only compose refs when child owns another ref or misses the motion ref. |
| 267 | + if (shouldInjectRef) { |
| 268 | + return React.cloneElement(motionChildren, { |
| 269 | + ref: mergedNodeRef, |
| 270 | + }); |
| 271 | + } |
| 272 | + |
| 273 | + return motionChildren; |
266 | 274 | }, |
267 | 275 | ); |
268 | 276 |
|
|
0 commit comments