summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/message-nav.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-11-22 18:17:45 -0600
committerAdam <[email protected]>2025-11-22 18:19:02 -0600
commit6173b69a8b4af8e11498bbf203ffda0247da3196 (patch)
tree53c70e2514dd325d89e427d10dec02cd6077a3c1 /packages/ui/src/components/message-nav.tsx
parentfc72cfe784433293b50f7fd771bc3a1b5a1c8f9a (diff)
downloadopencode-6173b69a8b4af8e11498bbf203ffda0247da3196.tar.gz
opencode-6173b69a8b4af8e11498bbf203ffda0247da3196.zip
wip(share): more styling
Diffstat (limited to 'packages/ui/src/components/message-nav.tsx')
-rw-r--r--packages/ui/src/components/message-nav.tsx66
1 files changed, 66 insertions, 0 deletions
diff --git a/packages/ui/src/components/message-nav.tsx b/packages/ui/src/components/message-nav.tsx
new file mode 100644
index 000000000..8475c3206
--- /dev/null
+++ b/packages/ui/src/components/message-nav.tsx
@@ -0,0 +1,66 @@
+import { UserMessage } from "@opencode-ai/sdk"
+import { ComponentProps, createMemo, For, Match, Show, splitProps, Switch } from "solid-js"
+import { DiffChanges } from "./diff-changes"
+import { Spinner } from "./spinner"
+
+export function MessageNav(
+ props: ComponentProps<"ul"> & {
+ messages: UserMessage[]
+ current?: UserMessage
+ size: "normal" | "compact"
+ working?: boolean
+ onMessageSelect: (message: UserMessage) => void
+ },
+) {
+ const [local, others] = splitProps(props, ["messages", "current", "size", "working", "onMessageSelect"])
+ const lastUserMessage = createMemo(() => {
+ return local.messages?.at(0)
+ })
+
+ return (
+ <ul role="list" data-component="message-nav" data-size={local.size} {...others}>
+ <For each={local.messages}>
+ {(message) => {
+ const messageWorking = createMemo(() => message.id === lastUserMessage()?.id && local.working)
+ const handleClick = () => local.onMessageSelect(message)
+
+ return (
+ <li data-slot="message-nav-item">
+ <Switch>
+ <Match when={local.size === "compact"}>
+ <button
+ data-slot="message-nav-tick-button"
+ data-active={message.id === local.current?.id || undefined}
+ onClick={handleClick}
+ >
+ <div data-slot="message-nav-tick-line" />
+ </button>
+ </Match>
+ <Match when={local.size === "normal"}>
+ <button data-slot="message-nav-message-button" onClick={handleClick}>
+ <Switch>
+ <Match when={messageWorking()}>
+ <Spinner />
+ </Match>
+ <Match when={true}>
+ <DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
+ </Match>
+ </Switch>
+ <div
+ data-slot="message-nav-title-preview"
+ data-active={message.id === local.current?.id || undefined}
+ >
+ <Show when={message.summary?.title} fallback="New message">
+ {message.summary?.title}
+ </Show>
+ </div>
+ </button>
+ </Match>
+ </Switch>
+ </li>
+ )
+ }}
+ </For>
+ </ul>
+ )
+}