|
| 1 | +# Shout button (cross compatible extension) |
| 2 | + |
| 3 | +This example defines an extension that adds a button in the right sidebar that |
| 4 | +if clicked will display an alert to the user and in JupyterLab will update |
| 5 | +a widget in the status bar. |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +We strongly advice to look to those examples before diving into this one: |
| 10 | + |
| 11 | +- [signals](../signals/): Communication between JavaScript objects. |
| 12 | +- [widgets](../widgets): The basic DOM Jupyter component |
| 13 | + |
| 14 | +## Jupyter Notebook / JupyterLab compatibility |
| 15 | + |
| 16 | +As Jupyter Notebook 7+ is built with components from JupyterLab, and since |
| 17 | +both use the same building blocks, that means your extension can work |
| 18 | +on both (or any other frontend built with JupyterLab components) with |
| 19 | +little or no modification depending on its design. |
| 20 | + |
| 21 | +This example has a part specific to JupyterLab. This translate by having |
| 22 | +optional dependency for your extension plugin. |
| 23 | + |
| 24 | +```ts |
| 25 | +// src/index.ts#L120-L120 |
| 26 | + |
| 27 | +optional: [IStatusBar], |
| 28 | +``` |
| 29 | + |
| 30 | +If your dependency is optional, the object pass to the `activate` method |
| 31 | +will be `null` if no other plugin provides it. |
| 32 | + |
| 33 | +```ts |
| 34 | +// src/index.ts#L124-L124 |
| 35 | + |
| 36 | +activate: (app: JupyterFrontEnd, statusBar: IStatusBar | null) => { |
| 37 | +``` |
| 38 | +
|
| 39 | +## Add the button in the sidebar |
| 40 | +
|
| 41 | +You can add a widget to the right sidebar through the application shell: |
| 42 | +
|
| 43 | +```ts |
| 44 | +// src/index.ts#L128-L131 |
| 45 | + |
| 46 | +const shoutWidget: ShoutWidget = new ShoutWidget(); |
| 47 | +shoutWidget.id = 'JupyterShoutWidget'; // Widgets need an id |
| 48 | + |
| 49 | +app.shell.add(shoutWidget, 'right'); |
| 50 | +``` |
| 51 | +
|
| 52 | +The `ShoutWidget` is a widget that contains a button that when clicked |
| 53 | +emit a signal `messageShouted` that any callback can listen to to react |
| 54 | +to it and display an alert to the user. |
| 55 | +
|
| 56 | +```ts |
| 57 | +// src/index.ts#L99-L103 |
| 58 | + |
| 59 | +shout() { |
| 60 | + this._lastShoutTime = new Date(); |
| 61 | + this._messageShouted.emit(this._lastShoutTime); |
| 62 | + window.alert('Shouting at ' + this._lastShoutTime); |
| 63 | +} |
| 64 | +``` |
| 65 | +
|
| 66 | +## Connect the button and the status bar |
| 67 | +
|
| 68 | +The status bar does not exist in all Jupyter applications (e.g. in |
| 69 | +Jupyter Notebook). So a good practice is to make that dependency |
| 70 | +optional and test for it to be non-null to carry related action: |
| 71 | +
|
| 72 | +```ts |
| 73 | +// src/index.ts#L135-L135 |
| 74 | + |
| 75 | +if (statusBar) { |
| 76 | +``` |
| 77 | +
|
| 78 | +In this specific case, the action is to create a widget to add to the |
| 79 | +status bar. You can achieve that by calling the `registerStatusItem` |
| 80 | +method from the status bar object. |
| 81 | +
|
| 82 | +```ts |
| 83 | +// src/index.ts#L136-L138 |
| 84 | + |
| 85 | +const statusBarWidget = new ShoutStatusBarSummary(); |
| 86 | + |
| 87 | +statusBar.registerStatusItem('shoutStatusBarSummary', { |
| 88 | +``` |
| 89 | +
|
| 90 | +If you want to react to a click on the button, you can `connect` to the |
| 91 | +widget `messageShouted` signal. In which for example, you update the |
| 92 | +text displayed in the status bar. |
| 93 | +
|
| 94 | +```ts |
| 95 | +// src/index.ts#L142-L144 |
| 96 | + |
| 97 | +// Connect to the messageShouted to be notified when a new message |
| 98 | +// is published and react to it by updating the status bar widget. |
| 99 | +shoutWidget.messageShouted.connect((widget: ShoutWidget, time: Date) => { |
| 100 | +``` |
| 101 | +
|
| 102 | +## Where to Go Next |
| 103 | +
|
| 104 | +You can have more information about making extension compatible with |
| 105 | +multiple applications in the |
| 106 | +[Extension Dual Compatibility Guide](https://jupyterlab.readthedocs.io/en/latest/extension_dual_compatibility.html). |
0 commit comments