mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 09:44:21 +01:00
96 lines
3.4 KiB
TypeScript
96 lines
3.4 KiB
TypeScript
import { children, For, Match, Show, Switch, type JSX } from "solid-js"
|
|
import { Collapsible } from "./collapsible"
|
|
import { Icon, IconProps } from "./icon"
|
|
|
|
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 && !(val instanceof Node)
|
|
}
|
|
|
|
export interface BasicToolProps {
|
|
icon: IconProps["name"]
|
|
trigger: TriggerTitle | JSX.Element
|
|
children?: JSX.Element
|
|
hideDetails?: boolean
|
|
}
|
|
|
|
export function BasicTool(props: BasicToolProps) {
|
|
const resolved = children(() => props.children)
|
|
return (
|
|
<Collapsible>
|
|
<Collapsible.Trigger>
|
|
<div data-component="tool-trigger">
|
|
<div data-slot="tool-trigger-content">
|
|
<Icon name={props.icon} size="small" data-slot="tool-icon" />
|
|
<div data-slot="tool-info">
|
|
<Switch>
|
|
<Match when={isTriggerTitle(props.trigger) && props.trigger}>
|
|
{(trigger) => (
|
|
<div data-slot="tool-info-structured">
|
|
<div data-slot="tool-info-main">
|
|
<span
|
|
data-slot="tool-title"
|
|
classList={{
|
|
[trigger().titleClass ?? ""]: !!trigger().titleClass,
|
|
}}
|
|
>
|
|
{trigger().title}
|
|
</span>
|
|
<Show when={trigger().subtitle}>
|
|
<span
|
|
data-slot="tool-subtitle"
|
|
classList={{
|
|
[trigger().subtitleClass ?? ""]: !!trigger().subtitleClass,
|
|
}}
|
|
>
|
|
{trigger().subtitle}
|
|
</span>
|
|
</Show>
|
|
<Show when={trigger().args?.length}>
|
|
<For each={trigger().args}>
|
|
{(arg) => (
|
|
<span
|
|
data-slot="tool-arg"
|
|
classList={{
|
|
[trigger().argsClass ?? ""]: !!trigger().argsClass,
|
|
}}
|
|
>
|
|
{arg}
|
|
</span>
|
|
)}
|
|
</For>
|
|
</Show>
|
|
</div>
|
|
<Show when={trigger().action}>{trigger().action}</Show>
|
|
</div>
|
|
)}
|
|
</Match>
|
|
<Match when={true}>{props.trigger as JSX.Element}</Match>
|
|
</Switch>
|
|
</div>
|
|
</div>
|
|
<Show when={resolved() && !props.hideDetails}>
|
|
<Collapsible.Arrow />
|
|
</Show>
|
|
</div>
|
|
</Collapsible.Trigger>
|
|
<Show when={resolved() && !props.hideDetails}>
|
|
<Collapsible.Content>{resolved()}</Collapsible.Content>
|
|
</Show>
|
|
</Collapsible>
|
|
)
|
|
}
|
|
|
|
export function GenericTool(props: { tool: string; hideDetails?: boolean }) {
|
|
return <BasicTool icon="mcp" trigger={{ title: props.tool }} hideDetails={props.hideDetails} />
|
|
}
|