Merge pull request #264 from mathuo/263-left-header-actions

feat: add left header actions
This commit is contained in:
mathuo 2023-06-21 20:09:51 +01:00 committed by GitHub
commit e0f167050c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 335 additions and 102 deletions

View File

@ -1,14 +1,14 @@
import { fireEvent } from '@testing-library/dom';
import { Emitter, Event } from '../../../events';
import { ContentContainer } from '../../../dockview/components/panel/content';
import { Emitter, Event } from '../../../../events';
import { ContentContainer } from '../../../../dockview/components/panel/content';
import {
GroupPanelContentPartInitParameters,
IContentRenderer,
} from '../../../dockview/types';
import { CompositeDisposable } from '../../../lifecycle';
import { PanelUpdateEvent } from '../../../panel/types';
import { IDockviewPanel } from '../../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../../dockview/dockviewPanelModel';
} from '../../../../dockview/types';
import { CompositeDisposable } from '../../../../lifecycle';
import { PanelUpdateEvent } from '../../../../panel/types';
import { IDockviewPanel } from '../../../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../../../dockview/dockviewPanelModel';
class TestContentRenderer
extends CompositeDisposable

View File

@ -1,9 +1,9 @@
import { fireEvent } from '@testing-library/dom';
import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { DockviewGroupPanelModel } from '../../dockview/dockviewGroupPanelModel';
import { Tab } from '../../dockview/components/tab/tab';
import { LocalSelectionTransfer, PanelTransfer } from '../../../dnd/dataTransfer';
import { DockviewComponent } from '../../../dockview/dockviewComponent';
import { DockviewGroupPanel } from '../../../dockview/dockviewGroupPanel';
import { DockviewGroupPanelModel } from '../../../dockview/dockviewGroupPanelModel';
import { Tab } from '../../../dockview/components/tab/tab';
describe('tab', () => {
test('that empty tab has inactive-tab class', () => {

View File

@ -1,13 +1,13 @@
import { DockviewComponent } from '../../../dockview/dockviewComponent';
import { TabsContainer } from '../../../dockview/components/titlebar/tabsContainer';
import { fireEvent } from '@testing-library/dom';
import {
LocalSelectionTransfer,
PanelTransfer,
} from '../../../dnd/dataTransfer';
import { TestPanel } from '../dockviewGroupPanelModel.spec';
import { DockviewGroupPanelModel } from '../../../dockview/dockviewGroupPanelModel';
import { DockviewGroupPanel } from '../../../dockview/dockviewGroupPanel';
} from '../../../../dnd/dataTransfer';
import { TabsContainer } from '../../../../dockview/components/titlebar/tabsContainer';
import { DockviewComponent } from '../../../../dockview/dockviewComponent';
import { DockviewGroupPanel } from '../../../../dockview/dockviewGroupPanel';
import { DockviewGroupPanelModel } from '../../../../dockview/dockviewGroupPanelModel';
import { fireEvent } from '@testing-library/dom';
import { TestPanel } from '../../dockviewGroupPanelModel.spec';
describe('tabsContainer', () => {
test('that an external event does not render a drop target and calls through to the group mode', () => {
@ -331,4 +331,136 @@ describe('tabsContainer', () => {
cut.element.getElementsByClassName('drop-target-dropzone').length
).toBe(0);
});
test('left actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
}) as DockviewComponent;
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{}) as DockviewGroupPanel;
});
const accessor = new accessorMock();
const groupPanel = new groupPanelMock();
const cut = new TabsContainer(accessor, groupPanel);
let query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .left-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.length).toBe(0);
// add left action
const left = document.createElement('div');
left.className = 'test-left-actions-element';
cut.setLeftActionsElement(left);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .left-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.item(0)?.className).toBe(
'test-left-actions-element'
);
expect(query[0].children.length).toBe(1);
// add left action
const left2 = document.createElement('div');
left2.className = 'test-left-actions-element-2';
cut.setLeftActionsElement(left2);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .left-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.item(0)?.className).toBe(
'test-left-actions-element-2'
);
expect(query[0].children.length).toBe(1);
// remove left action
cut.setLeftActionsElement(undefined);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .left-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.length).toBe(0);
});
test('right actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
}) as DockviewComponent;
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{}) as DockviewGroupPanel;
});
const accessor = new accessorMock();
const groupPanel = new groupPanelMock();
const cut = new TabsContainer(accessor, groupPanel);
let query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .right-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.length).toBe(0);
// add right action
const right = document.createElement('div');
right.className = 'test-right-actions-element';
cut.setRightActionsElement(right);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .right-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.item(0)?.className).toBe(
'test-right-actions-element'
);
expect(query[0].children.length).toBe(1);
// add right action
const right2 = document.createElement('div');
right2.className = 'test-right-actions-element-2';
cut.setRightActionsElement(right2);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .right-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.item(0)?.className).toBe(
'test-right-actions-element-2'
);
expect(query[0].children.length).toBe(1);
// remove right action
cut.setRightActionsElement(undefined);
query = cut.element.querySelectorAll(
'.tabs-and-actions-container > .right-actions-container'
);
expect(query.length).toBe(1);
expect(query[0].children.length).toBe(0);
});
});

View File

@ -28,7 +28,8 @@ export interface ITabsContainer extends IDisposable {
isActive: (tab: ITab) => boolean;
closePanel: (panel: IDockviewPanel) => void;
openPanel: (panel: IDockviewPanel, index?: number) => void;
setActionElement(element: HTMLElement | undefined): void;
setRightActionsElement(element: HTMLElement | undefined): void;
setLeftActionsElement(element: HTMLElement | undefined): void;
hidden: boolean;
show(): void;
hide(): void;
@ -40,12 +41,14 @@ export class TabsContainer
{
private readonly _element: HTMLElement;
private readonly tabContainer: HTMLElement;
private readonly actionContainer: HTMLElement;
private readonly rightActionsContainer: HTMLElement;
private readonly leftActionsContainer: HTMLElement;
private readonly voidContainer: VoidContainer;
private tabs: IValueDisposable<ITab>[] = [];
private selectedIndex = -1;
private actions: HTMLElement | undefined;
private rightActions: HTMLElement | undefined;
private leftActions: HTMLElement | undefined;
private _hidden = false;
@ -79,17 +82,31 @@ export class TabsContainer
this._element.style.display = 'none';
}
setActionElement(element: HTMLElement | undefined): void {
if (this.actions === element) {
setRightActionsElement(element: HTMLElement | undefined): void {
if (this.rightActions === element) {
return;
}
if (this.actions) {
this.actions.remove();
this.actions = undefined;
if (this.rightActions) {
this.rightActions.remove();
this.rightActions = undefined;
}
if (element) {
this.actionContainer.appendChild(element);
this.actions = element;
this.rightActionsContainer.appendChild(element);
this.rightActions = element;
}
}
setLeftActionsElement(element: HTMLElement | undefined): void {
if (this.leftActions === element) {
return;
}
if (this.leftActions) {
this.leftActions.remove();
this.leftActions = undefined;
}
if (element) {
this.leftActionsContainer.appendChild(element);
this.leftActions = element;
}
}
@ -146,8 +163,11 @@ export class TabsContainer
})
);
this.actionContainer = document.createElement('div');
this.actionContainer.className = 'action-container';
this.rightActionsContainer = document.createElement('div');
this.rightActionsContainer.className = 'right-actions-container';
this.leftActionsContainer = document.createElement('div');
this.leftActionsContainer.className = 'left-actions-container';
this.tabContainer = document.createElement('div');
this.tabContainer.className = 'tabs-container';
@ -155,8 +175,9 @@ export class TabsContainer
this.voidContainer = new VoidContainer(this.accessor, this.group);
this._element.appendChild(this.tabContainer);
this._element.appendChild(this.leftActionsContainer);
this._element.appendChild(this.voidContainer.element);
this._element.appendChild(this.actionContainer);
this._element.appendChild(this.rightActionsContainer);
this.addDisposables(
this.voidContainer,

View File

@ -71,7 +71,8 @@ export type DockviewComponentUpdateOptions = Pick<
| 'showDndOverlay'
| 'watermarkFrameworkComponent'
| 'defaultTabComponent'
| 'createGroupControlElement'
| 'createLeftHeaderActionsElement'
| 'createRightHeaderActionsElement'
>;
export interface DockviewDropEvent extends GroupviewDropEvent {

View File

@ -18,7 +18,7 @@ import {
import { DockviewDropTargets, IWatermarkRenderer } from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { IDockviewPanel } from './dockviewPanel';
import { IGroupControlRenderer } from './options';
import { IHeaderActionsRenderer } from './options';
export interface DndService {
canDisplayOverlay(
@ -137,7 +137,8 @@ export class DockviewGroupPanelModel
private watermark?: IWatermarkRenderer;
private _isGroupActive = false;
private _locked = false;
private _control: IGroupControlRenderer | undefined;
private _rightHeaderActions: IHeaderActionsRenderer | undefined;
private _leftHeaderActions: IHeaderActionsRenderer | undefined;
private mostRecentlyUsed: IDockviewPanel[] = [];
@ -319,16 +320,34 @@ export class DockviewGroupPanelModel
this.setActive(this.isActive, true, true);
this.updateContainer();
if (this.accessor.options.createGroupControlElement) {
this._control = this.accessor.options.createGroupControlElement(
this.groupPanel
);
this.addDisposables(this._control);
this._control.init({
if (this.accessor.options.createRightHeaderActionsElement) {
this._rightHeaderActions =
this.accessor.options.createRightHeaderActionsElement(
this.groupPanel
);
this.addDisposables(this._rightHeaderActions);
this._rightHeaderActions.init({
containerApi: new DockviewApi(this.accessor),
api: this.groupPanel.api,
});
this.tabsContainer.setActionElement(this._control.element);
this.tabsContainer.setRightActionsElement(
this._rightHeaderActions.element
);
}
if (this.accessor.options.createLeftHeaderActionsElement) {
this._leftHeaderActions =
this.accessor.options.createLeftHeaderActionsElement(
this.groupPanel
);
this.addDisposables(this._leftHeaderActions);
this._leftHeaderActions.init({
containerApi: new DockviewApi(this.accessor),
api: this.groupPanel.api,
});
this.tabsContainer.setLeftActionsElement(
this._leftHeaderActions.element
);
}
}
@ -511,7 +530,7 @@ export class DockviewGroupPanelModel
}
updateActions(element: HTMLElement | undefined): void {
this.tabsContainer.setActionElement(element);
this.tabsContainer.setRightActionsElement(element);
}
public setActive(

View File

@ -19,7 +19,7 @@ import { Position } from '../dnd/droptarget';
import { IDockviewPanel } from './dockviewPanel';
import { FrameworkFactory } from '../panel/componentFactory';
export interface IGroupControlRenderer extends IDisposable {
export interface IHeaderActionsRenderer extends IDisposable {
readonly element: HTMLElement;
init(params: {
containerApi: DockviewApi;
@ -79,9 +79,12 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
styles?: ISplitviewStyles;
defaultTabComponent?: string;
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
createGroupControlElement?: (
createRightHeaderActionsElement?: (
group: DockviewGroupPanel
) => IGroupControlRenderer;
) => IHeaderActionsRenderer;
createLeftHeaderActionsElement?: (
group: DockviewGroupPanel
) => IHeaderActionsRenderer;
singleTabMode?: 'fullwidth' | 'default';
parentElement?: HTMLElement;
}

View File

@ -3,9 +3,9 @@ import {
DockviewGroupPanelApi,
DockviewGroupPanelModel,
} from 'dockview-core';
import { ReactGroupControlsRendererPart } from '../../dockview/groupControlsRenderer';
import { ReactHeaderActionsRendererPart } from '../../dockview/headerActionsRenderer';
describe('groupControlsRenderer', () => {
describe('headerActionsRenderer', () => {
test('#1', () => {
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
@ -28,7 +28,7 @@ describe('groupControlsRenderer', () => {
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new ReactGroupControlsRendererPart(
const cut = new ReactHeaderActionsRendererPart(
jest.fn(),
{
addPortal: jest.fn(),

View File

@ -4,12 +4,12 @@ import {
DockviewDropEvent,
DockviewDndOverlayEvent,
GroupPanelFrameworkComponentFactory,
IGroupControlRenderer,
DockviewPanelApi,
DockviewApi,
IContentRenderer,
ITabRenderer,
DockviewGroupPanel,
IHeaderActionsRenderer,
} from 'dockview-core';
import { ReactPanelContentPart } from './reactContentPart';
import { ReactPanelHeaderPart } from './reactHeaderPart';
@ -18,17 +18,17 @@ import { ReactPortalStore, usePortalsLifecycle } from '../react';
import { IWatermarkPanelProps, ReactWatermarkPart } from './reactWatermarkPart';
import { PanelCollection, PanelParameters } from '../types';
import {
IDockviewGroupControlProps,
ReactGroupControlsRendererPart,
} from './groupControlsRenderer';
IDockviewHeaderActionsProps,
ReactHeaderActionsRendererPart,
} from './headerActionsRenderer';
function createGroupControlElement(
component: React.FunctionComponent<IDockviewGroupControlProps> | undefined,
component: React.FunctionComponent<IDockviewHeaderActionsProps> | undefined,
store: ReactPortalStore
): ((groupPanel: DockviewGroupPanel) => IGroupControlRenderer) | undefined {
): ((groupPanel: DockviewGroupPanel) => IHeaderActionsRenderer) | undefined {
return component
? (groupPanel: DockviewGroupPanel) => {
return new ReactGroupControlsRendererPart(
return new ReactHeaderActionsRendererPart(
component,
store,
groupPanel
@ -65,7 +65,8 @@ export interface IDockviewReactProps {
className?: string;
disableAutoResizing?: boolean;
defaultTabComponent?: React.FunctionComponent<IDockviewPanelHeaderProps>;
groupControlComponent?: React.FunctionComponent<IDockviewGroupControlProps>;
rightHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
leftHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
singleTabMode?: 'fullwidth' | 'default';
}
@ -150,10 +151,15 @@ export const DockviewReact = React.forwardRef(
? { separatorBorder: 'transparent' }
: undefined,
showDndOverlay: props.showDndOverlay,
createGroupControlElement: createGroupControlElement(
props.groupControlComponent,
createLeftHeaderActionsElement: createGroupControlElement(
props.leftHeaderActionsComponent,
{ addPortal }
),
createRightHeaderActionsElement: createGroupControlElement(
props.rightHeaderActionsComponent,
{ addPortal }
),
singleTabMode: props.singleTabMode,
});
@ -250,12 +256,24 @@ export const DockviewReact = React.forwardRef(
return;
}
dockviewRef.current.updateOptions({
createGroupControlElement: createGroupControlElement(
props.groupControlComponent,
createRightHeaderActionsElement: createGroupControlElement(
props.rightHeaderActionsComponent,
{ addPortal }
),
});
}, [props.groupControlComponent]);
}, [props.rightHeaderActionsComponent]);
React.useEffect(() => {
if (!dockviewRef.current) {
return;
}
dockviewRef.current.updateOptions({
createLeftHeaderActionsElement: createGroupControlElement(
props.leftHeaderActionsComponent,
{ addPortal }
),
});
}, [props.leftHeaderActionsComponent]);
return (
<div

View File

@ -10,24 +10,25 @@ import {
PanelUpdateEvent,
} from 'dockview-core';
export interface IDockviewGroupControlProps {
export interface IDockviewHeaderActionsProps {
api: DockviewGroupPanelApi;
containerApi: DockviewApi;
panels: IDockviewPanel[];
activePanel: IDockviewPanel | undefined;
isGroupActive: boolean;
group: DockviewGroupPanel;
}
export class ReactGroupControlsRendererPart {
export class ReactHeaderActionsRendererPart {
private mutableDisposable = new DockviewMutableDisposable();
private _element: HTMLElement;
private _part?: ReactPart<IDockviewGroupControlProps>;
private _part?: ReactPart<IDockviewHeaderActionsProps>;
get element(): HTMLElement {
return this._element;
}
get part(): ReactPart<IDockviewGroupControlProps> | undefined {
get part(): ReactPart<IDockviewHeaderActionsProps> | undefined {
return this._part;
}
@ -36,7 +37,7 @@ export class ReactGroupControlsRendererPart {
}
constructor(
private readonly component: React.FunctionComponent<IDockviewGroupControlProps>,
private readonly component: React.FunctionComponent<IDockviewHeaderActionsProps>,
private readonly reactPortalStore: ReactPortalStore,
private readonly _group: DockviewGroupPanel
) {
@ -77,6 +78,7 @@ export class ReactGroupControlsRendererPart {
panels: this._group.model.panels,
activePanel: this._group.model.activePanel,
isGroupActive: this._group.api.isActive,
group: this._group,
}
);
}

View File

@ -4,7 +4,7 @@ export * from './dockview/dockview';
export * from './dockview/defaultTab';
export * from './splitview/splitview';
export * from './gridview/gridview';
export { IDockviewGroupControlProps } from './dockview/groupControlsRenderer';
export { IDockviewHeaderActionsProps } from './dockview/headerActionsRenderer';
export { IWatermarkPanelProps } from './dockview/reactWatermarkPart';
export * from './paneview/paneview';
export * from './types';

View File

@ -18,7 +18,7 @@ import DockviewConstraints from '@site/sandboxes/constraints-dockview/src/app';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import NestedDockview from '@site/sandboxes/nested-dockview/src/app';
import EventsDockview from '@site/sandboxes/events-dockview/src/app';
import DockviewGroupControl from '@site/sandboxes/groupcontrol-dockview/src/app';
import DockviewGroupControl from '@site/sandboxes/headeractions-dockview/src/app';
import CustomHeadersDockview from '@site/sandboxes/customheader-dockview/src/app';
import DockviewNative from '@site/sandboxes/fullwidthtab-dockview/src/app';
import DockviewNative2 from '@site/sandboxes/nativeapp-dockview/src/app';
@ -59,20 +59,21 @@ You can create a Dockview through the use of the `DockviewReact` component.
import { DockviewReact } from 'dockview';
```
| Property | Type | Optional | Default | Description |
| --------------------- | ------------------------------------ | -------- | --------- | ------------------------------------------------------------ |
| onReady | (event: SplitviewReadyEvent) => void | No | | |
| components | object | No | | |
| tabComponents | object | Yes | | |
| watermarkComponent | object | Yes | | |
| hideBorders | boolean | Yes | false | |
| className | string | Yes | '' | |
| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
| onDidDrop | Event | Yes | false | |
| showDndOverlay | Event | Yes | false | |
| defaultTabComponent | object | Yes | | |
| groupControlComponent | object | Yes | | |
| singleTabMode | 'fullwidth' \| 'default' | Yes | 'default' | |
| Property | Type | Optional | Default | Description |
| --------------------------- | ------------------------------------ | -------- | --------- | ------------------------------------------------------------ |
| onReady | (event: SplitviewReadyEvent) => void | No | | |
| components | object | No | | |
| tabComponents | object | Yes | | |
| watermarkComponent | object | Yes | | |
| hideBorders | boolean | Yes | false | |
| className | string | Yes | '' | |
| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
| onDidDrop | Event | Yes | false | |
| showDndOverlay | Event | Yes | false | |
| defaultTabComponent | object | Yes | | |
| leftHeaderActionsComponent | object | Yes | | |
| rightHeaderActionsComponent | object | Yes | | |
| singleTabMode | 'fullwidth' \| 'default' | Yes | 'default' | |
## Dockview API
@ -683,22 +684,22 @@ panel.group.locked = true;
### Group Controls Panel
`DockviewReact` accepts a prop `groupControlComponent` which expects a React component whos props are `IDockviewGroupControlProps`.
This control will be rendered inside the header bar on the right hand side for each group of tabs.
`DockviewReact` accepts `leftHeaderActionsComponent` and `rightHeaderActionsComponent` which expect a React component with props `IDockviewHeaderActionsProps`.
These controls are rendered of the left and right side of the space to the right of the tabs in the header bar.
```tsx
const Component: React.FunctionComponent<IDockviewGroupControlProps> = () => {
const Component: React.FunctionComponent<IDockviewHeaderActionsProps> = () => {
return <div>{'...'}</div>;
};
return <DockviewReact {...props} groupControlComponent={Component} />;
return <DockviewReact {...props} leftHeaderActionsComponent={Component} rightHeaderActionsComponent={...} />;
```
As a simple example the below uses the `groupControlComponent` to render a small control that indicates whether the group
is active and which panel is active in that group.
```tsx
const GroupControlComponent = (props: IDockviewGroupControlProps) => {
const RightHeaderActionsComponent = (props: IDockviewHeaderActionsProps) => {
const isGroupActive = props.isGroupActive;
const activePanel = props.activePanel;

View File

@ -4,7 +4,7 @@ import {
DockviewReadyEvent,
IDockviewPanelHeaderProps,
IDockviewPanelProps,
IDockviewGroupControlProps,
IDockviewHeaderActionsProps,
} from 'dockview';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
@ -134,7 +134,7 @@ const groupControlsComponents = {
},
};
const GroupControls = (props: IDockviewGroupControlProps) => {
const RightControls = (props: IDockviewHeaderActionsProps) => {
const Component = React.useMemo(() => {
if (!props.isGroupActive || !props.activePanel) {
return null;
@ -161,6 +161,36 @@ const GroupControls = (props: IDockviewGroupControlProps) => {
);
};
let counter = 0;
const LeftControls = (props: IDockviewHeaderActionsProps) => {
const onClick = () => {
props.containerApi.addPanel({
id: `id_${Date.now().toString()}`,
component: 'default',
title: `Tab ${counter++}`,
position: {
referenceGroup: props.group,
},
});
};
return (
<div
className="group-control"
style={{
display: 'flex',
alignItems: 'center',
padding: '0px 8px',
height: '100%',
color: 'var(--dv-activegroup-visiblepanel-tab-color)',
}}
>
<Icon onClick={onClick} icon="add" />
</div>
);
};
const DockviewDemo = () => {
const onReady = (event: DockviewReadyEvent) => {
event.api.addPanel({
@ -196,8 +226,6 @@ const DockviewDemo = () => {
title: 'Panel 6',
position: { referencePanel: 'panel_4', direction: 'below' },
});
panel6.group.locked = true;
panel6.group.header.hidden = true;
event.api.addPanel({
id: 'panel_7',
component: 'default',
@ -211,8 +239,6 @@ const DockviewDemo = () => {
position: { referencePanel: 'panel_7', direction: 'within' },
});
event.api.addGroup();
event.api.getPanel('panel_1')!.api.setActive();
};
@ -220,7 +246,8 @@ const DockviewDemo = () => {
<DockviewReact
components={components}
defaultTabComponent={headerComponents.default}
groupControlComponent={GroupControls}
rightHeaderActionsComponent={RightControls}
leftHeaderActionsComponent={LeftControls}
onReady={onReady}
className="dockview-theme-abyss"
/>

View File

@ -1,5 +1,5 @@
{
"name": "groupcontrol-dockview",
"name": "headeractions-dockview",
"description": "",
"keywords": [
"dockview"
@ -29,4 +29,4 @@
"not ie <= 11",
"not op_mini all"
]
}
}

View File

@ -1,7 +1,7 @@
import {
DockviewReact,
DockviewReadyEvent,
IDockviewGroupControlProps,
IDockviewHeaderActionsProps,
IDockviewPanelProps,
} from 'dockview';
import * as React from 'react';
@ -26,9 +26,8 @@ const components = {
},
};
const GroupControlComponent = (props: IDockviewGroupControlProps) => {
const RightHeaderActions = (props: IDockviewHeaderActionsProps) => {
const isGroupActive = props.isGroupActive;
const activePanel = props.activePanel;
return (
<div className="dockview-groupcontrol-demo">
@ -40,6 +39,15 @@ const GroupControlComponent = (props: IDockviewGroupControlProps) => {
>
{isGroupActive ? 'Group Active' : 'Group Inactive'}
</span>
</div>
);
};
const LeftHeaderActions = (props: IDockviewHeaderActionsProps) => {
const activePanel = props.activePanel;
return (
<div className="dockview-groupcontrol-demo">
<span className="dockview-groupcontrol-demo-active-panel">{`activePanel: ${
activePanel?.id || 'null'
}`}</span>
@ -87,7 +95,8 @@ const DockviewGroupControl = () => {
<DockviewReact
onReady={onReady}
components={components}
groupControlComponent={GroupControlComponent}
leftHeaderActionsComponent={LeftHeaderActions}
rightHeaderActionsComponent={RightHeaderActions}
className="dockview-theme-abyss"
/>
);

View File

@ -18,7 +18,7 @@ import DockviewConstraints from '@site/sandboxes/constraints-dockview/src/app';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import NestedDockview from '@site/sandboxes/nested-dockview/src/app';
import EventsDockview from '@site/sandboxes/events-dockview/src/app';
import DockviewGroupControl from '@site/sandboxes/groupcontrol-dockview/src/app';
import DockviewGroupControl from '@site/sandboxes/headeractions-dockview/src/app';
import CustomHeadersDockview from '@site/sandboxes/customheader-dockview/src/app';
import DockviewNative from '@site/sandboxes/fullwidthtab-dockview/src/app';
import DockviewNative2 from '@site/sandboxes/nativeapp-dockview/src/app';