Merge branch 'master' of https://github.com/mathuo/dockview into 84-add-ability-to-have-fixed-panel-with-no-tab-in-dockviewreact

This commit is contained in:
mathuo 2022-05-02 17:20:07 +01:00
commit 05f8ab8f8b
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
19 changed files with 102 additions and 160 deletions

View File

@ -2,7 +2,7 @@
"packages": [ "packages": [
"packages/*" "packages/*"
], ],
"version": "1.3.0", "version": "1.3.1",
"command": { "command": {
"publish": { "publish": {
"message": "chore(release): publish %s" "message": "chore(release): publish %s"

View File

@ -1,6 +1,6 @@
{ {
"name": "dockview-demo", "name": "dockview-demo",
"version": "1.3.0", "version": "1.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -1,7 +1,7 @@
{ {
"name": "dockview-demo", "name": "dockview-demo",
"private": true, "private": true,
"version": "1.3.0", "version": "1.3.1",
"description": "Demo project for https://github.com/mathuo/dockview", "description": "Demo project for https://github.com/mathuo/dockview",
"scripts": { "scripts": {
"build": "npm run build-webpack && npm run build-storybook", "build": "npm run build-webpack && npm run build-storybook",
@ -15,7 +15,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@mdx-js/react": "^2.1.1", "@mdx-js/react": "^2.1.1",
"dockview": "^1.3.0", "dockview": "^1.3.1",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0", "react-dom": "^18.0.0",
"recoil": "^0.7.2" "recoil": "^0.7.2"

View File

@ -1,6 +1,6 @@
{ {
"name": "dockview", "name": "dockview",
"version": "1.3.0", "version": "1.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -1,6 +1,6 @@
{ {
"name": "dockview", "name": "dockview",
"version": "1.3.0", "version": "1.3.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support", "description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js", "main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts", "types": "./dist/cjs/index.d.ts",

View File

@ -1,4 +1,3 @@
import { DockviewComponent } from '../..';
import { import {
SplitviewApi, SplitviewApi,
PaneviewApi, PaneviewApi,
@ -8,6 +7,7 @@ import {
import { GridviewComponent } from '../../gridview/gridviewComponent'; import { GridviewComponent } from '../../gridview/gridviewComponent';
import { PaneviewComponent } from '../../paneview/paneviewComponent'; import { PaneviewComponent } from '../../paneview/paneviewComponent';
import { SplitviewComponent } from '../../splitview/splitviewComponent'; import { SplitviewComponent } from '../../splitview/splitviewComponent';
import { DockviewComponent } from '../../dockview/dockviewComponent';
describe('component.api', () => { describe('component.api', () => {
describe('splitview', () => { describe('splitview', () => {
@ -22,9 +22,8 @@ describe('component.api', () => {
'onDidLayoutChange', 'onDidLayoutChange',
'onDidAddView', 'onDidAddView',
'onDidRemoveView', 'onDidRemoveView',
'getPanels', 'panels',
'focus', 'focus',
'resizeToFit',
'toJSON', 'toJSON',
]; ];
@ -54,9 +53,8 @@ describe('component.api', () => {
'onDidLayoutChange', 'onDidLayoutChange',
'onDidAddView', 'onDidAddView',
'onDidRemoveView', 'onDidRemoveView',
'getPanels', 'panels',
'focus', 'focus',
'resizeToFit',
'toJSON', 'toJSON',
]; ];
@ -88,7 +86,6 @@ describe('component.api', () => {
'onDidLayoutChange', 'onDidLayoutChange',
'orientation', 'orientation',
'focus', 'focus',
'resizeToFit',
'toJSON', 'toJSON',
'onDidActiveGroupChange', 'onDidActiveGroupChange',
'onDidAddGroup', 'onDidAddGroup',
@ -130,7 +127,6 @@ describe('component.api', () => {
'activePanel', 'activePanel',
'focus', 'focus',
'closeAllGroups', 'closeAllGroups',
'resizeToFit',
'toJSON', 'toJSON',
'onDidActiveGroupChange', 'onDidActiveGroupChange',
'onDidAddGroup', 'onDidAddGroup',

View File

@ -1,4 +1,5 @@
import { import {
DockviewDropEvent,
IDockviewComponent, IDockviewComponent,
SerializedDockview, SerializedDockview,
} from '../dockview/dockviewComponent'; } from '../dockview/dockviewComponent';
@ -40,9 +41,7 @@ export interface CommonApi<T = any> {
readonly onDidLayoutFromJSON: Event<void>; readonly onDidLayoutFromJSON: Event<void>;
focus(): void; focus(): void;
layout(width: number, height: number): void; layout(width: number, height: number): void;
resizeToFit(): void;
fromJSON(data: T): void; fromJSON(data: T): void;
toJSON(): T; toJSON(): T;
} }
@ -71,6 +70,10 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
return this.component.orientation; return this.component.orientation;
} }
get panels(): ISplitviewPanel[] {
return this.component.panels;
}
get onDidLayoutFromJSON(): Event<void> { get onDidLayoutFromJSON(): Event<void> {
return this.component.onDidLayoutFromJSON; return this.component.onDidLayoutFromJSON;
} }
@ -101,10 +104,6 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
this.component.setVisible(panel, isVisible); this.component.setVisible(panel, isVisible);
} }
getPanels(): ISplitviewPanel[] {
return this.component.getPanels();
}
focus(): void { focus(): void {
this.component.focus(); this.component.focus();
} }
@ -121,12 +120,8 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
return this.component.layout(width, height); return this.component.layout(width, height);
} }
addPanel(options: AddSplitviewComponentOptions): void { addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel {
this.component.addPanel(options); return this.component.addPanel(options);
}
resizeToFit(): void {
this.component.resizeToFit();
} }
movePanel(from: number, to: number): void { movePanel(from: number, to: number): void {
@ -159,6 +154,10 @@ export class PaneviewApi implements CommonApi<SerializedPaneview> {
return this.component.width; return this.component.width;
} }
get panels(): IPaneviewPanel[] {
return this.component.panels;
}
get onDidLayoutChange(): Event<void> { get onDidLayoutChange(): Event<void> {
return this.component.onDidLayoutChange; return this.component.onDidLayoutChange;
} }
@ -192,10 +191,6 @@ export class PaneviewApi implements CommonApi<SerializedPaneview> {
constructor(private readonly component: IPaneviewComponent) {} constructor(private readonly component: IPaneviewComponent) {}
getPanels(): IPaneviewPanel[] {
return this.component.getPanels();
}
removePanel(panel: IPaneviewPanel): void { removePanel(panel: IPaneviewPanel): void {
this.component.removePanel(panel); this.component.removePanel(panel);
} }
@ -216,12 +211,8 @@ export class PaneviewApi implements CommonApi<SerializedPaneview> {
this.component.layout(width, height); this.component.layout(width, height);
} }
addPanel(options: AddPaneviewComponentOptions): void { addPanel(options: AddPaneviewComponentOptions): IPaneviewPanel {
this.component.addPanel(options); return this.component.addPanel(options);
}
resizeToFit(): void {
this.component.resizeToFit();
} }
fromJSON(data: SerializedPaneview): void { fromJSON(data: SerializedPaneview): void {
@ -300,8 +291,8 @@ export class GridviewApi implements CommonApi<SerializedGridview> {
this.component.layout(width, height, force); this.component.layout(width, height, force);
} }
addPanel(options: AddComponentOptions): void { addPanel(options: AddComponentOptions): IGridviewPanel {
this.component.addPanel(options); return this.component.addPanel(options);
} }
removePanel(panel: IGridviewPanel, sizing?: Sizing): void { removePanel(panel: IGridviewPanel, sizing?: Sizing): void {
@ -315,10 +306,6 @@ export class GridviewApi implements CommonApi<SerializedGridview> {
this.component.movePanel(panel, options); this.component.movePanel(panel, options);
} }
resizeToFit(): void {
this.component.resizeToFit();
}
getPanel(id: string): IGridviewPanel | undefined { getPanel(id: string): IGridviewPanel | undefined {
return this.component.getPanel(id); return this.component.getPanel(id);
} }
@ -409,6 +396,10 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.onDidLayoutChange; return this.component.onDidLayoutChange;
} }
get onDidDrop(): Event<DockviewDropEvent> {
return this.component.onDidDrop;
}
get panels(): IGroupPanel[] { get panels(): IGroupPanel[] {
return this.component.panels; return this.component.panels;
} }
@ -471,10 +462,6 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
this.component.removeGroup(<GroupviewPanel>group); this.component.removeGroup(<GroupviewPanel>group);
} }
resizeToFit(): void {
return this.component.resizeToFit();
}
getGroup(id: string): IGroupviewPanel | undefined { getGroup(id: string): IGroupviewPanel | undefined {
return this.component.getPanel(id); return this.component.getPanel(id);
} }

View File

@ -16,8 +16,7 @@ export interface SuppressClosableEvent {
* omit visibility modifiers since the visibility of a single group doesn't make sense * omit visibility modifiers since the visibility of a single group doesn't make sense
* because it belongs to a groupview * because it belongs to a groupview
*/ */
export interface DockviewPanelApi export interface DockviewPanelApi extends Omit<GridviewPanelApi, 'setVisible'> {
extends Omit<GridviewPanelApi, 'setVisible' | 'visible'> {
readonly group: GroupviewPanel | undefined; readonly group: GroupviewPanel | undefined;
readonly isGroupActive: boolean; readonly isGroupActive: boolean;
readonly title: string; readonly title: string;

View File

@ -15,26 +15,24 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: var(--dv-drag-over-background-color); background-color: var(--dv-drag-over-background-color);
transition: top 70ms ease-out,left 70ms ease-out,width 70ms ease-out,height 70ms ease-out,opacity .15s ease-out;
transition-duration: 0.15s;
transition-timing-function: ease-out;
will-change: transform; will-change: transform;
pointer-events: none; pointer-events: none;
&.left { &.left {
transform: translateX(-25%) scaleX(50%) transform: translateX(-25%) scaleX(0.5)
} }
&.right { &.right {
transform: translateX(25%) scaleX(50%) transform: translateX(25%) scaleX(0.5)
} }
&.top { &.top {
transform: translateY(-25%) scaleY(50%); transform: translateY(-25%) scaleY(0.5);
} }
&.bottom { &.bottom {
transform: translateY(25%) scaleY(50%); transform: translateY(25%) scaleY(0.5);
} }
&.small-top { &.small-top {

View File

@ -54,7 +54,6 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
watermarkFrameworkComponent?: any; watermarkFrameworkComponent?: any;
frameworkComponentFactory?: GroupPanelFrameworkComponentFactory; frameworkComponentFactory?: GroupPanelFrameworkComponentFactory;
tabHeight?: number; tabHeight?: number;
debug?: boolean;
orientation?: Orientation; orientation?: Orientation;
styles?: ISplitviewStyles; styles?: ISplitviewStyles;
showDndOverlay?: (event: DragEvent, target: DockviewDropTargets) => boolean; showDndOverlay?: (event: DragEvent, target: DockviewDropTargets) => boolean;

View File

@ -62,7 +62,6 @@ export interface IBaseGrid<T extends IGridPanelView> {
toJSON(): object; toJSON(): object;
fromJSON(data: any): void; fromJSON(data: any): void;
layout(width: number, height: number, force?: boolean): void; layout(width: number, height: number, force?: boolean): void;
resizeToFit(): void;
setVisible(panel: T, visible: boolean): void; setVisible(panel: T, visible: boolean): void;
isVisible(panel: T): boolean; isVisible(panel: T): boolean;
} }
@ -299,18 +298,6 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.gridview.layout(width, height); this.gridview.layout(width, height);
} }
/**
* Resize the layout to fit the parent container
*/
public resizeToFit(): void {
if (!this.element.parentElement) {
return;
}
const { width, height } =
this.element.parentElement.getBoundingClientRect();
this.layout(width, height);
}
public dispose(): void { public dispose(): void {
super.dispose(); super.dispose();

View File

@ -44,7 +44,7 @@ export interface AddComponentOptions extends BaseComponentOptions {
maximumHeight?: number; maximumHeight?: number;
position?: { position?: {
direction: Direction; direction: Direction;
reference: string; referencePanel: string;
}; };
location?: number[]; location?: number[];
} }
@ -62,7 +62,7 @@ export interface IGridviewComponent extends IBaseGrid<GridviewPanel> {
readonly orientation: Orientation; readonly orientation: Orientation;
readonly onDidLayoutFromJSON: Event<void>; readonly onDidLayoutFromJSON: Event<void>;
updateOptions(options: Partial<GridviewComponentUpdateOptions>): void; updateOptions(options: Partial<GridviewComponentUpdateOptions>): void;
addPanel(options: AddComponentOptions): void; addPanel(options: AddComponentOptions): IGridviewPanel;
removePanel(panel: IGridviewPanel, sizing?: Sizing): void; removePanel(panel: IGridviewPanel, sizing?: Sizing): void;
toggleVisibility(panel: IGridviewPanel): void; toggleVisibility(panel: IGridviewPanel): void;
focus(): void; focus(): void;
@ -273,17 +273,17 @@ export class GridviewComponent
this.doAddGroup(removedPanel, relativeLocation, options.size); this.doAddGroup(removedPanel, relativeLocation, options.size);
} }
public addPanel(options: AddComponentOptions): void { public addPanel(options: AddComponentOptions): IGridviewPanel {
let relativeLocation: number[] = options.location || [0]; let relativeLocation: number[] = options.location || [0];
if (options.position?.reference) { if (options.position?.referencePanel) {
const referenceGroup = this._groups.get( const referenceGroup = this._groups.get(
options.position.reference options.position.referencePanel
)?.value; )?.value;
if (!referenceGroup) { if (!referenceGroup) {
throw new Error( throw new Error(
`reference group ${options.position.reference} does not exist` `reference group ${options.position.referencePanel} does not exist`
); );
} }
@ -329,6 +329,8 @@ export class GridviewComponent
this.registerPanel(view); this.registerPanel(view);
this.doAddGroup(view, relativeLocation, options.size); this.doAddGroup(view, relativeLocation, options.size);
return view;
} }
private registerPanel(panel: GridviewPanel) { private registerPanel(panel: GridviewPanel) {

View File

@ -115,10 +115,10 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
return; return;
} }
const allPanels = containerApi.getPanels(); const allPanels = containerApi.panels;
const fromIndex = allPanels.indexOf(existingPanel); const fromIndex = allPanels.indexOf(existingPanel);
let toIndex = containerApi.getPanels().indexOf(this); let toIndex = containerApi.panels.indexOf(this);
if ( if (
event.position === Position.Left || event.position === Position.Left ||

View File

@ -98,6 +98,7 @@ export interface IPaneviewComponent extends IDisposable {
readonly height: number; readonly height: number;
readonly minimumSize: number; readonly minimumSize: number;
readonly maximumSize: number; readonly maximumSize: number;
readonly panels: IPaneviewPanel[];
readonly onDidAddView: Event<PaneviewPanel>; readonly onDidAddView: Event<PaneviewPanel>;
readonly onDidRemoveView: Event<PaneviewPanel>; readonly onDidRemoveView: Event<PaneviewPanel>;
readonly onDidDrop: Event<PaneviewDropEvent2>; readonly onDidDrop: Event<PaneviewDropEvent2>;
@ -107,9 +108,7 @@ export interface IPaneviewComponent extends IDisposable {
layout(width: number, height: number): void; layout(width: number, height: number): void;
toJSON(): SerializedPaneview; toJSON(): SerializedPaneview;
fromJSON(serializedPaneview: SerializedPaneview): void; fromJSON(serializedPaneview: SerializedPaneview): void;
resizeToFit(): void;
focus(): void; focus(): void;
getPanels(): IPaneviewPanel[];
removePanel(panel: IPaneviewPanel): void; removePanel(panel: IPaneviewPanel): void;
getPanel(id: string): IPaneviewPanel | undefined; getPanel(id: string): IPaneviewPanel | undefined;
movePanel(from: number, to: number): void; movePanel(from: number, to: number): void;
@ -139,6 +138,10 @@ export class PaneviewComponent
private readonly _onDidRemoveView = new Emitter<PaneviewPanel>(); private readonly _onDidRemoveView = new Emitter<PaneviewPanel>();
readonly onDidRemoveView = this._onDidRemoveView.event; readonly onDidRemoveView = this._onDidRemoveView.event;
get panels(): PaneviewPanel[] {
return this.paneview.getPanes();
}
set paneview(value: Paneview) { set paneview(value: Paneview) {
this._paneview = value; this._paneview = value;
@ -288,12 +291,8 @@ export class PaneviewComponent
return view; return view;
} }
getPanels(): PaneviewPanel[] {
return this.paneview.getPanes();
}
removePanel(panel: PaneviewPanel) { removePanel(panel: PaneviewPanel) {
const views = this.getPanels(); const views = this.panels;
const index = views.findIndex((_) => _ === panel); const index = views.findIndex((_) => _ === panel);
this.paneview.removePane(index); this.paneview.removePane(index);
@ -305,7 +304,7 @@ export class PaneviewComponent
} }
getPanel(id: string): PaneviewPanel | undefined { getPanel(id: string): PaneviewPanel | undefined {
return this.getPanels().find((view) => view.id === id); return this.panels.find((view) => view.id === id);
} }
layout(width: number, height: number): void { layout(width: number, height: number): void {
@ -316,18 +315,6 @@ export class PaneviewComponent
this.paneview.layout(size, orthogonalSize); this.paneview.layout(size, orthogonalSize);
} }
/**
* Resize the layout to fit the parent container
*/
resizeToFit(): void {
if (!this.element.parentElement) {
return;
}
const { width, height } =
this.element.parentElement.getBoundingClientRect();
this.layout(width, height);
}
toJSON(): SerializedPaneview { toJSON(): SerializedPaneview {
const maximum = (value: number) => const maximum = (value: number) =>
value === Number.MAX_SAFE_INTEGER || value === Number.MAX_SAFE_INTEGER ||

View File

@ -36,11 +36,10 @@ export interface DockviewReadyEvent {
} }
export interface IDockviewReactProps { export interface IDockviewReactProps {
components?: PanelCollection<IDockviewPanelProps>; components: PanelCollection<IDockviewPanelProps>;
tabComponents?: PanelCollection<IDockviewPanelHeaderProps>; tabComponents?: PanelCollection<IDockviewPanelHeaderProps>;
watermarkComponent?: React.FunctionComponent<IWatermarkPanelProps>; watermarkComponent?: React.FunctionComponent<IWatermarkPanelProps>;
onReady?: (event: DockviewReadyEvent) => void; onReady: (event: DockviewReadyEvent) => void;
debug?: boolean;
tabHeight?: number; tabHeight?: number;
onTabContextMenu?: (event: TabContextMenuEvent) => void; onTabContextMenu?: (event: TabContextMenuEvent) => void;
onDidDrop?: (event: DockviewDropEvent) => void; onDidDrop?: (event: DockviewDropEvent) => void;
@ -127,7 +126,6 @@ export const DockviewReact = React.forwardRef(
frameworkComponents: props.components, frameworkComponents: props.components,
frameworkTabComponents: props.tabComponents, frameworkTabComponents: props.tabComponents,
tabHeight: props.tabHeight, tabHeight: props.tabHeight,
debug: props.debug,
watermarkFrameworkComponent: props.watermarkComponent, watermarkFrameworkComponent: props.watermarkComponent,
styles: props.hideBorders styles: props.hideBorders
? { separatorBorder: 'transparent' } ? { separatorBorder: 'transparent' }

View File

@ -22,8 +22,8 @@ export interface IGridviewPanelProps<T extends { [index: string]: any } = any>
} }
export interface IGridviewReactProps { export interface IGridviewReactProps {
orientation: Orientation; orientation?: Orientation;
onReady?: (event: GridviewReadyEvent) => void; onReady: (event: GridviewReadyEvent) => void;
components: PanelCollection<IGridviewPanelProps>; components: PanelCollection<IGridviewPanelProps>;
hideBorders?: boolean; hideBorders?: boolean;
className?: string; className?: string;
@ -64,7 +64,7 @@ export const GridviewReact = React.forwardRef(
typeof props.proportionalLayout === 'boolean' typeof props.proportionalLayout === 'boolean'
? props.proportionalLayout ? props.proportionalLayout
: true, : true,
orientation: props.orientation, orientation: props.orientation || Orientation.HORIZONTAL,
frameworkComponents: props.components, frameworkComponents: props.components,
frameworkComponentFactory: { frameworkComponentFactory: {
createComponent: (id: string, componentId, component) => { createComponent: (id: string, componentId, component) => {

View File

@ -27,8 +27,8 @@ export interface PaneviewDropEvent extends PaneviewDropEvent2 {
} }
export interface IPaneviewReactProps { export interface IPaneviewReactProps {
onReady?: (event: PaneviewReadyEvent) => void; onReady: (event: PaneviewReadyEvent) => void;
components?: PanelCollection<IPaneviewPanelProps>; components: PanelCollection<IPaneviewPanelProps>;
headerComponents?: PanelCollection<IPaneviewPanelProps>; headerComponents?: PanelCollection<IPaneviewPanelProps>;
className?: string; className?: string;
disableAutoResizing?: boolean; disableAutoResizing?: boolean;

View File

@ -22,8 +22,8 @@ export interface ISplitviewPanelProps<T extends { [index: string]: any } = any>
} }
export interface ISplitviewReactProps { export interface ISplitviewReactProps {
orientation: Orientation; orientation?: Orientation;
onReady?: (event: SplitviewReadyEvent) => void; onReady: (event: SplitviewReadyEvent) => void;
components: PanelCollection<ISplitviewPanelProps>; components: PanelCollection<ISplitviewPanelProps>;
proportionalLayout?: boolean; proportionalLayout?: boolean;
hideBorders?: boolean; hideBorders?: boolean;
@ -58,7 +58,7 @@ export const SplitviewReact = React.forwardRef(
React.useEffect(() => { React.useEffect(() => {
const splitview = new SplitviewComponent(domRef.current!, { const splitview = new SplitviewComponent(domRef.current!, {
orientation: props.orientation, orientation: props.orientation || Orientation.HORIZONTAL,
frameworkComponents: props.components, frameworkComponents: props.components,
frameworkWrapper: { frameworkWrapper: {
createComponent: ( createComponent: (

View File

@ -61,18 +61,17 @@ export interface ISplitviewComponent extends IDisposable {
readonly onDidAddView: Event<IView>; readonly onDidAddView: Event<IView>;
readonly onDidRemoveView: Event<IView>; readonly onDidRemoveView: Event<IView>;
readonly onDidLayoutFromJSON: Event<void>; readonly onDidLayoutFromJSON: Event<void>;
readonly panels: SplitviewPanel[];
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void; updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void;
addPanel(options: AddSplitviewComponentOptions): void; addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel;
layout(width: number, height: number): void; layout(width: number, height: number): void;
onDidLayoutChange: Event<void>; onDidLayoutChange: Event<void>;
toJSON(): SerializedSplitview; toJSON(): SerializedSplitview;
fromJSON(serializedSplitview: SerializedSplitview): void; fromJSON(serializedSplitview: SerializedSplitview): void;
resizeToFit(): void;
focus(): void; focus(): void;
getPanel(id: string): ISplitviewPanel | undefined; getPanel(id: string): ISplitviewPanel | undefined;
setActive(view: ISplitviewPanel, skipFocus?: boolean): void; setActive(view: ISplitviewPanel, skipFocus?: boolean): void;
removePanel(panel: ISplitviewPanel, sizing?: Sizing): void; removePanel(panel: ISplitviewPanel, sizing?: Sizing): void;
getPanels(): SplitviewPanel[];
setVisible(panel: ISplitviewPanel, visible: boolean): void; setVisible(panel: ISplitviewPanel, visible: boolean): void;
movePanel(from: number, to: number): void; movePanel(from: number, to: number): void;
} }
@ -87,7 +86,7 @@ export class SplitviewComponent
private _disposable = new MutableDisposable(); private _disposable = new MutableDisposable();
private _splitview!: Splitview; private _splitview!: Splitview;
private _activePanel: SplitviewPanel | undefined; private _activePanel: SplitviewPanel | undefined;
private panels = new Map<string, IValueDisposable<SplitviewPanel>>(); private _panels = new Map<string, IValueDisposable<SplitviewPanel>>();
private _options: SplitviewComponentOptions; private _options: SplitviewComponentOptions;
private readonly _onDidLayoutfromJSON = new Emitter<void>(); private readonly _onDidLayoutfromJSON = new Emitter<void>();
@ -102,15 +101,23 @@ export class SplitviewComponent
private readonly _onDidLayoutChange = new Emitter<void>(); private readonly _onDidLayoutChange = new Emitter<void>();
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event; readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
get options() { get panels(): SplitviewPanel[] {
return this.splitview.getViews();
}
get options(): SplitviewComponentOptions {
return this._options; return this._options;
} }
get orientation() { get length(): number {
return this._panels.size;
}
get orientation(): Orientation {
return this.splitview.orientation; return this.splitview.orientation;
} }
get splitview() { get splitview(): Splitview {
return this._splitview; return this._splitview;
} }
@ -128,30 +135,26 @@ export class SplitviewComponent
); );
} }
get minimumSize() { get minimumSize(): number {
return this.splitview.minimumSize; return this.splitview.minimumSize;
} }
get maximumSize() { get maximumSize(): number {
return this.splitview.maximumSize; return this.splitview.maximumSize;
} }
get height() { get height(): number {
return this.splitview.orientation === Orientation.HORIZONTAL return this.splitview.orientation === Orientation.HORIZONTAL
? this.splitview.orthogonalSize ? this.splitview.orthogonalSize
: this.splitview.size; : this.splitview.size;
} }
get width() { get width(): number {
return this.splitview.orientation === Orientation.HORIZONTAL return this.splitview.orientation === Orientation.HORIZONTAL
? this.splitview.size ? this.splitview.size
: this.splitview.orthogonalSize; : this.splitview.orthogonalSize;
} }
get length() {
return this.panels.size;
}
constructor( constructor(
private readonly element: HTMLElement, private readonly element: HTMLElement,
options: SplitviewComponentOptions options: SplitviewComponentOptions
@ -195,23 +198,23 @@ export class SplitviewComponent
); );
} }
focus() { focus(): void {
this._activePanel?.focus(); this._activePanel?.focus();
} }
movePanel(from: number, to: number) { movePanel(from: number, to: number): void {
this.splitview.moveView(from, to); this.splitview.moveView(from, to);
} }
setVisible(panel: SplitviewPanel, visible: boolean) { setVisible(panel: SplitviewPanel, visible: boolean): void {
const index = this.getPanels().indexOf(panel); const index = this.panels.indexOf(panel);
this.splitview.setViewVisible(index, visible); this.splitview.setViewVisible(index, visible);
} }
setActive(view: SplitviewPanel, skipFocus?: boolean) { setActive(view: SplitviewPanel, skipFocus?: boolean): void {
this._activePanel = view; this._activePanel = view;
this.getPanels() this.panels
.filter((v) => v !== view) .filter((v) => v !== view)
.forEach((v) => { .forEach((v) => {
v.api._onDidActiveChange.fire({ isActive: false }); v.api._onDidActiveChange.fire({ isActive: false });
@ -225,12 +228,8 @@ export class SplitviewComponent
} }
} }
getPanels(): SplitviewPanel[] { removePanel(panel: SplitviewPanel, sizing?: Sizing): void {
return this.splitview.getViews(); const disposable = this._panels.get(panel.id);
}
removePanel(panel: SplitviewPanel, sizing?: Sizing) {
const disposable = this.panels.get(panel.id);
if (!disposable) { if (!disposable) {
throw new Error(`unknown splitview panel ${panel.id}`); throw new Error(`unknown splitview panel ${panel.id}`);
@ -239,23 +238,23 @@ export class SplitviewComponent
disposable.disposable.dispose(); disposable.disposable.dispose();
disposable.value.dispose(); disposable.value.dispose();
this.panels.delete(panel.id); this._panels.delete(panel.id);
const index = this.getPanels().findIndex((_) => _ === panel); const index = this.panels.findIndex((_) => _ === panel);
this.splitview.removeView(index, sizing); this.splitview.removeView(index, sizing);
const panels = this.getPanels(); const panels = this.panels;
if (panels.length > 0) { if (panels.length > 0) {
this.setActive(panels[panels.length - 1]); this.setActive(panels[panels.length - 1]);
} }
} }
getPanel(id: string): SplitviewPanel | undefined { getPanel(id: string): SplitviewPanel | undefined {
return this.getPanels().find((view) => view.id === id); return this.panels.find((view) => view.id === id);
} }
addPanel(options: AddSplitviewComponentOptions): void { addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel {
if (this.panels.has(options.id)) { if (this._panels.has(options.id)) {
throw new Error(`panel ${options.id} already exists`); throw new Error(`panel ${options.id} already exists`);
} }
@ -292,18 +291,8 @@ export class SplitviewComponent
this.doAddView(view); this.doAddView(view);
this.setActive(view); this.setActive(view);
}
/** return view;
* Resize the layout to fit the parent container
*/
resizeToFit(): void {
if (!this.element.parentElement) {
return;
}
const { width, height } =
this.element.parentElement.getBoundingClientRect();
this.layout(width, height);
} }
layout(width: number, height: number): void { layout(width: number, height: number): void {
@ -314,7 +303,7 @@ export class SplitviewComponent
this.splitview.layout(size, orthogonalSize); this.splitview.layout(size, orthogonalSize);
} }
private doAddView(view: SplitviewPanel) { private doAddView(view: SplitviewPanel): void {
const disposable = view.api.onDidFocusChange((event) => { const disposable = view.api.onDidFocusChange((event) => {
if (!event.isFocused) { if (!event.isFocused) {
return; return;
@ -322,7 +311,7 @@ export class SplitviewComponent
this.setActive(view, true); this.setActive(view, true);
}); });
this.panels.set(view.id, { disposable, value: view }); this._panels.set(view.id, { disposable, value: view });
} }
toJSON(): SerializedSplitview { toJSON(): SerializedSplitview {
@ -349,11 +338,11 @@ export class SplitviewComponent
fromJSON(serializedSplitview: SerializedSplitview): void { fromJSON(serializedSplitview: SerializedSplitview): void {
const { views, orientation, size, activeView } = serializedSplitview; const { views, orientation, size, activeView } = serializedSplitview;
for (const [_, value] of this.panels.entries()) { for (const [_, value] of this._panels.entries()) {
value.disposable.dispose(); value.disposable.dispose();
value.value.dispose(); value.value.dispose();
} }
this.panels.clear(); this._panels.clear();
this.splitview.dispose(); this.splitview.dispose();
const queue: Function[] = []; const queue: Function[] = [];
@ -366,7 +355,7 @@ export class SplitviewComponent
views: views.map((view) => { views: views.map((view) => {
const data = view.data; const data = view.data;
if (this.panels.has(data.id)) { if (this._panels.has(data.id)) {
throw new Error(`panel ${data.id} already exists`); throw new Error(`panel ${data.id} already exists`);
} }
@ -422,12 +411,12 @@ export class SplitviewComponent
this._onDidLayoutfromJSON.fire(); this._onDidLayoutfromJSON.fire();
} }
dispose() { dispose(): void {
for (const [_, value] of this.panels.entries()) { for (const [_, value] of this._panels.entries()) {
value.disposable.dispose(); value.disposable.dispose();
value.value.dispose(); value.value.dispose();
} }
this.panels.clear(); this._panels.clear();
this.splitview.dispose(); this.splitview.dispose();