From 4e69eabf52545d22d485ddf502ad8763b11298df Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Tue, 14 Apr 2020 14:13:00 -0700 Subject: [PATCH] UI feature - Notebook markdown toolbar (#9853) * Markdown editor toolbar - initial commit * Moved icons. Refactored new toolbar component to include markup. * Edited markdown toolbar component and referencing in textCell component markup. * Completed UI updates for selected cell toolbar and markdown toolbar. * Modified import path to Event class. Changed EventEmitter to Emitter. * Cleaned up newly added toolbar components * Works sometimes sometimes editor is null * Removed commented out code and styles. CellToolbar and MarkdownToolbar: moved component markup into html file. * Added icon for highlight. Removed more commented code. Re-scoped two styles to their parent components. Corrected templateUrl reference for the new toolbars. * Adjusted paths to SVG icons from toolbar stylesheet. * Add lists and links * Refactor out of component, add actionbar * Support for nothing selected, quick bug fix * Updated split view icons. Added markdown tool backgrounds and cell border colors to color registry and parent components. Updated toolbar icons to use mask as this allows the SVG icon colors to be adjusted on theme change. * Added colorRegistry entries for code cell. Removed colors from styles. Running registerThemingParticipant from code.component. * Revised code component style rules and corrected syntax. * Merged in Chris' working branch and removed unused markup. * Corrected styles and moved another color into colorRegistry for use in new markdown toolbar. * Corrected style error. Overrode left position of content inside textCell and codeCell. Added more entries to colorRegistry. * Moved toolbar and editor icons to common-icons location. Updated related stylesheet. Revised color theming rules for markdown and code cells. * Added themed border between markdown and preview. Moved all notebook themes into notebookStyles.ts * Merged in latest from origin/master and included a small but significant style tweak to light theme code cell toolbar. * Add Undo Support for Markdown Toolbar (#9915) * Remove comment * Renamed registered notebook colors and prefixed with notebook. Moved markdown component theme colors into notebookStyles.ts. Removed colors from cellToolbar styles. Revised icon class names to generic names for better re-use. Removed commented markup. Co-authored-by: chlafreniere Co-authored-by: Chris LaFreniere <40371649+chlafreniere@users.noreply.github.com> --- src/sql/media/icons/chevron_down.svg | 3 + src/sql/media/icons/chevron_down_inverse.svg | 3 + src/sql/media/icons/chevron_up.svg | 3 + src/sql/media/icons/chevron_up_inverse.svg | 3 + src/sql/media/icons/close-blue.svg | 3 + src/sql/media/icons/common-icons.css | 113 ++++++ src/sql/media/icons/down-arrow-blue.svg | 3 + src/sql/media/icons/ellipsis-blue.svg | 3 + src/sql/media/icons/execute_cell.svg | 4 + src/sql/media/icons/execute_cell_dark.svg | 4 + src/sql/media/icons/execute_cell_error.svg | 1 + src/sql/media/icons/execute_cell_grey.svg | 4 + src/sql/media/icons/execute_cell_hc.svg | 4 + .../media/icons/execute_cell_orange_hc.svg | 4 + src/sql/media/icons/execute_cell_white.svg | 4 + src/sql/media/icons/garbage-can-blue.svg | 3 + src/sql/media/icons/new-blue.svg | 3 + .../media/icons/stop_cell_solidanimation.svg | 16 + .../stop_cell_solidanimation_inverse.svg | 16 + src/sql/media/icons/toolbar-bold.svg | 4 + src/sql/media/icons/toolbar-code.svg | 4 + src/sql/media/icons/toolbar-highlight.svg | 4 + src/sql/media/icons/toolbar-image.svg | 4 + src/sql/media/icons/toolbar-italic.svg | 4 + src/sql/media/icons/toolbar-link.svg | 4 + src/sql/media/icons/toolbar-list.svg | 4 + src/sql/media/icons/toolbar-ordered-list.svg | 4 + .../icons/toolbar-preview-toggle-off.svg | 4 + .../media/icons/toolbar-preview-toggle-on.svg | 5 + .../platform/theme/common/colorRegistry.ts | 16 + .../cellViews/cellToolbar.component.html | 15 + .../cellViews/cellToolbar.component.ts | 26 ++ .../browser/cellViews/cellToolbar.css | 47 +++ .../notebook/browser/cellViews/code.css | 81 ++--- .../browser/cellViews/collapse.component.html | 2 +- .../browser/cellViews/collapse.component.ts | 4 +- .../cellViews/markdownToolbar.component.html | 7 + .../cellViews/markdownToolbar.component.ts | 67 ++++ .../browser/cellViews/markdownToolbar.css | 89 +++++ .../cellViews/media/execute_cell_dark.svg | 4 + .../cellViews/media/execute_cell_grey.svg | 4 + .../cellViews/media/execute_cell_hc.svg | 4 + .../cellViews/media/light/execute_cell.svg | 2 +- .../media/light/execute_cell_grey.svg | 1 + .../browser/cellViews/media/toolbar-bold.svg | 4 + .../browser/cellViews/media/toolbar-code.svg | 4 + .../cellViews/media/toolbar-highlight.svg | 4 + .../browser/cellViews/media/toolbar-image.svg | 4 + .../cellViews/media/toolbar-italic.svg | 4 + .../browser/cellViews/media/toolbar-link.svg | 4 + .../browser/cellViews/media/toolbar-list.svg | 4 + .../cellViews/media/toolbar-ordered-list.svg | 4 + .../media/toolbar-preview-toggle-off.svg | 4 + .../media/toolbar-preview-toggle-on.svg | 5 + .../browser/cellViews/textCell.component.html | 1 + .../browser/cellViews/textCell.component.ts | 1 - .../notebook/browser/cellViews/textCell.css | 16 + .../browser/markdownToolbarActions.ts | 344 ++++++++++++++++++ .../notebook/browser/notebook.component.html | 22 -- .../contrib/notebook/browser/notebook.css | 16 +- .../notebook/browser/notebook.module.ts | 4 + .../notebook/browser/notebookStyles.ts | 172 ++++----- 62 files changed, 1035 insertions(+), 189 deletions(-) create mode 100644 src/sql/media/icons/chevron_down.svg create mode 100644 src/sql/media/icons/chevron_down_inverse.svg create mode 100644 src/sql/media/icons/chevron_up.svg create mode 100644 src/sql/media/icons/chevron_up_inverse.svg create mode 100644 src/sql/media/icons/close-blue.svg create mode 100644 src/sql/media/icons/down-arrow-blue.svg create mode 100644 src/sql/media/icons/ellipsis-blue.svg create mode 100644 src/sql/media/icons/execute_cell.svg create mode 100644 src/sql/media/icons/execute_cell_dark.svg create mode 100644 src/sql/media/icons/execute_cell_error.svg create mode 100644 src/sql/media/icons/execute_cell_grey.svg create mode 100644 src/sql/media/icons/execute_cell_hc.svg create mode 100644 src/sql/media/icons/execute_cell_orange_hc.svg create mode 100644 src/sql/media/icons/execute_cell_white.svg create mode 100644 src/sql/media/icons/garbage-can-blue.svg create mode 100644 src/sql/media/icons/new-blue.svg create mode 100644 src/sql/media/icons/stop_cell_solidanimation.svg create mode 100644 src/sql/media/icons/stop_cell_solidanimation_inverse.svg create mode 100644 src/sql/media/icons/toolbar-bold.svg create mode 100644 src/sql/media/icons/toolbar-code.svg create mode 100644 src/sql/media/icons/toolbar-highlight.svg create mode 100644 src/sql/media/icons/toolbar-image.svg create mode 100644 src/sql/media/icons/toolbar-italic.svg create mode 100644 src/sql/media/icons/toolbar-link.svg create mode 100644 src/sql/media/icons/toolbar-list.svg create mode 100644 src/sql/media/icons/toolbar-ordered-list.svg create mode 100644 src/sql/media/icons/toolbar-preview-toggle-off.svg create mode 100644 src/sql/media/icons/toolbar-preview-toggle-on.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.html create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.ts create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.css create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.html create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.ts create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.css create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_dark.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_grey.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_hc.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell_grey.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-bold.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-code.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-highlight.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-image.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-italic.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-link.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-list.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-ordered-list.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-off.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-on.svg create mode 100644 src/sql/workbench/contrib/notebook/browser/markdownToolbarActions.ts diff --git a/src/sql/media/icons/chevron_down.svg b/src/sql/media/icons/chevron_down.svg new file mode 100644 index 0000000000..3a454b37ab --- /dev/null +++ b/src/sql/media/icons/chevron_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/chevron_down_inverse.svg b/src/sql/media/icons/chevron_down_inverse.svg new file mode 100644 index 0000000000..b09a9f4e6e --- /dev/null +++ b/src/sql/media/icons/chevron_down_inverse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/chevron_up.svg b/src/sql/media/icons/chevron_up.svg new file mode 100644 index 0000000000..b3fbc2bbe6 --- /dev/null +++ b/src/sql/media/icons/chevron_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/chevron_up_inverse.svg b/src/sql/media/icons/chevron_up_inverse.svg new file mode 100644 index 0000000000..f59d76d752 --- /dev/null +++ b/src/sql/media/icons/chevron_up_inverse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/close-blue.svg b/src/sql/media/icons/close-blue.svg new file mode 100644 index 0000000000..44dcff7ea9 --- /dev/null +++ b/src/sql/media/icons/close-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/common-icons.css b/src/sql/media/icons/common-icons.css index b8c6d54340..1a0b985de0 100644 --- a/src/sql/media/icons/common-icons.css +++ b/src/sql/media/icons/common-icons.css @@ -278,6 +278,119 @@ background-image: url('stop_inverse.svg') } +/* Notebook cells */ +.codicon.toolbarIconRunInactive { + background-image: url('execute_cell_grey.svg'); +} +.codicon.toolbarIconRun { + background-image: url('execute_cell.svg'); +} +.codicon.toolbarIconRunError { + background-image: url('execute_cell_error.svg'); +} +.codicon.toolbarIconStop { + background-image: url('stop_cell_solidanimation.svg'); +} +.vs-dark .codicon.toolbarIconRunInactive { + background-image: url('execute_cell_dark.svg'); +} +.vs-dark .codicon.toolbarIconRun { + background-image: url('execute_cell_white.svg'); +} +.hc-black .codicon.toolbarIconRunInactive { + background-image: url('execute_cell_hc.svg'); +} +.hc-black .codicon.toolbarIconRun { + background-image: url('execute_cell_orange_hc.svg'); +} +.vs-dark .codicon.toolbarIconStop, +.hc-black .codicon.toolbarIconStop { + background-image: url('stop_cell_solidanimation_inverse.svg'); +} + +.codicon.arrow-up { + background-image: url("chevron_up.svg"); +} +.vs-dark .codicon.arrow-up, +.hc-black .codicon.arrow-up { + background-image: url("chevron_up_inverse.svg"); +} + +.codicon.arrow-down { + background-image: url("chevron_down.svg"); +} +.vs-dark .codicon.arrow-down, +.hc-black .codicon.arrow-down { + background-image: url("chevron_down_inverse.svg"); +} + +/* Icons as masked elements for easy theme switching */ +.codicon.bold { + -webkit-mask-image: url('toolbar-bold.svg'); + mask-image: url('toolbar-bold.svg'); +} +.codicon.italic { + -webkit-mask-image: url('toolbar-italic.svg'); + mask-image: url('toolbar-italic.svg'); +} +.codicon.highlight { + -webkit-mask-image: url('toolbar-highlight.svg'); + mask-image: url('toolbar-highlight.svg'); +} +.codicon.code { + -webkit-mask-image: url('toolbar-code.svg'); + mask-image: url('toolbar-code.svg'); +} +.codicon.insert-link { + -webkit-mask-image: url('toolbar-link.svg'); + mask-image: url('toolbar-link.svg'); +} +.codicon.list { + -webkit-mask-image: url('toolbar-list.svg'); + mask-image: url('toolbar-list.svg'); +} +.codicon.ordered-list { + -webkit-mask-image: url('toolbar-ordered-list.svg'); + mask-image: url('toolbar-ordered-list.svg'); +} +.codicon.insert-image { + -webkit-mask-image: url('toolbar-image.svg'); + mask-image: url('toolbar-image.svg'); +} +.codicon.split-toggle-on { + -webkit-mask-image: url('toolbar-preview-toggle-on.svg'); + mask-image: url('toolbar-preview-toggle-on.svg'); +} +.codicon.split-toggle-off { + -webkit-mask-image: url('toolbar-preview-toggle-off.svg'); + mask-image: url('toolbar-preview-toggle-off.svg'); +} + +/* Cell toolbar icons */ +.cell-tool-close { + background-image: url('close-blue.svg'); +} +.cell-tool-edit { + background-image: url('edit.svg'); +} +.cell-tool-add { + background-image: url('new-blue.svg'); +} +.cell-tool-move-up { + background-image: url('down-arrow-blue.svg'); + transform: scale(-1); +} +.cell-tool-move-down { + background-image: url('down-arrow-blue.svg'); +} +.cell-tool-delete { + background-image: url('garbage-can-blue.svg'); +} +.cell-tool-more { + background-image: url('ellipsis-blue.svg'); +} + + .small { width: 16px; height: 16px; diff --git a/src/sql/media/icons/down-arrow-blue.svg b/src/sql/media/icons/down-arrow-blue.svg new file mode 100644 index 0000000000..fc472f1410 --- /dev/null +++ b/src/sql/media/icons/down-arrow-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/ellipsis-blue.svg b/src/sql/media/icons/ellipsis-blue.svg new file mode 100644 index 0000000000..0c6d78f456 --- /dev/null +++ b/src/sql/media/icons/ellipsis-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/execute_cell.svg b/src/sql/media/icons/execute_cell.svg new file mode 100644 index 0000000000..d83854d930 --- /dev/null +++ b/src/sql/media/icons/execute_cell.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/execute_cell_dark.svg b/src/sql/media/icons/execute_cell_dark.svg new file mode 100644 index 0000000000..b4d7cac08c --- /dev/null +++ b/src/sql/media/icons/execute_cell_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/execute_cell_error.svg b/src/sql/media/icons/execute_cell_error.svg new file mode 100644 index 0000000000..03de5943ed --- /dev/null +++ b/src/sql/media/icons/execute_cell_error.svg @@ -0,0 +1 @@ +execute_cell_error \ No newline at end of file diff --git a/src/sql/media/icons/execute_cell_grey.svg b/src/sql/media/icons/execute_cell_grey.svg new file mode 100644 index 0000000000..6e4c627a97 --- /dev/null +++ b/src/sql/media/icons/execute_cell_grey.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/execute_cell_hc.svg b/src/sql/media/icons/execute_cell_hc.svg new file mode 100644 index 0000000000..d1ffb0988f --- /dev/null +++ b/src/sql/media/icons/execute_cell_hc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/execute_cell_orange_hc.svg b/src/sql/media/icons/execute_cell_orange_hc.svg new file mode 100644 index 0000000000..afb33e8cdf --- /dev/null +++ b/src/sql/media/icons/execute_cell_orange_hc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/execute_cell_white.svg b/src/sql/media/icons/execute_cell_white.svg new file mode 100644 index 0000000000..0af50fc2b8 --- /dev/null +++ b/src/sql/media/icons/execute_cell_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/media/icons/garbage-can-blue.svg b/src/sql/media/icons/garbage-can-blue.svg new file mode 100644 index 0000000000..ab482a4fff --- /dev/null +++ b/src/sql/media/icons/garbage-can-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/new-blue.svg b/src/sql/media/icons/new-blue.svg new file mode 100644 index 0000000000..0ebe28953d --- /dev/null +++ b/src/sql/media/icons/new-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/media/icons/stop_cell_solidanimation.svg b/src/sql/media/icons/stop_cell_solidanimation.svg new file mode 100644 index 0000000000..38b4eaac4c --- /dev/null +++ b/src/sql/media/icons/stop_cell_solidanimation.svg @@ -0,0 +1,16 @@ + + +stop_cell_solidanimation + + + + + + \ No newline at end of file diff --git a/src/sql/media/icons/stop_cell_solidanimation_inverse.svg b/src/sql/media/icons/stop_cell_solidanimation_inverse.svg new file mode 100644 index 0000000000..1a3943d55d --- /dev/null +++ b/src/sql/media/icons/stop_cell_solidanimation_inverse.svg @@ -0,0 +1,16 @@ + + +stop_cell_solidanimation_inverse + + + + + + \ No newline at end of file diff --git a/src/sql/media/icons/toolbar-bold.svg b/src/sql/media/icons/toolbar-bold.svg new file mode 100644 index 0000000000..8cb47f4d5b --- /dev/null +++ b/src/sql/media/icons/toolbar-bold.svg @@ -0,0 +1,4 @@ + +bold + + diff --git a/src/sql/media/icons/toolbar-code.svg b/src/sql/media/icons/toolbar-code.svg new file mode 100644 index 0000000000..44ede8af94 --- /dev/null +++ b/src/sql/media/icons/toolbar-code.svg @@ -0,0 +1,4 @@ + +preformatted + + diff --git a/src/sql/media/icons/toolbar-highlight.svg b/src/sql/media/icons/toolbar-highlight.svg new file mode 100644 index 0000000000..e235385408 --- /dev/null +++ b/src/sql/media/icons/toolbar-highlight.svg @@ -0,0 +1,4 @@ + +highlight + + diff --git a/src/sql/media/icons/toolbar-image.svg b/src/sql/media/icons/toolbar-image.svg new file mode 100644 index 0000000000..df9c8276b0 --- /dev/null +++ b/src/sql/media/icons/toolbar-image.svg @@ -0,0 +1,4 @@ + +add inline image + + diff --git a/src/sql/media/icons/toolbar-italic.svg b/src/sql/media/icons/toolbar-italic.svg new file mode 100644 index 0000000000..6cfd388eb5 --- /dev/null +++ b/src/sql/media/icons/toolbar-italic.svg @@ -0,0 +1,4 @@ + +italics + + diff --git a/src/sql/media/icons/toolbar-link.svg b/src/sql/media/icons/toolbar-link.svg new file mode 100644 index 0000000000..d4da1b11e2 --- /dev/null +++ b/src/sql/media/icons/toolbar-link.svg @@ -0,0 +1,4 @@ + +link + + diff --git a/src/sql/media/icons/toolbar-list.svg b/src/sql/media/icons/toolbar-list.svg new file mode 100644 index 0000000000..59bb14a7ce --- /dev/null +++ b/src/sql/media/icons/toolbar-list.svg @@ -0,0 +1,4 @@ + +unordered list + + diff --git a/src/sql/media/icons/toolbar-ordered-list.svg b/src/sql/media/icons/toolbar-ordered-list.svg new file mode 100644 index 0000000000..60158dff0c --- /dev/null +++ b/src/sql/media/icons/toolbar-ordered-list.svg @@ -0,0 +1,4 @@ + +Ordered list + + diff --git a/src/sql/media/icons/toolbar-preview-toggle-off.svg b/src/sql/media/icons/toolbar-preview-toggle-off.svg new file mode 100644 index 0000000000..b5a8538ea6 --- /dev/null +++ b/src/sql/media/icons/toolbar-preview-toggle-off.svg @@ -0,0 +1,4 @@ + +markdown preview toggle - off + + diff --git a/src/sql/media/icons/toolbar-preview-toggle-on.svg b/src/sql/media/icons/toolbar-preview-toggle-on.svg new file mode 100644 index 0000000000..9294a58edc --- /dev/null +++ b/src/sql/media/icons/toolbar-preview-toggle-on.svg @@ -0,0 +1,5 @@ + +markdown preview toggle - on + + + diff --git a/src/sql/platform/theme/common/colorRegistry.ts b/src/sql/platform/theme/common/colorRegistry.ts index f6814a52f0..296055663c 100644 --- a/src/sql/platform/theme/common/colorRegistry.ts +++ b/src/sql/platform/theme/common/colorRegistry.ts @@ -41,4 +41,20 @@ export const gradientOne = registerColor('gradientOne', { light: '#f0f0f0', dark export const gradientTwo = registerColor('gradientTwo', { light: gradientTwoColorOne, dark: gradientTwoColorTwo, hc: gradientTwoColorTwo }, nls.localize('gradientTwo', "The bottom color for the banner image gradient")); export const gradientBackground = registerColor('gradientBackground', { light: '#fff', dark: 'transparent', hc: 'transparent' }, nls.localize('gradientBackground', "The background color for the banner image gradient")); +// --- Notebook Colors +export const toolbarBackground = registerColor('notebook.toolbarBackground', { light: '#F5F5F5', dark: '#252423', hc: '#000000' }, nls.localize('notebook.toolbarBackground', "Notebook: Markdown toolbar background")); +export const toolbarIcon = registerColor('notebook.toolbarIcon', { light: '#323130', dark: '#FFFFFe', hc: '#FFFFFe' }, nls.localize('notebook.toolbarIcon', "Notebook: Markdown toolbar icons")); +export const toolbarBottomBorder = registerColor('notebook.toolbarBottomBorder', { light: '#D4D4D4', dark: '#323130', hc: '#E86E58' }, nls.localize('notebook.toolbarBottomBorder', "Notebook: Markdown toolbar bottom border")); +// Notebook: All cells +export const cellBorder = registerColor('notebook.cellBorder', { light: '#0078D4', dark: '#0078D4', hc: '#E86E58' }, nls.localize('notebook.cellBorder', "Notebook: Active cell border")); +// Notebook: Markdown cell +export const markdownEditorBackground = registerColor('notebook.markdownEditorBackground', { light: '#FFFFFe', dark: '#1B1A19', hc: '#000000' }, nls.localize('notebook.markdownEditorBackground', "Notebook: Markdown editor background")); +export const splitBorder = registerColor('notebook.splitBorder', { light: '#E6E6E6', dark: '#323130', hc: '#872412' }, nls.localize('notebook.splitBorder', "Notebook: Border between Markdown editor and preview")); +// Notebook: Code cell +export const codeEditorBackground = registerColor('notebook.codeEditorBackground', { light: '#F5F5F5', dark: '#333333', hc: '#000000' }, nls.localize('notebook.codeEditorBackground', "Notebook: Code editor background")); +export const codeEditorBackgroundActive = registerColor('notebook.codeEditorBackgroundActive', { light: '#FFFFFe', dark: null, hc: null }, nls.localize('notebook.codeEditorBackgroundActive', "Notebook: Code editor background of active cell")); +export const codeEditorLineNumber = registerColor('notebook.codeEditorLineNumber', { light: '#A19F9D', dark: '#A19F9D', hc: '#FFFFFe' }, nls.localize('notebook.codeEditorLineNumber', "Notebook: Code editor line numbers")); +export const codeEditorToolbarIcon = registerColor('notebook.codeEditorToolbarIcon', { light: '#999999', dark: '#A19F9D', hc: '#FFFFFe' }, nls.localize('notebook.codeEditorToolbarIcon', "Notebook: Code editor toolbar icons")); +export const codeEditorToolbarBackground = registerColor('notebook.codeEditorToolbarBackground', { light: '#EEEEEE', dark: '#333333', hc: '#000000' }, nls.localize('notebook.codeEditorToolbarBackground', "Notebook: Code editor toolbar background")); +export const codeEditorToolbarBorder = registerColor('notebook.codeEditorToolbarBorder', { light: '#C8C6C4', dark: '#333333', hc: '#000000' }, nls.localize('notebook.codeEditorToolbarBorder', "Notebook: Code editor toolbar right border")); diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.html b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.html new file mode 100644 index 0000000000..43bea07c7f --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.html @@ -0,0 +1,15 @@ + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.ts new file mode 100644 index 0000000000..28e07d8aa1 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * 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!./cellToolbar'; + +import { Component } from '@angular/core'; +import { localize } from 'vs/nls'; + +export const CELL_TOOLBAR_SELECTOR: string = 'cell-toolbar-component'; + +@Component({ + selector: CELL_TOOLBAR_SELECTOR, + templateUrl: decodeURI(require.toUrl('./cellToolbar.component.html')) +}) +export class CellToolbarComponent { + public buttonEdit = localize('buttonEdit', "Edit"); + public buttonClose = localize('buttonClose', "Close"); + public buttonAdd = localize('buttonAdd', "Add new cell"); + public buttonMoveDown = localize('buttonMoveDown', "Move cell down"); + public buttonMoveUp = localize('buttonMoveUp', "Move cell up"); + public buttonDelete = localize('buttonDelete', "Delete cell"); + + constructor() { + } +} diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.css b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.css new file mode 100644 index 0000000000..68bf5e2cf9 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.css @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +cell-toolbar-component { + position: absolute; + left: 25px; + top: -21px; +} + +cell-toolbar-component ul { + display: inline-block; + list-style: none; + margin: 0; + padding: 5px 10px 0 10px; +} + +cell-toolbar-component li { + display: inline-block; + margin-right: 4px; + text-align: center; +} + +cell-toolbar-component li:last-child { + margin-right: 0; +} + +cell-toolbar-component li a { + background: 50% 50% no-repeat; + display: block; + height: 16px; + width: 16px; +} + +cell-toolbar-component li div { + background: 50% 50% no-repeat; + height: 16px; + width: 16px; +} + +cell-toolbar-component .offscreen { + height: 1px; + text-indent: -999999px; + margin-top: -1px; + position: absolute; +} diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/code.css b/src/sql/workbench/contrib/notebook/browser/cellViews/code.css index 3a51cbf1f1..d1ebc48294 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/code.css +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/code.css @@ -9,14 +9,20 @@ code-component { display: block; } +.notebook-cell:not(.active) code-component .toolbar { + border-right-color: transparent!important; +} + code-component .toolbar { + border-right-style: solid; border-right-width: 1px; - flex: 0 0 auto; + box-sizing: border-box; display: flex; + flex: 0 0 auto; flex-flow:column; - width: 40px; min-height: 40px; - orientation: portrait + orientation: portrait; + width: 52px; } code-component .toolbar.markdown { @@ -29,36 +35,37 @@ code-component .toolbar .carbon-taskbar { margin-top: 5px; } -code-component .toolbarIconRun { +code-component .toolbar .codicon { height: 20px; - background-image: url('./media/light/execute_cell.svg'); padding-bottom: 10px; } -.vs-dark code-component .toolbarIconRun, -.hc-black code-component .toolbarIconRun { - background-image: url('./media/dark/execute_cell_inverse.svg'); +.notebook-cell:not(.active):hover code-component .toolbarIconRun { + background-image: url('./media/execute_cell_grey.svg'); } - -code-component .toolbarIconRunError { - height: 20px; - background-image: url('./media/light/execute_cell_error.svg'); - padding-bottom: 10px; +.vs-dark .notebook-cell:not(.active):hover code-component .toolbarIconRun { + background-image: url('./media/execute_cell_dark.svg'); } - -code-component .toolbarIconStop { - height: 20px; - background-image: url('./media/light/stop_cell_solidanimation.svg'); - padding-bottom: 10px; -} - -.vs-dark code-component .toolbarIconStop, -.hc-black code-component .toolbarIconStop { - background-image: url('./media/dark/stop_cell_solidanimation_inverse.svg'); +.hc-black .notebook-cell:not(.active):hover code-component .toolbarIconRun { + background-image: url('./media/execute_cell_hc.svg'); } code-component .editor { - padding: 5px 0px 5px 0px + margin: 14px 0px 5px 0px +} + +code-cell-component code-component .monaco-editor .margin-view-overlays .line-numbers { + left: 0!important; +} +code-cell-component code-component .monaco-scrollable-element.editor-scrollable.vs { + left: 40px!important; +} + +code-cell-component .monaco-editor .margin, +code-cell-component code-component .monaco-editor, +code-cell-component code-component .monaco-editor-background, +code-cell-component code-component .monaco-editor .inputarea.ime-input { + background-color: transparent; } /* overview ruler */ @@ -84,7 +91,7 @@ code-component .carbon-taskbar .codicon.hideIcon { padding-left: 0px; padding-top: 6px; font-family: monospace; - font-size: 12px; + font-size: 14px; } code-component .carbon-taskbar .codicon.hideIcon.execCountTen { @@ -95,10 +102,6 @@ code-component .carbon-taskbar .codicon.hideIcon.execCountHundred { margin-left: -6px; } -code-component .carbon-taskbar.monaco-toolbar .monaco-action-bar.animated .actions-container { - padding-left: 10px -} - code-component .hide-component-button { height: 16px; width: 100%; @@ -106,23 +109,5 @@ code-component .hide-component-button { border-width: 0px; background-repeat: no-repeat; background-position: center; - background-color: inherit; -} - -code-component .hide-component-button.icon-hide-cell { - background-image: url("./media/light/chevron_up.svg"); -} - -code-component .hide-component-button.icon-show-cell { - background-image: url("./media/light/chevron_down.svg"); -} - -.vs-dark code-component .hide-component-button.icon-hide-cell, -.hc-black code-component .hide-component-button.icon-hide-cell { - background-image: url("./media/dark/chevron_up_inverse.svg"); -} - -.vs-dark code-component .hide-component-button.icon-show-cell, -.hc-black code-component .hide-component-button.icon-show-cell { - background-image: url("./media/dark/chevron_down_inverse.svg"); + background-color: transparent; } diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.html b/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.html index 0a5d144eb1..73fcf69d1e 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.html +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.html @@ -5,5 +5,5 @@ *--------------------------------------------------------------------------------------------*/ -->
- +
diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.ts index 6a9ef95efa..32745c21d0 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/collapse.component.ts @@ -20,10 +20,10 @@ export class CollapseComponent extends CellView implements OnInit, OnChanges { @ViewChild('collapseCellButton', { read: ElementRef }) private collapseCellButtonElement: ElementRef; private readonly expandButtonTitle = localize('expandCellContents', "Expand code cell contents"); - private readonly expandButtonClass = 'icon-show-cell'; + private readonly expandButtonClass = 'arrow-down'; private readonly collapseButtonTitle = localize('collapseCellContents', "Collapse code cell contents"); - private readonly collapseButtonClass = 'icon-hide-cell'; + private readonly collapseButtonClass = 'arrow-up'; @Input() cellModel: ICellModel; @Input() activeCellId: string; diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.html b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.html new file mode 100644 index 0000000000..3a80f4cc3a --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.html @@ -0,0 +1,7 @@ + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.ts new file mode 100644 index 0000000000..ed9cf102ab --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * 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!./markdownToolbar'; +import { Component, Input, Inject, ViewChild, ElementRef } from '@angular/core'; +import { localize } from 'vs/nls'; +import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces'; +import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar'; +import { TransformMarkdownAction, MarkdownButtonType } from 'sql/workbench/contrib/notebook/browser/markdownToolbarActions'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; + +export const MARKDOWN_TOOLBAR_SELECTOR: string = 'markdown-toolbar-component'; + +@Component({ + selector: MARKDOWN_TOOLBAR_SELECTOR, + templateUrl: decodeURI(require.toUrl('./markdownToolbar.component.html')) +}) +export class MarkdownToolbarComponent { + @ViewChild('mdtoolbar', { read: ElementRef }) private mdtoolbar: ElementRef; + + public buttonBold = localize('buttonBold', "Bold"); + public buttonItalic = localize('buttonItalic', "Italic"); + public buttonHighlight = localize('buttonHighlight', "Highlight"); + public buttonCode = localize('buttonCode', "Code"); + public buttonLink = localize('buttonLink', "Link"); + public buttonList = localize('buttonList', "List"); + public buttonOrderedList = localize('buttonOrderedList', "Ordered list"); + public buttonImage = localize('buttonImage', "Image"); + public buttonPreview = localize('buttonPreview', "Markdown preview toggle - off"); + + @Input() public cellModel: ICellModel; + private _actionBar: Taskbar; + + constructor( + @Inject(IInstantiationService) private _instantiationService: IInstantiationService + ) { } + + ngOnInit() { + this.initActionBar(); + } + + private initActionBar() { + let boldButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.boldText', '', 'bold', this.buttonBold, this.cellModel, MarkdownButtonType.BOLD); + let italicButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.italicText', '', 'italic', this.buttonItalic, this.cellModel, MarkdownButtonType.ITALIC); + let highlightButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.highlightText', '', 'highlight', this.buttonHighlight, this.cellModel, MarkdownButtonType.HIGHLIGHT); + let codeButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.codeText', '', 'code', this.buttonCode, this.cellModel, MarkdownButtonType.CODE); + let linkButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.linkText', '', 'insert-link', this.buttonLink, this.cellModel, MarkdownButtonType.LINK); + let listButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.listText', '', 'list', this.buttonList, this.cellModel, MarkdownButtonType.UNORDERED_LIST); + let orderedListButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.orderedText', '', 'ordered-list', this.buttonOrderedList, this.cellModel, MarkdownButtonType.ORDERED_LIST); + let imageButton = this._instantiationService.createInstance(TransformMarkdownAction, 'notebook.imageText', '', 'insert-image', this.buttonImage, this.cellModel, MarkdownButtonType.IMAGE); + + let taskbar = this.mdtoolbar.nativeElement; + this._actionBar = new Taskbar(taskbar); + this._actionBar.context = this; + this._actionBar.setContent([ + { action: boldButton }, + { action: italicButton }, + { action: highlightButton }, + { action: codeButton }, + { action: linkButton }, + { action: listButton }, + { action: orderedListButton }, + { action: imageButton } + ]); + } +} diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.css b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.css new file mode 100644 index 0000000000..3a37406edd --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.css @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/* Resets */ +.markdown-toolbar .carbon-taskbar li a.action-label { + margin: 0; + padding: 0; +} +.markdown-toolbar .carbon-taskbar.monaco-toolbar .monaco-action-bar.animated .actions-container { + padding: 0; +} + + +.markdown-toolbar { + border-bottom-width: 1px; + border-bottom-style: solid; + display: block; + list-style: none; + margin: 0; + padding: 4px 16px; +} +.markdown-toolbar .carbon-taskbar li.action-item { + display: inline-block; + margin-right: 14px; +} +.markdown-toolbar .carbon-taskbar li:nth-child(1) { + margin-right: 9px; +} +.markdown-toolbar .carbon-taskbar li:nth-child(2) { + margin-right: 9px; +} +.markdown-toolbar .carbon-taskbar li a { + display: inline-block; + height: 20px; + width: 20px; + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + mask-position: center; + mask-repeat: no-repeat; +} + +.markdown-toolbar li a.codicon.bold { + -webkit-mask-size: 50% 100%; + mask-size: 50% 100%; +} +.markdown-toolbar li a.codicon.italic { + -webkit-mask-size: 60% 100%; + mask-size: 60% 100%; +} +.markdown-toolbar li a.codicon.highlight { + -webkit-mask-size: 65% 100%; + mask-size: 65% 100%; +} +.markdown-toolbar li a.codicon.code { + -webkit-mask-size: 88% 100%; + mask-size: 88% 100%; +} +.markdown-toolbar li a.codicon.insert-link { + -webkit-mask-size: 80% 100%; + mask-size: 80% 100%; +} +.markdown-toolbar li a.codicon.list { + -webkit-mask-size: 80% 100%; + mask-size: 80% 100%; +} +.markdown-toolbar li a.codicon.ordered-list { + -webkit-mask-size: 86% 100%; + mask-size: 86% 100%; +} +.markdown-toolbar li a.codicon.insertimage { + -webkit-mask-size: 86% 100%; + mask-size: 86% 100%; +} +.markdown-toolbar li a.codicon.split-toggle-on { + -webkit-mask-size: 75% 100%; + mask-size: 75% 100%; +} +.markdown-toolbar li a.codicon.split-toggle-off { + -webkit-mask-size: 75% 100%; + mask-size: 75% 100%; +} + +text-cell-component .offscreen { + height: 1px; + margin-top: -1px; + position: absolute; + text-indent: -999999px; +} diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_dark.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_dark.svg new file mode 100644 index 0000000000..b4d7cac08c --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_grey.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_grey.svg new file mode 100644 index 0000000000..6e4c627a97 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_grey.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_hc.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_hc.svg new file mode 100644 index 0000000000..d1ffb0988f --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/execute_cell_hc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell.svg index 2a8f889c1e..9b4c857179 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell.svg +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell.svg @@ -1 +1 @@ -execute_cell \ No newline at end of file +execute_cell diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell_grey.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell_grey.svg new file mode 100644 index 0000000000..e1d4ff5773 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/light/execute_cell_grey.svg @@ -0,0 +1 @@ +execute_cell diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-bold.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-bold.svg new file mode 100644 index 0000000000..8cb47f4d5b --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-bold.svg @@ -0,0 +1,4 @@ + +bold + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-code.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-code.svg new file mode 100644 index 0000000000..44ede8af94 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-code.svg @@ -0,0 +1,4 @@ + +preformatted + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-highlight.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-highlight.svg new file mode 100644 index 0000000000..e235385408 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-highlight.svg @@ -0,0 +1,4 @@ + +highlight + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-image.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-image.svg new file mode 100644 index 0000000000..df9c8276b0 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-image.svg @@ -0,0 +1,4 @@ + +add inline image + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-italic.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-italic.svg new file mode 100644 index 0000000000..6cfd388eb5 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-italic.svg @@ -0,0 +1,4 @@ + +italics + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-link.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-link.svg new file mode 100644 index 0000000000..d4da1b11e2 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-link.svg @@ -0,0 +1,4 @@ + +link + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-list.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-list.svg new file mode 100644 index 0000000000..59bb14a7ce --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-list.svg @@ -0,0 +1,4 @@ + +unordered list + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-ordered-list.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-ordered-list.svg new file mode 100644 index 0000000000..60158dff0c --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-ordered-list.svg @@ -0,0 +1,4 @@ + +Ordered list + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-off.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-off.svg new file mode 100644 index 0000000000..b5a8538ea6 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-off.svg @@ -0,0 +1,4 @@ + +markdown preview toggle - off + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-on.svg b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-on.svg new file mode 100644 index 0000000000..9294a58edc --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/media/toolbar-preview-toggle-on.svg @@ -0,0 +1,5 @@ + +markdown preview toggle - on + + + diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.html b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.html index 72604439b1..9603ca29c3 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.html +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.html @@ -5,6 +5,7 @@ *--------------------------------------------------------------------------------------------*/ -->
+
diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts index b58d8d8fee..081e78d255 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts @@ -31,7 +31,6 @@ import { IColorTheme } from 'vs/platform/theme/common/themeService'; export const TEXT_SELECTOR: string = 'text-cell-component'; const USER_SELECT_CLASS = 'actionselect'; - @Component({ selector: TEXT_SELECTOR, templateUrl: decodeURI(require.toUrl('./textCell.component.html')) diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.css b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.css index 236b314921..c03714eb82 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.css +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.css @@ -7,6 +7,12 @@ text-cell-component { display: block; } +.notebookEditor .notebook-cell.active text-cell-component code-component { + border-color: transparent; + border-bottom-width: 1px; + border-style: solid; +} + text-cell-component .notebook-preview { user-select: none; padding-left: 8px; @@ -17,6 +23,16 @@ text-cell-component .notebook-preview { user-select: text; } +text-cell-component code-component .monaco-scrollable-element.editor-scrollable.vs { + left: 16px!important; +} +text-cell-component .monaco-editor .margin, +text-cell-component code-component .monaco-editor, +text-cell-component code-component .monaco-editor-background, +text-cell-component code-component .monaco-editor .inputarea.ime-input { + background-color: transparent; +} + .vs .notebook-preview .rangeHighlight { background-color: rgba(255, 255, 0, 0.2) } diff --git a/src/sql/workbench/contrib/notebook/browser/markdownToolbarActions.ts b/src/sql/workbench/contrib/notebook/browser/markdownToolbarActions.ts new file mode 100644 index 0000000000..257ed782e7 --- /dev/null +++ b/src/sql/workbench/contrib/notebook/browser/markdownToolbarActions.ts @@ -0,0 +1,344 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Action } from 'vs/base/common/actions'; + +import { INotebookEditor, INotebookService } from 'sql/workbench/services/notebook/browser/notebookService'; +import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; +import { IRange } from 'vs/editor/common/core/range'; +import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces'; +import { QueryTextEditor } from 'sql/workbench/browser/modelComponents/queryTextEditor'; +import { Selection } from 'vs/editor/common/core/selection'; + + + +// Action to decorate markdown +export class TransformMarkdownAction extends Action { + + constructor( + id: string, + label: string, + cssClass: string, + tooltip: string, + private _cellModel: ICellModel, + private _type: MarkdownButtonType, + @INotebookService private _notebookService: INotebookService + ) { + super(id, label, cssClass); + this._tooltip = tooltip; + } + public run(context: any): Promise { + return new Promise((resolve, reject) => { + try { + let markdownTextTransformer = new MarkdownTextTransformer(this._notebookService, this._cellModel); + markdownTextTransformer.transformText(this._type); + resolve(true); + } catch (e) { + reject(e); + } + }); + } +} + +export class MarkdownTextTransformer { + + private _notebookEditor: INotebookEditor; + constructor(private _notebookService: INotebookService, private _cellModel: ICellModel) { } + + public transformText(type: MarkdownButtonType): void { + let editorControl = this.getEditorControl(); + if (editorControl) { + let selections = editorControl.getSelections(); + // TODO: Support replacement for multiple selections + let selection = selections[0]; + let nothingSelected = this.editorHasNoSelection(selection); + let startRange: IRange = { + startColumn: selection.startColumn, + endColumn: selection.startColumn, + startLineNumber: selection.startLineNumber, + endLineNumber: selection.startLineNumber + }; + + // Get text to insert before selection + let beginInsertedCode = this.getStartTextToInsert(type); + // Get text to insert after selection + let endInsertedCode = this.getEndTextToInsert(type); + + // endInsertedCode can be an empty string (e.g. for unordered list), so no need to check for that as well + if (beginInsertedCode) { + let endRange: IRange = { + startColumn: selection.endColumn, + endColumn: selection.endColumn, + startLineNumber: selection.endLineNumber, + endLineNumber: selection.endLineNumber + }; + let editorModel = editorControl.getModel() as TextModel; + let isUndo = false; + if (editorModel) { + let markdownLineType = this.getMarkdownLineType(type); + isUndo = this.isUndoOperation(selection, type, markdownLineType, editorModel); + if (isUndo) { + if (markdownLineType === MarkdownLineType.BEGIN_AND_END_LINES) { + startRange = this.getIRangeWithOffsets(startRange, -1 * beginInsertedCode.length, 0, 0, 0); + endRange = this.getIRangeWithOffsets(endRange, 0, 0, endInsertedCode.length, 0); + editorModel.pushEditOperations(selections, [{ range: endRange, text: '' }, { range: startRange, text: '' }], null); + } else { + let operations: IIdentifiedSingleEditOperation[] = []; + startRange = this.getIRangeWithOffsets(startRange, 0, 0, beginInsertedCode.length, 0); + for (let i = 0; i < selection.endLineNumber - selection.startLineNumber + 1; i++) { + operations.push({ range: this.transformRangeByLineOffset(startRange, i), text: '' }); + } + editorModel.pushEditOperations(selections, operations, null); + } + } else { + // If the markdown we're inserting only needs to be added to the begin and end lines, add those edit operations directly + if (markdownLineType === MarkdownLineType.BEGIN_AND_END_LINES) { + editorModel.pushEditOperations(selections, [{ range: startRange, text: beginInsertedCode }, { range: endRange, text: endInsertedCode }], null); + } else { // Otherwise, add an operation per line (plus the operation at the last column + line) + let operations: IIdentifiedSingleEditOperation[] = []; + for (let i = 0; i < selection.endLineNumber - selection.startLineNumber + 1; i++) { + operations.push({ range: this.transformRangeByLineOffset(startRange, i), text: beginInsertedCode }); + } + operations.push({ range: endRange, text: endInsertedCode }); + editorModel.pushEditOperations(selections, operations, null); + } + } + } + + // If selection end is on same line as beginning, need to add offset for number of characters inserted + // Otherwise, the selection will not be correct after the transformation + let offset = selection.startLineNumber === selection.endLineNumber ? beginInsertedCode.length : 0; + endRange = this.getIRangeWithOffsets(endRange, offset, 0, offset, 0); + this.setEndSelection(endRange, type, editorControl, nothingSelected, isUndo); + } + // Always give focus back to the editor after pressing the button + editorControl.focus(); + } + } + + // For items like lists (where we need to insert a character at the beginning of each line), create + // range object for that range + private transformRangeByLineOffset(range: IRange, lineOffset: number): IRange { + return { + startColumn: lineOffset === 0 ? range.startColumn : 1, + endColumn: range.endColumn, + startLineNumber: range.endLineNumber + lineOffset, + endLineNumber: range.endLineNumber + lineOffset + }; + } + + private getStartTextToInsert(type: MarkdownButtonType): string { + switch (type) { + case MarkdownButtonType.BOLD: + return '**'; + case MarkdownButtonType.ITALIC: + return '_'; + case MarkdownButtonType.CODE: + return '```\n'; + case MarkdownButtonType.LINK: + return '['; + case MarkdownButtonType.UNORDERED_LIST: + return '- '; + case MarkdownButtonType.ORDERED_LIST: + return '1. '; + case MarkdownButtonType.IMAGE: + return '!['; + case MarkdownButtonType.HIGHLIGHT: + return ''; + default: + return ''; + } + } + + private getEndTextToInsert(type: MarkdownButtonType): string { + switch (type) { + case MarkdownButtonType.BOLD: + return '**'; + case MarkdownButtonType.ITALIC: + return '_'; + case MarkdownButtonType.CODE: + return '\n```'; + case MarkdownButtonType.LINK: + case MarkdownButtonType.IMAGE: + return ']()'; + case MarkdownButtonType.HIGHLIGHT: + return ''; + case MarkdownButtonType.UNORDERED_LIST: + case MarkdownButtonType.ORDERED_LIST: + default: + return ''; + } + } + + private getMarkdownLineType(type: MarkdownButtonType): MarkdownLineType { + switch (type) { + case MarkdownButtonType.UNORDERED_LIST: + case MarkdownButtonType.ORDERED_LIST: + return MarkdownLineType.EVERY_LINE; + default: + return MarkdownLineType.BEGIN_AND_END_LINES; + } + } + + // Get offset from the end column for editor selection + // For example, when inserting a link, we want to have the cursor be present in between the brackets + private getColumnOffsetForSelection(type: MarkdownButtonType, nothingSelected: boolean): number { + if (nothingSelected) { + return 0; + } + switch (type) { + case MarkdownButtonType.LINK: + return 2; + case MarkdownButtonType.IMAGE: + return 2; + // -1 is considered as having no explicit offset, so do not do anything with selection + default: return -1; + } + } + + private getEditorControl(): CodeEditorWidget | undefined { + if (!this._notebookEditor) { + this._notebookEditor = this._notebookService.findNotebookEditor(this._cellModel.notebookModel.notebookUri); + } + if (this._notebookEditor?.cellEditors?.length > 0) { + // Find cell editor provider via cell guid + let cellEditorProvider = this._notebookEditor.cellEditors.find(e => e.cellGuid() === this._cellModel.cellGuid); + if (cellEditorProvider) { + let editor = cellEditorProvider.getEditor() as QueryTextEditor; + if (editor) { + let editorControl = editor.getControl() as CodeEditorWidget; + return editorControl; + } + } + } + return undefined; + } + + private editorHasNoSelection(selection: Selection): boolean { + return !selection || (selection.startLineNumber === selection.endLineNumber && selection.startColumn === selection.endColumn); + } + + /** + * Sets the end selection state after the transform has occurred + * @param endRange range for end text that was inserted + * @param type MarkdownButtonType + * @param editorControl code editor widget + * @param noSelection controls whether there was no previous selection in the editor + */ + private setEndSelection(endRange: IRange, type: MarkdownButtonType, editorControl: CodeEditorWidget, noSelection: boolean, isUndo: boolean): void { + if (!endRange || !editorControl || isUndo) { + return; + } + let offset = this.getColumnOffsetForSelection(type, noSelection); + if (offset > -1) { + let newRange: IRange = { + startColumn: endRange.startColumn + offset, + startLineNumber: endRange.startLineNumber, + endColumn: endRange.startColumn + offset, + endLineNumber: endRange.endLineNumber + }; + editorControl.setSelection(newRange); + } else { + if (this.getMarkdownLineType(type) === MarkdownLineType.BEGIN_AND_END_LINES) { + let currentSelection = editorControl.getSelection(); + editorControl.setSelection({ + startColumn: currentSelection.startColumn + this.getStartTextToInsert(type).length, + startLineNumber: currentSelection.startLineNumber, + endColumn: currentSelection.endColumn - this.getEndTextToInsert(type).length, + endLineNumber: currentSelection.endLineNumber + }); + } + } + } + + /** + * Determine if user wants to perform an undo operation + * @param selection current user selection + * @param type markdown button type + * @param lineType markdown line type + * @param editorModel text model for the cell + */ + private isUndoOperation(selection: Selection, type: MarkdownButtonType, lineType: MarkdownLineType, editorModel: TextModel): boolean { + if (lineType === MarkdownLineType.BEGIN_AND_END_LINES) { + let selectedText = this.getExtendedSelectedText(selection, type, lineType, editorModel); + return selectedText && selectedText.startsWith(this.getStartTextToInsert(type)) && selectedText.endsWith(this.getEndTextToInsert(type)); + } else { + return this.everyLineMatchesBeginString(selection, type, editorModel); + } + } + + /** + * Gets the extended selected text (current selection + potential beginning + ending transformed text) + * @param selection Current selection in editor + * @param type Markdown Button Type + * @param lineType Markdown Line Type + * @param editorModel TextModel + */ + private getExtendedSelectedText(selection: Selection, type: MarkdownButtonType, lineType: MarkdownLineType, editorModel: TextModel): string { + if (lineType === MarkdownLineType.BEGIN_AND_END_LINES) { + return editorModel.getValueInRange({ + startColumn: selection.startColumn - this.getStartTextToInsert(type).length, + startLineNumber: selection.startLineNumber, + endColumn: selection.endColumn + this.getEndTextToInsert(type).length, + endLineNumber: selection.endLineNumber + }); + } + return ''; + } + + /** + * Returns whether all lines start with the expected transformed text for actions that match the EVERY_LINE line type + * @param selection Current selection in editor + * @param type Markdown Button Type + * @param editorModel TextModel + */ + private everyLineMatchesBeginString(selection: Selection, type: MarkdownButtonType, editorModel: TextModel): boolean { + if (this.getMarkdownLineType(type) !== MarkdownLineType.EVERY_LINE) { + return false; + } + for (let selectionLine = selection.startLineNumber; selectionLine <= selection.endLineNumber; selectionLine++) { + if (!editorModel.getLineContent(selectionLine).startsWith(this.getStartTextToInsert(type))) { + return false; + } + } + return true; + } + + /** + * Create new IRange object with arbitrary offsets + * @param initialRange range object + * @param startColumnOffset + * @param startLineNumberOffset + * @param endColumnOffset + * @param endLineNumberOffset + */ + private getIRangeWithOffsets(initialRange: IRange, startColumnOffset = 0, startLineNumberOffset = 0, endColumnOffset = 0, endLineNumberOffset = 0): IRange { + return { + startColumn: initialRange.startColumn + startColumnOffset, + startLineNumber: initialRange.startLineNumber + startLineNumberOffset, + endColumn: initialRange.endColumn + endColumnOffset, + endLineNumber: initialRange.endLineNumber + endLineNumberOffset + }; + } +} + +export enum MarkdownButtonType { + BOLD, + ITALIC, + CODE, + HIGHLIGHT, + LINK, + UNORDERED_LIST, + ORDERED_LIST, + IMAGE +} + +// If ALL_LINES, we need to insert markdown at each line (e.g. lists) +export enum MarkdownLineType { + BEGIN_AND_END_LINES, + EVERY_LINE +} diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.component.html b/src/sql/workbench/contrib/notebook/browser/notebook.component.html index bd3626aa07..723fe18a20 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.component.html +++ b/src/sql/workbench/contrib/notebook/browser/notebook.component.html @@ -9,17 +9,6 @@
-
- - - -
@@ -27,17 +16,6 @@
-
- - - -
diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.css b/src/sql/workbench/contrib/notebook/browser/notebook.css index 7fbb302a74..a997829229 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.css +++ b/src/sql/workbench/contrib/notebook/browser/notebook.css @@ -2,16 +2,21 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +.notebookEditor .scrollable { + margin-top: 5px; +} + .notebookEditor .editor-toolbar { - border-bottom-width: 1px; border-bottom-style: solid; + border-width: 0px 0px 1px 0px; } .notebookEditor .notebook-cell { - margin: 1px 20px; - border-width: 1px; + border-color: transparent; border-style: solid; - border-radius: 3px; + border-width: 1px 1px 1px 4px; + margin: 24px 20px; + position: relative; } .notebookEditor .notebook-info-label { @@ -120,6 +125,9 @@ .moreActions.actionhidden { visibility: hidden } +.moreActions .monaco-action-bar { + margin-left: -12px; +} .notebookEditor .notebook-cellTable { margin-left: 20px; diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.module.ts b/src/sql/workbench/contrib/notebook/browser/notebook.module.ts index 71ee5445ab..586ffb575e 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.module.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebook.module.ts @@ -30,6 +30,8 @@ import { LinkHandlerDirective } from 'sql/workbench/contrib/notebook/browser/cel import { IBootstrapParams, ISelector } from 'sql/workbench/services/bootstrap/common/bootstrapParams'; import { ICellComponenetRegistry, Extensions as OutputComponentExtensions } from 'sql/platform/notebooks/common/outputRegistry'; import { CollapseComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/collapse.component'; +import { MarkdownToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component'; +import { CellToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component'; const outputComponentRegistry = Registry.as(OutputComponentExtensions.CellComponentContributions); @@ -46,6 +48,8 @@ export const NotebookModule = (params, selector: string, instantiationService: I LoadingSpinner, CodeComponent, CodeCellComponent, + CellToolbarComponent, + MarkdownToolbarComponent, PlaceholderCellComponent, NotebookComponent, ComponentHostDirective, diff --git a/src/sql/workbench/contrib/notebook/browser/notebookStyles.ts b/src/sql/workbench/contrib/notebook/browser/notebookStyles.ts index 598868a2f6..347f613008 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebookStyles.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebookStyles.ts @@ -5,9 +5,10 @@ import 'vs/css!./notebook'; import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; -import { SIDE_BAR_BACKGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vs/workbench/common/theme'; +import { SIDE_BAR_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vs/workbench/common/theme'; import { activeContrastBorder, contrastBorder, buttonBackground, textLinkForeground, textLinkActiveForeground, textPreformatForeground, textBlockQuoteBackground, textBlockQuoteBorder, buttonForeground, editorBackground, lighten } from 'vs/platform/theme/common/colorRegistry'; import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry'; +import { cellBorder, markdownEditorBackground, splitBorder, codeEditorBackground, codeEditorBackgroundActive, codeEditorLineNumber, codeEditorToolbarIcon, codeEditorToolbarBackground, codeEditorToolbarBorder, toolbarBackground, toolbarIcon, toolbarBottomBorder } from 'sql/platform/theme/common/colorRegistry'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { BareResultsGridInfo, getBareResultsGridInfoStyles } from 'sql/workbench/contrib/query/browser/queryResultsEditor'; @@ -17,10 +18,6 @@ import * as types from 'vs/base/common/types'; export function registerNotebookThemes(overrideEditorThemeSetting: boolean, configurationService: IConfigurationService): IDisposable { return registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => { - let lightBoxShadow = '0px 4px 6px 0px rgba(0, 0, 0, 0.14)'; - let darkBoxShadow = '0px 4px 6px 0px rgba(0, 0, 0, 1)'; - let addBorderToInactiveCodeCells = true; - // Book Navigation Buttons const buttonForegroundColor = theme.getColor(buttonForeground); const buttonBackgroundColor = theme.getColor(buttonBackground); @@ -40,14 +37,6 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf if (buttonBackgroundColor) { let lighterBackgroundColor = lighten(buttonBackgroundColor, 0.825)(theme); collector.addRule(` - .notebookEditor .notebook-cell.active { - border-color: ${buttonBackgroundColor}; - border-width: 1px; - } - .notebookEditor .notebook-cell.active:hover { - border-color: ${buttonBackgroundColor}; - } - .notebookEditor .hoverButton { border-color: ${buttonBackgroundColor}; } @@ -58,7 +47,6 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf .notebookEditor .hoverButton { color: ${buttonBackgroundColor}; } - .vs-dark .notebookEditor .hoverButton { border-color: ${lighterBackgroundColor}; } @@ -89,38 +77,11 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf `); } - // 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; - } - `); - const inactiveBorder = theme.getColor(SIDE_BAR_BACKGROUND); - const sidebarColor = theme.getColor(SIDE_BAR_SECTION_HEADER_BACKGROUND); const notebookLineHighlight = theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND); // Code editor style overrides - only applied if user chooses this as preferred option if (overrideEditorThemeSetting) { + let lineHighlight = theme.getColor(editorLineHighlight); if (!lineHighlight || lineHighlight.isTransparent()) { // Use notebook color override @@ -135,43 +96,12 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf // Override values only for the children of code-component so regular editors aren't affected collector.addRule(`code-component .monaco-editor .view-overlays .current-line { border: 0px; }`); } - - // Override code editor background if color is defined - let codeBackground = inactiveBorder; // theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND); - if (codeBackground) { - // Main background - collector.addRule(`.notebook-cell:not(.active) code-component { background-color: ${codeBackground}; }`); - collector.addRule(` - .notebook-cell:not(.active) code-component .monaco-editor, - .notebook-cell:not(.active) code-component .monaco-editor-background, - .notebook-cell:not(.active) code-component .monaco-editor .inputarea.ime-input, - .notebook-cell.active .hide-component-button:hover - { - background-color: ${codeBackground}; - }`); - - // Margin background will be the same (may override some styles) - collector.addRule(`.notebook-cell:not(.active) code-component .monaco-editor .margin { background-color: ${codeBackground}; }`); - addBorderToInactiveCodeCells = false; - } } // Inactive border if (inactiveBorder) { // Standard notebook cell behavior collector.addRule(` - .notebookEditor .notebook-cell { - border-color: transparent; - border-width: 1px; - } - .notebookEditor .notebook-cell.active { - border-width: 1px; - } - .notebookEditor .notebook-cell:hover { - border-color: ${inactiveBorder}; - border-width: 1px; - } - .notebookEditor .hoverButtonsContainer .containerBackground { background-color: ${inactiveBorder}; } @@ -181,35 +111,10 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf collector.addRule(` .notebookEditor .notebook-cell.active code-component { border-color: ${inactiveBorder}; - border-width: 0px 0px 1px 0px; - border-style: solid; - border-radius: 0; } `); - - if (addBorderToInactiveCodeCells) { - // Sets a border for the editor component if we don't have a custom line color for editor instead - 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:hover code-component { - border-width: 0px 0px 1px 0px; - border-radius: 0px; - } - `); - } } - // Sidebar and cell outline toolbar color set only when active - collector.addRule(` - .notebook-cell.active code-component .toolbar { - background-color: ${sidebarColor}; - } - `); // Styling with Outline color (e.g. high contrast theme) const outline = theme.getColor(activeContrastBorder); const hcOutline = theme.getColor(contrastBorder); @@ -219,21 +124,11 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf 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; - } - .hc-black .notebookEditor .hoverButton { color: ${hcOutline}; } @@ -283,8 +178,6 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf } `); } - - let blockQuoteBackground = theme.getColor(textBlockQuoteBackground); let blockQuoteBorder = theme.getColor(textBlockQuoteBorder); if (preformatForeground) { @@ -313,5 +206,64 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf .grid-panel .monaco-table, .message-tree { ${getBareResultsGridInfoStyles(rawOptions)} }`); + + + // Cell border + const cellBorderColor = theme.getColor(cellBorder); + if (cellBorderColor) { + collector.addRule(`.notebookEditor .notebook-cell.active { border-color: ${cellBorderColor};}`); + } + + // Markdown editor toolbar + const toolbarBackgroundColor = theme.getColor(toolbarBackground); + if (toolbarBackgroundColor) { + collector.addRule(`markdown-toolbar-component { background: ${toolbarBackgroundColor};}`); + } + const toolbarIconColor = theme.getColor(toolbarIcon); + if (toolbarIconColor) { + collector.addRule(`.markdown-toolbar li a { background-color: ${toolbarIconColor};}`); + } + const toolbarBottomBorderColor = theme.getColor(toolbarBottomBorder); + if (toolbarBottomBorderColor) { + collector.addRule(`.markdown-toolbar { border-bottom-color: ${toolbarBottomBorderColor};}`); + } + + // Markdwon editor colors + const markdownEditorBackgroundColor = theme.getColor(markdownEditorBackground); + if (markdownEditorBackgroundColor) { + collector.addRule(`text-cell-component code-component { background-color: ${markdownEditorBackgroundColor}; }`); + } + const splitBorderColor = theme.getColor(splitBorder); + if (splitBorderColor) { + collector.addRule(`.notebookEditor .notebook-cell.active text-cell-component code-component { border-bottom-color: ${splitBorderColor}; }`); + } + + // Code editor colors + const codeEditorBackgroundColor = theme.getColor(codeEditorBackground); + if (codeEditorBackgroundColor) { + collector.addRule(`code-cell-component code-component { background-color: ${codeEditorBackgroundColor}; }`); + } + const codeEditorBackgroundActiveColor = theme.getColor(codeEditorBackgroundActive); + if (codeEditorBackgroundActiveColor) { + collector.addRule(`.notebook-cell.active code-cell-component code-component { background-color: ${codeEditorBackgroundActiveColor}; }`); + } + const codeEditorLineNumberColor = theme.getColor(codeEditorLineNumber); + if (codeEditorLineNumberColor) { + collector.addRule(`code-cell-component code-component .editor .line-numbers { color: ${codeEditorLineNumberColor};}`); + } + const codeEditorToolbarIconColor = theme.getColor(codeEditorToolbarIcon); + if (codeEditorToolbarIconColor) { + collector.addRule( + `code-cell-component code-component .carbon-taskbar .codicon.hideIcon { color: ${codeEditorToolbarIconColor};}` + ); + } + const codeEditorToolbarBackgroundColor = theme.getColor(codeEditorToolbarBackground); + if (codeEditorToolbarBackgroundColor) { + collector.addRule(`.notebook-cell.active code-cell-component code-component .toolbar { background-color: ${codeEditorToolbarBackgroundColor};}`); + } + const codeEditorToolbarBorderColor = theme.getColor(codeEditorToolbarBorder); + if (codeEditorToolbarBorderColor) { + collector.addRule(`.notebook-cell.active code-cell-component code-component .toolbar { border-right-color: ${codeEditorToolbarBorderColor}!important;}`); + } }); }