Skip to content

Commit

Permalink
Update scroll data in timeout (fixes #307)
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Dec 30, 2024
1 parent 5afa738 commit 5b43034
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
9 changes: 9 additions & 0 deletions .changeset/healthy-doors-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@solid-devtools/frontend": patch
---

Update scroll data in timeout, after the ResizeObserver callback
To prevent this error:
> ResizeObserver loop completed with undelivered notifications
As changing scroll data can then change el.scrollTop
Fixes #307
45 changes: 29 additions & 16 deletions packages/frontend/src/structure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,21 @@ const getFocusedNodeData = (
}

const DisplayStructureTree: s.Component = () => {
const [containerScroll, setContainerScroll] = s.createSignal({top: 0, height: 0})

const [containerScroll, setContainerScroll] = s.createSignal({
top: 0,
height: 0,
}, {
equals: (a, b) => a.top === b.top && a.height === b.height
})

const remSize = useRemSize()
const getContainerTopMargin = (): number => remSize() * v_margin_in_rem
const getRowHeight = (): number => remSize() * row_height_in_rem
const getContainerTopMargin = () => remSize() * v_margin_in_rem
const getRowHeight = () => remSize() * row_height_in_rem

const updateScrollData = (el: HTMLElement): void => {
setContainerScroll({
top: Math.max(el.scrollTop - getContainerTopMargin(), 0),
top: Math.max(el.scrollTop - getContainerTopMargin(), 0),
height: el.clientHeight,
})
}
Expand Down Expand Up @@ -621,16 +627,14 @@ const DisplayStructureTree: s.Component = () => {
})

// Seep the inspected or central node in view when the list is changing
s.createEffect(
defer(collapsedList, () => {
if (!lastFocusedNodeData) return
const [nodeId, lastPosition] = lastFocusedNodeData
const index = getNodeIndexById(nodeId)
if (index === -1) return
const move = index - virtual().start - lastPosition
if (move !== 0) container.scrollTop += move * getRowHeight()
}),
)
s.createEffect(defer(collapsedList, () => {
if (!lastFocusedNodeData) return
const [nodeId, lastPosition] = lastFocusedNodeData
const index = getNodeIndexById(nodeId)
if (index === -1) return
const move = index - virtual().start - lastPosition
if (move !== 0) container.scrollTop += move * getRowHeight()
}))

// Scroll to selected node when it changes
// listen to inspected ID, instead of node, because node reference can change
Expand Down Expand Up @@ -752,8 +756,17 @@ const DisplayStructureTree: s.Component = () => {
<ui.Scrollable
ref={el => {
container = el
setTimeout(() => updateScrollData(el))
createResizeObserver(el, () => updateScrollData(el))
createResizeObserver(el, () => {
/*
Update data in timeout, after the ResizeObserver callback
To prevent this error:
> ResizeObserver loop completed with undelivered notifications
As changing scroll data can then change el.scrollTop
*/
setTimeout(() => {
updateScrollData(el)
})
})
}}
onScroll={e => updateScrollData(e.currentTarget)}
>
Expand Down

0 comments on commit 5b43034

Please sign in to comment.