diff --git a/src/vs/sessions/contrib/chat/browser/media/chatWidget.css b/src/vs/sessions/contrib/chat/browser/media/chatWidget.css index 0ecc09577d9..785c0773b33 100644 --- a/src/vs/sessions/contrib/chat/browser/media/chatWidget.css +++ b/src/vs/sessions/contrib/chat/browser/media/chatWidget.css @@ -116,33 +116,59 @@ font-size: 16px; } -/* Attach context button */ +/* Attach context button (matches AddFilesButton from chatInputPart) */ .sessions-chat-attach-button { display: flex; align-items: center; - justify-content: center; - width: 26px; - height: 26px; - border-radius: 4px; - cursor: pointer; - color: var(--vscode-descriptionForeground); - background: transparent; - border: none; - outline: none; } -.sessions-chat-attach-button:hover { +.sessions-chat-attach-button.chat-attachment-button .action-label { + display: flex; + overflow: hidden; + font-size: 11px; + padding: 0 4px; + border: 1px solid var(--vscode-chat-requestBorder, var(--vscode-input-background, transparent)); + border-radius: 4px; + height: 18px; + max-width: 100%; + width: fit-content; + cursor: pointer; + color: var(--vscode-descriptionForeground); + text-decoration: none; + align-items: center; + gap: 2px; + white-space: nowrap; +} + +.sessions-chat-attach-button.chat-attachment-button .action-label:hover { background-color: var(--vscode-toolbar-hoverBackground); color: var(--vscode-foreground); } -.sessions-chat-attach-button:focus-visible { +.sessions-chat-attach-button.chat-attachment-button .action-label:focus-visible { outline: 1px solid var(--vscode-focusBorder); outline-offset: -1px; } -.sessions-chat-attach-button .codicon { - font-size: 16px; +.sessions-chat-attach-button.chat-attachment-button .action-label > .codicon { + font-size: 14px; + height: auto; +} + +.sessions-chat-attach-button.chat-attachment-button .action-label:not(.has-label) { + display: flex; + align-items: center; + justify-content: center; + padding: 2px 4px; + height: fit-content; + gap: 0; + border: 1px solid var(--vscode-chat-requestBorder, var(--vscode-input-background, transparent)); + border-radius: 4px; + box-sizing: border-box; +} + +.sessions-chat-attach-button.chat-attachment-button .action-label:not(.has-label) .codicon { + width: 14px; } /* Attached context container */ diff --git a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts index bef050ad7fa..baa93c3d156 100644 --- a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts +++ b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts @@ -32,7 +32,7 @@ import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { IThemeService } from '../../../../platform/theme/common/themeService.js'; import { IHoverService } from '../../../../platform/hover/browser/hover.js'; import { HoverPosition } from '../../../../base/browser/ui/hover/hoverWidget.js'; -import { renderIcon } from '../../../../base/browser/ui/iconLabel/iconLabels.js'; +import { renderIcon, renderLabelWithIcons } from '../../../../base/browser/ui/iconLabel/iconLabels.js'; import { basename, isEqual } from '../../../../base/common/resources.js'; import { localize } from '../../../../nls.js'; import { AgentSessionProviders } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessions.js'; @@ -198,6 +198,7 @@ class NewChatWidget extends Disposable { // Input private _editor!: CodeEditorWidget; private readonly _currentLanguageModel = observableValue('currentLanguageModel', undefined); + private _updateAddContextButtonLabel: (() => void) | undefined; private readonly _modelPickerDisposable = this._register(new MutableDisposable()); private _pendingSessionResource: URI | undefined; @@ -439,14 +440,9 @@ class NewChatWidget extends Disposable { private _createToolbar(container: HTMLElement): void { const toolbar = dom.append(container, dom.$('.sessions-chat-toolbar')); - // Plus button for attaching context - const attachButton = dom.append(toolbar, dom.$('.sessions-chat-attach-button')); - attachButton.tabIndex = 0; - attachButton.role = 'button'; - attachButton.title = localize('addContext', "Add Context..."); - attachButton.ariaLabel = localize('addContext', "Add Context..."); - dom.append(attachButton, renderIcon(Codicon.add)); - this._register(dom.addDisposableListener(attachButton, dom.EventType.CLICK, () => this._showAttachContextPicker())); + // Add context button (matches AddFilesButton from chatInputPart) + const attachContainer = dom.append(toolbar, dom.$('.sessions-chat-attach-button')); + this._renderAddContextButton(attachContainer); const modelPickerContainer = dom.append(toolbar, dom.$('.sessions-chat-model-picker')); this._createModelPicker(modelPickerContainer); @@ -461,6 +457,29 @@ class NewChatWidget extends Disposable { this._register(dom.addDisposableListener(sendButton, dom.EventType.CLICK, () => this._send())); } + private _renderAddContextButton(container: HTMLElement): void { + container.classList.add('chat-attachment-button'); + + const label = dom.append(container, dom.$('a.action-label')); + label.tabIndex = 0; + label.role = 'button'; + label.ariaLabel = localize('addContext', "Add Context..."); + + const updateLabel = () => { + const hasAttachments = this._attachedContext.length > 0; + label.classList.toggle('has-label', !hasAttachments); + const message = !hasAttachments + ? `$(attach) ${localize('addContext.label', "Add Context...")}` + : '$(attach)'; + dom.reset(label, ...renderLabelWithIcons(message)); + }; + + updateLabel(); + this._updateAddContextButtonLabel = updateLabel; + + this._register(dom.addDisposableListener(label, dom.EventType.CLICK, () => this._showAttachContextPicker())); + } + // --- Model picker --- private _createModelPicker(container: HTMLElement): void { @@ -576,6 +595,7 @@ class NewChatWidget extends Disposable { } dom.clearNode(this._attachedContextContainer); + this._updateAddContextButtonLabel?.(); if (this._attachedContext.length === 0) { this._attachedContextContainer.style.display = 'none';