Skip to content

Commit d0e9ef3

Browse files
authored
Properly handle action widget checked state (microsoft#250127)
1 parent 7e00e48 commit d0e9ef3

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

src/vs/platform/actionWidget/browser/actionList.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import * as dom from '../../../base/browser/dom.js';
66
import { KeybindingLabel } from '../../../base/browser/ui/keybindingLabel/keybindingLabel.js';
77
import { IListEvent, IListMouseEvent, IListRenderer, IListVirtualDelegate } from '../../../base/browser/ui/list/list.js';
8-
import { List } from '../../../base/browser/ui/list/listWidget.js';
8+
import { IListAccessibilityProvider, List } from '../../../base/browser/ui/list/listWidget.js';
99
import { CancellationToken, CancellationTokenSource } from '../../../base/common/cancellation.js';
1010
import { Codicon } from '../../../base/common/codicons.js';
1111
import { ResolvedKeybinding } from '../../../base/common/keybindings.js';
@@ -201,6 +201,7 @@ export class ActionList<T> extends Disposable {
201201
preview: boolean,
202202
items: readonly IActionListItem<T>[],
203203
private readonly _delegate: IActionListDelegate<T>,
204+
accessibilityProvider: Partial<IListAccessibilityProvider<IActionListItem<T>>> | undefined,
204205
@IContextViewService private readonly _contextViewService: IContextViewService,
205206
@IKeybindingService private readonly _keybindingService: IKeybindingService,
206207
@ILayoutService private readonly _layoutService: ILayoutService,
@@ -213,6 +214,7 @@ export class ActionList<T> extends Disposable {
213214
getTemplateId: element => element.kind
214215
};
215216

217+
216218
this._list = this._register(new List(user, this.domNode, virtualDelegate, [
217219
new ActionItemRenderer<IActionListItem<T>>(preview, this._keybindingService),
218220
new HeaderRenderer(),
@@ -234,6 +236,7 @@ export class ActionList<T> extends Disposable {
234236
getWidgetAriaLabel: () => localize({ key: 'customQuickFixWidget', comment: [`An action widget option`] }, "Action Widget"),
235237
getRole: (e) => e.kind === ActionListItemKind.Action ? 'option' : 'separator',
236238
getWidgetRole: () => 'listbox',
239+
...accessibilityProvider
237240
},
238241
}));
239242

src/vs/platform/actionWidget/browser/actionWidget.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { createDecorator, IInstantiationService, ServicesAccessor } from '../../
1919
import { KeybindingWeight } from '../../keybinding/common/keybindingsRegistry.js';
2020
import { inputActiveOptionBackground, registerColor } from '../../theme/common/colorRegistry.js';
2121
import { StandardMouseEvent } from '../../../base/browser/mouseEvent.js';
22+
import { IListAccessibilityProvider } from '../../../base/browser/ui/list/listWidget.js';
2223

2324
registerColor(
2425
'actionBar.toggledBackground',
@@ -35,7 +36,7 @@ export const IActionWidgetService = createDecorator<IActionWidgetService>('actio
3536
export interface IActionWidgetService {
3637
readonly _serviceBrand: undefined;
3738

38-
show<T>(user: string, supportsPreview: boolean, items: readonly IActionListItem<T>[], delegate: IActionListDelegate<T>, anchor: HTMLElement | StandardMouseEvent | IAnchor, container: HTMLElement | undefined, actionBarActions?: readonly IAction[]): void;
39+
show<T>(user: string, supportsPreview: boolean, items: readonly IActionListItem<T>[], delegate: IActionListDelegate<T>, anchor: HTMLElement | StandardMouseEvent | IAnchor, container: HTMLElement | undefined, actionBarActions?: readonly IAction[], accessibilityProvider?: Partial<IListAccessibilityProvider<IActionListItem<T>>>): void;
3940

4041
hide(didCancel?: boolean): void;
4142

@@ -59,10 +60,10 @@ class ActionWidgetService extends Disposable implements IActionWidgetService {
5960
super();
6061
}
6162

62-
show<T>(user: string, supportsPreview: boolean, items: readonly IActionListItem<T>[], delegate: IActionListDelegate<T>, anchor: HTMLElement | StandardMouseEvent | IAnchor, container: HTMLElement | undefined, actionBarActions?: readonly IAction[]): void {
63+
show<T>(user: string, supportsPreview: boolean, items: readonly IActionListItem<T>[], delegate: IActionListDelegate<T>, anchor: HTMLElement | StandardMouseEvent | IAnchor, container: HTMLElement | undefined, actionBarActions?: readonly IAction[], accessibilityProvider?: Partial<IListAccessibilityProvider<IActionListItem<T>>>): void {
6364
const visibleContext = ActionWidgetContextKeys.Visible.bindTo(this._contextKeyService);
6465

65-
const list = this._instantiationService.createInstance(ActionList, user, supportsPreview, items, delegate);
66+
const list = this._instantiationService.createInstance(ActionList, user, supportsPreview, items, delegate, accessibilityProvider);
6667
this._contextViewService.showContextView({
6768
getAnchor: () => anchor,
6869
render: (container: HTMLElement) => {

src/vs/platform/actionWidget/browser/actionWidgetDropdown.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ThemeIcon } from '../../../base/common/themables.js';
1111
import { Codicon } from '../../../base/common/codicons.js';
1212
import { getActiveElement, isHTMLElement } from '../../../base/browser/dom.js';
1313
import { IKeybindingService } from '../../keybinding/common/keybinding.js';
14+
import { IListAccessibilityProvider } from '../../../base/browser/ui/list/listWidget.js';
1415

1516
export interface IActionWidgetDropdownAction extends IAction {
1617
category?: { label: string; order: number };
@@ -126,14 +127,23 @@ export class ActionWidgetDropdown extends BaseDropdown {
126127
}
127128
}));
128129

130+
const accessibilityProvider: Partial<IListAccessibilityProvider<IActionListItem<IActionWidgetDropdownAction>>> = {
131+
isChecked(element) {
132+
return element.kind === ActionListItemKind.Action && !!element?.item?.checked;
133+
},
134+
getRole: (e) => e.kind === ActionListItemKind.Action ? 'menuitemcheckbox' : 'separator',
135+
getWidgetRole: () => 'menu',
136+
};
137+
129138
this.actionWidgetService.show<IActionWidgetDropdownAction>(
130139
this._options.label ?? '',
131140
false,
132141
actionWidgetItems,
133142
actionWidgetDelegate,
134143
this.element,
135144
undefined,
136-
actionBarActions
145+
actionBarActions,
146+
accessibilityProvider
137147
);
138148
}
139149
}

0 commit comments

Comments
 (0)