Merge pull request #454 from mathuo/447-feature-request-adding-a-gap-around-panels

work-in-progress: group gaps
This commit is contained in:
mathuo 2024-01-29 22:22:28 +00:00 committed by GitHub
commit 47b691b6b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 81 additions and 46 deletions

View File

@ -8,7 +8,7 @@ describe('groupPanelApi', () => {
const accessor: Partial<DockviewComponent> = {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
const panelMock = jest.fn<DockviewPanel, []>(() => {
@ -44,7 +44,7 @@ describe('groupPanelApi', () => {
const accessor: Partial<DockviewComponent> = {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
const groupViewPanel = new DockviewGroupPanel(
<DockviewComponent>accessor,
@ -74,7 +74,7 @@ describe('groupPanelApi', () => {
const accessor: Partial<DockviewComponent> = {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
const groupViewPanel = new DockviewGroupPanel(
<DockviewComponent>accessor,

View File

@ -16,7 +16,7 @@ describe('tabsContainer', () => {
return {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -71,7 +71,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid',
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -139,7 +139,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid',
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -204,7 +204,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid',
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -269,7 +269,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid',
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
options: { parentElement: document.createElement('div') },
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -336,7 +336,7 @@ describe('tabsContainer', () => {
test('left actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
}) as DockviewComponent;
@ -402,7 +402,7 @@ describe('tabsContainer', () => {
test('right actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
}) as DockviewComponent;
@ -468,7 +468,7 @@ describe('tabsContainer', () => {
test('that a tab will become floating when clicked if not floating and shift is selected', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),
@ -514,21 +514,21 @@ describe('tabsContainer', () => {
},
{ inDragMode: true }
);
expect(accessor.addFloatingGroup).toBeCalledTimes(1);
expect(eventPreventDefaultSpy).toBeCalledTimes(1);
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1);
expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(1);
const event2 = new KeyboardEvent('mousedown', { shiftKey: false });
const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault');
fireEvent(container, event2);
expect(accessor.addFloatingGroup).toBeCalledTimes(1);
expect(eventPreventDefaultSpy2).toBeCalledTimes(0);
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1);
expect(eventPreventDefaultSpy2).toHaveBeenCalledTimes(0);
});
test('that a tab that is already floating cannot be floated again', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),
@ -580,7 +580,7 @@ describe('tabsContainer', () => {
test('that selecting a tab with shift down will move that tab into a new floating group', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),
@ -642,7 +642,7 @@ describe('tabsContainer', () => {
test('pre header actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),
@ -712,7 +712,7 @@ describe('tabsContainer', () => {
test('left header actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),
@ -782,7 +782,7 @@ describe('tabsContainer', () => {
test('right header actions', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
element: document.createElement('div'),

View File

@ -243,7 +243,7 @@ describe('dockviewGroupPanelModel', () => {
options = {};
dockview = (<Partial<DockviewComponent>>{
options: {},
options: { parentElement: document.createElement('div') },
createWatermarkComponent: () => new Watermark(),
doSetGroupActive: jest.fn(),
id: 'dockview-1',
@ -639,6 +639,7 @@ describe('dockviewGroupPanelModel', () => {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
onDidAddPanel: jest.fn(),
@ -699,6 +700,7 @@ describe('dockviewGroupPanelModel', () => {
id: 'testcomponentid',
options: {
showDndOverlay: () => true,
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
onDidAddPanel: jest.fn(),
@ -790,6 +792,7 @@ describe('dockviewGroupPanelModel', () => {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
doSetGroupActive: jest.fn(),
@ -863,6 +866,7 @@ describe('dockviewGroupPanelModel', () => {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
doSetGroupActive: jest.fn(),
@ -941,6 +945,7 @@ describe('dockviewGroupPanelModel', () => {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
doSetGroupActive: jest.fn(),

View File

@ -38,6 +38,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: contentMock,
},
@ -131,6 +132,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: contentMock,
},
@ -159,6 +161,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: contentMock,
},
@ -190,6 +193,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: contentMock,
},
@ -222,6 +226,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: contentMock,
},
@ -244,6 +249,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
components: {
contentComponent: jest.fn().mockImplementation(() => {
return contentMock;
@ -271,6 +277,7 @@ describe('dockviewGroupPanel', () => {
accessorMock = jest.fn<DockviewComponent, []>(() => {
const partial: Partial<DockviewComponent> = {
options: {
parentElement: document.createElement('div'),
frameworkComponents: {
contentComponent: contentMock,
},

View File

@ -14,6 +14,32 @@
.dv-overlay-render-container {
position: relative;
}
.split-view-container {
&.horizontal {
> .view-container > .view {
&:not(:last-child) {
border-right: var(--dv-group-gap-size) solid transparent;
}
&:not(:first-child) {
border-left: var(--dv-group-gap-size) solid transparent;
}
}
}
&.vertical {
> .view-container > .view {
&:not(:last-child) {
border-bottom: var(--dv-group-gap-size) solid transparent;
}
&:not(:first-child) {
border-top: var(--dv-group-gap-size) solid transparent;
}
}
}
}
}
.groupview {

View File

@ -90,7 +90,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
group: DockviewGroupPanel
) => IHeaderActionsRenderer;
singleTabMode?: 'fullwidth' | 'default';
parentElement?: HTMLElement;
parentElement: HTMLElement;
disableFloatingGroups?: boolean;
floatingGroupBounds?:
| 'boundedWithinViewport'

View File

@ -0,0 +1,4 @@
.dv-root-wrapper {
height: 100%;
width: 100%;
}

View File

@ -1,7 +1,7 @@
import { Emitter, Event, TickDelayedEvent } from '../events';
import { getGridLocation, Gridview, IGridView } from './gridview';
import { Position } from '../dnd/droptarget';
import { IValueDisposable } from '../lifecycle';
import { Disposable, IValueDisposable } from '../lifecycle';
import { sequentialNumberGenerator } from '../math';
import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview';
import { IPanel } from '../panel/types';
@ -32,7 +32,7 @@ export interface BaseGridOptions {
readonly proportionalLayout: boolean;
readonly orientation: Orientation;
readonly styles?: ISplitviewStyles;
readonly parentElement?: HTMLElement;
readonly parentElement: HTMLElement;
readonly disableAutoResizing?: boolean;
}
@ -134,7 +134,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
}
constructor(options: BaseGridOptions) {
super(options.parentElement, options.disableAutoResizing);
super(document.createElement('div'), options.disableAutoResizing);
options.parentElement.appendChild(this.element);
this.gridview = new Gridview(
!!options.proportionalLayout,
@ -147,6 +149,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.layout(0, 0, true); // set some elements height/widths
this.addDisposables(
Disposable.from(() => {
this.element.parentElement?.removeChild(this.element);
}),
this.gridview.onDidChange(() => {
this._bufferOnDidLayoutChange.fire();
}),

View File

@ -17,5 +17,5 @@ export interface GridviewComponentOptions {
};
frameworkComponentFactory?: FrameworkFactory<GridviewPanel>;
styles?: ISplitviewStyles;
parentElement?: HTMLElement;
parentElement: HTMLElement;
}

View File

@ -25,5 +25,5 @@ export interface PaneviewComponentOptions {
};
disableDnd?: boolean;
showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean;
parentElement?: HTMLElement;
parentElement: HTMLElement;
}

View File

@ -17,19 +17,12 @@ export abstract class Resizable extends CompositeDisposable {
this._disableResizing = value;
}
constructor(parentElement?: HTMLElement, disableResizing = false) {
constructor(parentElement: HTMLElement, disableResizing = false) {
super();
this._disableResizing = disableResizing;
if (parentElement) {
this._element = parentElement;
} else {
this._element = document.createElement('div');
this._element.style.height = '100%';
this._element.style.width = '100%';
this._element.className = 'dv-resizable-container';
}
this._element = parentElement;
this.addDisposables(
watchElementResize(this._element, (entry) => {

View File

@ -28,5 +28,5 @@ export interface SplitviewComponentOptions extends SplitViewOptions {
[componentName: string]: any;
};
frameworkWrapper?: FrameworkFactory<SplitviewPanel>;
parentElement?: HTMLElement;
parentElement: HTMLElement;
}

View File

@ -12,6 +12,7 @@
@mixin dockview-theme-dark-mixin {
@include dockview-theme-core-mixin();
//
--dv-group-view-background-color: #1e1e1e;
//
@ -228,13 +229,7 @@
}
@mixin dockview-design-replit-mixin {
&.dv-dockview {
padding: 3px;
}
.view:has(> .groupview) {
padding: 3px;
}
--dv-group-gap-size: 3px;
.dv-resize-container:has(> .groupview) {
border-radius: 8px;

View File

@ -93,7 +93,7 @@ export const App: React.FC = (props: { theme?: string }) => {
);
};
const Container = () => {
const Container = (props: any) => {
const [value, setValue] = React.useState<string>('50');
return (
@ -108,7 +108,7 @@ const Container = () => {
value={value}
/>
<div style={{ height: `${value}%`, width: `${value}%` }}>
<App />
<App {...props} />
</div>
</div>
);