diff --git a/.eslintrc.js b/.eslintrc.js index 63280eb70..86246ee12 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { ], '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-namespace': 'off', '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/no-use-before-define': 'off', diff --git a/notebooks/yaml.ipynb b/notebooks/yaml.ipynb new file mode 100644 index 000000000..7f3fb2d6f --- /dev/null +++ b/notebooks/yaml.ipynb @@ -0,0 +1,54 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "d956aba2-61bc-43b8-810c-82aa31b2af44", + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Markdown, clear_output\n", + "from ipywidgets import ToggleButton, Output\n", + "import json\n", + "import yaml\n", + "\n", + "STR_JSON=\"\"\"{\"hey\": {\n", + " \"1\": \"hi\",\n", + " \"2\": \"yo\",\n", + " \"a\": {\n", + " \"b\": [\n", + " {\"value\": \"3\"},\n", + " {\"value\": \"5\"},\n", + " {\"value\": \"5\"}\n", + " ]\n", + " }\n", + "}}\"\"\"\n", + "\n", + "parsed = json.loads(STR_JSON) \n", + "s = yaml.dump(parsed, indent=2)\n", + "display(Markdown(\"\\n```yaml\\n\" + s + \"\\n```\")) " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/packages/voila/package.json b/packages/voila/package.json index f0823123e..3f0b83c17 100644 --- a/packages/voila/package.json +++ b/packages/voila/package.json @@ -12,6 +12,7 @@ "@jupyterlab/application": "^4.0.0", "@jupyterlab/apputils": "^4.0.0", "@jupyterlab/apputils-extension": "^4.0.0", + "@jupyterlab/codemirror": "^4.0.3", "@jupyterlab/codemirror-extension": "^4.0.0", "@jupyterlab/coreutils": "^6.0.0", "@jupyterlab/docregistry": "^4.0.0", @@ -47,7 +48,8 @@ "@lumino/virtualdom": "^2.0.0", "@lumino/widgets": "^2.0.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "style-mod": "^4.0.3" }, "devDependencies": { "@jupyterlab/builder": "^4.0.0", diff --git a/packages/voila/src/plugins/themes/index.ts b/packages/voila/src/plugins/themes/index.ts index d67da1d01..706dc7608 100644 --- a/packages/voila/src/plugins/themes/index.ts +++ b/packages/voila/src/plugins/themes/index.ts @@ -6,11 +6,13 @@ * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ +import { StyleModule } from 'style-mod'; import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; import { IThemeManager } from '@jupyterlab/apputils'; +import { jupyterHighlightStyle } from '@jupyterlab/codemirror'; import { PageConfig, URLExt } from '@jupyterlab/coreutils'; import { ThemeManager } from './thememanager'; @@ -62,6 +64,10 @@ export const themePlugin: JupyterFrontEndPlugin = { app: JupyterFrontEnd, themeManager: IThemeManager | null ) => { + if (jupyterHighlightStyle.module) { + StyleModule.mount(document, jupyterHighlightStyle.module); + } + if (!themeManager) { return; } diff --git a/packages/voila/webpack.config.js b/packages/voila/webpack.config.js index 99c6bb221..95e3701e9 100644 --- a/packages/voila/webpack.config.js +++ b/packages/voila/webpack.config.js @@ -13,6 +13,10 @@ const baseConfig = require('@jupyterlab/builder/lib/webpack.config.base'); const data = require('./package.json'); const names = Object.keys(data.dependencies).filter((name) => { + if (name === 'style-mod') { + return false; + } + const packageData = require(path.join(name, 'package.json')); return packageData.jupyterlab !== undefined; }); diff --git a/ui-tests/tests/voila.test.ts b/ui-tests/tests/voila.test.ts index 4295bda0a..2e43da4c1 100644 --- a/ui-tests/tests/voila.test.ts +++ b/ui-tests/tests/voila.test.ts @@ -339,4 +339,11 @@ test.describe('Voila performance Tests', () => { await addBenchmarkToTest(notebookName, testFunction, testInfo, browserName); expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); }); + + test('Render yaml.ipynb', async ({ page, browserName }, testInfo) => { + const notebookName = 'yaml'; + await page.goto(`/voila/render/${notebookName}.ipynb`); + await page.waitForSelector('span >> text=hey'); + expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); + }); }); diff --git a/ui-tests/tests/voila.test.ts-snapshots/yaml-linux.png b/ui-tests/tests/voila.test.ts-snapshots/yaml-linux.png new file mode 100644 index 000000000..02270ad4e Binary files /dev/null and b/ui-tests/tests/voila.test.ts-snapshots/yaml-linux.png differ diff --git a/yarn.lock b/yarn.lock index 2c7d9659c..c7e160f1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5199,6 +5199,7 @@ __metadata: "@jupyterlab/apputils": ^4.0.0 "@jupyterlab/apputils-extension": ^4.0.0 "@jupyterlab/builder": ^4.0.0 + "@jupyterlab/codemirror": ^4.0.3 "@jupyterlab/codemirror-extension": ^4.0.0 "@jupyterlab/coreutils": ^6.0.0 "@jupyterlab/docregistry": ^4.0.0 @@ -5243,6 +5244,7 @@ __metadata: react-dom: ^18.2.0 rimraf: ^3.0.2 style-loader: ~3.3.1 + style-mod: ^4.0.3 tsc-watch: ^6.0.0 typescript: ~5.0.2 watch: ^1.0.2 @@ -15358,7 +15360,7 @@ __metadata: languageName: node linkType: hard -"style-mod@npm:^4.0.0": +"style-mod@npm:^4.0.0, style-mod@npm:^4.0.3": version: 4.0.3 resolution: "style-mod@npm:4.0.3" checksum: 934556e720bd29026ff8fef43a1a35b58957813025b91f996d886e9405acf934ddb1934def4400b174bd7784c9263eb9c71f07ae83925af9271b7d921d546854