diff --git a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts index 8b075d620..c4b349bdf 100644 --- a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts @@ -1,4 +1,4 @@ -import { Position } from '../dnd/droptarget'; +import { Position, positionToDirection } from '../dnd/droptarget'; import { DockviewComponent } from '../dockview/dockviewComponent'; import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel'; import { DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel'; @@ -6,9 +6,9 @@ import { Emitter, Event } from '../events'; import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi'; export interface DockviewGroupPanelApi extends GridviewPanelApi { - readonly onDidRenderPositionChange: Event; + readonly onDidLocationChange: Event; readonly location: DockviewGroupLocation; - moveTo(options: { group: DockviewGroupPanel; position?: Position }): void; + moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void; maximize(): void; isMaximized(): boolean; exitMaximized(): void; @@ -24,10 +24,10 @@ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized'; export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { private _group: DockviewGroupPanel | undefined; - readonly _onDidRenderPositionChange = + readonly _onDidLocationChange = new Emitter(); - readonly onDidRenderPositionChange: Event = - this._onDidRenderPositionChange.event; + readonly onDidLocationChange: Event = + this._onDidLocationChange.event; get location(): DockviewGroupLocation { if (!this._group) { @@ -39,19 +39,25 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { constructor(id: string, private readonly accessor: DockviewComponent) { super(id); - this.addDisposables(this._onDidRenderPositionChange); + this.addDisposables(this._onDidLocationChange); } - moveTo(options: { group: DockviewGroupPanel; position?: Position }): void { + moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void { if (!this._group) { throw new Error(NOT_INITIALIZED_MESSAGE); } + const group = + options.group ?? + this.accessor.addGroup({ + direction: positionToDirection(options.position ?? 'right'), + }); + this.accessor.moveGroupOrPanel( - options.group, + group, this._group.id, undefined, - options.position ?? 'center' + options.group ? options.position ?? 'center' : 'center' ); } @@ -60,6 +66,11 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { throw new Error(NOT_INITIALIZED_MESSAGE); } + if (this.location !== 'grid') { + // only grid groups can be maximized + return; + } + this.accessor.maximizeGroup(this._group); } diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index 69c1c0abc..4f2c0f9ad 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -283,7 +283,7 @@ export class DockviewGroupPanelModel break; } - this.groupPanel.api._onDidRenderPositionChange.fire({ + this.groupPanel.api._onDidLocationChange.fire({ location: this.location, }); } diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx index bdb44f01a..84f07bf4c 100644 --- a/packages/docs/docs/components/dockview.mdx +++ b/packages/docs/docs/components/dockview.mdx @@ -389,6 +389,17 @@ From within a panel you may say props.containerApi.addPopoutGroup(props.api.group); ``` +To programatically move the popout group back into the main grid you can use the `moveTo` method in many ways, one of the following would suffice + +```tsx +// option 1: add absolutely to the right-side of the grid +props.group.api.moveTo({position: 'right'}); + +// option 2: create a new group and move the contents of the popout group to it +const group = props.containerApi.addGroup(); +props.group.api.moveTo({ group }); +``` + = { panel_1: () => { return ; }, @@ -130,6 +130,10 @@ const RightControls = (props: IDockviewHeaderActionsProps) => { : 'expand_content' ); + const [popoutIcon, setPopoutIcon] = React.useState( + props.api.location === 'popout' ? 'close_fullscreen' : 'open_in_new' + ); + React.useEffect(() => { const disposable = props.containerApi.onDidMaxmizedGroupChange(() => { setIcon( @@ -139,8 +143,17 @@ const RightControls = (props: IDockviewHeaderActionsProps) => { ); }); + const disposable2 = props.api.onDidLocationChange(() => { + setPopoutIcon( + props.api.location === 'popout' + ? 'close_fullscreen' + : 'open_in_new' + ); + }); + return () => { disposable.dispose(); + disposable2.dispose(); }; }, [props.containerApi]); @@ -152,6 +165,14 @@ const RightControls = (props: IDockviewHeaderActionsProps) => { } }; + const onClick2 = () => { + if (props.api.location !== 'popout') { + props.containerApi.addPopoutGroup(props.group); + } else { + props.api.moveTo({ position: 'right' }); + } + }; + return (
{ > {props.isGroupActive && } {Component && } +
); diff --git a/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx b/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx index d90e8c5ff..990913d2e 100644 --- a/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx +++ b/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx @@ -259,7 +259,7 @@ const RightComponent = (props: IDockviewHeaderActionsProps) => { ); React.useEffect(() => { - const disposable = props.group.api.onDidRenderPositionChange( + const disposable = props.group.api.onDidLocationChange( (event) => { setFloating(event.location === 'floating'); } diff --git a/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx b/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx index 1d16e0029..6a05cf811 100644 --- a/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx +++ b/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx @@ -218,7 +218,7 @@ const RightComponent = (props: IDockviewHeaderActionsProps) => { ); React.useEffect(() => { - const disposable = props.group.api.onDidRenderPositionChange( + const disposable = props.group.api.onDidLocationChange( (event) => [setPopout(event.location === 'popout')] );