From f386137fbaf2e2f56fb32f8656e802f592a41341 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 8 Mar 2026 06:34:02 -0500 Subject: chore: refactoring ui hooks --- packages/ui/src/components/tool-utils.ts | 101 +++++++++++++++++-------------- 1 file changed, 56 insertions(+), 45 deletions(-) (limited to 'packages/ui/src/components/tool-utils.ts') diff --git a/packages/ui/src/components/tool-utils.ts b/packages/ui/src/components/tool-utils.ts index 171649e3d..4d57c626e 100644 --- a/packages/ui/src/components/tool-utils.ts +++ b/packages/ui/src/components/tool-utils.ts @@ -1,4 +1,6 @@ +import type { ToolPart } from "@opencode-ai/sdk/v2" import { createEffect, createMemo, createSignal, on, onCleanup, onMount } from "solid-js" +import { useReducedMotion } from "../hooks/use-reduced-motion" import { animate, type AnimationPlaybackControls, @@ -8,8 +10,6 @@ import { GROW_SPRING, WIPE_MASK, } from "./motion" -import { prefersReducedMotion } from "../hooks/use-reduced-motion" -import type { ToolPart } from "@opencode-ai/sdk/v2" export const TEXT_RENDER_THROTTLE_MS = 100 @@ -106,57 +106,67 @@ export function useCollapsible(options: { measure?: () => number onOpen?: () => void }) { + const reduce = useReducedMotion() let heightAnim: AnimationPlaybackControls | undefined let fadeAnim: AnimationPlaybackControls | undefined let gen = 0 createEffect( - on( - options.open, - (isOpen) => { - const content = options.content() - const body = options.body() - if (!content || !body) return - heightAnim?.stop() - fadeAnim?.stop() - const id = ++gen + on(options.open, (isOpen) => { + const content = options.content() + const body = options.body() + if (!content || !body) return + heightAnim?.stop() + fadeAnim?.stop() + if (reduce()) { + body.style.opacity = "" + body.style.filter = "" if (isOpen) { content.style.display = "" - content.style.height = "0px" - body.style.opacity = "0" - body.style.filter = "blur(2px)" - fadeAnim = animate(body, { opacity: [0, 1], filter: ["blur(2px)", "blur(0px)"] }, COLLAPSIBLE_SPRING) - queueMicrotask(() => { - if (gen !== id) return - const c = options.content() - if (!c) return - const h = options.measure?.() ?? Math.ceil(body.getBoundingClientRect().height) - heightAnim = animate(c, { height: ["0px", `${h}px`] }, COLLAPSIBLE_SPRING) - heightAnim.finished.then( - () => { - if (gen !== id) return - c.style.height = "auto" - options.onOpen?.() - }, - () => {}, - ) - }) + content.style.height = "auto" + options.onOpen?.() return } + content.style.height = "0px" + content.style.display = "none" + return + } + const id = ++gen + if (isOpen) { + content.style.display = "" + content.style.height = "0px" + body.style.opacity = "0" + body.style.filter = "blur(2px)" + fadeAnim = animate(body, { opacity: [0, 1], filter: ["blur(2px)", "blur(0px)"] }, COLLAPSIBLE_SPRING) + queueMicrotask(() => { + if (gen !== id) return + const c = options.content() + if (!c) return + const h = options.measure?.() ?? Math.ceil(body.getBoundingClientRect().height) + heightAnim = animate(c, { height: ["0px", `${h}px`] }, COLLAPSIBLE_SPRING) + heightAnim.finished.then( + () => { + if (gen !== id) return + c.style.height = "auto" + options.onOpen?.() + }, + () => {}, + ) + }) + return + } - const h = content.getBoundingClientRect().height - heightAnim = animate(content, { height: [`${h}px`, "0px"] }, COLLAPSIBLE_SPRING) - fadeAnim = animate(body, { opacity: [1, 0], filter: ["blur(0px)", "blur(2px)"] }, COLLAPSIBLE_SPRING) - heightAnim.finished.then( - () => { - if (gen !== id) return - content.style.display = "none" - }, - () => {}, - ) - }, - { defer: true }, - ), + const h = content.getBoundingClientRect().height + heightAnim = animate(content, { height: [`${h}px`, "0px"] }, COLLAPSIBLE_SPRING) + fadeAnim = animate(body, { opacity: [1, 0], filter: ["blur(0px)", "blur(2px)"] }, COLLAPSIBLE_SPRING) + heightAnim.finished.then( + () => { + if (gen !== id) return + content.style.display = "none" + }, + () => {}, + ) + }), ) onCleanup(() => { @@ -181,7 +191,7 @@ export function useRowWipe(opts: { ref: () => HTMLElement | undefined seen: Set }) { - const reduce = prefersReducedMotion + const reduce = useReducedMotion() createEffect(() => { const id = opts.id() @@ -265,13 +275,14 @@ export function useToolFade( const delay = options?.delay ?? 0 const wipe = options?.wipe ?? false const active = options?.animate !== false + const reduce = useReducedMotion() onMount(() => { if (!active) return const el = ref() if (!el || typeof window === "undefined") return - if (prefersReducedMotion()) return + if (reduce()) return const mask = wipe && -- cgit v1.2.3