summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/app/src/components/settings-general.tsx10
-rw-r--r--packages/app/src/components/settings-keybinds.tsx10
-rw-r--r--packages/app/src/components/settings-models.tsx10
-rw-r--r--packages/app/src/components/settings-providers.tsx10
-rw-r--r--packages/ui/src/components/list.css50
-rw-r--r--packages/ui/src/components/list.tsx5
-rw-r--r--packages/ui/src/components/scroll-fade.css82
-rw-r--r--packages/ui/src/components/scroll-fade.tsx206
-rw-r--r--packages/ui/src/components/scroll-reveal.tsx141
-rw-r--r--packages/ui/src/styles/index.css1
10 files changed, 43 insertions, 482 deletions
diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx
index a0251ed41..94813871e 100644
--- a/packages/app/src/components/settings-general.tsx
+++ b/packages/app/src/components/settings-general.tsx
@@ -5,7 +5,6 @@ import { Select } from "@opencode-ai/ui/select"
import { Switch } from "@opencode-ai/ui/switch"
import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
import { showToast } from "@opencode-ai/ui/toast"
-import { ScrollFade } from "@opencode-ai/ui/scroll-fade"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { useSettings, monoFontFamily } from "@/context/settings"
@@ -131,12 +130,7 @@ export const SettingsGeneral: Component = () => {
const soundOptions = [...SOUND_OPTIONS]
return (
- <ScrollFade
- direction="vertical"
- fadeStartSize={0}
- fadeEndSize={16}
- class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
- >
+ <div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-1 pt-6 pb-8">
<h2 class="text-16-medium text-text-strong">{language.t("settings.tab.general")}</h2>
@@ -417,7 +411,7 @@ export const SettingsGeneral: Component = () => {
</div>
</div>
</div>
- </ScrollFade>
+ </div>
)
}
diff --git a/packages/app/src/components/settings-keybinds.tsx b/packages/app/src/components/settings-keybinds.tsx
index 8655bca34..a24db13f5 100644
--- a/packages/app/src/components/settings-keybinds.tsx
+++ b/packages/app/src/components/settings-keybinds.tsx
@@ -5,7 +5,6 @@ import { Icon } from "@opencode-ai/ui/icon"
import { IconButton } from "@opencode-ai/ui/icon-button"
import { TextField } from "@opencode-ai/ui/text-field"
import { showToast } from "@opencode-ai/ui/toast"
-import { ScrollFade } from "@opencode-ai/ui/scroll-fade"
import fuzzysort from "fuzzysort"
import { formatKeybind, parseKeybind, useCommand } from "@/context/command"
import { useLanguage } from "@/context/language"
@@ -353,12 +352,7 @@ export const SettingsKeybinds: Component = () => {
})
return (
- <ScrollFade
- direction="vertical"
- fadeStartSize={0}
- fadeEndSize={16}
- class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
- >
+ <div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-4 pt-6 pb-6 max-w-[720px]">
<div class="flex items-center justify-between gap-4">
@@ -436,6 +430,6 @@ export const SettingsKeybinds: Component = () => {
</div>
</Show>
</div>
- </ScrollFade>
+ </div>
)
}
diff --git a/packages/app/src/components/settings-models.tsx b/packages/app/src/components/settings-models.tsx
index 0ee5caf73..1807d561e 100644
--- a/packages/app/src/components/settings-models.tsx
+++ b/packages/app/src/components/settings-models.tsx
@@ -9,7 +9,6 @@ import { type Component, For, Show } from "solid-js"
import { useLanguage } from "@/context/language"
import { useModels } from "@/context/models"
import { popularProviders } from "@/hooks/use-providers"
-import { ScrollFade } from "@opencode-ai/ui/scroll-fade"
type ModelItem = ReturnType<ReturnType<typeof useModels>["list"]>[number]
@@ -40,12 +39,7 @@ export const SettingsModels: Component = () => {
})
return (
- <ScrollFade
- direction="vertical"
- fadeStartSize={0}
- fadeEndSize={16}
- class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
- >
+ <div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-4 pt-6 pb-6 max-w-[720px]">
<h2 class="text-16-medium text-text-strong">{language.t("settings.models.title")}</h2>
@@ -131,6 +125,6 @@ export const SettingsModels: Component = () => {
</Show>
</Show>
</div>
- </ScrollFade>
+ </div>
)
}
diff --git a/packages/app/src/components/settings-providers.tsx b/packages/app/src/components/settings-providers.tsx
index 2460534c0..dcc597139 100644
--- a/packages/app/src/components/settings-providers.tsx
+++ b/packages/app/src/components/settings-providers.tsx
@@ -12,7 +12,6 @@ import { useGlobalSync } from "@/context/global-sync"
import { DialogConnectProvider } from "./dialog-connect-provider"
import { DialogSelectProvider } from "./dialog-select-provider"
import { DialogCustomProvider } from "./dialog-custom-provider"
-import { ScrollFade } from "@opencode-ai/ui/scroll-fade"
type ProviderSource = "env" | "api" | "config" | "custom"
type ProviderMeta = { source?: ProviderSource }
@@ -116,12 +115,7 @@ export const SettingsProviders: Component = () => {
}
return (
- <ScrollFade
- direction="vertical"
- fadeStartSize={0}
- fadeEndSize={16}
- class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
- >
+ <div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-1 pt-6 pb-8 max-w-[720px]">
<h2 class="text-16-medium text-text-strong">{language.t("settings.providers.title")}</h2>
@@ -267,6 +261,6 @@ export const SettingsProviders: Component = () => {
</Button>
</div>
</div>
- </ScrollFade>
+ </div>
)
}
diff --git a/packages/ui/src/components/list.css b/packages/ui/src/components/list.css
index 7b365c288..b12d30415 100644
--- a/packages/ui/src/components/list.css
+++ b/packages/ui/src/components/list.css
@@ -1,7 +1,25 @@
+@property --bottom-fade {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 0px;
+}
+
+@keyframes scroll {
+ 0% {
+ --bottom-fade: 20px;
+ }
+ 90% {
+ --bottom-fade: 20px;
+ }
+ 100% {
+ --bottom-fade: 0;
+ }
+}
+
[data-component="list"] {
display: flex;
flex-direction: column;
- gap: 8px;
+ gap: 12px;
overflow: hidden;
padding: 0 12px;
@@ -19,9 +37,7 @@
flex-shrink: 0;
background-color: transparent;
opacity: 0.5;
- transition-property: opacity;
- transition-duration: var(--transition-duration);
- transition-timing-function: var(--transition-easing);
+ transition: opacity 0.15s ease;
&:hover:not(:disabled),
&:focus-visible:not(:disabled),
@@ -72,9 +88,7 @@
height: 20px;
background-color: transparent;
opacity: 0.5;
- transition-property: opacity;
- transition-duration: var(--transition-duration);
- transition-timing-function: var(--transition-easing);
+ transition: opacity 0.15s ease;
&:hover:not(:disabled),
&:focus-visible:not(:disabled),
@@ -117,6 +131,15 @@
gap: 12px;
overflow-y: auto;
overscroll-behavior: contain;
+ mask: linear-gradient(to bottom, #ffff calc(100% - var(--bottom-fade)), #0000);
+ animation: scroll;
+ animation-timeline: --scroll;
+ scroll-timeline: --scroll y;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+ &::-webkit-scrollbar {
+ display: none;
+ }
[data-slot="list-empty-state"] {
display: flex;
@@ -192,9 +215,7 @@
background: linear-gradient(to bottom, var(--surface-raised-stronger-non-alpha), transparent);
pointer-events: none;
opacity: 0;
- transition-property: opacity;
- transition-duration: var(--transition-duration);
- transition-timing-function: var(--transition-easing);
+ transition: opacity 0.15s ease;
}
&[data-stuck="true"]::after {
@@ -230,22 +251,17 @@
align-items: center;
justify-content: center;
flex-shrink: 0;
- aspect-ratio: 1 / 1;
+ aspect-ratio: 1/1;
[data-component="icon"] {
color: var(--icon-strong-base);
}
}
-
- [name="check"] {
- color: var(--icon-strong-base);
- }
-
[data-slot="list-item-active-icon"] {
display: none;
align-items: center;
justify-content: center;
flex-shrink: 0;
- aspect-ratio: 1 / 1;
+ aspect-ratio: 1/1;
[data-component="icon"] {
color: var(--icon-strong-base);
}
diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx
index 886ac5e6c..6c654cbb7 100644
--- a/packages/ui/src/components/list.tsx
+++ b/packages/ui/src/components/list.tsx
@@ -5,7 +5,6 @@ import { useI18n } from "../context/i18n"
import { Icon, type IconProps } from "./icon"
import { IconButton } from "./icon-button"
import { TextField } from "./text-field"
-import { ScrollFade } from "./scroll-fade"
function findByKey(container: HTMLElement, key: string) {
const nodes = container.querySelectorAll<HTMLElement>('[data-slot="list-item"][data-key]')
@@ -280,7 +279,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
{searchAction()}
</div>
</Show>
- <ScrollFade ref={setScrollRef} direction="vertical" fadeStartSize={0} fadeEndSize={20} data-slot="list-scroll">
+ <div ref={setScrollRef} data-slot="list-scroll">
<Show
when={flat().length > 0 || showAdd()}
fallback={
@@ -353,7 +352,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
</div>
</Show>
</Show>
- </ScrollFade>
+ </div>
</div>
)
}
diff --git a/packages/ui/src/components/scroll-fade.css b/packages/ui/src/components/scroll-fade.css
deleted file mode 100644
index ede5fabec..000000000
--- a/packages/ui/src/components/scroll-fade.css
+++ /dev/null
@@ -1,82 +0,0 @@
-[data-component="scroll-fade"] {
- overflow: auto;
- overscroll-behavior: contain;
- scrollbar-width: none;
- box-sizing: border-box;
- color: inherit;
- font: inherit;
- -ms-overflow-style: none;
-
- &::-webkit-scrollbar {
- display: none;
- }
-
- &[data-direction="horizontal"] {
- overflow-x: auto;
- overflow-y: hidden;
-
- /* Both fades */
- &[data-fade-start][data-fade-end] {
- mask-image: linear-gradient(
- to right,
- transparent,
- black var(--scroll-fade-start),
- black calc(100% - var(--scroll-fade-end)),
- transparent
- );
- -webkit-mask-image: linear-gradient(
- to right,
- transparent,
- black var(--scroll-fade-start),
- black calc(100% - var(--scroll-fade-end)),
- transparent
- );
- }
-
- /* Only start fade */
- &[data-fade-start]:not([data-fade-end]) {
- mask-image: linear-gradient(to right, transparent, black var(--scroll-fade-start), black 100%);
- -webkit-mask-image: linear-gradient(to right, transparent, black var(--scroll-fade-start), black 100%);
- }
-
- /* Only end fade */
- &:not([data-fade-start])[data-fade-end] {
- mask-image: linear-gradient(to right, black 0%, black calc(100% - var(--scroll-fade-end)), transparent);
- -webkit-mask-image: linear-gradient(to right, black 0%, black calc(100% - var(--scroll-fade-end)), transparent);
- }
- }
-
- &[data-direction="vertical"] {
- overflow-y: auto;
- overflow-x: hidden;
-
- &[data-fade-start][data-fade-end] {
- mask-image: linear-gradient(
- to bottom,
- transparent,
- black var(--scroll-fade-start),
- black calc(100% - var(--scroll-fade-end)),
- transparent
- );
- -webkit-mask-image: linear-gradient(
- to bottom,
- transparent,
- black var(--scroll-fade-start),
- black calc(100% - var(--scroll-fade-end)),
- transparent
- );
- }
-
- /* Only start fade */
- &[data-fade-start]:not([data-fade-end]) {
- mask-image: linear-gradient(to bottom, transparent, black var(--scroll-fade-start), black 100%);
- -webkit-mask-image: linear-gradient(to bottom, transparent, black var(--scroll-fade-start), black 100%);
- }
-
- /* Only end fade */
- &:not([data-fade-start])[data-fade-end] {
- mask-image: linear-gradient(to bottom, black 0%, black calc(100% - var(--scroll-fade-end)), transparent);
- -webkit-mask-image: linear-gradient(to bottom, black 0%, black calc(100% - var(--scroll-fade-end)), transparent);
- }
- }
-}
diff --git a/packages/ui/src/components/scroll-fade.tsx b/packages/ui/src/components/scroll-fade.tsx
deleted file mode 100644
index 97f0339e8..000000000
--- a/packages/ui/src/components/scroll-fade.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-import { type JSX, createEffect, createSignal, onCleanup, onMount, splitProps } from "solid-js"
-
-export interface ScrollFadeProps extends JSX.HTMLAttributes<HTMLDivElement> {
- direction?: "horizontal" | "vertical"
- fadeStartSize?: number
- fadeEndSize?: number
- trackTransformSelector?: string
- ref?: (el: HTMLDivElement) => void
-}
-
-export function ScrollFade(props: ScrollFadeProps) {
- const [local, others] = splitProps(props, [
- "children",
- "direction",
- "fadeStartSize",
- "fadeEndSize",
- "trackTransformSelector",
- "class",
- "style",
- "ref",
- ])
-
- const direction = () => local.direction ?? "vertical"
- const fadeStartSize = () => local.fadeStartSize ?? 20
- const fadeEndSize = () => local.fadeEndSize ?? 20
-
- const getTransformOffset = (element: Element): number => {
- const style = getComputedStyle(element)
- const transform = style.transform
- if (!transform || transform === "none") return 0
-
- const match = transform.match(/matrix(?:3d)?\(([^)]+)\)/)
- if (!match) return 0
-
- const values = match[1].split(",").map((v) => parseFloat(v.trim()))
- const isHorizontal = direction() === "horizontal"
-
- if (transform.startsWith("matrix3d")) {
- return isHorizontal ? -(values[12] || 0) : -(values[13] || 0)
- } else {
- return isHorizontal ? -(values[4] || 0) : -(values[5] || 0)
- }
- }
-
- let containerRef: HTMLDivElement | undefined
-
- const [fadeStart, setFadeStart] = createSignal(0)
- const [fadeEnd, setFadeEnd] = createSignal(0)
- const [isScrollable, setIsScrollable] = createSignal(false)
-
- let lastScrollPos = 0
- let lastTransformPos = 0
- let lastScrollSize = 0
- let lastClientSize = 0
-
- const updateFade = () => {
- if (!containerRef) return
-
- const isHorizontal = direction() === "horizontal"
- const scrollPos = isHorizontal ? containerRef.scrollLeft : containerRef.scrollTop
- const scrollSize = isHorizontal ? containerRef.scrollWidth : containerRef.scrollHeight
- const clientSize = isHorizontal ? containerRef.clientWidth : containerRef.clientHeight
-
- let transformPos = 0
- if (local.trackTransformSelector) {
- const transformElement = containerRef.querySelector(local.trackTransformSelector)
- if (transformElement) {
- transformPos = getTransformOffset(transformElement)
- }
- }
-
- const effectiveScrollPos = Math.max(scrollPos, transformPos)
-
- if (
- effectiveScrollPos === lastScrollPos &&
- transformPos === lastTransformPos &&
- scrollSize === lastScrollSize &&
- clientSize === lastClientSize
- ) {
- return
- }
-
- lastScrollPos = effectiveScrollPos
- lastTransformPos = transformPos
- lastScrollSize = scrollSize
- lastClientSize = clientSize
-
- const maxScroll = scrollSize - clientSize
- const canScroll = maxScroll > 1
-
- setIsScrollable(canScroll)
-
- if (!canScroll) {
- setFadeStart(0)
- setFadeEnd(0)
- return
- }
-
- const progress = maxScroll > 0 ? effectiveScrollPos / maxScroll : 0
-
- const startProgress = Math.min(progress / 0.1, 1)
- setFadeStart(startProgress * fadeStartSize())
-
- const endProgress = progress > 0.9 ? (1 - progress) / 0.1 : 1
- setFadeEnd(Math.max(0, endProgress) * fadeEndSize())
- }
-
- onMount(() => {
- if (!containerRef) return
-
- updateFade()
-
- let rafId: number | undefined
- let isPolling = false
- let pollTimeout: ReturnType<typeof setTimeout> | undefined
-
- const startPolling = () => {
- if (isPolling) return
- isPolling = true
-
- const pollScroll = () => {
- updateFade()
- rafId = requestAnimationFrame(pollScroll)
- }
- rafId = requestAnimationFrame(pollScroll)
- }
-
- const stopPolling = () => {
- if (!isPolling) return
- isPolling = false
- if (rafId !== undefined) {
- cancelAnimationFrame(rafId)
- rafId = undefined
- }
- }
-
- const schedulePollingStop = () => {
- if (pollTimeout !== undefined) clearTimeout(pollTimeout)
- pollTimeout = setTimeout(stopPolling, 1000)
- }
-
- const onActivity = () => {
- updateFade()
- if (local.trackTransformSelector) {
- startPolling()
- schedulePollingStop()
- }
- }
-
- containerRef.addEventListener("scroll", onActivity, { passive: true })
-
- const resizeObserver = new ResizeObserver(() => {
- lastScrollSize = 0
- lastClientSize = 0
- onActivity()
- })
- resizeObserver.observe(containerRef)
-
- const mutationObserver = new MutationObserver(() => {
- lastScrollSize = 0
- lastClientSize = 0
- requestAnimationFrame(onActivity)
- })
- mutationObserver.observe(containerRef, {
- childList: true,
- subtree: true,
- characterData: true,
- })
-
- onCleanup(() => {
- containerRef?.removeEventListener("scroll", onActivity)
- resizeObserver.disconnect()
- mutationObserver.disconnect()
- stopPolling()
- if (pollTimeout !== undefined) clearTimeout(pollTimeout)
- })
- })
-
- createEffect(() => {
- local.children
- requestAnimationFrame(updateFade)
- })
-
- return (
- <div
- ref={(el) => {
- containerRef = el
- local.ref?.(el)
- }}
- data-component="scroll-fade"
- data-direction={direction()}
- data-scrollable={isScrollable() || undefined}
- data-fade-start={fadeStart() > 0 || undefined}
- data-fade-end={fadeEnd() > 0 || undefined}
- class={local.class}
- style={{
- ...(typeof local.style === "object" ? local.style : {}),
- "--scroll-fade-start": `${fadeStart()}px`,
- "--scroll-fade-end": `${fadeEnd()}px`,
- }}
- {...others}
- >
- {local.children}
- </div>
- )
-}
diff --git a/packages/ui/src/components/scroll-reveal.tsx b/packages/ui/src/components/scroll-reveal.tsx
deleted file mode 100644
index 6e5072dc8..000000000
--- a/packages/ui/src/components/scroll-reveal.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-import { type JSX, onCleanup, splitProps } from "solid-js"
-import { ScrollFade, type ScrollFadeProps } from "./scroll-fade"
-
-const SCROLL_SPEED = 60
-const PAUSE_DURATION = 800
-
-type ScrollAnimationState = {
- rafId: number | null
- startTime: number
- running: boolean
-}
-
-const startScrollAnimation = (containerEl: HTMLElement): ScrollAnimationState | null => {
- containerEl.offsetHeight
-
- const extraWidth = containerEl.scrollWidth - containerEl.clientWidth
-
- if (extraWidth <= 0) {
- return null
- }
-
- const scrollDuration = (extraWidth / SCROLL_SPEED) * 1000
- const totalDuration = PAUSE_DURATION + scrollDuration + PAUSE_DURATION + scrollDuration + PAUSE_DURATION
-
- const state: ScrollAnimationState = {
- rafId: null,
- startTime: performance.now(),
- running: true,
- }
-
- const animate = (currentTime: number) => {
- if (!state.running) return
-
- const elapsed = currentTime - state.startTime
- const progress = (elapsed % totalDuration) / totalDuration
-
- const pausePercent = PAUSE_DURATION / totalDuration
- const scrollPercent = scrollDuration / totalDuration
-
- const pauseEnd1 = pausePercent
- const scrollEnd1 = pauseEnd1 + scrollPercent
- const pauseEnd2 = scrollEnd1 + pausePercent
- const scrollEnd2 = pauseEnd2 + scrollPercent
-
- let scrollPos = 0
-
- if (progress < pauseEnd1) {
- scrollPos = 0
- } else if (progress < scrollEnd1) {
- const scrollProgress = (progress - pauseEnd1) / scrollPercent
- scrollPos = scrollProgress * extraWidth
- } else if (progress < pauseEnd2) {
- scrollPos = extraWidth
- } else if (progress < scrollEnd2) {
- const scrollProgress = (progress - pauseEnd2) / scrollPercent
- scrollPos = extraWidth * (1 - scrollProgress)
- } else {
- scrollPos = 0
- }
-
- containerEl.scrollLeft = scrollPos
- state.rafId = requestAnimationFrame(animate)
- }
-
- state.rafId = requestAnimationFrame(animate)
- return state
-}
-
-const stopScrollAnimation = (state: ScrollAnimationState | null, containerEl?: HTMLElement) => {
- if (state) {
- state.running = false
- if (state.rafId !== null) {
- cancelAnimationFrame(state.rafId)
- }
- }
- if (containerEl) {
- containerEl.scrollLeft = 0
- }
-}
-
-export interface ScrollRevealProps extends Omit<ScrollFadeProps, "direction"> {
- hoverDelay?: number
-}
-
-export function ScrollReveal(props: ScrollRevealProps) {
- const [local, others] = splitProps(props, ["children", "hoverDelay", "ref"])
-
- const hoverDelay = () => local.hoverDelay ?? 300
-
- let containerRef: HTMLDivElement | undefined
- let hoverTimeout: ReturnType<typeof setTimeout> | undefined
- let scrollAnimationState: ScrollAnimationState | null = null
-
- const handleMouseEnter: JSX.EventHandler<HTMLDivElement, MouseEvent> = () => {
- hoverTimeout = setTimeout(() => {
- if (!containerRef) return
-
- containerRef.offsetHeight
-
- const isScrollable = containerRef.scrollWidth > containerRef.clientWidth + 1
-
- if (isScrollable) {
- stopScrollAnimation(scrollAnimationState, containerRef)
- scrollAnimationState = startScrollAnimation(containerRef)
- }
- }, hoverDelay())
- }
-
- const handleMouseLeave: JSX.EventHandler<HTMLDivElement, MouseEvent> = () => {
- if (hoverTimeout) {
- clearTimeout(hoverTimeout)
- hoverTimeout = undefined
- }
- stopScrollAnimation(scrollAnimationState, containerRef)
- scrollAnimationState = null
- }
-
- onCleanup(() => {
- if (hoverTimeout) {
- clearTimeout(hoverTimeout)
- }
- stopScrollAnimation(scrollAnimationState, containerRef)
- })
-
- return (
- <ScrollFade
- ref={(el) => {
- containerRef = el
- local.ref?.(el)
- }}
- fadeStartSize={8}
- fadeEndSize={8}
- direction="horizontal"
- onMouseEnter={handleMouseEnter}
- onMouseLeave={handleMouseLeave}
- {...others}
- >
- {local.children}
- </ScrollFade>
- )
-}
diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css
index d5939b2b3..55e1a16d1 100644
--- a/packages/ui/src/styles/index.css
+++ b/packages/ui/src/styles/index.css
@@ -41,7 +41,6 @@
@import "../components/select.css" layer(components);
@import "../components/spinner.css" layer(components);
@import "../components/switch.css" layer(components);
-@import "../components/scroll-fade.css" layer(components);
@import "../components/session-review.css" layer(components);
@import "../components/session-turn.css" layer(components);
@import "../components/sticky-accordion-header.css" layer(components);