mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 17:22:42 -05:00
Dashboard toolbar overflow (#9796)
* initial changes for actionbar collapsing * fix more not always all showing after resizing * collapse toolbar if window size is already small when dashboard is opened * make wrapping default behavior and collapse opt in * fix so keyboard navigation works in overflow * more keyboard fixing so that the actions in overflow get triggered * change overflow background with theme * change margin * udpate more button * use icon for ... * addressing comments * overflow css changes to match portal * arrow navigation working * handle tab and shift tab in overflow * keep arrow navigation within overflow * move reused code to helper methods * set roles for overflow * use actionsList instead of document.getElementById all the time * move collapsible action bar to its own class * renamve to overflowActionBar * fix focus rectangle around more element * hide overflow after an action is executed * hide overflow when clicking an action * hide overflow when focus leaves and loop focus within overflow when using arrow keys * fix double down arrow to move focus in overflow * update comment * fix clicking more not hiding overflow * add box-shadow for themes * fix hygiene error * fix hygiene error * widen focused outline for overflow actions
This commit is contained in:
@@ -27,18 +27,18 @@ const defaultOptions: IActionBarOptions = {
|
||||
*/
|
||||
export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
|
||||
private _options: IActionBarOptions;
|
||||
private _actionRunner: IActionRunner;
|
||||
private _context: any;
|
||||
protected _options: IActionBarOptions;
|
||||
protected _actionRunner: IActionRunner;
|
||||
protected _context: any;
|
||||
|
||||
// Items
|
||||
private _items: IActionViewItem[];
|
||||
private _focusedItem?: number;
|
||||
private _focusTracker: DOM.IFocusTracker;
|
||||
protected _items: IActionViewItem[];
|
||||
protected _focusedItem?: number;
|
||||
protected _focusTracker: DOM.IFocusTracker;
|
||||
|
||||
// Elements
|
||||
private _domNode: HTMLElement;
|
||||
private _actionsList: HTMLElement;
|
||||
protected _domNode: HTMLElement;
|
||||
protected _actionsList: HTMLElement;
|
||||
|
||||
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
|
||||
super();
|
||||
@@ -128,6 +128,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
this._actionsList = document.createElement('ul');
|
||||
this._actionsList.className = 'actions-container';
|
||||
this._actionsList.setAttribute('role', 'toolbar');
|
||||
this._actionsList.id = 'actions-container';
|
||||
if (this._options.ariaLabel) {
|
||||
this._actionsList.setAttribute('aria-label', this._options.ariaLabel);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
}
|
||||
}
|
||||
|
||||
private updateFocusedItem(): void {
|
||||
protected updateFocusedItem(): void {
|
||||
let actionIndex = 0;
|
||||
for (let i = 0; i < this._actionsList.children.length; i++) {
|
||||
let elem = this._actionsList.children[i];
|
||||
@@ -155,7 +156,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem.classList.contains('action-item')) {
|
||||
if (elem.classList.contains('action-item') && i !== this._actionsList.children.length - 1) {
|
||||
actionIndex++;
|
||||
}
|
||||
}
|
||||
@@ -268,7 +269,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
this.updateFocus();
|
||||
}
|
||||
|
||||
private focusNext(): void {
|
||||
protected focusNext(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._focusedItem = this._items.length - 1;
|
||||
}
|
||||
@@ -288,7 +289,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
this.updateFocus();
|
||||
}
|
||||
|
||||
private focusPrevious(): void {
|
||||
protected focusPrevious(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._focusedItem = 0;
|
||||
}
|
||||
@@ -313,7 +314,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
this.updateFocus();
|
||||
}
|
||||
|
||||
private updateFocus(): void {
|
||||
protected updateFocus(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._domNode.focus();
|
||||
return;
|
||||
@@ -329,7 +330,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
actionItem.focus();
|
||||
}
|
||||
} else {
|
||||
if (types.isFunction(actionItem.blur)) {
|
||||
if (actionItem && types.isFunction(actionItem.blur)) {
|
||||
actionItem.blur();
|
||||
}
|
||||
}
|
||||
@@ -349,7 +350,7 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
||||
}
|
||||
}
|
||||
|
||||
private cancel(): void {
|
||||
protected cancel(): void {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
(<HTMLElement>document.activeElement).blur(); // remove focus from focussed action
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .action-item.more {
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .action-label {
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0% 50%;
|
||||
@@ -86,3 +90,52 @@
|
||||
.carbon-taskbar .codicon {
|
||||
background-size: 11px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .overflow {
|
||||
position:absolute;
|
||||
right:0;
|
||||
display:none;
|
||||
z-index: 3;
|
||||
padding-left: 0;
|
||||
margin-top: 6px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.vs-dark .carbon-taskbar .overflow {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.hc-black .carbon-taskbar .overflow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.carbon-taskbar .overflow li {
|
||||
padding: 5px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.carbon-taskbar .overflow li.focused a.action-label {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.carbon-taskbar .overflow a {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .actions-container .action-item .action-label.moreActionsElement {
|
||||
height: 18px;
|
||||
margin-top: 3px;
|
||||
background-position: center;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .overflow .action-item .action-label{
|
||||
background-size: 16px;
|
||||
background-position: left;
|
||||
}
|
||||
|
||||
.overflow .taskbarSeparator {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
328
src/sql/base/browser/ui/taskbar/overflowActionbar.ts
Normal file
328
src/sql/base/browser/ui/taskbar/overflowActionbar.ts
Normal file
@@ -0,0 +1,328 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'sql/base/browser/ui/taskbar/overflowActionbarStyles';
|
||||
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import {
|
||||
IActionBarOptions, ActionsOrientation, IActionViewItem,
|
||||
IActionOptions
|
||||
} from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import * as nls from 'vs/nls';
|
||||
import { debounce } from 'vs/base/common/decorators';
|
||||
import { ActionBar } from 'sql/base/browser/ui/taskbar/actionbar';
|
||||
|
||||
const defaultOptions: IActionBarOptions = {
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
context: null
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends Actionbar so that it overflows when the window is resized to be smaller than the actionbar instead of wrapping
|
||||
*/
|
||||
export class OverflowActionBar extends ActionBar {
|
||||
// Elements
|
||||
private _overflow: HTMLElement;
|
||||
private _moreItemElement: HTMLElement;
|
||||
private _moreActionsElement: HTMLElement;
|
||||
|
||||
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
|
||||
super(container, options);
|
||||
|
||||
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => {
|
||||
if (this._actionsList) {
|
||||
this.resizeToolbar();
|
||||
}
|
||||
}));
|
||||
|
||||
this._overflow = document.createElement('ul');
|
||||
this._overflow.id = 'overflow';
|
||||
this._overflow.className = 'overflow';
|
||||
this._overflow.setAttribute('role', 'menu');
|
||||
this._domNode.appendChild(this._overflow);
|
||||
|
||||
this._register(DOM.addDisposableListener(this._overflow, DOM.EventType.FOCUS_OUT, e => {
|
||||
if (this._overflow && !DOM.isAncestor(e.relatedTarget as HTMLElement, this._overflow) && e.relatedTarget !== this._moreActionsElement) {
|
||||
this.hideOverflowDisplay();
|
||||
}
|
||||
}));
|
||||
this._actionsList.style.flexWrap = 'nowrap';
|
||||
|
||||
container.appendChild(this._domNode);
|
||||
}
|
||||
|
||||
@debounce(300)
|
||||
private resizeToolbar() {
|
||||
let width = this._actionsList.offsetWidth;
|
||||
let fullWidth = this._actionsList.scrollWidth;
|
||||
|
||||
// collapse actions that are beyond the width of the toolbar
|
||||
if (width < fullWidth) {
|
||||
// create '•••' more element if it doesn't exist yet
|
||||
if (!this._moreItemElement) {
|
||||
this.createMoreItemElement();
|
||||
}
|
||||
|
||||
this._moreItemElement.style.display = 'block';
|
||||
while (width < fullWidth) {
|
||||
let index = this._actionsList.childNodes.length - 2; // remove the last toolbar action before the more actions '...'
|
||||
if (index > -1) {
|
||||
this.collapseItem();
|
||||
fullWidth = this._actionsList.scrollWidth;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this._overflow?.hasChildNodes()) { // uncollapse actions if there is space for it
|
||||
while (width === fullWidth && this._overflow.hasChildNodes()) {
|
||||
// move placeholder in this._items
|
||||
let placeHolderItem = this._items.splice(this._actionsList.childNodes.length - 1, 1);
|
||||
this._items.splice(this._actionsList.childNodes.length, 0, placeHolderItem[0]);
|
||||
|
||||
let item = this._overflow.removeChild(this._overflow.firstChild);
|
||||
// change role back to button when it's in the toolbar
|
||||
if ((<HTMLElement>item).className !== 'taskbarSeparator') {
|
||||
(<HTMLElement>item.firstChild).setAttribute('role', 'button');
|
||||
}
|
||||
this._actionsList.insertBefore(item, this._actionsList.lastChild);
|
||||
|
||||
// if the action was too wide, collapse it again
|
||||
if (this._actionsList.scrollWidth > this._actionsList.offsetWidth) {
|
||||
// move placeholder in this._items
|
||||
this.collapseItem();
|
||||
break;
|
||||
} else if (!this._overflow.hasChildNodes()) {
|
||||
this._moreItemElement.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private collapseItem(): void {
|
||||
// move placeholder in this._items
|
||||
let placeHolderItem = this._items.splice(this._actionsList.childNodes.length - 1, 1);
|
||||
this._items.splice(this._actionsList.childNodes.length - 2, 0, placeHolderItem[0]);
|
||||
|
||||
let index = this._actionsList.childNodes.length - 2; // remove the last toolbar action before the more actions '...'
|
||||
let item = this._actionsList.removeChild(this._actionsList.childNodes[index]);
|
||||
this._overflow.insertBefore(item, this._overflow.firstChild);
|
||||
this._register(DOM.addDisposableListener(item, DOM.EventType.CLICK, (e => { this.hideOverflowDisplay(); })));
|
||||
|
||||
// change role to menuItem when it's in the overflow
|
||||
if ((<HTMLElement>this._overflow.firstChild).className !== 'taskbarSeparator') {
|
||||
(<HTMLElement>this._overflow.firstChild.firstChild).setAttribute('role', 'menuItem');
|
||||
}
|
||||
}
|
||||
|
||||
private createMoreItemElement(): void {
|
||||
this._moreItemElement = document.createElement('li');
|
||||
this._moreItemElement.className = 'action-item more';
|
||||
this._moreItemElement.setAttribute('role', 'presentation');
|
||||
this._moreActionsElement = document.createElement('a');
|
||||
this._moreActionsElement.className = 'moreActionsElement action-label codicon toggle-more';
|
||||
this._moreActionsElement.setAttribute('role', 'button');
|
||||
this._moreActionsElement.title = nls.localize('toggleMore', "Toggle More");
|
||||
this._moreActionsElement.tabIndex = 0;
|
||||
this._moreActionsElement.setAttribute('aria-haspopup', 'true');
|
||||
this._register(DOM.addDisposableListener(this._moreActionsElement, DOM.EventType.CLICK, (e => {
|
||||
this.moreElementOnClick(e);
|
||||
})));
|
||||
this._register(DOM.addDisposableListener(this._moreActionsElement, DOM.EventType.KEY_UP, (ev => {
|
||||
let event = new StandardKeyboardEvent(ev);
|
||||
if (event.keyCode === KeyCode.Enter || event.keyCode === KeyCode.Space) {
|
||||
this.moreElementOnClick(event);
|
||||
}
|
||||
})));
|
||||
|
||||
this._register(DOM.addDisposableListener(this._overflow, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
|
||||
// Close overflow if Escape is pressed
|
||||
if (event.equals(KeyCode.Escape)) {
|
||||
this.hideOverflowDisplay();
|
||||
this._moreActionsElement.focus();
|
||||
} else if (event.equals(KeyCode.UpArrow)) {
|
||||
// up arrow on first element in overflow should move focus to the bottom of the overflow
|
||||
if (this._focusedItem === this._actionsList.childElementCount) {
|
||||
this._focusedItem = this._actionsList.childElementCount + this._overflow.childElementCount - 2;
|
||||
this.updateFocus();
|
||||
} else {
|
||||
this.focusPrevious();
|
||||
}
|
||||
} else if (event.equals(KeyCode.DownArrow)) {
|
||||
// down arrow on last element should move focus to the first element of the overflow
|
||||
if (this._focusedItem === this._actionsList.childNodes.length + this._overflow.childNodes.length - 2) {
|
||||
this._focusedItem = this._actionsList.childElementCount;
|
||||
this.updateFocus();
|
||||
} else {
|
||||
this.focusNext();
|
||||
}
|
||||
} else if (event.equals(KeyMod.Shift | KeyCode.Tab)) {
|
||||
this.hideOverflowDisplay();
|
||||
this._focusedItem = this._actionsList.childElementCount - 1;
|
||||
this.updateFocus();
|
||||
} else if (event.equals(KeyCode.Tab)) {
|
||||
this.hideOverflowDisplay();
|
||||
}
|
||||
DOM.EventHelper.stop(event, true);
|
||||
}));
|
||||
|
||||
this._moreItemElement.appendChild(this._moreActionsElement);
|
||||
this._actionsList.appendChild(this._moreItemElement);
|
||||
this._items.push(undefined); // add place holder for more item element
|
||||
}
|
||||
|
||||
private moreElementOnClick(event: MouseEvent | StandardKeyboardEvent): void {
|
||||
this._overflow.style.display = this._overflow.style.display === 'block' ? 'none' : 'block';
|
||||
if (this._overflow.style.display === 'block') {
|
||||
this._focusedItem = this._actionsList.childElementCount;
|
||||
this.updateFocus();
|
||||
}
|
||||
DOM.EventHelper.stop(event, true);
|
||||
}
|
||||
|
||||
private hideOverflowDisplay(): void {
|
||||
this._overflow.style.display = 'none';
|
||||
this._focusedItem = this._actionsList.childElementCount - 1;
|
||||
}
|
||||
|
||||
protected updateFocusedItem(): void {
|
||||
let actionIndex = 0;
|
||||
for (let i = 0; i < this._actionsList.children.length; i++) {
|
||||
let elem = this._actionsList.children[i];
|
||||
|
||||
if (DOM.isAncestor(document.activeElement, elem)) {
|
||||
this._focusedItem = actionIndex;
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem.classList.contains('action-item') && i !== this._actionsList.children.length - 1) {
|
||||
actionIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// move focus to overflow items if there are any
|
||||
if (this._overflow) {
|
||||
for (let i = 0; i < this._overflow.children.length; i++) {
|
||||
let elem = this._overflow.children[i];
|
||||
|
||||
if (DOM.isAncestor(document.activeElement, elem)) {
|
||||
this._focusedItem = actionIndex;
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem.classList.contains('action-item')) {
|
||||
actionIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push an HTML Element onto the action bar UI in the position specified by options.
|
||||
* Pushes to the last position if no options are provided.
|
||||
*/
|
||||
public pushElement(element: HTMLElement, options: IActionOptions = {}): void {
|
||||
super.pushElement(element, options);
|
||||
this.resizeToolbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Push an action onto the action bar UI in the position specified by options.
|
||||
* Pushes to the last position if no options are provided.
|
||||
*/
|
||||
public pushAction(arg: IAction | IAction[], options: IActionOptions = {}): void {
|
||||
super.pushAction(arg, options);
|
||||
this.resizeToolbar();
|
||||
}
|
||||
|
||||
protected focusNext(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._focusedItem = this._items.length - 1;
|
||||
}
|
||||
|
||||
let startIndex = this._focusedItem;
|
||||
let item: IActionViewItem;
|
||||
|
||||
do {
|
||||
this._focusedItem = (this._focusedItem + 1) % this._items.length;
|
||||
item = this._items[this._focusedItem];
|
||||
} while (this._focusedItem !== startIndex && item && !item.isEnabled());
|
||||
|
||||
if (this._focusedItem === startIndex && item && !item.isEnabled()) {
|
||||
this._focusedItem = undefined;
|
||||
}
|
||||
|
||||
this.updateFocus();
|
||||
}
|
||||
|
||||
protected focusPrevious(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._focusedItem = 0;
|
||||
}
|
||||
|
||||
let startIndex = this._focusedItem;
|
||||
let item: IActionViewItem;
|
||||
|
||||
do {
|
||||
this._focusedItem = this._focusedItem - 1;
|
||||
|
||||
if (this._focusedItem < 0) {
|
||||
this._focusedItem = this._items.length - 1;
|
||||
}
|
||||
|
||||
item = this._items[this._focusedItem];
|
||||
} while (this._focusedItem !== startIndex && item && !item.isEnabled());
|
||||
|
||||
if (this._focusedItem === startIndex && item && !item.isEnabled()) {
|
||||
this._focusedItem = undefined;
|
||||
}
|
||||
|
||||
this.updateFocus();
|
||||
}
|
||||
|
||||
protected updateFocus(): void {
|
||||
if (typeof this._focusedItem === 'undefined') {
|
||||
this._domNode.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
let item = this._items[i];
|
||||
|
||||
let actionItem = <any>item;
|
||||
|
||||
if (i === this._focusedItem) {
|
||||
// placeholder for location of moreActionsElement
|
||||
if (!actionItem) {
|
||||
this._moreActionsElement.focus();
|
||||
}
|
||||
else if (types.isFunction(actionItem.focus)) {
|
||||
actionItem.focus();
|
||||
}
|
||||
} else {
|
||||
if (actionItem && types.isFunction(actionItem.blur)) {
|
||||
actionItem.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected cancel(): void {
|
||||
super.cancel();
|
||||
|
||||
if (this._overflow) {
|
||||
this.hideOverflowDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
public run(action: IAction, context?: any): Promise<any> {
|
||||
this.hideOverflowDisplay();
|
||||
return this._actionRunner.run(action, context);
|
||||
}
|
||||
}
|
||||
43
src/sql/base/browser/ui/taskbar/overflowActionbarStyles.ts
Normal file
43
src/sql/base/browser/ui/taskbar/overflowActionbarStyles.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// eslint-disable-next-line code-import-patterns
|
||||
import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
// eslint-disable-next-line code-import-patterns
|
||||
import { EDITOR_PANE_BACKGROUND, DASHBOARD_BORDER, TOOLBAR_OVERFLOW_SHADOW } from 'vs/workbench/common/theme';
|
||||
// eslint-disable-next-line code-import-patterns
|
||||
import { focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
|
||||
const overflowBackground = theme.getColor(EDITOR_PANE_BACKGROUND);
|
||||
if (overflowBackground) {
|
||||
collector.addRule(`.carbon-taskbar .overflow {
|
||||
background-color: ${overflowBackground};
|
||||
}`);
|
||||
}
|
||||
|
||||
const overflowShadow = theme.getColor(TOOLBAR_OVERFLOW_SHADOW);
|
||||
if (overflowShadow) {
|
||||
collector.addRule(`.carbon-taskbar .overflow {
|
||||
box-shadow: 0px 4px 4px ${overflowShadow};
|
||||
}`);
|
||||
}
|
||||
|
||||
const border = theme.getColor(DASHBOARD_BORDER);
|
||||
if (border) {
|
||||
collector.addRule(`.carbon-taskbar .overflow {
|
||||
border: 1px solid ${border};
|
||||
}`);
|
||||
}
|
||||
|
||||
const activeOutline = theme.getColor(focusBorder);
|
||||
if (activeOutline) {
|
||||
collector.addRule(`.carbon-taskbar .overflow li.focused {
|
||||
outline: 1px solid;
|
||||
outline-offset: -3px;
|
||||
outline-color: ${activeOutline}
|
||||
}`);
|
||||
}
|
||||
});
|
||||
@@ -11,6 +11,7 @@ import { ActionBar } from './actionbar';
|
||||
import { IActionRunner, IAction } from 'vs/base/common/actions';
|
||||
import { ActionsOrientation, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IToolBarOptions } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
import { OverflowActionBar } from 'sql/base/browser/ui/taskbar/overflowActionbar';
|
||||
|
||||
/**
|
||||
* A wrapper for the different types of content a QueryTaskbar can display
|
||||
@@ -33,20 +34,36 @@ export class Taskbar {
|
||||
private options: IToolBarOptions;
|
||||
private actionBar: ActionBar;
|
||||
|
||||
constructor(container: HTMLElement, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) {
|
||||
constructor(container: HTMLElement, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }, collapseOverflow: boolean = false) {
|
||||
this.options = options;
|
||||
|
||||
let element = document.createElement('div');
|
||||
element.className = 'monaco-toolbar carbon-taskbar';
|
||||
container.appendChild(element);
|
||||
|
||||
this.actionBar = new ActionBar(element, {
|
||||
orientation: options.orientation,
|
||||
ariaLabel: options.ariaLabel,
|
||||
actionViewItemProvider: (action: IAction): IActionViewItem | undefined => {
|
||||
return options.actionViewItemProvider ? options.actionViewItemProvider(action) : undefined;
|
||||
}
|
||||
});
|
||||
if (collapseOverflow) {
|
||||
this.actionBar = new OverflowActionBar(
|
||||
element,
|
||||
{
|
||||
orientation: options.orientation,
|
||||
ariaLabel: options.ariaLabel,
|
||||
actionViewItemProvider: (action: IAction): IActionViewItem | undefined => {
|
||||
return options.actionViewItemProvider ? options.actionViewItemProvider(action) : undefined;
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.actionBar = new ActionBar(
|
||||
element,
|
||||
{
|
||||
orientation: options.orientation,
|
||||
ariaLabel: options.ariaLabel,
|
||||
actionViewItemProvider: (action: IAction): IActionViewItem | undefined => {
|
||||
return options.actionViewItemProvider ? options.actionViewItemProvider(action) : undefined;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user