Skip to content

Commit a45ae99

Browse files
authored
Fix hover navigation across attachments (microsoft#229801)
fix hover navigation across attachments
1 parent 9e23739 commit a45ae99

File tree

1 file changed

+21
-24
lines changed

1 file changed

+21
-24
lines changed

src/vs/workbench/contrib/chat/browser/chatInputPart.ts

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { IHistoryNavigationWidget } from '../../../../base/browser/history.js';
99
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
1010
import * as aria from '../../../../base/browser/ui/aria/aria.js';
1111
import { Button } from '../../../../base/browser/ui/button/button.js';
12+
import { IManagedHoverContentOrFactory } from '../../../../base/browser/ui/hover/hover.js';
1213
import { IHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegate.js';
1314
import { createInstantHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegateFactory.js';
1415
import { renderLabelWithIcons } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
@@ -714,35 +715,39 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
714715
[...this.attachedContext.values()].forEach(async (attachment, index) => {
715716
const widget = dom.append(container, $('.chat-attached-context-attachment.show-file-icons'));
716717
const label = this._contextResourceLabels.create(widget, { supportIcons: true, hoverDelegate });
718+
719+
let hoverElement: IManagedHoverContentOrFactory;
720+
let ariaLabel: string | undefined;
721+
717722
const file = URI.isUri(attachment.value) ? attachment.value : attachment.value && typeof attachment.value === 'object' && 'uri' in attachment.value && URI.isUri(attachment.value.uri) ? attachment.value.uri : undefined;
718723
const range = attachment.value && typeof attachment.value === 'object' && 'range' in attachment.value && Range.isIRange(attachment.value.range) ? attachment.value.range : undefined;
719724
if (file && attachment.isFile) {
720725
const fileBasename = basename(file.path);
721726
const fileDirname = dirname(file.path);
722727
const friendlyName = `${fileBasename} ${fileDirname}`;
723-
const ariaLabel = range ? localize('chat.fileAttachmentWithRange', "Attached file, {0}, line {1} to line {2}", friendlyName, range.startLineNumber, range.endLineNumber) : localize('chat.fileAttachment', "Attached file, {0}", friendlyName);
728+
729+
ariaLabel = range ? localize('chat.fileAttachmentWithRange', "Attached file, {0}, line {1} to line {2}", friendlyName, range.startLineNumber, range.endLineNumber) : localize('chat.fileAttachment', "Attached file, {0}", friendlyName);
730+
hoverElement = file.fsPath;
724731

725732
label.setFile(file, {
726733
fileKind: FileKind.FILE,
727734
hidePath: true,
728735
range,
729736
});
730-
widget.ariaLabel = ariaLabel;
731-
widget.tabIndex = 0;
732737
this.attachButtonAndDisposables(widget, index, attachment, hoverDelegate);
733738
} else if (attachment.isImage) {
734-
let buffer: Uint8Array;
735-
const ariaLabel = localize('chat.imageAttachment', "Attached image, {0}", attachment.name);
736-
const pillIcon = dom.$('div.chat-attached-context-pill', {}, dom.$('span.codicon.codicon-file-media'));
739+
ariaLabel = localize('chat.imageAttachment', "Attached image, {0}", attachment.name);
737740

738-
const hoverElement = dom.$('div.chat-attached-context-hover');
741+
hoverElement = dom.$('div.chat-attached-context-hover');
739742
hoverElement.setAttribute('aria-label', ariaLabel);
740743

741744
// Custom label
745+
const pillIcon = dom.$('div.chat-attached-context-pill', {}, dom.$('span.codicon.codicon-file-media'));
742746
const textLabel = dom.$('span.chat-attached-context-custom-text', {}, attachment.name);
743747
widget.appendChild(pillIcon);
744748
widget.appendChild(textLabel);
745749

750+
let buffer: Uint8Array;
746751
try {
747752
if (attachment.value instanceof URI) {
748753
this.attachButtonAndDisposables(widget, index, attachment, hoverDelegate);
@@ -759,30 +764,22 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
759764
}
760765

761766
widget.style.position = 'relative';
762-
widget.ariaLabel = ariaLabel;
763-
widget.tabIndex = 0;
764-
765-
if (!this.attachedContextDisposables.isDisposed) {
766-
this.attachedContextDisposables.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverElement, { trapFocus: false }));
767-
768-
// No delay for keyboard
769-
this.attachedContextDisposables.add(dom.addDisposableListener(widget, 'keydown', (event) => {
770-
const keyboardEvent = new StandardKeyboardEvent(event);
771-
if (keyboardEvent.keyCode === KeyCode.Enter || keyboardEvent.keyCode === KeyCode.Space) {
772-
this.hoverService.showManagedHover(widget);
773-
}
774-
}));
775-
}
776-
777767
} else {
778768
const attachmentLabel = attachment.fullName ?? attachment.name;
779769
const withIcon = attachment.icon?.id ? `$(${attachment.icon.id}) ${attachmentLabel}` : attachmentLabel;
780770
label.setLabel(withIcon, undefined);
781771

782-
widget.ariaLabel = localize('chat.attachment', "Attached context, {0}", attachment.name);
783-
widget.tabIndex = 0;
772+
ariaLabel = localize('chat.attachment', "Attached context, {0}", attachment.name);
773+
hoverElement = attachmentLabel;
774+
784775
this.attachButtonAndDisposables(widget, index, attachment, hoverDelegate);
785776
}
777+
778+
widget.tabIndex = 0;
779+
widget.ariaLabel = ariaLabel;
780+
if (!this.attachedContextDisposables.isDisposed) {
781+
this.attachedContextDisposables.add(this.hoverService.setupManagedHover(hoverDelegate, widget, hoverElement, { trapFocus: false }));
782+
}
786783
});
787784

788785
if (oldHeight !== container.offsetHeight && !isLayout) {

0 commit comments

Comments
 (0)