|
| 1 | +# Main Widget Content Header |
| 2 | + |
| 3 | +> Insert a widget into the `contentHeader` section of a `MainAreaWidget`—useful for toolbars, headers, etc. |
| 4 | +
|
| 5 | + |
| 6 | + |
| 7 | +This JupyterLab example extension is intended to demo one specific feature of `MainAreaWidget`, namely, its `contentHeader` section. |
| 8 | + |
| 9 | +> As background, `MainAreaWidget` is a high-level JupyterLab widget that conventionally is used to enclose the Launcher (shown above) or a notebook editor. The `contentHeader`, in turn, is a Lumino `BoxPanel` widget positioned at the very top of this main area. This makes the `contentHeader` potentially useful to extensions needing some place to put content that the user will _always see_. |
| 10 | +
|
| 11 | +In code: after you get a `MainAreaWidget`, for example via |
| 12 | + |
| 13 | +```ts |
| 14 | +// src/index.ts#L37-L37 |
| 15 | + |
| 16 | +const main = app.shell.currentWidget; |
| 17 | +``` |
| 18 | + |
| 19 | +you can then create a widget of interest, for example as |
| 20 | + |
| 21 | +```ts |
| 22 | +// src/index.ts#L40-L40 |
| 23 | + |
| 24 | +const widget = new Widget(); |
| 25 | +``` |
| 26 | + |
| 27 | +before finally adding it to the JupyterLab main area's `contentHeader` real estate at its very top: |
| 28 | + |
| 29 | +```ts |
| 30 | +// src/index.ts#L45-L45 |
| 31 | + |
| 32 | +main.contentHeader.addWidget(widget); |
| 33 | +``` |
| 34 | + |
| 35 | +## Install |
| 36 | + |
| 37 | +First, ensure you've followed the installation instructions in the [top-level README](../README.md), e.g.: |
| 38 | + |
| 39 | +```bash |
| 40 | +# clone the repository |
| 41 | +git clone https://github.com/jupyterlab/extension-examples.git jupyterlab-extension-examples |
| 42 | + |
| 43 | +# go to the extension examples folder |
| 44 | +cd jupyterlab-extension-examples |
| 45 | + |
| 46 | +# create a new environment |
| 47 | +conda env create |
| 48 | + |
| 49 | +# activate the environment |
| 50 | +conda activate jupyterlab-extension-examples |
| 51 | +``` |
| 52 | + |
| 53 | +Then build this extension and launch it — this largely follows from the instructions in the top-level [README](../README.md), except using this example instead of the `hello-world` one: |
| 54 | + |
| 55 | +```bash |
| 56 | +# go to the contentheader example |
| 57 | +cd contentheader |
| 58 | + |
| 59 | +# install the extension in editable mode |
| 60 | +python -m pip install -e . |
| 61 | + |
| 62 | +# install your development version of the extension with JupyterLab |
| 63 | +jupyter labextension develop . --overwrite |
| 64 | + |
| 65 | +# build the TypeScript source after making changes |
| 66 | +jlpm run build |
| 67 | + |
| 68 | +# start JupyterLab |
| 69 | +jupyter lab |
| 70 | +``` |
| 71 | + |
| 72 | +## Activate |
| 73 | + |
| 74 | +As in the demo animated GIF above, once in JupyterLab |
| 75 | + |
| 76 | +1. Open the [Command Palette](https://jupyterlab.readthedocs.io/en/stable/user/commands.html) via, e.g., _View_ ➜ _Activate Command Palette_. |
| 77 | +2. Type in `populate` to see the command created by this extension: _Populate content header (time example)_. |
| 78 | +3. This will create a small header bar at the top of the main JupyterLab window that shows the current time in GMT (Greenwich Mean Time, also called UTC, Coordinated Universal Time). |
| 79 | + |
| 80 | +> Nota bene, you can _toggle_ the `contentHeader` via the _Command Palette_ ➜ _Show Header Above Content_ if you decide you don't want to see it. |
| 81 | +
|
| 82 | +> Nota bene 2, the `contentHeader` and the _Show Header Above Content_ toggle apply on a _per_ `MainAreaWidget`: if you run this extension, it will show the time in the `contentHeader` of the _active_ main area, and the time will not appear in another notebook tab. This may be useful for some extension workflows and not others. |
| 83 | +
|
| 84 | +## Implementation notes |
| 85 | + |
| 86 | +For full details see the body of the `execute` function in [`index.ts`](./src/index.ts), but in prose, here's what to do to make use of the `contentHeader` widget. |
| 87 | + |
| 88 | +First, get a `MainAreaWidget`. The approach used here will likely be useful for many JupyterLab use cases: `JupyterFrontEnd.shell.currentWidget` will be a `MainAreaWidget` if your extension is being activated with a classic JupyterLab window, and you can ensure that by testing for `app.shell.currentWidget instanceof MainAreaWidget`. |
| 89 | + |
| 90 | +`MainAreaWidget.contentHeader` is a "top-to-bottom" vertical [Lumino BoxPanel](https://jupyterlab.github.io/lumino/widgets/classes/boxpanel.html). You can call its `addWidget` and `insertWidget` methods to populate this space with your own custom widgets. |
| 91 | + |
| 92 | +## Background |
| 93 | + |
| 94 | +The motivation for this extension example was a question on the Jupyter Discourse, ["How to add Widget to an arbitrary HTMLElement?"](https://discourse.jupyter.org/t/how-to-add-widget-to-an-arbitrary-htmlelement/11576), where Michał Krassowski kindly recommended to create this example to remind JupyterLab developers of this feature. |
| 95 | + |
| 96 | +The feature was added in [that PR](https://github.com/jupyterlab/jupyterlab/pull/9984) which has further discussion. |
0 commit comments