From 6c39c448bbcbf4bc460c3e4e7c55b96e1e095df0 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:45:13 +0100 Subject: [PATCH 01/24] chore: updateOptions logic --- .../dockview/dockviewComponent.spec.ts | 4 +- .../gridview/baseComponentGridview.spec.ts | 10 +-- .../src/dockview/dockviewComponent.ts | 79 +++++-------------- packages/dockview-core/src/dom.ts | 47 +++++++++++ .../src/gridview/baseComponentGridview.ts | 42 ++++++---- .../src/gridview/gridviewComponent.ts | 3 +- .../src/paneview/paneviewComponent.ts | 23 +++--- .../src/splitview/splitviewComponent.ts | 31 +++----- 8 files changed, 118 insertions(+), 121 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index d8d887de5..ae45adf8f 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -8,9 +8,9 @@ import { PanelUpdateEvent } from '../../panel/types'; import { Orientation } from '../../splitview/splitview'; import { CompositeDisposable } from '../../lifecycle'; import { Emitter } from '../../events'; -import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel'; +import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; -import { fireEvent, getByTestId, queryByTestId } from '@testing-library/dom'; +import { fireEvent, queryByTestId } from '@testing-library/dom'; import { getPanelData } from '../../dnd/dataTransfer'; import { GroupDragEvent, diff --git a/packages/dockview-core/src/__tests__/gridview/baseComponentGridview.spec.ts b/packages/dockview-core/src/__tests__/gridview/baseComponentGridview.spec.ts index 6371488ee..d8ed45209 100644 --- a/packages/dockview-core/src/__tests__/gridview/baseComponentGridview.spec.ts +++ b/packages/dockview-core/src/__tests__/gridview/baseComponentGridview.spec.ts @@ -68,8 +68,8 @@ class TestPanel implements IGridPanelView { class ClassUnderTest extends BaseGrid { readonly gridview = this.gridview; - constructor(options: BaseGridOptions) { - super(options); + constructor(parentElement: HTMLElement, options: BaseGridOptions) { + super(parentElement, options); } doRemoveGroup( @@ -106,8 +106,7 @@ class ClassUnderTest extends BaseGrid { describe('baseComponentGridview', () => { test('that .layout(...) force flag works', () => { - const cut = new ClassUnderTest({ - parentElement: document.createElement('div'), + const cut = new ClassUnderTest(document.createElement('div'), { orientation: Orientation.HORIZONTAL, proportionalLayout: true, }); @@ -131,8 +130,7 @@ describe('baseComponentGridview', () => { }); test('can add group', () => { - const cut = new ClassUnderTest({ - parentElement: document.createElement('div'), + const cut = new ClassUnderTest(document.createElement('div'), { orientation: Orientation.HORIZONTAL, proportionalLayout: true, }); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index cf1c267ee..2a72db7fe 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -51,7 +51,12 @@ import { DockviewPanelModel } from './dockviewPanelModel'; import { getPanelData } from '../dnd/dataTransfer'; import { Parameters } from '../panel/types'; import { Overlay } from '../overlay/overlay'; -import { addTestId, toggleClass, watchElementResize } from '../dom'; +import { + addTestId, + getDockviewTheme, + toggleClass, + watchElementResize, +} from '../dom'; import { DockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel'; import { GroupDragEvent, @@ -92,33 +97,6 @@ function moveGroupWithoutDestroying(options: { }); } -function getDockviewTheme(element: HTMLElement): string | undefined { - function toClassList(element: HTMLElement) { - const list: string[] = []; - - for (let i = 0; i < element.classList.length; i++) { - list.push(element.classList.item(i)!); - } - - return list; - } - - let theme: string | undefined = undefined; - let parent: HTMLElement | null = element; - - while (parent !== null) { - theme = toClassList(parent).find((cls) => - cls.startsWith('dockview-theme-') - ); - if (typeof theme === 'string') { - break; - } - parent = parent.parentElement; - } - - return theme; -} - export interface PanelReference { update: (event: { params: { [key: string]: any } }) => void; remove: () => void; @@ -362,23 +340,18 @@ export class DockviewComponent } constructor(parentElement: HTMLElement, options: DockviewComponentOptions) { - super({ + super(parentElement, { proportionalLayout: true, orientation: Orientation.HORIZONTAL, styles: options.hideBorders ? { separatorBorder: 'transparent' } : undefined, - parentElement: parentElement, disableAutoResizing: options.disableAutoResizing, locked: options.locked, margin: options.gap, className: options.className, }); - // const gready = document.createElement('div'); - // gready.className = 'dv-overlay-render-container'; - // this.gridview.element.appendChild(gready); - this.overlayRenderContainer = new OverlayRenderContainer( this.gridview.element, this @@ -1022,19 +995,9 @@ export class DockviewComponent override updateOptions(options: Partial): void { super.updateOptions(options); - const changed_floatingGroupBounds = - 'floatingGroupBounds' in options && - options.floatingGroupBounds !== this.options.floatingGroupBounds; - - const changed_rootOverlayOptions = - 'rootOverlayModel' in options && - options.rootOverlayModel !== this.options.rootOverlayModel; - - this._options = { ...this.options, ...options }; - - if (changed_floatingGroupBounds) { + if ('floatingGroupBounds' in options) { for (const group of this._floatingGroups) { - switch (this.options.floatingGroupBounds) { + switch (options.floatingGroupBounds) { case 'boundedWithinViewport': group.overlay.minimumInViewportHeight = undefined; group.overlay.minimumInViewportWidth = undefined; @@ -1047,30 +1010,26 @@ export class DockviewComponent break; default: group.overlay.minimumInViewportHeight = - this.options.floatingGroupBounds?.minimumHeightWithinViewport; + options.floatingGroupBounds?.minimumHeightWithinViewport; group.overlay.minimumInViewportWidth = - this.options.floatingGroupBounds?.minimumWidthWithinViewport; + options.floatingGroupBounds?.minimumWidthWithinViewport; } group.overlay.setBounds(); } } - if (changed_rootOverlayOptions) { - this._rootDropTarget.setOverlayModel(options.rootOverlayModel!); + if ('rootOverlayModel' in options) { + this._rootDropTarget.setOverlayModel( + options.rootOverlayModel ?? DEFAULT_ROOT_OVERLAY_MODEL + ); } - if ( - // if explicitly set as `undefined` - 'gap' in options && - options.gap === undefined - ) { - this.gridview.margin = 0; + if ('gap' in options) { + this.gridview.margin = options.gap ?? 0; } - if (typeof options.gap === 'number') { - this.gridview.margin = options.gap; - } + this._options = { ...this.options, ...options }; this.layout(this.gridview.width, this.gridview.height, true); } @@ -1108,7 +1067,7 @@ export class DockviewComponent if (!this.activeGroup) { return; } - options.group = this.activeGroup; + options.group = this.activeGroup; } if (options.includePanel && options.group) { diff --git a/packages/dockview-core/src/dom.ts b/packages/dockview-core/src/dom.ts index 249b84181..bcc82a496 100644 --- a/packages/dockview-core/src/dom.ts +++ b/packages/dockview-core/src/dom.ts @@ -280,3 +280,50 @@ export function disableIframePointEvents() { }, }; } + +export function getDockviewTheme(element: HTMLElement): string | undefined { + function toClassList(element: HTMLElement) { + const list: string[] = []; + + for (let i = 0; i < element.classList.length; i++) { + list.push(element.classList.item(i)!); + } + + return list; + } + + let theme: string | undefined = undefined; + let parent: HTMLElement | null = element; + + while (parent !== null) { + theme = toClassList(parent).find((cls) => + cls.startsWith('dockview-theme-') + ); + if (typeof theme === 'string') { + break; + } + parent = parent.parentElement; + } + + return theme; +} + +export class Classnames { + private _classNames: string[] = []; + + constructor(private readonly element: HTMLElement) {} + + setClassNames(classNames: string) { + for (const className of this._classNames) { + toggleClass(this.element, className, false); + } + + this._classNames = classNames + .split(' ') + .filter((v) => v.trim().length > 0); + + for (const className of this._classNames) { + toggleClass(this.element, className, true); + } + } +} diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts index 6bed2c62c..332cef90c 100644 --- a/packages/dockview-core/src/gridview/baseComponentGridview.ts +++ b/packages/dockview-core/src/gridview/baseComponentGridview.ts @@ -7,7 +7,7 @@ import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview'; import { IPanel } from '../panel/types'; import { MovementOptions2 } from '../dockview/options'; import { Resizable } from '../resizable'; -import { toggleClass } from '../dom'; +import { Classnames, toggleClass } from '../dom'; const nextLayoutId = sequentialNumberGenerator(); @@ -33,7 +33,6 @@ export interface BaseGridOptions { readonly proportionalLayout: boolean; readonly orientation: Orientation; readonly styles?: ISplitviewStyles; - readonly parentElement: HTMLElement; readonly disableAutoResizing?: boolean; readonly locked?: boolean; readonly margin?: number; @@ -100,7 +99,7 @@ export abstract class BaseGrid readonly onDidViewVisibilityChangeMicroTaskQueue = this._onDidViewVisibilityChangeMicroTaskQueue.onEvent; - private classNames: string[] = []; + private readonly _classNames: Classnames; get id(): string { return this._id; @@ -147,18 +146,15 @@ export abstract class BaseGrid this.gridview.locked = value; } - constructor(options: BaseGridOptions) { + constructor(parentElement: HTMLElement, options: BaseGridOptions) { super(document.createElement('div'), options.disableAutoResizing); this.element.style.height = '100%'; this.element.style.width = '100%'; - this.classNames = options.className?.split(' ') ?? []; + this._classNames = new Classnames(this.element); + this._classNames.setClassNames(options.className ?? ''); - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } - - options.parentElement.appendChild(this.element); + parentElement.appendChild(this.element); this.gridview = new Gridview( !!options.proportionalLayout, @@ -214,14 +210,26 @@ export abstract class BaseGrid } updateOptions(options: Partial) { + if (typeof options.proportionalLayout === 'boolean') { + // this.gridview.proportionalLayout = options.proportionalLayout; // not supported + } + if (options.orientation) { + this.gridview.orientation = options.orientation; + } + if ('styles' in options) { + // this.gridview.styles = options.styles; // not supported + } + if ('disableResizing' in options) { + this.disableResizing = options.disableAutoResizing ?? false; + } + if ('locked' in options) { + this.locked = options.locked ?? false; + } + if ('margin' in options) { + this.gridview.margin = options.margin ?? 0; + } if ('className' in options) { - for (const className of this.classNames) { - toggleClass(this.element, className, false); - } - this.classNames = options.className?.split(' ') ?? []; - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } + this._classNames.setClassNames(options.className ?? ''); } } diff --git a/packages/dockview-core/src/gridview/gridviewComponent.ts b/packages/dockview-core/src/gridview/gridviewComponent.ts index c342d3a50..a0ea22288 100644 --- a/packages/dockview-core/src/gridview/gridviewComponent.ts +++ b/packages/dockview-core/src/gridview/gridviewComponent.ts @@ -115,8 +115,7 @@ export class GridviewComponent } constructor(parentElement: HTMLElement, options: GridviewComponentOptions) { - super({ - parentElement: parentElement, + super(parentElement, { proportionalLayout: options.proportionalLayout, orientation: options.orientation, styles: options.styles, diff --git a/packages/dockview-core/src/paneview/paneviewComponent.ts b/packages/dockview-core/src/paneview/paneviewComponent.ts index 944378c31..2920cb802 100644 --- a/packages/dockview-core/src/paneview/paneviewComponent.ts +++ b/packages/dockview-core/src/paneview/paneviewComponent.ts @@ -24,7 +24,7 @@ import { sequentialNumberGenerator } from '../math'; import { PaneTransfer } from '../dnd/dataTransfer'; import { Resizable } from '../resizable'; import { Parameters } from '../panel/types'; -import { toggleClass } from '../dom'; +import { Classnames, toggleClass } from '../dom'; const nextLayoutId = sequentialNumberGenerator(); @@ -152,7 +152,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { private readonly _onDidRemoveView = new Emitter(); readonly onDidRemoveView = this._onDidRemoveView.event; - private classNames: string[] = []; + private readonly _classNames: Classnames; get id(): string { return this._id; @@ -213,11 +213,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { this._onDidRemoveView ); - this.classNames = options.className?.split(' ') ?? []; - - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } + this._classNames = new Classnames(this.element); + this._classNames.setClassNames(options.className ?? ''); this._options = options; @@ -247,13 +244,11 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { updateOptions(options: Partial): void { if ('className' in options) { - for (const className of this.classNames) { - toggleClass(this.element, className, false); - } - this.classNames = options.className?.split(' ') ?? []; - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } + this._classNames.setClassNames(options.className ?? ''); + } + + if ('disableResizing' in options) { + this.disableResizing = options.disableAutoResizing ?? false; } this._options = { ...this.options, ...options }; diff --git a/packages/dockview-core/src/splitview/splitviewComponent.ts b/packages/dockview-core/src/splitview/splitviewComponent.ts index dc770d9a9..aa666fbfe 100644 --- a/packages/dockview-core/src/splitview/splitviewComponent.ts +++ b/packages/dockview-core/src/splitview/splitviewComponent.ts @@ -17,7 +17,7 @@ import { Emitter, Event } from '../events'; import { SplitviewPanel, ISplitviewPanel } from './splitviewPanel'; import { createComponent } from '../panel/componentFactory'; import { Resizable } from '../resizable'; -import { toggleClass } from '../dom'; +import { Classnames, toggleClass } from '../dom'; export interface SerializedSplitviewPanelData { id: string; @@ -100,7 +100,7 @@ export class SplitviewComponent private readonly _onDidLayoutChange = new Emitter(); readonly onDidLayoutChange: Event = this._onDidLayoutChange.event; - private classNames: string[] = []; + private readonly _classNames: Classnames; get panels(): SplitviewPanel[] { return this.splitview.getViews(); @@ -162,11 +162,8 @@ export class SplitviewComponent ) { super(parentElement, options.disableAutoResizing); - this.classNames = options.className?.split(' ') ?? []; - - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } + this._classNames = new Classnames(this.element); + this._classNames.setClassNames(options.className ?? ''); this._options = options; @@ -189,25 +186,19 @@ export class SplitviewComponent updateOptions(options: Partial): void { if ('className' in options) { - for (const className of this.classNames) { - toggleClass(this.element, className, false); - } - this.classNames = options.className?.split(' ') ?? []; - for (const className of this.classNames) { - toggleClass(this.element, className, true); - } + this._classNames.setClassNames(options.className ?? ''); } - const hasOrientationChanged = - typeof options.orientation === 'string' && - this.options.orientation !== options.orientation; + if ('disableResizing' in options) { + this.disableResizing = options.disableAutoResizing ?? false; + } - this._options = { ...this.options, ...options }; - - if (hasOrientationChanged) { + if (typeof options.orientation === 'string') { this.splitview.orientation = options.orientation!; } + this._options = { ...this.options, ...options }; + this.splitview.layout( this.splitview.size, this.splitview.orthogonalSize From 77bccb3f69eb4eb9bdad02c212322ebd46344382 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Thu, 15 Aug 2024 21:38:52 +0100 Subject: [PATCH 02/24] chore: remove method --- .../dockview/components/watermark/watermark.spec.ts | 1 - .../src/__tests__/dockview/dockviewGroupPanelModel.spec.ts | 4 ---- .../src/dockview/components/watermark/watermark.ts | 5 +---- .../dockview-core/src/dockview/dockviewGroupPanelModel.ts | 2 -- packages/dockview-core/src/dockview/types.ts | 1 - packages/dockview-vue/src/utils.ts | 4 ---- packages/dockview/src/dockview/reactWatermarkPart.ts | 7 ------- 7 files changed, 1 insertion(+), 23 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts b/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts index 662f73198..7ce6551e6 100644 --- a/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts @@ -14,7 +14,6 @@ describe('watermark', () => { const group = jest.fn() as any; cut.init({ containerApi: api }); - cut.updateParentGroup(group, true); const closeEl = cut.element.querySelector('.close-action')!; diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts index 1f83b8221..01d0c84d1 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts @@ -116,10 +116,6 @@ class Watermark implements IWatermarkRenderer { return {}; } - updateParentGroup() { - // - } - dispose() { // } diff --git a/packages/dockview-core/src/dockview/components/watermark/watermark.ts b/packages/dockview-core/src/dockview/components/watermark/watermark.ts index 28ecf9c7c..ca43401c7 100644 --- a/packages/dockview-core/src/dockview/components/watermark/watermark.ts +++ b/packages/dockview-core/src/dockview/components/watermark/watermark.ts @@ -78,10 +78,7 @@ export class Watermark this.render(); } - updateParentGroup(group: DockviewGroupPanel, _visible: boolean): void { - this._group = group; - this.render(); - } + dispose(): void { super.dispose(); diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index 574441eba..548cf9ef6 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -972,8 +972,6 @@ export class DockviewGroupPanelModel this.tabsContainer.hide(); this.contentContainer.element.appendChild(this.watermark.element); - - this.watermark.updateParentGroup(this.groupPanel, true); } if (!this.isEmpty && this.watermark) { this.watermark.element.remove(); diff --git a/packages/dockview-core/src/dockview/types.ts b/packages/dockview-core/src/dockview/types.ts index 99c7c38d9..0151381bd 100644 --- a/packages/dockview-core/src/dockview/types.ts +++ b/packages/dockview-core/src/dockview/types.ts @@ -32,7 +32,6 @@ export interface IWatermarkRenderer extends Optional, RendererMethodOptionalList> { readonly element: HTMLElement; init: (params: WatermarkRendererInitParameters) => void; - updateParentGroup(group: DockviewGroupPanel, visible: boolean): void; } export interface ITabRenderer diff --git a/packages/dockview-vue/src/utils.ts b/packages/dockview-vue/src/utils.ts index a4e18a5fe..4b6252899 100644 --- a/packages/dockview-vue/src/utils.ts +++ b/packages/dockview-vue/src/utils.ts @@ -183,10 +183,6 @@ export class VueWatermarkRenderer ); } - updateParentGroup(group: DockviewGroupPanel, visible: boolean): void { - // TODO: make optional on interface - } - update(event: PanelUpdateEvent): void { // noop } diff --git a/packages/dockview/src/dockview/reactWatermarkPart.ts b/packages/dockview/src/dockview/reactWatermarkPart.ts index f9b18a1c7..731ecd646 100644 --- a/packages/dockview/src/dockview/reactWatermarkPart.ts +++ b/packages/dockview/src/dockview/reactWatermarkPart.ts @@ -57,13 +57,6 @@ export class ReactWatermarkPart implements IWatermarkRenderer { // noop - retrieval from api } - updateParentGroup( - _group: DockviewGroupPanel, - _isPanelVisible: boolean - ): void { - // noop - } - dispose(): void { this.part?.dispose(); } From 4d71775804666d39e6404ca8b55d63f8586c2267 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Fri, 16 Aug 2024 18:54:33 +0100 Subject: [PATCH 03/24] chore: fix test --- .../components/watermark/watermark.spec.ts | 11 +++---- .../components/watermark/watermark.ts | 29 ++++--------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts b/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts index 7ce6551e6..c681f9b6b 100644 --- a/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/components/watermark/watermark.spec.ts @@ -1,19 +1,16 @@ import { DockviewApi } from '../../../../api/component.api'; import { Watermark } from '../../../../dockview/components/watermark/watermark'; +import { fromPartial } from '@total-typescript/shoehorn'; describe('watermark', () => { test('that the group is closed when the close button is clicked', () => { const cut = new Watermark(); - - const mockApi = jest.fn, any[]>(() => { - return { - removeGroup: jest.fn(), - }; + const api = fromPartial({ + removeGroup: jest.fn(), }); - const api = new mockApi(); const group = jest.fn() as any; - cut.init({ containerApi: api }); + cut.init({ containerApi: api, group }); const closeEl = cut.element.querySelector('.close-action')!; diff --git a/packages/dockview-core/src/dockview/components/watermark/watermark.ts b/packages/dockview-core/src/dockview/components/watermark/watermark.ts index ca43401c7..0742f8741 100644 --- a/packages/dockview-core/src/dockview/components/watermark/watermark.ts +++ b/packages/dockview-core/src/dockview/components/watermark/watermark.ts @@ -5,8 +5,7 @@ import { import { addDisposableListener } from '../../../events'; import { toggleClass } from '../../../dom'; import { CompositeDisposable } from '../../../lifecycle'; -import { DockviewGroupPanel } from '../../dockviewGroupPanel'; -import { PanelUpdateEvent } from '../../../panel/types'; +import { IDockviewGroupPanel } from '../../dockviewGroupPanel'; import { createCloseButton } from '../../../svg'; import { DockviewApi } from '../../../api/component.api'; @@ -15,7 +14,7 @@ export class Watermark implements IWatermarkRenderer { private _element: HTMLElement; - private _group: DockviewGroupPanel | undefined; + private _group: IDockviewGroupPanel | undefined; private _api: DockviewApi | undefined; get element(): HTMLElement { @@ -52,8 +51,9 @@ export class Watermark title.appendChild(actionsContainer); this.addDisposables( - addDisposableListener(closeAnchor, 'click', (ev) => { - ev.preventDefault(); + addDisposableListener(closeAnchor, 'click', (event: MouseEvent) => { + event.preventDefault(); + if (this._group) { this._api?.removeGroup(this._group); } @@ -61,29 +61,12 @@ export class Watermark ); } - update(_event: PanelUpdateEvent): void { - // noop - } - - focus(): void { - // noop - } - - layout(_width: number, _height: number): void { - // noop - } - init(_params: WatermarkRendererInitParameters): void { this._api = _params.containerApi; + this._group = _params.group; this.render(); } - - - dispose(): void { - super.dispose(); - } - private render(): void { const isOneGroup = !!(this._api && this._api.size <= 1); toggleClass(this.element, 'has-actions', isOneGroup); From 9d4f4cb534e94245a8b315c499ac9e6c6db74045 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:52:11 +0100 Subject: [PATCH 04/24] feat: panel constraints --- .../src/dockview/deserializer.ts | 4 ++ .../src/dockview/dockviewComponent.ts | 8 +++- .../src/dockview/dockviewGroupPanel.ts | 42 ++++++++++++++++++- .../src/dockview/dockviewGroupPanelModel.ts | 2 + .../src/dockview/dockviewPanel.ts | 36 +++++++++++++++- .../dockview-core/src/dockview/options.ts | 27 ++++++++---- packages/dockview-core/src/dockview/types.ts | 4 ++ .../src/gridview/gridviewPanel.ts | 7 ++++ 8 files changed, 117 insertions(+), 13 deletions(-) diff --git a/packages/dockview-core/src/dockview/deserializer.ts b/packages/dockview-core/src/dockview/deserializer.ts index 41a4a0102..1aa49b018 100644 --- a/packages/dockview-core/src/dockview/deserializer.ts +++ b/packages/dockview-core/src/dockview/deserializer.ts @@ -57,6 +57,10 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer { view, { renderer: panelData.renderer, + minimumWidth: panelData.minimumWidth, + minimumHeight: panelData.minimumHeight, + maximumWidth: panelData.maximumWidth, + maximumHeight: panelData.maximumHeight, } ); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 2a72db7fe..b06410090 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -2242,7 +2242,13 @@ export class DockviewComponent this._api, group, view, - { renderer: options.renderer } + { + renderer: options.renderer, + minimumWidth: options.minimumWidth, + minimumHeight: options.minimumHeight, + maximumWidth: options.maximumWidth, + maximumHeight: options.maximumHeight, + } ); panel.init({ diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts index 6f01fae5f..5edd14393 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts @@ -34,6 +34,38 @@ export class DockviewGroupPanel { private readonly _model: DockviewGroupPanelModel; + get minimumWidth(): number { + const sizes = this.panels + .filter((panel) => typeof panel.minimumWidth === 'number') + .map((panel) => panel.minimumWidth) as number[]; + + return sizes.length > 0 ? Math.max(...sizes) : 100; + } + + get minimumHeight(): number { + const sizes = this.panels + .filter((panel) => typeof panel.minimumHeight === 'number') + .map((panel) => panel.minimumHeight) as number[]; + + return sizes.length > 0 ? Math.max(...sizes) : 100; + } + + get maximumWidth(): number { + const sizes = this.panels + .filter((panel) => typeof panel.maximumWidth === 'number') + .map((panel) => panel.maximumWidth) as number[]; + + return sizes.length > 0 ? Math.min(...sizes) : Number.MAX_SAFE_INTEGER; + } + + get maximumHeight(): number { + const sizes = this.panels + .filter((panel) => typeof panel.maximumHeight === 'number') + .map((panel) => panel.maximumHeight) as number[]; + + return sizes.length > 0 ? Math.min(...sizes) : Number.MAX_SAFE_INTEGER; + } + get panels(): IDockviewPanel[] { return this._model.panels; } @@ -71,8 +103,14 @@ export class DockviewGroupPanel id, 'groupview_default', { - minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT, - minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH, + minimumHeight: + options.constraints?.minimumHeight ?? + MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT, + minimumWidth: + options.constraints?.maximumHeight ?? + MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH, + maximumHeight: options.constraints?.maximumHeight, + maximumWidth: options.constraints?.maximumWidth, }, new DockviewGroupPanelApiImpl(id, accessor) ); diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index 548cf9ef6..ae3c07ae3 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -38,6 +38,7 @@ import { } from './options'; import { OverlayRenderContainer } from '../overlay/overlayRenderContainer'; import { TitleEvent } from '../api/dockviewPanelApi'; +import { Contraints } from '../gridview/gridviewPanel'; interface GroupMoveEvent { groupId: string; @@ -50,6 +51,7 @@ interface CoreGroupOptions { locked?: DockviewGroupPanelLocked; hideHeader?: boolean; skipSetActive?: boolean; + constraints?: Partial; } export interface GroupOptions extends CoreGroupOptions { diff --git a/packages/dockview-core/src/dockview/dockviewPanel.ts b/packages/dockview-core/src/dockview/dockviewPanel.ts index 984c3fcdb..8eb2cfb7f 100644 --- a/packages/dockview-core/src/dockview/dockviewPanel.ts +++ b/packages/dockview-core/src/dockview/dockviewPanel.ts @@ -11,6 +11,7 @@ import { IDockviewPanelModel } from './dockviewPanelModel'; import { DockviewComponent } from './dockviewComponent'; import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer'; import { WillFocusEvent } from '../api/panelApi'; +import { Contraints } from '../gridview/gridviewPanel'; export interface IDockviewPanel extends IDisposable, IPanel { readonly view: IDockviewPanelModel; @@ -18,6 +19,10 @@ export interface IDockviewPanel extends IDisposable, IPanel { readonly api: DockviewPanelApi; readonly title: string | undefined; readonly params: Parameters | undefined; + readonly minimumWidth?: number; + readonly minimumHeight?: number; + readonly maximumWidth?: number; + readonly maximumHeight?: number; updateParentGroup( group: DockviewGroupPanel, options?: { skipSetActive?: boolean } @@ -40,6 +45,11 @@ export class DockviewPanel private _title: string | undefined; private _renderer: DockviewPanelRenderer | undefined; + private _minimumWidth: number | undefined; + private _minimumHeight: number | undefined; + private _maximumWidth: number | undefined; + private _maximumHeight: number | undefined; + get params(): Parameters | undefined { return this._params; } @@ -56,6 +66,22 @@ export class DockviewPanel return this._renderer ?? this.accessor.renderer; } + get minimumWidth(): number | undefined { + return this._minimumWidth; + } + + get minimumHeight(): number | undefined { + return this._minimumHeight; + } + + get maximumWidth(): number | undefined { + return this._maximumWidth; + } + + get maximumHeight(): number | undefined { + return this._maximumHeight; + } + constructor( public readonly id: string, component: string, @@ -64,11 +90,15 @@ export class DockviewPanel private readonly containerApi: DockviewApi, group: DockviewGroupPanel, readonly view: IDockviewPanelModel, - options: { renderer?: DockviewPanelRenderer } + options: { renderer?: DockviewPanelRenderer } & Partial ) { super(); this._renderer = options.renderer; this._group = group; + this._minimumWidth = options.minimumWidth; + this._minimumHeight = options.minimumHeight; + this._maximumWidth = options.maximumWidth; + this._maximumHeight = options.maximumHeight; this.api = new DockviewPanelApiImpl( this, @@ -129,6 +159,10 @@ export class DockviewPanel : undefined, title: this.title, renderer: this._renderer, + minimumHeight: this._minimumHeight, + maximumHeight: this._maximumHeight, + minimumWidth: this._minimumWidth, + maximumWidth: this._maximumWidth, }; } diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 5fce93ebf..bf3235b60 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -16,6 +16,7 @@ import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer'; import { IGroupHeaderProps } from './framework'; import { AnchoredBox } from '../types'; import { FloatingGroupOptions } from './dockviewComponent'; +import { Contraints } from '../gridview/gridviewPanel'; export interface IHeaderActionsRenderer extends IDisposable { readonly element: HTMLElement; @@ -116,6 +117,17 @@ export const PROPERTY_KEYS: (keyof DockviewOptions)[] = (() => { return Object.keys(properties) as (keyof DockviewOptions)[]; })(); +export interface CreateComponentOptions { + /** + * The unqiue identifer of the component + */ + id: string; + /** + * The component name, this should determine what is rendered. + */ + name: string; +} + export interface DockviewFrameworkOptions { defaultTabComponent?: string; createRightHeaderActionComponent?: ( @@ -127,14 +139,10 @@ export interface DockviewFrameworkOptions { createPrefixHeaderActionComponent?: ( group: DockviewGroupPanel ) => IHeaderActionsRenderer; - createTabComponent?: (options: { - id: string; - name: string; - }) => ITabRenderer | undefined; - createComponent: (options: { - id: string; - name: string; - }) => IContentRenderer; + createTabComponent?: ( + options: CreateComponentOptions + ) => ITabRenderer | undefined; + createComponent: (options: CreateComponentOptions) => IContentRenderer; createWatermarkComponent?: () => IWatermarkRenderer; } @@ -230,7 +238,8 @@ export type AddPanelOptions

= { * Defaults to `false` which forces newly added panels to become active. */ inactive?: boolean; -} & Partial; +} & Partial & + Partial; type AddGroupOptionsWithPanel = { referencePanel: string | IDockviewPanel; diff --git a/packages/dockview-core/src/dockview/types.ts b/packages/dockview-core/src/dockview/types.ts index 0151381bd..aa5cae998 100644 --- a/packages/dockview-core/src/dockview/types.ts +++ b/packages/dockview-core/src/dockview/types.ts @@ -63,4 +63,8 @@ export interface GroupviewPanelState { title?: string; renderer?: DockviewPanelRenderer; params?: { [key: string]: any }; + minimumWidth?: number; + minimumHeight?: number; + maximumWidth?: number; + maximumHeight?: number; } diff --git a/packages/dockview-core/src/gridview/gridviewPanel.ts b/packages/dockview-core/src/gridview/gridviewPanel.ts index 916c4f1e1..956d9baf8 100644 --- a/packages/dockview-core/src/gridview/gridviewPanel.ts +++ b/packages/dockview-core/src/gridview/gridviewPanel.ts @@ -15,6 +15,13 @@ import { Emitter, Event } from '../events'; import { IViewSize } from './gridview'; import { BaseGrid, IGridPanelView } from './baseComponentGridview'; +export interface Contraints { + minimumWidth?: number; + maximumWidth?: number; + minimumHeight?: number; + maximumHeight?: number; +} + export interface GridviewInitParameters extends PanelInitParameters { minimumWidth?: number; maximumWidth?: number; From 2dc0dafa5a001649d7b5b3e5555b01c4c4ca3994 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:00:21 +0100 Subject: [PATCH 05/24] feat: addGroup initial sizes --- .../src/dockview/dockviewComponent.ts | 14 +++++++++++++- .../src/dockview/dockviewGroupPanelModel.ts | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index b06410090..517f7c8b1 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -1640,7 +1640,12 @@ export class DockviewComponent ); const group = this.createGroup(options); - this.doAddGroup(group, relativeLocation); + const size = + this.getLocationOrientation(relativeLocation) === + Orientation.VERTICAL + ? options.initialHeight + : options.initialWidth; + this.doAddGroup(group, relativeLocation, size); if (!options.skipSetActive) { this.doSetGroupAndPanelActive(group); } @@ -1654,6 +1659,13 @@ export class DockviewComponent } } + private getLocationOrientation(location: number[]) { + return location.length % 2 == 0 && + this.gridview.orientation === Orientation.HORIZONTAL + ? Orientation.HORIZONTAL + : Orientation.VERTICAL; + } + removeGroup( group: DockviewGroupPanel, options?: diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index ae3c07ae3..1d02d4d33 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -52,6 +52,8 @@ interface CoreGroupOptions { hideHeader?: boolean; skipSetActive?: boolean; constraints?: Partial; + initialWidth?: number; + initialHeight?: number; } export interface GroupOptions extends CoreGroupOptions { From 4841d95573c37c6463bd54fcaf891e9466633267 Mon Sep 17 00:00:00 2001 From: OneAndOnlyFinbar Date: Sat, 24 Aug 2024 15:02:18 -0400 Subject: [PATCH 06/24] Fix typo in replit theme Remove duplicated pound sign. --- packages/dockview-core/src/theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dockview-core/src/theme.scss b/packages/dockview-core/src/theme.scss index 96c259d5f..ca0cb67c6 100644 --- a/packages/dockview-core/src/theme.scss +++ b/packages/dockview-core/src/theme.scss @@ -326,7 +326,7 @@ --dv-tabs-and-actions-container-background-color: #fcfcfc; // --dv-activegroup-visiblepanel-tab-background-color: #f0f1f2; - --dv-activegroup-hiddenpanel-tab-background-color: ##fcfcfc; + --dv-activegroup-hiddenpanel-tab-background-color: #fcfcfc; --dv-inactivegroup-visiblepanel-tab-background-color: #f0f1f2; --dv-inactivegroup-hiddenpanel-tab-background-color: #fcfcfc; --dv-tab-divider-color: transparent; From 1033b80783d09e4a359c43787a1fc5297e767339 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:17:54 +0100 Subject: [PATCH 07/24] feat: ensure use of pointerevents for touch support --- .../components/tab/defaultTab.spec.ts | 2 +- .../components/titlebar/tabsContainer.spec.ts | 14 +++++++---- .../src/__tests__/events.spec.ts | 24 +++++++++---------- .../dockview-core/src/dnd/groupDragHandler.ts | 2 +- .../src/dockview/components/tab/defaultTab.ts | 4 ++-- .../src/dockview/components/tab/tab.ts | 2 +- .../components/titlebar/tabsContainer.ts | 4 ++-- packages/dockview-core/src/overlay/overlay.ts | 16 +++++++------ .../__tests__/dockview/defaultTab.spec.tsx | 4 ++-- packages/dockview/src/dockview/defaultTab.tsx | 4 ++-- 10 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/components/tab/defaultTab.spec.ts b/packages/dockview-core/src/__tests__/dockview/components/tab/defaultTab.spec.ts index 291cf4712..2189282dd 100644 --- a/packages/dockview-core/src/__tests__/dockview/components/tab/defaultTab.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/components/tab/defaultTab.spec.ts @@ -54,7 +54,7 @@ describe('defaultTab', () => { let el = cut.element.querySelector('.dv-default-tab-action'); - fireEvent.mouseDown(el!); + fireEvent.pointerDown(el!); expect(api.close).toHaveBeenCalledTimes(0); fireEvent.click(el!); diff --git a/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts b/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts index bdcc370ee..7681e70ee 100644 --- a/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts @@ -459,6 +459,7 @@ describe('tabsContainer', () => { onDidRemovePanel: jest.fn(), element: document.createElement('div'), addFloatingGroup: jest.fn(), + doSetGroupActive: jest.fn(), }); const groupPanelMock = jest.fn(() => { @@ -486,10 +487,11 @@ describe('tabsContainer', () => { return { top: 10, left: 20, width: 0, height: 0 } as any; }); - const event = new KeyboardEvent('mousedown', { shiftKey: true }); + const event = new KeyboardEvent('pointerdown', { shiftKey: true }); const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault'); fireEvent(container, event); + expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel); expect(accessor.addFloatingGroup).toHaveBeenCalledWith(groupPanel, { x: 100, y: 60, @@ -498,7 +500,7 @@ describe('tabsContainer', () => { expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1); expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(1); - const event2 = new KeyboardEvent('mousedown', { shiftKey: false }); + const event2 = new KeyboardEvent('pointerdown', { shiftKey: false }); const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault'); fireEvent(container, event2); @@ -513,6 +515,7 @@ describe('tabsContainer', () => { onDidRemovePanel: jest.fn(), element: document.createElement('div'), addFloatingGroup: jest.fn(), + doSetGroupActive: jest.fn(), }); const groupPanelMock = jest.fn(() => { @@ -540,14 +543,15 @@ describe('tabsContainer', () => { return { top: 10, left: 20, width: 0, height: 0 } as any; }); - const event = new KeyboardEvent('mousedown', { shiftKey: true }); + const event = new KeyboardEvent('pointerdown', { shiftKey: true }); const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault'); fireEvent(container, event); + expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel); expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(0); expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(0); - const event2 = new KeyboardEvent('mousedown', { shiftKey: false }); + const event2 = new KeyboardEvent('pointerdown', { shiftKey: false }); const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault'); fireEvent(container, event2); @@ -595,7 +599,7 @@ describe('tabsContainer', () => { const el = cut.element.querySelector('.tab')!; expect(el).toBeTruthy(); - const event = new KeyboardEvent('mousedown', { shiftKey: true }); + const event = new KeyboardEvent('pointerdown', { shiftKey: true }); const preventDefaultSpy = jest.spyOn(event, 'preventDefault'); fireEvent(el, event); diff --git a/packages/dockview-core/src/__tests__/events.spec.ts b/packages/dockview-core/src/__tests__/events.spec.ts index af05c3f28..461b1518e 100644 --- a/packages/dockview-core/src/__tests__/events.spec.ts +++ b/packages/dockview-core/src/__tests__/events.spec.ts @@ -153,14 +153,14 @@ describe('events', () => { const disposable = addDisposableWindowListener( element as any, - 'mousedown', + 'pointerdown', handler, true ); expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toHaveBeenCalledWith( - 'mousedown', + 'pointerdown', handler, true ); @@ -171,7 +171,7 @@ describe('events', () => { expect(element.addEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledWith( - 'mousedown', + 'pointerdown', handler, true ); @@ -187,13 +187,13 @@ describe('events', () => { const disposable = addDisposableWindowListener( element as any, - 'mousedown', + 'pointerdown', handler ); expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toHaveBeenCalledWith( - 'mousedown', + 'pointerdown', handler, undefined ); @@ -204,7 +204,7 @@ describe('events', () => { expect(element.addEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledWith( - 'mousedown', + 'pointerdown', handler, undefined ); @@ -220,14 +220,14 @@ describe('events', () => { const disposable = addDisposableListener( element as any, - 'mousedown', + 'pointerdown', handler, true ); expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toHaveBeenCalledWith( - 'mousedown', + 'pointerdown', handler, true ); @@ -238,7 +238,7 @@ describe('events', () => { expect(element.addEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledWith( - 'mousedown', + 'pointerdown', handler, true ); @@ -254,13 +254,13 @@ describe('events', () => { const disposable = addDisposableListener( element as any, - 'mousedown', + 'pointerdown', handler ); expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toHaveBeenCalledWith( - 'mousedown', + 'pointerdown', handler, undefined ); @@ -271,7 +271,7 @@ describe('events', () => { expect(element.addEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledWith( - 'mousedown', + 'pointerdown', handler, undefined ); diff --git a/packages/dockview-core/src/dnd/groupDragHandler.ts b/packages/dockview-core/src/dnd/groupDragHandler.ts index 7138437bf..bdda2be3b 100644 --- a/packages/dockview-core/src/dnd/groupDragHandler.ts +++ b/packages/dockview-core/src/dnd/groupDragHandler.ts @@ -21,7 +21,7 @@ export class GroupDragHandler extends DragHandler { this.addDisposables( addDisposableListener( element, - 'mousedown', + 'pointerdown', (e) => { if (e.shiftKey) { /** diff --git a/packages/dockview-core/src/dockview/components/tab/defaultTab.ts b/packages/dockview-core/src/dockview/components/tab/defaultTab.ts index 8b927a105..af86ee35b 100644 --- a/packages/dockview-core/src/dockview/components/tab/defaultTab.ts +++ b/packages/dockview-core/src/dockview/components/tab/defaultTab.ts @@ -30,7 +30,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer { this._element.appendChild(this.action); this.addDisposables( - addDisposableListener(this.action, 'mousedown', (ev) => { + addDisposableListener(this.action, 'pointerdown', (ev) => { ev.preventDefault(); }) ); @@ -46,7 +46,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer { this._title = event.title; this.render(); }), - addDisposableListener(this.action, 'mousedown', (ev) => { + addDisposableListener(this.action, 'pointerdown', (ev) => { ev.preventDefault(); }), addDisposableListener(this.action, 'click', (ev) => { diff --git a/packages/dockview-core/src/dockview/components/tab/tab.ts b/packages/dockview-core/src/dockview/components/tab/tab.ts index c97f1f110..69094e92e 100644 --- a/packages/dockview-core/src/dockview/components/tab/tab.ts +++ b/packages/dockview-core/src/dockview/components/tab/tab.ts @@ -124,7 +124,7 @@ export class Tab extends CompositeDisposable { this._onDragStart.fire(event); }), dragHandler, - addDisposableListener(this._element, 'mousedown', (event) => { + addDisposableListener(this._element, 'pointerdown', (event) => { if (event.defaultPrevented) { return; } diff --git a/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts b/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts index 7557f3fde..f856d03df 100644 --- a/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts +++ b/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts @@ -253,7 +253,7 @@ export class TabsContainer }), addDisposableListener( this.voidContainer.element, - 'mousedown', + 'pointerdown', (event) => { const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups; @@ -278,7 +278,7 @@ export class TabsContainer } } ), - addDisposableListener(this.tabContainer, 'mousedown', (event) => { + addDisposableListener(this.tabContainer, 'pointerdown', (event) => { if (event.defaultPrevented) { return; } diff --git a/packages/dockview-core/src/overlay/overlay.ts b/packages/dockview-core/src/overlay/overlay.ts index 0f39961ce..bcc0ac3a2 100644 --- a/packages/dockview-core/src/overlay/overlay.ts +++ b/packages/dockview-core/src/overlay/overlay.ts @@ -37,7 +37,9 @@ class AriaLevelTracker { private update(): void { for (let i = 0; i < this._orderedList.length; i++) { this._orderedList[i].setAttribute('aria-level', `${i}`); - this._orderedList[i].style.zIndex = `${DEFAULT_OVERLAY_Z_INDEX + i * 2}`; + this._orderedList[i].style.zIndex = `${ + DEFAULT_OVERLAY_Z_INDEX + i * 2 + }`; } } } @@ -241,7 +243,7 @@ export class Overlay extends CompositeDisposable { iframes.release(); }, }, - addDisposableWindowListener(window, 'mousemove', (e) => { + addDisposableWindowListener(window, 'pointermove', (e) => { const containerRect = this.options.container.getBoundingClientRect(); const x = e.clientX - containerRect.left; @@ -342,7 +344,7 @@ export class Overlay extends CompositeDisposable { this.addDisposables( move, - addDisposableListener(dragTarget, 'mousedown', (event) => { + addDisposableListener(dragTarget, 'pointerdown', (event) => { if (event.defaultPrevented) { event.preventDefault(); return; @@ -358,7 +360,7 @@ export class Overlay extends CompositeDisposable { }), addDisposableListener( this.options.content, - 'mousedown', + 'pointerdown', (event) => { if (event.defaultPrevented) { return; @@ -377,7 +379,7 @@ export class Overlay extends CompositeDisposable { ), addDisposableListener( this.options.content, - 'mousedown', + 'pointerdown', () => { arialLevelTracker.push(this._element); }, @@ -409,7 +411,7 @@ export class Overlay extends CompositeDisposable { this.addDisposables( move, - addDisposableListener(resizeHandleElement, 'mousedown', (e) => { + addDisposableListener(resizeHandleElement, 'pointerdown', (e) => { e.preventDefault(); let startPosition: { @@ -422,7 +424,7 @@ export class Overlay extends CompositeDisposable { const iframes = disableIframePointEvents(); move.value = new CompositeDisposable( - addDisposableWindowListener(window, 'mousemove', (e) => { + addDisposableWindowListener(window, 'pointermove', (e) => { const containerRect = this.options.container.getBoundingClientRect(); const overlayRect = diff --git a/packages/dockview/src/__tests__/dockview/defaultTab.spec.tsx b/packages/dockview/src/__tests__/dockview/defaultTab.spec.tsx index d5fb32c7d..427e9650e 100644 --- a/packages/dockview/src/__tests__/dockview/defaultTab.spec.tsx +++ b/packages/dockview/src/__tests__/dockview/defaultTab.spec.tsx @@ -176,7 +176,7 @@ describe('defaultTab', () => { expect(element.querySelector('.dv-default-tab-action')).toBeTruthy(); }); - test('that mouseDown on close button prevents panel becoming active', async () => { + test('that pointerDown on close button prevents panel becoming active', async () => { const api = fromPartial({ setActive: jest.fn(), onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE), @@ -197,7 +197,7 @@ describe('defaultTab', () => { '.dv-default-tab-action' ) as HTMLElement; - fireEvent.mouseDown(btn); + fireEvent.pointerDown(btn); expect(api.setActive).toHaveBeenCalledTimes(0); fireEvent.click(element); diff --git a/packages/dockview/src/dockview/defaultTab.tsx b/packages/dockview/src/dockview/defaultTab.tsx index 56c3a6793..f1586fa83 100644 --- a/packages/dockview/src/dockview/defaultTab.tsx +++ b/packages/dockview/src/dockview/defaultTab.tsx @@ -49,7 +49,7 @@ export const DockviewDefaultTab: React.FunctionComponent< [api, closeActionOverride] ); - const onMouseDown = React.useCallback((e: React.MouseEvent) => { + const onPointerDown = React.useCallback((e: React.MouseEvent) => { e.preventDefault(); }, []); @@ -79,7 +79,7 @@ export const DockviewDefaultTab: React.FunctionComponent< {!hideClose && (

From 72f457ab9def66eef7ce6c79314fdbe73072f7dc Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:21:52 +0100 Subject: [PATCH 08/24] feat: panel initial sizing --- .../dockview/dockviewComponent.spec.ts | 18 ++++++-- .../src/dockview/dockviewComponent.ts | 43 +++++++++++++++++-- .../src/dockview/dockviewGroupPanel.ts | 36 +++++++--------- .../dockview-core/src/dockview/options.ts | 2 + 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index ae45adf8f..e38896f5a 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -8,7 +8,7 @@ import { PanelUpdateEvent } from '../../panel/types'; import { Orientation } from '../../splitview/splitview'; import { CompositeDisposable } from '../../lifecycle'; import { Emitter } from '../../events'; -import { IDockviewPanel } from '../../dockview/dockviewPanel'; +import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { fireEvent, queryByTestId } from '@testing-library/dom'; import { getPanelData } from '../../dnd/dataTransfer'; @@ -626,6 +626,7 @@ describe('dockviewComponent', () => { panel1: { id: 'panel1', contentComponent: 'default', + tabComponent: 'tab-default', title: 'panel1', }, panel2: { @@ -637,22 +638,26 @@ describe('dockviewComponent', () => { id: 'panel3', contentComponent: 'default', title: 'panel3', + renderer: 'onlyWhenVisible', }, panel4: { id: 'panel4', contentComponent: 'default', title: 'panel4', + renderer: 'always', }, panel5: { id: 'panel5', contentComponent: 'default', title: 'panel5', + minimumHeight: 100, + maximumHeight: 1000, + minimumWidth: 200, + maximumWidth: 2000, }, }, }); - // dockview.layout(1000, 1000, true); - expect(JSON.parse(JSON.stringify(dockview.toJSON()))).toEqual({ activeGroup: 'group-1', grid: { @@ -712,6 +717,7 @@ describe('dockviewComponent', () => { panel1: { id: 'panel1', contentComponent: 'default', + tabComponent: 'tab-default', title: 'panel1', }, panel2: { @@ -723,16 +729,22 @@ describe('dockviewComponent', () => { id: 'panel3', contentComponent: 'default', title: 'panel3', + renderer: 'onlyWhenVisible', }, panel4: { id: 'panel4', contentComponent: 'default', title: 'panel4', + renderer: 'always', }, panel5: { id: 'panel5', contentComponent: 'default', title: 'panel5', + minimumHeight: 100, + maximumHeight: 1000, + minimumWidth: 200, + maximumWidth: 2000, }, }, }); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 517f7c8b1..24c7093cd 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -3,6 +3,7 @@ import { SerializedGridObject, getGridLocation, ISerializedLeafNode, + orthogonal, } from '../gridview/gridview'; import { directionToPosition, @@ -1371,6 +1372,11 @@ export class DockviewComponent ); } + const initial = { + width: options.initialWidth, + height: options.initialHeight, + }; + if (options.position) { if (isPanelOptionsWithPanel(options.position)) { const referencePanel = @@ -1412,6 +1418,11 @@ export class DockviewComponent this.doSetGroupAndPanelActive(group); } + group.api.setSize({ + height: initial?.height, + width: initial?.width, + }); + return panel; } } else { @@ -1458,6 +1469,11 @@ export class DockviewComponent skipSetGroupActive: options.inactive, }); + referenceGroup.api.setSize({ + width: initial?.width, + height: initial?.height, + }); + if (!options.inactive) { this.doSetGroupAndPanelActive(referenceGroup); } @@ -1468,7 +1484,13 @@ export class DockviewComponent location, target ); - const group = this.createGroupAtLocation(relativeLocation); + const group = this.createGroupAtLocation( + relativeLocation, + this.orientationAtLocation(relativeLocation) === + Orientation.VERTICAL + ? initial?.height + : initial?.width + ); panel = this.createPanel(options, group); group.model.openPanel(panel, { skipSetActive: options.inactive, @@ -1502,7 +1524,12 @@ export class DockviewComponent skipSetGroupActive: options.inactive, }); } else { - const group = this.createGroupAtLocation(); + const group = this.createGroupAtLocation( + [0], + this.gridview.orientation === Orientation.VERTICAL + ? initial?.height + : initial?.width + ); panel = this.createPanel(options, group); group.model.openPanel(panel, { skipSetActive: options.inactive, @@ -2272,10 +2299,11 @@ export class DockviewComponent } private createGroupAtLocation( - location: number[] = [0] + location: number[], + size?: number ): DockviewGroupPanel { const group = this.createGroup(); - this.doAddGroup(group, location); + this.doAddGroup(group, location, size); return group; } @@ -2284,4 +2312,11 @@ export class DockviewComponent group.value.model.containsPanel(panel) )?.value; } + + private orientationAtLocation(location: number[]) { + const rootOrientation = this.gridview.orientation; + return location.length % 2 == 1 + ? rootOrientation + : orthogonal(rootOrientation); + } } diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts index 5edd14393..4efee9cd6 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts @@ -35,35 +35,31 @@ export class DockviewGroupPanel private readonly _model: DockviewGroupPanelModel; get minimumWidth(): number { - const sizes = this.panels - .filter((panel) => typeof panel.minimumWidth === 'number') - .map((panel) => panel.minimumWidth) as number[]; - - return sizes.length > 0 ? Math.max(...sizes) : 100; + const activePanelMinimumWidth = this.activePanel?.minimumWidth; + return typeof activePanelMinimumWidth === 'number' + ? activePanelMinimumWidth + : MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH; } get minimumHeight(): number { - const sizes = this.panels - .filter((panel) => typeof panel.minimumHeight === 'number') - .map((panel) => panel.minimumHeight) as number[]; - - return sizes.length > 0 ? Math.max(...sizes) : 100; + const activePanelMinimumHeight = this.activePanel?.minimumHeight; + return typeof activePanelMinimumHeight === 'number' + ? activePanelMinimumHeight + : MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT; } get maximumWidth(): number { - const sizes = this.panels - .filter((panel) => typeof panel.maximumWidth === 'number') - .map((panel) => panel.maximumWidth) as number[]; - - return sizes.length > 0 ? Math.min(...sizes) : Number.MAX_SAFE_INTEGER; + const activePanelMaximumWidth = this.activePanel?.maximumWidth; + return typeof activePanelMaximumWidth === 'number' + ? activePanelMaximumWidth + : Number.MAX_SAFE_INTEGER; } get maximumHeight(): number { - const sizes = this.panels - .filter((panel) => typeof panel.maximumHeight === 'number') - .map((panel) => panel.maximumHeight) as number[]; - - return sizes.length > 0 ? Math.min(...sizes) : Number.MAX_SAFE_INTEGER; + const activePanelMaximumHeight = this.activePanel?.maximumHeight; + return typeof activePanelMaximumHeight === 'number' + ? activePanelMaximumHeight + : Number.MAX_SAFE_INTEGER; } get panels(): IDockviewPanel[] { diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index bf3235b60..561a732f4 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -238,6 +238,8 @@ export type AddPanelOptions

= { * Defaults to `false` which forces newly added panels to become active. */ inactive?: boolean; + initialWidth?: number; + initialHeight?: number; } & Partial & Partial; From e2e91834ff5aee0e0400e7a5556ac400db1dba1e Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:28:39 +0100 Subject: [PATCH 09/24] feat: retain size when moving groups --- .../dockview/dockviewComponent.spec.ts | 108 +++++++++++++++++- .../src/dockview/dockviewComponent.ts | 19 ++- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index ae45adf8f..0d8d258c1 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -8,7 +8,7 @@ import { PanelUpdateEvent } from '../../panel/types'; import { Orientation } from '../../splitview/splitview'; import { CompositeDisposable } from '../../lifecycle'; import { Emitter } from '../../events'; -import { IDockviewPanel } from '../../dockview/dockviewPanel'; +import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { fireEvent, queryByTestId } from '@testing-library/dom'; import { getPanelData } from '../../dnd/dataTransfer'; @@ -262,6 +262,112 @@ describe('dockviewComponent', () => { dockview.dispose(); }); + describe('move group', () => { + test('horizontal', () => { + dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + dockview.layout(600, 1000); + + const panel1 = dockview.addPanel({ + id: 'panel1', + component: 'default', + }); + const panel2 = dockview.addPanel({ + id: 'panel2', + component: 'default', + position: { direction: 'right' }, + }); + const panel3 = dockview.addPanel({ + id: 'panel3', + component: 'default', + position: { direction: 'right' }, + }); + + expect(panel1.api.width).toBe(200); + expect(panel2.api.width).toBe(200); + expect(panel3.api.width).toBe(200); + + panel3.api.setSize({ width: 300 }); + + expect(panel1.api.width).toBe(200); + expect(panel2.api.width).toBe(100); + expect(panel3.api.width).toBe(300); + + dockview.moveGroup({ + from: { group: panel3.api.group }, + to: { group: panel1.api.group, position: 'right' }, + }); + + expect(panel1.api.width).toBe(200); + expect(panel2.api.width).toBe(100); + expect(panel3.api.width).toBe(300); + }); + + test('vertical', () => { + dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + dockview.layout(1000, 600); + + const panel1 = dockview.addPanel({ + id: 'panel1', + component: 'default', + }); + const panel2 = dockview.addPanel({ + id: 'panel2', + component: 'default', + position: { direction: 'below' }, + }); + const panel3 = dockview.addPanel({ + id: 'panel3', + component: 'default', + position: { direction: 'below' }, + }); + + expect(panel1.api.height).toBe(200); + expect(panel2.api.height).toBe(200); + expect(panel3.api.height).toBe(200); + + panel3.api.setSize({ height: 300 }); + + expect(panel1.api.height).toBe(200); + expect(panel2.api.height).toBe(100); + expect(panel3.api.height).toBe(300); + + dockview.moveGroup({ + from: { group: panel3.api.group }, + to: { group: panel1.api.group, position: 'bottom' }, + }); + + expect(panel1.api.height).toBe(200); + expect(panel2.api.height).toBe(100); + expect(panel3.api.height).toBe(300); + }); + }); + test('set active panel', () => { dockview.layout(500, 1000); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 2a72db7fe..4aac7e1ed 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -2068,7 +2068,24 @@ export class DockviewComponent target ); - this.gridview.addView(from, Sizing.Distribute, dropLocation); + let size: number; + + switch (this.gridview.orientation) { + case Orientation.VERTICAL: + size = + referenceLocation.length % 2 == 0 + ? from.api.width + : from.api.height; + break; + case Orientation.HORIZONTAL: + size = + referenceLocation.length % 2 == 0 + ? from.api.height + : from.api.width; + break; + } + + this.gridview.addView(from, size, dropLocation); } from.panels.forEach((panel) => { From ab5a11f13b973e7bb9023a884ab0ce389af4e058 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Wed, 28 Aug 2024 21:53:08 +0100 Subject: [PATCH 10/24] chore: docs --- packages/docs/docs/advanced/events.mdx | 12 - packages/docs/docs/core/dnd/external.mdx | 18 +- packages/docs/docs/core/overview.mdx | 9 + packages/docs/docs/core/panels/register.mdx | 33 +- packages/docs/docs/core/watermark.mdx | 2 +- .../docs/overview/getStarted/installation.mdx | 2 +- .../docs/docs/overview/getStarted/theme.mdx | 7 +- .../sandboxes/iframe-dockview/src/app.tsx | 24 +- .../react/dockview/demo-dockview/src/app.scss | 60 +- .../react/dockview/demo-dockview/src/app.tsx | 44 +- .../demo-dockview/src/gridActions.tsx | 130 ++++- .../demo-dockview/src/groupActions.tsx | 10 +- .../demo-dockview/src/panelBuilder.tsx | 115 ++++ .../docs/src/components/frameworkSpecific.tsx | 2 +- packages/docs/src/generated/api.output.json | 547 ++++++++++++++---- .../dockview/demo-dockview/react/src/app.tsx | 7 +- .../dockview/watermark/react/src/app.tsx | 3 +- .../watermark/typescript/src/index.ts | 135 +++++ 18 files changed, 955 insertions(+), 205 deletions(-) delete mode 100644 packages/docs/docs/advanced/events.mdx create mode 100644 packages/docs/sandboxes/react/dockview/demo-dockview/src/panelBuilder.tsx create mode 100644 packages/docs/templates/dockview/watermark/typescript/src/index.ts diff --git a/packages/docs/docs/advanced/events.mdx b/packages/docs/docs/advanced/events.mdx deleted file mode 100644 index e4edada93..000000000 --- a/packages/docs/docs/advanced/events.mdx +++ /dev/null @@ -1,12 +0,0 @@ -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import EventsDockview from '@site/sandboxes/events-dockview/src/app'; - -# Events - -A simple example showing events fired by `dockviewz that can be interacted with. - - diff --git a/packages/docs/docs/core/dnd/external.mdx b/packages/docs/docs/core/dnd/external.mdx index 7e80d2dc7..7264446a1 100644 --- a/packages/docs/docs/core/dnd/external.mdx +++ b/packages/docs/docs/core/dnd/external.mdx @@ -9,25 +9,9 @@ import { DocRef } from '@site/src/components/ui/reference/docRef'; import LiveExample from '@site/src/components/ui/exampleFrame'; - - - - - - - - - - - - - - ## Intercepting Drag Events You can intercept drag events to attach your own metadata using the `onWillDragPanel` and `onWillDragGroup` api methods. diff --git a/packages/docs/docs/core/overview.mdx b/packages/docs/docs/core/overview.mdx index abedc5738..f3cf26628 100644 --- a/packages/docs/docs/core/overview.mdx +++ b/packages/docs/docs/core/overview.mdx @@ -8,6 +8,15 @@ This section provided a core overview. The component takes a collection of [Options](/docs/api/dockview/options) as inputs and once you have created a dock you can store a reference to the [API](/docs/api/dockview/overview) that is created. + + +```tsx +const element: HTMLElement +const options: DockviewComponentOptions +const api: DockviewApi = createDockview(element, options); +``` + + ```tsx function onReady(event: DockviewReadyEvent) { diff --git a/packages/docs/docs/core/panels/register.mdx b/packages/docs/docs/core/panels/register.mdx index 0b3b834be..5f90c7bb5 100644 --- a/packages/docs/docs/core/panels/register.mdx +++ b/packages/docs/docs/core/panels/register.mdx @@ -20,7 +20,7 @@ You can register panels through the dock [option](/docs/api/dockview/options) ` - + @@ -44,6 +44,37 @@ return + +```tsx +class Panel implements IContentRenderer { + private readonly _element: HTMLElement; + + get element(): HTMLElement { + return this._element; + } + + constructor() { + this._element = document.createElement('div'); + } + + init(parameters: GroupPanelPartInitParameters): void { + // + } +} + + +const api = createDockview(parentElement, { + createComponent: (options) => { + switch (options.name) { + case 'component_1': + return new Panel(); + } + }, +}); +``` + + + ```tsx const App = { diff --git a/packages/docs/docs/core/watermark.mdx b/packages/docs/docs/core/watermark.mdx index 7c8549ff3..e2416a6d8 100644 --- a/packages/docs/docs/core/watermark.mdx +++ b/packages/docs/docs/core/watermark.mdx @@ -25,7 +25,7 @@ The following properties can be set to configure the behaviours of floating grou diff --git a/packages/docs/docs/overview/getStarted/installation.mdx b/packages/docs/docs/overview/getStarted/installation.mdx index 4503011d6..2f0e97935 100644 --- a/packages/docs/docs/overview/getStarted/installation.mdx +++ b/packages/docs/docs/overview/getStarted/installation.mdx @@ -18,7 +18,7 @@ npm install dockview-core Firstly, install the `dockview` library: ```sh -npm install dockview +npm install dockview-react ``` diff --git a/packages/docs/docs/overview/getStarted/theme.mdx b/packages/docs/docs/overview/getStarted/theme.mdx index 06e9189c3..2e89eefe6 100644 --- a/packages/docs/docs/overview/getStarted/theme.mdx +++ b/packages/docs/docs/overview/getStarted/theme.mdx @@ -19,10 +19,15 @@ Firstly, you should import `dockview.css`: ```css -@import './node_modules/dockview/dist/styles/dockview.css'; +@import './node_modules/dockview-react/dist/styles/dockview.css'; ``` + +```css +@import './node_modules/dockview-vue/dist/styles/dockview.css'; +``` + ## Provided themes diff --git a/packages/docs/sandboxes/iframe-dockview/src/app.tsx b/packages/docs/sandboxes/iframe-dockview/src/app.tsx index 5a6587484..5e2b1a882 100644 --- a/packages/docs/sandboxes/iframe-dockview/src/app.tsx +++ b/packages/docs/sandboxes/iframe-dockview/src/app.tsx @@ -1,13 +1,33 @@ -import { DockviewReact, DockviewReadyEvent } from 'dockview'; +import { + DockviewReact, + DockviewReadyEvent, + IDockviewPanelProps, +} from 'dockview'; import * as React from 'react'; const components = { - iframeComponent: () => { + iframeComponent: (props: IDockviewPanelProps) => { + const [enabled, setEnabled] = React.useState( + props.api.isActive + ); + + React.useEffect(() => { + const disposable = props.api.onDidActiveChange((event) => { + setEnabled(event.isActive); + console.log(event); + }); + + return () => { + disposable.dispose(); + }; + }, [props.api]); + return (