Skip to content

Commit faf27e7

Browse files
authored
fix(ScrollArea, Presence): cancel ScrollAreaThumb RAF loop and clean up Presence listeners on unmount (#2744)
* fix(ScrollArea): cancel ScrollAreaThumb RAF loop and clean up Presence listeners on unmount - ScrollAreaThumb: call removeUnlinkedScrollListenerRef to cancel the requestAnimationFrame loop on unmount, preventing a perpetual RAF loop that retains DOM references after component destruction - ScrollAreaThumb: remove duplicate viewport event listener removal - Presence: explicitly remove animation event listeners from the DOM node when the host component unmounts, preventing leaked listeners on teleported nodes Closes #2420 * chore(ScrollAreaThumb): use optional chaining for viewport cleanup
1 parent 04cba00 commit faf27e7

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

packages/core/src/Presence/usePresence.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ export function usePresence(
158158
onUnmounted(() => {
159159
watcher()
160160
stateWatcher()
161+
if (node.value) {
162+
node.value.removeEventListener('animationstart', handleAnimationStart)
163+
node.value.removeEventListener('animationcancel', handleAnimationEnd)
164+
node.value.removeEventListener('animationend', handleAnimationEnd)
165+
}
166+
if (timeoutId !== undefined)
167+
ownerWindow?.clearTimeout(timeoutId)
161168
})
162169

163170
const isPresent = computed(() =>

packages/core/src/ScrollArea/ScrollAreaThumb.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ watchOnce(sizes, () => {
6363
})
6464
6565
onUnmounted(() => {
66-
viewport.value!.removeEventListener('scroll', handleScroll)
67-
rootContext.viewport.value?.removeEventListener('scroll', handleScroll)
66+
viewport.value?.removeEventListener('scroll', handleScroll)
67+
removeUnlinkedScrollListenerRef.value?.()
6868
})
6969
</script>
7070

0 commit comments

Comments
 (0)