Skip to content

Commit a2272c3

Browse files
committed
fix: add mutation observer for resizes on activate and on take
1 parent 307c8a7 commit a2272c3

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

packages/webui/src/client/lib/VirtualElement.tsx

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)