fix(chat): repair Arco migration fallout in the chat page

The Phase 006 walkthrough surfaced four issues the automated checks could
not see. Dead naive-ui class names left behind by the migration stopped
matching, tooltips that carried their label as trailing default-slot text
leaked that text into the flex row, the workspace panel squeezed the chat
column until the input toolbar wrapped, and the Escape fallback still
looked for naive-ui's modal mask.

Tooltips now pass their label through the content prop, the tool panel
reserves a minimum width for the chat column, and Escape finds the visible
Arco modal and clicks its close button.
This commit is contained in:
2026-10-18 03:11:35 +08:00
parent effc29085c
commit c3eeea4187
10 changed files with 181 additions and 85 deletions
@@ -1048,11 +1048,10 @@ function isImage(type: string): boolean {
<div v-if="showContextUsage" class="context-usage-row">
<span class="context-info" :class="{ 'context-warning': usagePercent > 80 }">
{{ formatTokens(totalTokens) }} /
<a-tooltip trigger="hover" :disabled="isMobileViewport">
<a-tooltip trigger="hover" :disabled="isMobileViewport" :content="t('chat.contextClickToEdit')">
<span class="context-limit-editable" @click="handleEditContextLimit">
{{ formatTokens(contextLength) }}
</span>
<span>{{ t('chat.contextClickToEdit') }}</span>
</a-tooltip>
· {{ t('chat.contextRemaining') }} {{ formatTokens(remainingTokens) }}
</span>
@@ -1083,13 +1082,16 @@ function isImage(type: string): boolean {
<div class="input-toolbar">
<!-- Bottom bar: attach + input settings + actions -->
<div class="input-top-bar">
<a-tooltip trigger="hover" :disabled="isMobileViewport">
<a-tooltip
trigger="hover"
:disabled="isMobileViewport"
:content="t('chat.attachFiles')"
>
<a-button type="secondary" size="mini" shape="circle" @click="handleAttachClick" class="toolbar-icon-button">
<template #icon>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
</template>
</a-button>
{{ t('chat.attachFiles') }}
</a-tooltip>
<a-dropdown
@@ -1159,7 +1161,11 @@ function isImage(type: string): boolean {
</template>
</a-dropdown>
<a-tooltip trigger="hover" :disabled="isMobileViewport">
<a-tooltip
trigger="hover"
:disabled="isMobileViewport"
:content="props.modelLabel || t('models.selectModel')"
>
<a-button
type="secondary"
size="mini"
@@ -1193,7 +1199,6 @@ function isImage(type: string): boolean {
<span class="input-model-label">{{ compactModelLabel }}</span>
<svg class="toolbar-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6"/></svg>
</a-button>
{{ props.modelLabel || t('models.selectModel') }}
</a-tooltip>
</div>
@@ -1386,8 +1391,8 @@ function isImage(type: string): boolean {
}
}
:deep(.n-switch),
:deep(.n-switch__rail) {
:deep(.arco-switch),
:deep(.arco-switch-track) {
margin-right: 0;
}
}
@@ -1405,12 +1410,6 @@ function isImage(type: string): boolean {
background: transparent !important;
opacity: 1;
:deep(.n-button__state-border),
:deep(.n-button__border),
:deep(.n-button__ripple) {
display: none;
}
.tool-trace-icon {
display: block;
flex: 0 0 16px;
@@ -1433,16 +1432,8 @@ function isImage(type: string): boolean {
color: $text-secondary;
border-radius: 999px;
padding: 0 7px 0 6px;
:deep(.n-button__content) {
gap: 4px;
}
:deep(.n-button__state-border),
:deep(.n-button__border),
:deep(.n-button__ripple) {
display: none;
}
gap: 4px;
border-color: transparent;
}
.input-model-button {
@@ -1450,17 +1441,8 @@ function isImage(type: string): boolean {
border-radius: 999px;
max-width: 190px;
padding: 0 4px 0 6px;
:deep(.n-button__content) {
gap: 4px;
min-width: 0;
}
:deep(.n-button__state-border),
:deep(.n-button__border),
:deep(.n-button__ripple) {
display: none;
}
gap: 4px;
border-color: transparent;
}
.input-model-label {
@@ -1476,15 +1458,12 @@ function isImage(type: string): boolean {
color: $text-secondary;
border-radius: 999px;
padding: 0 4px 0 6px;
gap: 4px;
border-color: transparent;
&.active {
color: #4caf50;
}
:deep(.n-button__content) {
gap: 4px;
min-width: 0;
}
}
.reasoning-effort-label {
@@ -1625,14 +1604,7 @@ function isImage(type: string): boolean {
.input-settings-button {
min-width: 36px;
padding: 0 4px 0 6px;
:deep(.n-button__content) {
gap: 2px;
}
:deep(.n-button__icon) {
margin: 0;
}
gap: 2px;
}
.input-settings-label {
@@ -1820,6 +1792,7 @@ function isImage(type: string): boolean {
gap: 12px;
margin-top: auto;
min-height: 32px;
flex-wrap: nowrap;
}
.toolbar-icon-button {
@@ -1833,22 +1806,12 @@ function isImage(type: string): boolean {
padding: 0 !important;
border: 0 !important;
box-shadow: none !important;
gap: 0;
:deep(.n-button__icon) {
:deep(.arco-btn-icon) {
margin: 0 !important;
}
:deep(.n-button__content) {
display: none;
}
:deep(.n-button__border),
:deep(.n-button__state-border),
:deep(.n-button__ripple),
:deep(.n-base-wave) {
display: none;
}
&:disabled {
color: var(--text-on-overlay);
background-color: #9f9f9f;