Skip to content

Commit 661654a

Browse files
authored
Fix: example (#383)
* rename: notebook2 * output: reactive codemirror editor * fix: nextjs * lint * fix: cell example * fix: plotlye * example: vite * fix: notebook2 example * fix: notebook2 sidebar * fix: enable back the sidebars in the examples * readme
1 parent 12f6d4d commit 661654a

31 files changed

+313
-123
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
# 🪐 ⚛️ Jupyter UI
66

77
> React.js components 💯% compatible with 🪐 Jupyter.
8+
>
9+
> Documentation: https://jupyter-ui.datalayer.tech
10+
>
11+
> Storybook: https://jupyter-ui-storybook.datalayer.tech
812
913
Jupyter UI is a set of [React.js](https://react.dev) components that allow a frontend/webapp developer to build data products compatible with the [Jupyter](https://jupyter.org) ecosystem. The user interface delivers executable notebooks, cells, terminals, file browsers and allows the developer to manage a full integrated React tree instead of relying on iframes to display the Jupyter noteboks.
1014

examples/next-js/src/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Image from "next/image";
44
import dynamic from 'next/dynamic';
55

66
const JupyterComponentNoSSR = dynamic(
7-
() => import('../components/CellComponent'),
7+
() => import('../components/NotebookComponent'),
88
{
99
ssr: false,
1010
loading: () => <p>Loading Jupyter Component...</p>

examples/next-js/src/components/CellComponent.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,41 @@
66

77
'use client';
88

9-
import { useEffect, useState } from 'react';
10-
import { useJupyter, JupyterReactTheme } from '@datalayer/jupyter-react';
9+
import { useJupyter, JupyterReactTheme, Cell } from '@datalayer/jupyter-react';
10+
/*
1111
import dynamic from 'next/dynamic';
12-
13-
// Dynamically import the Cell component with SSR disabled
1412
const Cell = dynamic(
1513
() => import('@datalayer/jupyter-react').then((mod) => ({ default: mod.Cell })),
1614
{
1715
ssr: false,
1816
loading: () => <p>Loading Jupyter Cell...</p>
1917
}
2018
);
21-
19+
*/
2220
export const CellComponent = () => {
2321
const { defaultKernel } = useJupyter({
2422
jupyterServerUrl: "https://oss.datalayer.run/api/jupyter-server",
2523
jupyterServerToken: "60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6",
2624
startDefaultKernel: true,
2725
});
28-
if (!defaultKernel) {
29-
return <p>Loading Jupyter Cell...</p>;
30-
}
3126
return (
3227
<>
33-
<div style={{fontSize: 20}}>Jupyter Cell in Next.js</div>
34-
<JupyterReactTheme>
35-
<Cell
36-
id="test-cell"
37-
type="code"
38-
source="1+1"
39-
kernel={defaultKernel}
40-
autoStart
41-
/>
42-
</JupyterReactTheme>
28+
{defaultKernel ?
29+
<>
30+
<div style={{fontSize: 20}}>Jupyter Cell in Next.js</div>
31+
<JupyterReactTheme>
32+
<Cell
33+
id="test-cell"
34+
type="code"
35+
source="1+1"
36+
kernel={defaultKernel}
37+
autoStart
38+
/>
39+
</JupyterReactTheme>
40+
</>
41+
:
42+
<p>Loading Jupyter Cell...</p>
43+
}
4344
</>
4445
)
4546
}

examples/next-js/src/components/NotebookComponent.tsx

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,64 @@
66

77
'use client'
88

9-
import { JupyterReactTheme, Notebook, CellSidebarExtension, CellSidebarButton } from '@datalayer/jupyter-react';
10-
import { NotebookToolbar } from '@datalayer/jupyter-react';
9+
import { useJupyter, JupyterReactTheme, Notebook2, NotebookToolbar, CellSidebarExtension, CellSidebarButton } from '@datalayer/jupyter-react';
10+
import { Box } from '@primer/react';
1111
import { PrimerTheme } from './PrimerTheme';
12+
import { useMemo } from 'react';
1213

13-
type NotebookComponentProps = {
14+
type INotebookComponentProps = {
1415
colorMode?: 'light' | 'dark';
1516
theme?: PrimerTheme;
1617
}
1718

18-
export const NotebookComponent = (props: NotebookComponentProps) => {
19-
const { colorMode, theme } = props;
19+
export const NotebookComponent = (props: INotebookComponentProps) => {
20+
// const { colorMode, theme } = props;
21+
const { defaultKernel, serviceManager } = useJupyter({
22+
jupyterServerUrl: "https://oss.datalayer.run/api/jupyter-server",
23+
jupyterServerToken: "60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6",
24+
startDefaultKernel: true,
25+
});
26+
const extensions = useMemo(() => [
27+
new CellSidebarExtension({ factory: CellSidebarButton })
28+
], []);
2029
return (
2130
<>
22-
<div style={{fontSize: 20}}>Jupyter Notebook in Next.js</div>
23-
<JupyterReactTheme>
24-
<Notebook
25-
path="ipywidgets.ipynb"
26-
id="notebook-nextjs-1"
27-
cellSidebarMargin={120}
28-
height="500px"
29-
extensions={[new CellSidebarExtension({ factory: CellSidebarButton })]}
30-
Toolbar={NotebookToolbar}
31-
/>
32-
</JupyterReactTheme>
31+
{ defaultKernel && serviceManager ?
32+
<>
33+
<div style={{fontSize: 20}}>Jupyter Notebook in Next.js</div>
34+
<JupyterReactTheme>
35+
<Box
36+
sx={{
37+
'& .jp-NotebookPanel': {
38+
height: '500px !important',
39+
maxHeight: '500px !important',
40+
width: '100%',
41+
overflowY: 'hidden',
42+
},
43+
'& .jp-Notebook': {
44+
flex: '1 1 auto !important',
45+
height: '500px !important',
46+
maxHeight: '500px !important',
47+
overflowY: 'scroll',
48+
},
49+
}}
50+
>
51+
<Notebook2
52+
path="ipywidgets.ipynb"
53+
id="notebook-nextjs-1"
54+
cellSidebarMargin={120}
55+
height="500px"
56+
kernelId={defaultKernel.id}
57+
serviceManager={serviceManager}
58+
extensions={extensions}
59+
Toolbar={NotebookToolbar}
60+
/>
61+
</Box>
62+
</JupyterReactTheme>
63+
</>
64+
:
65+
<p>Loading Jupyter Notebook...</p>
66+
}
3367
</>
3468
)
3569
}

examples/vite/src/App.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
import { useState } from "react";
88
import reactLogo from "./assets/react.svg";
9-
import CellExample from "./examples/CellExample";
9+
import { useJupyter, JupyterReactTheme } from '@datalayer/jupyter-react';
10+
import { CellExample } from "./examples/CellExample";
11+
import { NotebookExample } from "./examples/NotebookExample";
1012

1113
// Fix for controls version failing to load in Vite.
1214
// import * as controls from "@jupyter-widgets/controls/lib/index";
@@ -16,11 +18,19 @@ import CellExample from "./examples/CellExample";
1618
import "./App.css";
1719

1820
function App() {
21+
const { defaultKernel, serviceManager } = useJupyter({
22+
jupyterServerUrl: "https://oss.datalayer.run/api/jupyter-server",
23+
jupyterServerToken: "60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6",
24+
startDefaultKernel: true,
25+
});
1926
const [count, setCount] = useState(0);
2027
return (
2128
<div className="App">
2229
<>
23-
<CellExample />
30+
<JupyterReactTheme>
31+
{ defaultKernel && <CellExample kernel={defaultKernel}/> }
32+
{ defaultKernel && serviceManager && <NotebookExample kernel={defaultKernel} serviceManager={serviceManager}/> }
33+
</JupyterReactTheme>
2434
</>
2535
<div>
2636
<a href="https://reactjs.org" target="_blank">

examples/vite/src/examples/CellExample.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
*/
66

77
import { Box, Button, Label } from '@primer/react';
8-
import { CodeCell } from '@jupyterlab/cells';
9-
import { JupyterReactTheme, useJupyter, Cell, KernelIndicator, useKernelsStore, useCellsStore } from '@datalayer/jupyter-react';
8+
import { Cell, KernelIndicator, useKernelsStore, useCellsStore, Kernel } from '@datalayer/jupyter-react';
109

1110
const CELL_ID = 'cell-example-1';
1211

@@ -15,12 +14,16 @@ const DEFAULT_SOURCE = `from IPython.display import display
1514
for i in range(10):
1615
display('I am a long string which is repeatedly added to the dom in separated divs: %d' % i)`;
1716

18-
const CellExample = () => {
19-
const { defaultKernel } = useJupyter();
17+
type ICellExampleProps = {
18+
kernel: Kernel;
19+
}
20+
21+
export const CellExample = (props: ICellExampleProps) => {
22+
const { kernel } = props;
2023
const cellsStore = useCellsStore();
2124
const kernelsStore = useKernelsStore();
2225
return (
23-
<JupyterReactTheme>
26+
<>
2427
<Box as="h1">A Jupyter Cell</Box>
2528
<Box>
2629
Source: {cellsStore.getSource(CELL_ID)}
@@ -29,24 +32,24 @@ const CellExample = () => {
2932
Outputs Count: {cellsStore.getOutputsCount(CELL_ID)}
3033
</Box>
3134
<Box>
32-
Kernel State: <Label>{defaultKernel && kernelsStore.getExecutionState(defaultKernel.id)}</Label>
35+
Kernel State: <Label>{kernelsStore.getExecutionState(kernel.id)}</Label>
3336
</Box>
3437
<Box>
35-
Kernel Phase: <Label>{defaultKernel && kernelsStore.getExecutionPhase(defaultKernel.id)}</Label>
38+
Kernel Phase: <Label>{kernelsStore.getExecutionPhase(kernel.id)}</Label>
3639
</Box>
3740
<Box display="flex">
3841
<Box>
3942
Kernel Indicator:
4043
</Box>
4144
<Box ml={3}>
42-
<KernelIndicator kernel={defaultKernel && defaultKernel.connection}/>
45+
<KernelIndicator kernel={kernel.connection}/>
4346
</Box>
4447
</Box>
4548
<Box>
4649
<Button onClick={() => cellsStore.execute(CELL_ID)}>Run cell</Button>
4750
</Box>
4851
<Cell source={DEFAULT_SOURCE} id={CELL_ID}/>
49-
</JupyterReactTheme>
52+
</>
5053
)
5154
}
5255

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2021-2023 Datalayer, Inc.
3+
*
4+
* MIT License
5+
*/
6+
7+
import { useMemo } from 'react';
8+
import { Box } from '@primer/react';
9+
import { Notebook2, Kernel, NotebookToolbar, CellSidebarExtension, CellSidebarButton } from '@datalayer/jupyter-react';
10+
import { ServiceManager } from '@jupyterlab/services';
11+
12+
const NOTEBOOK_ID = 'notebook-example-1';
13+
14+
type INotebookExampleProps = {
15+
kernel: Kernel;
16+
serviceManager: ServiceManager.IManager;
17+
}
18+
19+
export const NotebookExample = (props: INotebookExampleProps) => {
20+
const { kernel, serviceManager } = props;
21+
const extensions = useMemo(() => [
22+
new CellSidebarExtension({ factory: CellSidebarButton })
23+
], []);
24+
return (
25+
<>
26+
<Box as="h1">A Jupyter Notebook</Box>
27+
<Notebook2
28+
path="ipywidgets.ipynb"
29+
id={NOTEBOOK_ID}
30+
serviceManager={serviceManager}
31+
kernelId={kernel.id}
32+
extensions={extensions}
33+
Toolbar={NotebookToolbar}
34+
/>
35+
</>
36+
)
37+
}
38+
39+
export default NotebookExample;

packages/react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datalayer/jupyter-react",
3-
"version": "1.0.3",
3+
"version": "1.0.5",
44
"description": "Jupyter React - React.js components 100% compatible with Jupyter.",
55
"license": "MIT",
66
"main": "lib/index.js",

packages/react/src/app/tabs/components/NotebookComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const NotebookComponent = () => {
1313
return (
1414
<>
1515
<Notebook
16-
startDefaultKernel={true}
16+
startDefaultKernel
1717
nbformat={nbformat}
1818
id="notebook-id"
1919
cellSidebarMargin={60}

packages/react/src/components/codemirror/CodeMirrorDatalayerEditor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const CodeMirrorDatalayerEditor = (props: {
8080
};
8181
useEffect(() => {
8282
outputStore.setInput(sourceId, code);
83-
const language = new Compartment();
83+
const language = new Compartment();
8484
const keyBinding = [
8585
{
8686
key: 'Shift-Enter',
@@ -92,10 +92,10 @@ export const CodeMirrorDatalayerEditor = (props: {
9292
doc: code,
9393
extensions: [
9494
basicSetup,
95-
language.of(python()),
95+
language.of(python()),
9696
EditorView.lineWrapping,
9797
keymap.of([...keyBinding]),
98-
codeMirrorTheme,
98+
codeMirrorTheme,
9999
EditorView.updateListener.of((viewUpdate: ViewUpdate) => {
100100
if (viewUpdate.docChanged) {
101101
const source = viewUpdate.state.doc.toString();

0 commit comments

Comments
 (0)