Skip to content

Commit 99d8aab

Browse files
committed
fix(app): can't scroll files
1 parent 7dd6369 commit 99d8aab

4 files changed

Lines changed: 22 additions & 13 deletions

File tree

packages/app/src/pages/session/file-tabs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,9 @@ export function FileTabContent(props: { tab: string }) {
446446
)
447447

448448
return (
449-
<Tabs.Content value={props.tab} class="mt-3 relative h-full">
449+
<Tabs.Content value={props.tab} class="mt-3 relative flex h-full min-h-0 flex-col overflow-hidden contain-strict">
450450
<ScrollView
451-
class="h-full"
451+
class="h-full min-h-0 flex-1"
452452
viewportRef={(el: HTMLDivElement) => {
453453
scroll = el
454454
restoreScroll()

packages/app/src/pages/session/message-timeline.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ export function MessageTimeline(props: {
347347
placeholderTitle={placeholderTitle}
348348
/>
349349
<ScrollView
350+
reverse
350351
viewportRef={props.setScrollRef}
351352
onWheel={(e) => {
352353
const root = e.currentTarget

packages/ui/src/components/scroll-view.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
overflow-y: auto;
1010
scrollbar-width: none;
1111
outline: none;
12+
display: block;
13+
overflow-anchor: none;
14+
}
15+
16+
.scroll-view__viewport[data-reverse="true"] {
1217
display: flex;
1318
flex-direction: column-reverse;
14-
overflow-anchor: none;
1519
}
1620

1721
.scroll-view__viewport::-webkit-scrollbar {

packages/ui/src/components/scroll-view.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { FAST_SPRING } from "./motion"
55

66
export interface ScrollViewProps extends ComponentProps<"div"> {
77
viewportRef?: (el: HTMLDivElement) => void
8+
reverse?: boolean
89
}
910

1011
export function ScrollView(props: ScrollViewProps) {
1112
const i18n = useI18n()
1213
const [local, events, rest] = splitProps(
1314
props,
14-
["class", "children", "viewportRef", "style"],
15+
["class", "children", "viewportRef", "style", "reverse"],
1516
[
1617
"onScroll",
1718
"onWheel",
@@ -36,6 +37,8 @@ export function ScrollView(props: ScrollViewProps) {
3637
const [thumbTop, setThumbTop] = createSignal(0)
3738
const [showThumb, setShowThumb] = createSignal(false)
3839

40+
const reverse = () => local.reverse === true
41+
3942
const updateThumb = () => {
4043
if (!viewportRef) return
4144
const { scrollTop, scrollHeight, clientHeight } = viewportRef
@@ -57,10 +60,11 @@ export function ScrollView(props: ScrollViewProps) {
5760
const maxScrollTop = scrollHeight - clientHeight
5861
const maxThumbTop = trackHeight - height
5962

60-
// With column-reverse: scrollTop=0 is at bottom, negative = scrolled up
61-
// Normalize so 0 = at top, maxScrollTop = at bottom
62-
const normalizedScrollTop = maxScrollTop + scrollTop
63-
const top = maxScrollTop > 0 ? (normalizedScrollTop / maxScrollTop) * maxThumbTop : 0
63+
const top = (() => {
64+
if (maxScrollTop <= 0) return 0
65+
if (!reverse()) return (scrollTop / maxScrollTop) * maxThumbTop
66+
return ((maxScrollTop + scrollTop) / maxScrollTop) * maxThumbTop
67+
})()
6468

6569
// Ensure thumb stays within bounds
6670
const boundedTop = trackPadding + Math.max(0, Math.min(top, maxThumbTop))
@@ -135,7 +139,8 @@ export function ScrollView(props: ScrollViewProps) {
135139

136140
const limit = (top: number) => {
137141
const max = viewportRef.scrollHeight - viewportRef.clientHeight
138-
return Math.max(-max, Math.min(0, top))
142+
if (reverse()) return Math.max(-max, Math.min(0, top))
143+
return Math.max(0, Math.min(max, top))
139144
}
140145

141146
const glide = (top: number) => {
@@ -175,13 +180,11 @@ export function ScrollView(props: ScrollViewProps) {
175180
break
176181
case "Home":
177182
e.preventDefault()
178-
// With column-reverse, top of content = -(scrollHeight - clientHeight)
179-
glide(-(viewportRef.scrollHeight - viewportRef.clientHeight))
183+
glide(reverse() ? -(viewportRef.scrollHeight - viewportRef.clientHeight) : 0)
180184
break
181185
case "End":
182186
e.preventDefault()
183-
// With column-reverse, bottom of content = 0
184-
glide(0)
187+
glide(reverse() ? 0 : viewportRef.scrollHeight - viewportRef.clientHeight)
185188
break
186189
case "ArrowUp":
187190
e.preventDefault()
@@ -206,6 +209,7 @@ export function ScrollView(props: ScrollViewProps) {
206209
<div
207210
ref={viewportRef}
208211
class="scroll-view__viewport"
212+
data-reverse={reverse() ? "true" : undefined}
209213
onScroll={(e) => {
210214
updateThumb()
211215
if (typeof events.onScroll === "function") events.onScroll(e as any)

0 commit comments

Comments
 (0)