diff options
| author | Adam <[email protected]> | 2026-03-09 07:36:39 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-09 07:36:39 -0500 |
| commit | c71d1bde5e8dcc8be49c15697ad2e5d0f2607e5e (patch) | |
| tree | a30482cedb38dc24cad70e24ad717817065620d6 /packages/ui/src/components/scroll-view.tsx | |
| parent | f27ef595f65aa719be3f8d08665d683e95083ed3 (diff) | |
| download | opencode-c71d1bde5e8dcc8be49c15697ad2e5d0f2607e5e.tar.gz opencode-c71d1bde5e8dcc8be49c15697ad2e5d0f2607e5e.zip | |
revert(app): "STUPID SEXY TIMELINE (#16420)" (#16745)
Diffstat (limited to 'packages/ui/src/components/scroll-view.tsx')
| -rw-r--r-- | packages/ui/src/components/scroll-view.tsx | 70 |
1 files changed, 14 insertions, 56 deletions
diff --git a/packages/ui/src/components/scroll-view.tsx b/packages/ui/src/components/scroll-view.tsx index a8d3cf0f8..52ed39a46 100644 --- a/packages/ui/src/components/scroll-view.tsx +++ b/packages/ui/src/components/scroll-view.tsx @@ -1,18 +1,17 @@ -import { createSignal, onCleanup, onMount, splitProps, type ComponentProps, Show } from "solid-js" -import { animate, type AnimationPlaybackControls } from "motion" +import { createSignal, onCleanup, onMount, splitProps, type ComponentProps, Show, mergeProps } from "solid-js" import { useI18n } from "../context/i18n" -import { FAST_SPRING } from "./motion" export interface ScrollViewProps extends ComponentProps<"div"> { viewportRef?: (el: HTMLDivElement) => void - reverse?: boolean + orientation?: "vertical" | "horizontal" // currently only vertical is fully implemented for thumb } export function ScrollView(props: ScrollViewProps) { const i18n = useI18n() + const merged = mergeProps({ orientation: "vertical" }, props) const [local, events, rest] = splitProps( - props, - ["class", "children", "viewportRef", "style", "reverse"], + merged, + ["class", "children", "viewportRef", "orientation", "style"], [ "onScroll", "onWheel", @@ -26,9 +25,9 @@ export function ScrollView(props: ScrollViewProps) { ], ) + let rootRef!: HTMLDivElement let viewportRef!: HTMLDivElement let thumbRef!: HTMLDivElement - let anim: AnimationPlaybackControls | undefined const [isHovered, setIsHovered] = createSignal(false) const [isDragging, setIsDragging] = createSignal(false) @@ -37,8 +36,6 @@ export function ScrollView(props: ScrollViewProps) { const [thumbTop, setThumbTop] = createSignal(0) const [showThumb, setShowThumb] = createSignal(false) - const reverse = () => local.reverse === true - const updateThumb = () => { if (!viewportRef) return const { scrollTop, scrollHeight, clientHeight } = viewportRef @@ -60,13 +57,9 @@ export function ScrollView(props: ScrollViewProps) { const maxScrollTop = scrollHeight - clientHeight const maxThumbTop = trackHeight - height - const top = (() => { - if (maxScrollTop <= 0) return 0 - if (!reverse()) return (scrollTop / maxScrollTop) * maxThumbTop - return ((maxScrollTop + scrollTop) / maxScrollTop) * maxThumbTop - })() + const top = maxScrollTop > 0 ? (scrollTop / maxScrollTop) * maxThumbTop : 0 - // Ensure thumb stays within bounds + // Ensure thumb stays within bounds (shouldn't be necessary due to math above, but good for safety) const boundedTop = trackPadding + Math.max(0, Math.min(top, maxThumbTop)) setThumbHeight(height) @@ -89,7 +82,6 @@ export function ScrollView(props: ScrollViewProps) { } onCleanup(() => { - stop() observer.disconnect() }) @@ -131,31 +123,6 @@ export function ScrollView(props: ScrollViewProps) { thumbRef.addEventListener("pointerup", onPointerUp) } - const stop = () => { - if (!anim) return - anim.stop() - anim = undefined - } - - const limit = (top: number) => { - const max = viewportRef.scrollHeight - viewportRef.clientHeight - if (reverse()) return Math.max(-max, Math.min(0, top)) - return Math.max(0, Math.min(max, top)) - } - - const glide = (top: number) => { - stop() - anim = animate(viewportRef.scrollTop, limit(top), { - ...FAST_SPRING, - onUpdate: (v) => { - viewportRef.scrollTop = v - }, - onComplete: () => { - anim = undefined - }, - }) - } - // Keybinds implementation // We ensure the viewport has a tabindex so it can receive focus // We can also explicitly catch PageUp/Down if we want smooth scroll or specific behavior, @@ -180,11 +147,11 @@ export function ScrollView(props: ScrollViewProps) { break case "Home": e.preventDefault() - glide(reverse() ? -(viewportRef.scrollHeight - viewportRef.clientHeight) : 0) + viewportRef.scrollTo({ top: 0, behavior: "smooth" }) break case "End": e.preventDefault() - glide(reverse() ? 0 : viewportRef.scrollHeight - viewportRef.clientHeight) + viewportRef.scrollTo({ top: viewportRef.scrollHeight, behavior: "smooth" }) break case "ArrowUp": e.preventDefault() @@ -199,6 +166,7 @@ export function ScrollView(props: ScrollViewProps) { return ( <div + ref={rootRef} class={`scroll-view ${local.class || ""}`} style={local.style} onPointerEnter={() => setIsHovered(true)} @@ -209,26 +177,16 @@ export function ScrollView(props: ScrollViewProps) { <div ref={viewportRef} class="scroll-view__viewport" - data-reverse={reverse() ? "true" : undefined} onScroll={(e) => { updateThumb() if (typeof events.onScroll === "function") events.onScroll(e as any) }} - onWheel={(e) => { - if (e.deltaY) stop() - if (typeof events.onWheel === "function") events.onWheel(e as any) - }} - onTouchStart={(e) => { - stop() - if (typeof events.onTouchStart === "function") events.onTouchStart(e as any) - }} + onWheel={events.onWheel as any} + onTouchStart={events.onTouchStart as any} onTouchMove={events.onTouchMove as any} onTouchEnd={events.onTouchEnd as any} onTouchCancel={events.onTouchCancel as any} - onPointerDown={(e) => { - stop() - if (typeof events.onPointerDown === "function") events.onPointerDown(e as any) - }} + onPointerDown={events.onPointerDown as any} onClick={events.onClick as any} tabIndex={0} role="region" |
