Skip to content

Commit efdf928

Browse files
authored
Add text area (#28)
1 parent e6cc54f commit efdf928

2 files changed

Lines changed: 74 additions & 1 deletion

File tree

examples/yjs-widget-controls/notebooks/simple.ipynb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,38 @@
8686
"source": [
8787
"w.max = 200"
8888
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"id": "952ece55",
93+
"source": "from ypywidgets import Reactive\nfrom ypywidgets.comm import CommWidget\n\n\nclass Textarea(CommWidget):\n value = Reactive[str](\"\")\n rows = Reactive[int](4)\n disabled = Reactive[bool](False)\n continuous_update = Reactive[bool](True)\n\n @value.watch\n def _watch_value(self, old, new):\n # Watch the value of the textarea, and print the new value change\n #\n # From JupyterLab, show the log console with info level to see the print\n # \"Ctrl + Shift + C\" then type \"Log Console\" to expand that panel\n print(f\"value changed: '{old}'->'{new}'\")",
94+
"metadata": {},
95+
"execution_count": null,
96+
"outputs": []
97+
},
98+
{
99+
"cell_type": "code",
100+
"id": "0e4022fe",
101+
"source": "t = Textarea()\nt",
102+
"metadata": {},
103+
"execution_count": null,
104+
"outputs": []
105+
},
106+
{
107+
"cell_type": "code",
108+
"id": "77c2eba3",
109+
"source": "t.value = \"Hello, world!\"",
110+
"metadata": {},
111+
"execution_count": null,
112+
"outputs": []
113+
},
114+
{
115+
"cell_type": "code",
116+
"id": "5b519c6b",
117+
"source": "t.rows = 8",
118+
"metadata": {},
119+
"execution_count": null,
120+
"outputs": []
89121
}
90122
],
91123
"metadata": {
@@ -109,4 +141,4 @@
109141
},
110142
"nbformat": 4,
111143
"nbformat_minor": 5
112-
}
144+
}

examples/yjs-widget-controls/src/index.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,53 @@ class IntSlider {
4646
slider: HTMLInputElement;
4747
}
4848

49+
class Textarea {
50+
constructor(yModel: IJupyterYModel, node: HTMLElement) {
51+
this.yModel = yModel;
52+
this.node = node;
53+
54+
this.textarea = document.createElement('textarea');
55+
56+
this.yModel.sharedModel.attrsChanged.connect(this._stateChanged.bind(this));
57+
58+
this.textarea.value = this.yModel.sharedModel.getAttr('value');
59+
this.textarea.rows = this.yModel.sharedModel.getAttr('rows');
60+
this.textarea.disabled = this.yModel.sharedModel.getAttr('disabled');
61+
62+
this.textarea.onchange = this._textareaChanged.bind(this);
63+
this.textarea.oninput = this._textareaInput.bind(this);
64+
65+
node.appendChild(this.textarea);
66+
}
67+
68+
_stateChanged(_: IJupyterYDoc, change: MapChange): void {
69+
for (const key of change.keys()) {
70+
this.textarea[key] = this.yModel.sharedModel.getAttr(key);
71+
}
72+
}
73+
74+
_textareaChanged(): void {
75+
this.yModel.sharedModel.setAttr('value', this.textarea.value ?? '');
76+
}
77+
78+
_textareaInput(): void {
79+
if (this.yModel.sharedModel.getAttr('continuous_update')) {
80+
this.yModel.sharedModel.setAttr('value', this.textarea.value ?? '');
81+
}
82+
}
83+
84+
yModel: IJupyterYModel;
85+
node: HTMLElement;
86+
textarea: HTMLTextAreaElement;
87+
}
88+
4989
const simple: JupyterFrontEndPlugin<void> = {
5090
id: 'example:simple',
5191
autoStart: true,
5292
requires: [IJupyterYWidgetManager],
5393
activate: (_: JupyterFrontEnd, wm: IJupyterYWidgetManager): void => {
5494
wm.registerWidget('IntSlider', JupyterYModel, IntSlider);
95+
wm.registerWidget('Textarea', JupyterYModel, Textarea);
5596
}
5697
};
5798

0 commit comments

Comments
 (0)