style(ui): restore compact tool output language

Keep the expanded tool-arguments view using the full Tool Output header while restoring the normal no-arguments view to a compact output chrome that shows only the language label and right-aligned actions.

This preserves access to copy and word-wrap controls for markdown-backed tool output without adding the redundant Tool Output label when tool arguments are disabled.

Validated with npm run typecheck --workspace @codenomad/ui.
This commit is contained in:
Shantur Rathore 2026-06-18 10:45:11 +01:00
parent 2cc6630d40
commit 4e63aeaced
2 changed files with 92 additions and 9 deletions

View file

@ -583,6 +583,55 @@ function ToolCallDetails(props: {
</div>
)
const renderOutputActions = (options: {
language?: () => string | null | undefined
copyText?: () => string | null | undefined
actions?: () => JSXElement
wrapToggle?: () => boolean | undefined
}) => (
<div class="tool-call-output-actions">
<Show when={options.language?.()}>
{(language) => <span class="tool-call-output-language">{language()}</span>}
</Show>
<span class="tool-call-output-action-buttons">
<Show when={options.actions?.()}>
{(actions) => <span class="tool-call-io-actions">{actions()}</span>}
</Show>
<Show when={options.copyText?.()}>
{(copyText) => (
<button
type="button"
class="tool-call-header-icon-button tool-call-header-copy tool-call-output-copy"
onClick={(event) => void copyIoText(event, copyText())}
aria-label={props.t("toolCall.header.copyAriaLabel")}
title={props.t("toolCall.header.copyTitle")}
>
<Copy class="w-3.5 h-3.5" aria-hidden="true" />
</button>
)}
</Show>
<Show when={options.wrapToggle?.()}>
<button
type="button"
class={`tool-call-header-icon-button tool-call-header-copy tool-call-output-wrap${outputWrapEnabled() ? " active" : ""}`}
onClick={(event) => {
event.preventDefault()
event.stopPropagation()
setOutputWrapEnabled((enabled) => !enabled)
}}
aria-label={outputWrapTitle()}
title={outputWrapTitle()}
>
<WrapText class="w-3.5 h-3.5" aria-hidden="true" />
</button>
</Show>
</span>
</div>
)
const renderToolOutputBody = () => {
const body = renderToolBody()
const error = renderError()
@ -596,19 +645,14 @@ function ToolCallDetails(props: {
if (chrome.wrapToggle) {
return (
<div class="tool-call-body">
<div class="tool-call-io-section">
{renderIoHeader({
title: () => chrome.title || props.t("toolCall.io.output"),
{renderOutputActions({
language: () => outputChrome().language,
expanded: props.outputSectionExpanded,
onToggle: props.toggleOutputSection,
copyText: () => outputChrome().copyText,
actions: () => outputChrome().actions,
wrapToggle: () => outputChrome().wrapToggle,
})}
<Show when={props.outputSectionExpanded()}>
<div class="tool-call-io-body" data-suppress-inner-header={chrome.suppressInnerHeader === false ? undefined : "true"}>
<div class="tool-call-io-body" data-suppress-inner-header={chrome.suppressInnerHeader === false ? undefined : "true"}>
{body}
{error}
@ -618,8 +662,6 @@ function ToolCallDetails(props: {
<span>{props.t("toolCall.pending.waitingToRun")}</span>
</div>
</Show>
</div>
</Show>
</div>
</div>
)

View file

@ -386,6 +386,47 @@
color: var(--text-primary);
}
.tool-call-output-actions {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-xs);
min-height: 1.6rem;
padding-inline-start: var(--space-sm);
padding-inline-end: var(--space-sm);
background-color: var(--surface-secondary);
border-bottom: 1px solid var(--tool-call-body-border-color, var(--border-base));
}
.tool-call-output-language {
flex: 0 1 auto;
min-width: 0;
font-family: var(--message-part-header-font-family);
font-size: var(--message-part-header-type-font-size);
font-weight: var(--message-part-header-type-font-weight);
line-height: var(--message-part-header-title-line-height);
color: var(--text-primary);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.tool-call-output-action-buttons {
display: inline-flex;
align-items: center;
justify-content: flex-end;
gap: var(--space-xs);
flex: 0 0 auto;
}
.tool-call-output-copy,
.tool-call-output-wrap {
margin-inline-end: 0;
}
.tool-call-output-wrap.active {
color: var(--text-primary);
}
.tool-call-io-body {
background-color: var(--surface-code);
}