Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor styling of toggle, dialog, inputbox & checkbox #166542

Merged
merged 3 commits into from Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/vs/base/browser/ui/actionbar/actionViewItems.ts
Expand Up @@ -12,6 +12,7 @@ import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview
import { IHoverDelegate } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
import { ICustomHover, setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { ISelectBoxOptions, ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { IToggleStyles } from 'vs/base/browser/ui/toggle/toggle';
import { Action, ActionRunner, IAction, IActionChangeEvent, IActionRunner, Separator } from 'vs/base/common/actions';
import { Disposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
Expand Down Expand Up @@ -261,6 +262,7 @@ export interface IActionViewItemOptions extends IBaseActionViewItemOptions {
icon?: boolean;
label?: boolean;
keybinding?: string | null;
toggleStyles?: IToggleStyles;
}

export class ActionViewItem extends BaseActionViewItem {
Expand All @@ -270,7 +272,7 @@ export class ActionViewItem extends BaseActionViewItem {

private cssClass?: string;

constructor(context: unknown, action: IAction, options: IActionViewItemOptions = {}) {
constructor(context: unknown, action: IAction, options: IActionViewItemOptions) {
super(context, action, options);

this.options = options;
Expand Down
117 changes: 53 additions & 64 deletions src/vs/base/browser/ui/dialog/dialog.ts
Expand Up @@ -8,10 +8,9 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { ButtonBar, ButtonWithDescription, IButtonStyles } from 'vs/base/browser/ui/button/button';
import { ICheckboxStyles, Checkbox } from 'vs/base/browser/ui/toggle/toggle';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { IInputBoxStyles, InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Action } from 'vs/base/common/actions';
import { Codicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { Disposable } from 'vs/base/common/lifecycle';
Expand Down Expand Up @@ -39,6 +38,9 @@ export interface IDialogOptions {
readonly disableCloseAction?: boolean;
readonly disableDefaultAction?: boolean;
readonly buttonStyles: IButtonStyles;
readonly checkboxStyles: ICheckboxStyles;
readonly inputBoxStyles: IInputBoxStyles;
readonly dialogStyles: IDialogStyles;
}

export interface IDialogResult {
Expand All @@ -47,19 +49,15 @@ export interface IDialogResult {
readonly values?: string[];
}

export interface IDialogStyles extends ICheckboxStyles {
readonly dialogForeground?: Color;
readonly dialogBackground?: Color;
readonly dialogShadow?: Color;
readonly dialogBorder?: Color;
readonly errorIconForeground?: Color;
readonly warningIconForeground?: Color;
readonly infoIconForeground?: Color;
readonly inputBackground?: Color;
readonly inputForeground?: Color;
readonly inputBorder?: Color;
readonly textLinkForeground?: Color;

export interface IDialogStyles {
readonly dialogForeground: string | undefined;
readonly dialogBackground: string | undefined;
readonly dialogShadow: string | undefined;
readonly dialogBorder: string | undefined;
readonly errorIconForeground: string | undefined;
readonly warningIconForeground: string | undefined;
readonly infoIconForeground: string | undefined;
readonly textLinkForeground: string | undefined;
}

interface ButtonMapEntry {
Expand All @@ -78,7 +76,6 @@ export class Dialog extends Disposable {
private readonly checkbox: Checkbox | undefined;
private readonly toolbarContainer: HTMLElement;
private buttonBar: ButtonBar | undefined;
private styles: IDialogStyles | undefined;
private focusToReturn: HTMLElement | undefined;
private readonly inputs: InputBox[];
private readonly buttons: string[];
Expand Down Expand Up @@ -140,6 +137,7 @@ export class Dialog extends Disposable {
const inputBox = this._register(new InputBox(inputRowElement, undefined, {
placeholder: input.placeholder,
type: input.type ?? 'text',
inputBoxStyles: options.inputBoxStyles
}));

if (input.value) {
Expand All @@ -155,7 +153,9 @@ export class Dialog extends Disposable {
if (this.options.checkboxLabel) {
const checkboxRowElement = this.messageContainer.appendChild($('.dialog-checkbox-row'));

const checkbox = this.checkbox = this._register(new Checkbox(this.options.checkboxLabel, !!this.options.checkboxChecked));
const checkbox = this.checkbox = this._register(
new Checkbox(this.options.checkboxLabel, !!this.options.checkboxChecked, options.checkboxStyles)
);

checkboxRowElement.appendChild(checkbox.domNode);

Expand All @@ -166,6 +166,8 @@ export class Dialog extends Disposable {

const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row'));
this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar'));

this.applyStyles();
}

private getIconAriaLabel(): string {
Expand Down Expand Up @@ -391,7 +393,7 @@ export class Dialog extends Disposable {
});
}));

actionBar.push(action, { icon: true, label: false, });
actionBar.push(action, { icon: true, label: false });
}

this.applyStyles();
Expand All @@ -416,60 +418,47 @@ export class Dialog extends Disposable {
}

private applyStyles() {
if (this.styles) {
const style = this.styles;

const fgColor = style.dialogForeground;
const bgColor = style.dialogBackground;
const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : '';
const border = style.dialogBorder ? `1px solid ${style.dialogBorder}` : '';
const linkFgColor = style.textLinkForeground;

this.shadowElement.style.boxShadow = shadowColor;

this.element.style.color = fgColor?.toString() ?? '';
this.element.style.backgroundColor = bgColor?.toString() ?? '';
this.element.style.border = border;
const style = this.options.dialogStyles;

this.checkbox?.style(style);
const fgColor = style.dialogForeground;
const bgColor = style.dialogBackground;
const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : '';
const border = style.dialogBorder ? `1px solid ${style.dialogBorder}` : '';
const linkFgColor = style.textLinkForeground;

if (fgColor && bgColor) {
const messageDetailColor = fgColor.transparent(.9);
this.messageDetailElement.style.color = messageDetailColor.makeOpaque(bgColor).toString();
}
this.shadowElement.style.boxShadow = shadowColor;

if (linkFgColor) {
for (const el of this.messageContainer.getElementsByTagName('a')) {
el.style.color = linkFgColor.toString();
}
}
this.element.style.color = fgColor?.toString() ?? '';
this.element.style.backgroundColor = bgColor?.toString() ?? '';
this.element.style.border = border;

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();
}
// TODO fix
// if (fgColor && bgColor) {
// const messageDetailColor = fgColor.transparent(.9);
// this.messageDetailElement.style.mixBlendMode = messageDetailColor.makeOpaque(bgColor).toString();
// }

for (const input of this.inputs) {
input.style(style);
if (linkFgColor) {
for (const el of this.messageContainer.getElementsByTagName('a')) {
el.style.color = linkFgColor;
}
}
}

style(style: IDialogStyles): void {
this.styles = style;

this.applyStyles();
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;
}
}

override dispose(): void {
Expand Down