@@ -63,7 +63,7 @@ export function VirtualElement({
6363 id ?: string | undefined
6464 className ?: string
6565} > ) : JSX . Element | null {
66- const resizeObserverManager = ResizeObserverManager . getInstance ( )
66+ const resizeObserverManager = ElementObserverManager . getInstance ( )
6767 const [ waitForInitialLoad , setWaitForInitialLoad ] = useState ( true )
6868 const [ inView , setInView ] = useState ( initialShow ?? false )
6969 const [ isShowingChildren , setIsShowingChildren ] = useState ( inView )
@@ -349,48 +349,86 @@ function measureElement(wrapperEl: HTMLDivElement, placeholderHeight?: number):
349349}
350350
351351// Singleton class to manage ResizeObserver instances
352- export class ResizeObserverManager {
353- private static instance : ResizeObserverManager
352+ export class ElementObserverManager {
353+ private static instance : ElementObserverManager
354354 private resizeObserver : ResizeObserver
355- private observedElements : Map < HTMLElement , ( entry : ResizeObserverEntry ) => void >
355+ private mutationObserver : MutationObserver
356+ private observedElements : Map < HTMLElement , ( ) => void >
356357
357358 private constructor ( ) {
358359 this . observedElements = new Map ( )
360+
361+ // Configure ResizeObserver
359362 this . resizeObserver = new ResizeObserver ( ( entries ) => {
360363 entries . forEach ( ( entry ) => {
361364 const element = entry . target as HTMLElement
362365 const callback = this . observedElements . get ( element )
363366 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
365387 }
366388 } )
389+
390+ // Call callbacks for affected elements
391+ targets . forEach ( ( element ) => {
392+ const callback = this . observedElements . get ( element )
393+ if ( callback ) callback ( )
394+ } )
367395 } )
368396 }
369397
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 ( )
373401 }
374- return ResizeObserverManager . instance
402+ return ElementObserverManager . instance
375403 }
376404
377- public observe ( element : HTMLElement , callback : ( entry : ResizeObserverEntry ) => void ) : void {
405+ public observe ( element : HTMLElement , callback : ( ) => void ) : void {
378406 if ( ! element ) return
379407
380- // Store the callback in our map
381408 this . observedElements . set ( element , callback )
382-
383- // Start observing
384409 this . resizeObserver . observe ( element )
410+ this . mutationObserver . observe ( element , {
411+ childList : true ,
412+ subtree : true ,
413+ attributes : true ,
414+ characterData : true ,
415+ } )
385416 }
386417
387418 public unobserve ( element : HTMLElement ) : void {
388419 if ( ! element ) return
389-
390- // Remove from our map
391420 this . observedElements . delete ( element )
392-
393- // Stop observing
394421 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+ } )
395433 }
396434}
0 commit comments