fix(ui): unify thinking controls with icon buttons
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, untrack } from "solid-js"
|
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, untrack } from "solid-js"
|
||||||
import { ExternalLink, FoldVertical, Trash2 } from "lucide-solid"
|
import { ChevronsDownUp, ChevronsUpDown, ExternalLink, FoldVertical, Trash2 } from "lucide-solid"
|
||||||
import MessageItem from "./message-item"
|
import MessageItem from "./message-item"
|
||||||
import ToolCall from "./tool-call"
|
import ToolCall from "./tool-call"
|
||||||
import type { InstanceMessageStore } from "../stores/message-v2/instance-store"
|
import type { InstanceMessageStore } from "../stores/message-v2/instance-store"
|
||||||
@@ -1010,10 +1010,13 @@ function ReasoningCard(props: ReasoningCardProps) {
|
|||||||
|
|
||||||
const toggle = () => setExpanded((prev) => !prev)
|
const toggle = () => setExpanded((prev) => !prev)
|
||||||
|
|
||||||
|
const viewHideLabel = () =>
|
||||||
|
expanded() ? t("messageBlock.reasoning.indicator.hide") : t("messageBlock.reasoning.indicator.view")
|
||||||
|
|
||||||
const hasDeleteTarget = () => Boolean(props.partId)
|
const hasDeleteTarget = () => Boolean(props.partId)
|
||||||
const canDelete = () => hasDeleteTarget() && !deleting()
|
const canDelete = () => hasDeleteTarget() && !deleting()
|
||||||
|
|
||||||
const handleDelete = async (event: Event) => {
|
const handleDelete = async (event: MouseEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
if (!canDelete()) return
|
if (!canDelete()) return
|
||||||
@@ -1033,56 +1036,66 @@ function ReasoningCard(props: ReasoningCardProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="message-reasoning-card">
|
<div class="message-reasoning-card">
|
||||||
<button
|
<div class="message-reasoning-header">
|
||||||
type="button"
|
<button
|
||||||
class="message-reasoning-toggle"
|
type="button"
|
||||||
onClick={toggle}
|
class="message-reasoning-toggle"
|
||||||
aria-expanded={expanded()}
|
onClick={toggle}
|
||||||
aria-label={expanded() ? t("messageBlock.reasoning.collapseAriaLabel") : t("messageBlock.reasoning.expandAriaLabel")}
|
aria-expanded={expanded()}
|
||||||
>
|
aria-label={expanded() ? t("messageBlock.reasoning.collapseAriaLabel") : t("messageBlock.reasoning.expandAriaLabel")}
|
||||||
<span class="message-reasoning-label flex flex-wrap items-center gap-2">
|
>
|
||||||
<span>{t("messageBlock.reasoning.thinkingLabel")}</span>
|
<span class="message-reasoning-label flex flex-wrap items-center gap-2">
|
||||||
<Show when={props.showAgentMeta && (agentIdentifier() || modelIdentifier())}>
|
<span>{t("messageBlock.reasoning.thinkingLabel")}</span>
|
||||||
<span class="message-step-meta-inline">
|
<Show when={props.showAgentMeta && (agentIdentifier() || modelIdentifier())}>
|
||||||
<Show when={agentIdentifier()}>
|
<span class="message-step-meta-inline">
|
||||||
{(value) => (
|
<Show when={agentIdentifier()}>
|
||||||
<span class="font-medium text-[var(--message-assistant-border)]">{t("messageBlock.step.agentLabel", { agent: value() })}</span>
|
{(value) => (
|
||||||
)}
|
<span class="font-medium text-[var(--message-assistant-border)]">{t("messageBlock.step.agentLabel", { agent: value() })}</span>
|
||||||
</Show>
|
)}
|
||||||
<Show when={modelIdentifier()}>
|
</Show>
|
||||||
{(value) => (
|
<Show when={modelIdentifier()}>
|
||||||
<span class="font-medium text-[var(--message-assistant-border)]">{t("messageBlock.step.modelLabel", { model: value() })}</span>
|
{(value) => (
|
||||||
)}
|
<span class="font-medium text-[var(--message-assistant-border)]">{t("messageBlock.step.modelLabel", { model: value() })}</span>
|
||||||
</Show>
|
)}
|
||||||
</span>
|
</Show>
|
||||||
</Show>
|
</span>
|
||||||
</span>
|
</Show>
|
||||||
<span class="message-reasoning-meta">
|
|
||||||
<span class="message-reasoning-indicator">
|
|
||||||
{expanded() ? t("messageBlock.reasoning.indicator.hide") : t("messageBlock.reasoning.indicator.view")}
|
|
||||||
</span>
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="message-reasoning-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="message-action-button"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
toggle()
|
||||||
|
}}
|
||||||
|
aria-label={viewHideLabel()}
|
||||||
|
title={viewHideLabel()}
|
||||||
|
>
|
||||||
|
<Show when={expanded()} fallback={<ChevronsUpDown class="w-3.5 h-3.5" aria-hidden="true" />}>
|
||||||
|
<ChevronsDownUp class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
|
</Show>
|
||||||
|
</button>
|
||||||
|
|
||||||
<Show when={hasDeleteTarget()}>
|
<Show when={hasDeleteTarget()}>
|
||||||
<span
|
<button
|
||||||
class={`message-reasoning-indicator${canDelete() ? "" : " opacity-50 pointer-events-none"}`}
|
type="button"
|
||||||
role="button"
|
class="message-action-button"
|
||||||
tabIndex={0}
|
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
onKeyDown={(event) => {
|
disabled={!canDelete()}
|
||||||
if (event.key === "Enter" || event.key === " ") {
|
|
||||||
handleDelete(event)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
aria-label={t("messagePart.actions.deleteTitle")}
|
aria-label={t("messagePart.actions.deleteTitle")}
|
||||||
title={t("messagePart.actions.deleteTitle")}
|
title={t("messagePart.actions.deleteTitle")}
|
||||||
>
|
>
|
||||||
{deleting() ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
<Trash2 class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</span>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<span class="message-reasoning-time">{timestamp()}</span>
|
<span class="message-reasoning-time">{timestamp()}</span>
|
||||||
</span>
|
</div>
|
||||||
</button>
|
</div>
|
||||||
|
|
||||||
<Show when={expanded()}>
|
<Show when={expanded()}>
|
||||||
<div class="message-reasoning-expanded">
|
<div class="message-reasoning-expanded">
|
||||||
|
|||||||
@@ -305,19 +305,6 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
>
|
>
|
||||||
<Copy class="w-3.5 h-3.5" aria-hidden="true" />
|
<Copy class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
<Show when={deletableTextPartId()}>
|
|
||||||
{(partId) => (
|
|
||||||
<button
|
|
||||||
class="message-action-button"
|
|
||||||
onClick={() => void handleDeletePart(partId())}
|
|
||||||
disabled={isDeletingPart(partId())}
|
|
||||||
title={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
|
||||||
aria-label={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
|
||||||
>
|
|
||||||
<Trash2 class="w-3.5 h-3.5" aria-hidden="true" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</Show>
|
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={!isUser()}>
|
<Show when={!isUser()}>
|
||||||
|
|||||||
@@ -298,11 +298,20 @@
|
|||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-reasoning-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.message-reasoning-toggle {
|
.message-reasoning-toggle {
|
||||||
width: 100%;
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
width: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: flex-start;
|
||||||
gap: 0.65rem;
|
gap: 0.65rem;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -314,6 +323,13 @@
|
|||||||
transition: background-color 0.2s ease, box-shadow 0.2s ease;
|
transition: background-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-reasoning-actions {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.25rem 0.6rem 0.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
.message-reasoning-toggle:hover {
|
.message-reasoning-toggle:hover {
|
||||||
background-color: var(--surface-hover);
|
background-color: var(--surface-hover);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user