React component library for Jupyter notebooks. Monorepo with 4 main packages.
# Setup
npm install
npm run build
# Development
npm run jupyter:server # Start Jupyter (port 8686)
npm run storybook # Start Storybook (port 6006)
# React package dev (cd packages/react)
npm run start # Remote server config
npm run start-local # Local server (webpack + jupyter)
npm run start-local:webpack # Only webpack
# Code quality
npm run check # Format, lint, type-check
npm run check:fix # Auto-fix and check- Node.js: >= 20.0.0 (use .nvmrc)
- Server token:
60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6 - Webpack entry: Edit
packages/react/webpack.config.js→ENTRYvariable - Jupyter config:
dev/config/jupyter_server_config.py
- Install:
pip install jupyter-collaboration jupyterlab - Enable: Set
c.LabApp.collaborative = Truein jupyter config - Test: Open http://localhost:3208/ in multiple windows
// Basic usage
const provider = new JupyterCollaborationProvider();
<Notebook collaborationProvider={provider} path="notebook.ipynb" />;
// With config
const provider = new JupyterCollaborationProvider({
path: 'notebook.ipynb',
serverSettings: mySettings,
});- Build fails: Run
npm run type-check - Lint errors: Run
npm run lint:fix - Node version: Use Node 20+ (
nvm use) - Collaboration issues: Check WebSocket connections and jupyter-collaboration installation
- Use npm, not yarn
- Prefer editing over creating files
- Run checks after changes:
npm run check:fix
Status: ✅ COMPLETED - All improvements tested and working in VS Code extension
-
KernelActionMenu Always Visible (
packages/react/src/components/kernel/KernelActionMenu.tsx)- Three dot menu now visible regardless of kernel connection state
- All menu items always rendered with appropriate disabled states
- "Interrupt kernel" and "Restart kernel" disabled when no kernel
- "Clear outputs" always enabled (works with or without kernel)
- Added
onClearOutputs?: () => voidcallback prop for custom clear logic
-
Progress Bar Conditional Display (
packages/react/src/components/output/Output.tsx)- Progress bar only shows when kernel is connected and not idle
- Space preserved with transparent background when inactive
- Prevents visual jumping in the UI
-
Clear Outputs Functionality (
packages/react/src/components/output/Output.tsx)- Works from both toolbar and three dot menu
- Functions correctly with or without kernel connection
- Fixed adapter/propsAdapter logic to match rendering behavior
- Added
handleClearOutputscallback that checks bothadapterandpropsAdapter
-
Architecture Improvement
- Removed VS Code-specific CSS from
Output.css - Platform-specific styling now handled by consuming packages
- Keeps jupyter-react library platform-agnostic
- Removed VS Code-specific CSS from
The Adapter/PropsAdapter Issue: Fixed mismatch between clear logic and rendering logic:
// Rendering logic (line 356 in Output.tsx)
const currentAdapter = adapter || propsAdapter;
return lumino ? (currentAdapter ? <Lumino>{currentAdapter.outputArea}</Lumino> : null) : ...
// Fixed clear logic to match
const currentAdapter = adapter || propsAdapter;
if (currentAdapter) {
currentAdapter.clear(); // Now matches rendering logic
}Conditional Rendering vs Disabled Props: Changed from conditional rendering to disabled props:
// Before: Hidden when no kernel
{kernel && <ActionList.Item onSelect={...}>Interrupt kernel</ActionList.Item>}
// After: Always visible, disabled when no kernel
<ActionList.Item disabled={!kernel} onSelect={...}>Interrupt kernel</ActionList.Item>The jupyter-react package now provides:
- Generic components without platform-specific styling
onClearOutputscallback prop for custom clear logic- Always-visible menu with disabled states
Consuming packages (like vscode-datalayer) can:
- Apply platform-specific CSS overrides
- Provide custom clear callbacks that match their rendering strategy
- Theme components using their platform's variables
Example (VS Code extension):
// Custom CSS in vscode-datalayer/webview/styles/vscode-primer-overrides.css
[class*="ActionMenu-"] {
background-color: var(--vscode-menu-background) !important;
}
// Custom clear callback in Output component
<KernelActionMenu
kernel={kernel}
outputAdapter={adapter}
onClearOutputs={handleClearOutputs} // Custom logic for VS Code
/>Background:
The @datalayer/jupyter-lexical package includes Jupyter output nodes (JupyterOutputNode, JupyterCellNode) that create Lumino widgets during module initialization. When this package is imported, it immediately initializes these widgets.
Issue: If lexical is imported in contexts where it's not needed (e.g., notebook-only tools), the Lumino widget initialization runs prematurely and crashes with:
Cannot set properties of undefined (setting 'class-name')
Root Cause:
packages/lexical/src/index.tsexports./pluginsand./nodes- These modules create Lumino
OutputAreawidgets on load - If DOM isn't ready or initialization order is wrong → crash
DO:
- Import lexical only when actually needed for lexical editing
- Separate imports by use case (notebook vs lexical)
- Use dynamic imports for optional features
DON'T:
- Import lexical in notebook-only code
- Create combined adapters that import both
@datalayer/jupyter-reactand@datalayer/jupyter-lexical - Mix package imports unless both are actively needed
The @datalayer/core package had a combined hooks file that imported both packages:
// ❌ BAD - Causes crash when only notebook tools are needed
import { ... } from '@datalayer/jupyter-lexical';
import { ... } from '@datalayer/jupyter-react';Fixed by splitting into separate files:
// ✅ GOOD - notebookHooks.tsx (notebook only)
import { ... } from '@datalayer/jupyter-react';
// ✅ GOOD - lexicalHooks.tsx (lexical only)
import { ... } from '@datalayer/jupyter-lexical';This ensures lexical code only loads when lexical editing is actually used.
If you modify lexical or react packages, test that:
- Notebook-only code doesn't trigger lexical loading
- Lexical code loads correctly when needed
- No crashes during module initialization
- Bundle size doesn't include unused packages
Check consuming packages (like @datalayer/core) to ensure they use proper separation patterns.