From 3fdfa64a3bb1b26136a09a2957dc0b7865473c0a Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Thu, 15 Jun 2023 15:54:55 +0200 Subject: [PATCH] Add tippy.js based tooltip (#110) --- conda.recipe/meta.yaml | 2 +- package.json | 3 ++- src/plugin.ts | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 5cce952..b450194 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -15,7 +15,7 @@ build: requirements: build: - jupyter-packaging - - jupyterlab + - jupyterlab <4 - notebook - python - setuptools diff --git a/package.json b/package.json index ad28140..9cbad24 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,8 @@ "@jupyterlab/settingregistry": "^3.1.0", "@jupyterlab/ui-components": "^3.1.0", "@lumino/coreutils": "^1.5.3", - "@lumino/signaling": "^1.4.3" + "@lumino/signaling": "^1.4.3", + "tippy.js": "^6" }, "resolutions": { "@lumino/widgets": "^1.37.2", diff --git a/src/plugin.ts b/src/plugin.ts index 0fc2ba3..726f2ce 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -56,6 +56,9 @@ export type INBWidgetExtension = DocumentRegistry.IWidgetExtension< INotebookModel >; +import tippy from 'tippy.js'; +import 'tippy.js/dist/tippy.css'; // optional for styling + let registerWidgetManager: any = null; try { const jlm = require('@jupyter-widgets/jupyterlab-manager'); @@ -77,6 +80,15 @@ export namespace CommandIDs { export const lumenOpen = 'notebook:open-with-lumen'; } +const TOOLTIP_CONTENT = ` +Preview with Panel +
+
+ + Note: Your notebook must publish Panel contents with .servable(). + +`; + /** * A notebook widget extension that adds a panel preview button to the toolbar. */ @@ -96,13 +108,23 @@ class PanelRenderButton createNew(panel: NotebookPanel): IDisposable { const button = new ToolbarButton({ className: 'panelRender', - tooltip: 'Render with Panel', icon: panelIcon, onClick: (): void => { this._commands.execute(CommandIDs.panelRender); } }); + setTimeout(() => { + requestAnimationFrame(() => { + tippy(button.node, { + allowHTML: true, + arrow: true, + content: TOOLTIP_CONTENT, + placement: 'bottom' + }); + }); + }, 0); + panel.toolbar.insertAfter('cellType', 'panelRender', button); return button; } @@ -129,13 +151,22 @@ class LumenRenderButton createNew(panel: NotebookPanel): IDisposable { const button = new ToolbarButton({ className: 'lumenRender', - tooltip: 'Render with Lumen', icon: panelIcon, onClick: () => { this._commands.execute(CommandIDs.lumenRender); } }); + setTimeout(() => { + requestAnimationFrame(() => { + tippy(button.node, { + arrow: true, + content: 'Preview with Lumen', + placement: 'bottom' + }); + }); + }, 0); + panel.toolbar.addItem('lumenRender', button); return button; } @@ -318,7 +349,7 @@ export const extension: JupyterFrontEndPlugin = { const { commands, docRegistry } = app; commands.addCommand(CommandIDs.panelRender, { - label: 'Render Notebook with Panel', + label: 'Preview Notebook with Panel', execute: async args => { const current = getCurrent(args); let context: DocumentRegistry.IContext;