diff options
Diffstat (limited to 'src/features/chat/ui')
| -rw-r--r-- | src/features/chat/ui/ChatView.svelte | 32 | ||||
| -rw-r--r-- | src/features/chat/ui/Composer.svelte | 6 | ||||
| -rw-r--r-- | src/features/chat/ui/ModelSelector.svelte | 22 |
3 files changed, 42 insertions, 18 deletions
diff --git a/src/features/chat/ui/ChatView.svelte b/src/features/chat/ui/ChatView.svelte index ce66798..cb6069b 100644 --- a/src/features/chat/ui/ChatView.svelte +++ b/src/features/chat/ui/ChatView.svelte @@ -4,14 +4,16 @@ let { chunks }: { chunks: readonly RenderedChunk[] } = $props(); </script> -<div class="chat-transcript" role="log" aria-live="polite"> +<div class="flex flex-col gap-2 p-4" role="log" aria-live="polite"> {#each chunks as rendered, i (rendered.seq != null ? `c${rendered.seq}` : `p${i}`)} - <article - class="message message--{rendered.role}" - class:message--provisional={rendered.provisional} - > - <header class="message__role">{rendered.role}</header> - <div class="message__content"> + <div class="chat {rendered.role === 'user' ? 'chat-start' : 'chat-end'}"> + <div class="chat-header text-xs opacity-70">{rendered.role}</div> + <div + class="chat-bubble" + class:chat-bubble-primary={rendered.role === "user"} + class:chat-bubble-secondary={rendered.role === "assistant"} + class:opacity-50={rendered.provisional} + > {#if rendered.chunk.type === "text"} <p>{rendered.chunk.text}</p> {:else if rendered.chunk.type === "thinking"} @@ -20,26 +22,26 @@ <p>{rendered.chunk.text}</p> </details> {:else if rendered.chunk.type === "tool-call"} - <div class="tool-call"> + <div class="text-sm"> <strong>{rendered.chunk.toolName}</strong> - <pre>{JSON.stringify(rendered.chunk.input, null, 2)}</pre> + <pre class="text-xs mt-1">{JSON.stringify(rendered.chunk.input, null, 2)}</pre> </div> {:else if rendered.chunk.type === "tool-result"} - <div class="tool-result" class:tool-result--error={rendered.chunk.isError}> + <div class="text-sm" class:text-error={rendered.chunk.isError}> <strong>{rendered.chunk.toolName}</strong> - <pre>{rendered.chunk.content}</pre> + <pre class="text-xs mt-1">{rendered.chunk.content}</pre> </div> {:else if rendered.chunk.type === "error"} - <div class="error" role="alert"> + <div class="text-error" role="alert"> {rendered.chunk.message} {#if rendered.chunk.code} - <span class="error__code">[{rendered.chunk.code}]</span> + <span class="text-xs opacity-70">[{rendered.chunk.code}]</span> {/if} </div> {:else if rendered.chunk.type === "system"} - <div class="system">{rendered.chunk.text}</div> + <div class="text-sm opacity-70">{rendered.chunk.text}</div> {/if} </div> - </article> + </div> {/each} </div> diff --git a/src/features/chat/ui/Composer.svelte b/src/features/chat/ui/Composer.svelte index dc71e11..3762340 100644 --- a/src/features/chat/ui/Composer.svelte +++ b/src/features/chat/ui/Composer.svelte @@ -18,16 +18,16 @@ } </script> -<form class="composer" onsubmit={prevent => { prevent.preventDefault(); handleSubmit(); }}> +<form class="flex gap-2 p-4" onsubmit={(e) => { e.preventDefault(); handleSubmit(); }}> <textarea - class="composer__input" + class="textarea textarea-bordered flex-1" bind:value={text} onkeydown={handleKeydown} placeholder="Type a message..." rows="3" aria-label="Message input" ></textarea> - <button class="composer__send" type="submit" disabled={text.trim().length === 0}> + <button class="btn btn-primary" type="submit" disabled={text.trim().length === 0}> Send </button> </form> diff --git a/src/features/chat/ui/ModelSelector.svelte b/src/features/chat/ui/ModelSelector.svelte new file mode 100644 index 0000000..3e25ec3 --- /dev/null +++ b/src/features/chat/ui/ModelSelector.svelte @@ -0,0 +1,22 @@ +<script lang="ts"> + let { + models, + selected, + onSelect, + }: { + models: readonly string[]; + selected: string; + onSelect: (model: string) => void; + } = $props(); +</script> + +<select + class="select" + value={selected} + onchange={(e) => onSelect(e.currentTarget.value)} + aria-label="Model selector" +> + {#each models as model (model)} + <option value={model}>{model}</option> + {/each} +</select> |
