diff --git a/src/sql/base/browser/ui/colorbox/colorbox.ts b/src/sql/base/browser/ui/colorbox/colorbox.ts new file mode 100644 index 0000000000..4dba8603f0 --- /dev/null +++ b/src/sql/base/browser/ui/colorbox/colorbox.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- + * 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!./media/colorbox'; + +import { Color } from 'vs/base/common/color'; +import { Event, Emitter } from 'vs/base/common/event'; +import { Widget } from 'vs/base/browser/ui/widget'; + +export interface ColorboxOptions { + name: string; + class?: string[]; + label?: string; +} + +export interface ColorboxStyle { + backgroundColor?: Color; +} + +export class Colorbox extends Widget { + readonly domNode: HTMLInputElement; + private backgroundColor?: Color; + + private _onSelect = new Emitter(); + public readonly onSelect: Event = this._onSelect.event; + + private _checked: boolean; + + constructor(container: HTMLElement, opts: ColorboxOptions) { + super(); + + this.domNode = document.createElement('input'); + this.domNode.type = 'radio'; + this.domNode.name = opts.name; + this._checked = false; + + this.domNode.classList.add('colorbox'); + if (opts.class) { + this.domNode.classList.add(...opts.class); + } + if (opts.label) { + this.domNode.setAttribute('aria-label', opts.label); + } + + container.appendChild(this.domNode); + + this.onfocus(this.domNode, () => { + this._onSelect.fire(); + }); + + } + + public style(styles: ColorboxStyle): void { + if (styles.backgroundColor) { + this.backgroundColor = styles.backgroundColor; + } + this.updateStyle(); + } + + private updateStyle(): void { + this.domNode.style.background = this.backgroundColor ? this.backgroundColor.toString() : this.domNode.style.background; + } + + public get checked(): boolean { + return this._checked; + } + + public set checked(checked: boolean) { + this._checked = checked; + if (this._checked) { + this.domNode.classList.add('checked'); + } else { + this.domNode.classList.remove('checked'); + } + } + + public focus() { + this.domNode.focus(); + } +} diff --git a/src/sql/base/browser/ui/colorbox/media/colorbox.css b/src/sql/base/browser/ui/colorbox/media/colorbox.css new file mode 100644 index 0000000000..109072b00b --- /dev/null +++ b/src/sql/base/browser/ui/colorbox/media/colorbox.css @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.colorbox { + cursor: pointer; + -webkit-appearance: none; + opacity: 0.3; +} + +.colorbox.checked { + opacity: 1; + outline: none; +} diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts b/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts index b3f94f9e7c..4cbf055a7f 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/serverGroupDialog'; -import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; +import { Colorbox } from 'sql/base/browser/ui/colorbox/colorbox'; import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import * as DOM from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -27,12 +27,13 @@ import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { Color } from 'vs/base/common/color'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class ServerGroupDialog extends Modal { private _addServerButton: Button; private _closeButton: Button; - private _colorCheckBoxesMap: Array<{ color: string, checkbox: Checkbox }> = []; + private _colorColorBoxesMap: Array<{ color: string, colorbox: Colorbox }> = []; private _selectedColorOption: number; private _groupNameInputBox: InputBox; private _groupDescriptionInputBox: InputBox; @@ -127,8 +128,8 @@ export class ServerGroupDialog extends Modal { private isFocusOnColors(): boolean { let result = false; - this._colorCheckBoxesMap.forEach(({ checkbox }) => { - if (document.activeElement === checkbox.domNode) { + this._colorColorBoxesMap.forEach(({ colorbox: colorbox }) => { + if (document.activeElement === colorbox.domNode) { result = true; } }); @@ -140,7 +141,7 @@ export class ServerGroupDialog extends Modal { if (this._groupNameInputBox.hasFocus()) { this._groupDescriptionInputBox.focus(); } else if (this._groupDescriptionInputBox.hasFocus()) { - this._colorCheckBoxesMap[this._selectedColorOption].checkbox.focus(); + this._colorColorBoxesMap[this._selectedColorOption].colorbox.focus(); } else if (this.isFocusOnColors()) { this._addServerButton.enabled ? this._addServerButton.focus() : this._closeButton.focus(); } else if (document.activeElement === this._addServerButton.element) { @@ -153,9 +154,9 @@ export class ServerGroupDialog extends Modal { private focusPrevious(): void { if (document.activeElement === this._closeButton.element) { - this._addServerButton.enabled ? this._addServerButton.focus() : this._colorCheckBoxesMap[this._selectedColorOption].checkbox.focus(); + this._addServerButton.enabled ? this._addServerButton.focus() : this._colorColorBoxesMap[this._selectedColorOption].colorbox.focus(); } else if (document.activeElement === this._addServerButton.element) { - this._colorCheckBoxesMap[this._selectedColorOption].checkbox.focus(); + this._colorColorBoxesMap[this._selectedColorOption].colorbox.focus(); } else if (this.isFocusOnColors()) { this._groupDescriptionInputBox.focus(); } else if (this._groupDescriptionInputBox.hasFocus()) { @@ -167,8 +168,8 @@ export class ServerGroupDialog extends Modal { private focusNextColor(moveRight: boolean): void { let focusIndex: number = -1; - for (let i = 0; i < this._colorCheckBoxesMap.length; i++) { - if (document.activeElement === this._colorCheckBoxesMap[i].checkbox.domNode) { + for (let i = 0; i < this._colorColorBoxesMap.length; i++) { + if (document.activeElement === this._colorColorBoxesMap[i].colorbox.domNode) { focusIndex = i; break; } @@ -184,12 +185,12 @@ export class ServerGroupDialog extends Modal { // check for wraps if (focusIndex < 0) { - focusIndex = this._colorCheckBoxesMap.length - 1; - } else if (focusIndex >= this._colorCheckBoxesMap.length) { + focusIndex = this._colorColorBoxesMap.length - 1; + } else if (focusIndex >= this._colorColorBoxesMap.length) { focusIndex = 0; } - this._colorCheckBoxesMap[focusIndex].checkbox.focus(); + this._colorColorBoxesMap[focusIndex].colorbox.focus(); } } @@ -221,22 +222,24 @@ export class ServerGroupDialog extends Modal { for (let i = 0; i < this._viewModel.colors.length; i++) { const color = this._viewModel.colors[i]; - const colorCheckBox = new Checkbox({ - actionClassName: 'server-group-color', - title: color, - isChecked: false + const colorColorBox = new Colorbox(container, { + name: 'server-group-color', + class: ['server-group-color'], + label: `Colobox Color: ${color}`, }); - this._register(colorCheckBox.onChange((viaKeyboard) => { + + this._register(colorColorBox.onSelect((viaKeyboard) => { this.onSelectGroupColor(color); })); - colorCheckBox.domNode.style.backgroundColor = color; - container.appendChild(colorCheckBox.domNode); + colorColorBox.style({ + backgroundColor: Color.fromHex(color) + }); // Theme styler - this._register(attachCheckboxStyler(colorCheckBox, this._themeService)); + this._register(attachCheckboxStyler(colorColorBox, this._themeService)); - // add the new checkbox to the color map - this._colorCheckBoxesMap[i] = { color, checkbox: colorCheckBox }; + // add the new colorbox to the color map + this._colorColorBoxesMap[i] = { color, colorbox: colorColorBox }; } } @@ -259,7 +262,7 @@ export class ServerGroupDialog extends Modal { } public get selectedColor(): string { - return this._colorCheckBoxesMap[this._selectedColorOption].color; + return this._colorColorBoxesMap[this._selectedColorOption].color; } public get viewModel(): ServerGroupViewModel { @@ -309,13 +312,13 @@ export class ServerGroupDialog extends Modal { // update UI elements that have derivative behaviors based on other state changes private updateView(): void { // check the color buttons and if their checked state does not match the view model state then correct it - for (let i = 0; i < this._colorCheckBoxesMap.length; i++) { - let { checkbox, color } = this._colorCheckBoxesMap[i]; - if ((this._viewModel.groupColor === color) && (checkbox.checked === false)) { - checkbox.checked = true; + for (let i = 0; i < this._colorColorBoxesMap.length; i++) { + let { colorbox: colorbox, color } = this._colorColorBoxesMap[i]; + if ((this._viewModel.groupColor === color) && (colorbox.checked === false)) { + colorbox.checked = true; this._selectedColorOption = i; - } else if ((this._viewModel.groupColor !== color) && (checkbox.checked === true)) { - checkbox.checked = false; + } else if ((this._viewModel.groupColor !== color) && (colorbox.checked === true)) { + colorbox.checked = false; } }