diff --git a/packages/dashboard/src/Dashboard.scss b/packages/dashboard/src/Dashboard.scss
index bd47aa48eb..5e70a86dfb 100644
--- a/packages/dashboard/src/Dashboard.scss
+++ b/packages/dashboard/src/Dashboard.scss
@@ -1,3 +1,12 @@
.dashboard-container {
position: relative;
}
+
+.dashboard-empty {
+ position: absolute;
+ display: grid;
+ place-items: center;
+ inset: 0;
+ color: var(--dh-color-neutral);
+ font-size: 1.5rem;
+}
diff --git a/packages/dashboard/src/DashboardLayout.tsx b/packages/dashboard/src/DashboardLayout.tsx
index c4da4e68cd..79ae4774ae 100644
--- a/packages/dashboard/src/DashboardLayout.tsx
+++ b/packages/dashboard/src/DashboardLayout.tsx
@@ -82,7 +82,7 @@ type DashboardLayoutProps = React.PropsWithChildren<{
export function DashboardLayout({
id,
children,
- emptyDashboard =
Dashboard is empty.
,
+ emptyDashboard = Dashboard is empty.
,
layout,
layoutConfig = DEFAULT_LAYOUT_CONFIG,
onLayoutChange = DEFAULT_CALLBACK,
diff --git a/packages/golden-layout/scss/goldenlayout-dark-theme.scss b/packages/golden-layout/scss/goldenlayout-dark-theme.scss
index a59ab27784..f191b4fc19 100644
--- a/packages/golden-layout/scss/goldenlayout-dark-theme.scss
+++ b/packages/golden-layout/scss/goldenlayout-dark-theme.scss
@@ -59,6 +59,19 @@ body:not(.lm_dragging) .lm_header .lm_tab:hover .lm_close_tab {
}
}
+// give visual indication of the bounds of a nested golden-layout while dragging
+.lm_goldenlayout .lm_goldenlayout.lm_dragging {
+ &::after {
+ content: '';
+ position: absolute;
+ inset: 1px;
+ background: var(--dh-color-highlight-selected);
+ border: 1px dashed var(--dh-color-hover-border);
+ pointer-events: none;
+ z-index: 9999;
+ }
+}
+
// Entire GoldenLayout Container, if a background is set, it is visible as color of "pane header" and "splitters" (if these latest has opacity very low)
.lm_goldenlayout {
background: $background;
diff --git a/packages/golden-layout/src/controls/DragSource.ts b/packages/golden-layout/src/controls/DragSource.ts
index b9011de4d2..bd972f9d65 100644
--- a/packages/golden-layout/src/controls/DragSource.ts
+++ b/packages/golden-layout/src/controls/DragSource.ts
@@ -34,7 +34,11 @@ export default class DragSource {
* Called initially and after every drag
*/
_createDragListener() {
- this._dragListener = new DragListener(this._element, true);
+ this._dragListener = new DragListener(
+ this._element,
+ this._layoutManager.root,
+ true
+ );
this._dragListener.on('dragStart', this._onDragStart, this);
this._dragListener.on('dragStop', this._createDragListener, this);
return this._dragListener;
diff --git a/packages/golden-layout/src/controls/DragSourceFromEvent.ts b/packages/golden-layout/src/controls/DragSourceFromEvent.ts
index 5c85384781..6a116e9cb2 100644
--- a/packages/golden-layout/src/controls/DragSourceFromEvent.ts
+++ b/packages/golden-layout/src/controls/DragSourceFromEvent.ts
@@ -42,7 +42,15 @@ export default class DragSourceFromEvent {
return;
}
- this._dragListener = new DragListener(this._element, true);
+ if (!this._layoutManager) {
+ return;
+ }
+
+ this._dragListener = new DragListener(
+ this._element,
+ this._layoutManager.root,
+ true
+ );
this._dragListener.on('dragStart', this._onDragStart, this);
this._dragListener.on('dragStop', this._destroy, this);
diff --git a/packages/golden-layout/src/controls/Tab.ts b/packages/golden-layout/src/controls/Tab.ts
index d4c7d169cd..4c8aa3c1f3 100644
--- a/packages/golden-layout/src/controls/Tab.ts
+++ b/packages/golden-layout/src/controls/Tab.ts
@@ -50,7 +50,10 @@ export default class Tab {
this._layoutManager.config.settings?.reorderEnabled &&
contentItem.config.reorderEnabled
) {
- this._dragListener = new DragListener(this.element);
+ this._dragListener = new DragListener(
+ this.element,
+ this._layoutManager.root
+ );
this._dragListener.on('dragStart', this._onDragStart, this);
this.contentItem.on(
'destroy',
diff --git a/packages/golden-layout/src/utils/DragListener.ts b/packages/golden-layout/src/utils/DragListener.ts
index b22256c2b6..0e7809ac39 100644
--- a/packages/golden-layout/src/utils/DragListener.ts
+++ b/packages/golden-layout/src/utils/DragListener.ts
@@ -1,5 +1,6 @@
import $ from 'jquery';
import EventEmitter from './EventEmitter';
+import { Root } from '../items';
export type DragListenerEvent = Pick<
JQuery.TriggeredEvent,
@@ -10,7 +11,7 @@ class DragListener extends EventEmitter {
private _eElement: JQuery | undefined;
private _oDocument: JQuery | undefined;
private _eBody: JQuery | undefined;
-
+ private _root: Root | undefined;
private _destroyAfterMouseUp: boolean;
/**
@@ -34,12 +35,17 @@ class DragListener extends EventEmitter {
private _bDragging = false;
- constructor(eElement: JQuery, destroyAfterMouseUp = false) {
+ constructor(
+ eElement: JQuery,
+ root?: Root,
+ destroyAfterMouseUp = false
+ ) {
super();
this._eElement = eElement;
this._oDocument = $(document);
this._eBody = $(document.body);
+ this._root = root;
// used by drag sources, to destroy listener at the right time
this._destroyAfterMouseUp = destroyAfterMouseUp;
@@ -119,6 +125,7 @@ class DragListener extends EventEmitter {
// after dragStop, so that .lm_dragging is removed after size is processed
// and any overflow: hidden remains applied during the calculations
this._eBody?.removeClass('lm_dragging');
+ this._root?.childElementContainer.removeClass('lm_dragging');
if (!(this._eElement instanceof Window)) {
this._eElement?.removeClass('lm_dragging');
}
@@ -132,6 +139,7 @@ class DragListener extends EventEmitter {
this._bDragging = true;
this._eBody?.addClass('lm_dragging');
this._eElement?.addClass('lm_dragging');
+ this._root?.childElementContainer.addClass('lm_dragging');
this._oDocument?.find('iframe')?.css('pointer-events', 'none');
this.emit('dragStart', this._nOriginalX, this._nOriginalY);
}