mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 17:22:42 -05:00
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.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="width: 100%; height: 100%; display: flex; flex-flow: row">
|
||||
<div style="width: 100%; height: 100%; display: flex; flex-flow: row" (mouseover)="hover=true" (mouseleave)="hover=false">
|
||||
<div #toolbar class="toolbar" style="flex: 0 0 auto; display: flex; flex-flow:column; width: 40px; min-height: 40px; orientation: portrait">
|
||||
</div>
|
||||
<div #editor class="editor" style="flex: 1 1 auto; overflow: hidden;">
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div class="notebook-code" style="flex: 0 0 auto;">
|
||||
<div style="flex: 0 0 auto;">
|
||||
<code-component [cellModel]="cellModel" [model]="model" [activeCellId]="activeCellId"></code-component>
|
||||
</div>
|
||||
<div style="flex: 0 0 auto; width: 100%; height: 100%; display: block">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column" (mouseover)="hover=true" (mouseleave)="hover=false">
|
||||
<loading-spinner [loading]="isLoading"></loading-spinner>
|
||||
<div class="notebook-text" style="flex: 0 0 auto;">
|
||||
<code-component *ngIf="isEditMode" [cellModel]="cellModel" (onContentChanged)="handleContentChanged()" [model]="model" [activeCellId]="activeCellId" [hideVerticalToolbar]=true>
|
||||
|
||||
@@ -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) {
|
||||
(<HTMLElement>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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user