diff --git a/packages/notebook/src/browser/style/index.css b/packages/notebook/src/browser/style/index.css index c99bdaf0b24af..e557a7983e7d8 100644 --- a/packages/notebook/src/browser/style/index.css +++ b/packages/notebook/src/browser/style/index.css @@ -335,7 +335,13 @@ width: 100%; } +.theia-notebook-collapsed-output-container { + width: 0; + overflow: visible; +} + .theia-notebook-collapsed-output { + text-wrap: nowrap; padding: 4px 8px; color: var(--theia-foreground); margin-left: 30px; diff --git a/packages/notebook/src/browser/view/notebook-code-cell-view.tsx b/packages/notebook/src/browser/view/notebook-code-cell-view.tsx index d9b779275c9d7..537776e03adaf 100644 --- a/packages/notebook/src/browser/view/notebook-code-cell-view.tsx +++ b/packages/notebook/src/browser/view/notebook-code-cell-view.tsx @@ -95,14 +95,12 @@ export class NotebookCodeCellRenderer implements CellRenderer { renderSidebar(notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode { return
-
- - this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, cell, { - contextMenuArgs: () => [notebookModel, cell, cell.outputs[0]] - }) - } /> -
+ + this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, cell, { + contextMenuArgs: () => [notebookModel, cell, cell.outputs[0]] + }) + } />
; } @@ -299,19 +297,20 @@ export class NotebookCodeCellOutputs extends React.Component { - if (event.cellHandle === props.cell.handle) { + override async componentDidMount(): Promise { + const { cell } = this.props; + this.toDispose.push(cell.onDidChangeOutputs(() => this.forceUpdate())); + this.toDispose.push(this.props.cell.onDidChangeOutputVisibility(() => this.forceUpdate())); + this.toDispose.push(this.props.outputWebview.onDidRenderOutput(event => { + if (event.cellHandle === this.props.cell.handle) { this.outputHeight = event.outputHeight; this.forceUpdate(); } - }); + })); } - override async componentDidMount(): Promise { - const { cell } = this.props; - this.toDispose.push(cell.onDidChangeOutputs(() => this.forceUpdate())); + override componentWillUnmount(): void { + this.toDispose.dispose(); } override render(): React.ReactNode { @@ -323,7 +322,7 @@ export class NotebookCodeCellOutputs extends React.Component; } - return {nls.localizeByDefault('Outputs are collapsed')}; + return
{nls.localizeByDefault('Outputs are collapsed')}
; } } diff --git a/packages/plugin-ext/src/main/browser/notebooks/renderers/cell-output-webview.tsx b/packages/plugin-ext/src/main/browser/notebooks/renderers/cell-output-webview.tsx index aa39068aed7eb..c142424c6ca77 100644 --- a/packages/plugin-ext/src/main/browser/notebooks/renderers/cell-output-webview.tsx +++ b/packages/plugin-ext/src/main/browser/notebooks/renderers/cell-output-webview.tsx @@ -318,6 +318,13 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable { }]); })); this.toDispose.push(cell.onDidCellHeightChange(height => this.setCellHeight(cell, height))); + this.toDispose.push(cell.onDidChangeOutputVisibility(visible => { + this.webviewWidget.sendMessage({ + type: 'outputVisibilityChanged', + cellHandle: cell.handle, + visible + }); + })); } render(): React.JSX.Element { diff --git a/packages/plugin-ext/src/main/browser/notebooks/renderers/output-webview-internal.ts b/packages/plugin-ext/src/main/browser/notebooks/renderers/output-webview-internal.ts index ae5cba306fa4e..8054449c30bbb 100644 --- a/packages/plugin-ext/src/main/browser/notebooks/renderers/output-webview-internal.ts +++ b/packages/plugin-ext/src/main/browser/notebooks/renderers/output-webview-internal.ts @@ -210,11 +210,25 @@ export async function outputWebviewPreload(ctx: PreloadContext): Promise { public updateCellHeight(cellKind: number, height: number): void { let additionalHeight = 54.5; additionalHeight -= cells[0] === this ? 2.5 : 0; // first cell - additionalHeight -= cellKind === 1 ? 5 : 0; // markdown cell additionalHeight -= this.outputElements.length ? 0 : 5.5; // no outputs this.element.style.paddingTop = `${height + additionalHeight}px`; } + public outputVisibilityChanged(visible: boolean): void { + console.log('outputVisibilityChanged', visible); + this.outputElements.forEach(output => { + output.element.style.display = visible ? 'initial' : 'none'; + }); + if (visible) { + this.element.getElementsByClassName('output-hidden')?.[0].remove(); + } else { + const outputHiddenElement = document.createElement('div'); + outputHiddenElement.classList.add('output-hidden'); + outputHiddenElement.style.height = '16px'; + this.element.appendChild(outputHiddenElement); + } + } + // public updateScroll(request: webviewCommunication.IContentWidgetTopRequest): void { // this.element.style.top = `${request.cellTop}px`; @@ -695,6 +709,7 @@ export async function outputWebviewPreload(ctx: PreloadContext): Promise { window.addEventListener('message', async rawEvent => { const event = rawEvent as ({ data: webviewCommunication.ToWebviewMessage }); + let cellHandle: number | undefined; switch (event.data.type) { case 'updateRenderers': renderers.updateRendererData(event.data.rendererData); @@ -709,9 +724,9 @@ export async function outputWebviewPreload(ctx: PreloadContext): Promise { renderers.getRenderer(event.data.rendererId)?.receiveMessage(event.data.message); break; case 'changePreferredMimetype': - const handle = event.data.cellHandle; + cellHandle = event.data.cellHandle; const outputId = event.data.outputId; - cells.find(c => c.cellHandle === handle) + cells.find(c => c.cellHandle === cellHandle) ?.outputElements.find(o => o.outputId === outputId) ?.preferredMimeTypeChange(event.data.mimeType); break; @@ -742,12 +757,17 @@ export async function outputWebviewPreload(ctx: PreloadContext): Promise { } break; case 'cellHeightUpdate': - const cellHandle = event.data.cellHandle; + cellHandle = event.data.cellHandle; const cell = cells.find(c => c.cellHandle === cellHandle); if (cell) { cell.updateCellHeight(event.data.cellKind, event.data.height); } break; + case 'outputVisibilityChanged': + console.log('change visibility', event.data); + cellHandle = event.data.cellHandle; + cells.find(c => c.cellHandle === cellHandle)?.outputVisibilityChanged(event.data.visible); + break; } }); window.addEventListener('wheel', handleWheel); diff --git a/packages/plugin-ext/src/main/browser/notebooks/renderers/webview-communication.ts b/packages/plugin-ext/src/main/browser/notebooks/renderers/webview-communication.ts index e2b397f79e3f5..9b68854f67b30 100644 --- a/packages/plugin-ext/src/main/browser/notebooks/renderers/webview-communication.ts +++ b/packages/plugin-ext/src/main/browser/notebooks/renderers/webview-communication.ts @@ -100,6 +100,12 @@ export interface CellHeightUpdateMessage { height: number; } +export interface OutputVisibilityChangedMessage { + type: 'outputVisibilityChanged'; + cellHandle: number; + visible: boolean; +} + export type ToWebviewMessage = UpdateRenderersMessage | OutputChangedMessage | ChangePreferredMimetypeMessage @@ -109,7 +115,8 @@ export type ToWebviewMessage = UpdateRenderersMessage | notebookStylesMessage | CellHeigthsMessage | CellHeightUpdateMessage - | CellsChangedMessage; + | CellsChangedMessage + | OutputVisibilityChangedMessage; export interface WebviewInitialized { readonly type: 'initialized';