Socket
Socket
Sign inDemoInstall

@jupyterlab/ui-components

Package Overview
Dependencies
Maintainers
10
Versions
309
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jupyterlab/ui-components - npm Package Compare versions

Comparing version 4.1.0-alpha.4 to 4.1.0-beta.0

2

lib/components/form.js

@@ -217,3 +217,3 @@ /*

!hasCustomField &&
(rawErrors ? (
((rawErrors === null || rawErrors === void 0 ? void 0 : rawErrors.length) ? (
// Shows a red indicator for fields that have validation errors

@@ -220,0 +220,0 @@ React.createElement("div", { className: "jp-modifiedIndicator jp-errorIndicator" })) : (

@@ -353,2 +353,3 @@ import { ITranslator } from '@jupyterlab/translation';

constructor(props: CommandToolbarButtonComponent.IProps);
protected setCommandAttributes(commands: CommandRegistry, id: string, args: ReadonlyJSONObject | undefined): void;
render(): JSX.Element;

@@ -355,0 +356,0 @@ }

@@ -730,4 +730,35 @@ // Copyright (c) Jupyter Development Team.

this.props = props;
const { commands, id, args } = props;
addCommandToolbarButtonClass(this);
this.setCommandAttributes(commands, id, args);
commands.commandChanged.connect((_, change) => {
if (change.id === props.id) {
this.setCommandAttributes(commands, id, args);
}
}, this);
}
setCommandAttributes(commands, id, args) {
if (commands.isToggled(id, args)) {
this.addClass('lm-mod-toggled');
}
else {
this.removeClass('lm-mod-toggled');
}
if (commands.isVisible(id, args)) {
this.removeClass('lm-mod-hidden');
}
else {
this.addClass('lm-mod-hidden');
}
if (commands.isEnabled(id, args)) {
if ('disabled' in this.node) {
this.node.disabled = false;
}
}
else {
if ('disabled' in this.node) {
this.node.disabled = true;
}
}
}
render() {

@@ -734,0 +765,0 @@ return React.createElement(CommandToolbarButtonComponent, { ...this.props });

@@ -207,3 +207,3 @@ import { IChangedArgs } from '@jupyterlab/coreutils';

*/
export declare class WindowedList<T extends WindowedList.IModel = WindowedList.IModel> extends Widget {
export declare class WindowedList<T extends WindowedList.IModel = WindowedList.IModel, U = any> extends Widget {
/**

@@ -218,3 +218,3 @@ * Default widget size

*/
constructor(options: WindowedList.IOptions<T>);
constructor(options: WindowedList.IOptions<T, U>);
/**

@@ -233,6 +233,19 @@ * Whether the parent is hidden or not.

/**
* The outer container of the windowed list.
*/
get outerNode(): HTMLElement;
/**
* Viewport
*/
get viewportNode(): HTMLDivElement;
get viewportNode(): HTMLElement;
/**
* Flag to enable virtual scrollbar.
*/
get scrollbar(): boolean;
set scrollbar(enabled: boolean);
/**
* The renderer for this windowed list. Set at instantiation.
*/
protected renderer: WindowedList.IRenderer<U>;
/**
* Windowed list view model

@@ -307,9 +320,39 @@ */

protected onUpdateRequest(msg: Message): void;
/**
* A signal that emits the index when the virtual scrollbar jumps to an item.
*/
protected jumped: Signal<this, number>;
private _adjustDimensionsForScrollbar;
/**
* Add listeners for viewport, contents and the virtual scrollbar.
*/
private _addListeners;
/**
* Turn off windowing related styles in the viewport.
*/
private _applyNoWindowingStyles;
/**
* Remove listeners for viewport and contents (but not the virtual scrollbar).
*/
private _removeListeners;
/**
* Update viewport and DOM state.
*/
private _update;
/**
* Handle viewport content (e.g. widgets) resize.
*/
private _onWidgetResize;
/**
* Clear any outstanding timeout and enqueue scrolling to a new item.
*/
private _resetScrollToItem;
protected _viewModel: T;
/**
* Render virtual scrollbar.
*/
private _renderScrollbar;
/**
* Handle `pointerdown` events on the virtual scrollbar.
*/
private _evtPointerDown;
private _innerElement;

@@ -319,5 +362,7 @@ private _isParentHidden;

private _needsUpdate;
private _windowElement;
private _outerElement;
private _resetScrollToItemTimeout;
private _resizeObserver;
private _scrollbarElement;
private _scrollbarResizeObserver;
private _scrollRepaint;

@@ -327,2 +372,4 @@ private _scrollToItem;

private _updater;
private _viewModel;
private _viewport;
}

@@ -415,5 +462,30 @@ /**

/**
* The default renderer class for windowed lists.
*/
class Renderer<T = any> implements IRenderer<T> {
/**
* Create the outer, root element of the windowed list.
*/
createOuter(): HTMLElement;
/**
* Create the virtual scrollbar element.
*/
createScrollbar(): HTMLOListElement;
/**
* Create an individual item rendered in the scrollbar.
*/
createScrollbarItem(_: WindowedList, index: number): HTMLLIElement;
/**
* Create the viewport element into which virtualized children are added.
*/
createViewport(): HTMLElement;
}
/**
* The default renderer for windowed lists.
*/
const defaultRenderer: Renderer<any>;
/**
* Windowed list model interface
*/
interface IModel extends IDisposable {
interface IModel<T = any> extends IDisposable {
/**

@@ -485,2 +557,3 @@ * Provide a best guess for the widget size at position index

itemsList: {
get?: (index: number) => T;
length: number;

@@ -572,3 +645,3 @@ changed: ISignal<any, IObservableList.IChangedArgs<any>>;

*/
interface IOptions<T extends WindowedList.IModel = WindowedList.IModel> {
interface IOptions<T extends WindowedList.IModel = WindowedList.IModel, U = any> {
/**

@@ -582,4 +655,33 @@ * Windowed list model to display

layout?: WindowedLayout;
/**
* A renderer for the elements of the windowed list.
*/
renderer?: IRenderer<U>;
/**
* Whether the windowed list should display a scrollbar UI.
*/
scrollbar?: boolean;
}
/**
* A windowed list element renderer.
*/
interface IRenderer<T = any> {
/**
* Create the outer, root element of the windowed list.
*/
createOuter(): HTMLElement;
/**
* Create the virtual scrollbar element.
*/
createScrollbar(): HTMLElement;
/**
* Create an individual item rendered in the scrollbar.
*/
createScrollbarItem(list: WindowedList, index: number, item: T | undefined): HTMLElement;
/**
* Create the viewport element into which virtualized children are added.
*/
createViewport(): HTMLElement;
}
/**
* Item list metadata

@@ -586,0 +688,0 @@ */

@@ -567,17 +567,29 @@ /*

constructor(options) {
var _a;
// TODO probably needs to be able to customize outer HTML tag (could be ul / ol / table, ...)
var _a, _b;
const renderer = (_a = options.renderer) !== null && _a !== void 0 ? _a : WindowedList.defaultRenderer;
const node = document.createElement('div');
node.className = 'jp-WindowedPanel-outer';
const innerElement = node.appendChild(document.createElement('div'));
node.className = 'jp-WindowedPanel';
const scrollbarElement = node.appendChild(document.createElement('div'));
scrollbarElement.classList.add('jp-WindowedPanel-scrollbar');
const list = scrollbarElement.appendChild(renderer.createScrollbar());
list.classList.add('jp-WindowedPanel-scrollbar-content');
const outerElement = node.appendChild(renderer.createOuter());
outerElement.classList.add('jp-WindowedPanel-outer');
const innerElement = outerElement.appendChild(document.createElement('div'));
innerElement.className = 'jp-WindowedPanel-inner';
const windowContainer = innerElement.appendChild(document.createElement('div'));
windowContainer.className = 'jp-WindowedPanel-window';
const viewport = innerElement.appendChild(renderer.createViewport());
viewport.classList.add('jp-WindowedPanel-viewport');
super({ node });
/**
* A signal that emits the index when the virtual scrollbar jumps to an item.
*/
this.jumped = new Signal(this);
this._needsUpdate = false;
super.layout = (_a = options.layout) !== null && _a !== void 0 ? _a : new WindowedLayout();
this._viewModel = options.model;
super.layout = (_b = options.layout) !== null && _b !== void 0 ? _b : new WindowedLayout();
this.renderer = renderer;
this._innerElement = innerElement;
this._isScrolling = null;
this._windowElement = windowContainer;
this._outerElement = outerElement;
this._resizeObserver = null;
this._scrollbarElement = scrollbarElement;
this._scrollToItem = null;

@@ -587,4 +599,8 @@ this._scrollRepaint = null;

this._updater = new Throttler(() => this.update(), 50);
this._resizeObserver = null;
this._viewModel.stateChanged.connect(this.onStateChanged, this);
this._viewModel = options.model;
this._viewport = viewport;
if (options.scrollbar) {
node.classList.add('jp-mod-virtual-scrollbar');
}
this.viewModel.stateChanged.connect(this.onStateChanged, this);
}

@@ -610,8 +626,30 @@ /**

/**
* The outer container of the windowed list.
*/
get outerNode() {
return this._outerElement;
}
/**
* Viewport
*/
get viewportNode() {
return this._windowElement;
return this._viewport;
}
/**
* Flag to enable virtual scrollbar.
*/
get scrollbar() {
return this.node.classList.contains('jp-mod-virtual-scrollbar');
}
set scrollbar(enabled) {
if (enabled) {
this.node.classList.add('jp-mod-virtual-scrollbar');
}
else {
this.node.classList.remove('jp-mod-virtual-scrollbar');
}
this._adjustDimensionsForScrollbar();
this.update();
}
/**
* Windowed list view model

@@ -636,2 +674,7 @@ */

switch (event.type) {
case 'pointerdown':
event.preventDefault();
event.stopPropagation();
this._evtPointerDown(event);
break;
case 'scroll':

@@ -699,3 +742,3 @@ this.onScroll(event);

this._resetScrollToItem();
this.scrollTo(this.viewModel.getOffsetForIndexAndAlignment(Math.max(0, Math.min(index, this._viewModel.widgetCount - 1)), align, margin));
this.scrollTo(this.viewModel.getOffsetForIndexAndAlignment(Math.max(0, Math.min(index, this.viewModel.widgetCount - 1)), align, margin));
return this._isScrolling.promise;

@@ -708,3 +751,3 @@ }

super.onAfterAttach(msg);
if (this._viewModel.windowingActive) {
if (this.viewModel.windowingActive) {
this._addListeners();

@@ -718,2 +761,3 @@ }

this.viewModel.paddingTop = parseFloat(style.paddingTop);
this._scrollbarElement.addEventListener('pointerdown', this);
}

@@ -724,5 +768,7 @@ /**

onBeforeDetach(msg) {
if (this._viewModel.windowingActive) {
if (this.viewModel.windowingActive) {
this._removeListeners();
}
this._scrollbarElement.removeEventListener('pointerdown', this);
super.onBeforeDetach(msg);
}

@@ -764,2 +810,3 @@ /**

super.onResize(msg);
void this._updater.invoke();
}

@@ -795,2 +842,5 @@ /**

onUpdateRequest(msg) {
if (this.scrollbar) {
this._renderScrollbar();
}
if (this.viewModel.windowingActive) {

@@ -817,2 +867,42 @@ // Throttle update request

}
/*
* Hide the native scrollbar if necessary and update dimensions
*/
_adjustDimensionsForScrollbar() {
const outer = this._outerElement;
const scrollbar = this._scrollbarElement;
if (this.scrollbar) {
// Query DOM
let outerScrollbarWidth = outer.offsetWidth - outer.clientWidth;
// Update DOM
// 1) The native scrollbar is hidden by shifting it out of view.
if (outerScrollbarWidth == 0) {
// If the scrollbar width is zero, one of the following is true:
// - (a) the content is not overflowing
// - (b) the browser uses overlay scrollbars
// In (b) the overlay scrollbars could show up even even if
// occluded by a child element; to prevent this resulting in
// double scrollbar we shift the content by an arbitrary offset.
outerScrollbarWidth = 1000;
outer.style.paddingRight = `${outerScrollbarWidth}px`;
outer.style.boxSizing = 'border-box';
}
else {
outer.style.paddingRight = '0';
}
outer.style.width = `calc(100% + ${outerScrollbarWidth}px)`;
// 2) The inner window is shrank to accommodate the virtual scrollbar
this._innerElement.style.marginRight = `${scrollbar.offsetWidth}px`;
}
else {
// Reset all styles that may have been touched.
outer.style.width = '100%';
this._innerElement.style.marginRight = '0';
outer.style.paddingRight = '0';
outer.style.boxSizing = '';
}
}
/**
* Add listeners for viewport, contents and the virtual scrollbar.
*/
_addListeners() {

@@ -826,16 +916,30 @@ if (!this._resizeObserver) {

}
this.node.addEventListener('scroll', this, passiveIfSupported);
this._windowElement.style.position = 'absolute';
this._outerElement.addEventListener('scroll', this, passiveIfSupported);
this._viewport.style.position = 'absolute';
this._scrollbarResizeObserver = new ResizeObserver(this._adjustDimensionsForScrollbar.bind(this));
this._scrollbarResizeObserver.observe(this._outerElement);
this._scrollbarResizeObserver.observe(this._scrollbarElement);
}
/**
* Turn off windowing related styles in the viewport.
*/
_applyNoWindowingStyles() {
this._windowElement.style.position = 'relative';
this._windowElement.style.top = '0px';
this._viewport.style.position = 'relative';
this._viewport.style.top = '0px';
}
/**
* Remove listeners for viewport and contents (but not the virtual scrollbar).
*/
_removeListeners() {
var _a;
this.node.removeEventListener('scroll', this);
var _a, _b;
this._outerElement.removeEventListener('scroll', this);
(_a = this._resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
this._resizeObserver = null;
(_b = this._scrollbarResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
this._scrollbarResizeObserver = null;
this._applyNoWindowingStyles();
}
/**
* Update viewport and DOM state.
*/
_update() {

@@ -883,4 +987,4 @@ var _a;

const [top, minHeight] = this.viewModel.getSpan(startIndex, stopIndex);
this._windowElement.style.top = `${top}px`;
this._windowElement.style.minHeight = `${minHeight}px`;
this._viewport.style.top = `${top}px`;
this._viewport.style.minHeight = `${minHeight}px`;
}

@@ -890,9 +994,9 @@ else {

this._innerElement.style.height = `0px`;
// Update position of window container
this._windowElement.style.top = `0px`;
this._windowElement.style.minHeight = `0px`;
// Update position of viewport node
this._viewport.style.top = `0px`;
this._viewport.style.minHeight = `0px`;
}
// Update scroll
if (this._scrollUpdateWasRequested) {
this.node.scrollTop = this.viewModel.scrollOffset;
this._outerElement.scrollTop = this.viewModel.scrollOffset;
this._scrollUpdateWasRequested = false;

@@ -903,3 +1007,3 @@ }

let index2 = -1;
for (const w of this.viewportNode.children) {
for (const w of this._viewport.children) {
const currentIdx = parseInt(w.dataset.windowedListIndex, 10);

@@ -914,2 +1018,5 @@ if (currentIdx < index2) {

}
/**
* Handle viewport content (e.g. widgets) resize.
*/
_onWidgetResize(entries) {

@@ -943,2 +1050,5 @@ this._resetScrollToItem();

}
/**
* Clear any outstanding timeout and enqueue scrolling to a new item.
*/
_resetScrollToItem() {

@@ -958,2 +1068,38 @@ if (this._resetScrollToItemTimeout) {

}
/**
* Render virtual scrollbar.
*/
_renderScrollbar() {
var _a, _b;
const { node, renderer, viewModel } = this;
const content = node.querySelector('.jp-WindowedPanel-scrollbar-content');
while (content.firstChild) {
content.removeChild(content.firstChild);
}
const list = viewModel.itemsList;
const count = (_a = list === null || list === void 0 ? void 0 : list.length) !== null && _a !== void 0 ? _a : viewModel.widgetCount;
for (let index = 0; index < count; index += 1) {
const item = (_b = list === null || list === void 0 ? void 0 : list.get) === null || _b === void 0 ? void 0 : _b.call(list, index);
const element = renderer.createScrollbarItem(this, index, item);
element.classList.add('jp-WindowedPanel-scrollbar-item');
element.dataset.index = `${index}`;
content.appendChild(element);
}
}
/**
* Handle `pointerdown` events on the virtual scrollbar.
*/
_evtPointerDown(event) {
let target = event.target;
while (target && target.parentElement) {
if (target.hasAttribute('data-index')) {
const index = parseInt(target.getAttribute('data-index'), 10);
return void (async () => {
await this.scrollToItem(index);
this.jumped.emit(index);
})();
}
target = target.parentElement;
}
}
}

@@ -1088,2 +1234,43 @@ /**

}
/**
* A namespace for windowed list
*/
(function (WindowedList) {
/**
* The default renderer class for windowed lists.
*/
class Renderer {
/**
* Create the outer, root element of the windowed list.
*/
createOuter() {
return document.createElement('div');
}
/**
* Create the virtual scrollbar element.
*/
createScrollbar() {
return document.createElement('ol');
}
/**
* Create an individual item rendered in the scrollbar.
*/
createScrollbarItem(_, index) {
const li = document.createElement('li');
li.appendChild(document.createTextNode(`${index}`));
return li;
}
/**
* Create the viewport element into which virtualized children are added.
*/
createViewport() {
return document.createElement('div');
}
}
WindowedList.Renderer = Renderer;
/**
* The default renderer for windowed lists.
*/
WindowedList.defaultRenderer = new Renderer();
})(WindowedList || (WindowedList = {}));
//# sourceMappingURL=windowedlist.js.map
{
"name": "@jupyterlab/ui-components",
"version": "4.1.0-alpha.4",
"version": "4.1.0-beta.0",
"description": "JupyterLab - UI components written in React",

@@ -46,6 +46,6 @@ "homepage": "https://github.com/jupyterlab/jupyterlab",

"@jupyter/web-components": "^0.13.3",
"@jupyterlab/coreutils": "^6.1.0-alpha.4",
"@jupyterlab/observables": "^5.1.0-alpha.4",
"@jupyterlab/rendermime-interfaces": "^3.9.0-alpha.3",
"@jupyterlab/translation": "^4.1.0-alpha.4",
"@jupyterlab/coreutils": "^6.1.0-beta.0",
"@jupyterlab/observables": "^5.1.0-beta.0",
"@jupyterlab/rendermime-interfaces": "^3.9.0-beta.0",
"@jupyterlab/translation": "^4.1.0-beta.0",
"@lumino/algorithm": "^2.0.1",

@@ -61,4 +61,4 @@ "@lumino/commands": "^2.2.0",

"@lumino/widgets": "^2.3.1",
"@rjsf/core": "^5.13.2",
"@rjsf/utils": "^5.13.2",
"@rjsf/core": "^5.13.4",
"@rjsf/utils": "^5.13.4",
"react": "^18.2.0",

@@ -69,3 +69,3 @@ "react-dom": "^18.2.0",

"devDependencies": {
"@jupyterlab/testing": "^4.1.0-alpha.4",
"@jupyterlab/testing": "^4.1.0-beta.0",
"@types/jest": "^29.2.0",

@@ -72,0 +72,0 @@ "@types/react": "^18.0.26",

@@ -724,3 +724,4 @@ /*

export class WindowedList<
T extends WindowedList.IModel = WindowedList.IModel
T extends WindowedList.IModel = WindowedList.IModel,
U = any
> extends Widget {

@@ -737,18 +738,34 @@ /**

*/
constructor(options: WindowedList.IOptions<T>) {
// TODO probably needs to be able to customize outer HTML tag (could be ul / ol / table, ...)
constructor(options: WindowedList.IOptions<T, U>) {
const renderer = options.renderer ?? WindowedList.defaultRenderer;
const node = document.createElement('div');
node.className = 'jp-WindowedPanel-outer';
const innerElement = node.appendChild(document.createElement('div'));
innerElement.className = 'jp-WindowedPanel-inner';
const windowContainer = innerElement.appendChild(
node.className = 'jp-WindowedPanel';
const scrollbarElement = node.appendChild(document.createElement('div'));
scrollbarElement.classList.add('jp-WindowedPanel-scrollbar');
const list = scrollbarElement.appendChild(renderer.createScrollbar());
list.classList.add('jp-WindowedPanel-scrollbar-content');
const outerElement = node.appendChild(renderer.createOuter());
outerElement.classList.add('jp-WindowedPanel-outer');
const innerElement = outerElement.appendChild(
document.createElement('div')
);
windowContainer.className = 'jp-WindowedPanel-window';
innerElement.className = 'jp-WindowedPanel-inner';
const viewport = innerElement.appendChild(renderer.createViewport());
viewport.classList.add('jp-WindowedPanel-viewport');
super({ node });
super.layout = options.layout ?? new WindowedLayout();
this._viewModel = options.model;
this.renderer = renderer;
this._innerElement = innerElement;
this._isScrolling = null;
this._windowElement = windowContainer;
this._outerElement = outerElement;
this._resizeObserver = null;
this._scrollbarElement = scrollbarElement;
this._scrollToItem = null;

@@ -758,5 +775,10 @@ this._scrollRepaint = null;

this._updater = new Throttler(() => this.update(), 50);
this._resizeObserver = null;
this._viewModel = options.model;
this._viewport = viewport;
this._viewModel.stateChanged.connect(this.onStateChanged, this);
if (options.scrollbar) {
node.classList.add('jp-mod-virtual-scrollbar');
}
this.viewModel.stateChanged.connect(this.onStateChanged, this);
}

@@ -785,9 +807,37 @@

/**
* The outer container of the windowed list.
*/
get outerNode(): HTMLElement {
return this._outerElement;
}
/**
* Viewport
*/
get viewportNode(): HTMLDivElement {
return this._windowElement;
get viewportNode(): HTMLElement {
return this._viewport;
}
/**
* Flag to enable virtual scrollbar.
*/
get scrollbar(): boolean {
return this.node.classList.contains('jp-mod-virtual-scrollbar');
}
set scrollbar(enabled: boolean) {
if (enabled) {
this.node.classList.add('jp-mod-virtual-scrollbar');
} else {
this.node.classList.remove('jp-mod-virtual-scrollbar');
}
this._adjustDimensionsForScrollbar();
this.update();
}
/**
* The renderer for this windowed list. Set at instantiation.
*/
protected renderer: WindowedList.IRenderer<U>;
/**
* Windowed list view model

@@ -814,2 +864,7 @@ */

switch (event.type) {
case 'pointerdown':
event.preventDefault();
event.stopPropagation();
this._evtPointerDown(event as PointerEvent);
break;
case 'scroll':

@@ -893,3 +948,3 @@ this.onScroll(event);

this.viewModel.getOffsetForIndexAndAlignment(
Math.max(0, Math.min(index, this._viewModel.widgetCount - 1)),
Math.max(0, Math.min(index, this.viewModel.widgetCount - 1)),
align,

@@ -908,3 +963,3 @@ margin

super.onAfterAttach(msg);
if (this._viewModel.windowingActive) {
if (this.viewModel.windowingActive) {
this._addListeners();

@@ -917,2 +972,3 @@ } else {

this.viewModel.paddingTop = parseFloat(style.paddingTop);
this._scrollbarElement.addEventListener('pointerdown', this);
}

@@ -924,5 +980,7 @@

protected onBeforeDetach(msg: Message): void {
if (this._viewModel.windowingActive) {
if (this.viewModel.windowingActive) {
this._removeListeners();
}
this._scrollbarElement.removeEventListener('pointerdown', this);
super.onBeforeDetach(msg);
}

@@ -974,2 +1032,3 @@

super.onResize(msg);
void this._updater.invoke();
}

@@ -1009,2 +1068,5 @@

protected onUpdateRequest(msg: Message): void {
if (this.scrollbar) {
this._renderScrollbar();
}
if (this.viewModel.windowingActive) {

@@ -1030,2 +1092,48 @@ // Throttle update request

/**
* A signal that emits the index when the virtual scrollbar jumps to an item.
*/
protected jumped = new Signal<this, number>(this);
/*
* Hide the native scrollbar if necessary and update dimensions
*/
private _adjustDimensionsForScrollbar() {
const outer = this._outerElement;
const scrollbar = this._scrollbarElement;
if (this.scrollbar) {
// Query DOM
let outerScrollbarWidth = outer.offsetWidth - outer.clientWidth;
// Update DOM
// 1) The native scrollbar is hidden by shifting it out of view.
if (outerScrollbarWidth == 0) {
// If the scrollbar width is zero, one of the following is true:
// - (a) the content is not overflowing
// - (b) the browser uses overlay scrollbars
// In (b) the overlay scrollbars could show up even even if
// occluded by a child element; to prevent this resulting in
// double scrollbar we shift the content by an arbitrary offset.
outerScrollbarWidth = 1000;
outer.style.paddingRight = `${outerScrollbarWidth}px`;
outer.style.boxSizing = 'border-box';
} else {
outer.style.paddingRight = '0';
}
outer.style.width = `calc(100% + ${outerScrollbarWidth}px)`;
// 2) The inner window is shrank to accommodate the virtual scrollbar
this._innerElement.style.marginRight = `${scrollbar.offsetWidth}px`;
} else {
// Reset all styles that may have been touched.
outer.style.width = '100%';
this._innerElement.style.marginRight = '0';
outer.style.paddingRight = '0';
outer.style.boxSizing = '';
}
}
/**
* Add listeners for viewport, contents and the virtual scrollbar.
*/
private _addListeners() {

@@ -1043,18 +1151,35 @@ if (!this._resizeObserver) {

}
this.node.addEventListener('scroll', this, passiveIfSupported);
this._windowElement.style.position = 'absolute';
this._outerElement.addEventListener('scroll', this, passiveIfSupported);
this._viewport.style.position = 'absolute';
this._scrollbarResizeObserver = new ResizeObserver(
this._adjustDimensionsForScrollbar.bind(this)
);
this._scrollbarResizeObserver.observe(this._outerElement);
this._scrollbarResizeObserver.observe(this._scrollbarElement);
}
/**
* Turn off windowing related styles in the viewport.
*/
private _applyNoWindowingStyles() {
this._windowElement.style.position = 'relative';
this._windowElement.style.top = '0px';
this._viewport.style.position = 'relative';
this._viewport.style.top = '0px';
}
/**
* Remove listeners for viewport and contents (but not the virtual scrollbar).
*/
private _removeListeners() {
this.node.removeEventListener('scroll', this);
this._outerElement.removeEventListener('scroll', this);
this._resizeObserver?.disconnect();
this._resizeObserver = null;
this._scrollbarResizeObserver?.disconnect();
this._scrollbarResizeObserver = null;
this._applyNoWindowingStyles();
}
/**
* Update viewport and DOM state.
*/
private _update(): void {

@@ -1113,4 +1238,4 @@ if (this.isDisposed || !this.layout) {

);
this._windowElement.style.top = `${top}px`;
this._windowElement.style.minHeight = `${minHeight}px`;
this._viewport.style.top = `${top}px`;
this._viewport.style.minHeight = `${minHeight}px`;
} else {

@@ -1120,5 +1245,5 @@ // Update inner container height

// Update position of window container
this._windowElement.style.top = `0px`;
this._windowElement.style.minHeight = `0px`;
// Update position of viewport node
this._viewport.style.top = `0px`;
this._viewport.style.minHeight = `0px`;
}

@@ -1128,3 +1253,3 @@

if (this._scrollUpdateWasRequested) {
this.node.scrollTop = this.viewModel.scrollOffset;
this._outerElement.scrollTop = this.viewModel.scrollOffset;
this._scrollUpdateWasRequested = false;

@@ -1136,3 +1261,3 @@ }

let index2 = -1;
for (const w of this.viewportNode.children) {
for (const w of this._viewport.children) {
const currentIdx = parseInt(

@@ -1150,2 +1275,5 @@ (w as HTMLElement).dataset.windowedListIndex!,

/**
* Handle viewport content (e.g. widgets) resize.
*/
private _onWidgetResize(entries: ResizeObserverEntry[]): void {

@@ -1187,2 +1315,5 @@ this._resetScrollToItem();

/**
* Clear any outstanding timeout and enqueue scrolling to a new item.
*/
private _resetScrollToItem(): void {

@@ -1204,10 +1335,50 @@ if (this._resetScrollToItemTimeout) {

protected _viewModel: T;
private _innerElement: HTMLDivElement;
/**
* Render virtual scrollbar.
*/
private _renderScrollbar(): void {
const { node, renderer, viewModel } = this;
const content = node.querySelector('.jp-WindowedPanel-scrollbar-content')!;
while (content.firstChild) {
content.removeChild(content.firstChild);
}
const list = viewModel.itemsList;
const count = list?.length ?? viewModel.widgetCount;
for (let index = 0; index < count; index += 1) {
const item = list?.get?.(index);
const element = renderer.createScrollbarItem(this, index, item);
element.classList.add('jp-WindowedPanel-scrollbar-item');
element.dataset.index = `${index}`;
content.appendChild(element);
}
}
/**
* Handle `pointerdown` events on the virtual scrollbar.
*/
private _evtPointerDown(event: PointerEvent): void {
let target = event.target as HTMLElement;
while (target && target.parentElement) {
if (target.hasAttribute('data-index')) {
const index = parseInt(target.getAttribute('data-index')!, 10);
return void (async () => {
await this.scrollToItem(index);
this.jumped.emit(index);
})();
}
target = target.parentElement;
}
}
private _innerElement: HTMLElement;
private _isParentHidden: boolean;
private _isScrolling: PromiseDelegate<void> | null;
private _needsUpdate = false;
private _windowElement: HTMLDivElement;
private _outerElement: HTMLElement;
private _resetScrollToItemTimeout: number | null;
private _resizeObserver: ResizeObserver | null;
private _scrollbarElement: HTMLElement;
private _scrollbarResizeObserver: ResizeObserver | null;
private _scrollRepaint: number | null;

@@ -1217,2 +1388,4 @@ private _scrollToItem: [number, WindowedList.ScrollToAlign] | null;

private _updater: Throttler;
private _viewModel: T;
private _viewport: HTMLElement;
}

@@ -1365,5 +1538,45 @@

/**
* The default renderer class for windowed lists.
*/
export class Renderer<T = any> implements IRenderer<T> {
/**
* Create the outer, root element of the windowed list.
*/
createOuter(): HTMLElement {
return document.createElement('div');
}
/**
* Create the virtual scrollbar element.
*/
createScrollbar(): HTMLOListElement {
return document.createElement('ol');
}
/**
* Create an individual item rendered in the scrollbar.
*/
createScrollbarItem(_: WindowedList, index: number): HTMLLIElement {
const li = document.createElement('li');
li.appendChild(document.createTextNode(`${index}`));
return li;
}
/**
* Create the viewport element into which virtualized children are added.
*/
createViewport(): HTMLElement {
return document.createElement('div');
}
}
/**
* The default renderer for windowed lists.
*/
export const defaultRenderer = new Renderer();
/**
* Windowed list model interface
*/
export interface IModel extends IDisposable {
export interface IModel<T = any> extends IDisposable {
/**

@@ -1412,2 +1625,3 @@ * Provide a best guess for the widget size at position index

): number;
/**

@@ -1446,2 +1660,3 @@ * Compute the items range to display.

itemsList: {
get?: (index: number) => T;
length: number;

@@ -1551,3 +1766,4 @@ changed: ISignal<any, IObservableList.IChangedArgs<any>>;

export interface IOptions<
T extends WindowedList.IModel = WindowedList.IModel
T extends WindowedList.IModel = WindowedList.IModel,
U = any
> {

@@ -1562,5 +1778,44 @@ /**

layout?: WindowedLayout;
/**
* A renderer for the elements of the windowed list.
*/
renderer?: IRenderer<U>;
/**
* Whether the windowed list should display a scrollbar UI.
*/
scrollbar?: boolean;
}
/**
* A windowed list element renderer.
*/
export interface IRenderer<T = any> {
/**
* Create the outer, root element of the windowed list.
*/
createOuter(): HTMLElement;
/**
* Create the virtual scrollbar element.
*/
createScrollbar(): HTMLElement;
/**
* Create an individual item rendered in the scrollbar.
*/
createScrollbarItem(
list: WindowedList,
index: number,
item: T | undefined
): HTMLElement;
/**
* Create the viewport element into which virtualized children are added.
*/
createViewport(): HTMLElement;
}
/**
* Item list metadata

@@ -1567,0 +1822,0 @@ */

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc