From 098c40e9ac34d9bb6beeef83c6623c8dfae2d0eb Mon Sep 17 00:00:00 2001 From: Kevin Cunnane Date: Tue, 5 Feb 2019 11:28:07 -0800 Subject: [PATCH] Use document-style for Notebooks (#3902) * Added hover support, adding box shadow and light outline on hovering and the "more actions" button showing on hover * Added box shadow for dark themes (hooray!) * Remove border from everything but the code cell unless a cell is selected or hovered over. This ensures this looks like a document * Fix high contrast theming issues. --- .../notebook/cellViews/code.component.html | 2 +- .../notebook/cellViews/code.component.ts | 18 +++++ .../cellViews/codeCell.component.html | 2 +- .../parts/notebook/cellViews/outputArea.css | 4 +- .../cellViews/textCell.component.html | 2 +- .../notebook/cellViews/textCell.component.ts | 40 ++++++++--- src/sql/parts/notebook/cellViews/textCell.css | 2 - src/sql/parts/notebook/notebookStyles.ts | 71 +++++++++++++++++-- 8 files changed, 116 insertions(+), 25 deletions(-) diff --git a/src/sql/parts/notebook/cellViews/code.component.html b/src/sql/parts/notebook/cellViews/code.component.html index 661e1e4c6b..07198750e4 100644 --- a/src/sql/parts/notebook/cellViews/code.component.html +++ b/src/sql/parts/notebook/cellViews/code.component.html @@ -4,7 +4,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ --> -
+
diff --git a/src/sql/parts/notebook/cellViews/code.component.ts b/src/sql/parts/notebook/cellViews/code.component.ts index 887f2c11be..d5dd019dc2 100644 --- a/src/sql/parts/notebook/cellViews/code.component.ts +++ b/src/sql/parts/notebook/cellViews/code.component.ts @@ -54,6 +54,15 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange this._activeCellId = value; } + @Input() set hover(value: boolean) { + this._hover = value; + if (!this.isActive()) { + // Only make a change if we're not active, since this has priority + this.toggleMoreActionsButton(this._hover); + } + } + + protected _actionBar: Taskbar; private readonly _minimumHeight = 30; private _editor: QueryTextEditor; @@ -63,6 +72,7 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange private _model: NotebookModel; private _activeCellId: string; private _cellToggleMoreActions: CellToggleMoreActions; + private _hover: boolean; constructor( @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, @@ -202,4 +212,12 @@ export class CodeComponent extends AngularDisposable implements OnInit, OnChange this._editor.getContainer().scrollIntoView(); } } + + protected isActive() { + return this.cellModel && this.cellModel.id === this.activeCellId; + } + + protected toggleMoreActionsButton(isActive: boolean) { + this._cellToggleMoreActions.toggle(isActive, this.moreActionsElementRef, this.model, this.cellModel); + } } diff --git a/src/sql/parts/notebook/cellViews/codeCell.component.html b/src/sql/parts/notebook/cellViews/codeCell.component.html index a55e47e4da..c346ffb299 100644 --- a/src/sql/parts/notebook/cellViews/codeCell.component.html +++ b/src/sql/parts/notebook/cellViews/codeCell.component.html @@ -5,7 +5,7 @@ *--------------------------------------------------------------------------------------------*/ -->
-
+
diff --git a/src/sql/parts/notebook/cellViews/outputArea.css b/src/sql/parts/notebook/cellViews/outputArea.css index c3bae82b99..95317793ca 100644 --- a/src/sql/parts/notebook/cellViews/outputArea.css +++ b/src/sql/parts/notebook/cellViews/outputArea.css @@ -7,9 +7,7 @@ output-area-component { } output-area-component .notebook-output { - border-top-width: 1px; - border-top-style: solid; + border-top-width: 0px; user-select: initial; padding: 5px 20px 0px; - box-shadow: rgba(120, 120, 120, 0.75) 0px -2px 1px -2px; } \ No newline at end of file diff --git a/src/sql/parts/notebook/cellViews/textCell.component.html b/src/sql/parts/notebook/cellViews/textCell.component.html index e2bc42f96e..1f8501d9f6 100644 --- a/src/sql/parts/notebook/cellViews/textCell.component.html +++ b/src/sql/parts/notebook/cellViews/textCell.component.html @@ -4,7 +4,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ --> -
+
diff --git a/src/sql/parts/notebook/cellViews/textCell.component.ts b/src/sql/parts/notebook/cellViews/textCell.component.ts index 0ab5fd5eb7..ed28494ed3 100644 --- a/src/sql/parts/notebook/cellViews/textCell.component.ts +++ b/src/sql/parts/notebook/cellViews/textCell.component.ts @@ -41,6 +41,14 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges { this._activeCellId = value; } + @Input() set hover(value: boolean) { + this._hover = value; + if (!this.isActive()) { + // Only make a change if we're not active, since this has priority + this.updateMoreActions(); + } + } + private _content: string; private isEditMode: boolean; private _sanitizer: ISanitizer; @@ -50,6 +58,7 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges { public readonly onDidClickLink = this._onDidClickLink.event; protected isLoading: boolean; private _cellToggleMoreActions: CellToggleMoreActions; + private _hover: boolean; constructor( @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, @@ -158,24 +167,33 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges { public toggleEditMode(editMode?: boolean): void { this.isEditMode = editMode !== undefined? editMode : !this.isEditMode; - if (!this.isEditMode && this.cellModel.id === this._activeCellId) { - this._cellToggleMoreActions.toggle(true, this.moreActionsElementRef, this.model, this.cellModel); - } - else { - this._cellToggleMoreActions.toggle(false, this.moreActionsElementRef, this.model, this.cellModel); - } + this.updateMoreActions(); this.updatePreview(); this._changeRef.detectChanges(); } - private setFocusAndScroll(): void { - if (this.cellModel.id === this._activeCellId) { - this.toggleEditMode(true); - } else { - this.toggleEditMode(false); + private updateMoreActions(): void { + if (!this.isEditMode && (this.isActive() || this._hover)) { + this.toggleMoreActionsButton(true); } + else { + this.toggleMoreActionsButton(false); + } + } + + private setFocusAndScroll(): void { + this.toggleEditMode(this.isActive()); + if (this.output && this.output.nativeElement) { (this.output.nativeElement).scrollTo(); } } + + protected isActive() { + return this.cellModel && this.cellModel.id === this.activeCellId; + } + + protected toggleMoreActionsButton(isActive: boolean) { + this._cellToggleMoreActions.toggle(isActive, this.moreActionsElementRef, this.model, this.cellModel); + } } diff --git a/src/sql/parts/notebook/cellViews/textCell.css b/src/sql/parts/notebook/cellViews/textCell.css index bb2b57b980..4f218a1ffe 100644 --- a/src/sql/parts/notebook/cellViews/textCell.css +++ b/src/sql/parts/notebook/cellViews/textCell.css @@ -8,8 +8,6 @@ text-cell-component { } text-cell-component .notebook-preview { - border-top-width: 1px; - border-top-style: solid; user-select: initial; padding-left: 8px; padding-right: 8px; diff --git a/src/sql/parts/notebook/notebookStyles.ts b/src/sql/parts/notebook/notebookStyles.ts index 200b7dd0e1..45f4fa6deb 100644 --- a/src/sql/parts/notebook/notebookStyles.ts +++ b/src/sql/parts/notebook/notebookStyles.ts @@ -6,10 +6,12 @@ import 'vs/css!./notebook'; import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; -import { activeContrastBorder, buttonBackground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { activeContrastBorder, contrastBorder, buttonBackground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + let lightBoxShadow = '0px 4px 6px 0px rgba(0,0,0,0.14)'; + let darkBoxShadow = '0 4px 6px 0px rgba(0, 0, 0, 1)'; // Active border const activeBorder = theme.getColor(buttonBackground); if (activeBorder) { @@ -17,17 +19,64 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { .notebookEditor .notebook-cell.active { border-color: ${activeBorder}; border-width: 1px; - box-shadow: 0px 4px 6px 0px rgba(0,0,0,0.14); } `); } + // Box shadow handling + collector.addRule(` + .notebookEditor .notebook-cell.active { + box-shadow: ${lightBoxShadow}; + } + + .vs-dark .notebookEditor .notebook-cell.active { + box-shadow: ${darkBoxShadow}; + } + + .hc-black .notebookEditor .notebook-cell.active { + box-shadow: 0; + } + + .notebookEditor .notebook-cell:hover:not(.active) { + box-shadow: ${lightBoxShadow}; + } + + .vs-dark .notebookEditor .notebook-cell:hover:not(.active) { + box-shadow: ${darkBoxShadow}; + } + + .hc-black .notebookEditor .notebook-cell:hover:not(.active) { + box-shadow: 0; + } + `); + + // Inactive border const inactiveBorder = theme.getColor(SIDE_BAR_BACKGROUND); if (inactiveBorder) { collector.addRule(` + .notebookEditor .notebook-cell code-component { + border-color: ${inactiveBorder}; + border-width: 1px; + border-style: solid; + border-radius: 3px 3px 3px 3px; + } + .notebookEditor .notebook-cell.active code-component { + border-width: 0px 0px 1px 0px; + border-radius: 0px; + } + .notebookEditor .notebook-cell:hover code-component { + border-width: 0px 0px 1px 0px; + border-radius: 0px; + } .notebookEditor .notebook-cell { border-color: ${inactiveBorder}; + border-width: 0px; + } + .notebookEditor .notebook-cell.active { + border-width: 1px; + } + .notebookEditor .notebook-cell:hover { border-width: 1px; } `); @@ -41,17 +90,27 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { // Styling with Outline color (e.g. high contrast theme) const outline = theme.getColor(activeContrastBorder); + const hcOutline = theme.getColor(contrastBorder); if (outline) { collector.addRule(` + .hc-black .notebookEditor .notebook-cell:not(.active) code-component { + border-color: ${hcOutline}; + border-width: 0px 0px 1px 0px; + } + .hc-black .notebookEditor .notebook-cell.active code-component { + border-color: ${outline}; + border-width: 0px 0px 1px 0px; + } + .hc-black .notebookEditor .notebook-cell:not(.active) { + outline-color: ${hcOutline}; + outline-width: 1px; + outline-style: solid; + } .notebookEditor .notebook-cell.active { outline-color: ${outline}; outline-width: 1px; outline-style: solid; } - - .notebookEditor .notebook-cell:hover:not(.active) { - outline-style: dashed; - } `); }