mirror of
https://github.com/mathuo/dockview
synced 2025-05-01 09:08:24 +00:00
feat: add left header actions
This commit is contained in:
parent
6434e68b5b
commit
13d3db605b
@ -46,30 +46,5 @@
|
||||
padding: 0px 8px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.action-container {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
|
||||
.tab-list {
|
||||
display: flex;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
justify-content: flex-end;
|
||||
|
||||
.tab-action {
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:hover {
|
||||
border-radius: 2px;
|
||||
background-color: var(--dv-icon-hover-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -71,7 +71,8 @@ export type DockviewComponentUpdateOptions = Pick<
|
||||
| 'showDndOverlay'
|
||||
| 'watermarkFrameworkComponent'
|
||||
| 'defaultTabComponent'
|
||||
| 'createGroupControlElement'
|
||||
| 'createLeftHeaderActionsElement'
|
||||
| 'createRightHeaderActionsElement'
|
||||
>;
|
||||
|
||||
export interface DockviewDropEvent extends GroupviewDropEvent {
|
||||
@ -717,7 +718,7 @@ export class DockviewComponent
|
||||
|
||||
if (itemId === undefined) {
|
||||
if (sourceGroup) {
|
||||
this.moveGroup(sourceGroup, referenceGroup, target);
|
||||
this.moveGroup(sourceGroup, referenceGroup, target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ export class DockviewGroupPanelModel
|
||||
private _isGroupActive = false;
|
||||
private _locked = false;
|
||||
private _control: IGroupControlRenderer | undefined;
|
||||
private _lhs: IGroupControlRenderer | undefined;
|
||||
|
||||
private mostRecentlyUsed: IDockviewPanel[] = [];
|
||||
|
||||
@ -319,16 +320,29 @@ export class DockviewGroupPanelModel
|
||||
this.setActive(this.isActive, true, true);
|
||||
this.updateContainer();
|
||||
|
||||
if (this.accessor.options.createGroupControlElement) {
|
||||
this._control = this.accessor.options.createGroupControlElement(
|
||||
this.groupPanel
|
||||
);
|
||||
if (this.accessor.options.createRightHeaderActionsElement) {
|
||||
this._control =
|
||||
this.accessor.options.createRightHeaderActionsElement(
|
||||
this.groupPanel
|
||||
);
|
||||
this.addDisposables(this._control);
|
||||
this._control.init({
|
||||
containerApi: new DockviewApi(this.accessor),
|
||||
api: this.groupPanel.api,
|
||||
});
|
||||
this.tabsContainer.setActionElement(this._control.element);
|
||||
this.tabsContainer.setRightActionsElement(this._control.element);
|
||||
}
|
||||
|
||||
if (this.accessor.options.createLeftHeaderActionsElement) {
|
||||
this._lhs = this.accessor.options.createLeftHeaderActionsElement(
|
||||
this.groupPanel
|
||||
);
|
||||
this.addDisposables(this._lhs);
|
||||
this._lhs.init({
|
||||
containerApi: new DockviewApi(this.accessor),
|
||||
api: this.groupPanel.api,
|
||||
});
|
||||
this.tabsContainer.setLeftActionsElement(this._lhs.element);
|
||||
}
|
||||
}
|
||||
|
||||
@ -511,7 +525,7 @@ export class DockviewGroupPanelModel
|
||||
}
|
||||
|
||||
updateActions(element: HTMLElement | undefined): void {
|
||||
this.tabsContainer.setActionElement(element);
|
||||
this.tabsContainer.setRightActionsElement(element);
|
||||
}
|
||||
|
||||
public setActive(
|
||||
|
@ -79,7 +79,10 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
|
||||
styles?: ISplitviewStyles;
|
||||
defaultTabComponent?: string;
|
||||
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
|
||||
createGroupControlElement?: (
|
||||
createRightHeaderActionsElement?: (
|
||||
group: DockviewGroupPanel
|
||||
) => IGroupControlRenderer;
|
||||
createLeftHeaderActionsElement?: (
|
||||
group: DockviewGroupPanel
|
||||
) => IGroupControlRenderer;
|
||||
singleTabMode?: 'fullwidth' | 'default';
|
||||
|
@ -65,7 +65,8 @@ export interface IDockviewReactProps {
|
||||
className?: string;
|
||||
disableAutoResizing?: boolean;
|
||||
defaultTabComponent?: React.FunctionComponent<IDockviewPanelHeaderProps>;
|
||||
groupControlComponent?: React.FunctionComponent<IDockviewGroupControlProps>;
|
||||
rightHeaderActionsComponent?: React.FunctionComponent<IDockviewGroupControlProps>;
|
||||
leftHeaderActionsComponent?: React.FunctionComponent<IDockviewGroupControlProps>;
|
||||
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
|
||||
|
@ -58,20 +58,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
|
||||
|
||||
|
@ -26,7 +26,7 @@ const components = {
|
||||
},
|
||||
};
|
||||
|
||||
const GroupControlComponent = (props: IDockviewGroupControlProps) => {
|
||||
const RightHeaderActions = (props: IDockviewGroupControlProps) => {
|
||||
const isGroupActive = props.isGroupActive;
|
||||
const activePanel = props.activePanel;
|
||||
|
||||
@ -87,7 +87,7 @@ const DockviewGroupControl = () => {
|
||||
<DockviewReact
|
||||
onReady={onReady}
|
||||
components={components}
|
||||
groupControlComponent={GroupControlComponent}
|
||||
rightHeaderActionsComponent={RightHeaderActions}
|
||||
className="dockview-theme-abyss"
|
||||
/>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user