Skip to content

Commit

Permalink
feat: popout groups
Browse files Browse the repository at this point in the history
  • Loading branch information
mathuo committed Jan 8, 2024
1 parent aa6eb27 commit 105be36
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 14 deletions.
31 changes: 21 additions & 10 deletions packages/dockview-core/src/api/dockviewGroupPanelApi.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
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';
import { Emitter, Event } from '../events';
import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi';

export interface DockviewGroupPanelApi extends GridviewPanelApi {
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly location: DockviewGroupLocation;
moveTo(options: { group: DockviewGroupPanel; position?: Position }): void;
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void;
maximize(): void;
isMaximized(): boolean;
exitMaximized(): void;
Expand All @@ -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<DockviewGroupPanelFloatingChangeEvent>();
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent> =
this._onDidRenderPositionChange.event;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent> =
this._onDidLocationChange.event;

get location(): DockviewGroupLocation {
if (!this._group) {
Expand All @@ -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'
);
}

Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ export class DockviewGroupPanelModel
break;
}

this.groupPanel.api._onDidRenderPositionChange.fire({
this.groupPanel.api._onDidLocationChange.fire({
location: this.location,
});
}
Expand Down
11 changes: 11 additions & 0 deletions packages/docs/docs/components/dockview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
```

<MultiFrameworkContainer
height={600}
sandboxId="popoutgroup-dockview"
Expand Down
24 changes: 23 additions & 1 deletion packages/docs/sandboxes/demo-dockview/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const Icon = (props: {
);
};

const groupControlsComponents = {
const groupControlsComponents: Record<string, React.FC> = {
panel_1: () => {
return <Icon icon="file_download" />;
},
Expand All @@ -130,6 +130,10 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
: 'expand_content'
);

const [popoutIcon, setPopoutIcon] = React.useState<string>(
props.api.location === 'popout' ? 'close_fullscreen' : 'open_in_new'
);

React.useEffect(() => {
const disposable = props.containerApi.onDidMaxmizedGroupChange(() => {
setIcon(
Expand All @@ -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]);

Expand All @@ -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 (
<div
className="group-control"
Expand All @@ -165,6 +186,7 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
>
{props.isGroupActive && <Icon icon="star" />}
{Component && <Component />}
<Icon icon={popoutIcon} onClick={onClick2} />
<Icon icon={icon} onClick={onClick} />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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')]
);

Expand Down

0 comments on commit 105be36

Please sign in to comment.