diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 441c673..232db9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,3 +31,14 @@ jobs: run: pixi run pre-commit-all - name: Run unit tests run: pixi run test + - name: Run example notebook + run: | + pixi run serve-jupyter nbconvert \ + --to notebook \ + --execute \ + --ExecutePreprocessor.store_widget_state=False \ + --output "${PWD}/out.ipynb" \ + examples/widgets.ipynb + + # Widgets did render successufully as mime bundle + grep 'application/vnd.jupyter.ywidget-view+json' "${PWD}/out.ipynb" diff --git a/R/comm.R b/R/comm.R index 5bcbb4b..6438786 100644 --- a/R/comm.R +++ b/R/comm.R @@ -221,7 +221,8 @@ mime_bundle.CommWidget <- function(x, mimetypes = mime_types(x), ...) { model_id = x$comm_id() ) ), - metadata = list() + # Serialize as dict, not list + metadata = structure(list(), names = character(0)) ) } diff --git a/examples/widgets.ipynb b/examples/widgets.ipynb new file mode 100644 index 0000000..fa2469a --- /dev/null +++ b/examples/widgets.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "8ea1654d-6607-46dc-ad2f-60d58b451741", + "metadata": {}, + "outputs": [], + "source": [ + "# devtools::load_all(\".\")\n", + "\n", + "library(\"ywidget\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc523884-6cdd-4191-84ea-cb2fafda18c2", + "metadata": {}, + "outputs": [], + "source": [ + "IntSlider <- make_comm_widget(\n", + " \"IntSlider\",\n", + " value = 50L,\n", + " min = 0L,\n", + " max = 100L,\n", + " step = 1L\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0df5ce5-779b-4b8c-b338-3e5cab824318", + "metadata": {}, + "outputs": [], + "source": [ + "s <- IntSlider$new()\n", + "s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "359d9faa-7400-4548-b03e-641edc373b19", + "metadata": {}, + "outputs": [], + "source": [ + "s$value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51225b68-1855-4557-9825-d76270e07468", + "metadata": {}, + "outputs": [], + "source": [ + "s$value = 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ce581d9-2932-40bd-92f0-8b7ab5e64610", + "metadata": {}, + "outputs": [], + "source": [ + "s2 <- IntSlider$new()\n", + "s2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "163e7eb1-400b-4e54-9ca4-bb8186259c64", + "metadata": {}, + "outputs": [], + "source": [ + "s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54f82252-6b3d-402f-8525-b4980ef4e5a8", + "metadata": {}, + "outputs": [], + "source": [ + "Textarea <- make_comm_widget(\n", + " \"Textarea\",\n", + " value = \"\",\n", + " rows = 0L,\n", + " disabled = FALSE,\n", + " continuous_update = TRUE\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c327b3f-9f81-4a94-a013-760b3ee9bc93", + "metadata": {}, + "outputs": [], + "source": [ + "t <- Textarea$new()\n", + "t" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8fa605f-e8f1-403a-a429-21ede9dfd29c", + "metadata": {}, + "outputs": [], + "source": [ + "t$value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "237427fd-6d51-4d8b-a85c-27a4a269a4d6", + "metadata": {}, + "outputs": [], + "source": [ + "t$value <- \"Hello world!\"" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R 4.4.3 (xr)", + "language": "R", + "name": "xr" + }, + "language_info": { + "codemirror_mode": "", + "file_extension": ".R", + "mimetype": "text/x-R", + "name": "R", + "nbconvert_exporter": "", + "pygments_lexer": "r", + "version": "4.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pixi.lock b/pixi.lock index d3dc5e8..7ef50e5 100644 --- a/pixi.lock +++ b/pixi.lock @@ -819,7 +819,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.1-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-collection-0.5.1-pyh09b8992_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda @@ -1171,7 +1172,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xeus-r-0.11.0-r45h45edcf1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xeus-zmq-4.0.0-h695af4d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-collection-0.5.1-pyh09b8992_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-h27d9b8f_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.2-hbb4bfdb_2.conda @@ -1524,7 +1526,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xeus-r-0.11.0-r44he0f44cb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xeus-zmq-4.0.0-h5cc99d8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-collection-0.5.1-pyh09b8992_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda @@ -1855,7 +1858,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/xeus-r-0.11.0-r45h72f11de_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xeus-zmq-4.0.0-hecdc818_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-collection-0.5.1-pyh09b8992_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda @@ -13485,16 +13489,25 @@ packages: license_family: MIT size: 63944 timestamp: 1753484092156 -- conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.0-pyhcf101f3_1.conda - sha256: 774bf6e7e2aacc57bfeae08151327a8f29739826cc96154f4f11d8cd5db47a1e - md5: 23dc2f4422c692df7e572ffc51ff473e +- conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-0.5.1-pyhcf101f3_0.conda + sha256: b71a470cb5205e0917746b705434c25c00a45227ba2044469bd17de9500fadd0 + md5: 0b9a1b6ac64d07fd43c783f0da66141e depends: - python >=3.10 - python license: BSD-3-Clause - license_family: BSD - size: 38437 - timestamp: 1778658872139 + size: 38600 + timestamp: 1779191003900 +- conda: https://conda.anaconda.org/conda-forge/noarch/yjs-widgets-collection-0.5.1-pyh09b8992_0.conda + sha256: a757728a193793799cfe58cee7f842fec86563127871de6f473506b7156114c6 + md5: 635c6d948f936e415717fee074df379a + depends: + - yjs-widgets ==0.5.1 pyhcf101f3_0 + - python >=3.10 + - python + license: BSD-3-Clause + size: 31544 + timestamp: 1779191003900 - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda sha256: 325d370b28e2b9cc1f765c5b4cdb394c91a5d958fbd15da1a14607a28fee09f6 md5: 755b096086851e1193f3b10347415d7c diff --git a/pixi.toml b/pixi.toml index c8c4112..ae1e498 100644 --- a/pixi.toml +++ b/pixi.toml @@ -30,6 +30,15 @@ typos = "*" pre-commit = "*" jupyterlab = ">=4" jupyterlab-kernelspy = "*" +yjs-widgets = "*" +yjs-widgets-collection = "*" + +[feature.dev.tasks.install-ywidget] +cmd = "R CMD INSTALL ." + +[feature.dev.tasks.serve-jupyter] +cmd = "jupyter" +depends-on = ["install-ywidget"] [feature.dev.tasks] # Document