CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/npm-jupyterlab--ui-components

JupyterLab React-based UI components library providing icons, forms, buttons, and widgets for consistent interface development.

43%

Overall

Evaluation43%

1.59x

Agent success when using this tile

Overview
Eval results
Files

advanced-widgets.mddocs/

Advanced Widgets

Specialized widgets for complex use cases including windowed lists, collapsible panels, search interfaces, and layout components. These widgets handle large datasets, provide advanced interactions, and support complex UI patterns.

Capabilities

WindowedList

High-performance widget for rendering large lists with virtual scrolling and dynamic sizing.

/**
 * Abstract model for windowed list data and behavior
 */
abstract class WindowedListModel implements WindowedList.IModel {
  /**
   * Create windowed list model
   * @param options - Model configuration options
   */
  constructor(options?: WindowedList.IModelOptions);
  
  // Abstract methods that must be implemented
  /** Estimate size of widget at given index */
  abstract estimateWidgetSize: (index: number) => number;
  /** Create widget for rendering item at index */
  abstract widgetRenderer: (index: number) => Widget;
  
  // Scroll behavior configuration
  readonly scrollDownThreshold: number = 1;
  readonly scrollUpThreshold: number = 0;
  paddingTop: number = 0;
  
  /** Total height of the viewport */
  get height(): number;
  set height(h: number);
  
  /** Observable list of items */
  get itemsList(): ISimpleObservableList | null;
  set itemsList(v: ISimpleObservableList | null);
  
  /** Number of items to render outside visible area */
  get overscanCount(): number;
  set overscanCount(newValue: number);
  
  /** Current scroll position */
  get scrollOffset(): number;
  set scrollOffset(offset: number);
  
  /** Total number of widgets/items */
  get widgetCount(): number;
  set widgetCount(newValue: number);
  
  /** Whether windowing optimization is active */
  get windowingActive(): boolean;
  set windowingActive(newValue: boolean);
  
  /** Signal emitted when model state changes */
  get stateChanged(): ISignal<WindowedListModel, IChangedArgs<any, any, string>>;
  
  // Methods for size and scroll calculations
  getEstimatedTotalSize(): number;
  getOffsetForIndexAndAlignment(/* parameters */): number;
  getRangeToRender(): WindowedList.WindowIndex | null;
  getSpan(startIndex: number, stopIndex: number): [number, number];
  resetAfterIndex(index: number): void;
  setWidgetSize(sizes: { index: number; size: number }[]): boolean;
}

/**
 * High-performance windowed list widget for large datasets
 */
class WindowedList<T extends WindowedList.IModel = WindowedList.IModel, U = any> extends Widget {
  static readonly DEFAULT_WIDGET_SIZE = 50;
  
  /**
   * Create windowed list widget
   * @param options - Widget configuration options
   */
  constructor(options: WindowedList.IOptions<T, U>);
  
  /** Whether parent container is hidden */
  get isParentHidden(): boolean;
  set isParentHidden(v: boolean);
  
  /** Layout manager for the list */
  get layout(): WindowedLayout;
  
  /** Outer container element */
  get outerNode(): HTMLElement;
  
  /** Viewport scrolling element */
  get viewportNode(): HTMLElement;
  
  /** Whether scrollbar is enabled */
  get scrollbar(): boolean;
  set scrollbar(enabled: boolean);
  
  /**
   * Scroll to specific offset
   * @param scrollOffset - Pixel offset to scroll to
   */
  scrollTo(scrollOffset: number): void;
  
  /**
   * Scroll to specific item index
   * @param index - Item index to scroll to
   * @param align - Alignment behavior
   * @param margin - Additional margin
   * @param alignPreference - Alignment preference
   * @returns Promise that resolves when scroll completes
   */
  scrollToItem(
    index: number,
    align?: WindowedList.ScrollToAlign,
    margin?: number,
    alignPreference?: WindowedList.BaseScrollToAlignment
  ): Promise<void>;
}

namespace WindowedList {
  interface IModel<T = any> extends IDisposable {
    estimateWidgetSize: (index: number) => number;
    widgetRenderer: (index: number) => Widget;
    // ... extensive interface with many properties
  }
  
  interface IOptions<T extends WindowedList.IModel = WindowedList.IModel, U = any> {
    /** Model instance */
    model: T;
    /** Custom layout */
    layout?: WindowedLayout;
    /** Custom renderer */
    renderer?: IRenderer<U>;
    /** Enable scrollbar */
    scrollbar?: boolean;
  }
  
  interface IRenderer<T = any> {
    createOuter(): HTMLElement;
    createScrollbar(): HTMLElement;
    createScrollbarViewportIndicator?(): HTMLElement;
    createScrollbarItem(list: WindowedList, index: number, item: T | undefined): HTMLElement | IRenderer.IScrollbarItem;
    createViewport(): HTMLElement;
  }
  
  type BaseScrollToAlignment = 'center' | 'top-center' | 'start' | 'end';
  type ScrollToAlign = 'auto' | 'smart' | BaseScrollToAlignment;
  type WindowIndex = [number, number, number, number];
}

/**
 * Observable list interface for windowed lists
 */
interface ISimpleObservableList<T> {
  readonly length: number;
  get(index: number): T | undefined;
  set(index: number, value: T): void;
  push(...values: T[]): number;
  insert(index: number, value: T): void;
  remove(index: number): T | undefined;
  clear(): void;
}

Usage Examples:

import { WindowedList, WindowedListModel, ReactWidget } from '@jupyterlab/ui-components';
import { Widget } from '@lumino/widgets';

// Custom model for file list
class FileListModel extends WindowedListModel {
  constructor(private files: FileInfo[]) {
    super();
    this.widgetCount = files.length;
  }

  estimateWidgetSize = (index: number): number => {
    // Estimate size based on file type
    const file = this.files[index];
    return file?.isDirectory ? 40 : 30;
  };

  widgetRenderer = (index: number): Widget => {
    const file = this.files[index];
    return ReactWidget.create(
      <div className="file-item">
        <span className="file-icon">{file.isDirectory ? '📁' : '📄'}</span>
        <span className="file-name">{file.name}</span>
        <span className="file-size">{file.size}</span>
      </div>
    );
  };
}

// Create windowed file list
const fileModel = new FileListModel(largeFileArray);
const fileList = new WindowedList({
  model: fileModel,
  scrollbar: true
});

// Handle large datasets efficiently
fileModel.itemsList = new ObservableList(largeFileArray);
fileModel.windowingActive = true;
fileModel.overscanCount = 10; // Render 10 extra items outside viewport

// Scroll to specific file
async function scrollToFile(fileName: string) {
  const index = largeFileArray.findIndex(f => f.name === fileName);
  if (index >= 0) {
    await fileList.scrollToItem(index, 'center');
  }
}

// Custom renderer for complex items
class CustomFileRenderer implements WindowedList.IRenderer<FileInfo> {
  createOuter(): HTMLElement {
    const outer = document.createElement('div');
    outer.className = 'custom-file-list';
    return outer;
  }

  createViewport(): HTMLElement {
    const viewport = document.createElement('div');
    viewport.className = 'file-viewport';
    return viewport;
  }

  createScrollbar(): HTMLElement {
    const scrollbar = document.createElement('div');
    scrollbar.className = 'custom-scrollbar';
    return scrollbar;
  }

  createScrollbarItem(list: WindowedList, index: number, file: FileInfo | undefined) {
    const item = document.createElement('div');
    item.className = 'scrollbar-item';
    if (file) {
      item.textContent = file.name.charAt(0).toUpperCase();
    }
    return item;
  }
}

PanelWithToolbar

Panel widget that combines content area with integrated toolbar.

/**
 * Panel widget with integrated toolbar
 */
class PanelWithToolbar extends Panel implements Toolbar.IWidgetToolbar {
  /**
   * Create panel with toolbar
   * @param options - Panel configuration options
   */
  constructor(options?: PanelWithToolbar.IOptions);
  
  /** Integrated toolbar instance */
  get toolbar(): Toolbar;
}

namespace PanelWithToolbar {
  interface IOptions extends Panel.IOptions {
    /** Custom toolbar instance */
    toolbar?: Toolbar;
  }
}

Usage Examples:

import { PanelWithToolbar, Toolbar, ToolbarButton } from '@jupyterlab/ui-components';
import { saveIcon, refreshIcon } from '@jupyterlab/ui-components';

// Create panel with integrated toolbar
const panel = new PanelWithToolbar();
panel.title.label = 'File Editor';
panel.addClass('editor-panel');

// Add buttons to toolbar
const saveButton = new ToolbarButton({
  icon: saveIcon,
  tooltip: 'Save file',
  onClick: () => saveCurrentFile()
});

const refreshButton = new ToolbarButton({
  icon: refreshIcon,
  tooltip: 'Refresh content',
  onClick: () => refreshContent()
});

panel.toolbar.addItem('save', saveButton);
panel.toolbar.addItem('refresh', refreshButton);

// Add content widgets
const editorWidget = new CodeEditorWrapper();
const statusWidget = new StatusBar();

panel.addWidget(editorWidget);
panel.addWidget(statusWidget);

// Custom toolbar for specific use case
const customToolbar = new Toolbar();
customToolbar.addClass('custom-editor-toolbar');

const customPanel = new PanelWithToolbar({
  toolbar: customToolbar
});

SidePanel

Widget for sidebars with accordion-style layout and toolbar integration.

/**
 * Widget for sidebars with accordion layout
 */
class SidePanel extends Widget {
  /**
   * Create side panel
   * @param options - Side panel configuration options
   */
  constructor(options?: SidePanel.IOptions);
  
  /** Content panel for main widgets */
  get content(): Panel;
  
  /** Header panel for titles/controls */
  get header(): Panel;
  
  /** Integrated toolbar */
  get toolbar(): Toolbar;
  
  /** Array of contained widgets */
  get widgets(): ReadonlyArray<Widget>;
  
  /**
   * Add widget to side panel
   * @param widget - Widget with toolbar support
   */
  addWidget(widget: Toolbar.IWidgetToolbar): void;
  
  /**
   * Insert widget at specific index
   * @param index - Position to insert at
   * @param widget - Widget with toolbar support
   */
  insertWidget(index: number, widget: Toolbar.IWidgetToolbar): void;
}

namespace SidePanel {
  interface IOptions extends AccordionPanel.IOptions {
    /** Custom content panel */
    content?: Panel;
    /** Custom header panel */
    header?: Panel;
    /** Custom toolbar */
    toolbar?: Toolbar;
    /** Translator for internationalization */
    translator?: ITranslator;
  }
}

Usage Examples:

import { SidePanel, ReactWidget } from '@jupyterlab/ui-components';

// Create side panel for file browser
const filePanel = new SidePanel();
filePanel.title.label = 'Files';
filePanel.addClass('file-browser-panel');

// Create widgets for side panel sections
class FileTreeWidget extends ReactWidget {
  constructor() {
    super();
    this.title.label = 'File Tree';
    this.addClass('file-tree-widget');
  }

  protected render() {
    return <div>File tree content here</div>;
  }
}

class SearchWidget extends ReactWidget {
  constructor() {
    super();
    this.title.label = 'Search';
    this.addClass('search-widget');
  }

  protected render() {
    return <div>Search interface here</div>;
  }
}

// Add sections to side panel
const fileTree = new FileTreeWidget();
const searchWidget = new SearchWidget();

filePanel.addWidget(fileTree);
filePanel.addWidget(searchWidget);

// Access panel components
console.log('Content panel:', filePanel.content);
console.log('Header panel:', filePanel.header);
console.log('Toolbar:', filePanel.toolbar);

// Add custom toolbar items
const refreshButton = new ToolbarButton({
  icon: refreshIcon,
  tooltip: 'Refresh files'
});
filePanel.toolbar.addItem('refresh', refreshButton);

AccordionToolbar

Specialized accordion panel with toolbar support and custom rendering.

/**
 * Accordion panel with toolbar support
 */
namespace AccordionToolbar {
  class Renderer extends AccordionPanel.Renderer {
    /**
     * Create collapse icon for section headers
     * @param data - Title data for the section
     * @returns HTML element for collapse icon
     */
    createCollapseIcon(data: Title<Widget>): HTMLElement;
    
    /**
     * Create section title element
     * @param data - Title data for the section
     * @returns HTML element for section title
     */
    createSectionTitle(data: Title<Widget>): HTMLElement;
  }
  
  /** Default renderer instance */
  const defaultRenderer: Renderer;
  
  /**
   * Create layout for accordion with toolbar support
   * @param options - Accordion panel options
   * @returns Configured accordion layout
   */
  function createLayout(options: AccordionPanel.IOptions): AccordionLayout;
}

Usage Examples:

import { AccordionToolbar, AccordionPanel } from '@jupyterlab/ui-components';

// Create accordion with custom renderer
const accordion = new AccordionPanel({
  renderer: AccordionToolbar.defaultRenderer
});

// Create layout with toolbar support
const layout = AccordionToolbar.createLayout({
  renderer: AccordionToolbar.defaultRenderer
});

// Custom accordion with enhanced titles
class EnhancedAccordion extends AccordionPanel {
  constructor() {
    super({
      renderer: new AccordionToolbar.Renderer()
    });
  }
}

const enhancedAccordion = new EnhancedAccordion();

// Add sections with custom titles
const section1 = new ReactWidget();
section1.title.label = 'Configuration';
section1.title.iconClass = 'jp-SettingsIcon';

const section2 = new ReactWidget();
section2.title.label = 'Advanced Options';
section2.title.iconClass = 'jp-AdvancedIcon';

enhancedAccordion.addWidget(section1);
enhancedAccordion.addWidget(section2);

Menu Components

Enhanced menu system with ranking and disposable items.

/**
 * Extensible menu interface with ranking support
 */
interface IRankedMenu extends IDisposable {
  /**
   * Add group of menu items with shared rank
   * @param items - Array of menu item options
   * @param rank - Rank for ordering (default: 100)
   * @returns Disposable for removing the group
   */
  addGroup(items: Menu.IItemOptions[], rank?: number): IDisposable;
  
  /**
   * Add single menu item with rank
   * @param options - Menu item options with rank
   * @returns Disposable menu item
   */
  addItem(options: IRankedMenu.IItemOptions): IDisposable;
  
  /** Read-only array of menu items */
  readonly items: ReadonlyArray<Menu.IItem>;
  
  /** Optional rank for this menu */
  readonly rank?: number;
}

namespace IRankedMenu {
  const DEFAULT_RANK = 100;
  
  interface IItemOptions extends Menu.IItemOptions {
    /** Item rank for ordering */
    rank?: number;
  }
  
  interface IOptions extends Menu.IOptions {
    /** Include separators between ranked groups */
    includeSeparators?: boolean;
    /** Menu rank */
    rank?: number;
  }
}

/**
 * Menu implementation with ranking support
 */
class RankedMenu extends Menu implements IRankedMenu {
  /**
   * Create ranked menu
   * @param options - Menu configuration options
   */
  constructor(options: IRankedMenu.IOptions);
  
  /** Menu rank */
  get rank(): number | undefined;
  
  /**
   * Add group of items with shared rank
   */
  addGroup(items: IRankedMenu.IItemOptions[], rank?: number): IDisposable;
  
  /**
   * Add single item with rank
   */
  addItem(options: IRankedMenu.IItemOptions): IDisposableMenuItem;
  
  /**
   * Get rank of item at index
   * @param index - Item index
   * @returns Item rank
   */
  getRankAt(index: number): number;
}

/**
 * Disposable menu item interface
 */
interface IDisposableMenuItem extends IDisposable {
  // Menu item that can be disposed
}

Usage Examples:

import { RankedMenu, IRankedMenu, CommandRegistry } from '@jupyterlab/ui-components';

// Create ranked menu with commands
const commands = new CommandRegistry();

commands.addCommand('file:new', {
  label: 'New File',
  execute: () => console.log('New file')
});

commands.addCommand('file:open', {
  label: 'Open File', 
  execute: () => console.log('Open file')
});

const fileMenu = new RankedMenu({
  commands,
  includeSeparators: true
});

// Add file operations group (high priority)
const fileGroup = fileMenu.addGroup([
  { command: 'file:new', rank: 10 },
  { command: 'file:open', rank: 20 }
], 1);

// Add recent files group (lower priority)
const recentGroup = fileMenu.addGroup([
  { type: 'submenu', submenu: recentFilesMenu, rank: 10 }
], 50);

// Add individual items
const saveItem = fileMenu.addItem({
  command: 'file:save',
  rank: 30
});

// Clean up when done
function cleanup() {
  fileGroup.dispose();
  recentGroup.dispose(); 
  saveItem.dispose();
}

// Check item ranks
for (let i = 0; i < fileMenu.items.length; i++) {
  console.log(`Item ${i} rank:`, fileMenu.getRankAt(i));
}

Styling Utilities

Node styling utilities for consistent widget appearance.

/**
 * Node styling utilities
 */
namespace Styling {
  /**
   * Apply styling to HTML element
   * @param node - Element to style
   * @param className - CSS class to apply
   */
  function styleNode(node: HTMLElement, className?: string): void;
  
  /**
   * Apply styling to elements by tag name
   * @param node - Container element
   * @param tagName - Tag name to target
   * @param className - CSS class to apply
   */
  function styleNodeByTag(node: HTMLElement, tagName: string, className?: string): void;
  
  /**
   * Wrap select element with custom styling
   * @param node - Select element to wrap
   * @param multiple - Whether select allows multiple selections
   * @returns Wrapped container element
   */
  function wrapSelect(node: HTMLSelectElement, multiple?: boolean): HTMLElement;
}

Usage Examples:

import { Styling } from '@jupyterlab/ui-components';

// Style widget nodes
class CustomWidget extends Widget {
  onAfterAttach() {
    super.onAfterAttach();
    
    // Apply JupyterLab styling
    Styling.styleNode(this.node, 'jp-CustomWidget');
    
    // Style all buttons in widget
    Styling.styleNodeByTag(this.node, 'button', 'jp-Button');
    
    // Style all inputs
    Styling.styleNodeByTag(this.node, 'input', 'jp-InputGroup-input');
  }
}

// Wrap select elements
const selectElement = document.createElement('select');
selectElement.innerHTML = `
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
`;

const wrappedSelect = Styling.wrapSelect(selectElement);
document.body.appendChild(wrappedSelect);

// Multi-select wrapper
const multiSelect = document.createElement('select');
multiSelect.multiple = true;
const wrappedMulti = Styling.wrapSelect(multiSelect, true);
tessl i tessl/npm-jupyterlab--ui-components@4.4.0

docs

advanced-widgets.md

components.md

forms.md

icons.md

index.md

toolbars.md

utilities.md

widgets.md

tile.json