@@ -63,7 +63,7 @@ export function VirtualElement({
63
63
id ?: string | undefined
64
64
className ?: string
65
65
} > ) : JSX . Element | null {
66
- const resizeObserverManager = ResizeObserverManager . getInstance ( )
66
+ const resizeObserverManager = ElementObserverManager . getInstance ( )
67
67
const [ waitForInitialLoad , setWaitForInitialLoad ] = useState ( true )
68
68
const [ inView , setInView ] = useState ( initialShow ?? false )
69
69
const [ isShowingChildren , setIsShowingChildren ] = useState ( inView )
@@ -349,48 +349,86 @@ function measureElement(wrapperEl: HTMLDivElement, placeholderHeight?: number):
349
349
}
350
350
351
351
// Singleton class to manage ResizeObserver instances
352
- export class ResizeObserverManager {
353
- private static instance : ResizeObserverManager
352
+ export class ElementObserverManager {
353
+ private static instance : ElementObserverManager
354
354
private resizeObserver : ResizeObserver
355
- private observedElements : Map < HTMLElement , ( entry : ResizeObserverEntry ) => void >
355
+ private mutationObserver : MutationObserver
356
+ private observedElements : Map < HTMLElement , ( ) => void >
356
357
357
358
private constructor ( ) {
358
359
this . observedElements = new Map ( )
360
+
361
+ // Configure ResizeObserver
359
362
this . resizeObserver = new ResizeObserver ( ( entries ) => {
360
363
entries . forEach ( ( entry ) => {
361
364
const element = entry . target as HTMLElement
362
365
const callback = this . observedElements . get ( element )
363
366
if ( callback ) {
364
- callback ( entry )
367
+ callback ( )
368
+ }
369
+ } )
370
+ } )
371
+
372
+ // Configure MutationObserver
373
+ this . mutationObserver = new MutationObserver ( ( mutations ) => {
374
+ const targets = new Set < HTMLElement > ( )
375
+
376
+ mutations . forEach ( ( mutation ) => {
377
+ const target = mutation . target as HTMLElement
378
+ // Find the closest observed element
379
+ let element = target
380
+ while ( element ) {
381
+ if ( this . observedElements . has ( element ) ) {
382
+ targets . add ( element )
383
+ break
384
+ }
385
+ if ( ! element . parentElement ) break
386
+ element = element . parentElement
365
387
}
366
388
} )
389
+
390
+ // Call callbacks for affected elements
391
+ targets . forEach ( ( element ) => {
392
+ const callback = this . observedElements . get ( element )
393
+ if ( callback ) callback ( )
394
+ } )
367
395
} )
368
396
}
369
397
370
- public static getInstance ( ) : ResizeObserverManager {
371
- if ( ! ResizeObserverManager . instance ) {
372
- ResizeObserverManager . instance = new ResizeObserverManager ( )
398
+ public static getInstance ( ) : ElementObserverManager {
399
+ if ( ! ElementObserverManager . instance ) {
400
+ ElementObserverManager . instance = new ElementObserverManager ( )
373
401
}
374
- return ResizeObserverManager . instance
402
+ return ElementObserverManager . instance
375
403
}
376
404
377
- public observe ( element : HTMLElement , callback : ( entry : ResizeObserverEntry ) => void ) : void {
405
+ public observe ( element : HTMLElement , callback : ( ) => void ) : void {
378
406
if ( ! element ) return
379
407
380
- // Store the callback in our map
381
408
this . observedElements . set ( element , callback )
382
-
383
- // Start observing
384
409
this . resizeObserver . observe ( element )
410
+ this . mutationObserver . observe ( element , {
411
+ childList : true ,
412
+ subtree : true ,
413
+ attributes : true ,
414
+ characterData : true ,
415
+ } )
385
416
}
386
417
387
418
public unobserve ( element : HTMLElement ) : void {
388
419
if ( ! element ) return
389
-
390
- // Remove from our map
391
420
this . observedElements . delete ( element )
392
-
393
- // Stop observing
394
421
this . resizeObserver . unobserve ( element )
422
+
423
+ // Disconnect and reconnect mutation observer to refresh the list of observed elements
424
+ this . mutationObserver . disconnect ( )
425
+ this . observedElements . forEach ( ( _ , el ) => {
426
+ this . mutationObserver . observe ( el , {
427
+ childList : true ,
428
+ subtree : true ,
429
+ attributes : true ,
430
+ characterData : true ,
431
+ } )
432
+ } )
395
433
}
396
434
}
0 commit comments