From 0df4062de4e3da89d11b5429b0a513de62a7dd49 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Wed, 17 Jan 2024 19:46:12 +0000
Subject: [PATCH 1/4] feat: scrollbar as default
---
.codesandbox/ci.json | 3 +-
.../src/dockview/dockviewGroupPanel.scss | 2 +-
packages/docs/docs/components/dockview.mdx | 17 ++++
.../scrollbars-dockview/package.json | 34 ++++++++
.../scrollbars-dockview/public/index.html | 45 +++++++++++
.../scrollbars-dockview/src/app.scss | 16 ++++
.../sandboxes/scrollbars-dockview/src/app.tsx | 77 +++++++++++++++++++
.../scrollbars-dockview/src/index.tsx | 20 +++++
.../scrollbars-dockview/src/styles.css | 16 ++++
.../scrollbars-dockview/tsconfig.json | 18 +++++
10 files changed, 246 insertions(+), 2 deletions(-)
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/package.json
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/public/index.html
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/src/app.scss
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/src/app.tsx
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/src/index.tsx
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/src/styles.css
create mode 100644 packages/docs/sandboxes/scrollbars-dockview/tsconfig.json
diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
index f460a9448..e450b957b 100644
--- a/.codesandbox/ci.json
+++ b/.codesandbox/ci.json
@@ -28,6 +28,7 @@
"/packages/docs/sandboxes/rendermode-dockview",
"/packages/docs/sandboxes/resize-dockview",
"/packages/docs/sandboxes/resizecontainer-dockview",
+ "/packages/docs/sandboxes/scrollbars-dockview",
"/packages/docs/sandboxes/simple-dockview",
"/packages/docs/sandboxes/simple-gridview",
"/packages/docs/sandboxes/simple-paneview",
@@ -40,4 +41,4 @@
"/packages/docs/sandboxes/javascript/vanilla-dockview"
],
"node": "18"
-}
+}
\ No newline at end of file
diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanel.scss b/packages/dockview-core/src/dockview/dockviewGroupPanel.scss
index d1c10568a..dc8b46a8d 100644
--- a/packages/dockview-core/src/dockview/dockviewGroupPanel.scss
+++ b/packages/dockview-core/src/dockview/dockviewGroupPanel.scss
@@ -17,7 +17,7 @@
> .content-container {
flex-grow: 1;
- overflow: hidden;
+ min-height: 0;
outline: none;
}
}
diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx
index 0472c1e1a..e31864d21 100644
--- a/packages/docs/docs/components/dockview.mdx
+++ b/packages/docs/docs/components/dockview.mdx
@@ -31,6 +31,7 @@ import DockviewKeyboard from '@site/sandboxes/keyboard-dockview/src/app';
import DockviewPopoutGroup from '@site/sandboxes/popoutgroup-dockview/src/app';
import DockviewMaximizeGroup from '@site/sandboxes/maximizegroup-dockview/src/app';
import DockviewRenderMode from '@site/sandboxes/rendermode-dockview/src/app';
+import DockviewScrollbars from '@site/sandboxes/scrollbars-dockview/src/app';
import { DocRef } from '@site/src/components/ui/reference/docRef';
@@ -196,6 +197,22 @@ If you refresh the page you should notice your layout is loaded as you left it.
react={DockviewPersistance}
/>
+## Scrollbars
+
+Scrollbars will appear if the contents of your view has a fixed height. If you are using a relative height such
+as *100%* you will need to define an inner container with the appropiate `overflow` value to allow scrollbars to appear.
+
+The following container three views:
+- **Panel 1**: Sets `height: 100%` and no scrollbar appears even, the content is clipped.
+- **Panel 2**: Sets `height: 2000px` and a scrollbar does appear since a fixed height has been used.
+- **Panel 3**: Sets `height: 100%` and defines an inner component with `overflow: auto` to enable the scrollbars.
+
+
+
+
## Resizing
### Panel Resizing
diff --git a/packages/docs/sandboxes/scrollbars-dockview/package.json b/packages/docs/sandboxes/scrollbars-dockview/package.json
new file mode 100644
index 000000000..6d2ffca5d
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "scrollbars-dockview",
+ "description": "",
+ "keywords": [
+ "dockview"
+ ],
+ "version": "1.0.0",
+ "main": "src/index.tsx",
+ "dependencies": {
+ "dockview": "*",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "uuid": "^9.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.28",
+ "@types/react-dom": "^18.0.11",
+ "@types/uuid": "^9.0.0",
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/scrollbars-dockview/public/index.html b/packages/docs/sandboxes/scrollbars-dockview/public/index.html
new file mode 100644
index 000000000..5a4850c1d
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/public/index.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/sandboxes/scrollbars-dockview/src/app.scss b/packages/docs/sandboxes/scrollbars-dockview/src/app.scss
new file mode 100644
index 000000000..e03cd2acf
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/src/app.scss
@@ -0,0 +1,16 @@
+.group-control {
+ .action {
+ padding: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-sizing: border-box;
+ font-size: 18px;
+ cursor: pointer;
+
+ &:hover {
+ border-radius: 2px;
+ background-color: var(--dv-icon-hover-background-color);
+ }
+ }
+}
diff --git a/packages/docs/sandboxes/scrollbars-dockview/src/app.tsx b/packages/docs/sandboxes/scrollbars-dockview/src/app.tsx
new file mode 100644
index 000000000..bece60098
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/src/app.tsx
@@ -0,0 +1,77 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+} from 'dockview';
+import './app.scss';
+
+const TEXT =
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
+
+const components = {
+ fixedHeightContainer: (props: IDockviewPanelProps<{ title: string }>) => {
+ return (
+
+ {[TEXT, '\n\n'].join('').repeat(20)}
+
+ );
+ },
+ overflowContainer: (props: IDockviewPanelProps<{ title: string }>) => {
+ return (
+
+ {[TEXT, '\n\n'].join('').repeat(20)}
+
+ );
+ },
+ userDefinedOverflowContainer: (
+ props: IDockviewPanelProps<{ title: string }>
+ ) => {
+ return (
+
+
+ {[TEXT, '\n\n'].join('').repeat(20)}
+
+
+ );
+ },
+};
+
+const DockviewComponent = (props: { theme?: string }) => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'fixedHeightContainer',
+ title: 'Panel 1',
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'overflowContainer',
+ title: 'Panel 2',
+ position: { direction: 'right' },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'userDefinedOverflowContainer',
+ title: 'Panel 3',
+ position: { direction: 'right' },
+ });
+ };
+
+ return (
+
+ );
+};
+
+export default DockviewComponent;
diff --git a/packages/docs/sandboxes/scrollbars-dockview/src/index.tsx b/packages/docs/sandboxes/scrollbars-dockview/src/index.tsx
new file mode 100644
index 000000000..2fe1be232
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/src/index.tsx
@@ -0,0 +1,20 @@
+import { StrictMode } from 'react';
+import * as ReactDOMClient from 'react-dom/client';
+import './styles.css';
+import 'dockview/dist/styles/dockview.css';
+
+import App from './app';
+
+const rootElement = document.getElementById('root');
+
+if (rootElement) {
+ const root = ReactDOMClient.createRoot(rootElement);
+
+ root.render(
+
+
+
+ );
+}
diff --git a/packages/docs/sandboxes/scrollbars-dockview/src/styles.css b/packages/docs/sandboxes/scrollbars-dockview/src/styles.css
new file mode 100644
index 000000000..92b6a1b36
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/src/styles.css
@@ -0,0 +1,16 @@
+body {
+ margin: 0px;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+}
+
+#root {
+ height: 100vh;
+ width: 100vw;
+}
+
+.app {
+ height: 100%;
+
+}
diff --git a/packages/docs/sandboxes/scrollbars-dockview/tsconfig.json b/packages/docs/sandboxes/scrollbars-dockview/tsconfig.json
new file mode 100644
index 000000000..cdc4fb5f5
--- /dev/null
+++ b/packages/docs/sandboxes/scrollbars-dockview/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true
+ }
+}
From e3e87f413352a9721fb2fd1542b30e4def8146d7 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Wed, 17 Jan 2024 22:19:43 +0000
Subject: [PATCH 2/4] feat: provide classnames for droptarget overlays
---
.../dockview-core/src/dnd/droptarget.scss | 24 ++++++++++++-------
packages/dockview-core/src/dnd/droptarget.ts | 14 +++++++----
2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/packages/dockview-core/src/dnd/droptarget.scss b/packages/dockview-core/src/dnd/droptarget.scss
index 2767c2c24..9baf55508 100644
--- a/packages/dockview-core/src/dnd/droptarget.scss
+++ b/packages/dockview-core/src/dnd/droptarget.scss
@@ -22,20 +22,28 @@
will-change: transform;
pointer-events: none;
- &.small-top {
- border-top: 1px solid var(--dv-drag-over-border-color);
+ &.dv-overlay-top {
+ &.dv-overlay-small-vertical {
+ border-top: 1px solid var(--dv-drag-over-border-color);
+ }
}
- &.small-bottom {
- border-bottom: 1px solid var(--dv-drag-over-border-color);
+ &.dv-overlay-bottom {
+ &.dv-overlay-small-vertical {
+ border-bottom: 1px solid var(--dv-drag-over-border-color);
+ }
}
- &.small-left {
- border-left: 1px solid var(--dv-drag-over-border-color);
+ &.dv-overlay-left {
+ &.dv-overlay-small-horizontal {
+ border-left: 1px solid var(--dv-drag-over-border-color);
+ }
}
- &.small-right {
- border-right: 1px solid var(--dv-drag-over-border-color);
+ &.dv-overlay-right {
+ &.dv-overlay-small-horizontal {
+ border-right: 1px solid var(--dv-drag-over-border-color);
+ }
}
}
}
diff --git a/packages/dockview-core/src/dnd/droptarget.ts b/packages/dockview-core/src/dnd/droptarget.ts
index 357d4c32f..c9c638f82 100644
--- a/packages/dockview-core/src/dnd/droptarget.ts
+++ b/packages/dockview-core/src/dnd/droptarget.ts
@@ -269,10 +269,16 @@ export class Droptarget extends CompositeDisposable {
this.overlayElement.style.transform = transform;
- toggleClass(this.overlayElement, 'small-right', isSmallX && isRight);
- toggleClass(this.overlayElement, 'small-left', isSmallX && isLeft);
- toggleClass(this.overlayElement, 'small-top', isSmallY && isTop);
- toggleClass(this.overlayElement, 'small-bottom', isSmallY && isBottom);
+ toggleClass(this.overlayElement, 'dv-overlay-small-vertical', isSmallY);
+ toggleClass(
+ this.overlayElement,
+ 'dv-overlay-small-horizontal',
+ isSmallX
+ );
+ toggleClass(this.overlayElement, 'dv-overlay-left', isLeft);
+ toggleClass(this.overlayElement, 'dv-overlay-right', isRight);
+ toggleClass(this.overlayElement, 'dv-overlay-top', isTop);
+ toggleClass(this.overlayElement, 'dv-overlay-bottom', isBottom);
}
private setState(quadrant: Position): void {
From a6bafcc063fc5a2990a6725731ae9e976e095362 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Thu, 18 Jan 2024 15:29:03 +0000
Subject: [PATCH 3/4] feat: short-circuit resize calls when display:none
---
packages/dockview-core/src/resizable.ts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/packages/dockview-core/src/resizable.ts b/packages/dockview-core/src/resizable.ts
index d06418528..02df77be0 100644
--- a/packages/dockview-core/src/resizable.ts
+++ b/packages/dockview-core/src/resizable.ts
@@ -45,6 +45,22 @@ export abstract class Resizable extends CompositeDisposable {
return;
}
+ if (!this._element.offsetParent) {
+ /**
+ * offsetParent === null is equivalent to display: none being set on the element or one
+ * of it's parents. In the display: none case the size will become (0, 0) which we do
+ * not want to propagate.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
+ *
+ * You could use checkVisibility() but at the time of writing it's not supported across
+ * all Browsers
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility
+ */
+ return;
+ }
+
if (!isInDocument(this._element)) {
/**
* since the event is dispatched through requestAnimationFrame there is a small chance
From cc88096413056482708ba276bfb689feb53a1908 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Wed, 10 Jan 2024 10:26:58 +0000
Subject: [PATCH 4/4] feat: expose dockview root droptarget overlay options
---
packages/dockview-core/src/dnd/droptarget.ts | 97 ++++++++-----------
.../src/dockview/dockviewComponent.ts | 42 +++++---
.../dockview-core/src/dockview/options.ts | 3 +-
packages/dockview-core/src/index.ts | 2 +
packages/dockview/src/dockview/dockview.tsx | 12 +++
5 files changed, 88 insertions(+), 68 deletions(-)
diff --git a/packages/dockview-core/src/dnd/droptarget.ts b/packages/dockview-core/src/dnd/droptarget.ts
index 357d4c32f..caa35d1e2 100644
--- a/packages/dockview-core/src/dnd/droptarget.ts
+++ b/packages/dockview-core/src/dnd/droptarget.ts
@@ -5,10 +5,6 @@ import { DragAndDropObserver } from './dnd';
import { clamp } from '../math';
import { Direction } from '../gridview/baseComponentGridview';
-function numberOrFallback(maybeNumber: any, fallback: number): number {
- return typeof maybeNumber === 'number' ? maybeNumber : fallback;
-}
-
export function directionToPosition(direction: Direction): Position {
switch (direction) {
case 'above':
@@ -54,6 +50,26 @@ export type CanDisplayOverlay =
| boolean
| ((dragEvent: DragEvent, state: Position) => boolean);
+export type MeasuredValue = { value: number; type: 'pixels' | 'percentage' };
+
+export type DroptargetOverlayModel = {
+ size?: MeasuredValue;
+ activationSize?: MeasuredValue;
+};
+
+const DEFAULT_ACTIVATION_SIZE: MeasuredValue = {
+ value: 20,
+ type: 'percentage',
+};
+
+const DEFAULT_SIZE: MeasuredValue = {
+ value: 50,
+ type: 'percentage',
+};
+
+const SMALL_WIDTH_BOUNDARY = 100;
+const SMALL_HEIGHT_BOUNDARY = 100;
+
export class Droptarget extends CompositeDisposable {
private targetElement: HTMLElement | undefined;
private overlayElement: HTMLElement | undefined;
@@ -76,13 +92,7 @@ export class Droptarget extends CompositeDisposable {
private readonly options: {
canDisplayOverlay: CanDisplayOverlay;
acceptedTargetZones: Position[];
- overlayModel?: {
- size?: { value: number; type: 'pixels' | 'percentage' };
- activationSize?: {
- value: number;
- type: 'pixels' | 'percentage';
- };
- };
+ overlayModel?: DroptargetOverlayModel;
}
) {
super();
@@ -158,7 +168,7 @@ export class Droptarget extends CompositeDisposable {
this.toggleClasses(quadrant, width, height);
- this.setState(quadrant);
+ this._state = quadrant;
},
onDragLeave: () => {
this.removeDropTarget();
@@ -189,6 +199,10 @@ export class Droptarget extends CompositeDisposable {
this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
}
+ setOverlayModel(model: DroptargetOverlayModel): void {
+ this.options.overlayModel = model;
+ }
+
dispose(): void {
this.removeDropTarget();
super.dispose();
@@ -202,7 +216,7 @@ export class Droptarget extends CompositeDisposable {
}
/**
- * Check is the event has already been used by another instance od DropTarget
+ * Check is the event has already been used by another instance of DropTarget
*/
private isAlreadyUsed(event: DragEvent): boolean {
const value = (event as any)[Droptarget.USED_EVENT_ID];
@@ -218,8 +232,8 @@ export class Droptarget extends CompositeDisposable {
return;
}
- const isSmallX = width < 100;
- const isSmallY = height < 100;
+ const isSmallX = width < SMALL_WIDTH_BOUNDARY;
+ const isSmallY = height < SMALL_HEIGHT_BOUNDARY;
const isLeft = quadrant === 'left';
const isRight = quadrant === 'right';
@@ -231,22 +245,18 @@ export class Droptarget extends CompositeDisposable {
const topClass = !isSmallY && isTop;
const bottomClass = !isSmallY && isBottom;
- let size = 0.5;
+ let size = 1;
- if (this.options.overlayModel?.size?.type === 'percentage') {
- size = clamp(this.options.overlayModel.size.value, 0, 100) / 100;
- }
+ const sizeOptions = this.options.overlayModel?.size ?? DEFAULT_SIZE;
- if (this.options.overlayModel?.size?.type === 'pixels') {
+ if (sizeOptions.type === 'percentage') {
+ size = clamp(sizeOptions.value, 0, 100) / 100;
+ } else {
if (rightClass || leftClass) {
- size =
- clamp(0, this.options.overlayModel.size.value, width) /
- width;
+ size = clamp(0, sizeOptions.value, width) / width;
}
if (topClass || bottomClass) {
- size =
- clamp(0, this.options.overlayModel.size.value, height) /
- height;
+ size = clamp(0, sizeOptions.value, height) / height;
}
}
@@ -275,26 +285,6 @@ export class Droptarget extends CompositeDisposable {
toggleClass(this.overlayElement, 'small-bottom', isSmallY && isBottom);
}
- private setState(quadrant: Position): void {
- switch (quadrant) {
- case 'top':
- this._state = 'top';
- break;
- case 'left':
- this._state = 'left';
- break;
- case 'bottom':
- this._state = 'bottom';
- break;
- case 'right':
- this._state = 'right';
- break;
- case 'center':
- this._state = 'center';
- break;
- }
- }
-
private calculateQuadrant(
overlayType: Set,
x: number,
@@ -302,14 +292,11 @@ export class Droptarget extends CompositeDisposable {
width: number,
height: number
): Position | null {
- const isPercentage =
- this.options.overlayModel?.activationSize === undefined ||
- this.options.overlayModel?.activationSize?.type === 'percentage';
+ const activationSizeOptions =
+ this.options.overlayModel?.activationSize ??
+ DEFAULT_ACTIVATION_SIZE;
- const value = numberOrFallback(
- this.options?.overlayModel?.activationSize?.value,
- 20
- );
+ const isPercentage = activationSizeOptions.type === 'percentage';
if (isPercentage) {
return calculateQuadrantAsPercentage(
@@ -318,7 +305,7 @@ export class Droptarget extends CompositeDisposable {
y,
width,
height,
- value
+ activationSizeOptions.value
);
}
@@ -328,7 +315,7 @@ export class Droptarget extends CompositeDisposable {
y,
width,
height,
- value
+ activationSizeOptions.value
);
}
diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts
index 019b2789a..39e9126cf 100644
--- a/packages/dockview-core/src/dockview/dockviewComponent.ts
+++ b/packages/dockview-core/src/dockview/dockviewComponent.ts
@@ -4,7 +4,12 @@ import {
getGridLocation,
ISerializedLeafNode,
} from '../gridview/gridview';
-import { directionToPosition, Droptarget, Position } from '../dnd/droptarget';
+import {
+ directionToPosition,
+ Droptarget,
+ DroptargetOverlayModel,
+ Position,
+} from '../dnd/droptarget';
import { tail, sequenceEquals, remove } from '../array';
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
import { CompositeDisposable, Disposable } from '../lifecycle';
@@ -63,6 +68,11 @@ import {
OverlayRenderContainer,
} from '../overlayRenderContainer';
+const DEFAULT_ROOT_OVERLAY_MODEL: DroptargetOverlayModel = {
+ activationSize: { type: 'pixels', value: 10 },
+ size: { type: 'pixels', value: 20 },
+};
+
function getTheme(element: HTMLElement): string | undefined {
function toClassList(element: HTMLElement) {
const list: string[] = [];
@@ -219,6 +229,7 @@ export type DockviewComponentUpdateOptions = Pick<
| 'createPrefixHeaderActionsElement'
| 'disableFloatingGroups'
| 'floatingGroupBounds'
+ | 'rootOverlayModel'
>;
export interface DockviewDropEvent extends GroupviewDropEvent {
@@ -319,6 +330,7 @@ export class DockviewComponent
private readonly _floatingGroups: DockviewFloatingGroupPanel[] = [];
private readonly _popoutGroups: DockviewPopoutGroupPanel[] = [];
+ private readonly _rootDropTarget: Droptarget;
get orientation(): Orientation {
return this.gridview.orientation;
@@ -424,7 +436,7 @@ export class DockviewComponent
this.options.watermarkComponent = Watermark;
}
- const dropTarget = new Droptarget(this.element, {
+ this._rootDropTarget = new Droptarget(this.element, {
canDisplayOverlay: (event, position) => {
const data = getPanelData();
@@ -463,14 +475,12 @@ export class DockviewComponent
return false;
},
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
- overlayModel: {
- activationSize: { type: 'pixels', value: 10 },
- size: { type: 'pixels', value: 20 },
- },
+ overlayModel:
+ this.options.rootOverlayModel ?? DEFAULT_ROOT_OVERLAY_MODEL,
});
this.addDisposables(
- dropTarget.onDrop((event) => {
+ this._rootDropTarget.onDrop((event) => {
const data = getPanelData();
if (data) {
@@ -489,7 +499,7 @@ export class DockviewComponent
});
}
}),
- dropTarget
+ this._rootDropTarget
);
this._api = new DockviewApi(this);
@@ -714,20 +724,24 @@ export class DockviewComponent
}
updateOptions(options: DockviewComponentUpdateOptions): void {
- const hasOrientationChanged =
+ const changed_orientation =
typeof options.orientation === 'string' &&
this.gridview.orientation !== options.orientation;
- const hasFloatingGroupOptionsChanged =
+ const changed_floatingGroupBounds =
options.floatingGroupBounds !== undefined &&
options.floatingGroupBounds !== this.options.floatingGroupBounds;
+ const changed_rootOverlayOptions =
+ options.rootOverlayModel !== undefined &&
+ options.rootOverlayModel !== this.options.rootOverlayModel;
+
this._options = { ...this.options, ...options };
- if (hasOrientationChanged) {
+ if (changed_orientation) {
this.gridview.orientation = options.orientation!;
}
- if (hasFloatingGroupOptionsChanged) {
+ if (changed_floatingGroupBounds) {
for (const group of this._floatingGroups) {
switch (this.options.floatingGroupBounds) {
case 'boundedWithinViewport':
@@ -751,6 +765,10 @@ export class DockviewComponent
}
}
+ if (changed_rootOverlayOptions) {
+ this._rootDropTarget.setOverlayModel(options.rootOverlayModel!);
+ }
+
this.layout(this.gridview.width, this.gridview.height, true);
}
diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts
index 96493354b..34ab98989 100644
--- a/packages/dockview-core/src/dockview/options.ts
+++ b/packages/dockview-core/src/dockview/options.ts
@@ -13,7 +13,7 @@ import { DockviewGroupPanel } from './dockviewGroupPanel';
import { ISplitviewStyles, Orientation } from '../splitview/splitview';
import { PanelTransfer } from '../dnd/dataTransfer';
import { IDisposable } from '../lifecycle';
-import { Position } from '../dnd/droptarget';
+import { DroptargetOverlayModel, Position } from '../dnd/droptarget';
import { IDockviewPanel } from './dockviewPanel';
import {
ComponentConstructor,
@@ -100,6 +100,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
popoutUrl?: string;
defaultRenderer?: DockviewPanelRenderer;
debug?: boolean;
+ rootOverlayModel?: DroptargetOverlayModel;
}
export interface PanelOptions {
diff --git a/packages/dockview-core/src/index.ts b/packages/dockview-core/src/index.ts
index b3fda3fa7..62d415174 100644
--- a/packages/dockview-core/src/index.ts
+++ b/packages/dockview-core/src/index.ts
@@ -55,6 +55,8 @@ export {
Position,
positionToDirection,
directionToPosition,
+ MeasuredValue,
+ DroptargetOverlayModel,
} from './dnd/droptarget';
export {
FocusEvent,
diff --git a/packages/dockview/src/dockview/dockview.tsx b/packages/dockview/src/dockview/dockview.tsx
index 3a7c2ac35..91aaa0562 100644
--- a/packages/dockview/src/dockview/dockview.tsx
+++ b/packages/dockview/src/dockview/dockview.tsx
@@ -11,6 +11,7 @@ import {
DockviewGroupPanel,
IHeaderActionsRenderer,
DockviewPanelRenderer,
+ DroptargetOverlayModel,
} from 'dockview-core';
import { ReactPanelContentPart } from './reactContentPart';
import { ReactPanelHeaderPart } from './reactHeaderPart';
@@ -79,6 +80,7 @@ export interface IDockviewReactProps {
};
debug?: boolean;
defaultRenderer?: DockviewPanelRenderer;
+ rootOverlayModel?: DroptargetOverlayModel;
}
const DEFAULT_REACT_TAB = 'props.defaultTabComponent';
@@ -180,6 +182,7 @@ export const DockviewReact = React.forwardRef(
floatingGroupBounds: props.floatingGroupBounds,
defaultRenderer: props.defaultRenderer,
debug: props.debug,
+ rootOverlayModel: props.rootOverlayModel,
});
const { clientWidth, clientHeight } = domRef.current;
@@ -312,6 +315,15 @@ export const DockviewReact = React.forwardRef(
});
}, [props.leftHeaderActionsComponent]);
+ React.useEffect(() => {
+ if (!dockviewRef.current) {
+ return;
+ }
+ dockviewRef.current.updateOptions({
+ rootOverlayModel: props.rootOverlayModel,
+ });
+ }, [props.rootOverlayModel]);
+
React.useEffect(() => {
if (!dockviewRef.current) {
return;