Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions packages/notebook-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { Poll } from '@lumino/polling';
import { Widget } from '@lumino/widgets';

import { TrustedComponent } from './trusted';
import { scrollButtons } from './scroll-buttons';

/**
* The class for kernel status errors.
Expand Down Expand Up @@ -432,30 +433,15 @@ const scrollOutput: JupyterFrontEndPlugin<void> = {
tracker: INotebookTracker,
settingRegistry: ISettingRegistry | null
) => {
const autoScrollThreshold = 100;
let autoScrollOutputs = true;
// Auto-scroll functionality temporarily disabled
// const autoScrollThreshold = 50;
// let autoScrollOutputs = true;

// decide whether to scroll the output of the cell based on some heuristics
const autoScroll = (cell: CodeCell) => {
if (!autoScrollOutputs) {
// bail if disabled via the settings
cell.removeClass(SCROLLED_OUTPUTS_CLASS);
return;
}
const { outputArea } = cell;
// respect cells with an explicit scrolled state
const scrolled = cell.model.getMetadata('scrolled');
if (scrolled !== undefined) {
return;
}
const { node } = outputArea;
const height = node.scrollHeight;
const fontSize = parseFloat(node.style.fontSize.replace('px', ''));
const lineHeight = (fontSize || 14) * 1.3;
// do not set via cell.outputScrolled = true, as this would
// otherwise synchronize the scrolled state to the notebook metadata
const scroll = height > lineHeight * autoScrollThreshold;
cell.toggleClass(SCROLLED_OUTPUTS_CLASS, scroll);
// Auto-scroll disabled to fix issues
cell.removeClass(SCROLLED_OUTPUTS_CLASS);
return;
};

const handlers: { [id: string]: () => void } = {};
Expand Down Expand Up @@ -690,6 +676,7 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
kernelStatus,
notebookToolsWidget,
scrollOutput,
scrollButtons,
tabIcon,
trusted,
];
Expand Down
90 changes: 90 additions & 0 deletions packages/notebook-extension/src/scroll-buttons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';

Check failure on line 4 in packages/notebook-extension/src/scroll-buttons.ts

View workflow job for this annotation

GitHub Actions / Test Lint

Replace `·JupyterFrontEnd,·JupyterFrontEndPlugin·` with `⏎··JupyterFrontEnd,⏎··JupyterFrontEndPlugin,⏎`
import { INotebookTracker } from '@jupyterlab/notebook';
import { ITranslator } from '@jupyterlab/translation';

/**
* The class name for the scroll buttons container
*/
const SCROLL_BUTTONS_CLASS = 'jp-Notebook-scrollButtons';

/**
* The class name for individual scroll buttons
*/
const SCROLL_BUTTON_CLASS = 'jp-Notebook-scrollButton';

/**
* The class name for hiding scroll buttons
*/
const SCROLL_BUTTONS_HIDDEN_CLASS = 'jp-mod-hidden';

/**
* A plugin that adds scroll buttons to the notebook
*/
export const scrollButtons: JupyterFrontEndPlugin<void> = {
id: '@jupyter-notebook/notebook-extension:scroll-buttons',
description: 'A plugin that adds scroll buttons to the notebook.',
autoStart: true,
requires: [INotebookTracker],
optional: [ITranslator],
activate: (app: JupyterFrontEnd, tracker: INotebookTracker) => {
// Create scroll buttons container
const buttonContainer = document.createElement('div');
buttonContainer.className = SCROLL_BUTTONS_CLASS;

// Create up button
const upButton = document.createElement('button');
upButton.className = SCROLL_BUTTON_CLASS;
upButton.innerHTML = '↑';
upButton.title = 'Scroll to top';
upButton.onclick = () => {
const notebook = tracker.currentWidget?.content;
if (notebook) {
notebook.node.scrollTo({
top: 0,
behavior: 'smooth'

Check failure on line 47 in packages/notebook-extension/src/scroll-buttons.ts

View workflow job for this annotation

GitHub Actions / Test Lint

Insert `,`
});
}
};

// Create down button
const downButton = document.createElement('button');
downButton.className = SCROLL_BUTTON_CLASS;
downButton.innerHTML = '↓';
downButton.title = 'Scroll to bottom';
downButton.onclick = () => {
const notebook = tracker.currentWidget?.content;
if (notebook) {
notebook.node.scrollTo({
top: notebook.node.scrollHeight,
behavior: 'smooth'

Check failure on line 62 in packages/notebook-extension/src/scroll-buttons.ts

View workflow job for this annotation

GitHub Actions / Test Lint

Insert `,`
});
}
};

// Add buttons to container
buttonContainer.appendChild(upButton);
buttonContainer.appendChild(downButton);

// Add container to document body
document.body.appendChild(buttonContainer);

// Show/hide buttons based on scroll position
tracker.currentChanged.connect(() => {
const notebook = tracker.currentWidget?.content;
if (notebook) {
const handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = notebook.node;

Check warning on line 79 in packages/notebook-extension/src/scroll-buttons.ts

View workflow job for this annotation

GitHub Actions / Test Lint

'scrollTop' is assigned a value but never used
buttonContainer.classList.toggle(
SCROLL_BUTTONS_HIDDEN_CLASS,
scrollHeight <= clientHeight
);
};
notebook.node.addEventListener('scroll', handleScroll);
handleScroll(); // Initial check
}
});
}

Check failure on line 89 in packages/notebook-extension/src/scroll-buttons.ts

View workflow job for this annotation

GitHub Actions / Test Lint

Insert `,`
};
1 change: 1 addition & 0 deletions packages/notebook-extension/style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
|----------------------------------------------------------------------------*/

@import './variables.css';
@import './scroll-buttons.css';

/**
Document oriented look for the notebook.
Expand Down
42 changes: 42 additions & 0 deletions packages/notebook-extension/style/scroll-buttons.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* Scroll buttons container */
.jp-Notebook-scrollButtons {
position: fixed;
bottom: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 8px;
z-index: 1000;
}

/* Common button styles */
.jp-Notebook-scrollButton {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: var(--jp-layout-color1);
border: 1px solid var(--jp-border-color1);
color: var(--jp-ui-font-color1);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s, transform 0.2s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Hover state */
.jp-Notebook-scrollButton:hover {
background-color: var(--jp-layout-color2);
transform: translateY(-2px);
}

/* Active state */
.jp-Notebook-scrollButton:active {
transform: translateY(0);
}

/* Hide buttons when not needed */
.jp-Notebook-scrollButtons.jp-mod-hidden {
display: none;
}
Loading