Connection error box style fix (#14469)

* Modified modal styles, limiting height of basic modal to 480px.

* wip - added new attachCalloutDialogStyler. Moved callout-specific styler code out of modal.ts

* Moved attach styler code to workbench/common. Added custom styles to imageCalloutDialog

* Moved styler code into calloutDialog. Added callout-specific theme colors to colorRegistry. Removed color styles from modal and callout stylesheets.

* Added CalloutDialogModal that extends CalloutDialog so that the callout can be instantiated from core. Revised calloutDialog so the position cn be passed in from where it is instantiated.

* Revised refactor of modal and image/link callouts so that callout dialog invoked by core can also use the styler. Removed unused properties from dialog code.

* Added conditional to dialogModal to use correct styler for callouts.

* Cleaned up styles. Modified custom colors.

* Wrapped call to positionCalloutDialog in conditional.

* Style, colors, styler and modal updates to align callout with latest OPAC toolkit styles.

* Moved calloutDialog stylesheet

* Consolidated styler code and added a flexible custom styler to provide values for dialogModal

* Added image callout code.

* Remove image callout dialog until wired fully

* Test fixes

Co-authored-by: chlafreniere <hichise@gmail.com>
This commit is contained in:
Hale Rankin
2021-03-05 17:34:02 -08:00
committed by GitHub
parent 0ef99ab42a
commit 972b649beb
11 changed files with 235 additions and 166 deletions

View File

@@ -77,3 +77,11 @@ export const infoButtonForeground = registerColor('infoButton.foreground', { dar
export const infoButtonBackground = registerColor('infoButton.background', { dark: '#1B1A19', light: '#FFFFFF', hc: '#000000' }, nls.localize('infoButton.background', "Info button background color.")); export const infoButtonBackground = registerColor('infoButton.background', { dark: '#1B1A19', light: '#FFFFFF', hc: '#000000' }, nls.localize('infoButton.background', "Info button background color."));
export const infoButtonBorder = registerColor('infoButton.border', { dark: '#1B1A19', light: '#FFFFFF', hc: contrastBorder }, nls.localize('infoButton.border', "Info button border color.")); export const infoButtonBorder = registerColor('infoButton.border', { dark: '#1B1A19', light: '#FFFFFF', hc: contrastBorder }, nls.localize('infoButton.border', "Info button border color."));
export const infoButtonHoverBackground = registerColor('infoButton.hoverBackground', { dark: '#282625', light: '#F3F2F1', hc: '#000000' }, nls.localize('infoButton.hoverBackground', "Info button hover background color.")); export const infoButtonHoverBackground = registerColor('infoButton.hoverBackground', { dark: '#282625', light: '#F3F2F1', hc: '#000000' }, nls.localize('infoButton.hoverBackground', "Info button hover background color."));
// Callout Dialog
export const calloutDialogForeground = registerColor('calloutDialog.foreground', { light: '#616161', dark: '#CCCCCC', hc: '#FFFFFF' }, nls.localize('calloutDialogForeground', 'Callout dialog foreground.'));
export const calloutDialogInteriorBorder = registerColor('calloutDialog.interiorBorder', { light: '#D6D6D6', dark: '#323130', hc: '#2B56F2' }, nls.localize('calloutDialogInteriorBorder', "Callout dialog interior borders used for separating elements."));
export const calloutDialogExteriorBorder = registerColor('calloutDialog.exteriorBorder', { light: '#CCCCCC', dark: '#CCCCCC', hc: '#2B56F2' }, nls.localize('calloutDialogExteriorBorder', "Callout dialog exterior borders to provide contrast against notebook UI."));
export const calloutDialogHeaderFooterBackground = registerColor('calloutDialog.headerFooterBackground', { light: '#FFFFFF', dark: '#1E1E1E', hc: Color.black }, nls.localize('calloutDialogHeaderFooterBackground', 'Callout dialog header and footer background.'));
export const calloutDialogBodyBackground = registerColor('calloutDialog.bodyBackground', { light: '#FFFFFF', dark: '#1E1E1E', hc: Color.black }, nls.localize('calloutDialogBodyBackground', "Callout dialog body background."));
export const calloutDialogShadowColor = registerColor('calloutDialog.shadow', { light: '#000000', dark: '#FFFFFF', hc: '#000000' }, nls.localize('calloutDialogShadowColor', 'Callout dialog box shadow color.'));

View File

@@ -8,7 +8,8 @@
} }
.modal.callout-dialog .modal-dialog { .modal.callout-dialog .modal-dialog {
border-radius: 2px; border-radius: 2px;
box-shadow: 0px 3px 8px rgba(var(--foreground)); border-width: 1px;
border-style: solid;
max-height: 300px; max-height: 300px;
position: absolute; position: absolute;
} }
@@ -28,60 +29,37 @@
} }
.callout-arrow:before { .callout-arrow:before {
border-width: 1px;
border-style: solid; border-style: solid;
border-color: border-width: 1px;
transparent
transparent
var(--bodybackground)
var(--bodybackground);
box-shadow: -3px 3px 3px 0 rgba(var(--foreground));
content: ''; content: '';
display: block; display: block;
height: 0; height: 10px;
position: absolute; position: absolute;
width: 0; width: 10px;
} }
.callout-arrow.from-below:before { .callout-arrow.from-below:before {
border-width: 0.5em; left: 24px;
left: 2em; top: -6px;
top: -0.2em;
transform: rotate(135deg); transform: rotate(135deg);
} }
.callout-arrow.from-above:before { .callout-arrow.from-above:before {
border-width: 0.5em; bottom: -6px;
left: 2em; left: 24px;
bottom: -0.2em;
transform: rotate(-45deg); transform: rotate(-45deg);
} }
.callout-arrow.from-left:before { .callout-arrow.from-left:before {
background-color: var(--bodybackground);
height: 26px; height: 26px;
right: -13px; right: -14px;
top: 26px; top: 26px;
transform: rotate(-135deg); transform: rotate(-135deg);
width: 26px; width: 26px;
} }
.hc-black .callout-arrow:before { .hc-black .callout-arrow:before {
background-color: var(--bodybackground);
border-color:
transparent
transparent
var(--border)
var(--border);
border-width: 0.1em;
box-shadow: none; box-shadow: none;
height: 0.8em;
width: 0.8em;
}
.hc-black .callout-arrow.from-below:before {
top: -0.4em;
} }
.hc-black .callout-arrow.from-left:before { .hc-black .callout-arrow.from-left:before {
height: 2em; box-shadow: none;
right: -1.2em;
width: 2em;
} }
.modal.callout-dialog .modal-header { .modal.callout-dialog .modal-header {

View File

@@ -21,17 +21,13 @@
.modal:not(.flyout-dialog):not(.callout-dialog) .modal-dialog { .modal:not(.flyout-dialog):not(.callout-dialog) .modal-dialog {
margin: auto; margin: auto;
width: 640px; width: 640px;
height: 480px; max-height: 480px;
} }
.modal .modal-header { .modal .modal-header {
padding: 15px; padding: 15px;
} }
.modal .modal-footer {
padding: 15px;
}
.modal .codicon.in-progress { .modal .codicon.in-progress {
width: 25px; width: 25px;
height: 25px; height: 25px;
@@ -129,8 +125,8 @@
} }
.modal .modal-footer { .modal .modal-footer {
border-top: 1px solid #E1E1E1;
display: flex; display: flex;
padding: 15px;
} }
.modal .modal-footer .left-footer { .modal .modal-footer .left-footer {

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/modal'; import 'vs/css!./media/modal';
import 'vs/css!./media/calloutDialog';
import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { Color } from 'vs/base/common/color'; import { Color } from 'vs/base/common/color';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
@@ -13,7 +14,6 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { Button } from 'sql/base/browser/ui/button/button'; import { Button } from 'sql/base/browser/ui/button/button';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -27,9 +27,6 @@ import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { alert } from 'vs/base/browser/ui/aria/aria'; import { alert } from 'vs/base/browser/ui/aria/aria';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { editorWidgetForeground, editorBackground } from 'vs/platform/theme/common/colorRegistry';
import { notebookToolbarLines } from 'sql/platform/theme/common/colorRegistry';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
export enum MessageLevel { export enum MessageLevel {
Error = 0, Error = 0,
@@ -55,7 +52,9 @@ export interface IModalDialogStyles {
footerBackgroundColor?: Color; footerBackgroundColor?: Color;
footerBorderTopWidth?: Color; footerBorderTopWidth?: Color;
footerBorderTopStyle?: Color; footerBorderTopStyle?: Color;
footerBorderTopColor?: Color; dialogInteriorBorder?: Color;
dialogExteriorBorder?: Color;
dialogShadowColor?: Color;
} }
export type DialogWidth = 'narrow' | 'medium' | 'wide' | number | string; export type DialogWidth = 'narrow' | 'medium' | 'wide' | number | string;
@@ -72,8 +71,6 @@ export interface IDialogProperties {
export interface IModalOptions { export interface IModalOptions {
dialogStyle?: DialogStyle; dialogStyle?: DialogStyle;
dialogPosition?: DialogPosition; dialogPosition?: DialogPosition;
positionX?: number;
positionY?: number;
width?: DialogWidth; width?: DialogWidth;
isAngular?: boolean; isAngular?: boolean;
hasBackButton?: boolean; hasBackButton?: boolean;
@@ -89,8 +86,6 @@ export interface IModalOptions {
const defaultOptions: IModalOptions = { const defaultOptions: IModalOptions = {
dialogStyle: 'flyout', dialogStyle: 'flyout',
dialogPosition: undefined, dialogPosition: undefined,
positionX: undefined,
positionY: undefined,
width: 'narrow', width: 'narrow',
isAngular: false, isAngular: false,
hasBackButton: false, hasBackButton: false,
@@ -108,6 +103,7 @@ export type HideReason = 'close' | 'cancel' | 'ok';
export abstract class Modal extends Disposable implements IThemable { export abstract class Modal extends Disposable implements IThemable {
protected _useDefaultMessageBoxLocation: boolean = true; protected _useDefaultMessageBoxLocation: boolean = true;
private _styleElement: HTMLStyleElement;
protected _messageElement?: HTMLElement; protected _messageElement?: HTMLElement;
protected _modalOptions: IModalOptions; protected _modalOptions: IModalOptions;
protected readonly disposableStore = this._register(new DisposableStore()); protected readonly disposableStore = this._register(new DisposableStore());
@@ -132,7 +128,9 @@ export abstract class Modal extends Disposable implements IThemable {
private _dialogBorder?: Color; private _dialogBorder?: Color;
private _dialogHeaderAndFooterBackground?: Color; private _dialogHeaderAndFooterBackground?: Color;
private _dialogBodyBackground?: Color; private _dialogBodyBackground?: Color;
private _footerBorderTopColor?: Color; private _dialogInteriorBorder?: Color;
private _dialogExteriorBorder?: Color;
private _dialogShadowColor?: Color;
private _modalDialog?: HTMLElement; private _modalDialog?: HTMLElement;
private _modalContent?: HTMLElement; private _modalContent?: HTMLElement;
@@ -140,7 +138,7 @@ export abstract class Modal extends Disposable implements IThemable {
private _modalBodySection?: HTMLElement; private _modalBodySection?: HTMLElement;
private _modalFooterSection?: HTMLElement; private _modalFooterSection?: HTMLElement;
private _closeButtonInHeader?: HTMLElement; private _closeButtonInHeader?: HTMLElement;
private _bodyContainer?: HTMLElement; protected _bodyContainer?: HTMLElement;
private _modalTitle?: HTMLElement; private _modalTitle?: HTMLElement;
private _modalTitleIcon?: HTMLElement; private _modalTitleIcon?: HTMLElement;
private _leftFooter?: HTMLElement; private _leftFooter?: HTMLElement;
@@ -198,6 +196,8 @@ export abstract class Modal extends Disposable implements IThemable {
* *
*/ */
public render() { public render() {
this._styleElement = DOM.createStyleSheet(this._bodyContainer);
let top: number; let top: number;
let builderClass = '.modal.fade'; let builderClass = '.modal.fade';
builderClass += this._modalOptions.dialogStyle === 'flyout' ? '.flyout-dialog' builderClass += this._modalOptions.dialogStyle === 'flyout' ? '.flyout-dialog'
@@ -424,54 +424,55 @@ export abstract class Modal extends Disposable implements IThemable {
/** /**
* Tasks to perform before dialog is shown * Tasks to perform before callout dialog is shown
* Includes: positioning of dialog * Includes: positioning of dialog
*/ */
protected positionDialog(): void { protected positionCalloutDialog(): void {
/** /**
* In the case of 'below', dialog will be positioned beneath the trigger and arrow aligned with trigger. * In the case of 'below', dialog will be positioned beneath the trigger and arrow aligned with trigger.
* In the case of 'left', dialog will be positioned left of the trigger and arrow aligned with trigger. * In the case of 'left', dialog will be positioned left of the trigger and arrow aligned with trigger.
*/ */
if (this._modalOptions.dialogStyle === 'callout') { let dialogWidth;
let dialogWidth; if (typeof this._modalOptions.width === 'number') {
if (typeof this._modalOptions.width === 'number') { dialogWidth = this._modalOptions.width;
dialogWidth = this._modalOptions.width;
}
if (this._modalOptions.dialogPosition === 'above') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - this._modalOptions.dialogProperties.width}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos - 235}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.positionX}px`;
this._modalDialog.style.top = `${this._modalOptions.positionY - 235}px`;
}
} else if (this._modalOptions.dialogPosition === 'below') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - this._modalOptions.dialogProperties.width}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos + (this._modalOptions.dialogProperties.height)}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.positionX}px`;
this._modalDialog.style.top = `${this._modalOptions.positionY}px`;
}
} else if (this._modalOptions.dialogPosition === 'left') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.positionX - (dialogWidth + this._modalOptions.dialogProperties.width)}px`;
this._modalDialog.style.top = `${this._modalOptions.positionY - this._modalOptions.dialogProperties.height * 2}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.positionX - (dialogWidth)}px`;
this._modalDialog.style.top = `${this._modalOptions.positionY}px`;
}
}
this._modalDialog.style.width = `${dialogWidth}px`;
} }
if (this._modalOptions.dialogPosition === 'above') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - this._modalOptions.dialogProperties.width}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos - 235}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos - 235}px`;
}
} else if (this._modalOptions.dialogPosition === 'below') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - this._modalOptions.dialogProperties.width}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos + (this._modalOptions.dialogProperties.height)}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos}px`;
}
} else if (this._modalOptions.dialogPosition === 'left') {
if (this._modalOptions.dialogProperties) {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - (dialogWidth + this._modalOptions.dialogProperties.width)}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos - this._modalOptions.dialogProperties.height * 2}px`;
} else {
this._modalDialog.style.left = `${this._modalOptions.dialogProperties.xPos - (dialogWidth)}px`;
this._modalDialog.style.top = `${this._modalOptions.dialogProperties.yPos}px`;
}
}
this._modalDialog.style.width = `${dialogWidth}px`;
} }
/** /**
* Shows the modal and attaches key listeners * Shows the modal and attaches key listeners
*/ */
protected show() { protected show() {
this.positionDialog(); if (this._modalOptions.dialogStyle === 'callout') {
this.positionCalloutDialog();
}
this._focusedElementBeforeOpen = <HTMLElement>document.activeElement; this._focusedElementBeforeOpen = <HTMLElement>document.activeElement;
this._modalShowingContext.get()!.push(this._staticKey); this._modalShowingContext.get()!.push(this._staticKey);
DOM.append(this.layoutService.container, this._bodyContainer!); DOM.append(this.layoutService.container, this._bodyContainer!);
@@ -689,15 +690,13 @@ export abstract class Modal extends Disposable implements IThemable {
* Called by the theme registry on theme change to style the component * Called by the theme registry on theme change to style the component
*/ */
public style(styles: IModalDialogStyles): void { public style(styles: IModalDialogStyles): void {
this._dialogForeground = styles.dialogForeground ? styles.dialogForeground : this._themeService.getColorTheme().getColor(editorWidgetForeground); this._dialogForeground = styles.dialogForeground;
this._dialogBorder = styles.dialogBorder ? styles.dialogBorder : this._themeService.getColorTheme().getColor(notebookToolbarLines); this._dialogBorder = styles.dialogBorder;
if (this._modalOptions.dialogStyle === 'callout') { this._dialogHeaderAndFooterBackground = styles.dialogHeaderAndFooterBackground;
this._dialogHeaderAndFooterBackground = styles.dialogBodyBackground ? styles.dialogBodyBackground : this._themeService.getColorTheme().getColor(SIDE_BAR_BACKGROUND); this._dialogBodyBackground = styles.dialogBodyBackground;
} else { this._dialogInteriorBorder = styles.dialogInteriorBorder;
this._dialogHeaderAndFooterBackground = styles.dialogHeaderAndFooterBackground ? styles.dialogHeaderAndFooterBackground : this._themeService.getColorTheme().getColor(SIDE_BAR_BACKGROUND); this._dialogExteriorBorder = styles.dialogExteriorBorder;
} this._dialogShadowColor = styles.dialogShadowColor;
this._dialogBodyBackground = styles.dialogBodyBackground ? styles.dialogBodyBackground : this._themeService.getColorTheme().getColor(editorBackground);
this._footerBorderTopColor = styles.footerBorderTopColor ? styles.footerBorderTopColor : this._themeService.getColorTheme().getColor(notebookToolbarLines);
this.applyStyles(); this.applyStyles();
} }
@@ -706,10 +705,8 @@ export abstract class Modal extends Disposable implements IThemable {
const border = this._dialogBorder ? this._dialogBorder.toString() : ''; const border = this._dialogBorder ? this._dialogBorder.toString() : '';
const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : ''; const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : '';
const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : ''; const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : '';
const calloutStyle: CSSStyleDeclaration = this._modalDialog.style; const footerBorderTopWidth = border ? '1px' : '';
const footerTopBorderColor = this._footerBorderTopColor ? this._footerBorderTopColor.toString() : ''; const footerBorderTopStyle = border ? 'solid' : '';
const foregroundRgb: Color = Color.Format.CSS.parseHex(foreground);
if (this._closeButtonInHeader) { if (this._closeButtonInHeader) {
this._closeButtonInHeader.style.color = foreground; this._closeButtonInHeader.style.color = foreground;
@@ -719,17 +716,6 @@ export abstract class Modal extends Disposable implements IThemable {
this._modalDialog.style.borderWidth = border ? '1px' : ''; this._modalDialog.style.borderWidth = border ? '1px' : '';
this._modalDialog.style.borderStyle = border ? 'solid' : ''; this._modalDialog.style.borderStyle = border ? 'solid' : '';
this._modalDialog.style.borderColor = border; this._modalDialog.style.borderColor = border;
calloutStyle.setProperty('--border', `${border}`);
calloutStyle.setProperty('--bodybackground', `${bodyBackground}`);
if (foregroundRgb) {
calloutStyle.setProperty('--foreground', `
${foregroundRgb.rgba.r},
${foregroundRgb.rgba.g},
${foregroundRgb.rgba.b},
0.08
`);
}
} }
if (this._modalHeaderSection) { if (this._modalHeaderSection) {
@@ -754,9 +740,50 @@ export abstract class Modal extends Disposable implements IThemable {
if (this._modalFooterSection) { if (this._modalFooterSection) {
this._modalFooterSection.style.backgroundColor = headerAndFooterBackground; this._modalFooterSection.style.backgroundColor = headerAndFooterBackground;
this._modalFooterSection.style.borderTopWidth = border ? '1px' : ''; this._modalFooterSection.style.borderTopWidth = footerBorderTopWidth;
this._modalFooterSection.style.borderTopStyle = border ? 'solid' : ''; this._modalFooterSection.style.borderTopStyle = footerBorderTopStyle;
this._modalFooterSection.style.borderTopColor = footerTopBorderColor; if (!(this._modalOptions.dialogStyle === 'callout')) {
this._modalFooterSection.style.borderTopColor = border;
}
}
if (this._modalOptions.dialogStyle === 'callout') {
const content: string[] = [];
const exteriorBorder = this._dialogExteriorBorder ? this._dialogExteriorBorder.toString() : '';
const exteriorBorderRgb: Color = Color.Format.CSS.parseHex(exteriorBorder);
const shadow = this._dialogShadowColor ? this._dialogShadowColor.toString() : '';
const shadowRgb: Color = Color.Format.CSS.parseHex(shadow);
if (exteriorBorderRgb && shadowRgb) {
content.push(`
.modal.callout-dialog .modal-dialog {
border-color: rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b},0.5);
box-shadow: 0px 3.2px 7.2px rgba(${shadowRgb.rgba.r}, ${shadowRgb.rgba.g}, ${shadowRgb.rgba.b}, 0.132),
0px 0.6px 1.8px rgba(${shadowRgb.rgba.r}, ${shadowRgb.rgba.g}, ${shadowRgb.rgba.b}, 0.108);
}
.hc-black .modal.callout-dialog .modal-dialog {
border-color: rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b}, 1);
}
.modal.callout-dialog .modal-footer {
border-top-color: ${this._dialogInteriorBorder};
}
.callout-arrow:before {
background-color: ${this._dialogBodyBackground};
border-color: transparent transparent rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b}, 0.5) rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b}, 0.5);
}
.hc-black .callout-arrow:before {
border-color: transparent transparent rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b}, 1) rgba(${exteriorBorderRgb.rgba.r}, ${exteriorBorderRgb.rgba.g}, ${exteriorBorderRgb.rgba.b}, 1);
}
.callout-arrow.from-left:before {
background-color: ${this._dialogBodyBackground};
box-shadow: -4px 4px 4px rgba(${shadowRgb.rgba.r}, ${shadowRgb.rgba.g}, ${shadowRgb.rgba.b}, 0.05);
}`);
}
const newStyles = content.join('\n');
if (newStyles !== this._styleElement.innerHTML) {
this._styleElement.innerHTML = newStyles;
}
} }
} }

View File

@@ -6,26 +6,32 @@
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable } from 'vs/base/common/lifecycle';
import * as cr from 'vs/platform/theme/common/colorRegistry'; import * as cr from 'vs/platform/theme/common/colorRegistry';
import * as sqlcr from 'sql/platform/theme/common/colorRegistry';
import { IThemable } from 'vs/base/common/styler'; import { IThemable } from 'vs/base/common/styler';
import { attachStyler } from 'vs/platform/theme/common/styler'; import { attachStyler, IStyleOverrides } from 'vs/platform/theme/common/styler';
import { import {
SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_BACKGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_BACKGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_DRAG_AND_DROP_BACKGROUND,
PANEL_ACTIVE_TITLE_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, VERTICAL_TAB_ACTIVE_BACKGROUND, DASHBOARD_BORDER, PANEL_ACTIVE_TITLE_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, VERTICAL_TAB_ACTIVE_BACKGROUND, DASHBOARD_BORDER,
} from 'vs/workbench/common/theme'; } from 'vs/workbench/common/theme';
export function attachModalDialogStyler(widget: IThemable, themeService: IThemeService, style?: export interface IModalDialogStyleOverrides extends IStyleOverrides {
{ dialogForeground?: cr.ColorIdentifier,
dialogForeground?: cr.ColorIdentifier, dialogHeaderAndFooterBackground?: cr.ColorIdentifier,
dialogHeaderAndFooterBackground?: cr.ColorIdentifier, dialogBodyBackground?: cr.ColorIdentifier,
dialogBodyBackground?: cr.ColorIdentifier, dialogBorder?: cr.ColorIdentifier,
}): IDisposable { dialogInteriorBorder?: cr.ColorIdentifier,
dialogExteriorBorder?: cr.ColorIdentifier,
dialogShadowColor?: cr.ColorIdentifier
}
export function attachModalDialogStyler(widget: IThemable, themeService: IThemeService, style?: IModalDialogStyleOverrides): IDisposable {
return attachStyler(themeService, { return attachStyler(themeService, {
dialogForeground: (style && style.dialogForeground) || cr.foreground, dialogForeground: (style && style.dialogForeground) || cr.foreground,
dialogBorder: cr.contrastBorder, dialogBorder: cr.contrastBorder,
dialogHeaderAndFooterBackground: (style && style.dialogHeaderAndFooterBackground) || SIDE_BAR_BACKGROUND, dialogHeaderAndFooterBackground: (style && style.dialogHeaderAndFooterBackground) || SIDE_BAR_BACKGROUND,
dialogBodyBackground: (style && style.dialogBodyBackground) || cr.editorBackground dialogBodyBackground: (style && style.dialogBodyBackground) || cr.editorBackground
}, widget); } as IModalDialogStyleOverrides, widget);
} }
export function attachPanelStyler(widget: IThemable, themeService: IThemeService) { export function attachPanelStyler(widget: IThemable, themeService: IThemeService) {
@@ -49,3 +55,34 @@ export function attachTabbedPanelStyler(widget: IThemable, themeService: IThemeS
activeTabContrastBorder: cr.activeContrastBorder activeTabContrastBorder: cr.activeContrastBorder
}, widget); }, widget);
} }
export function attachCalloutDialogStyler(widget: IThemable, themeService: IThemeService, style?: IModalDialogStyleOverrides): IDisposable {
return attachStyler(themeService, {
dialogForeground: (style && style.dialogForeground) || sqlcr.calloutDialogForeground,
dialogHeaderAndFooterBackground: (style && style.dialogHeaderAndFooterBackground) || sqlcr.calloutDialogHeaderFooterBackground,
dialogBodyBackground: (style && style.dialogBodyBackground) || sqlcr.calloutDialogBodyBackground,
dialogInteriorBorder: (style && style.dialogInteriorBorder) || sqlcr.calloutDialogInteriorBorder,
dialogExteriorBorder: (style && style.dialogExteriorBorder) || sqlcr.calloutDialogExteriorBorder,
dialogShadowColor: (style && style.dialogShadowColor) || sqlcr.calloutDialogShadowColor
} as IModalDialogStyleOverrides, widget);
}
export function attachCustomDialogStyler(widget: IThemable, themeService: IThemeService, dialogStyle?: string, style?: IModalDialogStyleOverrides): IDisposable {
if (dialogStyle === 'callout') {
return attachStyler(themeService, {
dialogForeground: (style && style.dialogForeground) || sqlcr.calloutDialogForeground,
dialogHeaderAndFooterBackground: (style && style.dialogHeaderAndFooterBackground) || sqlcr.calloutDialogHeaderFooterBackground,
dialogBodyBackground: (style && style.dialogBodyBackground) || sqlcr.calloutDialogBodyBackground,
dialogInteriorBorder: (style && style.dialogInteriorBorder) || sqlcr.calloutDialogInteriorBorder,
dialogExteriorBorder: (style && style.dialogExteriorBorder) || sqlcr.calloutDialogExteriorBorder,
dialogShadowColor: (style && style.dialogShadowColor) || sqlcr.calloutDialogShadowColor
} as IModalDialogStyleOverrides, widget);
} else {
return attachStyler(themeService, {
dialogForeground: (style && style.dialogForeground) || cr.foreground,
dialogBorder: cr.contrastBorder,
dialogHeaderAndFooterBackground: (style && style.dialogHeaderAndFooterBackground) || SIDE_BAR_BACKGROUND,
dialogBodyBackground: (style && style.dialogBodyBackground) || cr.editorBackground
} as IModalDialogStyleOverrides, widget);
}
}

View File

@@ -6,12 +6,12 @@
import 'vs/css!./media/imageCalloutDialog'; import 'vs/css!./media/imageCalloutDialog';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import * as styler from 'vs/platform/theme/common/styler'; import * as styler from 'vs/platform/theme/common/styler';
import { URI } from 'vs/base/common/uri'; import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import * as constants from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/constants'; import * as constants from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/constants';
import { CalloutDialog } from 'sql/workbench/browser/modal/calloutDialog'; import { URI } from 'vs/base/common/uri';
import { Modal, IDialogProperties } from 'sql/workbench/browser/modal/modal';
import { IFileDialogService, IOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; import { IFileDialogService, IOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IDialogProperties } from 'sql/workbench/browser/modal/modal';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
@@ -25,7 +25,7 @@ import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { RadioButton } from 'sql/base/browser/ui/radioButton/radioButton'; import { RadioButton } from 'sql/base/browser/ui/radioButton/radioButton';
import { DialogPosition, DialogWidth } from 'sql/workbench/api/common/sqlExtHostTypes'; import { DialogPosition, DialogWidth } from 'sql/workbench/api/common/sqlExtHostTypes';
import { attachModalDialogStyler } from 'sql/workbench/common/styler'; import { attachCalloutDialogStyler } from 'sql/workbench/common/styler';
import { escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils'; import { escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils';
export interface IImageCalloutDialogOptions { export interface IImageCalloutDialogOptions {
@@ -35,7 +35,9 @@ export interface IImageCalloutDialogOptions {
embedImage?: boolean embedImage?: boolean
} }
export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions> { const DEFAULT_DIALOG_WIDTH: DialogWidth = 452;
export class ImageCalloutDialog extends Modal {
private _selectionComplete: Deferred<IImageCalloutDialogOptions> = new Deferred<IImageCalloutDialogOptions>(); private _selectionComplete: Deferred<IImageCalloutDialogOptions> = new Deferred<IImageCalloutDialogOptions>();
private _imageLocationLabel: HTMLElement; private _imageLocationLabel: HTMLElement;
private _imageLocalRadioButton: RadioButton; private _imageLocalRadioButton: RadioButton;
@@ -49,9 +51,8 @@ export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions
constructor( constructor(
title: string, title: string,
width: DialogWidth,
dialogProperties: IDialogProperties,
dialogPosition: DialogPosition, dialogPosition: DialogPosition,
dialogProperties: IDialogProperties,
@IPathService private readonly _pathService: IPathService, @IPathService private readonly _pathService: IPathService,
@IFileDialogService private readonly _fileDialogService: IFileDialogService, @IFileDialogService private readonly _fileDialogService: IFileDialogService,
@IContextViewService private readonly _contextViewService: IContextViewService, @IContextViewService private readonly _contextViewService: IContextViewService,
@@ -65,19 +66,26 @@ export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions
) { ) {
super( super(
title, title,
width, TelemetryKeys.CalloutDialog,
dialogProperties,
dialogPosition,
themeService,
layoutService,
telemetryService, telemetryService,
contextKeyService, layoutService,
clipboardService, clipboardService,
themeService,
logService, logService,
textResourcePropertiesService textResourcePropertiesService,
contextKeyService,
{
dialogStyle: 'callout',
dialogPosition: dialogPosition,
dialogProperties: dialogProperties,
width: DEFAULT_DIALOG_WIDTH
}
); );
} }
protected layout(height?: number): void {
}
/** /**
* Opens the dialog and returns a promise for what options the user chooses. * Opens the dialog and returns a promise for what options the user chooses.
*/ */
@@ -88,7 +96,8 @@ export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions
public render(): void { public render(): void {
super.render(); super.render();
attachModalDialogStyler(this, this._themeService); attachCalloutDialogStyler(this, this._themeService);
this.addFooterButton(constants.insertButtonText, () => this.insert()); this.addFooterButton(constants.insertButtonText, () => this.insert());
this.addFooterButton(constants.cancelButtonText, () => this.cancel(), undefined, true); this.addFooterButton(constants.cancelButtonText, () => this.cancel(), undefined, true);
this.registerListeners(); this.registerListeners();
@@ -196,7 +205,7 @@ export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions
} }
public cancel(): void { public cancel(): void {
super.cancel(); this.hide('cancel');
this._selectionComplete.resolve({ this._selectionComplete.resolve({
insertEscapedMarkdown: '', insertEscapedMarkdown: '',
imagePath: undefined, imagePath: undefined,
@@ -225,5 +234,4 @@ export class ImageCalloutDialog extends CalloutDialog<IImageCalloutDialogOptions
return undefined; return undefined;
} }
} }
} }

View File

@@ -7,9 +7,9 @@ import 'vs/css!./media/linkCalloutDialog';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import * as styler from 'vs/platform/theme/common/styler'; import * as styler from 'vs/platform/theme/common/styler';
import * as constants from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/constants'; import * as constants from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/constants';
import { CalloutDialog } from 'sql/workbench/browser/modal/calloutDialog'; import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { Modal, IDialogProperties, DialogPosition, DialogWidth } from 'sql/workbench/browser/modal/modal';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { DialogPosition, IDialogProperties } from 'sql/workbench/browser/modal/modal';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -19,12 +19,10 @@ import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { Deferred } from 'sql/base/common/promise'; import { Deferred } from 'sql/base/common/promise';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox'; import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { attachModalDialogStyler } from 'sql/workbench/common/styler'; import { attachCalloutDialogStyler } from 'sql/workbench/common/styler';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { escapeLabel, escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils'; import { escapeLabel, escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils';
const DEFAULT_DIALOG_WIDTH = 452;
export interface ILinkCalloutDialogOptions { export interface ILinkCalloutDialogOptions {
insertTitle?: string, insertTitle?: string,
insertEscapedMarkdown?: string, insertEscapedMarkdown?: string,
@@ -32,7 +30,9 @@ export interface ILinkCalloutDialogOptions {
insertUnescapedLinkUrl?: string insertUnescapedLinkUrl?: string
} }
export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions> { const DEFAULT_DIALOG_WIDTH: DialogWidth = 452;
export class LinkCalloutDialog extends Modal {
private _selectionComplete: Deferred<ILinkCalloutDialogOptions> = new Deferred<ILinkCalloutDialogOptions>(); private _selectionComplete: Deferred<ILinkCalloutDialogOptions> = new Deferred<ILinkCalloutDialogOptions>();
private _linkTextLabel: HTMLElement; private _linkTextLabel: HTMLElement;
private _linkTextInputBox: InputBox; private _linkTextInputBox: InputBox;
@@ -42,8 +42,8 @@ export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions>
constructor( constructor(
title: string, title: string,
dialogProperties: IDialogProperties,
dialogPosition: DialogPosition, dialogPosition: DialogPosition,
dialogProperties: IDialogProperties,
private readonly _defaultLabel: string = '', private readonly _defaultLabel: string = '',
@IContextViewService private readonly _contextViewService: IContextViewService, @IContextViewService private readonly _contextViewService: IContextViewService,
@IThemeService themeService: IThemeService, @IThemeService themeService: IThemeService,
@@ -56,16 +56,20 @@ export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions>
) { ) {
super( super(
title, title,
DEFAULT_DIALOG_WIDTH, TelemetryKeys.CalloutDialog,
dialogProperties,
dialogPosition,
themeService,
layoutService,
telemetryService, telemetryService,
contextKeyService, layoutService,
clipboardService, clipboardService,
themeService,
logService, logService,
textResourcePropertiesService textResourcePropertiesService,
contextKeyService,
{
dialogStyle: 'callout',
dialogPosition: dialogPosition,
dialogProperties: dialogProperties,
width: DEFAULT_DIALOG_WIDTH
}
); );
let selection = window.getSelection(); let selection = window.getSelection();
if (selection.rangeCount > 0) { if (selection.rangeCount > 0) {
@@ -73,6 +77,9 @@ export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions>
} }
} }
protected layout(height?: number): void {
}
/** /**
* Opens the dialog and returns a promise for what options the user chooses. * Opens the dialog and returns a promise for what options the user chooses.
*/ */
@@ -84,7 +91,8 @@ export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions>
public render(): void { public render(): void {
super.render(); super.render();
attachModalDialogStyler(this, this._themeService); attachCalloutDialogStyler(this, this._themeService);
this.addFooterButton(constants.insertButtonText, () => this.insert()); this.addFooterButton(constants.insertButtonText, () => this.insert());
this.addFooterButton(constants.cancelButtonText, () => this.cancel(), undefined, true); this.addFooterButton(constants.cancelButtonText, () => this.cancel(), undefined, true);
this.registerListeners(); this.registerListeners();
@@ -165,7 +173,7 @@ export class LinkCalloutDialog extends CalloutDialog<ILinkCalloutDialogOptions>
} }
public cancel(): void { public cancel(): void {
super.cancel(); this.hide('cancel');
this._selectionComplete.resolve({ this._selectionComplete.resolve({
insertEscapedMarkdown: '', insertEscapedMarkdown: '',
insertUnescapedLinkLabel: escapeLabel(this._linkTextInputBox.value) insertUnescapedLinkLabel: escapeLabel(this._linkTextInputBox.value)

View File

@@ -220,11 +220,12 @@ export class MarkdownToolbarComponent extends AngularDisposable {
DOM.EventHelper.stop(event, true); DOM.EventHelper.stop(event, true);
let triggerElement = event.target as HTMLElement; let triggerElement = event.target as HTMLElement;
let needsTransform = true; let needsTransform = true;
let calloutResult: ILinkCalloutDialogOptions; let linkCalloutResult: ILinkCalloutDialogOptions;
if (type === MarkdownButtonType.LINK_PREVIEW) { if (type === MarkdownButtonType.LINK_PREVIEW) {
calloutResult = await this.createCallout(type, triggerElement); linkCalloutResult = await this.createCallout(type, triggerElement);
// If no URL is present, no-op // If no URL is present, no-op
if (!calloutResult.insertUnescapedLinkUrl) { if (!linkCalloutResult.insertUnescapedLinkUrl) {
return; return;
} }
// If cell edit mode isn't WYSIWYG, use result from callout. No need for further transformation. // If cell edit mode isn't WYSIWYG, use result from callout. No need for further transformation.
@@ -234,15 +235,18 @@ export class MarkdownToolbarComponent extends AngularDisposable {
// Otherwise, re-focus on the output element, and insert the link directly. // Otherwise, re-focus on the output element, and insert the link directly.
this.output?.nativeElement?.focus(); this.output?.nativeElement?.focus();
// Callout is responsible for returning escaped strings // Callout is responsible for returning escaped strings
document.execCommand('insertHTML', false, `<a href="${calloutResult?.insertUnescapedLinkUrl}">${calloutResult?.insertUnescapedLinkLabel}</a>`); document.execCommand('insertHTML', false, `<a href="${linkCalloutResult?.insertUnescapedLinkUrl}">${linkCalloutResult?.insertUnescapedLinkLabel}</a>`);
return; return;
} }
} }
const transformer = new MarkdownTextTransformer(this._notebookService, this.cellModel); const transformer = new MarkdownTextTransformer(this._notebookService, this.cellModel);
if (needsTransform) { if (needsTransform) {
await transformer.transformText(type); await transformer.transformText(type);
} else if (!needsTransform) { } else if (!needsTransform) {
await insertFormattedMarkdown(calloutResult?.insertEscapedMarkdown, this.getCellEditorControl()); if (type === MarkdownButtonType.LINK_PREVIEW) {
await insertFormattedMarkdown(linkCalloutResult?.insertEscapedMarkdown, this.getCellEditorControl());
}
} }
} }
@@ -283,7 +287,7 @@ export class MarkdownToolbarComponent extends AngularDisposable {
if (type === MarkdownButtonType.LINK_PREVIEW) { if (type === MarkdownButtonType.LINK_PREVIEW) {
const defaultLabel = this.getCurrentSelectionText(); const defaultLabel = this.getCurrentSelectionText();
this._linkCallout = this._instantiationService.createInstance(LinkCalloutDialog, this.insertLinkHeading, dialogProperties, dialogPosition, defaultLabel); this._linkCallout = this._instantiationService.createInstance(LinkCalloutDialog, this.insertLinkHeading, dialogPosition, dialogProperties, defaultLabel);
this._linkCallout.render(); this._linkCallout.render();
calloutOptions = await this._linkCallout.open(); calloutOptions = await this._linkCallout.open();
} }

View File

@@ -11,6 +11,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { Deferred } from 'sql/base/common/promise'; import { Deferred } from 'sql/base/common/promise';
import { escapeLabel, escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils'; import { escapeLabel, escapeUrl } from 'sql/workbench/contrib/notebook/browser/calloutDialog/common/utils';
import { IDialogProperties } from 'sql/workbench/browser/modal/modal';
suite('Link Callout Dialog', function (): void { suite('Link Callout Dialog', function (): void {
let layoutService: ILayoutService; let layoutService: ILayoutService;
@@ -18,6 +19,8 @@ suite('Link Callout Dialog', function (): void {
let telemetryService: IAdsTelemetryService; let telemetryService: IAdsTelemetryService;
let contextKeyService: IContextKeyService; let contextKeyService: IContextKeyService;
const defaultDialogProperties: IDialogProperties = { xPos: 0, yPos: 0, height: 250, width: 100 };
setup(() => { setup(() => {
layoutService = new TestLayoutService(); layoutService = new TestLayoutService();
themeService = new TestThemeService(); themeService = new TestThemeService();
@@ -26,7 +29,7 @@ suite('Link Callout Dialog', function (): void {
}); });
test('Should return empty markdown on cancel', async function (): Promise<void> { test('Should return empty markdown on cancel', async function (): Promise<void> {
let linkCalloutDialog = new LinkCalloutDialog('Title', undefined, 'below', 'defaultLabel', let linkCalloutDialog = new LinkCalloutDialog('Title', 'below', defaultDialogProperties, 'defaultLabel',
undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined); undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined);
linkCalloutDialog.render(); linkCalloutDialog.render();
@@ -47,7 +50,7 @@ suite('Link Callout Dialog', function (): void {
test('Should return expected values on insert', async function (): Promise<void> { test('Should return expected values on insert', async function (): Promise<void> {
const defaultLabel = 'defaultLabel'; const defaultLabel = 'defaultLabel';
const sampleUrl = 'https://www.aka.ms/azuredatastudio'; const sampleUrl = 'https://www.aka.ms/azuredatastudio';
let linkCalloutDialog = new LinkCalloutDialog('Title', undefined, 'below', defaultLabel, let linkCalloutDialog = new LinkCalloutDialog('Title', 'below', defaultDialogProperties, defaultLabel,
undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined); undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined);
linkCalloutDialog.render(); linkCalloutDialog.render();
@@ -70,7 +73,7 @@ suite('Link Callout Dialog', function (): void {
test('Should return expected values on insert when escape necessary', async function (): Promise<void> { test('Should return expected values on insert when escape necessary', async function (): Promise<void> {
const defaultLabel = 'default[]Label'; const defaultLabel = 'default[]Label';
const sampleUrl = 'https://www.aka.ms/azuredatastudio()'; const sampleUrl = 'https://www.aka.ms/azuredatastudio()';
let linkCalloutDialog = new LinkCalloutDialog('Title', undefined, 'below', defaultLabel, let linkCalloutDialog = new LinkCalloutDialog('Title', 'below', defaultDialogProperties, defaultLabel,
undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined); undefined, themeService, layoutService, telemetryService, contextKeyService, undefined, undefined, undefined);
linkCalloutDialog.render(); linkCalloutDialog.render();

View File

@@ -22,8 +22,8 @@ export class CustomDialogService {
let name = dialogName ? dialogName : 'CustomDialog'; let name = dialogName ? dialogName : 'CustomDialog';
if (options && (options.dialogStyle === 'callout')) { if (options && (options.dialogStyle === 'callout')) {
options.positionX = document.activeElement.getBoundingClientRect().left; options.dialogProperties.xPos = document.activeElement.getBoundingClientRect().left;
options.positionY = document.activeElement.getBoundingClientRect().top; options.dialogProperties.yPos = document.activeElement.getBoundingClientRect().top;
options.renderFooter = false; options.renderFooter = false;
} }
let dialogModal = this._instantiationService.createInstance(DialogModal, dialog, name, options || DefaultDialogOptions); let dialogModal = this._instantiationService.createInstance(DialogModal, dialog, name, options || DefaultDialogOptions);

View File

@@ -23,7 +23,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
import { attachModalDialogStyler } from 'sql/workbench/common/styler'; import { attachCustomDialogStyler } from 'sql/workbench/common/styler';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
export class DialogModal extends Modal { export class DialogModal extends Modal {
@@ -56,7 +56,7 @@ export class DialogModal extends Modal {
public render() { public render() {
super.render(); super.render();
attachModalDialogStyler(this, this._themeService); attachCustomDialogStyler(this, this._themeService, this._modalOptions.dialogStyle);
if (this._modalOptions.renderFooter !== false) { if (this._modalOptions.renderFooter !== false) {
this._modalOptions.renderFooter = true; this._modalOptions.renderFooter = true;