import { createEffect, createSignal, For, Match, on, onCleanup, Show, Switch, type JSX } from "solid-js" import { Collapsible } from "./collapsible" import type { IconProps } from "./icon" import { TextShimmer } from "./text-shimmer" export type TriggerTitle = { title: string titleClass?: string subtitle?: string subtitleClass?: string args?: string[] argsClass?: string action?: JSX.Element } const isTriggerTitle = (val: any): val is TriggerTitle => { return ( typeof val === "object" && val !== null && "title" in val && (typeof Node === "undefined" || !(val instanceof Node)) ) } export interface BasicToolProps { icon: IconProps["name"] trigger: TriggerTitle | JSX.Element children?: JSX.Element status?: string hideDetails?: boolean defaultOpen?: boolean forceOpen?: boolean defer?: boolean locked?: boolean onSubtitleClick?: () => void } export function BasicTool(props: BasicToolProps) { const [open, setOpen] = createSignal(props.defaultOpen ?? false) const [ready, setReady] = createSignal(open()) const pending = () => props.status === "pending" || props.status === "running" let frame: number | undefined const cancel = () => { if (frame === undefined) return cancelAnimationFrame(frame) frame = undefined } onCleanup(cancel) createEffect(() => { if (props.forceOpen) setOpen(true) }) createEffect( on( open, (value) => { if (!props.defer) return if (!value) { cancel() setReady(false) return } cancel() frame = requestAnimationFrame(() => { frame = undefined if (!open()) return setReady(true) }) }, { defer: true }, ), ) const handleOpenChange = (value: boolean) => { if (pending()) return if (props.locked && !value) return setOpen(value) } return ( {(trigger) => ( { if (props.onSubtitleClick) { e.stopPropagation() props.onSubtitleClick() } }} > {trigger().subtitle} {(arg) => ( {arg} )} {trigger().action} )} {props.trigger as JSX.Element} {props.children} ) } export function GenericTool(props: { tool: string; status?: string; hideDetails?: boolean }) { return }