@perspective-dev/workspace 4.0.0

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.
Files changed (44) hide show
  1. package/LICENSE.md +193 -0
  2. package/dist/cdn/perspective-workspace.js +45 -0
  3. package/dist/cdn/perspective-workspace.js.map +7 -0
  4. package/dist/css/pro-dark.css +1 -0
  5. package/dist/css/pro.css +1 -0
  6. package/dist/esm/perspective-workspace.d.ts +181 -0
  7. package/dist/esm/perspective-workspace.js +14 -0
  8. package/dist/esm/perspective-workspace.js.map +7 -0
  9. package/dist/esm/utils/custom_elements.d.ts +14 -0
  10. package/dist/esm/utils/observable_map.d.ts +9 -0
  11. package/dist/esm/workspace/commands.d.ts +3 -0
  12. package/dist/esm/workspace/dockpanel.d.ts +13 -0
  13. package/dist/esm/workspace/index.d.ts +1 -0
  14. package/dist/esm/workspace/menu.d.ts +11 -0
  15. package/dist/esm/workspace/tabbar.d.ts +25 -0
  16. package/dist/esm/workspace/tabbarrenderer.d.ts +19 -0
  17. package/dist/esm/workspace/widget.d.ts +27 -0
  18. package/dist/esm/workspace/workspace.d.ts +123 -0
  19. package/package.json +55 -0
  20. package/src/html/workspace.html +11 -0
  21. package/src/less/dockpanel.less +95 -0
  22. package/src/less/injected.less +14 -0
  23. package/src/less/menu.less +128 -0
  24. package/src/less/tabbar.less +366 -0
  25. package/src/less/viewer.less +86 -0
  26. package/src/less/widget.less +40 -0
  27. package/src/less/workspace.less +70 -0
  28. package/src/svg/bookmark-icon.svg +4 -0
  29. package/src/svg/drag-handle.svg +10 -0
  30. package/src/themes/pro-dark.less +139 -0
  31. package/src/themes/pro.less +93 -0
  32. package/src/ts/external.d.ts +21 -0
  33. package/src/ts/external.js +11 -0
  34. package/src/ts/perspective-workspace.ts +306 -0
  35. package/src/ts/utils/custom_elements.ts +95 -0
  36. package/src/ts/utils/observable_map.ts +39 -0
  37. package/src/ts/workspace/commands.ts +269 -0
  38. package/src/ts/workspace/dockpanel.ts +145 -0
  39. package/src/ts/workspace/index.ts +13 -0
  40. package/src/ts/workspace/menu.ts +213 -0
  41. package/src/ts/workspace/tabbar.ts +237 -0
  42. package/src/ts/workspace/tabbarrenderer.ts +91 -0
  43. package/src/ts/workspace/widget.ts +101 -0
  44. package/src/ts/workspace/workspace.ts +1056 -0
@@ -0,0 +1,14 @@
1
+ export interface CustomElementProto extends CustomElementConstructor {
2
+ connectedCallback(): void;
3
+ }
4
+ /**
5
+ * A simple tool for creating Web Components v0.
6
+ *
7
+ * Params
8
+ * ------
9
+ * template : An HTML string representing a template. Should have an 'id'
10
+ * attribute which will become the new Web Component's tag name.
11
+ * proto : The new Web Component's prototype object, as per spec.
12
+ */
13
+ export declare function registerElement(templateString: string, styleString: string, proto: CustomElementProto): void;
14
+ export declare function bindTemplate(template: string, ...styleStrings: string[]): (cls: CustomElementProto) => void;
@@ -0,0 +1,9 @@
1
+ export declare class ObservableMap<K, V> extends Map<K, V> {
2
+ _set_listener?: (name: K, val: V) => void;
3
+ _delete_listener?: (name: K) => void;
4
+ set(name: K, item: V): this;
5
+ get(name: K): V;
6
+ delete(name: K): boolean;
7
+ addSetListener(listener: (name: K, val: V) => void): void;
8
+ addDeleteListener(listener: (name: K) => void): void;
9
+ }
@@ -0,0 +1,3 @@
1
+ import { CommandRegistry } from "@lumino/commands";
2
+ import type { PerspectiveWorkspace } from "./workspace";
3
+ export declare const createCommands: (workspace: PerspectiveWorkspace, indicator: HTMLElement) => CommandRegistry;
@@ -0,0 +1,13 @@
1
+ import { DockLayout, DockPanel, TabBar, Widget } from "@lumino/widgets";
2
+ import { PerspectiveWorkspace } from "./workspace";
3
+ import { PerspectiveViewerWidget } from "./widget";
4
+ export declare class PerspectiveDockPanel extends DockPanel {
5
+ constructor(workspace: PerspectiveWorkspace);
6
+ _onTabDetachRequested(sender: TabBar<Widget>, args: TabBar.ITabDetachRequestedArgs<Widget>): void;
7
+ static getWidgets(layout: DockPanel.ILayoutConfig): PerspectiveViewerWidget[];
8
+ static getAreaWidgets(layout: DockLayout.AreaConfig): PerspectiveViewerWidget[];
9
+ widgets(): IterableIterator<PerspectiveViewerWidget>;
10
+ static mapWidgets(widgetFunc: (widget: any) => any, layout: any): DockPanel.ILayoutConfig;
11
+ static mapAreaWidgets(widgetFunc: (widget: any) => any, layout: DockLayout.AreaConfig): DockLayout.AreaConfig;
12
+ onAfterAttach(): void;
13
+ }
@@ -0,0 +1 @@
1
+ export * from "./workspace";
@@ -0,0 +1,11 @@
1
+ import { Menu } from "@lumino/widgets";
2
+ export declare class WorkspaceMenu extends Menu {
3
+ private _host;
4
+ private _workspace;
5
+ init_overlay?: () => void;
6
+ constructor(host: ShadowRoot, workspace: HTMLElement, options: Menu.IOptions);
7
+ open(x: number, y: number, options?: Menu.IOpenOptions): void;
8
+ private _overrideOpenChildMenu;
9
+ }
10
+ export declare function openSubmenu(submenu: Menu, itemNode: HTMLElement, host: HTMLElement): void;
11
+ export declare const SUBMENU_OVERLAP = 3;
@@ -0,0 +1,25 @@
1
+ import { TabBar } from "@lumino/widgets";
2
+ import { Menu } from "@lumino/widgets";
3
+ import { PerspectiveWorkspace } from "./workspace";
4
+ import { Message } from "@lumino/messaging";
5
+ import { Title } from "@lumino/widgets";
6
+ export declare class PerspectiveTabBar extends TabBar<any> {
7
+ _workspace: PerspectiveWorkspace;
8
+ __content_node__?: HTMLElement;
9
+ _menu?: Menu;
10
+ __titles: string[];
11
+ constructor(workspace: PerspectiveWorkspace, options?: {});
12
+ get private_titles(): Title<any>[];
13
+ onUpdateRequest(msg: Message): void;
14
+ onClick(otherTitles: Title<any>[], index: number, event: MouseEvent): void;
15
+ _check_shade(): void;
16
+ handleEvent(event: MouseEvent): void;
17
+ /**
18
+ * Shadow dom targets events at the host, not the clicked element, which
19
+ * Lumino dislikes. This makes the event look like it is not crossing
20
+ * the ShadowDom boundary.
21
+ *
22
+ */
23
+ retargetEvent(event: MouseEvent): MouseEvent;
24
+ _addEventListeners(): void;
25
+ }
@@ -0,0 +1,19 @@
1
+ import { TabBar } from "@lumino/widgets";
2
+ export declare const TabBarItems: {
3
+ Config: string;
4
+ Label: string;
5
+ };
6
+ export declare const DEFAULT_TITLE = "untitled";
7
+ export declare class PerspectiveTabBarRenderer extends TabBar.Renderer {
8
+ maximized: boolean;
9
+ constructor(maximized: boolean);
10
+ renderLabel(data: {
11
+ title: {
12
+ label?: string;
13
+ };
14
+ }): import("@lumino/virtualdom").VirtualElement;
15
+ renderInert(): import("@lumino/virtualdom").VirtualElement;
16
+ renderTab(data: TabBar.IRenderData<any>, onclick?: (this: HTMLElement, event: MouseEvent) => any): import("@lumino/virtualdom").VirtualElement;
17
+ renderDragHandle(): import("@lumino/virtualdom").VirtualElement;
18
+ renderCloseIcon(): import("@lumino/virtualdom").VirtualElement;
19
+ }
@@ -0,0 +1,27 @@
1
+ import { Widget } from "@lumino/widgets";
2
+ import { Message } from "@lumino/messaging";
3
+ import type * as psp_viewer from "@perspective-dev/viewer";
4
+ import type * as psp from "@perspective-dev/client";
5
+ interface IPerspectiveViewerWidgetOptions {
6
+ node: HTMLElement;
7
+ viewer: psp_viewer.HTMLPerspectiveViewerElement;
8
+ }
9
+ export declare class PerspectiveViewerWidget extends Widget {
10
+ viewer: psp_viewer.HTMLPerspectiveViewerElement;
11
+ _title: string;
12
+ _is_table_loaded: boolean;
13
+ _is_pivoted: boolean;
14
+ _restore_config?: () => Promise<void>;
15
+ task?: Promise<void>;
16
+ constructor({ viewer, node }: IPerspectiveViewerWidgetOptions);
17
+ get name(): string;
18
+ toggleConfig(): Promise<void>;
19
+ load(table: psp.Table | Promise<psp.Table>): Promise<void>;
20
+ restore(config: psp_viewer.ViewerConfigUpdate & {
21
+ table: string;
22
+ }): Promise<any> | undefined;
23
+ save(): Promise<any>;
24
+ removeClass(name: string): void;
25
+ onCloseRequest(msg: Message): Promise<void>;
26
+ }
27
+ export {};
@@ -0,0 +1,123 @@
1
+ import { SplitPanel } from "@lumino/widgets";
2
+ import type { HTMLPerspectiveViewerElement, ViewerConfigUpdate } from "@perspective-dev/viewer";
3
+ import type * as psp from "@perspective-dev/client";
4
+ import { PerspectiveDockPanel } from "./dockpanel";
5
+ import { WorkspaceMenu } from "./menu";
6
+ import { PerspectiveViewerWidget } from "./widget";
7
+ import { ObservableMap } from "../utils/observable_map";
8
+ export interface PerspectiveLayout<T> {
9
+ children?: PerspectiveLayout<T>[];
10
+ widgets?: T[];
11
+ sizes: number[];
12
+ }
13
+ export interface ViewerConfigUpdateExt extends ViewerConfigUpdate {
14
+ table: string;
15
+ }
16
+ export interface PerspectiveWorkspaceConfig<T> {
17
+ sizes: number[];
18
+ master: PerspectiveLayout<T>;
19
+ detail: PerspectiveLayout<T>;
20
+ viewers: Record<string, ViewerConfigUpdateExt>;
21
+ }
22
+ export declare class PerspectiveWorkspace extends SplitPanel {
23
+ private dockpanel;
24
+ private detailPanel;
25
+ private masterPanel;
26
+ element: HTMLElement;
27
+ menu_elem: HTMLElement;
28
+ private _tables;
29
+ private listeners;
30
+ private indicator;
31
+ private commands;
32
+ private _menu?;
33
+ private _minimizedLayoutSlots?;
34
+ private _minimizedLayout?;
35
+ private _maximizedWidget?;
36
+ private _last_updated_state?;
37
+ constructor(element: HTMLElement);
38
+ get_context_menu(): WorkspaceMenu | undefined;
39
+ get_dock_panel(): PerspectiveDockPanel;
40
+ init_indicator(): HTMLElement;
41
+ apply_indicator_theme(): void;
42
+ /***************************************************************************
43
+ *
44
+ * `<perspective-workspace>` Public API
45
+ *
46
+ */
47
+ addTable(name: string, table: Promise<psp.Table>): void;
48
+ getTable(name: string): psp.Table | Promise<psp.Table>;
49
+ removeTable(name: string): boolean;
50
+ replaceTable(name: string, table: Promise<psp.Table>): void;
51
+ get tables(): ObservableMap<string, psp.Table | Promise<psp.Table>>;
52
+ save(): Promise<{
53
+ viewers: Record<string, ViewerConfigUpdate>;
54
+ sizes: number[];
55
+ detail: import("@lumino/widgets").DockLayout.ILayoutConfig | undefined;
56
+ master: {
57
+ widgets: string[];
58
+ sizes: number[];
59
+ } | undefined;
60
+ }>;
61
+ restore(value: PerspectiveWorkspaceConfig<string>): Promise<void>;
62
+ _capture_widgets(): Generator<PerspectiveViewerWidget[], void, unknown>;
63
+ _capture_viewers(): Generator<HTMLPerspectiveViewerElement[], void, unknown>;
64
+ _restore_callback(viewers: Record<string, ViewerConfigUpdateExt>, starting_viewers: HTMLPerspectiveViewerElement[], starting_widgets: PerspectiveViewerWidget[], master: boolean, widgetName: string): PerspectiveViewerWidget;
65
+ _validate(table: any): any;
66
+ _set_listener(name: string, table: psp.Table | Promise<psp.Table>): void;
67
+ _delete_listener(name: string): void;
68
+ update_widget_for_viewer(viewer: HTMLPerspectiveViewerElement): void;
69
+ remove_unslotted_widgets(viewers: HTMLPerspectiveViewerElement[]): void;
70
+ update_details_panel(viewers: HTMLPerspectiveViewerElement[]): void;
71
+ /***************************************************************************
72
+ *
73
+ * Workspace-level contextmenu actions
74
+ *
75
+ */
76
+ duplicate(widget: PerspectiveViewerWidget): Promise<void>;
77
+ toggleMasterDetail(widget: PerspectiveViewerWidget): void;
78
+ _maximize(widget: PerspectiveViewerWidget): void;
79
+ _unmaximize(): void;
80
+ toggleSingleDocument(widget: PerspectiveViewerWidget): void;
81
+ _filterViewer(viewer: HTMLPerspectiveViewerElement, filters: [string, string, string][], candidates: Set<string>): Promise<void>;
82
+ onPerspectiveSelect(event: CustomEvent): Promise<void>;
83
+ makeMaster(widget: PerspectiveViewerWidget): Promise<void>;
84
+ makeDetail(widget: PerspectiveViewerWidget): void;
85
+ /***************************************************************************
86
+ *
87
+ * Context Menu
88
+ *
89
+ */
90
+ createContextMenu(widget: PerspectiveViewerWidget | null): WorkspaceMenu;
91
+ showContextMenu(widget: PerspectiveViewerWidget | null, event: MouseEvent): void;
92
+ /***************************************************************************
93
+ *
94
+ * Context Menu
95
+ *
96
+ */
97
+ clearLayout(): void;
98
+ setupMasterPanel(sizes: number[]): void;
99
+ addViewer(config: ViewerConfigUpdateExt, is_global_filter?: boolean): void;
100
+ /*********************************************************************
101
+ * Widget helper methods
102
+ */
103
+ _createWidgetAndNode({ config, slot: slotname, }: {
104
+ config: ViewerConfigUpdateExt;
105
+ slot?: string;
106
+ }): PerspectiveViewerWidget;
107
+ _gen_id(): string;
108
+ _createNode(slotname?: string): HTMLElement;
109
+ _createWidget({ config, elem, viewer, }: {
110
+ config: ViewerConfigUpdateExt;
111
+ elem?: Element;
112
+ viewer: HTMLPerspectiveViewerElement;
113
+ }): PerspectiveViewerWidget;
114
+ _addWidgetEventListeners(widget: PerspectiveViewerWidget): void;
115
+ getWidgetByName(name: string): PerspectiveViewerWidget | null;
116
+ getAllWidgets(): PerspectiveViewerWidget[];
117
+ /***************************************************************************
118
+ *
119
+ * `workspace-layout-update` event
120
+ *
121
+ */
122
+ workspaceUpdated(): Promise<void>;
123
+ }
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@perspective-dev/workspace",
3
+ "version": "4.0.0",
4
+ "description": "Perspective Workspace",
5
+ "files": [
6
+ "dist/**/*",
7
+ "src/**/*",
8
+ "index.d.ts"
9
+ ],
10
+ "type": "module",
11
+ "exports": {
12
+ ".": "./dist/esm/perspective-workspace.js",
13
+ "./esm/": "./dist/esm/",
14
+ "./src/*": "./src/*",
15
+ "./dist/*": "./dist/*",
16
+ "./dist/themes/": "./src/themes/",
17
+ "./package.json": "./package.json"
18
+ },
19
+ "unpkg": "./dist/cdn/perspective-workspace.js",
20
+ "jsdelivr": "./dist/cdn/perspective-workspace.js",
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/perspective-dev/perspective"
27
+ },
28
+ "author": "",
29
+ "license": "Apache-2.0",
30
+ "dependencies": {
31
+ "@perspective-dev/client": "",
32
+ "@perspective-dev/viewer": "",
33
+ "@lumino/algorithm": ">=2 <3",
34
+ "@lumino/commands": ">=2 <3",
35
+ "@lumino/domutils": ">=2 <3",
36
+ "@lumino/messaging": ">=2 <3",
37
+ "@lumino/virtualdom": ">=2 <3",
38
+ "@lumino/widgets": ">=2 <3",
39
+ "@lumino/coreutils": ">=2 <3",
40
+ "@lumino/signaling": ">=2 <3",
41
+ "lodash": "^4.17.20"
42
+ },
43
+ "devDependencies": {
44
+ "@prospective.co/procss": "0.1.17",
45
+ "@perspective-dev/esbuild-plugin": "",
46
+ "@perspective-dev/test": "",
47
+ "@types/lodash": "^4.17.20",
48
+ "typescript": ">=5 <6",
49
+ "zx": ">=8 <9"
50
+ },
51
+ "scripts": {
52
+ "build": "node ./build.mjs",
53
+ "clean": "node ./clean.mjs"
54
+ }
55
+ }
@@ -0,0 +1,11 @@
1
+ <!--
2
+
3
+ Copyright (c) 2017, the Perspective Authors.
4
+
5
+ This file is part of the Perspective library, distributed under the terms of
6
+ the Apache License 2.0. The full license can be found in the LICENSE file.
7
+
8
+ -->
9
+ <template id="perspective-workspace">
10
+ <div id="container" class="workspace"></div>
11
+ </template>
@@ -0,0 +1,95 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ .lm-DockPanel {
14
+ overflow: var(--dock-panel--overflow, hidden);
15
+ position: absolute;
16
+ background-color: var(--detail--background-color, transparent);
17
+ padding: 3px;
18
+ top: 0;
19
+ left: 0;
20
+ right: 0;
21
+ bottom: 0;
22
+ &[data-mode="single-document"] {
23
+ padding: 0px;
24
+ }
25
+ }
26
+
27
+ .lm-Widget,
28
+ .lm-Widget {
29
+ cursor: inherit;
30
+ }
31
+
32
+ .lm-DockPanel.ew,
33
+ .lm-DockPanel.ew .lm-Widget,
34
+ .lm-SplitPanel.ew,
35
+ .lm-SplitPanel.ew .lm-Widget {
36
+ cursor: ew-resize !important;
37
+ }
38
+
39
+ .lm-DockPanel.ns,
40
+ .lm-DockPanel.ns .lm-Widget,
41
+ .lm-SplitPanel.ns,
42
+ .lm-SplitPanel.ns .lm-Widget {
43
+ cursor: ns-resize !important;
44
+ }
45
+
46
+ .workspace-master-widget {
47
+ min-width: 100px !important;
48
+ }
49
+
50
+ .lm-DockPanel.resizing ::slotted(perspective-viewer),
51
+ .lm-SplitPanel.resizing ::slotted(perspective-viewer) {
52
+ pointer-events: none;
53
+ }
54
+
55
+ .widget-blur ::slotted(perspective-viewer) {
56
+ opacity: 0.5;
57
+ }
58
+
59
+ .lm-DockPanel-handle.resizing {
60
+ background-color: rgba(0, 0, 0, 0.05);
61
+ }
62
+
63
+ .perspective-scroll-panel {
64
+ overflow: auto !important;
65
+ }
66
+
67
+ .lm-Panel {
68
+ min-height: 100%;
69
+ }
70
+
71
+ .lm-DockPanel-handle {
72
+ background-color: none;
73
+ }
74
+
75
+ .lm-SplitPanel-handle {
76
+ background-color: var(--workspace-split-panel-handle--background-color);
77
+ }
78
+
79
+ .lm-SplitPanel-handle,
80
+ .lm-DockPanel-handle {
81
+ transition: background-color 0.3s ease-out;
82
+ &:hover {
83
+ background-color: rgba(0, 0, 0, 0.05);
84
+ }
85
+ }
86
+
87
+ .lm-DockPanel-overlay {
88
+ background: rgba(75, 75, 75, 0.2);
89
+ border: 1px dashed #666;
90
+ border-radius: 6px;
91
+ transition-property: top, left, right, bottom;
92
+ transition-duration: 50ms;
93
+ transition-timing-function: linear;
94
+ margin: 0px;
95
+ }
@@ -0,0 +1,14 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ @import "./viewer.less";
14
+ @import "./menu.less";
@@ -0,0 +1,128 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ @import "@lumino/widgets/style/menu.css";
14
+
15
+ .lm-Menu {
16
+ font-size: 12px;
17
+ padding: 8px;
18
+ background-color: var(--plugin--background);
19
+ color: var(--icon--color);
20
+ border: 1px solid var(--inactive--color);
21
+ border-radius: 3px;
22
+ max-width: 350px;
23
+ top: 0;
24
+ left: 0;
25
+ }
26
+
27
+ .lm-Menu.perspective-workspace-menu {
28
+ .lm-Menu-item {
29
+ padding-left: 37px !important;
30
+ min-width: var(--min-width);
31
+ }
32
+ }
33
+
34
+ .lm-Menu-item.lm-mod-active {
35
+ background-color: var(--icon--color);
36
+ color: var(--plugin--background);
37
+ }
38
+
39
+ .lm-Menu-item.lm-mod-disabled {
40
+ opacity: 0.5;
41
+ }
42
+
43
+ .lm-Menu-itemIcon {
44
+ width: 24px;
45
+ height: 12px;
46
+ margin-right: 4px;
47
+ }
48
+
49
+ .lm-Menu-itemLabel {
50
+ flex: 1 1;
51
+ padding: 4px 2px 4px 2px;
52
+ }
53
+
54
+ .lm-Menu-itemMnemonic {
55
+ text-decoration: underline;
56
+ }
57
+
58
+ .lm-Menu-itemShortcut {
59
+ padding: 4px 0px;
60
+ }
61
+
62
+ .lm-Menu-itemSubmenuIcon {
63
+ width: 24px;
64
+ height: 18px;
65
+ }
66
+
67
+ .lm-Menu-item {
68
+ display: flex;
69
+ align-items: center;
70
+ outline: none;
71
+
72
+ margin: 0 -8px;
73
+ padding: 0 8px;
74
+ }
75
+
76
+ .lm-Menu-item[data-type="separator"] > div {
77
+ padding: 0;
78
+ height: 9px;
79
+ }
80
+
81
+ .lm-Menu-item[data-type="separator"] > div::after {
82
+ content: "";
83
+ display: block;
84
+ position: relative;
85
+ top: 4px;
86
+ border-top: 1px solid;
87
+ }
88
+
89
+ .lm-MenuBar-menu {
90
+ transform: translateY(-1px);
91
+ }
92
+
93
+ .lm-MenuBar-item {
94
+ padding: 10px 32px;
95
+ border-left: 1px solid transparent;
96
+ border-right: 1px solid transparent;
97
+ color: #737373 !important;
98
+ }
99
+
100
+ .lm-MenuBar-item.lm-mod-active {
101
+ background: rgba(0, 0, 0, 0.2);
102
+ }
103
+
104
+ .lm-MenuBar.lm-mod-active .lm-MenuBar-item.lm-mod-active {
105
+ z-index: 10001;
106
+ background: rgba(0, 0, 0, 0.2);
107
+ // border-left: 1px solid #c0c0c0;
108
+ // border-right: 1px solid #c0c0c0;
109
+ }
110
+
111
+ .lm-Menu-itemIcon:before {
112
+ content: attr(content);
113
+ font-family:
114
+ "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
115
+ "Liberation Mono", monospace;
116
+ }
117
+
118
+ [data-type="submenu"] .lm-Menu-itemSubmenuIcon:before {
119
+ content: ">";
120
+ font-family:
121
+ "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
122
+ "Liberation Mono", monospace;
123
+ height: 18px;
124
+ }
125
+
126
+ .lm-mod-drag-image.lm-TabBar-tab {
127
+ display: none;
128
+ }