Skip to content

Commit 9bb89b1

Browse files
authored
Add demo model-view (#32)
* WIP add model view demo * Finish model case with signal * Update yarn.lock
1 parent 8d04a6f commit 9bb89b1

File tree

5 files changed

+123
-1
lines changed

5 files changed

+123
-1
lines changed

packages/lab-example/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@
5252
"@jupyter-notebook/web-components": "^0.8.1",
5353
"@jupyterlab/application": "^3.1.0",
5454
"@jupyterlab/apputils": "^3.0.0",
55+
"@lumino/messaging": "^1.10.1",
56+
"@lumino/signaling": "^1.10.1",
5557
"@lumino/widgets": "^1.30.0",
58+
"@microsoft/fast-element": "^1.8.0",
5659
"react": "^17.0.0"
5760
},
5861
"devDependencies": {

packages/lab-example/src/index.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ import {
4949
JupyterFrontEndPlugin
5050
} from '@jupyterlab/application';
5151
import { IThemeManager, ReactWidget } from '@jupyterlab/apputils';
52-
import { Widget } from '@lumino/widgets';
52+
import { Panel, Widget } from '@lumino/widgets';
5353
import React from 'react';
54+
import {
55+
BasicModel,
56+
BasicView,
57+
ObservableModel,
58+
ObservableView
59+
} from './model';
5460

5561
provideJupyterDesignSystem().register(allComponents);
5662
addJupyterLabThemeChangeListener();
@@ -191,6 +197,26 @@ const plugin: JupyterFrontEndPlugin<void> = {
191197
dataRef.current.rowsData = TABLE_DATA;
192198
}
193199
}
200+
201+
// Demo Model-View
202+
const panel = new Panel();
203+
panel.id = 'jupyter-ui-toolkit-demo-panel';
204+
const title1 = new Widget();
205+
title1.node.textContent = 'Using signal';
206+
panel.addWidget(title1);
207+
const view1 = new BasicView();
208+
view1.model = new BasicModel();
209+
panel.addWidget(new Widget({ node: view1 }));
210+
211+
const title2 = new Widget();
212+
title2.node.textContent = 'Using FAST observable';
213+
panel.addWidget(title2);
214+
const view2 = new ObservableView();
215+
view2.model = new ObservableModel();
216+
panel.addWidget(new Widget({ node: view2 }));
217+
218+
panel.title.label = 'Demo';
219+
app.shell.add(panel, 'right');
194220
});
195221
}
196222
};

packages/lab-example/src/model.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { VDomModel } from '@jupyterlab/apputils';
2+
import {
3+
customElement,
4+
FASTElement,
5+
html,
6+
Observable,
7+
observable
8+
} from '@microsoft/fast-element';
9+
10+
/*
11+
* Common HTML template
12+
*/
13+
const template = html<ObservableView | BasicView>`<div>
14+
<button
15+
@click=${x => {
16+
x.model?.incrementCounter();
17+
}}
18+
>
19+
Increment
20+
</button>
21+
<span>${x => x.model?.counter ?? '0'}</span>
22+
</div>`;
23+
24+
/*
25+
* VDOM model with Lumino signal
26+
*/
27+
28+
export class BasicModel extends VDomModel {
29+
get counter(): number {
30+
return this._counter;
31+
}
32+
33+
incrementCounter(): void {
34+
this._counter += 1;
35+
this.stateChanged.emit();
36+
}
37+
private _counter = 0;
38+
}
39+
40+
@customElement({
41+
name: 'jp-test-basic-view',
42+
template
43+
})
44+
export class BasicView extends FASTElement {
45+
get model(): BasicModel | null {
46+
Observable.track(this, 'model');
47+
return this._model;
48+
}
49+
set model(m: BasicModel | null) {
50+
this._model?.stateChanged.disconnect(this._onStateChanged, this);
51+
this._model = m;
52+
this._model?.stateChanged.connect(this._onStateChanged, this);
53+
this._onStateChanged();
54+
}
55+
56+
private _onStateChanged(): void {
57+
this.$fastController.notify('model');
58+
}
59+
60+
private _model: BasicModel | null = null;
61+
}
62+
63+
/*
64+
* Model - view using FAST observable
65+
*/
66+
67+
export class ObservableModel {
68+
get counter(): number {
69+
return this._counter;
70+
}
71+
72+
incrementCounter(): void {
73+
this._counter += 1;
74+
}
75+
76+
@observable
77+
private _counter = 0;
78+
}
79+
80+
@customElement({
81+
name: 'jp-test-observable-view',
82+
template
83+
})
84+
export class ObservableView extends FASTElement {
85+
public model: ObservableModel | null = null;
86+
}

packages/lab-example/style/base.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,9 @@ jp-toolbar > * {
7474
margin-top: auto;
7575
margin-bottom: auto;
7676
}
77+
78+
#jupyter-ui-toolkit-demo-panel {
79+
background-color: var(--jp-layout-color1);
80+
color: var(--jp-ui-font-color1);
81+
padding: 5px;
82+
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"composite": true,
55
"declaration": true,
66
"esModuleInterop": true,
7+
"experimentalDecorators": true,
78
"incremental": true,
89
"jsx": "react",
910
"module": "esnext",

0 commit comments

Comments
 (0)