jupyter-specta 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -1 +1,52 @@
1
- # specta
1
+ <h1 align="center">specta 🌟</h1>
2
+
3
+ [![Github Actions Status](https://github.com/trungleduc/specta/workflows/Build/badge.svg)](https://github.com/trungleduc/specta/actions/workflows/build.yml)
4
+ [![Documentation Status](https://readthedocs.org/projects/specta/badge/?version=latest)](https://specta.readthedocs.io/en/latest/?badge=latest)
5
+ [![Try on lite](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://trungleduc.github.io/specta/specta/)
6
+
7
+ <h2 align="center"> A JupyterLite app to present your Jupyter documents in different ways</h2>
8
+
9
+ Specta is a custom JupyterLite app for rendering notebooks and Jupyter‑supported files in multiple modes: dashboards, blog‑style articles, fullscreen viewers, and more. It is built on top of [JupyterLite](https://github.com/jupyterlite/jupyterlite), which allows you to share your documents through alternative interfaces to the IDE-like JupyterLab.
10
+
11
+ ## Features
12
+
13
+ ### Multi-mode Notebook Rendering
14
+
15
+ Render notebooks in:
16
+
17
+ - **Dashboard mode** – structured panels for interactive widgets and outputs
18
+ - **Article mode** – a minimal, blog-like reading experience
19
+
20
+ ### Clean Viewer for all Jupyter-supported file types
21
+
22
+ View any Jupyter-supported file using Specta's clean viewer with all Jupyter UI elements removed.
23
+
24
+ ### Preview from JupyterLab
25
+
26
+ A `specta` preview can be launched directly from JupyterLab, letting users verify how their documents will look when published.
27
+
28
+ ## Installation and Usage
29
+
30
+ You can install `specta` using `pip` or `conda`
31
+
32
+ ```bash
33
+ # Install using pip
34
+ pip install specta
35
+
36
+ # Install using conda
37
+ conda install -c conda-forge specta
38
+ ```
39
+
40
+ Once installed, you can build your JupyterLite app, a `specta` app will be included automatically in the output directory of `jupyterlite`:
41
+
42
+ ```
43
+ jupyter lite build
44
+ ```
45
+
46
+ Then serve the contents of the output directory (by default `./_output`) using any static file server. You can access the `specta` app at the `/specta/` path.
47
+
48
+ ## Try it online!
49
+
50
+ You can try it online by clicking on this badge:
51
+
52
+ [![Try on lite](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://trungleduc.github.io/specta/specta/)
@@ -32,7 +32,6 @@ export async function createNotebookContext(options) {
32
32
  path,
33
33
  kernelPreference: kernelPreference
34
34
  });
35
- await context.sessionContext.initialize();
36
35
  return context;
37
36
  }
38
37
  export function createNotebookPanel(options) {
@@ -2,16 +2,21 @@ import { IThemeManager } from '@jupyterlab/apputils';
2
2
  import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry';
3
3
  import { INotebookModel } from '@jupyterlab/notebook';
4
4
  import { SpectaWidgetFactory } from '../specta_widget_factory';
5
- import { ISpectaLayoutRegistry } from '../token';
5
+ import { ISpectaLayoutRegistry, ISpectaShell } from '../token';
6
6
  import { NotebookSpectaDocWidget } from './widget';
7
7
  interface IOptions extends DocumentRegistry.IWidgetFactoryOptions {
8
8
  spectaWidgetFactory: SpectaWidgetFactory;
9
9
  layoutRegistry?: ISpectaLayoutRegistry;
10
10
  themeManager?: IThemeManager;
11
+ shell: ISpectaShell;
12
+ spectaLayoutRegistry: ISpectaLayoutRegistry;
11
13
  }
12
14
  export declare class NotebookGridWidgetFactory extends ABCWidgetFactory<NotebookSpectaDocWidget, INotebookModel> {
13
15
  constructor(options: IOptions);
14
16
  protected createNewWidget(context: DocumentRegistry.IContext<INotebookModel>): NotebookSpectaDocWidget;
15
17
  private _spectaWidgetFactory;
18
+ private _shell;
19
+ private _themeManager?;
20
+ private _layoutRegistry;
16
21
  }
17
22
  export {};
@@ -9,17 +9,41 @@ export class NotebookGridWidgetFactory extends ABCWidgetFactory {
9
9
  constructor(options) {
10
10
  super(options);
11
11
  this._spectaWidgetFactory = options.spectaWidgetFactory;
12
+ this._shell = options.shell;
13
+ this._themeManager = options.themeManager;
14
+ this._layoutRegistry = options.spectaLayoutRegistry;
12
15
  }
13
16
  createNewWidget(context) {
14
17
  const content = new Panel();
15
18
  content.addClass('jp-specta-notebook-panel');
16
- const spectaConfig = readSpectaConfig(context.model.metadata);
17
- if (!isSpectaApp() && !spectaConfig.hideTopbar) {
18
- // Not a specta app, add topbar to document widget
19
- const topbar = ReactWidget.create(React.createElement(TopbarElement, null));
20
- content.addWidget(topbar);
21
- }
22
19
  context.ready.then(async () => {
20
+ var _a;
21
+ const path = (_a = context.contentsModel) === null || _a === void 0 ? void 0 : _a.path;
22
+ const spectaConfig = readSpectaConfig({
23
+ nbMetadata: context.model.metadata,
24
+ nbPath: path
25
+ });
26
+ const isSpecta = isSpectaApp();
27
+ if (!spectaConfig.hideTopbar) {
28
+ const topbar = ReactWidget.create(React.createElement(TopbarElement, { config: spectaConfig.topBar, themeManager: this._themeManager, layoutRegistry: this._layoutRegistry }));
29
+ topbar.addClass('specta-topbar-element');
30
+ if (!isSpecta) {
31
+ // Not a specta app, add topbar to document widget
32
+ content.addWidget(topbar);
33
+ }
34
+ else {
35
+ // Specta app, add topbar to layout
36
+ topbar.id = 'specta-topbar-widget';
37
+ this._shell.add(topbar, 'top');
38
+ if (topbar.parent) {
39
+ topbar.parent.node.style.boxShadow =
40
+ 'rgba(0 0 0 / 20%) 0 2px 4px -1px, rgba(0 0 0 / 14%) 0 4px 5px 0, rgba(0 0 0 / 12%) 0 1px 10px 0';
41
+ }
42
+ }
43
+ }
44
+ else if (isSpecta) {
45
+ this._shell.hideTopBar();
46
+ }
23
47
  const spectaWidget = await this._spectaWidgetFactory.createNew({
24
48
  context
25
49
  });
@@ -1,4 +1,5 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  import { IWidgetTracker } from '@jupyterlab/apputils';
3
- export declare const spectaDocument: JupyterFrontEndPlugin<IWidgetTracker>;
3
+ import { ISpectaShell } from '../token';
4
+ export declare const spectaDocument: JupyterFrontEndPlugin<IWidgetTracker, ISpectaShell>;
4
5
  export declare const spectaOpener: JupyterFrontEndPlugin<void>;
@@ -1,4 +1,4 @@
1
- import { WidgetTracker } from '@jupyterlab/apputils';
1
+ import { IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
2
2
  import { IEditorServices } from '@jupyterlab/codeeditor';
3
3
  import { PathExt } from '@jupyterlab/coreutils';
4
4
  import { IDocumentManager } from '@jupyterlab/docmanager';
@@ -8,7 +8,7 @@ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
8
8
  import { IKernelSpecManager } from '@jupyterlab/services';
9
9
  import { ISpectaDocTracker, ISpectaLayoutRegistry } from '../token';
10
10
  import { createFileBrowser, hideAppLoadingIndicator, isSpectaApp, registerDocumentFactory } from '../tool';
11
- const activate = (app, rendermime, tracker, editorServices, contentFactory, spectaLayoutRegistry) => {
11
+ const activate = (app, rendermime, tracker, editorServices, contentFactory, spectaLayoutRegistry, themeManager) => {
12
12
  const namespace = 'specta';
13
13
  const spectaTracker = new WidgetTracker({ namespace });
14
14
  registerDocumentFactory({
@@ -19,7 +19,8 @@ const activate = (app, rendermime, tracker, editorServices, contentFactory, spec
19
19
  editorServices,
20
20
  contentFactory,
21
21
  spectaTracker,
22
- spectaLayoutRegistry
22
+ spectaLayoutRegistry,
23
+ themeManager
23
24
  });
24
25
  return spectaTracker;
25
26
  };
@@ -31,7 +32,8 @@ export const spectaDocument = {
31
32
  INotebookTracker,
32
33
  IEditorServices,
33
34
  NotebookPanel.IContentFactory,
34
- ISpectaLayoutRegistry
35
+ ISpectaLayoutRegistry,
36
+ IThemeManager
35
37
  ],
36
38
  activate,
37
39
  provides: ISpectaDocTracker
@@ -1,4 +1,4 @@
1
1
  export * from './tool';
2
2
  export * from './token';
3
- declare const _default: (import("@jupyterlab/application").JupyterFrontEndPlugin<import("@jupyterlab/apputils").IWidgetTracker<import("@lumino/widgets").Widget>> | import("@jupyterlab/application").JupyterFrontEndPlugin<void> | import("@jupyterlab/application").JupyterFrontEndPlugin<import("./token").ISpectaLayoutRegistry>)[];
3
+ declare const _default: (import("@jupyterlab/application").JupyterFrontEndPlugin<import("@jupyterlab/apputils").IWidgetTracker<import("@lumino/widgets").Widget>, import("./token").ISpectaShell> | import("@jupyterlab/application").JupyterFrontEndPlugin<import("./token").ISpectaLayoutRegistry> | import("@jupyterlab/application").JupyterFrontEndPlugin<void, import("./token").ISpectaShell>)[];
4
4
  export default _default;
@@ -8,7 +8,7 @@ export const spectaLayoutRegistry = {
8
8
  activate: (app) => {
9
9
  var _a;
10
10
  const layoutRegistry = new SpectaLayoutRegistry();
11
- const spectaConfig = readSpectaConfig();
11
+ const spectaConfig = readSpectaConfig({});
12
12
  const defaultLayout = (_a = spectaConfig.defaultLayout) !== null && _a !== void 0 ? _a : 'default';
13
13
  layoutRegistry.setSelectedLayout(defaultLayout);
14
14
  return layoutRegistry;
package/lib/shell.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { JupyterFrontEnd } from '@jupyterlab/application';
2
1
  import { DocumentRegistry } from '@jupyterlab/docregistry';
3
2
  import { Widget } from '@lumino/widgets';
3
+ import { ISpectaShell } from './token';
4
4
  /**
5
5
  * A namespace for Shell statics
6
6
  */
@@ -13,7 +13,7 @@ export declare namespace IShell {
13
13
  /**
14
14
  * The application shell.
15
15
  */
16
- export declare class SpectaShell extends Widget implements JupyterFrontEnd.IShell {
16
+ export declare class SpectaShell extends Widget implements ISpectaShell {
17
17
  constructor();
18
18
  /**
19
19
  * The current widget in the shell's main area.
@@ -30,6 +30,7 @@ export declare class SpectaShell extends Widget implements JupyterFrontEnd.IShel
30
30
  *
31
31
  */
32
32
  add(widget: Widget, area?: IShell.Area, options?: DocumentRegistry.IOpenOptions): void;
33
+ hideTopBar(): void;
33
34
  widgets(area: IShell.Area): IterableIterator<Widget>;
34
35
  /**
35
36
  * Add a widget to the top content area.
package/lib/shell.js CHANGED
@@ -78,6 +78,9 @@ export class SpectaShell extends Widget {
78
78
  break;
79
79
  }
80
80
  }
81
+ hideTopBar() {
82
+ this._topHandler.panel.hide();
83
+ }
81
84
  widgets(area) {
82
85
  switch (area) {
83
86
  case 'top':
@@ -2,7 +2,6 @@ import { CodeCell, MarkdownCell, RawCell } from '@jupyterlab/cells';
2
2
  import { OutputAreaModel, SimplifiedOutputArea } from '@jupyterlab/outputarea';
3
3
  import { createNotebookContext, createNotebookPanel } from './create_notebook_panel';
4
4
  import { SpectaCellOutput } from './specta_cell_output';
5
- import { PromiseDelegate } from '@lumino/coreutils';
6
5
  import { readCellConfig } from './tool';
7
6
  export const VIEW = 'grid_default';
8
7
  export class AppModel {
@@ -49,41 +48,18 @@ export class AppModel {
49
48
  return this._notebookPanel;
50
49
  }
51
50
  async initialize() {
52
- var _a;
53
- const pd = new PromiseDelegate();
54
51
  this._context = await createNotebookContext({
55
52
  manager: this._manager,
56
53
  kernelPreference: this._kernelPreference
57
54
  });
58
55
  this._context.model.fromJSON(this._notebookModelJson);
59
- const connectKernel = () => {
60
- pd.resolve();
61
- this._notebookPanel = createNotebookPanel({
62
- context: this._context,
63
- rendermime: this.options.rendermime,
64
- editorServices: this.options.editorServices
65
- });
66
- this.options.tracker.widgetAdded.emit(this._notebookPanel);
67
- };
68
- const kernel = (_a = this._context.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
69
- if (kernel) {
70
- const status = kernel.status;
71
- if (status !== 'unknown') {
72
- // Connected to an existing kernel.
73
- connectKernel();
74
- return;
75
- }
76
- }
77
- this._context.sessionContext.connectionStatusChanged.connect((_, status) => {
78
- var _a;
79
- if (status === 'connected') {
80
- const kernel = (_a = this._context.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
81
- if (kernel) {
82
- connectKernel();
83
- }
84
- }
85
- }, this);
86
- return pd.promise;
56
+ this._notebookPanel = createNotebookPanel({
57
+ context: this._context,
58
+ rendermime: this.options.rendermime,
59
+ editorServices: this.options.editorServices
60
+ });
61
+ this.options.tracker.add(this._notebookPanel);
62
+ await this._context.sessionContext.initialize();
87
63
  }
88
64
  createCell(cellModel) {
89
65
  let item;
@@ -8,6 +8,7 @@ export class SpectaWidgetFactory {
8
8
  this._options = options;
9
9
  }
10
10
  async createNew(options) {
11
+ var _a;
11
12
  const { context } = options;
12
13
  const rendermime = this._options.rendermime.clone({
13
14
  resolver: context.urlResolver
@@ -23,12 +24,16 @@ export class SpectaWidgetFactory {
23
24
  notebookConfig: StaticNotebook.defaultNotebookConfig,
24
25
  editorServices: this._options.editorServices
25
26
  });
27
+ const spectaConfig = readSpectaConfig({
28
+ nbMetadata: context.model.metadata,
29
+ nbPath: (_a = context.contentsModel) === null || _a === void 0 ? void 0 : _a.path
30
+ });
26
31
  const panel = new AppWidget({
27
32
  id: UUID.uuid4(),
28
33
  label: '',
29
34
  model,
30
35
  layoutRegistry: this._options.spectaLayoutRegistry,
31
- spectaConfig: readSpectaConfig(context.model.metadata)
36
+ spectaConfig
32
37
  });
33
38
  return panel;
34
39
  }
package/lib/token.d.ts CHANGED
@@ -4,6 +4,10 @@ import { SpectaCellOutput } from './specta_cell_output';
4
4
  import * as nbformat from '@jupyterlab/nbformat';
5
5
  import { ISignal } from '@lumino/signaling';
6
6
  import { IWidgetTracker } from '@jupyterlab/apputils';
7
+ import { JupyterFrontEnd } from '@jupyterlab/application';
8
+ export interface ISpectaShell extends JupyterFrontEnd.IShell {
9
+ hideTopBar: () => void;
10
+ }
7
11
  export interface ISpectaLayout {
8
12
  render(options: {
9
13
  host: Panel;
package/lib/tool.d.ts CHANGED
@@ -1,25 +1,29 @@
1
1
  import { JupyterFrontEnd } from '@jupyterlab/application';
2
- import { WidgetTracker } from '@jupyterlab/apputils';
2
+ import { IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
3
3
  import { IEditorServices } from '@jupyterlab/codeeditor';
4
4
  import { IDefaultFileBrowser } from '@jupyterlab/filebrowser';
5
5
  import { ICell, INotebookMetadata } from '@jupyterlab/nbformat';
6
6
  import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
7
7
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
8
- import { ISpectaAppConfig, ISpectaCellConfig, ISpectaLayoutRegistry } from './token';
8
+ import { ISpectaAppConfig, ISpectaCellConfig, ISpectaLayoutRegistry, ISpectaShell } from './token';
9
9
  export declare function registerDocumentFactory(options: {
10
10
  factoryName: string;
11
- app: JupyterFrontEnd;
11
+ app: JupyterFrontEnd<ISpectaShell>;
12
12
  rendermime: IRenderMimeRegistry;
13
13
  tracker: INotebookTracker;
14
14
  editorServices: IEditorServices;
15
15
  contentFactory: NotebookPanel.IContentFactory;
16
16
  spectaTracker: WidgetTracker;
17
17
  spectaLayoutRegistry: ISpectaLayoutRegistry;
18
+ themeManager?: IThemeManager;
18
19
  }): void;
19
20
  export declare function createFileBrowser(options: {
20
21
  defaultBrowser: IDefaultFileBrowser;
21
22
  }): any;
22
23
  export declare function hideAppLoadingIndicator(): void;
23
24
  export declare function isSpectaApp(): boolean;
24
- export declare function readSpectaConfig(nbMetadata?: INotebookMetadata): ISpectaAppConfig;
25
+ export declare function readSpectaConfig({ nbMetadata, nbPath }: {
26
+ nbMetadata?: INotebookMetadata;
27
+ nbPath?: string | null;
28
+ }): ISpectaAppConfig;
25
29
  export declare function readCellConfig(cell?: ICell): Required<ISpectaCellConfig>;
package/lib/tool.js CHANGED
@@ -1,9 +1,20 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { PageConfig, URLExt } from '@jupyterlab/coreutils';
2
13
  import { NotebookModelFactory } from '@jupyterlab/notebook';
3
14
  import { NotebookGridWidgetFactory } from './document/factory';
4
15
  import { SpectaWidgetFactory } from './specta_widget_factory';
5
16
  export function registerDocumentFactory(options) {
6
- const { factoryName, app, rendermime, tracker, editorServices, contentFactory, spectaTracker, spectaLayoutRegistry } = options;
17
+ const { factoryName, app, rendermime, tracker, editorServices, contentFactory, spectaTracker, spectaLayoutRegistry, themeManager } = options;
7
18
  const spectaWidgetFactory = new SpectaWidgetFactory({
8
19
  manager: app.serviceManager,
9
20
  rendermime,
@@ -17,7 +28,10 @@ export function registerDocumentFactory(options) {
17
28
  name: factoryName,
18
29
  modelName: 'notebook',
19
30
  fileTypes: ['ipynb'],
20
- spectaWidgetFactory
31
+ spectaWidgetFactory,
32
+ shell: app.shell,
33
+ themeManager,
34
+ spectaLayoutRegistry
21
35
  });
22
36
  // Registering the widget factory
23
37
  app.docRegistry.addWidgetFactory(widgetFactory);
@@ -89,13 +103,17 @@ export function hideAppLoadingIndicator() {
89
103
  export function isSpectaApp() {
90
104
  return !!document.querySelector('meta[name="specta-config"]');
91
105
  }
92
- export function readSpectaConfig(nbMetadata) {
106
+ export function readSpectaConfig({ nbMetadata, nbPath }) {
93
107
  var _a;
94
108
  let rawConfig = PageConfig.getOption('spectaConfig');
95
109
  if (!rawConfig || rawConfig.length === 0) {
96
110
  rawConfig = '{}';
97
111
  }
98
- const spectaConfig = JSON.parse(rawConfig);
112
+ const _b = JSON.parse(rawConfig), { perFileConfig } = _b, globalConfig = __rest(_b, ["perFileConfig"]);
113
+ let spectaConfig = Object.assign({}, (globalConfig !== null && globalConfig !== void 0 ? globalConfig : {}));
114
+ if (perFileConfig && nbPath && perFileConfig[nbPath]) {
115
+ spectaConfig = Object.assign(Object.assign({}, spectaConfig), perFileConfig[nbPath]);
116
+ }
99
117
  const spectaMetadata = ((_a = nbMetadata === null || nbMetadata === void 0 ? void 0 : nbMetadata.specta) !== null && _a !== void 0 ? _a : {});
100
118
  return Object.assign(Object.assign({}, spectaConfig), spectaMetadata);
101
119
  }
@@ -1,5 +1,3 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
- /**
3
- * Initialization data for the voila_topbar extension.
4
- */
5
- export declare const topbarPlugin: JupyterFrontEndPlugin<void>;
2
+ import { ISpectaShell } from '../token';
3
+ export declare const topbarPlugin: JupyterFrontEndPlugin<void, ISpectaShell>;
@@ -4,11 +4,9 @@ import { TopbarElement } from './widget';
4
4
  import * as React from 'react';
5
5
  import { isSpectaApp, readSpectaConfig } from '../tool';
6
6
  import { ISpectaLayoutRegistry } from '../token';
7
- /**
8
- * Initialization data for the voila_topbar extension.
9
- */
7
+ import { PathExt } from '@jupyterlab/coreutils';
10
8
  export const topbarPlugin = {
11
- id: 'specta:topba',
9
+ id: 'specta:topbar',
12
10
  description: 'Specta topbar extension',
13
11
  autoStart: true,
14
12
  requires: [IThemeManager, ISpectaLayoutRegistry],
@@ -17,7 +15,17 @@ export const topbarPlugin = {
17
15
  if (!isSpecta) {
18
16
  return;
19
17
  }
20
- const config = readSpectaConfig();
18
+ const urlParams = new URLSearchParams(window.location.search);
19
+ const path = urlParams.get('path');
20
+ if (path && PathExt.extname(path) === '.ipynb') {
21
+ // Specta document will handle the top bar.
22
+ return;
23
+ }
24
+ const config = readSpectaConfig({ nbPath: path });
25
+ if (config.hideTopbar) {
26
+ app.shell.hideTopBar();
27
+ return;
28
+ }
21
29
  const widget = ReactWidget.create(React.createElement(TopbarElement, { config: config.topBar, themeManager: themeManager, layoutRegistry: layoutRegistry }));
22
30
  widget.id = 'specta-topbar-widget';
23
31
  widget.addClass('specta-topbar-element');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyter-specta",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/trungleduc/specta",
@@ -36,6 +36,7 @@
36
36
  "build:all": "npm run build:app && npm run build:labextension",
37
37
  "build:all:dev": "npm run build:app:dev && npm run build:labextension:dev",
38
38
  "build:demo": "cd demo && rm -rf .jupyterlite.doit.db _output && jupyter lite build .",
39
+ "update:demo": "node script/build-dev.mjs",
39
40
  "lint": "npm run lint:prettier && npm run lint:eslint",
40
41
  "lint:prettier": "prettier --no-error-on-unmatched-pattern --write \"**/*{.ts,.tsx,.jsx,.css,.json,.md,.yml}\"",
41
42
  "lint:eslint": "eslint --ext .ts,.tsx .",
@@ -56,9 +57,9 @@
56
57
  "@jupyterlab/coreutils": "^6.4.2",
57
58
  "@jupyterlab/docmanager": "^4.4.2",
58
59
  "@jupyterlab/docmanager-extension": "^4.4.2",
60
+ "@jupyterlab/docregistry": "^4.4.2",
59
61
  "@jupyterlab/filebrowser": "^4.4.2",
60
62
  "@jupyterlab/filebrowser-extension": "^4.4.2",
61
- "@jupyterlab/docregistry": "^4.4.2",
62
63
  "@jupyterlab/json-extension": "^4.4.2",
63
64
  "@jupyterlab/logconsole": "^4.4.2",
64
65
  "@jupyterlab/mainmenu": "^4.4.2",
@@ -109,14 +110,15 @@
109
110
  },
110
111
  "devDependencies": {
111
112
  "@jupyterlab/builder": "~4.4.2",
113
+ "@types/react": "^18.0.26",
112
114
  "@typescript-eslint/eslint-plugin": "^6.1.0",
113
115
  "@typescript-eslint/parser": "^6.1.0",
114
- "@types/react": "^18.0.26",
115
116
  "css-loader": "^7.1.2",
116
117
  "eslint": "^8.36.0",
117
118
  "eslint-config-prettier": "^8.8.0",
118
119
  "eslint-plugin-prettier": "^5.0.0",
119
120
  "eslint-plugin-react-hooks": "^5.0.0",
121
+ "fs-extra": "^11.3.0",
120
122
  "handlebars": "^4.7.8",
121
123
  "html-webpack-plugin": "^5.5.3",
122
124
  "ignore-loader": "^0.1.2",
@@ -9,12 +9,6 @@
9
9
  "metadataSchema": {
10
10
  "type": "object",
11
11
  "properties": {
12
- "/specta/hideTopbar": {
13
- "title": "Hide top bar",
14
- "type": "boolean",
15
- "enum": [true, false],
16
- "default": false
17
- },
18
12
  "/specta/defaultLayout": {
19
13
  "title": "Page layout",
20
14
  "type": "string",
package/style/base.css CHANGED
@@ -62,6 +62,7 @@
62
62
  display: flex;
63
63
  box-shadow: unset !important;
64
64
  z-index: 100;
65
+ contain: unset !important;
65
66
  }
66
67
 
67
68
  .specta-topbar-element {
package/style/style.css CHANGED
@@ -8,12 +8,6 @@
8
8
  display: none;
9
9
  }
10
10
 
11
- #specta-top-panel {
12
- contain: unset !important;
13
- box-shadow: unset !important;
14
- z-index: 100;
15
- }
16
-
17
11
  .specta-file-browser {
18
12
  max-width: 1200px;
19
13
  margin: 0 auto;