Skip to content

Commit

Permalink
Merge pull request #2862 from finos/workspaces-fixes
Browse files Browse the repository at this point in the history
Remove `workspace-layout-update` event debounce
  • Loading branch information
texodus authored Nov 30, 2024
2 parents 13b8a63 + fbd3e06 commit b70d5a8
Show file tree
Hide file tree
Showing 24 changed files with 312 additions and 141 deletions.
9 changes: 2 additions & 7 deletions examples/blocks/src/superstore/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,12 @@
<link rel="stylesheet" crossorigin="anonymous" href="/node_modules/@finos/perspective-viewer/dist/css/pro.css" />
<link rel="stylesheet" crossorigin="anonymous" href="/node_modules/@finos/perspective-workspace/dist/css/pro.css" />
<style>
body {
display: flex;
flex-direction: column;
perspective-workspace {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
Expand Down
10 changes: 3 additions & 7 deletions packages/perspective-viewer-datagrid/src/less/row-hover.less
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@ regular-table {
tr:hover:after {
border-color: var(--rt-hover--border-color, #c5c9d080) !important;
background-color: transparent;
box-shadow: 0px 1px 0px var(--rt-hover--border-color, #c5c9d080),
0px 3px 0px rgba(0, 0, 0, 0.05), 0px 5px 0px rgba(0, 0, 0, 0.01);
box-shadow: 0px 1px 0px var(--rt-hover--border-color, #c5c9d080);

&.psp-menu-open {
box-shadow: inset -2px 0px 0px var(--icon--color),
inset 2px 0px 0px var(--icon--color),
0px 1px 0px var(--rt-hover--border-color, #c5c9d080),
0px 3px 0px rgba(0, 0, 0, 0.05),
0px 5px 0px rgba(0, 0, 0, 0.01);
0px 1px 0px var(--rt-hover--border-color, #c5c9d080);
}
}

Expand All @@ -37,8 +34,7 @@ regular-table {
box-shadow: inset -2px 0px 0px var(--icon--color),
inset 2px 0px 0px var(--icon--color),
inset 0px -2px 0px var(--icon--color),
0px 1px 0px var(--rt-hover--border-color, #c5c9d080),
0px 3px 0px rgba(0, 0, 0, 0.05), 0px 5px 0px rgba(0, 0, 0, 0.01);
0px 1px 0px var(--rt-hover--border-color, #c5c9d080);
}

tr:hover
Expand Down
4 changes: 2 additions & 2 deletions packages/perspective-workspace/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ async function build_all() {
pro_dark.compile().get("output.css")
);

await Promise.all(BUILD.map(build)).catch(() => process.exit(1));

try {
await $`npx tsc --project ./tsconfig.json`.stdio(
"inherit",
Expand All @@ -152,8 +154,6 @@ async function build_all() {
} catch (e) {
process.exit(1);
}

await Promise.all(BUILD.map(build)).catch(() => process.exit(1));
}

build_all();
4 changes: 4 additions & 0 deletions packages/perspective-workspace/src/less/menu.less
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

@import "@lumino/widgets/style/menu.css";

:host {
position: absolute;
}

.lm-Menu {
font-size: 12px;
padding: 8px;
Expand Down
9 changes: 5 additions & 4 deletions packages/perspective-workspace/src/less/viewer.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
}
}

perspective-viewer {
::slotted(perspective-viewer) {
flex: 1;
position: relative;
display: block;
Expand All @@ -76,10 +76,11 @@ perspective-viewer {
overflow: visible !important;
}

.lm-mod-override-cursor {
:host-context(.lm-mod-override-cursor) {
cursor: grabbing !important;
}

.lm-mod-override-cursor perspective-viewer > * {
pointer-events: none;
:host-context(.lm-mod-override-cursor) ::slotted(perspective-viewer),
.context-menu ::slotted(perspective-viewer) {
--override-content-pointer-events: none;
}
6 changes: 4 additions & 2 deletions packages/perspective-workspace/src/less/workspace.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@
@import "@lumino/widgets/style/tabbar.css";
@import "@lumino/widgets/style/tabpanel.css";

@import "./injected.less";

:host {
@import "./tabbar.less";
@import "./dockpanel.less";
@import "./widget.less";

background-color: hsl(210deg 18% 90%);

width: 100%;
height: 100%;
// width: 100%;
// height: 100%;

.workspace {
width: 100%;
Expand Down
4 changes: 2 additions & 2 deletions packages/perspective-workspace/src/themes/pro-dark.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ perspective-indicator[theme="Pro Dark"] {
--theme-name: "Pro Dark";
}

.lm-Menu {
perspective-workspace-menu {
@include perspective-viewer-pro-dark--colors;
}

Expand Down Expand Up @@ -62,7 +62,7 @@ perspective-viewer[theme="Pro Dark"].workspace-master-widget {
--plugin--background: @grey800;
}

.lm-Menu {
perspective-workspace-menu {
font-family: "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo",
"Consolas", "Liberation Mono", monospace;
font-weight: 300;
Expand Down
4 changes: 2 additions & 2 deletions packages/perspective-workspace/src/themes/pro.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ perspective-workspace {
background-color: #dadada;
}

.lm-Menu {
perspective-workspace-menu {
@include perspective-viewer-pro--colors;
background-color: #ffffff;
}
Expand Down Expand Up @@ -84,7 +84,7 @@ perspective-viewer[theme="Pro Light"].workspace-master-widget {
--workspace-tabbar-tab--border-width: 1px 1px 0px 1px;
}

.lm-Menu {
perspective-workspace-menu {
font-family: "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo",
"Consolas", "Liberation Mono", monospace;
font-weight: 300;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
import { bindTemplate, CustomElementProto } from "./utils/custom_elements";
import style from "../../build/css/workspace.css";
import template from "../html/workspace.html";
import injectedStyles from "../../build/css/injected.css";

/**
* A Custom Element for coordinating a set of `<perspective-viewer>` light DOM
Expand All @@ -52,13 +51,10 @@ import injectedStyles from "../../build/css/injected.css";
* name="View One"
* table="superstore">
* </perspective-viewer>
*
* <perspective-viewer
* row-pivots='["State"]'
* name="View Two"
* table="superstore">
* </perspective-viewer>
*
* </perspective-workspace>
* ```
*
Expand Down Expand Up @@ -295,11 +291,6 @@ export class HTMLPerspectiveWorkspaceElement extends HTMLElement {
}
}

const _injectStyle = document.createElement("style");
_injectStyle.toggleAttribute("injected", true);
_injectStyle.innerHTML = injectedStyles;
document.head.appendChild(_injectStyle);

bindTemplate(
template,
style
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,9 @@ export function registerElement(
`<style>${styleString.toString()}</style>` + template.innerHTML;
}

template.innerHTML =
`<style id="psp_styles" scope="${template.getAttribute(
"id"
)}">test{}</style>` + template.innerHTML;

const _perspective_element = class extends proto {
_initialized: boolean;
_initializing: boolean;
private _initialized: boolean;
private _initializing: boolean;

constructor() {
super();
Expand Down
8 changes: 6 additions & 2 deletions packages/perspective-workspace/src/ts/workspace/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
} from "@finos/perspective-viewer";

import type { PerspectiveWorkspace } from "./workspace";
import { WorkspaceMenu } from "./menu";

export const createCommands = (
workspace: PerspectiveWorkspace,
Expand All @@ -43,7 +44,10 @@ export const createCommands = (
workspace.get_context_menu()?.init_overlay?.();
menu.addEventListener("blur", () => {
const context_menu = workspace.get_context_menu()!;
const signal = context_menu.aboutToClose as Signal<Menu, any>;
const signal = context_menu.aboutToClose as Signal<
WorkspaceMenu,
any
>;
signal.emit({});
});
},
Expand Down Expand Up @@ -83,7 +87,7 @@ export const createCommands = (
menu.addEventListener("blur", () => {
(
workspace.get_context_menu()?.aboutToClose as
| Signal<Menu, any>
| Signal<WorkspaceMenu, any>
| undefined
)?.emit({});
});
Expand Down
5 changes: 3 additions & 2 deletions packages/perspective-workspace/src/ts/workspace/dockpanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import { DockLayout, DockPanel, TabBar, Widget } from "@lumino/widgets";
import { toArray } from "@lumino/algorithm";
import { PerspectiveTabBar } from "./tabbar";
import { PerspectiveTabBarRenderer } from "./tabbarrenderer";
import { PerspectiveWorkspace } from "./workspace";
Expand Down Expand Up @@ -55,7 +54,7 @@ export class PerspectiveDockPanel extends DockPanel {
const widget = sender.titles[args.index].owner;
const layout = this.layout as DockLayout;
const old = layout.saveLayout();
if (toArray(layout.widgets()).length > 1) {
if (Array.from(layout.widgets()).length > 1) {
layout.removeWidget(widget);
}

Expand All @@ -65,6 +64,8 @@ export class PerspectiveDockPanel extends DockPanel {
// @ts-ignore: accessing a private member `_drag`
const drag = this._drag;
if (drag) {
drag.dragImage?.parentElement.removeChild(drag.dragImage);
drag.dragImage = null;
drag._promise.then(() => {
if (!widget.node.isConnected) {
layout.restoreLayout(old);
Expand Down
124 changes: 122 additions & 2 deletions packages/perspective-workspace/src/ts/workspace/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,61 @@
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import { ElementExt } from "@lumino/domutils";
import { MessageLoop } from "@lumino/messaging";
import { h } from "@lumino/virtualdom";
import { Menu } from "@lumino/widgets";
import { Menu, Widget } from "@lumino/widgets";

export class MenuRenderer extends Menu.Renderer {
export class WorkspaceMenu extends Menu {
private _host: ShadowRoot;
init_overlay?: () => void;

constructor(host: ShadowRoot, options: Menu.IOptions) {
options.renderer = new MenuRenderer();
super(options);
this._host = host;
(this as any)._openChildMenu = this._overrideOpenChildMenu.bind(this);
}

open(x: number, y: number, options?: Menu.IOpenOptions) {
options ||= {};
options.host = this._host as any as HTMLElement;
super.open(x, y, options);
}

// Override this lumino private method because it will otherwise always
// attach to `document.body`.
private _overrideOpenChildMenu(activateFirst = false) {
const self = this as any;
let item = this.activeItem;
if (!item || item.type !== "submenu" || !item.submenu) {
self._closeChildMenu();
return;
}

let submenu = item.submenu;
if (submenu === self._childMenu) {
return;
}

Menu.saveWindowData();
self._closeChildMenu();
self._childMenu = submenu;
self._childIndex = self._activeIndex;
(submenu as any)._parentMenu = this;
MessageLoop.sendMessage(this, Widget.Msg.UpdateRequest);
let itemNode = this.contentNode.children[self._activeIndex];
openSubmenu(submenu, itemNode as HTMLElement, self._host);
if (activateFirst) {
submenu.activeIndex = -1;
submenu.activateNextItem();
}

submenu.activate();
}
}

class MenuRenderer extends Menu.Renderer {
formatLabel(data: Menu.IRenderData) {
let { label, mnemonic } = data.item;
if (mnemonic < 0 || mnemonic >= label.length) {
Expand Down Expand Up @@ -67,3 +118,72 @@ export class MenuRenderer extends Menu.Renderer {
);
}
}

// Prevent submenus from attaching outside the Shadow DOM.
// Forked from [Lumino](https://github.com/jupyterlab/lumino/blob/main/packages/widgets/src/menu.ts).
// [License](https://github.com/jupyterlab/lumino/blob/main/LICENSE)
export function openSubmenu(
submenu: Menu,
itemNode: HTMLElement,
host: HTMLElement
): void {
const windowData = getWindowData();
let px = windowData.pageXOffset;
let py = windowData.pageYOffset;
let cw = windowData.clientWidth;
let ch = windowData.clientHeight;
const hostData = (host as any).host.getBoundingClientRect();
let hx = hostData.x;
let hy = hostData.y;
MessageLoop.sendMessage(submenu, Widget.Msg.UpdateRequest);
let maxHeight = ch;
let node = submenu.node;
let style = node.style;
style.opacity = "0";
style.maxHeight = `${maxHeight}px`;
Widget.attach(submenu, host);
let { width, height } = node.getBoundingClientRect();
let box = ElementExt.boxSizing(submenu.node);
let itemRect = itemNode.getBoundingClientRect();
let x = itemRect.right - SUBMENU_OVERLAP - hx;
if (x + width > px + cw + hx) {
x = itemRect.left + SUBMENU_OVERLAP - width;
}

let y = itemRect.top - box.borderTop - box.paddingTop - hy;
if (y + height > py + ch + hy) {
y = itemRect.bottom + box.borderBottom + box.paddingBottom - height;
}

style.transform = `translate(${Math.max(0, x)}px, ${Math.max(0, y)}px`;
style.opacity = "1";
}

export const SUBMENU_OVERLAP = 3;

let transientWindowDataCache: IWindowData | null = null;
let transientCacheCounter: number = 0;

function getWindowData(): IWindowData {
if (transientCacheCounter > 0) {
transientCacheCounter--;
return transientWindowDataCache!;
}
return _getWindowData();
}

function _getWindowData(): IWindowData {
return {
pageXOffset: window.pageXOffset,
pageYOffset: window.pageYOffset,
clientWidth: document.documentElement.clientWidth,
clientHeight: document.documentElement.clientHeight,
};
}

interface IWindowData {
pageXOffset: number;
pageYOffset: number;
clientWidth: number;
clientHeight: number;
}
Loading

0 comments on commit b70d5a8

Please sign in to comment.