Adds a new colorbox element (#6549)

* Colorbox

* Finish colorbox work

* Change references to colorbox

* Typo

* Delete console.log

* Remove unnecessary code

* Remove css variables, define color in ts.

* Accessibility labels
This commit is contained in:
Amir Omidi
2019-08-01 15:43:33 -07:00
committed by GitHub
parent 3a3c0ce1d7
commit c4ab7f64e6
3 changed files with 128 additions and 29 deletions

View File

@@ -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<void>();
public readonly onSelect: Event<void> = 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();
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}