@@ -21,6 +21,10 @@ export function useResizeObserver(positioner: Positioner) {
2121 return resizeObserver ;
2222}
2323
24+ const _handlerForType = rafSchd ( ( target : HTMLElement ) => { } ) ;
25+
26+ type IHandler = typeof _handlerForType ;
27+
2428/**
2529 * Creates a resize observer that fires an `updater` callback whenever the height of
2630 * one or many cells change. The `useResizeObserver()` hook is using this under the hood.
@@ -33,33 +37,48 @@ export const createResizeObserver = trieMemoize(
3337 // TODO: figure out a way to test this
3438 /* istanbul ignore next */
3539 ( positioner : Positioner , updater : ( updates : number [ ] ) => void ) => {
36- const handleEntries = rafSchd ( ( ( entries ) => {
37- const updates : number [ ] = [ ] ;
38- let i = 0 ;
39-
40- for ( ; i < entries . length ; i ++ ) {
41- const entry = entries [ i ] ;
42- const height = ( entry . target as HTMLElement ) . offsetHeight ;
43-
44- if ( height > 0 ) {
45- const index = elementsCache . get ( entry . target ) ;
46-
47- if ( index !== void 0 ) {
48- const position = positioner . get ( index ) ;
49-
50- if ( position !== void 0 && height !== position . height )
51- updates . push ( index , height ) ;
52- }
53- }
54- }
40+ const updates : number [ ] = [ ] ;
5541
42+ const update = rafSchd ( ( ) => {
5643 if ( updates . length > 0 ) {
5744 // Updates the size/positions of the cell with the resize
5845 // observer updates
5946 positioner . update ( updates ) ;
6047 updater ( updates ) ;
6148 }
62- } ) as ResizeObserverCallback ) ;
49+ updates . length = 0 ;
50+ } ) ;
51+
52+ const commonHandler = ( target : HTMLElement ) => {
53+ const height = target . offsetHeight ;
54+ if ( height > 0 ) {
55+ const index = elementsCache . get ( target ) ;
56+ if ( index !== void 0 ) {
57+ const position = positioner . get ( index ) ;
58+ if ( position !== void 0 && height !== position . height )
59+ updates . push ( index , height ) ;
60+ }
61+ }
62+ update ( ) ;
63+ } ;
64+
65+ const handlers = new Map < number , IHandler > ( ) ;
66+ const handleEntries : ResizeObserverCallback = ( entries ) => {
67+ let i = 0 ;
68+
69+ for ( ; i < entries . length ; i ++ ) {
70+ const entry = entries [ i ] ;
71+ const index = elementsCache . get ( entry . target ) ;
72+
73+ if ( index === void 0 ) continue ;
74+ let handler = handlers . get ( index ) ;
75+ if ( ! handler ) {
76+ handler = rafSchd ( commonHandler ) ;
77+ handlers . set ( index , handler ) ;
78+ }
79+ handler ( entry . target as HTMLElement ) ;
80+ }
81+ } ;
6382
6483 const ro = new ResizeObserver ( handleEntries ) ;
6584 // Overrides the original disconnect to include cancelling handling the entries.
@@ -68,7 +87,9 @@ export const createResizeObserver = trieMemoize(
6887 const disconnect = ro . disconnect . bind ( ro ) ;
6988 ro . disconnect = ( ) => {
7089 disconnect ( ) ;
71- handleEntries . cancel ( ) ;
90+ handlers . forEach ( ( handler ) => {
91+ handler . cancel ( ) ;
92+ } ) ;
7293 } ;
7394
7495 return ro ;
0 commit comments