mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-06 09:35:41 -05:00
Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2
This commit is contained in:
committed by
Anthony Dresser
parent
3603f55d97
commit
7f1d8fc32f
@@ -822,6 +822,7 @@ export const EventType = {
|
||||
MOUSE_OUT: 'mouseout',
|
||||
MOUSE_ENTER: 'mouseenter',
|
||||
MOUSE_LEAVE: 'mouseleave',
|
||||
MOUSE_WHEEL: browser.isEdge ? 'mousewheel' : 'wheel',
|
||||
POINTER_UP: 'pointerup',
|
||||
POINTER_DOWN: 'pointerdown',
|
||||
POINTER_MOVE: 'pointermove',
|
||||
|
||||
@@ -197,8 +197,8 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
|
||||
const renderedMarkdown = marked.parse(
|
||||
markdown.supportThemeIcons
|
||||
? markdownEscapeEscapedCodicons(markdown.value)
|
||||
: markdown.value,
|
||||
? markdownEscapeEscapedCodicons(markdown.value || '')
|
||||
: (markdown.value || ''),
|
||||
markedOptions
|
||||
);
|
||||
|
||||
|
||||
@@ -80,15 +80,11 @@ export class StandardMouseEvent implements IMouseEvent {
|
||||
}
|
||||
|
||||
public preventDefault(): void {
|
||||
if (this.browserEvent.preventDefault) {
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
|
||||
public stopPropagation(): void {
|
||||
if (this.browserEvent.stopPropagation) {
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,17 +204,13 @@ export class StandardWheelEvent {
|
||||
|
||||
public preventDefault(): void {
|
||||
if (this.browserEvent) {
|
||||
if (this.browserEvent.preventDefault) {
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public stopPropagation(): void {
|
||||
if (this.browserEvent) {
|
||||
if (this.browserEvent.stopPropagation) {
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
|
||||
if (platform.isMacintosh) {
|
||||
// macOS: allow to trigger the button when holding Ctrl+key and pressing the
|
||||
// main mouse button. This is for scenarios where e.g. some interaction forces
|
||||
// main mouse button. This is for scenarios where e.g. some interaction forces
|
||||
// the Ctrl+key to be pressed and hold but the user still wants to interact
|
||||
// with the actions (for example quick access in quick navigation mode).
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CONTEXT_MENU, e => {
|
||||
@@ -276,7 +276,6 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
this.label = DOM.append(this.element, DOM.$('a.action-label'));
|
||||
}
|
||||
|
||||
|
||||
if (this.label) {
|
||||
if (this._action.id === Separator.ID) {
|
||||
this.label.setAttribute('role', 'presentation'); // A separator is a presentation item
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./aria';
|
||||
import * as nls from 'vs/nls';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
|
||||
@@ -23,7 +22,8 @@ export function setARIAContainer(parent: HTMLElement) {
|
||||
|
||||
statusContainer = document.createElement('div');
|
||||
statusContainer.className = 'monaco-status';
|
||||
statusContainer.setAttribute('role', 'status');
|
||||
statusContainer.setAttribute('role', 'complementary');
|
||||
statusContainer.setAttribute('aria-live', 'polite');
|
||||
statusContainer.setAttribute('aria-atomic', 'true');
|
||||
ariaContainer.appendChild(statusContainer);
|
||||
|
||||
@@ -33,51 +33,30 @@ export function setARIAContainer(parent: HTMLElement) {
|
||||
/**
|
||||
* Given the provided message, will make sure that it is read as alert to screen readers.
|
||||
*/
|
||||
export function alert(msg: string, disableRepeat?: boolean): void {
|
||||
insertMessage(alertContainer, msg, disableRepeat);
|
||||
export function alert(msg: string): void {
|
||||
insertMessage(alertContainer, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the provided message, will make sure that it is read as status to screen readers.
|
||||
*/
|
||||
export function status(msg: string, disableRepeat?: boolean): void {
|
||||
export function status(msg: string): void {
|
||||
if (isMacintosh) {
|
||||
alert(msg, disableRepeat); // VoiceOver does not seem to support status role
|
||||
alert(msg); // VoiceOver does not seem to support status role
|
||||
} else {
|
||||
insertMessage(statusContainer, msg, disableRepeat);
|
||||
insertMessage(statusContainer, msg);
|
||||
}
|
||||
}
|
||||
|
||||
let repeatedTimes = 0;
|
||||
let prevText: string | undefined = undefined;
|
||||
function insertMessage(target: HTMLElement, msg: string, disableRepeat?: boolean): void {
|
||||
function insertMessage(target: HTMLElement, msg: string): void {
|
||||
if (!ariaContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the same message should be inserted that is already present, a screen reader would
|
||||
// not announce this message because it matches the previous one. As a workaround, we
|
||||
// alter the message with the number of occurences unless this is explicitly disabled
|
||||
// via the disableRepeat flag.
|
||||
if (!disableRepeat) {
|
||||
if (prevText === msg) {
|
||||
repeatedTimes++;
|
||||
} else {
|
||||
prevText = msg;
|
||||
repeatedTimes = 0;
|
||||
}
|
||||
|
||||
switch (repeatedTimes) {
|
||||
case 0: break;
|
||||
case 1: msg = nls.localize('repeated', "{0} (occurred again)", msg); break;
|
||||
default: msg = nls.localize('repeatedNtimes', "{0} (occurred {1} times)", msg, repeatedTimes); break;
|
||||
}
|
||||
}
|
||||
|
||||
dom.clearNode(target);
|
||||
target.textContent = msg;
|
||||
|
||||
// See https://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
|
||||
target.style.visibility = 'hidden';
|
||||
target.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item .codicon-chevron-right {
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item .codicon-breadcrumb-separator {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Color } from 'vs/base/common/color';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
import 'vs/css!./breadcrumbsWidget';
|
||||
|
||||
export abstract class BreadcrumbsItem {
|
||||
@@ -55,6 +56,8 @@ export interface IBreadcrumbsItemEvent {
|
||||
payload: any;
|
||||
}
|
||||
|
||||
const breadcrumbSeparatorIcon = registerIcon('breadcrumb-separator', Codicon.chevronRight);
|
||||
|
||||
export class BreadcrumbsWidget {
|
||||
|
||||
private readonly _disposables = new DisposableStore();
|
||||
@@ -336,7 +339,7 @@ export class BreadcrumbsWidget {
|
||||
container.tabIndex = -1;
|
||||
container.setAttribute('role', 'listitem');
|
||||
dom.addClasses(container, 'monaco-breadcrumb-item');
|
||||
const iconContainer = dom.$('.codicon.codicon-chevron-right');
|
||||
const iconContainer = dom.$(breadcrumbSeparatorIcon.cssSelector);
|
||||
container.appendChild(iconContainer);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,13 @@ import { Widget } from 'vs/base/browser/ui/widget';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export interface ICheckboxOpts extends ICheckboxStyles {
|
||||
readonly actionClassName?: string;
|
||||
readonly icon?: Codicon;
|
||||
readonly title: string;
|
||||
readonly isChecked: boolean;
|
||||
}
|
||||
@@ -93,13 +94,23 @@ export class Checkbox extends Widget {
|
||||
constructor(opts: ICheckboxOpts) {
|
||||
super();
|
||||
|
||||
this._opts = objects.deepClone(opts);
|
||||
objects.mixin(this._opts, defaultOpts, false);
|
||||
this._opts = { ...defaultOpts, ...opts };
|
||||
this._checked = this._opts.isChecked;
|
||||
|
||||
const classes = ['monaco-custom-checkbox'];
|
||||
if (this._opts.icon) {
|
||||
classes.push(this._opts.icon.classNames);
|
||||
} else {
|
||||
classes.push('codicon'); // todo@aeschli: remove once codicon fully adopted
|
||||
}
|
||||
if (this._opts.actionClassName) {
|
||||
classes.push(this._opts.actionClassName);
|
||||
}
|
||||
classes.push(this._checked ? 'checked' : 'unchecked');
|
||||
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.title = this._opts.title;
|
||||
this.domNode.className = 'monaco-custom-checkbox codicon ' + (this._opts.actionClassName || '') + ' ' + (this._checked ? 'checked' : 'unchecked');
|
||||
this.domNode.className = classes.join(' ');
|
||||
this.domNode.tabIndex = 0;
|
||||
this.domNode.setAttribute('role', 'checkbox');
|
||||
this.domNode.setAttribute('aria-checked', String(this._checked));
|
||||
@@ -192,7 +203,7 @@ export class SimpleCheckbox extends Widget {
|
||||
constructor(private title: string, private isChecked: boolean) {
|
||||
super();
|
||||
|
||||
this.checkbox = new Checkbox({ title: this.title, isChecked: this.isChecked, actionClassName: 'monaco-simple-checkbox codicon-check' });
|
||||
this.checkbox = new Checkbox({ title: this.title, isChecked: this.isChecked, icon: Codicon.check, actionClassName: 'monaco-simple-checkbox' });
|
||||
|
||||
this.domNode = this.checkbox.domNode;
|
||||
|
||||
|
||||
@@ -1,427 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
@font-face {
|
||||
font-family: "codicon";
|
||||
src: url("./codicon.ttf?a76e99e42eab7c1a55601640b708d820") format("truetype");
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
font: normal normal normal 16px/1 codicon;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
text-align: center;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.codicon-add:before { content: "\ea60" }
|
||||
.codicon-plus:before { content: "\ea60" }
|
||||
.codicon-gist-new:before { content: "\ea60" }
|
||||
.codicon-repo-create:before { content: "\ea60" }
|
||||
.codicon-lightbulb:before { content: "\ea61" }
|
||||
.codicon-light-bulb:before { content: "\ea61" }
|
||||
.codicon-repo:before { content: "\ea62" }
|
||||
.codicon-repo-delete:before { content: "\ea62" }
|
||||
.codicon-gist-fork:before { content: "\ea63" }
|
||||
.codicon-repo-forked:before { content: "\ea63" }
|
||||
.codicon-git-pull-request:before { content: "\ea64" }
|
||||
.codicon-git-pull-request-abandoned:before { content: "\ea64" }
|
||||
.codicon-record-keys:before { content: "\ea65" }
|
||||
.codicon-keyboard:before { content: "\ea65" }
|
||||
.codicon-tag:before { content: "\ea66" }
|
||||
.codicon-tag-add:before { content: "\ea66" }
|
||||
.codicon-tag-remove:before { content: "\ea66" }
|
||||
.codicon-person:before { content: "\ea67" }
|
||||
.codicon-person-add:before { content: "\ea67" }
|
||||
.codicon-person-follow:before { content: "\ea67" }
|
||||
.codicon-person-outline:before { content: "\ea67" }
|
||||
.codicon-person-filled:before { content: "\ea67" }
|
||||
.codicon-git-branch:before { content: "\ea68" }
|
||||
.codicon-git-branch-create:before { content: "\ea68" }
|
||||
.codicon-git-branch-delete:before { content: "\ea68" }
|
||||
.codicon-source-control:before { content: "\ea68" }
|
||||
.codicon-mirror:before { content: "\ea69" }
|
||||
.codicon-mirror-public:before { content: "\ea69" }
|
||||
.codicon-star:before { content: "\ea6a" }
|
||||
.codicon-star-add:before { content: "\ea6a" }
|
||||
.codicon-star-delete:before { content: "\ea6a" }
|
||||
.codicon-star-empty:before { content: "\ea6a" }
|
||||
.codicon-comment:before { content: "\ea6b" }
|
||||
.codicon-comment-add:before { content: "\ea6b" }
|
||||
.codicon-alert:before { content: "\ea6c" }
|
||||
.codicon-warning:before { content: "\ea6c" }
|
||||
.codicon-search:before { content: "\ea6d" }
|
||||
.codicon-search-save:before { content: "\ea6d" }
|
||||
.codicon-log-out:before { content: "\ea6e" }
|
||||
.codicon-sign-out:before { content: "\ea6e" }
|
||||
.codicon-log-in:before { content: "\ea6f" }
|
||||
.codicon-sign-in:before { content: "\ea6f" }
|
||||
.codicon-eye:before { content: "\ea70" }
|
||||
.codicon-eye-unwatch:before { content: "\ea70" }
|
||||
.codicon-eye-watch:before { content: "\ea70" }
|
||||
.codicon-circle-filled:before { content: "\ea71" }
|
||||
.codicon-primitive-dot:before { content: "\ea71" }
|
||||
.codicon-close-dirty:before { content: "\ea71" }
|
||||
.codicon-debug-breakpoint:before { content: "\ea71" }
|
||||
.codicon-debug-breakpoint-disabled:before { content: "\ea71" }
|
||||
.codicon-debug-hint:before { content: "\ea71" }
|
||||
.codicon-primitive-square:before { content: "\ea72" }
|
||||
.codicon-edit:before { content: "\ea73" }
|
||||
.codicon-pencil:before { content: "\ea73" }
|
||||
.codicon-info:before { content: "\ea74" }
|
||||
.codicon-issue-opened:before { content: "\ea74" }
|
||||
.codicon-gist-private:before { content: "\ea75" }
|
||||
.codicon-git-fork-private:before { content: "\ea75" }
|
||||
.codicon-lock:before { content: "\ea75" }
|
||||
.codicon-mirror-private:before { content: "\ea75" }
|
||||
.codicon-close:before { content: "\ea76" }
|
||||
.codicon-remove-close:before { content: "\ea76" }
|
||||
.codicon-x:before { content: "\ea76" }
|
||||
.codicon-repo-sync:before { content: "\ea77" }
|
||||
.codicon-sync:before { content: "\ea77" }
|
||||
.codicon-clone:before { content: "\ea78" }
|
||||
.codicon-desktop-download:before { content: "\ea78" }
|
||||
.codicon-beaker:before { content: "\ea79" }
|
||||
.codicon-microscope:before { content: "\ea79" }
|
||||
.codicon-vm:before { content: "\ea7a" }
|
||||
.codicon-device-desktop:before { content: "\ea7a" }
|
||||
.codicon-file:before { content: "\ea7b" }
|
||||
.codicon-file-text:before { content: "\ea7b" }
|
||||
.codicon-more:before { content: "\ea7c" }
|
||||
.codicon-ellipsis:before { content: "\ea7c" }
|
||||
.codicon-kebab-horizontal:before { content: "\ea7c" }
|
||||
.codicon-mail-reply:before { content: "\ea7d" }
|
||||
.codicon-reply:before { content: "\ea7d" }
|
||||
.codicon-organization:before { content: "\ea7e" }
|
||||
.codicon-organization-filled:before { content: "\ea7e" }
|
||||
.codicon-organization-outline:before { content: "\ea7e" }
|
||||
.codicon-new-file:before { content: "\ea7f" }
|
||||
.codicon-file-add:before { content: "\ea7f" }
|
||||
.codicon-new-folder:before { content: "\ea80" }
|
||||
.codicon-file-directory-create:before { content: "\ea80" }
|
||||
.codicon-trash:before { content: "\ea81" }
|
||||
.codicon-trashcan:before { content: "\ea81" }
|
||||
.codicon-history:before { content: "\ea82" }
|
||||
.codicon-clock:before { content: "\ea82" }
|
||||
.codicon-folder:before { content: "\ea83" }
|
||||
.codicon-file-directory:before { content: "\ea83" }
|
||||
.codicon-symbol-folder:before { content: "\ea83" }
|
||||
.codicon-logo-github:before { content: "\ea84" }
|
||||
.codicon-mark-github:before { content: "\ea84" }
|
||||
.codicon-github:before { content: "\ea84" }
|
||||
.codicon-terminal:before { content: "\ea85" }
|
||||
.codicon-console:before { content: "\ea85" }
|
||||
.codicon-repl:before { content: "\ea85" }
|
||||
.codicon-zap:before { content: "\ea86" }
|
||||
.codicon-symbol-event:before { content: "\ea86" }
|
||||
.codicon-error:before { content: "\ea87" }
|
||||
.codicon-stop:before { content: "\ea87" }
|
||||
.codicon-variable:before { content: "\ea88" }
|
||||
.codicon-symbol-variable:before { content: "\ea88" }
|
||||
.codicon-array:before { content: "\ea8a" }
|
||||
.codicon-symbol-array:before { content: "\ea8a" }
|
||||
.codicon-symbol-module:before { content: "\ea8b" }
|
||||
.codicon-symbol-package:before { content: "\ea8b" }
|
||||
.codicon-symbol-namespace:before { content: "\ea8b" }
|
||||
.codicon-symbol-object:before { content: "\ea8b" }
|
||||
.codicon-symbol-method:before { content: "\ea8c" }
|
||||
.codicon-symbol-function:before { content: "\ea8c" }
|
||||
.codicon-symbol-constructor:before { content: "\ea8c" }
|
||||
.codicon-symbol-boolean:before { content: "\ea8f" }
|
||||
.codicon-symbol-null:before { content: "\ea8f" }
|
||||
.codicon-symbol-numeric:before { content: "\ea90" }
|
||||
.codicon-symbol-number:before { content: "\ea90" }
|
||||
.codicon-symbol-structure:before { content: "\ea91" }
|
||||
.codicon-symbol-struct:before { content: "\ea91" }
|
||||
.codicon-symbol-parameter:before { content: "\ea92" }
|
||||
.codicon-symbol-type-parameter:before { content: "\ea92" }
|
||||
.codicon-symbol-key:before { content: "\ea93" }
|
||||
.codicon-symbol-text:before { content: "\ea93" }
|
||||
.codicon-symbol-reference:before { content: "\ea94" }
|
||||
.codicon-go-to-file:before { content: "\ea94" }
|
||||
.codicon-symbol-enum:before { content: "\ea95" }
|
||||
.codicon-symbol-value:before { content: "\ea95" }
|
||||
.codicon-symbol-ruler:before { content: "\ea96" }
|
||||
.codicon-symbol-unit:before { content: "\ea96" }
|
||||
.codicon-activate-breakpoints:before { content: "\ea97" }
|
||||
.codicon-archive:before { content: "\ea98" }
|
||||
.codicon-arrow-both:before { content: "\ea99" }
|
||||
.codicon-arrow-down:before { content: "\ea9a" }
|
||||
.codicon-arrow-left:before { content: "\ea9b" }
|
||||
.codicon-arrow-right:before { content: "\ea9c" }
|
||||
.codicon-arrow-small-down:before { content: "\ea9d" }
|
||||
.codicon-arrow-small-left:before { content: "\ea9e" }
|
||||
.codicon-arrow-small-right:before { content: "\ea9f" }
|
||||
.codicon-arrow-small-up:before { content: "\eaa0" }
|
||||
.codicon-arrow-up:before { content: "\eaa1" }
|
||||
.codicon-bell:before { content: "\eaa2" }
|
||||
.codicon-bold:before { content: "\eaa3" }
|
||||
.codicon-book:before { content: "\eaa4" }
|
||||
.codicon-bookmark:before { content: "\eaa5" }
|
||||
.codicon-debug-breakpoint-conditional-unverified:before { content: "\eaa6" }
|
||||
.codicon-debug-breakpoint-conditional:before { content: "\eaa7" }
|
||||
.codicon-debug-breakpoint-conditional-disabled:before { content: "\eaa7" }
|
||||
.codicon-debug-breakpoint-data-unverified:before { content: "\eaa8" }
|
||||
.codicon-debug-breakpoint-data:before { content: "\eaa9" }
|
||||
.codicon-debug-breakpoint-data-disabled:before { content: "\eaa9" }
|
||||
.codicon-debug-breakpoint-log-unverified:before { content: "\eaaa" }
|
||||
.codicon-debug-breakpoint-log:before { content: "\eaab" }
|
||||
.codicon-debug-breakpoint-log-disabled:before { content: "\eaab" }
|
||||
.codicon-briefcase:before { content: "\eaac" }
|
||||
.codicon-broadcast:before { content: "\eaad" }
|
||||
.codicon-browser:before { content: "\eaae" }
|
||||
.codicon-bug:before { content: "\eaaf" }
|
||||
.codicon-calendar:before { content: "\eab0" }
|
||||
.codicon-case-sensitive:before { content: "\eab1" }
|
||||
.codicon-check:before { content: "\eab2" }
|
||||
.codicon-checklist:before { content: "\eab3" }
|
||||
.codicon-chevron-down:before { content: "\eab4" }
|
||||
.codicon-chevron-left:before { content: "\eab5" }
|
||||
.codicon-chevron-right:before { content: "\eab6" }
|
||||
.codicon-chevron-up:before { content: "\eab7" }
|
||||
.codicon-chrome-close:before { content: "\eab8" }
|
||||
.codicon-chrome-maximize:before { content: "\eab9" }
|
||||
.codicon-chrome-minimize:before { content: "\eaba" }
|
||||
.codicon-chrome-restore:before { content: "\eabb" }
|
||||
.codicon-circle-outline:before { content: "\eabc" }
|
||||
.codicon-debug-breakpoint-unverified:before { content: "\eabc" }
|
||||
.codicon-circle-slash:before { content: "\eabd" }
|
||||
.codicon-circuit-board:before { content: "\eabe" }
|
||||
.codicon-clear-all:before { content: "\eabf" }
|
||||
.codicon-clippy:before { content: "\eac0" }
|
||||
.codicon-close-all:before { content: "\eac1" }
|
||||
.codicon-cloud-download:before { content: "\eac2" }
|
||||
.codicon-cloud-upload:before { content: "\eac3" }
|
||||
.codicon-code:before { content: "\eac4" }
|
||||
.codicon-collapse-all:before { content: "\eac5" }
|
||||
.codicon-color-mode:before { content: "\eac6" }
|
||||
.codicon-comment-discussion:before { content: "\eac7" }
|
||||
.codicon-compare-changes:before { content: "\eac8" }
|
||||
.codicon-credit-card:before { content: "\eac9" }
|
||||
.codicon-dash:before { content: "\eacc" }
|
||||
.codicon-dashboard:before { content: "\eacd" }
|
||||
.codicon-database:before { content: "\eace" }
|
||||
.codicon-debug-continue:before { content: "\eacf" }
|
||||
.codicon-debug-disconnect:before { content: "\ead0" }
|
||||
.codicon-debug-pause:before { content: "\ead1" }
|
||||
.codicon-debug-restart:before { content: "\ead2" }
|
||||
.codicon-debug-start:before { content: "\ead3" }
|
||||
.codicon-debug-step-into:before { content: "\ead4" }
|
||||
.codicon-debug-step-out:before { content: "\ead5" }
|
||||
.codicon-debug-step-over:before { content: "\ead6" }
|
||||
.codicon-debug-stop:before { content: "\ead7" }
|
||||
.codicon-debug:before { content: "\ead8" }
|
||||
.codicon-device-camera-video:before { content: "\ead9" }
|
||||
.codicon-device-camera:before { content: "\eada" }
|
||||
.codicon-device-mobile:before { content: "\eadb" }
|
||||
.codicon-diff-added:before { content: "\eadc" }
|
||||
.codicon-diff-ignored:before { content: "\eadd" }
|
||||
.codicon-diff-modified:before { content: "\eade" }
|
||||
.codicon-diff-removed:before { content: "\eadf" }
|
||||
.codicon-diff-renamed:before { content: "\eae0" }
|
||||
.codicon-diff:before { content: "\eae1" }
|
||||
.codicon-discard:before { content: "\eae2" }
|
||||
.codicon-editor-layout:before { content: "\eae3" }
|
||||
.codicon-empty-window:before { content: "\eae4" }
|
||||
.codicon-exclude:before { content: "\eae5" }
|
||||
.codicon-extensions:before { content: "\eae6" }
|
||||
.codicon-eye-closed:before { content: "\eae7" }
|
||||
.codicon-file-binary:before { content: "\eae8" }
|
||||
.codicon-file-code:before { content: "\eae9" }
|
||||
.codicon-file-media:before { content: "\eaea" }
|
||||
.codicon-file-pdf:before { content: "\eaeb" }
|
||||
.codicon-file-submodule:before { content: "\eaec" }
|
||||
.codicon-file-symlink-directory:before { content: "\eaed" }
|
||||
.codicon-file-symlink-file:before { content: "\eaee" }
|
||||
.codicon-file-zip:before { content: "\eaef" }
|
||||
.codicon-files:before { content: "\eaf0" }
|
||||
.codicon-filter:before { content: "\eaf1" }
|
||||
.codicon-flame:before { content: "\eaf2" }
|
||||
.codicon-fold-down:before { content: "\eaf3" }
|
||||
.codicon-fold-up:before { content: "\eaf4" }
|
||||
.codicon-fold:before { content: "\eaf5" }
|
||||
.codicon-folder-active:before { content: "\eaf6" }
|
||||
.codicon-folder-opened:before { content: "\eaf7" }
|
||||
.codicon-gear:before { content: "\eaf8" }
|
||||
.codicon-gift:before { content: "\eaf9" }
|
||||
.codicon-gist-secret:before { content: "\eafa" }
|
||||
.codicon-gist:before { content: "\eafb" }
|
||||
.codicon-git-commit:before { content: "\eafc" }
|
||||
.codicon-git-compare:before { content: "\eafd" }
|
||||
.codicon-git-merge:before { content: "\eafe" }
|
||||
.codicon-github-action:before { content: "\eaff" }
|
||||
.codicon-github-alt:before { content: "\eb00" }
|
||||
.codicon-globe:before { content: "\eb01" }
|
||||
.codicon-grabber:before { content: "\eb02" }
|
||||
.codicon-graph:before { content: "\eb03" }
|
||||
.codicon-gripper:before { content: "\eb04" }
|
||||
.codicon-heart:before { content: "\eb05" }
|
||||
.codicon-home:before { content: "\eb06" }
|
||||
.codicon-horizontal-rule:before { content: "\eb07" }
|
||||
.codicon-hubot:before { content: "\eb08" }
|
||||
.codicon-inbox:before { content: "\eb09" }
|
||||
.codicon-issue-closed:before { content: "\eb0a" }
|
||||
.codicon-issue-reopened:before { content: "\eb0b" }
|
||||
.codicon-issues:before { content: "\eb0c" }
|
||||
.codicon-italic:before { content: "\eb0d" }
|
||||
.codicon-jersey:before { content: "\eb0e" }
|
||||
.codicon-json:before { content: "\eb0f" }
|
||||
.codicon-kebab-vertical:before { content: "\eb10" }
|
||||
.codicon-key:before { content: "\eb11" }
|
||||
.codicon-law:before { content: "\eb12" }
|
||||
.codicon-lightbulb-autofix:before { content: "\eb13" }
|
||||
.codicon-link-external:before { content: "\eb14" }
|
||||
.codicon-link:before { content: "\eb15" }
|
||||
.codicon-list-ordered:before { content: "\eb16" }
|
||||
.codicon-list-unordered:before { content: "\eb17" }
|
||||
.codicon-live-share:before { content: "\eb18" }
|
||||
.codicon-loading:before { content: "\eb19" }
|
||||
.codicon-location:before { content: "\eb1a" }
|
||||
.codicon-mail-read:before { content: "\eb1b" }
|
||||
.codicon-mail:before { content: "\eb1c" }
|
||||
.codicon-markdown:before { content: "\eb1d" }
|
||||
.codicon-megaphone:before { content: "\eb1e" }
|
||||
.codicon-mention:before { content: "\eb1f" }
|
||||
.codicon-milestone:before { content: "\eb20" }
|
||||
.codicon-mortar-board:before { content: "\eb21" }
|
||||
.codicon-move:before { content: "\eb22" }
|
||||
.codicon-multiple-windows:before { content: "\eb23" }
|
||||
.codicon-mute:before { content: "\eb24" }
|
||||
.codicon-no-newline:before { content: "\eb25" }
|
||||
.codicon-note:before { content: "\eb26" }
|
||||
.codicon-octoface:before { content: "\eb27" }
|
||||
.codicon-open-preview:before { content: "\eb28" }
|
||||
.codicon-package:before { content: "\eb29" }
|
||||
.codicon-paintcan:before { content: "\eb2a" }
|
||||
.codicon-pin:before { content: "\eb2b" }
|
||||
.codicon-play:before { content: "\eb2c" }
|
||||
.codicon-run:before { content: "\eb2c" }
|
||||
.codicon-plug:before { content: "\eb2d" }
|
||||
.codicon-preserve-case:before { content: "\eb2e" }
|
||||
.codicon-preview:before { content: "\eb2f" }
|
||||
.codicon-project:before { content: "\eb30" }
|
||||
.codicon-pulse:before { content: "\eb31" }
|
||||
.codicon-question:before { content: "\eb32" }
|
||||
.codicon-quote:before { content: "\eb33" }
|
||||
.codicon-radio-tower:before { content: "\eb34" }
|
||||
.codicon-reactions:before { content: "\eb35" }
|
||||
.codicon-references:before { content: "\eb36" }
|
||||
.codicon-refresh:before { content: "\eb37" }
|
||||
.codicon-regex:before { content: "\eb38" }
|
||||
.codicon-remote-explorer:before { content: "\eb39" }
|
||||
.codicon-remote:before { content: "\eb3a" }
|
||||
.codicon-remove:before { content: "\eb3b" }
|
||||
.codicon-replace-all:before { content: "\eb3c" }
|
||||
.codicon-replace:before { content: "\eb3d" }
|
||||
.codicon-repo-clone:before { content: "\eb3e" }
|
||||
.codicon-repo-force-push:before { content: "\eb3f" }
|
||||
.codicon-repo-pull:before { content: "\eb40" }
|
||||
.codicon-repo-push:before { content: "\eb41" }
|
||||
.codicon-report:before { content: "\eb42" }
|
||||
.codicon-request-changes:before { content: "\eb43" }
|
||||
.codicon-rocket:before { content: "\eb44" }
|
||||
.codicon-root-folder-opened:before { content: "\eb45" }
|
||||
.codicon-root-folder:before { content: "\eb46" }
|
||||
.codicon-rss:before { content: "\eb47" }
|
||||
.codicon-ruby:before { content: "\eb48" }
|
||||
.codicon-save-all:before { content: "\eb49" }
|
||||
.codicon-save-as:before { content: "\eb4a" }
|
||||
.codicon-save:before { content: "\eb4b" }
|
||||
.codicon-screen-full:before { content: "\eb4c" }
|
||||
.codicon-screen-normal:before { content: "\eb4d" }
|
||||
.codicon-search-stop:before { content: "\eb4e" }
|
||||
.codicon-server:before { content: "\eb50" }
|
||||
.codicon-settings-gear:before { content: "\eb51" }
|
||||
.codicon-settings:before { content: "\eb52" }
|
||||
.codicon-shield:before { content: "\eb53" }
|
||||
.codicon-smiley:before { content: "\eb54" }
|
||||
.codicon-sort-precedence:before { content: "\eb55" }
|
||||
.codicon-split-horizontal:before { content: "\eb56" }
|
||||
.codicon-split-vertical:before { content: "\eb57" }
|
||||
.codicon-squirrel:before { content: "\eb58" }
|
||||
.codicon-star-full:before { content: "\eb59" }
|
||||
.codicon-star-half:before { content: "\eb5a" }
|
||||
.codicon-symbol-class:before { content: "\eb5b" }
|
||||
.codicon-symbol-color:before { content: "\eb5c" }
|
||||
.codicon-symbol-constant:before { content: "\eb5d" }
|
||||
.codicon-symbol-enum-member:before { content: "\eb5e" }
|
||||
.codicon-symbol-field:before { content: "\eb5f" }
|
||||
.codicon-symbol-file:before { content: "\eb60" }
|
||||
.codicon-symbol-interface:before { content: "\eb61" }
|
||||
.codicon-symbol-keyword:before { content: "\eb62" }
|
||||
.codicon-symbol-misc:before { content: "\eb63" }
|
||||
.codicon-symbol-operator:before { content: "\eb64" }
|
||||
.codicon-symbol-property:before { content: "\eb65" }
|
||||
.codicon-wrench:before { content: "\eb65" }
|
||||
.codicon-wrench-subaction:before { content: "\eb65" }
|
||||
.codicon-symbol-snippet:before { content: "\eb66" }
|
||||
.codicon-tasklist:before { content: "\eb67" }
|
||||
.codicon-telescope:before { content: "\eb68" }
|
||||
.codicon-text-size:before { content: "\eb69" }
|
||||
.codicon-three-bars:before { content: "\eb6a" }
|
||||
.codicon-thumbsdown:before { content: "\eb6b" }
|
||||
.codicon-thumbsup:before { content: "\eb6c" }
|
||||
.codicon-tools:before { content: "\eb6d" }
|
||||
.codicon-triangle-down:before { content: "\eb6e" }
|
||||
.codicon-triangle-left:before { content: "\eb6f" }
|
||||
.codicon-triangle-right:before { content: "\eb70" }
|
||||
.codicon-triangle-up:before { content: "\eb71" }
|
||||
.codicon-twitter:before { content: "\eb72" }
|
||||
.codicon-unfold:before { content: "\eb73" }
|
||||
.codicon-unlock:before { content: "\eb74" }
|
||||
.codicon-unmute:before { content: "\eb75" }
|
||||
.codicon-unverified:before { content: "\eb76" }
|
||||
.codicon-verified:before { content: "\eb77" }
|
||||
.codicon-versions:before { content: "\eb78" }
|
||||
.codicon-vm-active:before { content: "\eb79" }
|
||||
.codicon-vm-outline:before { content: "\eb7a" }
|
||||
.codicon-vm-running:before { content: "\eb7b" }
|
||||
.codicon-watch:before { content: "\eb7c" }
|
||||
.codicon-whitespace:before { content: "\eb7d" }
|
||||
.codicon-whole-word:before { content: "\eb7e" }
|
||||
.codicon-window:before { content: "\eb7f" }
|
||||
.codicon-word-wrap:before { content: "\eb80" }
|
||||
.codicon-zoom-in:before { content: "\eb81" }
|
||||
.codicon-zoom-out:before { content: "\eb82" }
|
||||
.codicon-list-filter:before { content: "\eb83" }
|
||||
.codicon-list-flat:before { content: "\eb84" }
|
||||
.codicon-list-selection:before { content: "\eb85" }
|
||||
.codicon-selection:before { content: "\eb85" }
|
||||
.codicon-list-tree:before { content: "\eb86" }
|
||||
.codicon-debug-breakpoint-function-unverified:before { content: "\eb87" }
|
||||
.codicon-debug-breakpoint-function:before { content: "\eb88" }
|
||||
.codicon-debug-breakpoint-function-disabled:before { content: "\eb88" }
|
||||
.codicon-debug-stackframe-active:before { content: "\eb89" }
|
||||
.codicon-debug-stackframe-dot:before { content: "\eb8a" }
|
||||
.codicon-debug-stackframe:before { content: "\eb8b" }
|
||||
.codicon-debug-stackframe-focused:before { content: "\eb8b" }
|
||||
.codicon-debug-breakpoint-unsupported:before { content: "\eb8c" }
|
||||
.codicon-symbol-string:before { content: "\eb8d" }
|
||||
.codicon-debug-reverse-continue:before { content: "\eb8e" }
|
||||
.codicon-debug-step-back:before { content: "\eb8f" }
|
||||
.codicon-debug-restart-frame:before { content: "\eb90" }
|
||||
.codicon-debug-alternate:before { content: "\eb91" }
|
||||
.codicon-call-incoming:before { content: "\eb92" }
|
||||
.codicon-call-outgoing:before { content: "\eb93" }
|
||||
.codicon-menu:before { content: "\eb94" }
|
||||
.codicon-expand-all:before { content: "\eb95" }
|
||||
.codicon-feedback:before { content: "\eb96" }
|
||||
.codicon-group-by-ref-type:before { content: "\eb97" }
|
||||
.codicon-ungroup-by-ref-type:before { content: "\eb98" }
|
||||
.codicon-account:before { content: "\eb99" }
|
||||
.codicon-bell-dot:before { content: "\eb9a" }
|
||||
.codicon-debug-console:before { content: "\eb9b" }
|
||||
.codicon-library:before { content: "\eb9c" }
|
||||
.codicon-output:before { content: "\eb9d" }
|
||||
.codicon-run-all:before { content: "\eb9e" }
|
||||
.codicon-sync-ignored:before { content: "\eb9f" }
|
||||
.codicon-debug-alt-2:before { content: "\f101" }
|
||||
.codicon-debug-alt:before { content: "\f102" }
|
||||
24
src/vs/base/browser/ui/codicons/codicon/codicon.css
Normal file
24
src/vs/base/browser/ui/codicons/codicon/codicon.css
Normal file
@@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
@font-face {
|
||||
font-family: "codicon";
|
||||
src: url("./codicon.ttf?5d4d76ab2ce5108968ad644d591a16a6") format("truetype");
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
font: normal normal normal 16px/1 codicon;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
text-align: center;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
/* icon rules are dynamically created in codiconStyles */
|
||||
Binary file not shown.
@@ -3,9 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./codicon/codicon';
|
||||
import 'vs/css!./codicon/codicon-modifications';
|
||||
import 'vs/css!./codicon/codicon-animations';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
|
||||
39
src/vs/base/browser/ui/codicons/codiconStyles.ts
Normal file
39
src/vs/base/browser/ui/codicons/codiconStyles.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./codicon/codicon';
|
||||
import 'vs/css!./codicon/codicon-modifications';
|
||||
import 'vs/css!./codicon/codicon-animations';
|
||||
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { createStyleSheet } from 'vs/base/browser/dom';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
|
||||
function initialize() {
|
||||
let codiconStyleSheet = createStyleSheet();
|
||||
codiconStyleSheet.id = 'codiconStyles';
|
||||
|
||||
function updateAll() {
|
||||
const rules = [];
|
||||
for (let c of iconRegistry.all) {
|
||||
rules.push(formatRule(c));
|
||||
}
|
||||
codiconStyleSheet.innerHTML = rules.join('\n');
|
||||
}
|
||||
|
||||
const delayer = new RunOnceScheduler(updateAll, 0);
|
||||
iconRegistry.onDidRegister(() => delayer.schedule());
|
||||
delayer.schedule();
|
||||
}
|
||||
|
||||
function formatRule(c: Codicon) {
|
||||
let def = c.definition;
|
||||
while (def instanceof Codicon) {
|
||||
def = def.definition;
|
||||
}
|
||||
return `.codicon-${c.id}:before { content: '${def.character}'; }`;
|
||||
}
|
||||
|
||||
initialize();
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./dialog';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { $, hide, show, EventHelper, clearNode, removeClasses, addClass, addClasses, removeNode, isAncestor, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { $, hide, show, EventHelper, clearNode, removeClasses, addClasses, removeNode, isAncestor, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
@@ -17,6 +17,7 @@ import { Action } from 'vs/base/common/actions';
|
||||
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { isMacintosh, isLinux } from 'vs/base/common/platform';
|
||||
import { SimpleCheckbox, ISimpleCheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
export interface IDialogOptions {
|
||||
cancelId?: number;
|
||||
@@ -37,6 +38,9 @@ export interface IDialogStyles extends IButtonStyles, ISimpleCheckboxStyles {
|
||||
dialogBackground?: Color;
|
||||
dialogShadow?: Color;
|
||||
dialogBorder?: Color;
|
||||
errorIconForeground?: Color;
|
||||
warningIconForeground?: Color;
|
||||
infoIconForeground?: Color;
|
||||
}
|
||||
|
||||
interface ButtonMapEntry {
|
||||
@@ -44,6 +48,11 @@ interface ButtonMapEntry {
|
||||
index: number;
|
||||
}
|
||||
|
||||
const dialogErrorIcon = registerIcon('dialog-error', Codicon.error);
|
||||
const dialogWarningIcon = registerIcon('dialog-warning', Codicon.warning);
|
||||
const dialogInfoIcon = registerIcon('dialog-info', Codicon.info);
|
||||
const dialogCloseIcon = registerIcon('dialog-close', Codicon.close);
|
||||
|
||||
export class Dialog extends Disposable {
|
||||
private element: HTMLElement | undefined;
|
||||
private shadowElement: HTMLElement | undefined;
|
||||
@@ -202,30 +211,29 @@ export class Dialog extends Disposable {
|
||||
}
|
||||
}));
|
||||
|
||||
addClass(this.iconElement, 'codicon');
|
||||
removeClasses(this.iconElement, 'codicon-alert', 'codicon-warning', 'codicon-info');
|
||||
removeClasses(this.iconElement, dialogErrorIcon.classNames, dialogWarningIcon.classNames, dialogInfoIcon.classNames, Codicon.loading.classNames);
|
||||
|
||||
switch (this.options.type) {
|
||||
case 'error':
|
||||
addClass(this.iconElement, 'codicon-error');
|
||||
addClasses(this.iconElement, dialogErrorIcon.classNames);
|
||||
break;
|
||||
case 'warning':
|
||||
addClass(this.iconElement, 'codicon-warning');
|
||||
addClasses(this.iconElement, dialogWarningIcon.classNames);
|
||||
break;
|
||||
case 'pending':
|
||||
addClasses(this.iconElement, 'codicon-loading', 'codicon-animation-spin');
|
||||
addClasses(this.iconElement, Codicon.loading.classNames, 'codicon-animation-spin');
|
||||
break;
|
||||
case 'none':
|
||||
case 'info':
|
||||
case 'question':
|
||||
default:
|
||||
addClass(this.iconElement, 'codicon-info');
|
||||
addClasses(this.iconElement, dialogInfoIcon.classNames);
|
||||
break;
|
||||
}
|
||||
|
||||
const actionBar = new ActionBar(this.toolbarContainer, {});
|
||||
|
||||
const action = new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), 'codicon codicon-close', true, () => {
|
||||
const action = new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), dialogCloseIcon.classNames, true, () => {
|
||||
resolve({ button: this.options.cancelId || 0, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined });
|
||||
return Promise.resolve();
|
||||
});
|
||||
@@ -268,10 +276,28 @@ export class Dialog extends Disposable {
|
||||
this.checkbox.style(style);
|
||||
}
|
||||
|
||||
if (this.messageDetailElement) {
|
||||
if (this.messageDetailElement && fgColor && bgColor) {
|
||||
const messageDetailColor = Color.fromHex(fgColor).transparent(.9);
|
||||
this.messageDetailElement.style.color = messageDetailColor.makeOpaque(Color.fromHex(bgColor)).toString();
|
||||
}
|
||||
|
||||
if (this.iconElement) {
|
||||
let color;
|
||||
switch (this.options.type) {
|
||||
case 'error':
|
||||
color = style.errorIconForeground;
|
||||
break;
|
||||
case 'warning':
|
||||
color = style.warningIconForeground;
|
||||
break;
|
||||
default:
|
||||
color = style.infoIconForeground;
|
||||
break;
|
||||
}
|
||||
if (color) {
|
||||
this.iconElement.style.color = color.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable | null => {
|
||||
this.element = append(el, $('a.action-label.codicon'));
|
||||
this.element = append(el, $('a.action-label.codicon')); // todo@aeschli: remove codicon, should come through `this.clazz`
|
||||
if (this.clazz) {
|
||||
addClasses(this.element, this.clazz);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export interface IFindInputCheckboxOpts {
|
||||
readonly appendTitle: string;
|
||||
@@ -21,7 +22,7 @@ const NLS_REGEX_CHECKBOX_LABEL = nls.localize('regexDescription', "Use Regular E
|
||||
export class CaseSensitiveCheckbox extends Checkbox {
|
||||
constructor(opts: IFindInputCheckboxOpts) {
|
||||
super({
|
||||
actionClassName: 'codicon-case-sensitive',
|
||||
icon: Codicon.caseSensitive,
|
||||
title: NLS_CASE_SENSITIVE_CHECKBOX_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
@@ -33,7 +34,7 @@ export class CaseSensitiveCheckbox extends Checkbox {
|
||||
export class WholeWordsCheckbox extends Checkbox {
|
||||
constructor(opts: IFindInputCheckboxOpts) {
|
||||
super({
|
||||
actionClassName: 'codicon-whole-word',
|
||||
icon: Codicon.wholeWord,
|
||||
title: NLS_WHOLE_WORD_CHECKBOX_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
@@ -45,7 +46,7 @@ export class WholeWordsCheckbox extends Checkbox {
|
||||
export class RegexCheckbox extends Checkbox {
|
||||
constructor(opts: IFindInputCheckboxOpts) {
|
||||
super({
|
||||
actionClassName: 'codicon-regex',
|
||||
icon: Codicon.regex,
|
||||
title: NLS_REGEX_CHECKBOX_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ICheckboxStyles, Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
|
||||
import { IFindInputCheckboxOpts } from 'vs/base/browser/ui/findinput/findInputCheckboxes';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export interface IReplaceInputOptions extends IReplaceInputStyles {
|
||||
readonly placeholder?: string;
|
||||
@@ -42,7 +43,7 @@ export class PreserveCaseCheckbox extends Checkbox {
|
||||
constructor(opts: IFindInputCheckboxOpts) {
|
||||
super({
|
||||
// TODO: does this need its own icon?
|
||||
actionClassName: 'codicon-preserve-case',
|
||||
icon: Codicon.preserveCase,
|
||||
title: NLS_PRESERVE_CASE_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
|
||||
@@ -594,7 +594,7 @@ export class InputBox extends Widget {
|
||||
|
||||
this.element.style.backgroundColor = background;
|
||||
this.element.style.color = foreground;
|
||||
this.input.style.backgroundColor = background;
|
||||
this.input.style.backgroundColor = 'inherit';
|
||||
this.input.style.color = foreground;
|
||||
|
||||
this.element.style.borderWidth = border ? '1px' : '';
|
||||
|
||||
@@ -129,10 +129,6 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-list-type-filter > .controls > .filter:checked::before {
|
||||
content: "\eb83" !important; /* codicon-list-filter */
|
||||
}
|
||||
|
||||
.monaco-list-type-filter > .controls > .filter {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
@@ -63,17 +63,6 @@ export interface IIdentityProvider<T> {
|
||||
getId(element: T): { toString(): string; };
|
||||
}
|
||||
|
||||
export enum ListAriaRootRole {
|
||||
/** default list structure role */
|
||||
LIST = 'list',
|
||||
|
||||
/** default tree structure role */
|
||||
TREE = 'tree',
|
||||
|
||||
/** role='tree' can interfere with screenreaders reading nested elements inside the tree row. Use FORM in that case. */
|
||||
FORM = 'form'
|
||||
}
|
||||
|
||||
export interface IKeyboardNavigationLabelProvider<T> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,10 +7,11 @@ import 'vs/css!./list';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent } from './list';
|
||||
import { List, IListStyles, IListOptions } from './listWidget';
|
||||
import { List, IListStyles, IListOptions, IListAccessibilityProvider } from './listWidget';
|
||||
import { IPagedModel } from 'vs/base/common/paging';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
|
||||
export interface IPagedRenderer<TElement, TTemplateData> extends IListRenderer<TElement, TTemplateData> {
|
||||
renderPlaceholder(index: number, templateData: TTemplateData): void;
|
||||
@@ -70,6 +71,54 @@ class PagedRenderer<TElement, TTemplateData> implements IListRenderer<number, IT
|
||||
}
|
||||
}
|
||||
|
||||
class PagedAccessibilityProvider<T> implements IListAccessibilityProvider<number> {
|
||||
|
||||
constructor(
|
||||
private modelProvider: () => IPagedModel<T>,
|
||||
private accessibilityProvider: IListAccessibilityProvider<T>
|
||||
) { }
|
||||
|
||||
getWidgetAriaLabel(): string {
|
||||
return this.accessibilityProvider.getWidgetAriaLabel();
|
||||
}
|
||||
|
||||
getAriaLabel(index: number): string | null {
|
||||
const model = this.modelProvider();
|
||||
|
||||
if (!model.isResolved(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.accessibilityProvider.getAriaLabel(model.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
export interface IPagedListOptions<T> {
|
||||
readonly enableKeyboardNavigation?: boolean;
|
||||
readonly automaticKeyboardNavigation?: boolean;
|
||||
readonly ariaLabel?: string;
|
||||
readonly keyboardSupport?: boolean;
|
||||
readonly multipleSelectionSupport?: boolean;
|
||||
readonly accessibilityProvider?: IListAccessibilityProvider<T>;
|
||||
|
||||
// list view options
|
||||
readonly useShadows?: boolean;
|
||||
readonly verticalScrollMode?: ScrollbarVisibility;
|
||||
readonly setRowLineHeight?: boolean;
|
||||
readonly setRowHeight?: boolean;
|
||||
readonly supportDynamicHeights?: boolean;
|
||||
readonly mouseSupport?: boolean;
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly additionalScrollHeight?: number;
|
||||
}
|
||||
|
||||
function fromPagedListOptions<T>(modelProvider: () => IPagedModel<T>, options: IPagedListOptions<T>): IListOptions<number> {
|
||||
return {
|
||||
...options,
|
||||
accessibilityProvider: options.accessibilityProvider && new PagedAccessibilityProvider(modelProvider, options.accessibilityProvider)
|
||||
};
|
||||
}
|
||||
|
||||
export class PagedList<T> implements IDisposable {
|
||||
|
||||
private list: List<number>;
|
||||
@@ -80,10 +129,11 @@ export class PagedList<T> implements IDisposable {
|
||||
container: HTMLElement,
|
||||
virtualDelegate: IListVirtualDelegate<number>,
|
||||
renderers: IPagedRenderer<T, any>[],
|
||||
options: IListOptions<any> = {}
|
||||
options: IPagedListOptions<T> = {}
|
||||
) {
|
||||
const pagedRenderers = renderers.map(r => new PagedRenderer<T, ITemplateData<T>>(r, () => this.model));
|
||||
this.list = new List(user, container, virtualDelegate, pagedRenderers, options);
|
||||
const modelProvider = () => this.model;
|
||||
const pagedRenderers = renderers.map(r => new PagedRenderer<T, ITemplateData<T>>(r, modelProvider));
|
||||
this.list = new List(user, container, virtualDelegate, pagedRenderers, fromPagedListOptions(modelProvider, options));
|
||||
}
|
||||
|
||||
getHTMLElement(): HTMLElement {
|
||||
|
||||
@@ -41,11 +41,11 @@ export interface IListViewDragAndDrop<T> extends IListDragAndDrop<T> {
|
||||
getDragElements(element: T): T[];
|
||||
}
|
||||
|
||||
export interface IAriaProvider<T> {
|
||||
getSetSize(element: T, index: number, listLength: number): number;
|
||||
getPosInSet(element: T, index: number): number;
|
||||
export interface IListViewAccessibilityProvider<T> {
|
||||
getSetSize?(element: T, index: number, listLength: number): number;
|
||||
getPosInSet?(element: T, index: number): number;
|
||||
getRole?(element: T): string;
|
||||
isChecked?(element: T): boolean;
|
||||
isChecked?(element: T): boolean | undefined;
|
||||
}
|
||||
|
||||
export interface IListViewOptions<T> {
|
||||
@@ -57,7 +57,7 @@ export interface IListViewOptions<T> {
|
||||
readonly supportDynamicHeights?: boolean;
|
||||
readonly mouseSupport?: boolean;
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly ariaProvider?: IAriaProvider<T>;
|
||||
readonly accessibilityProvider?: IListViewAccessibilityProvider<T>;
|
||||
readonly additionalScrollHeight?: number;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,40 @@ function equalsDragFeedback(f1: number[] | undefined, f2: number[] | undefined):
|
||||
return f1 === f2;
|
||||
}
|
||||
|
||||
class ListViewAccessibilityProvider<T> implements Required<IListViewAccessibilityProvider<T>> {
|
||||
|
||||
readonly getSetSize: (element: any, index: number, listLength: number) => number;
|
||||
readonly getPosInSet: (element: any, index: number) => number;
|
||||
readonly getRole: (element: T) => string;
|
||||
readonly isChecked: (element: T) => boolean | undefined;
|
||||
|
||||
constructor(accessibilityProvider?: IListViewAccessibilityProvider<T>) {
|
||||
if (accessibilityProvider?.getSetSize) {
|
||||
this.getSetSize = accessibilityProvider.getSetSize.bind(accessibilityProvider);
|
||||
} else {
|
||||
this.getSetSize = (e, i, l) => l;
|
||||
}
|
||||
|
||||
if (accessibilityProvider?.getPosInSet) {
|
||||
this.getPosInSet = accessibilityProvider.getPosInSet.bind(accessibilityProvider);
|
||||
} else {
|
||||
this.getPosInSet = (e, i) => i + 1;
|
||||
}
|
||||
|
||||
if (accessibilityProvider?.getRole) {
|
||||
this.getRole = accessibilityProvider.getRole.bind(accessibilityProvider);
|
||||
} else {
|
||||
this.getRole = _ => 'listitem';
|
||||
}
|
||||
|
||||
if (accessibilityProvider?.isChecked) {
|
||||
this.isChecked = accessibilityProvider.isChecked.bind(accessibilityProvider);
|
||||
} else {
|
||||
this.isChecked = _ => undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
private static InstanceCount = 0;
|
||||
@@ -181,7 +215,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
private supportDynamicHeights: boolean;
|
||||
private horizontalScrolling: boolean;
|
||||
private additionalScrollHeight: number;
|
||||
private ariaProvider: IAriaProvider<T>;
|
||||
private accessibilityProvider: ListViewAccessibilityProvider<T>;
|
||||
private scrollWidth: number | undefined;
|
||||
|
||||
private dnd: IListViewDragAndDrop<T>;
|
||||
@@ -237,7 +271,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
this.additionalScrollHeight = typeof options.additionalScrollHeight === 'undefined' ? 0 : options.additionalScrollHeight;
|
||||
|
||||
this.ariaProvider = options.ariaProvider || { getSetSize: (e, i, length) => length, getPosInSet: (_, index) => index + 1 };
|
||||
this.accessibilityProvider = new ListViewAccessibilityProvider(options.accessibilityProvider);
|
||||
|
||||
this.rowsContainer = document.createElement('div');
|
||||
this.rowsContainer.className = 'monaco-list-rows';
|
||||
@@ -611,11 +645,11 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
if (!item.row) {
|
||||
item.row = this.cache.alloc(item.templateId);
|
||||
const role = this.ariaProvider.getRole ? this.ariaProvider.getRole(item.element) : 'listitem';
|
||||
const role = this.accessibilityProvider.getRole(item.element);
|
||||
item.row!.domNode!.setAttribute('role', role);
|
||||
const checked = this.ariaProvider.isChecked ? this.ariaProvider.isChecked(item.element) : undefined;
|
||||
const checked = this.accessibilityProvider.isChecked(item.element);
|
||||
if (typeof checked !== 'undefined') {
|
||||
item.row!.domNode!.setAttribute('aria-checked', String(checked));
|
||||
item.row!.domNode!.setAttribute('aria-checked', String(!!checked));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,8 +721,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
item.row!.domNode!.setAttribute('data-index', `${index}`);
|
||||
item.row!.domNode!.setAttribute('data-last-element', index === this.length - 1 ? 'true' : 'false');
|
||||
item.row!.domNode!.setAttribute('aria-setsize', String(this.ariaProvider.getSetSize(item.element, index, this.length)));
|
||||
item.row!.domNode!.setAttribute('aria-posinset', String(this.ariaProvider.getPosInSet(item.element, index)));
|
||||
item.row!.domNode!.setAttribute('aria-setsize', String(this.accessibilityProvider.getSetSize(item.element, index, this.length)));
|
||||
item.row!.domNode!.setAttribute('aria-posinset', String(this.accessibilityProvider.getPosInSet(item.element, index)));
|
||||
item.row!.domNode!.setAttribute('id', this.getElementDomId(index));
|
||||
|
||||
DOM.toggleClass(item.row!.domNode!, 'drop-target', item.dropTarget);
|
||||
|
||||
@@ -16,8 +16,8 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Event, Emitter, EventBufferer } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole, ListError, IKeyboardNavigationDelegate } from './list';
|
||||
import { ListView, IListViewOptions, IListViewDragAndDrop, IAriaProvider } from './listView';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListError, IKeyboardNavigationDelegate } from './list';
|
||||
import { ListView, IListViewOptions, IListViewDragAndDrop, IListViewAccessibilityProvider } from './listView';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
|
||||
@@ -686,25 +686,11 @@ export interface IStyleController {
|
||||
style(styles: IListStyles): void;
|
||||
}
|
||||
|
||||
export interface IAccessibilityProvider<T> {
|
||||
|
||||
/**
|
||||
* Given an element in the tree, return the ARIA label that should be associated with the
|
||||
* item. This helps screen readers to provide a meaningful label for the currently focused
|
||||
* tree element.
|
||||
*
|
||||
* Returning null will not disable ARIA for the element. Instead it is up to the screen reader
|
||||
* to compute a meaningful label based on the contents of the element in the DOM
|
||||
*
|
||||
* See also: https://www.w3.org/TR/wai-aria/#aria-label
|
||||
*/
|
||||
export interface IListAccessibilityProvider<T> extends IListViewAccessibilityProvider<T> {
|
||||
getAriaLabel(element: T): string | null;
|
||||
|
||||
/**
|
||||
* https://www.w3.org/TR/wai-aria/#aria-level
|
||||
*/
|
||||
getWidgetAriaLabel(): string;
|
||||
getWidgetRole?(): string;
|
||||
getAriaLevel?(element: T): number | undefined;
|
||||
|
||||
onDidChangeActiveDescendant?: Event<void>;
|
||||
getActiveDescendantId?(element: T): string | undefined;
|
||||
}
|
||||
@@ -836,14 +822,12 @@ export interface IListOptions<T> {
|
||||
readonly automaticKeyboardNavigation?: boolean;
|
||||
readonly keyboardNavigationLabelProvider?: IKeyboardNavigationLabelProvider<T>;
|
||||
readonly keyboardNavigationDelegate?: IKeyboardNavigationDelegate;
|
||||
readonly ariaRole?: ListAriaRootRole | string;
|
||||
readonly ariaLabel?: string;
|
||||
readonly keyboardSupport?: boolean;
|
||||
readonly multipleSelectionSupport?: boolean;
|
||||
readonly multipleSelectionController?: IMultipleSelectionController<T>;
|
||||
readonly openController?: IOpenController;
|
||||
readonly styleController?: (suffix: string) => IStyleController;
|
||||
readonly accessibilityProvider?: IAccessibilityProvider<T>;
|
||||
readonly accessibilityProvider?: IListAccessibilityProvider<T>;
|
||||
|
||||
// list view options
|
||||
readonly useShadows?: boolean;
|
||||
@@ -853,7 +837,6 @@ export interface IListOptions<T> {
|
||||
readonly supportDynamicHeights?: boolean;
|
||||
readonly mouseSupport?: boolean;
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly ariaProvider?: IAriaProvider<T>;
|
||||
readonly additionalScrollHeight?: number;
|
||||
}
|
||||
|
||||
@@ -894,7 +877,7 @@ const defaultStyles: IListStyles = {
|
||||
treeIndentGuidesStroke: Color.fromHex('#a9a9a9')
|
||||
};
|
||||
|
||||
const DefaultOptions = {
|
||||
const DefaultOptions: IListOptions<any> = {
|
||||
keyboardSupport: true,
|
||||
mouseSupport: true,
|
||||
multipleSelectionSupport: true,
|
||||
@@ -903,8 +886,7 @@ const DefaultOptions = {
|
||||
onDragStart(): void { },
|
||||
onDragOver() { return false; },
|
||||
drop() { }
|
||||
},
|
||||
ariaRootRole: ListAriaRootRole.LIST
|
||||
}
|
||||
};
|
||||
|
||||
// TODO@Joao: move these utils into a SortedArray class
|
||||
@@ -1036,7 +1018,7 @@ class AccessibiltyRenderer<T> implements IListRenderer<T, HTMLElement> {
|
||||
|
||||
templateId: string = 'a18n';
|
||||
|
||||
constructor(private accessibilityProvider: IAccessibilityProvider<T>) { }
|
||||
constructor(private accessibilityProvider: IListAccessibilityProvider<T>) { }
|
||||
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
@@ -1123,7 +1105,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
private spliceable: ISpliceable<T>;
|
||||
private styleController: IStyleController;
|
||||
private typeLabelController?: TypeLabelController<T>;
|
||||
private accessibilityProvider?: IAccessibilityProvider<T>;
|
||||
private accessibilityProvider?: IListAccessibilityProvider<T>;
|
||||
private _ariaLabel: string = '';
|
||||
|
||||
protected readonly disposables = new DisposableStore();
|
||||
|
||||
@@ -1202,7 +1185,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
renderers: IListRenderer<any /* TODO@joao */, any>[],
|
||||
private _options: IListOptions<T> = DefaultOptions
|
||||
) {
|
||||
this.selection = new SelectionTrait(this._options.ariaRole !== 'listbox');
|
||||
const role = this._options.accessibilityProvider && this._options.accessibilityProvider.getWidgetRole ? this._options.accessibilityProvider?.getWidgetRole() : 'list';
|
||||
this.selection = new SelectionTrait(role !== 'listbox');
|
||||
this.focus = new Trait('focused');
|
||||
|
||||
mixin(_options, defaultStyles, false);
|
||||
@@ -1227,12 +1211,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
};
|
||||
|
||||
this.view = new ListView(container, virtualDelegate, renderers, viewOptions);
|
||||
|
||||
if (typeof _options.ariaRole !== 'string') {
|
||||
this.view.domNode.setAttribute('role', ListAriaRootRole.LIST);
|
||||
} else {
|
||||
this.view.domNode.setAttribute('role', _options.ariaRole);
|
||||
}
|
||||
this.view.domNode.setAttribute('role', role);
|
||||
|
||||
if (_options.styleController) {
|
||||
this.styleController = _options.styleController(this.view.domId);
|
||||
@@ -1273,8 +1252,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
this.onDidChangeFocus(this._onFocusChange, this, this.disposables);
|
||||
this.onDidChangeSelection(this._onSelectionChange, this, this.disposables);
|
||||
|
||||
if (_options.ariaLabel) {
|
||||
this.view.domNode.setAttribute('aria-label', localize('aria list', "{0}. Use the navigation keys to navigate.", _options.ariaLabel));
|
||||
if (this.accessibilityProvider) {
|
||||
this.ariaLabel = this.accessibilityProvider.getWidgetAriaLabel();
|
||||
}
|
||||
if (_options.multipleSelectionSupport) {
|
||||
this.view.domNode.setAttribute('aria-multiselectable', 'true');
|
||||
@@ -1377,6 +1356,15 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
return this.view.lastVisibleIndex;
|
||||
}
|
||||
|
||||
get ariaLabel(): string {
|
||||
return this._ariaLabel;
|
||||
}
|
||||
|
||||
set ariaLabel(value: string) {
|
||||
this._ariaLabel = value;
|
||||
this.view.domNode.setAttribute('aria-label', localize('aria list', "{0}. Use the navigation keys to navigate.", value));
|
||||
}
|
||||
|
||||
domFocus(): void {
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
|
||||
.menubar.compact {
|
||||
flex-shrink: 0;
|
||||
overflow: visible; /* to avoid the compact menu to be repositioned when clicking */
|
||||
}
|
||||
|
||||
.menubar.compact > .menubar-menu-button {
|
||||
@@ -201,7 +202,7 @@
|
||||
}
|
||||
|
||||
.menubar.compact .toolbar-toggle-more {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 5.625H0V4.5H18V5.625ZM18 14.625H0V13.5H18V14.625ZM18 10.1162H0V9H18V10.1162Z" fill="white"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 209 B |
@@ -19,11 +19,14 @@ import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { stripCodicons } from 'vs/base/common/codicons';
|
||||
import { Codicon, registerIcon, stripCodicons } from 'vs/base/common/codicons';
|
||||
|
||||
export const MENU_MNEMONIC_REGEX = /\(&([^\s&])\)|(^|[^&])&([^\s&])/;
|
||||
export const MENU_ESCAPED_MNEMONIC_REGEX = /(&)?(&)([^\s&])/g;
|
||||
|
||||
const menuSelectionIcon = registerIcon('menu-selection', Codicon.check);
|
||||
const menuSubmenuIcon = registerIcon('menu-submenu', Codicon.chevronRight);
|
||||
|
||||
export enum Direction {
|
||||
Right,
|
||||
Left
|
||||
@@ -423,7 +426,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
this.check = append(this.item, $('span.menu-item-check.codicon.codicon-check'));
|
||||
this.check = append(this.item, $('span.menu-item-check' + menuSelectionIcon.cssSelector));
|
||||
this.check.setAttribute('role', 'none');
|
||||
|
||||
this.label = append(this.item, $('span.action-label'));
|
||||
@@ -670,7 +673,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
addClass(this.item, 'monaco-submenu-item');
|
||||
this.item.setAttribute('aria-haspopup', 'true');
|
||||
this.updateAriaExpanded('false');
|
||||
this.submenuIndicator = append(this.item, $('span.submenu-indicator.codicon.codicon-chevron-right'));
|
||||
this.submenuIndicator = append(this.item, $('span.submenu-indicator' + menuSubmenuIcon.cssSelector));
|
||||
this.submenuIndicator.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,12 @@ import { ScanCodeUtils, ScanCode } from 'vs/base/common/scanCode';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
const menuBarMoreIcon = registerIcon('menubar-more', Codicon.more);
|
||||
|
||||
export interface IMenuBarOptions {
|
||||
enableMnemonics?: boolean;
|
||||
disableAltFocus?: boolean;
|
||||
@@ -313,7 +316,7 @@ export class MenuBar extends Disposable {
|
||||
const label = this.options.compactMode !== undefined ? nls.localize('mAppMenu', 'Application Menu') : nls.localize('mMore', 'More');
|
||||
const title = this.options.compactMode !== undefined ? label : undefined;
|
||||
const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': -1, 'aria-label': label, 'title': title, 'aria-haspopup': true });
|
||||
const titleElement = $('div.menubar-menu-title.toolbar-toggle-more.codicon.codicon-more', { 'role': 'none', 'aria-hidden': true });
|
||||
const titleElement = $('div.menubar-menu-title.toolbar-toggle-more' + menuBarMoreIcon.cssSelector, { 'role': 'none', 'aria-hidden': true });
|
||||
|
||||
buttonElement.appendChild(titleElement);
|
||||
this.container.appendChild(buttonElement);
|
||||
|
||||
@@ -9,6 +9,11 @@ import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/s
|
||||
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
|
||||
import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
|
||||
import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
|
||||
const scrollbarButtonLeftIcon = registerIcon('scrollbar-button-left', Codicon.triangleLeft);
|
||||
const scrollbarButtonRightIcon = registerIcon('scrollbar-button-right', Codicon.triangleRight);
|
||||
|
||||
export class HorizontalScrollbar extends AbstractScrollbar {
|
||||
|
||||
@@ -36,7 +41,8 @@ export class HorizontalScrollbar extends AbstractScrollbar {
|
||||
let scrollbarDelta = (options.horizontalScrollbarSize - ARROW_IMG_SIZE) / 2;
|
||||
|
||||
this._createArrow({
|
||||
className: 'scra codicon codicon-triangle-left',
|
||||
className: 'scra',
|
||||
icon: scrollbarButtonLeftIcon,
|
||||
top: scrollbarDelta,
|
||||
left: arrowDelta,
|
||||
bottom: undefined,
|
||||
@@ -47,7 +53,8 @@ export class HorizontalScrollbar extends AbstractScrollbar {
|
||||
});
|
||||
|
||||
this._createArrow({
|
||||
className: 'scra codicon codicon-triangle-right',
|
||||
className: 'scra',
|
||||
icon: scrollbarButtonRightIcon,
|
||||
top: scrollbarDelta,
|
||||
left: undefined,
|
||||
bottom: undefined,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/scrollbars';
|
||||
import { isEdge } from 'vs/base/browser/browser';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IMouseEvent, StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
@@ -266,7 +265,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
}
|
||||
|
||||
public setScrollDimensions(dimensions: INewScrollDimensions): void {
|
||||
this._scrollable.setScrollDimensions(dimensions);
|
||||
this._scrollable.setScrollDimensions(dimensions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,7 +335,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
this._onMouseWheel(new StandardWheelEvent(browserEvent));
|
||||
};
|
||||
|
||||
this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, isEdge ? 'mousewheel' : 'wheel', onMouseWheel, { passive: false }));
|
||||
this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.EventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveM
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Widget } from 'vs/base/browser/ui/widget';
|
||||
import { IntervalTimer, TimeoutTimer } from 'vs/base/common/async';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { addClasses } from 'vs/base/browser/dom';
|
||||
|
||||
/**
|
||||
* The arrow image size.
|
||||
@@ -16,6 +18,7 @@ export const ARROW_IMG_SIZE = 11;
|
||||
export interface ScrollbarArrowOptions {
|
||||
onActivate: () => void;
|
||||
className: string;
|
||||
icon: Codicon;
|
||||
|
||||
bgWidth: number;
|
||||
bgHeight: number;
|
||||
@@ -59,6 +62,8 @@ export class ScrollbarArrow extends Widget {
|
||||
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.className = opts.className;
|
||||
addClasses(this.domNode, opts.icon.classNames);
|
||||
|
||||
this.domNode.style.position = 'absolute';
|
||||
this.domNode.style.width = ARROW_IMG_SIZE + 'px';
|
||||
this.domNode.style.height = ARROW_IMG_SIZE + 'px';
|
||||
|
||||
@@ -9,6 +9,10 @@ import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/s
|
||||
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
|
||||
import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
|
||||
import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
const scrollbarButtonUpIcon = registerIcon('scrollbar-button-up', Codicon.triangleUp);
|
||||
const scrollbarButtonDownIcon = registerIcon('scrollbar-button-down', Codicon.triangleDown);
|
||||
|
||||
export class VerticalScrollbar extends AbstractScrollbar {
|
||||
|
||||
@@ -37,7 +41,8 @@ export class VerticalScrollbar extends AbstractScrollbar {
|
||||
let scrollbarDelta = (options.verticalScrollbarSize - ARROW_IMG_SIZE) / 2;
|
||||
|
||||
this._createArrow({
|
||||
className: 'scra codicon codicon-triangle-up',
|
||||
className: 'scra',
|
||||
icon: scrollbarButtonUpIcon,
|
||||
top: arrowDelta,
|
||||
left: scrollbarDelta,
|
||||
bottom: undefined,
|
||||
@@ -48,7 +53,8 @@ export class VerticalScrollbar extends AbstractScrollbar {
|
||||
});
|
||||
|
||||
this._createArrow({
|
||||
className: 'scra codicon codicon-triangle-down',
|
||||
className: 'scra',
|
||||
icon: scrollbarButtonDownIcon,
|
||||
top: undefined,
|
||||
left: scrollbarDelta,
|
||||
bottom: arrowDelta,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxSty
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
||||
import { IContentActionHandler } from 'vs/base/browser/formattedTextRenderer';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -732,12 +733,20 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.listRenderer = new SelectListRenderer();
|
||||
|
||||
this.selectList = new List('SelectBoxCustom', this.selectDropDownListContainer, this, [this.listRenderer], {
|
||||
ariaLabel: this.selectBoxOptions.ariaLabel,
|
||||
useShadows: false,
|
||||
verticalScrollMode: ScrollbarVisibility.Visible,
|
||||
keyboardSupport: false,
|
||||
mouseSupport: false
|
||||
mouseSupport: false,
|
||||
accessibilityProvider: {
|
||||
getAriaLabel: (element) => element.text,
|
||||
getWidgetAriaLabel: () => localize('selectBox', "Select Box"),
|
||||
getRole: () => 'option',
|
||||
getWidgetRole: () => 'listbox'
|
||||
}
|
||||
});
|
||||
if (this.selectBoxOptions.ariaLabel) {
|
||||
this.selectList.ariaLabel = this.selectBoxOptions.ariaLabel;
|
||||
}
|
||||
|
||||
// SetUp list keyboard controller - control navigation, disabled items, focus
|
||||
const onSelectDropDownKeyDown = Event.chain(domEvent(this.selectDropDownListContainer, 'keydown'))
|
||||
|
||||
@@ -236,6 +236,7 @@ export abstract class Pane extends Disposable implements IView {
|
||||
const height = this._orientation === Orientation.VERTICAL ? size - headerSize : this.orthogonalSize - headerSize;
|
||||
|
||||
if (this.isExpanded()) {
|
||||
toggleClass(this.body, 'wide', width >= 600);
|
||||
this.layoutBody(height, width);
|
||||
this.expandedSize = size;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,12 @@ import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
export const CONTEXT = 'context.toolbar';
|
||||
|
||||
const toolBarMoreIcon = registerIcon('toolbar-more', Codicon.more);
|
||||
|
||||
export interface IToolBarOptions {
|
||||
orientation?: ActionsOrientation;
|
||||
actionViewItemProvider?: IActionViewItemProvider;
|
||||
@@ -65,7 +68,7 @@ export class ToolBar extends Disposable {
|
||||
this.options.actionViewItemProvider,
|
||||
this.actionRunner,
|
||||
this.options.getKeyBinding,
|
||||
'codicon-more',
|
||||
toolBarMoreIcon.classNames,
|
||||
this.options.anchorAlignmentProvider
|
||||
);
|
||||
this.toggleMenuActionViewItem.value.setActionContext(this.actionBar.context);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/tree';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate, ListAriaRootRole } from 'vs/base/browser/ui/list/list';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode, addClasses, removeClasses } from 'vs/base/browser/dom';
|
||||
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
@@ -26,6 +26,7 @@ import { values } from 'vs/base/common/map';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { SetMap } from 'vs/base/common/collections';
|
||||
import { treeItemExpandedIcon, treeFilterOnTypeOnIcon, treeFilterOnTypeOffIcon, treeFilterClearIcon } from 'vs/base/browser/ui/tree/treeIcons';
|
||||
|
||||
class TreeElementsDragAndDropData<T, TFilterData, TContext> extends ElementsDragAndDropData<T, TContext> {
|
||||
|
||||
@@ -162,9 +163,30 @@ function asListOptions<T, TFilterData, TRef>(modelProvider: () => ITreeModel<T,
|
||||
},
|
||||
accessibilityProvider: options.accessibilityProvider && {
|
||||
...options.accessibilityProvider,
|
||||
getSetSize(node) {
|
||||
const model = modelProvider();
|
||||
const ref = model.getNodeLocation(node);
|
||||
const parentRef = model.getParentNodeLocation(ref);
|
||||
const parentNode = model.getNode(parentRef);
|
||||
|
||||
return parentNode.visibleChildrenCount;
|
||||
},
|
||||
getPosInSet(node) {
|
||||
return node.visibleChildIndex + 1;
|
||||
},
|
||||
isChecked: options.accessibilityProvider && options.accessibilityProvider.isChecked ? (node) => {
|
||||
return options.accessibilityProvider!.isChecked!(node.element);
|
||||
} : undefined,
|
||||
getRole: options.accessibilityProvider && options.accessibilityProvider.getRole ? (node) => {
|
||||
return options.accessibilityProvider!.getRole!(node.element);
|
||||
} : () => 'treeitem',
|
||||
getAriaLabel(e) {
|
||||
return options.accessibilityProvider!.getAriaLabel(e.element);
|
||||
},
|
||||
getWidgetAriaLabel() {
|
||||
return options.accessibilityProvider!.getWidgetAriaLabel();
|
||||
},
|
||||
getWidgetRole: options.accessibilityProvider && options.accessibilityProvider.getWidgetRole ? () => options.accessibilityProvider!.getWidgetRole!() : () => 'tree',
|
||||
getAriaLevel(node) {
|
||||
return node.depth;
|
||||
},
|
||||
@@ -178,27 +200,7 @@ function asListOptions<T, TFilterData, TRef>(modelProvider: () => ITreeModel<T,
|
||||
return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(node.element);
|
||||
}
|
||||
},
|
||||
enableKeyboardNavigation: options.simpleKeyboardNavigation,
|
||||
ariaProvider: {
|
||||
getSetSize(node) {
|
||||
const model = modelProvider();
|
||||
const ref = model.getNodeLocation(node);
|
||||
const parentRef = model.getParentNodeLocation(ref);
|
||||
const parentNode = model.getNode(parentRef);
|
||||
|
||||
return parentNode.visibleChildrenCount;
|
||||
},
|
||||
getPosInSet(node) {
|
||||
return node.visibleChildIndex + 1;
|
||||
},
|
||||
isChecked: options.ariaProvider && options.ariaProvider.isChecked ? (node) => {
|
||||
return options.ariaProvider!.isChecked!(node.element);
|
||||
} : undefined,
|
||||
getRole: options.ariaProvider && options.ariaProvider.getRole ? (node) => {
|
||||
return options.ariaProvider!.getRole!(node.element);
|
||||
} : () => 'treeitem'
|
||||
},
|
||||
ariaRole: ListAriaRootRole.TREE
|
||||
enableKeyboardNavigation: options.simpleKeyboardNavigation
|
||||
};
|
||||
}
|
||||
|
||||
@@ -404,10 +406,10 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
||||
}
|
||||
|
||||
if (node.collapsible && (!this.hideTwistiesOfChildlessElements || node.visibleChildrenCount > 0)) {
|
||||
addClasses(templateData.twistie, 'codicon', 'codicon-chevron-down', 'collapsible');
|
||||
addClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible');
|
||||
toggleClass(templateData.twistie, 'collapsed', node.collapsed);
|
||||
} else {
|
||||
removeClasses(templateData.twistie, 'codicon', 'codicon-chevron-down', 'collapsible', 'collapsed');
|
||||
removeClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible', 'collapsed');
|
||||
}
|
||||
|
||||
if (node.collapsible) {
|
||||
@@ -645,14 +647,14 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
const controls = append(this.domNode, $('.controls'));
|
||||
|
||||
this._filterOnType = !!tree.options.filterOnType;
|
||||
this.filterOnTypeDomNode = append(controls, $<HTMLInputElement>('input.filter.codicon.codicon-list-selection'));
|
||||
this.filterOnTypeDomNode = append(controls, $<HTMLInputElement>('input.filter'));
|
||||
this.filterOnTypeDomNode.type = 'checkbox';
|
||||
this.filterOnTypeDomNode.checked = this._filterOnType;
|
||||
this.filterOnTypeDomNode.tabIndex = -1;
|
||||
this.updateFilterOnTypeTitle();
|
||||
this.updateFilterOnTypeTitleAndIcon();
|
||||
domEvent(this.filterOnTypeDomNode, 'input')(this.onDidChangeFilterOnType, this, this.disposables);
|
||||
|
||||
this.clearDomNode = append(controls, $<HTMLInputElement>('button.clear.codicon.codicon-close'));
|
||||
this.clearDomNode = append(controls, $<HTMLInputElement>('button.clear' + treeFilterClearIcon.cssSelector));
|
||||
this.clearDomNode.tabIndex = -1;
|
||||
this.clearDomNode.title = localize('clear', "Clear");
|
||||
|
||||
@@ -858,13 +860,17 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
this.tree.refilter();
|
||||
this.tree.domFocus();
|
||||
this.render();
|
||||
this.updateFilterOnTypeTitle();
|
||||
this.updateFilterOnTypeTitleAndIcon();
|
||||
}
|
||||
|
||||
private updateFilterOnTypeTitle(): void {
|
||||
private updateFilterOnTypeTitleAndIcon(): void {
|
||||
if (this.filterOnType) {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
this.filterOnTypeDomNode.title = localize('disable filter on type', "Disable Filter on Type");
|
||||
} else {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
this.filterOnTypeDomNode.title = localize('enable filter on type', "Enable Filter on Type");
|
||||
}
|
||||
}
|
||||
@@ -1445,6 +1451,14 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
return node.element;
|
||||
}
|
||||
|
||||
get ariaLabel(): string {
|
||||
return this.view.ariaLabel;
|
||||
}
|
||||
|
||||
set ariaLabel(value: string) {
|
||||
this.view.ariaLabel = value;
|
||||
}
|
||||
|
||||
domFocus(): void {
|
||||
this.view.domFocus();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole } from 'vs/base/browser/ui/list/list';
|
||||
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper, ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
@@ -15,12 +15,13 @@ import { Iterable } from 'vs/base/common/iterator';
|
||||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { toggleClass } from 'vs/base/browser/dom';
|
||||
import { removeClasses, addClasses } from 'vs/base/browser/dom';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
import { isFilterResult, getVisibleState } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { treeItemLoadingIcon } from 'vs/base/browser/ui/tree/treeIcons';
|
||||
|
||||
interface IAsyncDataTreeNode<TInput, T> {
|
||||
element: TInput | T;
|
||||
@@ -109,7 +110,11 @@ class AsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> implements IT
|
||||
}
|
||||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
toggleClass(twistieElement, 'codicon-loading', element.slow);
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -231,9 +236,21 @@ function asObjectTreeOptions<TInput, T, TFilterData>(options?: IAsyncDataTreeOpt
|
||||
},
|
||||
accessibilityProvider: options.accessibilityProvider && {
|
||||
...options.accessibilityProvider,
|
||||
getPosInSet: undefined,
|
||||
getSetSize: undefined,
|
||||
getRole: options.accessibilityProvider!.getRole ? (el) => {
|
||||
return options.accessibilityProvider!.getRole!(el.element as T);
|
||||
} : () => 'treeitem',
|
||||
isChecked: options.accessibilityProvider!.isChecked ? (e) => {
|
||||
return !!(options.accessibilityProvider?.isChecked!(e.element as T));
|
||||
} : undefined,
|
||||
getAriaLabel(e) {
|
||||
return options.accessibilityProvider!.getAriaLabel(e.element as T);
|
||||
},
|
||||
getWidgetAriaLabel() {
|
||||
return options.accessibilityProvider!.getWidgetAriaLabel();
|
||||
},
|
||||
getWidgetRole: options.accessibilityProvider!.getWidgetRole ? () => options.accessibilityProvider!.getWidgetRole!() : () => 'tree',
|
||||
getAriaLevel: options.accessibilityProvider!.getAriaLevel && (node => {
|
||||
return options.accessibilityProvider!.getAriaLevel!(node.element as T);
|
||||
}),
|
||||
@@ -258,21 +275,6 @@ function asObjectTreeOptions<TInput, T, TFilterData>(options?: IAsyncDataTreeOpt
|
||||
e => (options.expandOnlyOnTwistieClick as ((e: T) => boolean))(e.element as T)
|
||||
)
|
||||
),
|
||||
ariaProvider: options.ariaProvider && {
|
||||
getPosInSet(el, index) {
|
||||
return options.ariaProvider!.getPosInSet(el.element as T, index);
|
||||
},
|
||||
getSetSize(el, index, listLength) {
|
||||
return options.ariaProvider!.getSetSize(el.element as T, index, listLength);
|
||||
},
|
||||
getRole: options.ariaProvider!.getRole ? (el) => {
|
||||
return options.ariaProvider!.getRole!(el.element as T);
|
||||
} : () => 'treeitem',
|
||||
isChecked: options.ariaProvider!.isChecked ? (e) => {
|
||||
return !!(options.ariaProvider?.isChecked!(e.element as T));
|
||||
} : undefined
|
||||
},
|
||||
ariaRole: ListAriaRootRole.TREE,
|
||||
additionalScrollHeight: options.additionalScrollHeight
|
||||
};
|
||||
}
|
||||
@@ -448,6 +450,14 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
return this.tree.lastVisibleElement!.element as T;
|
||||
}
|
||||
|
||||
get ariaLabel(): string {
|
||||
return this.tree.ariaLabel;
|
||||
}
|
||||
|
||||
set ariaLabel(value: string) {
|
||||
this.tree.ariaLabel = value;
|
||||
}
|
||||
|
||||
domFocus(): void {
|
||||
this.tree.domFocus();
|
||||
}
|
||||
@@ -1044,7 +1054,11 @@ class CompressibleAsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> i
|
||||
}
|
||||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
toggleClass(twistieElement, 'codicon-loading', element.slow);
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,6 @@
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.monaco-tl-twistie.codicon-loading::before {
|
||||
.monaco-tl-twistie.codicon-tree-item-loading::before {
|
||||
animation: codicon-spin 1.25s linear infinite;
|
||||
}
|
||||
|
||||
14
src/vs/base/browser/ui/tree/treeIcons.ts
Normal file
14
src/vs/base/browser/ui/tree/treeIcons.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
|
||||
export const treeItemExpandedIcon = registerIcon('tree-item-expanded', Codicon.chevronDown); // collapsed is done with rotation
|
||||
|
||||
export const treeFilterOnTypeOnIcon = registerIcon('tree-filter-on-type-on', Codicon.listFilter);
|
||||
export const treeFilterOnTypeOffIcon = registerIcon('tree-filter-on-type-off', Codicon.listSelection);
|
||||
export const treeFilterClearIcon = registerIcon('tree-filter-clear', Codicon.close);
|
||||
|
||||
export const treeItemLoadingIcon = registerIcon('tree-item-loading', Codicon.loading);
|
||||
Reference in New Issue
Block a user