11import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode' ;
22import { supportRef , useComposeRef , getNodeRef } from '@rc-component/util/lib/ref' ;
33import * as React from 'react' ;
4- import type { ResizeObserverProps } from '..' ;
4+ import type { ResizeObserverProps , SizeInfo } from '..' ;
55import { CollectionContext } from '../Collection' ;
6- import { observe , unobserve } from '../utils/observerUtil ' ;
6+ import useResizeObserver from '../useResizeObserver ' ;
77
88export interface SingleObserverProps extends ResizeObserverProps {
99 children : React . ReactElement | ( ( ref : React . RefObject < Element > ) => React . ReactElement ) ;
1010}
1111
1212function SingleObserver ( props : SingleObserverProps , ref : React . Ref < HTMLElement > ) {
13- const { children, disabled } = props ;
13+ const { children, disabled, onResize , data } = props ;
1414 const elementRef = React . useRef < Element > ( null ) ;
1515
1616 const onCollectionResize = React . useContext ( CollectionContext ) ;
@@ -19,14 +19,6 @@ function SingleObserver(props: SingleObserverProps, ref: React.Ref<HTMLElement>)
1919 const isRenderProps = typeof children === 'function' ;
2020 const mergedChildren = isRenderProps ? children ( elementRef ) : children ;
2121
22- // ============================= Size =============================
23- const sizeRef = React . useRef ( {
24- width : - 1 ,
25- height : - 1 ,
26- offsetWidth : - 1 ,
27- offsetHeight : - 1 ,
28- } ) ;
29-
3022 // ============================= Ref ==============================
3123 const canRef =
3224 ! isRenderProps && React . isValidElement ( mergedChildren ) && supportRef ( mergedChildren ) ;
@@ -35,81 +27,22 @@ function SingleObserver(props: SingleObserverProps, ref: React.Ref<HTMLElement>)
3527 const mergedRef = useComposeRef ( originRef , elementRef ) ;
3628
3729 const getDomElement = ( ) => {
38- return getDOM ( elementRef . current ) as HTMLElement
39- }
40-
30+ return getDOM ( elementRef . current ) as HTMLElement ;
31+ } ;
4132
4233 React . useImperativeHandle ( ref , ( ) => getDomElement ( ) ) ;
4334
4435 // =========================== Observe ============================
45- const propsRef = React . useRef < SingleObserverProps > ( props ) ;
46- propsRef . current = props ;
47-
48- // Handler
49- const onInternalResize = React . useCallback ( ( target : HTMLElement ) => {
50- const { onResize, data } = propsRef . current ;
51-
52- const { width, height } = target . getBoundingClientRect ( ) ;
53- const { offsetWidth, offsetHeight } = target ;
54-
55- /**
56- * Resize observer trigger when content size changed.
57- * In most case we just care about element size,
58- * let's use `boundary` instead of `contentRect` here to avoid shaking.
59- */
60- const fixedWidth = Math . floor ( width ) ;
61- const fixedHeight = Math . floor ( height ) ;
62-
63- if (
64- sizeRef . current . width !== fixedWidth ||
65- sizeRef . current . height !== fixedHeight ||
66- sizeRef . current . offsetWidth !== offsetWidth ||
67- sizeRef . current . offsetHeight !== offsetHeight
68- ) {
69- const size = { width : fixedWidth , height : fixedHeight , offsetWidth, offsetHeight } ;
70- sizeRef . current = size ;
71-
72- // IE is strange, right?
73- const mergedOffsetWidth = offsetWidth === Math . round ( width ) ? width : offsetWidth ;
74- const mergedOffsetHeight = offsetHeight === Math . round ( height ) ? height : offsetHeight ;
75-
76- const sizeInfo = {
77- ...size ,
78- offsetWidth : mergedOffsetWidth ,
79- offsetHeight : mergedOffsetHeight ,
80- } ;
81-
82- // Let collection know what happened
83- onCollectionResize ?.( sizeInfo , target , data ) ;
84-
85- if ( onResize ) {
86- // defer the callback but not defer to next frame
87- Promise . resolve ( ) . then ( ( ) => {
88- onResize ( sizeInfo , target ) ;
89- } ) ;
90- }
91- }
92- } , [ ] ) ;
93-
94- // Dynamic observe
95- React . useEffect ( ( ) => {
96- const currentElement : HTMLElement = getDomElement ( ) ;
97-
98- if ( currentElement && ! disabled ) {
99- observe ( currentElement , onInternalResize ) ;
100- }
101-
102- return ( ) => unobserve ( currentElement , onInternalResize ) ;
103- } , [ elementRef . current , disabled ] ) ;
36+ useResizeObserver ( ! disabled , getDomElement , onResize , ( sizeInfo , target ) => {
37+ onCollectionResize ?.( sizeInfo , target , data ) ;
38+ } ) ;
10439
10540 // ============================ Render ============================
106- return (
107- canRef
108- ? React . cloneElement ( mergedChildren as any , {
109- ref : mergedRef ,
110- } )
111- : mergedChildren
112- ) ;
41+ return canRef
42+ ? React . cloneElement ( mergedChildren as any , {
43+ ref : mergedRef ,
44+ } )
45+ : mergedChildren ;
11346}
11447
11548const RefSingleObserver = React . forwardRef ( SingleObserver ) ;
0 commit comments