summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/ui/src/hooks/create-auto-scroll.tsx29
1 files changed, 13 insertions, 16 deletions
diff --git a/packages/ui/src/hooks/create-auto-scroll.tsx b/packages/ui/src/hooks/create-auto-scroll.tsx
index 9733b094e..cb76ca828 100644
--- a/packages/ui/src/hooks/create-auto-scroll.tsx
+++ b/packages/ui/src/hooks/create-auto-scroll.tsx
@@ -1,6 +1,6 @@
-import { createEffect, createSignal, on, onCleanup } from "solid-js"
+import { createEffect, on, onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
-import { makeEventListener } from "@solid-primitives/event-listener"
+import { createEventListener } from "@solid-primitives/event-listener"
import { createResizeObserver } from "@solid-primitives/resize-observer"
export interface AutoScrollOptions {
@@ -11,7 +11,6 @@ export interface AutoScrollOptions {
}
export function createAutoScroll(options: AutoScrollOptions) {
- let scroll: HTMLElement | undefined
let settling = false
let settleTimer: ReturnType<typeof setTimeout> | undefined
let autoTimer: ReturnType<typeof setTimeout> | undefined
@@ -21,6 +20,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
const [store, setStore] = createStore({
contentRef: undefined as HTMLElement | undefined,
+ scrollRef: undefined as HTMLElement | undefined,
userScrolled: false,
})
@@ -64,7 +64,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
}
const scrollToBottomNow = (behavior: ScrollBehavior) => {
- const el = scroll
+ const el = store.scrollRef
if (!el) return
markAuto(el)
if (behavior === "smooth") {
@@ -81,7 +81,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
if (force && store.userScrolled) setStore("userScrolled", false)
- const el = scroll
+ const el = store.scrollRef
if (!el) return
if (!force && store.userScrolled) return
@@ -98,7 +98,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
}
const stop = () => {
- const el = scroll
+ const el = store.scrollRef
if (!el) return
if (!canScroll(el)) {
if (store.userScrolled) setStore("userScrolled", false)
@@ -115,7 +115,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
// If the user is scrolling within a nested scrollable region (tool output,
// code block, etc), don't treat it as leaving the "follow bottom" mode.
// Those regions opt in via `data-scrollable`.
- const el = scroll
+ const el = store.scrollRef
const target = e.target instanceof Element ? e.target : undefined
const nested = target?.closest("[data-scrollable]")
if (el && nested && nested !== el) return
@@ -123,7 +123,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
}
const handleScroll = () => {
- const el = scroll
+ const el = store.scrollRef
if (!el) return
if (!canScroll(el)) {
@@ -172,7 +172,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
createResizeObserver(
() => store.contentRef,
() => {
- const el = scroll
+ const el = store.scrollRef
if (el && !canScroll(el)) {
if (store.userScrolled) setStore("userScrolled", false)
return
@@ -208,23 +208,20 @@ export function createAutoScroll(options: AutoScrollOptions) {
// Track `userScrolled` even before `scrollRef` is attached, so we can
// update overflow anchoring once the element exists.
store.userScrolled
- const el = scroll
+ const el = store.scrollRef
if (!el) return
updateOverflowAnchor(el)
})
+ createEventListener(() => store.scrollRef, "wheel", handleWheel, { passive: true })
+
onCleanup(() => {
if (settleTimer) clearTimeout(settleTimer)
if (autoTimer) clearTimeout(autoTimer)
})
return {
- scrollRef: (el: HTMLElement | undefined) => {
- if (!el) return
-
- updateOverflowAnchor(el)
- makeEventListener(el, "wheel", handleWheel, { passive: true })
- },
+ scrollRef: (el: HTMLElement | undefined) => setStore("scrollRef", el),
contentRef: (el: HTMLElement | undefined) => setStore("contentRef", el),
handleScroll,
handleInteraction,