diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index 0d8d258c1..44379aa61 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -732,6 +732,7 @@ describe('dockviewComponent', () => { panel1: { id: 'panel1', contentComponent: 'default', + tabComponent: 'tab-default', title: 'panel1', }, panel2: { @@ -743,22 +744,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: { @@ -818,6 +823,7 @@ describe('dockviewComponent', () => { panel1: { id: 'panel1', contentComponent: 'default', + tabComponent: 'tab-default', title: 'panel1', }, panel2: { @@ -829,16 +835,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/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 4aac7e1ed..7a511ec67 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, @@ -1640,7 +1667,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 +1686,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?: @@ -2259,7 +2298,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({ @@ -2271,10 +2316,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; } @@ -2283,4 +2329,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 6f01fae5f..4efee9cd6 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts @@ -34,6 +34,34 @@ export class DockviewGroupPanel { private readonly _model: DockviewGroupPanelModel; + get minimumWidth(): number { + const activePanelMinimumWidth = this.activePanel?.minimumWidth; + return typeof activePanelMinimumWidth === 'number' + ? activePanelMinimumWidth + : MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH; + } + + get minimumHeight(): number { + const activePanelMinimumHeight = this.activePanel?.minimumHeight; + return typeof activePanelMinimumHeight === 'number' + ? activePanelMinimumHeight + : MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT; + } + + get maximumWidth(): number { + const activePanelMaximumWidth = this.activePanel?.maximumWidth; + return typeof activePanelMaximumWidth === 'number' + ? activePanelMaximumWidth + : Number.MAX_SAFE_INTEGER; + } + + get maximumHeight(): number { + const activePanelMaximumHeight = this.activePanel?.maximumHeight; + return typeof activePanelMaximumHeight === 'number' + ? activePanelMaximumHeight + : Number.MAX_SAFE_INTEGER; + } + get panels(): IDockviewPanel[] { return this._model.panels; } @@ -71,8 +99,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..1d02d4d33 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,9 @@ interface CoreGroupOptions { locked?: DockviewGroupPanelLocked; hideHeader?: boolean; skipSetActive?: boolean; + constraints?: Partial; + initialWidth?: number; + initialHeight?: number; } 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..561a732f4 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,10 @@ export type AddPanelOptions

= { * Defaults to `false` which forces newly added panels to become active. */ inactive?: boolean; -} & Partial; + initialWidth?: number; + initialHeight?: number; +} & 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;