@jupyter-notebook/application-extension 7.0.0-alpha.1 → 7.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Jupyter Development Team.
2
2
  // Distributed under the terms of the Modified BSD License.
3
- import { ILabStatus, IRouter, ITreePathUpdater, JupyterFrontEnd, Router } from '@jupyterlab/application';
4
- import { sessionContextDialogs, ISessionContextDialogs, DOMUtils, ICommandPalette } from '@jupyterlab/apputils';
3
+ import { ILabStatus, IRouter, ITreePathUpdater, JupyterFrontEnd } from '@jupyterlab/application';
4
+ import { sessionContextDialogs, ISessionContextDialogs, DOMUtils, ICommandPalette, IToolbarWidgetRegistry } from '@jupyterlab/apputils';
5
5
  import { ConsolePanel } from '@jupyterlab/console';
6
6
  import { PageConfig, PathExt, URLExt } from '@jupyterlab/coreutils';
7
7
  import { IDocumentManager, renameDialog } from '@jupyterlab/docmanager';
@@ -9,19 +9,11 @@ import { DocumentWidget } from '@jupyterlab/docregistry';
9
9
  import { IMainMenu } from '@jupyterlab/mainmenu';
10
10
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
11
11
  import { ITranslator } from '@jupyterlab/translation';
12
- import { NotebookApp, NotebookShell, INotebookShell } from '@jupyter-notebook/application';
12
+ import { NotebookApp, NotebookShell, INotebookShell, SidePanelPalette } from '@jupyter-notebook/application';
13
13
  import { jupyterIcon } from '@jupyter-notebook/ui-components';
14
14
  import { PromiseDelegate } from '@lumino/coreutils';
15
15
  import { DisposableDelegate, DisposableSet } from '@lumino/disposable';
16
- import { Widget } from '@lumino/widgets';
17
- /**
18
- * The default notebook factory.
19
- */
20
- const NOTEBOOK_FACTORY = 'Notebook';
21
- /**
22
- * The editor factory.
23
- */
24
- const EDITOR_FACTORY = 'Editor';
16
+ import { Menu, Widget } from '@lumino/widgets';
25
17
  /**
26
18
  * A regular expression to match path to notebooks and documents
27
19
  */
@@ -39,6 +31,10 @@ var CommandIDs;
39
31
  * Toggle Top Bar visibility
40
32
  */
41
33
  CommandIDs.toggleTop = 'application:toggle-top';
34
+ /**
35
+ * Toggle side panel visibility
36
+ */
37
+ CommandIDs.togglePanel = 'application:toggle-panel';
42
38
  /**
43
39
  * Toggle the Zen mode
44
40
  */
@@ -98,7 +94,8 @@ const logo = {
98
94
  elementPosition: 'center',
99
95
  padding: '2px 2px 2px 8px',
100
96
  height: '28px',
101
- width: 'auto'
97
+ width: 'auto',
98
+ cursor: 'pointer'
102
99
  });
103
100
  logo.id = 'jp-NotebookLogo';
104
101
  app.shell.add(logo, 'top', { rank: 0 });
@@ -116,7 +113,7 @@ const opener = {
116
113
  const command = 'router:tree';
117
114
  commands.addCommand(command, {
118
115
  execute: (args) => {
119
- var _a;
116
+ var _a, _b;
120
117
  const parsed = args;
121
118
  const matches = (_a = parsed.path.match(TREE_PATTERN)) !== null && _a !== void 0 ? _a : [];
122
119
  const [, , path] = matches;
@@ -124,19 +121,12 @@ const opener = {
124
121
  return;
125
122
  }
126
123
  const file = decodeURIComponent(path);
127
- const ext = PathExt.extname(file);
128
- app.restored.then(async () => {
129
- // TODO: get factory from file type instead?
130
- if (ext === '.ipynb') {
131
- docManager.open(file, NOTEBOOK_FACTORY, undefined, {
132
- ref: '_noref'
133
- });
134
- }
135
- else {
136
- docManager.open(file, EDITOR_FACTORY, undefined, {
137
- ref: '_noref'
138
- });
139
- }
124
+ const urlParams = new URLSearchParams(parsed.search);
125
+ const factory = (_b = urlParams.get('factory')) !== null && _b !== void 0 ? _b : 'default';
126
+ app.started.then(async () => {
127
+ docManager.open(file, factory, undefined, {
128
+ ref: '_noref'
129
+ });
140
130
  });
141
131
  }
142
132
  });
@@ -145,8 +135,6 @@ const opener = {
145
135
  };
146
136
  /**
147
137
  * A plugin to customize menus
148
- *
149
- * TODO: use this plugin to customize the menu items and their order
150
138
  */
151
139
  const menus = {
152
140
  id: '@jupyter-notebook/application-extension:menus',
@@ -173,6 +161,19 @@ const menus = {
173
161
  }
174
162
  }
175
163
  };
164
+ /**
165
+ * A plugin to provide a spacer at rank 900 in the menu area
166
+ */
167
+ const menuSpacer = {
168
+ id: '@jupyter-notebook/application-extension:menu-spacer',
169
+ autoStart: true,
170
+ activate: (app) => {
171
+ const menu = new Widget();
172
+ menu.id = DOMUtils.createDomID();
173
+ menu.addClass('jp-NotebookSpacer');
174
+ app.shell.add(menu, 'menu', { rank: 900 });
175
+ }
176
+ };
176
177
  /**
177
178
  * Add commands to open the tree and running pages.
178
179
  */
@@ -180,8 +181,8 @@ const pages = {
180
181
  id: '@jupyter-notebook/application-extension:pages',
181
182
  autoStart: true,
182
183
  requires: [ITranslator],
183
- optional: [ICommandPalette, IMainMenu],
184
- activate: (app, translator, palette, menu) => {
184
+ optional: [ICommandPalette],
185
+ activate: (app, translator, palette) => {
185
186
  const trans = translator.load('notebook');
186
187
  const baseUrl = PageConfig.getBaseUrl();
187
188
  app.commands.addCommand(CommandIDs.openLab, {
@@ -201,9 +202,6 @@ const pages = {
201
202
  palette.addItem({ command, category: 'View' });
202
203
  });
203
204
  }
204
- if (menu) {
205
- menu.viewMenu.addGroup([{ command: CommandIDs.openLab }, { command: CommandIDs.openTree }], 0);
206
- }
207
205
  }
208
206
  };
209
207
  /**
@@ -220,29 +218,6 @@ const paths = {
220
218
  return app.paths;
221
219
  }
222
220
  };
223
- /**
224
- * The default URL router provider.
225
- */
226
- const router = {
227
- id: '@jupyter-notebook/application-extension:router',
228
- autoStart: true,
229
- provides: IRouter,
230
- requires: [JupyterFrontEnd.IPaths],
231
- activate: (app, paths) => {
232
- const { commands } = app;
233
- const base = paths.urls.base;
234
- const router = new Router({ base, commands });
235
- void app.started.then(() => {
236
- // Route the very first request on load.
237
- void router.route();
238
- // Route all pop state events.
239
- window.addEventListener('popstate', () => {
240
- void router.route();
241
- });
242
- });
243
- return router;
244
- }
245
- };
246
221
  /**
247
222
  * The default session dialogs plugin
248
223
  */
@@ -266,25 +241,6 @@ const shell = {
266
241
  autoStart: true,
267
242
  provides: INotebookShell
268
243
  };
269
- /**
270
- * A plugin to provide a spacer at rank 900 for flex panels
271
- * TODO: reuse upstream @jupyterlab/application-extension:top-spacer plugin when fixed
272
- * in https://github.com/jupyterlab/jupyterlab/pull/11900
273
- */
274
- const spacer = {
275
- id: '@jupyter-notebook/application-extension:spacer',
276
- autoStart: true,
277
- activate: (app) => {
278
- const top = new Widget();
279
- top.id = DOMUtils.createDomID();
280
- top.addClass('jp-NotebookSpacer');
281
- app.shell.add(top, 'top', { rank: 900 });
282
- const menu = new Widget();
283
- menu.id = DOMUtils.createDomID();
284
- menu.addClass('jp-NotebookSpacer');
285
- app.shell.add(menu, 'menu', { rank: 900 });
286
- }
287
- };
288
244
  /**
289
245
  * The default JupyterLab application status provider.
290
246
  */
@@ -340,25 +296,30 @@ const title = {
340
296
  id: '@jupyter-notebook/application-extension:title',
341
297
  autoStart: true,
342
298
  requires: [INotebookShell, ITranslator],
343
- optional: [IDocumentManager, IRouter],
344
- activate: (app, shell, translator, docManager, router) => {
299
+ optional: [IDocumentManager, IRouter, IToolbarWidgetRegistry],
300
+ activate: (app, shell, translator, docManager, router, toolbarRegistry) => {
345
301
  const { commands } = app;
346
302
  const trans = translator.load('notebook');
347
- const widget = new Widget();
348
- widget.id = 'jp-title';
349
- app.shell.add(widget, 'top', { rank: 10 });
303
+ const node = document.createElement('div');
304
+ if (toolbarRegistry) {
305
+ toolbarRegistry.addFactory('TopBar', 'widgetTitle', toolbar => {
306
+ const widget = new Widget({ node });
307
+ widget.id = 'jp-title';
308
+ return widget;
309
+ });
310
+ }
350
311
  const addTitle = async () => {
351
312
  const current = shell.currentWidget;
352
313
  if (!current || !(current instanceof DocumentWidget)) {
353
314
  return;
354
315
  }
355
- if (widget.node.children.length > 0) {
316
+ if (node.children.length > 0) {
356
317
  return;
357
318
  }
358
319
  const h = document.createElement('h1');
359
320
  h.textContent = current.title.label.replace(STRIP_IPYNB, '');
360
- widget.node.appendChild(h);
361
- widget.node.style.marginLeft = '10px';
321
+ node.appendChild(h);
322
+ node.style.marginLeft = '10px';
362
323
  if (!docManager) {
363
324
  return;
364
325
  }
@@ -370,11 +331,11 @@ const title = {
370
331
  label: () => trans.__('Rename…'),
371
332
  isEnabled,
372
333
  execute: async () => {
373
- var _a, _b;
334
+ var _a;
374
335
  if (!isEnabled()) {
375
336
  return;
376
337
  }
377
- const result = await renameDialog(docManager, current.context.path);
338
+ const result = await renameDialog(docManager, current.context);
378
339
  // activate the current widget to bring the focus
379
340
  if (current) {
380
341
  current.activate();
@@ -382,13 +343,13 @@ const title = {
382
343
  if (result === null) {
383
344
  return;
384
345
  }
385
- const newPath = (_a = current.context.path) !== null && _a !== void 0 ? _a : result.path;
346
+ const newPath = current.context.path;
386
347
  const basename = PathExt.basename(newPath);
387
348
  h.textContent = basename.replace(STRIP_IPYNB, '');
388
349
  if (!router) {
389
350
  return;
390
351
  }
391
- const matches = (_b = router.current.path.match(TREE_PATTERN)) !== null && _b !== void 0 ? _b : [];
352
+ const matches = (_a = router.current.path.match(TREE_PATTERN)) !== null && _a !== void 0 ? _a : [];
392
353
  const [, route, path] = matches;
393
354
  if (!route || !path) {
394
355
  return;
@@ -399,7 +360,7 @@ const title = {
399
360
  });
400
361
  }
401
362
  });
402
- widget.node.onclick = async () => {
363
+ node.onclick = async () => {
403
364
  void commands.execute(CommandIDs.rename);
404
365
  };
405
366
  };
@@ -413,8 +374,8 @@ const title = {
413
374
  const topVisibility = {
414
375
  id: '@jupyter-notebook/application-extension:top',
415
376
  requires: [INotebookShell, ITranslator],
416
- optional: [IMainMenu, ISettingRegistry],
417
- activate: (app, notebookShell, translator, menu, settingRegistry) => {
377
+ optional: [ISettingRegistry, ICommandPalette],
378
+ activate: (app, notebookShell, translator, settingRegistry, palette) => {
418
379
  const trans = translator.load('notebook');
419
380
  const top = notebookShell.top;
420
381
  const pluginId = topVisibility.id;
@@ -428,9 +389,6 @@ const topVisibility = {
428
389
  },
429
390
  isToggled: () => top.isVisible
430
391
  });
431
- if (menu) {
432
- menu.viewMenu.addGroup([{ command: CommandIDs.toggleTop }], 2);
433
- }
434
392
  let settingsOverride = false;
435
393
  if (settingRegistry) {
436
394
  const loadSettings = settingRegistry.load(pluginId);
@@ -452,6 +410,9 @@ const topVisibility = {
452
410
  console.error(reason.message);
453
411
  });
454
412
  }
413
+ if (palette) {
414
+ palette.addItem({ command: CommandIDs.toggleTop, category: 'View' });
415
+ }
455
416
  const onChanged = () => {
456
417
  if (settingsOverride) {
457
418
  return;
@@ -468,6 +429,190 @@ const topVisibility = {
468
429
  },
469
430
  autoStart: true
470
431
  };
432
+ /**
433
+ * Plugin to toggle the left or right side panel's visibility.
434
+ */
435
+ const sidePanelVisibility = {
436
+ id: '@jupyter-notebook/application-extension:sidepanel',
437
+ requires: [INotebookShell, ITranslator],
438
+ optional: [IMainMenu, ICommandPalette],
439
+ autoStart: true,
440
+ activate: (app, notebookShell, translator, menu, palette) => {
441
+ const trans = translator.load('notebook');
442
+ /* Arguments for togglePanel command:
443
+ * side, left or right area
444
+ * title, widget title to show in the menu
445
+ * id, widget ID to activate in the side panel
446
+ */
447
+ app.commands.addCommand(CommandIDs.togglePanel, {
448
+ label: args => args['title'],
449
+ caption: args => {
450
+ // We do not substitute the parameter into the string because the parameter is not
451
+ // localized (e.g., it is always 'left') even though the string is localized.
452
+ if (args['side'] === 'left') {
453
+ return trans.__('Show %1 in the left sidebar', args['title']);
454
+ }
455
+ else if (args['side'] === 'right') {
456
+ return trans.__('Show %1 in the right sidebar', args['title']);
457
+ }
458
+ return trans.__('Show %1 in the sidebar', args['title']);
459
+ },
460
+ execute: args => {
461
+ var _a, _b;
462
+ switch (args['side']) {
463
+ case 'left':
464
+ if (notebookShell.leftCollapsed) {
465
+ notebookShell.expandLeft(args.id);
466
+ }
467
+ else if (((_a = notebookShell.leftHandler.currentWidget) === null || _a === void 0 ? void 0 : _a.id) !== args.id) {
468
+ notebookShell.expandLeft(args.id);
469
+ }
470
+ else {
471
+ notebookShell.collapseLeft();
472
+ if (notebookShell.currentWidget) {
473
+ notebookShell.activateById(notebookShell.currentWidget.id);
474
+ }
475
+ }
476
+ break;
477
+ case 'right':
478
+ if (notebookShell.rightCollapsed) {
479
+ notebookShell.expandRight(args.id);
480
+ }
481
+ else if (((_b = notebookShell.rightHandler.currentWidget) === null || _b === void 0 ? void 0 : _b.id) !== args.id) {
482
+ notebookShell.expandRight(args.id);
483
+ }
484
+ else {
485
+ notebookShell.collapseRight();
486
+ if (notebookShell.currentWidget) {
487
+ notebookShell.activateById(notebookShell.currentWidget.id);
488
+ }
489
+ }
490
+ break;
491
+ }
492
+ },
493
+ isToggled: args => {
494
+ switch (args['side']) {
495
+ case 'left': {
496
+ if (notebookShell.leftCollapsed) {
497
+ return false;
498
+ }
499
+ const currentWidget = notebookShell.leftHandler.currentWidget;
500
+ if (!currentWidget) {
501
+ return false;
502
+ }
503
+ return currentWidget.id === args['id'];
504
+ }
505
+ case 'right': {
506
+ if (notebookShell.rightCollapsed) {
507
+ return false;
508
+ }
509
+ const currentWidget = notebookShell.rightHandler.currentWidget;
510
+ if (!currentWidget) {
511
+ return false;
512
+ }
513
+ return currentWidget.id === args['id'];
514
+ }
515
+ }
516
+ return false;
517
+ }
518
+ });
519
+ const sidePanelMenu = {
520
+ left: null,
521
+ right: null
522
+ };
523
+ /**
524
+ * The function which adds entries to the View menu for each widget of a side panel.
525
+ *
526
+ * @param area - 'left' or 'right', the area of the side panel.
527
+ * @param entryLabel - the name of the main entry in the View menu for that side panel.
528
+ * @returns - The disposable menu added to the View menu or null.
529
+ */
530
+ const updateMenu = (area, entryLabel) => {
531
+ var _a;
532
+ if (menu === null) {
533
+ return null;
534
+ }
535
+ // Remove the previous menu entry for this side panel.
536
+ (_a = sidePanelMenu[area]) === null || _a === void 0 ? void 0 : _a.dispose();
537
+ // Creates a new menu entry and populates it with side panel widgets.
538
+ const newMenu = new Menu({ commands: app.commands });
539
+ newMenu.title.label = entryLabel;
540
+ const widgets = notebookShell.widgets(area);
541
+ let menuToAdd = false;
542
+ for (const widget of widgets) {
543
+ newMenu.addItem({
544
+ command: CommandIDs.togglePanel,
545
+ args: {
546
+ side: area,
547
+ title: `Show ${widget.title.caption}`,
548
+ id: widget.id
549
+ }
550
+ });
551
+ menuToAdd = true;
552
+ }
553
+ // If there are widgets, add the menu to the main menu entry.
554
+ if (menuToAdd) {
555
+ sidePanelMenu[area] = menu.viewMenu.addItem({
556
+ type: 'submenu',
557
+ submenu: newMenu
558
+ });
559
+ }
560
+ };
561
+ app.restored.then(() => {
562
+ // Create menu entries for the left and right panel.
563
+ if (menu) {
564
+ const getSidePanelLabel = (area) => {
565
+ if (area === 'left') {
566
+ return trans.__('Left Sidebar');
567
+ }
568
+ else {
569
+ return trans.__('Right Sidebar');
570
+ }
571
+ };
572
+ const leftArea = notebookShell.leftHandler.area;
573
+ const leftLabel = getSidePanelLabel(leftArea);
574
+ updateMenu(leftArea, leftLabel);
575
+ const rightArea = notebookShell.rightHandler.area;
576
+ const rightLabel = getSidePanelLabel(rightArea);
577
+ updateMenu(rightArea, rightLabel);
578
+ const handleSidePanelChange = (sidePanel, widget) => {
579
+ const label = getSidePanelLabel(sidePanel.area);
580
+ updateMenu(sidePanel.area, label);
581
+ };
582
+ notebookShell.leftHandler.widgetAdded.connect(handleSidePanelChange);
583
+ notebookShell.leftHandler.widgetRemoved.connect(handleSidePanelChange);
584
+ notebookShell.rightHandler.widgetAdded.connect(handleSidePanelChange);
585
+ notebookShell.rightHandler.widgetRemoved.connect(handleSidePanelChange);
586
+ }
587
+ // Add palette entries for side panels.
588
+ if (palette) {
589
+ const sidePanelPalette = new SidePanelPalette({
590
+ commandPalette: palette,
591
+ command: CommandIDs.togglePanel
592
+ });
593
+ notebookShell.leftHandler.widgets.forEach(widget => {
594
+ sidePanelPalette.addItem(widget, notebookShell.leftHandler.area);
595
+ });
596
+ notebookShell.rightHandler.widgets.forEach(widget => {
597
+ sidePanelPalette.addItem(widget, notebookShell.rightHandler.area);
598
+ });
599
+ // Update menu and palette when widgets are added or removed from side panels.
600
+ notebookShell.leftHandler.widgetAdded.connect((sidePanel, widget) => {
601
+ sidePanelPalette.addItem(widget, sidePanel.area);
602
+ });
603
+ notebookShell.leftHandler.widgetRemoved.connect((sidePanel, widget) => {
604
+ sidePanelPalette.removeItem(widget, sidePanel.area);
605
+ });
606
+ notebookShell.rightHandler.widgetAdded.connect((sidePanel, widget) => {
607
+ sidePanelPalette.addItem(widget, sidePanel.area);
608
+ });
609
+ notebookShell.rightHandler.widgetRemoved.connect((sidePanel, widget) => {
610
+ sidePanelPalette.removeItem(widget, sidePanel.area);
611
+ });
612
+ }
613
+ });
614
+ }
615
+ };
471
616
  /**
472
617
  * The default tree route resolver plugin.
473
618
  */
@@ -537,8 +682,8 @@ const zen = {
537
682
  id: '@jupyter-notebook/application-extension:zen',
538
683
  autoStart: true,
539
684
  requires: [ITranslator],
540
- optional: [ICommandPalette, INotebookShell, IMainMenu],
541
- activate: (app, translator, palette, notebookShell, menu) => {
685
+ optional: [ICommandPalette, INotebookShell],
686
+ activate: (app, translator, palette, notebookShell) => {
542
687
  const { commands } = app;
543
688
  const elem = document.documentElement;
544
689
  const trans = translator.load('notebook');
@@ -574,9 +719,6 @@ const zen = {
574
719
  if (palette) {
575
720
  palette.addItem({ command: CommandIDs.toggleZen, category: 'Mode' });
576
721
  }
577
- if (menu) {
578
- menu.viewMenu.addGroup([{ command: CommandIDs.toggleZen }], 3);
579
- }
580
722
  }
581
723
  };
582
724
  /**
@@ -586,13 +728,13 @@ const plugins = [
586
728
  dirty,
587
729
  logo,
588
730
  menus,
731
+ menuSpacer,
589
732
  opener,
590
733
  pages,
591
734
  paths,
592
- router,
593
735
  sessionDialogs,
594
736
  shell,
595
- spacer,
737
+ sidePanelVisibility,
596
738
  status,
597
739
  tabTitle,
598
740
  title,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter-notebook/application-extension",
3
- "version": "7.0.0-alpha.1",
3
+ "version": "7.0.0-alpha.10",
4
4
  "description": "Jupyter Notebook - Application Extension",
5
5
  "homepage": "https://github.com/jupyter/notebook",
6
6
  "bugs": {
@@ -39,27 +39,26 @@
39
39
  "watch": "tsc -b --watch"
40
40
  },
41
41
  "dependencies": {
42
- "@jupyter-notebook/application": "^7.0.0-alpha.1",
43
- "@jupyter-notebook/ui-components": "^7.0.0-alpha.1",
44
- "@jupyterlab/application": "^4.0.0-alpha.5",
45
- "@jupyterlab/apputils": "^4.0.0-alpha.5",
46
- "@jupyterlab/celltags": "^4.0.0-alpha.5",
47
- "@jupyterlab/codeeditor": "^4.0.0-alpha.5",
48
- "@jupyterlab/codemirror": "^4.0.0-alpha.5",
49
- "@jupyterlab/console": "^4.0.0-alpha.5",
50
- "@jupyterlab/coreutils": "^6.0.0-alpha.5",
51
- "@jupyterlab/docmanager": "^4.0.0-alpha.5",
52
- "@jupyterlab/docregistry": "^4.0.0-alpha.5",
53
- "@jupyterlab/mainmenu": "^4.0.0-alpha.5",
54
- "@jupyterlab/settingregistry": "^4.0.0-alpha.5",
55
- "@jupyterlab/translation": "^4.0.0-alpha.4",
56
- "@lumino/coreutils": "^1.12.0",
57
- "@lumino/disposable": "^1.10.1",
58
- "@lumino/widgets": "^1.31.1"
42
+ "@jupyter-notebook/application": "^7.0.0-alpha.10",
43
+ "@jupyter-notebook/ui-components": "^7.0.0-alpha.10",
44
+ "@jupyterlab/application": "^4.0.0-alpha.17",
45
+ "@jupyterlab/apputils": "^4.0.0-alpha.17",
46
+ "@jupyterlab/celltags": "^4.0.0-alpha.17",
47
+ "@jupyterlab/codeeditor": "^4.0.0-alpha.17",
48
+ "@jupyterlab/console": "^4.0.0-alpha.17",
49
+ "@jupyterlab/coreutils": "^6.0.0-alpha.17",
50
+ "@jupyterlab/docmanager": "^4.0.0-alpha.17",
51
+ "@jupyterlab/docregistry": "^4.0.0-alpha.17",
52
+ "@jupyterlab/mainmenu": "^4.0.0-alpha.17",
53
+ "@jupyterlab/settingregistry": "^4.0.0-alpha.17",
54
+ "@jupyterlab/translation": "^4.0.0-alpha.17",
55
+ "@lumino/coreutils": "^2.0.0-alpha.7",
56
+ "@lumino/disposable": "^2.0.0-alpha.7",
57
+ "@lumino/widgets": "^2.0.0-alpha.7"
59
58
  },
60
59
  "devDependencies": {
61
- "rimraf": "~3.0.0",
62
- "typescript": "~4.1.3"
60
+ "rimraf": "^3.0.2",
61
+ "typescript": "~4.9.3"
63
62
  },
64
63
  "publishConfig": {
65
64
  "access": "public"
package/schema/menus.json CHANGED
@@ -8,13 +8,56 @@
8
8
  "items": [
9
9
  {
10
10
  "command": "application:rename",
11
- "rank": 4
11
+ "rank": 4.5
12
12
  },
13
13
  {
14
14
  "command": "notebook:trust",
15
15
  "rank": 20
16
16
  }
17
17
  ]
18
+ },
19
+ {
20
+ "id": "jp-mainmenu-view",
21
+ "items": [
22
+ {
23
+ "type": "submenu",
24
+ "disabled": true,
25
+ "submenu": {
26
+ "id": "jp-mainmenu-view-appearance"
27
+ }
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "id": "jp-mainmenu-run",
33
+ "items": [
34
+ {
35
+ "type": "separator",
36
+ "rank": 1000
37
+ },
38
+ {
39
+ "type": "submenu",
40
+ "rank": 1010,
41
+ "submenu": {
42
+ "id": "jp-runmenu-change-cell-type",
43
+ "label": "Cell Type",
44
+ "items": [
45
+ {
46
+ "command": "notebook:change-cell-to-code",
47
+ "rank": 0
48
+ },
49
+ {
50
+ "command": "notebook:change-cell-to-markdown",
51
+ "rank": 0
52
+ },
53
+ {
54
+ "command": "notebook:change-cell-to-raw",
55
+ "rank": 0
56
+ }
57
+ ]
58
+ }
59
+ }
60
+ ]
18
61
  }
19
62
  ]
20
63
  },
@@ -0,0 +1,24 @@
1
+ {
2
+ "title": "Jupyter Notebook Pages",
3
+ "description": "Jupyter Notebook Pages",
4
+ "jupyter.lab.menus": {
5
+ "main": [
6
+ {
7
+ "id": "jp-mainmenu-view",
8
+ "items": [
9
+ {
10
+ "command": "application:open-lab",
11
+ "rank": 2
12
+ },
13
+ {
14
+ "command": "application:open-tree",
15
+ "rank": 2
16
+ }
17
+ ]
18
+ }
19
+ ]
20
+ },
21
+ "properties": {},
22
+ "additionalProperties": false,
23
+ "type": "object"
24
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "title": "Title widget",
3
+ "description": "Title widget",
4
+ "jupyter.lab.toolbars": {
5
+ "TopBar": [{ "name": "widgetTitle", "rank": 10 }]
6
+ },
7
+ "properties": {},
8
+ "additionalProperties": false,
9
+ "type": "object"
10
+ }
package/schema/top.json CHANGED
@@ -3,6 +3,19 @@
3
3
  "jupyter.lab.setting-icon-label": "Jupyter Notebook Top Area",
4
4
  "title": "Jupyter Notebook Top Area",
5
5
  "description": "Jupyter Notebook Top Area settings",
6
+ "jupyter.lab.menus": {
7
+ "main": [
8
+ {
9
+ "id": "jp-mainmenu-view",
10
+ "items": [
11
+ {
12
+ "command": "application:toggle-top",
13
+ "rank": 2
14
+ }
15
+ ]
16
+ }
17
+ ]
18
+ },
6
19
  "properties": {
7
20
  "visible": {
8
21
  "type": "boolean",
@@ -0,0 +1,20 @@
1
+ {
2
+ "title": "Jupyter Notebook Zen Mode",
3
+ "description": "Jupyter Notebook Zen Mode",
4
+ "jupyter.lab.menus": {
5
+ "main": [
6
+ {
7
+ "id": "jp-mainmenu-view",
8
+ "items": [
9
+ {
10
+ "command": "application:toggle-zen",
11
+ "rank": 3
12
+ }
13
+ ]
14
+ }
15
+ ]
16
+ },
17
+ "properties": {},
18
+ "additionalProperties": false,
19
+ "type": "object"
20
+ }
package/style/base.css CHANGED
@@ -12,3 +12,18 @@
12
12
  .jp-MainAreaWidget {
13
13
  height: 100%;
14
14
  }
15
+
16
+ .jp-Toolbar > .jp-Toolbar-item {
17
+ height: unset;
18
+ }
19
+
20
+ #jp-UserMenu {
21
+ flex: 0 0 auto;
22
+ display: flex;
23
+ text-align: center;
24
+ margin-top: 8px;
25
+ }
26
+
27
+ .jp-MimeDocument .jp-RenderedJSON {
28
+ background: var(--jp-layout-color0);
29
+ }