JupyterLab React-based UI components library providing icons, forms, buttons, and widgets for consistent interface development.
Advanced form rendering capabilities using React JSON Schema Form (RJSF) with JupyterLab-specific customizations. The form system provides dynamic form generation, validation, and custom field rendering with full TypeScript support.
Generic RJSF form component with JupyterLab customizations and styling.
/**
* Generic RJSF form component with JupyterLab styling and customizations
*/
interface IFormComponentProps<T = ReadonlyJSONObject> extends FormProps<T>, FormComponent.ILabCustomizerProps {
/** Current form data */
formData: T;
/** Callback for form data changes */
onChange: (e: IChangeEvent<T>) => any;
/** Additional form context */
formContext?: unknown;
}
/**
* Main form component for rendering JSON Schema forms
* @param props - Form configuration and data
* @returns JSX form element
*/
function FormComponent(props: IFormComponentProps): JSX.Element;
namespace FormComponent {
interface IButtonProps {
/** Button style variant for array controls */
buttonStyle?: 'icons' | 'text';
/** Translator for internationalization */
translator?: ITranslator;
}
interface ILabCustomizerProps extends IButtonProps {
/** Use compact form layout */
compact?: boolean;
/** Show indicators for values that differ from defaults */
showModifiedFromDefault?: boolean;
}
}
/**
* Default UI options for forms
*/
const DEFAULT_UI_OPTIONS = {
submitButtonOptions: { norender: true }
};Usage Examples:
import React, { useState } from 'react';
import { FormComponent, DEFAULT_UI_OPTIONS } from '@jupyterlab/ui-components';
import { JSONSchema7 } from 'json-schema';
// Basic form usage
interface UserSettings {
theme: string;
fontSize: number;
enableAutoSave: boolean;
}
const userSchema: JSONSchema7 = {
type: 'object',
properties: {
theme: {
type: 'string',
enum: ['light', 'dark', 'auto'],
default: 'light'
},
fontSize: {
type: 'number',
minimum: 10,
maximum: 24,
default: 14
},
enableAutoSave: {
type: 'boolean',
default: true
}
}
};
function SettingsForm() {
const [formData, setFormData] = useState<UserSettings>({
theme: 'light',
fontSize: 14,
enableAutoSave: true
});
return (
<FormComponent
schema={userSchema}
formData={formData}
onChange={(e) => setFormData(e.formData)}
uiSchema={{
...DEFAULT_UI_OPTIONS,
theme: { 'ui:widget': 'select' },
fontSize: { 'ui:widget': 'range' }
}}
compact={true}
showModifiedFromDefault={true}
/>
);
}
// Advanced form with custom widgets
const advancedSchema: JSONSchema7 = {
type: 'object',
properties: {
plugins: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
enabled: { type: 'boolean' },
config: { type: 'object' }
}
}
}
}
};
function AdvancedForm() {
const [data, setData] = useState({ plugins: [] });
return (
<FormComponent
schema={advancedSchema}
formData={data}
onChange={(e) => setData(e.formData)}
buttonStyle="icons"
uiSchema={{
plugins: {
'ui:options': {
addable: true,
removable: true
}
}
}}
/>
);
}Specialized buttons for managing array items in forms.
/**
* Button for moving array items up/down
* @param props - Button styling properties
* @returns JSX button element
*/
function MoveButton(props: FormComponent.IButtonProps): JSX.Element;
/**
* Button for removing array items
* @param props - Button styling properties
* @returns JSX button element
*/
function DropButton(props: FormComponent.IButtonProps): JSX.Element;
/**
* Button for adding new array items
* @param props - Button styling properties
* @returns JSX button element
*/
function AddButton(props: FormComponent.IButtonProps): JSX.Element;Usage Examples:
import { MoveButton, DropButton, AddButton } from '@jupyterlab/ui-components';
// Custom array template with styled buttons
function CustomArrayTemplate(props: any) {
return (
<div className="array-container">
<div className="array-header">
<h3>{props.title}</h3>
<AddButton buttonStyle="icons" />
</div>
{props.items.map((element: any, index: number) => (
<div key={index} className="array-item">
<div className="item-content">
{element.children}
</div>
<div className="item-controls">
<MoveButton buttonStyle="icons" />
<DropButton buttonStyle="text" />
</div>
</div>
))}
</div>
);
}
// Use in form configuration
const arrayFormConfig = {
schema: myArraySchema,
uiSchema: {
myArray: {
'ui:ArrayFieldTemplate': CustomArrayTemplate
}
}
};Registry system for custom form field and widget renderers.
/**
* Interface for form renderers
*/
interface IFormRenderer {
/** Custom field renderer */
fieldRenderer?: Field;
/** Custom widget renderer */
widgetRenderer?: Widget;
}
/**
* Registry interface for managing form renderers
*/
interface IFormRendererRegistry {
/** Add a new renderer to the registry */
addRenderer: (id: string, renderer: IFormRenderer) => void;
/** Get renderer by ID */
getRenderer: (id: string) => IFormRenderer;
/** All registered renderers */
renderers: { [id: string]: IFormRenderer };
}
/**
* Dependency injection token for form renderer registry
*/
const IFormRendererRegistry: Token<IFormRendererRegistry>;
/**
* Concrete implementation of form renderer registry
*/
class FormRendererRegistry implements IFormRendererRegistry {
addRenderer(id: string, renderer: IFormRenderer): void;
getRenderer(id: string): IFormRenderer;
get renderers(): { [id: string]: IFormRenderer };
}
/**
* Placeholder interface for future icon manager functionality
*/
interface ILabIconManager {}
/**
* Dependency injection token for icon manager service
*/
const ILabIconManager: Token<ILabIconManager>;Usage Examples:
import { FormRendererRegistry, IFormRenderer } from '@jupyterlab/ui-components';
// Create custom renderer
const colorPickerRenderer: IFormRenderer = {
widgetRenderer: ({ value, onChange }) => (
<input
type="color"
value={value || '#000000'}
onChange={(e) => onChange(e.target.value)}
className="color-picker-widget"
/>
)
};
// Register custom renderer
const registry = new FormRendererRegistry();
registry.addRenderer('colorPicker', colorPickerRenderer);
// Use in form schema
const schemaWithCustomWidget: JSONSchema7 = {
type: 'object',
properties: {
backgroundColor: {
type: 'string',
format: 'color',
default: '#ffffff'
}
}
};
const uiSchemaWithCustomWidget = {
backgroundColor: {
'ui:widget': 'colorPicker'
}
};
// Register with dependency injection
import { ServiceManager } from '@jupyterlab/services';
const services = new ServiceManager();
services.contents.add(IFormRendererRegistry, new FormRendererRegistry());
// Get registered renderer
const renderer = registry.getRenderer('colorPicker');Built-in validation and error display capabilities.
// Form validation is handled through JSON Schema validation
// Custom validation can be added through schema definitions
interface ValidationError {
name: string;
property: string;
message: string;
argument: any;
stack: string;
}
// Error handling in form components
interface FormErrorProps {
errors: ValidationError[];
schema: JSONSchema7;
uiSchema: any;
}Usage Examples:
import { FormComponent } from '@jupyterlab/ui-components';
import { JSONSchema7 } from 'json-schema';
// Schema with validation rules
const validationSchema: JSONSchema7 = {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
title: 'Email Address'
},
age: {
type: 'number',
minimum: 0,
maximum: 150,
title: 'Age'
},
password: {
type: 'string',
minLength: 8,
pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)',
title: 'Password'
}
},
required: ['email', 'password']
};
// Custom validation function
function customValidate(formData: any, errors: any) {
if (formData.password && formData.confirmPassword) {
if (formData.password !== formData.confirmPassword) {
errors.confirmPassword.addError('Passwords must match');
}
}
return errors;
}
// Form with validation
function ValidatedForm() {
const [formData, setFormData] = useState({});
const [errors, setErrors] = useState<ValidationError[]>([]);
return (
<div>
<FormComponent
schema={validationSchema}
formData={formData}
onChange={(e) => {
setFormData(e.formData);
setErrors(e.errors || []);
}}
validate={customValidate}
showErrorList={true}
liveValidate={true}
/>
{errors.length > 0 && (
<div className="form-errors">
<h4>Please fix the following errors:</h4>
<ul>
{errors.map((error, i) => (
<li key={i}>{error.message}</li>
))}
</ul>
</div>
)}
</div>
);
}Create custom templates for specific form fields and layouts.
// Custom field template interfaces from RJSF
interface FieldTemplateProps {
id: string;
label: string;
children: React.ReactNode;
errors: React.ReactNode;
help: React.ReactNode;
description: React.ReactNode;
hidden: boolean;
required: boolean;
readonly: boolean;
disabled: boolean;
displayLabel: boolean;
schema: JSONSchema7;
uiSchema: any;
formContext: any;
}Usage Examples:
import { FormComponent } from '@jupyterlab/ui-components';
// Custom field template
function CustomFieldTemplate(props: FieldTemplateProps) {
const { id, label, children, errors, help, required, schema } = props;
return (
<div className={`field-${schema.type}`}>
<div className="field-header">
<label htmlFor={id} className="field-label">
{label}
{required && <span className="required">*</span>}
</label>
{help && <div className="field-help">{help}</div>}
</div>
<div className="field-input">
{children}
</div>
{errors && <div className="field-errors">{errors}</div>}
</div>
);
}
// Use custom template in form
<FormComponent
schema={mySchema}
formData={formData}
onChange={handleChange}
templates={{
FieldTemplate: CustomFieldTemplate
}}
/>
// Custom object field template
function CustomObjectTemplate(props: any) {
return (
<fieldset className="object-fieldset">
<legend>{props.title}</legend>
<div className="object-properties">
{props.properties.map((prop: any) => prop.content)}
</div>
</fieldset>
);
}
// Apply to specific fields
const customUiSchema = {
myObject: {
'ui:ObjectFieldTemplate': CustomObjectTemplate
}
};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