Skip to content

Commit c4b3971

Browse files
authored
app: unify auto scroll ref handling (#20716)
1 parent 3faabda commit c4b3971

1 file changed

Lines changed: 13 additions & 16 deletions

File tree

packages/ui/src/hooks/create-auto-scroll.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { createEffect, createSignal, on, onCleanup } from "solid-js"
1+
import { createEffect, on, onCleanup } from "solid-js"
22
import { createStore } from "solid-js/store"
3-
import { makeEventListener } from "@solid-primitives/event-listener"
3+
import { createEventListener } from "@solid-primitives/event-listener"
44
import { createResizeObserver } from "@solid-primitives/resize-observer"
55

66
export interface AutoScrollOptions {
@@ -11,7 +11,6 @@ export interface AutoScrollOptions {
1111
}
1212

1313
export function createAutoScroll(options: AutoScrollOptions) {
14-
let scroll: HTMLElement | undefined
1514
let settling = false
1615
let settleTimer: ReturnType<typeof setTimeout> | undefined
1716
let autoTimer: ReturnType<typeof setTimeout> | undefined
@@ -21,6 +20,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
2120

2221
const [store, setStore] = createStore({
2322
contentRef: undefined as HTMLElement | undefined,
23+
scrollRef: undefined as HTMLElement | undefined,
2424
userScrolled: false,
2525
})
2626

@@ -64,7 +64,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
6464
}
6565

6666
const scrollToBottomNow = (behavior: ScrollBehavior) => {
67-
const el = scroll
67+
const el = store.scrollRef
6868
if (!el) return
6969
markAuto(el)
7070
if (behavior === "smooth") {
@@ -81,7 +81,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
8181

8282
if (force && store.userScrolled) setStore("userScrolled", false)
8383

84-
const el = scroll
84+
const el = store.scrollRef
8585
if (!el) return
8686

8787
if (!force && store.userScrolled) return
@@ -98,7 +98,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
9898
}
9999

100100
const stop = () => {
101-
const el = scroll
101+
const el = store.scrollRef
102102
if (!el) return
103103
if (!canScroll(el)) {
104104
if (store.userScrolled) setStore("userScrolled", false)
@@ -115,15 +115,15 @@ export function createAutoScroll(options: AutoScrollOptions) {
115115
// If the user is scrolling within a nested scrollable region (tool output,
116116
// code block, etc), don't treat it as leaving the "follow bottom" mode.
117117
// Those regions opt in via `data-scrollable`.
118-
const el = scroll
118+
const el = store.scrollRef
119119
const target = e.target instanceof Element ? e.target : undefined
120120
const nested = target?.closest("[data-scrollable]")
121121
if (el && nested && nested !== el) return
122122
stop()
123123
}
124124

125125
const handleScroll = () => {
126-
const el = scroll
126+
const el = store.scrollRef
127127
if (!el) return
128128

129129
if (!canScroll(el)) {
@@ -172,7 +172,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
172172
createResizeObserver(
173173
() => store.contentRef,
174174
() => {
175-
const el = scroll
175+
const el = store.scrollRef
176176
if (el && !canScroll(el)) {
177177
if (store.userScrolled) setStore("userScrolled", false)
178178
return
@@ -208,23 +208,20 @@ export function createAutoScroll(options: AutoScrollOptions) {
208208
// Track `userScrolled` even before `scrollRef` is attached, so we can
209209
// update overflow anchoring once the element exists.
210210
store.userScrolled
211-
const el = scroll
211+
const el = store.scrollRef
212212
if (!el) return
213213
updateOverflowAnchor(el)
214214
})
215215

216+
createEventListener(() => store.scrollRef, "wheel", handleWheel, { passive: true })
217+
216218
onCleanup(() => {
217219
if (settleTimer) clearTimeout(settleTimer)
218220
if (autoTimer) clearTimeout(autoTimer)
219221
})
220222

221223
return {
222-
scrollRef: (el: HTMLElement | undefined) => {
223-
if (!el) return
224-
225-
updateOverflowAnchor(el)
226-
makeEventListener(el, "wheel", handleWheel, { passive: true })
227-
},
224+
scrollRef: (el: HTMLElement | undefined) => setStore("scrollRef", el),
228225
contentRef: (el: HTMLElement | undefined) => setStore("contentRef", el),
229226
handleScroll,
230227
handleInteraction,

0 commit comments

Comments
 (0)