JupyterLab React-based UI components library providing icons, forms, buttons, and widgets for consistent interface development.
Lumino widget classes that provide JupyterLab-compatible components with signals, lifecycle management, and integration with the Lumino widget framework. These widgets can be used in both traditional Lumino applications and modern React-based interfaces.
Abstract base class for creating Lumino widgets that render React components.
/**
* Abstract Lumino widget that renders React components
* Bridges React components with Lumino's widget system
*/
abstract class ReactWidget extends Widget {
/**
* Create a ReactWidget from a React element
* @param element - React element to render
* @returns ReactWidget instance
*/
static create(element: ReactRenderElement): ReactWidget;
/**
* Abstract method to define React content
* @returns React element to render or null
*/
protected abstract render(): ReactRenderElement | null;
/** Promise that resolves when render is complete */
renderPromise?: Promise<void>;
}Usage Examples:
import { ReactWidget } from '@jupyterlab/ui-components';
import React from 'react';
// Custom widget with React content
class MyWidget extends ReactWidget {
constructor() {
super();
this.addClass('my-custom-widget');
this.title.label = 'My Widget';
}
protected render() {
return (
<div>
<h2>Hello from React!</h2>
<button onClick={() => this.handleClick()}>
Click me
</button>
</div>
);
}
private handleClick() {
console.log('Button clicked in widget');
}
}
// Create widget from React element
const quickWidget = ReactWidget.create(
<div>
<p>Quick widget content</p>
</div>
);Advanced ReactWidget with model support and automatic re-rendering on model changes.
/**
* Abstract ReactWidget with a model that triggers re-renders
*/
abstract class VDomRenderer<T extends VDomRenderer.IModel | null = null> extends ReactWidget {
/**
* Create a VDomRenderer with optional model
* @param model - Model instance or null
*/
constructor(model?: T);
/** Signal emitted when model changes */
get modelChanged(): ISignal<this, void>;
/** Current model instance */
set model(newValue: T);
get model(): T;
}
namespace VDomRenderer {
/**
* Interface for VDomRenderer models
*/
interface IModel extends IDisposable {
/** Signal emitted when state changes */
readonly stateChanged: ISignal<this, void>;
}
}
/**
* Concrete implementation of VDomRenderer model
*/
class VDomModel implements VDomRenderer.IModel {
/** Signal for state changes */
readonly stateChanged: Signal<this, void>;
/** Check if model is disposed */
get isDisposed(): boolean;
/** Dispose of the model */
dispose(): void;
}Usage Examples:
import { VDomRenderer, VDomModel, ISignal } from '@jupyterlab/ui-components';
// Custom model for widget data
class CounterModel extends VDomModel {
constructor() {
super();
this._count = 0;
}
get count(): number {
return this._count;
}
increment(): void {
this._count++;
this.stateChanged.emit();
}
private _count: number;
}
// Widget that uses the model
class CounterWidget extends VDomRenderer<CounterModel> {
constructor() {
super(new CounterModel());
this.addClass('counter-widget');
}
protected render() {
return (
<div>
<p>Count: {this.model.count}</p>
<button onClick={() => this.model.increment()}>
Increment
</button>
</div>
);
}
}
// Widget automatically re-renders when model changes
const counter = new CounterWidget();React component for connecting to Lumino signals within React components.
/**
* React component for listening to Lumino signals
*/
interface IUseSignalProps<SENDER, ARGS> {
/** Signal to listen to */
signal: ISignal<SENDER, ARGS>;
/** Initial sender value */
initialSender?: SENDER;
/** Initial arguments value */
initialArgs?: ARGS;
/** Render function called with signal data */
children: (sender?: SENDER, args?: ARGS) => React.ReactNode;
/** Function to determine if component should update */
shouldUpdate?: (sender: SENDER, args: ARGS) => boolean;
}
class UseSignal<SENDER, ARGS> extends React.Component<
IUseSignalProps<SENDER, ARGS>,
IUseSignalState<SENDER, ARGS>
>;Usage Examples:
import React from 'react';
import { UseSignal, ReactWidget } from '@jupyterlab/ui-components';
import { Signal } from '@lumino/signaling';
// Widget with signal
class DataWidget extends ReactWidget {
constructor() {
super();
this._dataChanged = new Signal(this);
}
get dataChanged(): ISignal<this, string[]> {
return this._dataChanged;
}
updateData(newData: string[]): void {
this._dataChanged.emit(newData);
}
protected render() {
return (
<div>
<UseSignal signal={this.dataChanged}>
{(sender, data) => (
<ul>
{data?.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
)}
</UseSignal>
</div>
);
}
private _dataChanged: Signal<this, string[]>;
}
// Usage with shouldUpdate
<UseSignal
signal={mySignal}
shouldUpdate={(sender, args) => args.length > 0}
>
{(sender, args) => <div>Items: {args?.length}</div>}
</UseSignal>Toggle switch widget with value tracking and change signals.
/**
* Switch widget for boolean toggle functionality
*/
class Switch extends Widget {
constructor();
/** Current switch value */
get value(): boolean;
set value(newValue: boolean);
/** Signal emitted when value changes */
get valueChanged(): ISignal<this, IChangedArgs<boolean, boolean, 'value'>>;
/** Switch label text */
get label(): string;
set label(x: string);
/** Switch caption text */
get caption(): string;
set caption(x: string);
}Usage Examples:
import { Switch } from '@jupyterlab/ui-components';
// Basic switch usage
const debugSwitch = new Switch();
debugSwitch.label = 'Enable Debug Mode';
debugSwitch.caption = 'Shows additional debugging information';
debugSwitch.value = false;
// Listen for changes
debugSwitch.valueChanged.connect((sender, args) => {
console.log(`Debug mode ${args.newValue ? 'enabled' : 'disabled'}`);
updateDebugMode(args.newValue);
});
// Programmatically toggle
function toggleDebug() {
debugSwitch.value = !debugSwitch.value;
}
// Add to layout
const panel = new Panel();
panel.addWidget(debugSwitch);Collapsible container widget for expandable content sections.
/**
* Collapsible panel widget that can contain other widgets
*/
class Collapser<T extends Widget = Widget> extends Widget {
/**
* Create a Collapser widget
* @param options - Configuration options
*/
constructor(options: Collapser.IOptions<T>);
/** The contained widget */
get widget(): T;
set widget(widget: T);
/** Whether the collapser is collapsed */
get collapsed(): boolean;
set collapsed(value: boolean);
/** Signal emitted when collapse state changes */
get collapseChanged(): ISignal<Collapser, void>;
/** Toggle the collapse state */
toggle(): void;
/** Dispose of the widget and its contents */
dispose(): void;
}
namespace Collapser {
interface IOptions<T extends Widget = Widget> extends Widget.IOptions {
/** Widget to contain */
widget: T;
/** Initial collapsed state */
collapsed?: boolean;
}
}Usage Examples:
import { Collapser, ReactWidget } from '@jupyterlab/ui-components';
// Create content widget
const contentWidget = ReactWidget.create(
<div>
<h3>Expandable Content</h3>
<p>This content can be collapsed.</p>
</div>
);
// Create collapser
const collapser = new Collapser({
widget: contentWidget,
collapsed: true
});
// Listen for collapse changes
collapser.collapseChanged.connect(() => {
console.log(`Panel ${collapser.collapsed ? 'collapsed' : 'expanded'}`);
});
// Control programmatically
function expandPanel() {
collapser.collapsed = false;
}
function collapsePanel() {
collapser.collapsed = true;
}
// Toggle with animation
function animatedToggle() {
collapser.toggle();
}Loading spinner widget for indicating progress.
/**
* Spinner widget for showing loading states
*/
class Spinner extends Widget {
constructor();
}Usage Examples:
import { Spinner, Panel } from '@jupyterlab/ui-components';
// Basic spinner
const loadingSpinner = new Spinner();
loadingSpinner.addClass('my-loading-spinner');
// Add to layout
const container = new Panel();
container.addWidget(loadingSpinner);
// Show/hide spinner based on loading state
async function loadData() {
container.addWidget(loadingSpinner);
try {
const data = await fetchData();
processData(data);
} finally {
loadingSpinner.parent = null; // Remove from layout
}
}Widget that wraps an HTML iframe element with security and loading options.
/**
* Lumino widget that wraps an IFrame with security options
*/
class IFrame extends Widget {
/**
* Create an IFrame widget
* @param options - IFrame configuration options
*/
constructor(options?: IFrame.IOptions);
/** Referrer policy for the iframe */
get referrerPolicy(): IFrame.ReferrerPolicy;
set referrerPolicy(value: IFrame.ReferrerPolicy);
/** Loading behavior for the iframe */
get loading(): IFrame.Loading;
set loading(value: IFrame.Loading);
/** Sandbox restrictions for the iframe */
get sandbox(): IFrame.SandboxExceptions[];
set sandbox(values: IFrame.SandboxExceptions[]);
/** URL to load in the iframe */
get url(): string;
set url(url: string);
}
namespace IFrame {
type ReferrerPolicy =
| 'no-referrer'
| 'no-referrer-when-downgrade'
| 'origin'
| 'origin-when-cross-origin'
| 'same-origin'
| 'strict-origin'
| 'strict-origin-when-cross-origin'
| 'unsafe-url';
type SandboxExceptions =
| 'allow-downloads'
| 'allow-forms'
| 'allow-modals'
| 'allow-orientation-lock'
| 'allow-pointer-lock'
| 'allow-popups'
| 'popups-to-escape-sandbox'
| 'allow-presentation'
| 'allow-same-origin'
| 'allow-scripts'
| 'allow-storage-access-by-user-activation'
| 'allow-top-navigation'
| 'allow-top-navigation-by-user-activation';
type Loading = 'eager' | 'lazy';
interface IOptions {
/** Sandbox exceptions to allow */
sandbox?: SandboxExceptions[];
/** Referrer policy */
referrerPolicy?: ReferrerPolicy;
/** Loading behavior */
loading?: Loading;
}
}Usage Examples:
import { IFrame } from '@jupyterlab/ui-components';
// Basic iframe
const docViewer = new IFrame({
loading: 'lazy',
referrerPolicy: 'strict-origin-when-cross-origin'
});
docViewer.url = 'https://jupyter.org/documentation';
// Secure iframe with restricted sandbox
const secureFrame = new IFrame({
sandbox: ['allow-scripts', 'allow-same-origin'],
referrerPolicy: 'no-referrer'
});
secureFrame.url = 'https://trusted-content.example.com';
// Iframe for user-generated content
const userContentFrame = new IFrame({
sandbox: [], // No exceptions - maximum security
loading: 'lazy'
});
// Update URL dynamically
function loadDocument(url: string) {
docViewer.url = url;
}
// Modify security settings
function allowForms() {
const current = secureFrame.sandbox;
secureFrame.sandbox = [...current, 'allow-forms'];
}tessl i tessl/npm-jupyterlab--ui-components@4.4.0evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10