Skip to content

Conversation

@karthiknadig
Copy link
Member

@karthiknadig karthiknadig commented Jan 28, 2026

Fixes #291328
Fixes #291708

Copilot AI review requested due to automatic review settings January 28, 2026 17:44
@karthiknadig karthiknadig self-assigned this Jan 28, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the chat question carousel UI to use a list-style selection experience (QuickPick-like) for both single- and multi-select questions, instead of native radio buttons/checkboxes.

Changes:

  • Reworked single-select rendering to a role="listbox" list with selectable rows and a checkmark indicator.
  • Reworked multi-select rendering to list rows with VS Code’s Checkbox component and listbox semantics.
  • Updated CSS and adjusted unit tests to validate the new DOM structure and selection state.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts Implements list-style single/multi-select rendering, keyboard handling, and answer extraction.
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css Adds styling for list-style selection rows (QuickPick-like look/feel).
src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatQuestionCarouselPart.test.ts Updates tests to assert list-based DOM structure and selection state classes.
Comments suppressed due to low confidence (1)

src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts:681

  • Pressing Space in multi-select toggles checkboxes[focusedIndex].checked programmatically, but this won’t emit checkbox.onChange, so the corresponding list item’s checked class and aria-selected can get out of sync. Use the same toggle path as mouse/keyboard interaction (e.g., invoke the checkbox click/toggle method or update list item state alongside the assignment).
			} else if (event.keyCode === KeyCode.Space) {
				e.preventDefault();
				// Toggle the currently focused checkbox
				if (focusedIndex >= 0 && focusedIndex < checkboxes.length) {
					checkboxes[focusedIndex].checked = !checkboxes[focusedIndex].checked;

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatQuestionCarouselPart.test.ts:140

  • The updated UI adds row-level click handling and keyboard navigation for list-style selection, but the test suite only asserts initial DOM structure/classes. Adding interaction tests (clicking on the list item outside the checkbox, arrow navigation + Space/Enter behavior) would help prevent regressions and would have caught state-sync issues.
		test('renders list items with checkboxes for multiSelect type questions', () => {
			const carousel = createMockCarousel([
				{
					id: 'q1',
					type: 'multiSelect',
					title: 'Choose multiple',
					options: [
						{ id: 'a', label: 'Option A', value: 'a' },
						{ id: 'b', label: 'Option B', value: 'b' },
						{ id: 'c', label: 'Option C', value: 'c' }
					]
				}
			]);
			createWidget(carousel);

			const listItems = widget.domNode.querySelectorAll('.chat-question-list-item.multi-select');
			assert.strictEqual(listItems.length, 3, 'Should have 3 list items for multiSelect');
			const checkboxes = widget.domNode.querySelectorAll('.chat-question-list-checkbox');
			assert.strictEqual(checkboxes.length, 3, 'Should have 3 checkboxes');
		});

src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts:683

  • The keyboard handler toggles checkboxes[focusedIndex].checked via the setter, which won’t fire onChange either, so visual state/ARIA can get out of sync when using Space. Consider toggling through the Checkbox’s UI event path (e.g. click its domNode) or manually mirroring the state update here as well.
			freeformTextarea.placeholder = localize('chat.questionCarousel.enterCustomAnswer', 'Enter custom answer');
			freeformTextarea.rows = 1;
			freeformTextarea.setAttribute('aria-labelledby', freeformLabelId);

			if (previousFreeform !== undefined) {
				freeformTextarea.value = previousFreeform;
			}

@eli-w-king eli-w-king marked this pull request as ready for review January 29, 2026 00:27
eli-w-king
eli-w-king previously approved these changes Jan 29, 2026
@eli-w-king eli-w-king enabled auto-merge January 29, 2026 00:28
@vs-code-engineering vs-code-engineering bot added this to the January 2026 milestone Jan 29, 2026
@eli-w-king
Copy link
Contributor

Latest UI:

Screen.Recording.2026-01-29.at.4.10.11.PM.mov

@eli-w-king
Copy link
Contributor

Screen.Recording.2026-01-30.at.1.39.07.PM.mov

Updated UI

Copy link
Collaborator

@justschen justschen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, no blocking changes but maybe just a little cleanup during debt + as we move the tool into core

also this selection looks really really similar to the action list - curious if we tried using that before making a standalone custom list haha
Screenshot 2026-01-30 at 3 44 03 PM

/* Secondary buttons (prev, next) use gray secondary background */
.chat-question-carousel-nav .monaco-button.chat-question-nav-arrow.chat-question-nav-prev,
.chat-question-carousel-nav .monaco-button.chat-question-nav-arrow.chat-question-nav-next {
background: var(--vscode-button-secondaryBackground) !important;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are some changes from Lee that got merged as a candidate regarding the secondaryBackground not working as intended - just an extra UI nit to keep an eye out for when testing.

margin-left: 4px;
.chat-question-carousel-nav .monaco-button.chat-question-nav-arrow.chat-question-nav-prev:hover:not(.disabled),
.chat-question-carousel-nav .monaco-button.chat-question-nav-arrow.chat-question-nav-next:hover:not(.disabled) {
background: var(--vscode-button-secondaryHoverBackground) !important;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also nit or maybe cleanup - i'm not a super big fan of doing !important, and ik with the monaco buttons it's kinda annoying, but with enough specficity (ie, wrapping in .interactive-session .interactive-response etc, we can maybe avoid.

not blocking tho.

label.htmlFor = `option-${question.id}-${index}`;
label.id = `label-${question.id}-${index}`;
label.textContent = option.label;
if (isChecked) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe can look into using toggle for things like this

also not blocking

@eli-w-king eli-w-king merged commit cffc62c into main Jan 30, 2026
22 checks passed
@eli-w-king eli-w-king deleted the international-orca branch January 30, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

askQuestions tool does not respond to touch on selections (radio) Question carousel UI: Use list-style selection instead of radio buttons/checkboxes

5 participants