diff --git a/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts b/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts index 1d610ba99..e2474bc63 100644 --- a/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts +++ b/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts @@ -8,7 +8,7 @@ describe('groupPanelApi', () => { const accessor: Partial = { onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; const panelMock = jest.fn(() => { @@ -44,7 +44,7 @@ describe('groupPanelApi', () => { const accessor: Partial = { onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; const groupViewPanel = new DockviewGroupPanel( accessor, @@ -74,7 +74,7 @@ describe('groupPanelApi', () => { const accessor: Partial = { onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; const groupViewPanel = new DockviewGroupPanel( accessor, diff --git a/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts b/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts index 58a007393..8d3a16b19 100644 --- a/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/components/titlebar/tabsContainer.spec.ts @@ -16,7 +16,7 @@ describe('tabsContainer', () => { return { onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; }); const groupviewMock = jest.fn, []>( @@ -71,7 +71,7 @@ describe('tabsContainer', () => { id: 'testcomponentid', onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; }); const groupviewMock = jest.fn, []>( @@ -139,7 +139,7 @@ describe('tabsContainer', () => { id: 'testcomponentid', onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; }); const groupviewMock = jest.fn, []>( @@ -204,7 +204,7 @@ describe('tabsContainer', () => { id: 'testcomponentid', onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; }); const groupviewMock = jest.fn, []>( @@ -269,7 +269,7 @@ describe('tabsContainer', () => { id: 'testcomponentid', onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), - options: {}, + options: { parentElement: document.createElement('div') }, }; }); const groupviewMock = jest.fn, []>( @@ -336,7 +336,7 @@ describe('tabsContainer', () => { test('left actions', () => { const accessorMock = jest.fn(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - 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(() => { return (>{ - options: {}, + options: { parentElement: document.createElement('div') }, onDidAddPanel: jest.fn(), onDidRemovePanel: jest.fn(), element: document.createElement('div'), diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts index 6c58659dd..704a26009 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts @@ -243,7 +243,7 @@ describe('dockviewGroupPanelModel', () => { options = {}; dockview = (>{ - 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(), diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts index aacf0ca93..01fb2813f 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts @@ -38,6 +38,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: contentMock, }, @@ -131,6 +132,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: contentMock, }, @@ -159,6 +161,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: contentMock, }, @@ -190,6 +193,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: contentMock, }, @@ -222,6 +226,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: contentMock, }, @@ -244,6 +249,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), components: { contentComponent: jest.fn().mockImplementation(() => { return contentMock; @@ -271,6 +277,7 @@ describe('dockviewGroupPanel', () => { accessorMock = jest.fn(() => { const partial: Partial = { options: { + parentElement: document.createElement('div'), frameworkComponents: { contentComponent: contentMock, }, diff --git a/packages/dockview-core/src/dockview/dockviewComponent.scss b/packages/dockview-core/src/dockview/dockviewComponent.scss index 54a0e290d..22261c1f4 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.scss +++ b/packages/dockview-core/src/dockview/dockviewComponent.scss @@ -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 { diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 60a3953e4..a3e794daf 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -90,7 +90,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions { group: DockviewGroupPanel ) => IHeaderActionsRenderer; singleTabMode?: 'fullwidth' | 'default'; - parentElement?: HTMLElement; + parentElement: HTMLElement; disableFloatingGroups?: boolean; floatingGroupBounds?: | 'boundedWithinViewport' diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.scss b/packages/dockview-core/src/gridview/baseComponentGridview.scss new file mode 100644 index 000000000..4b12e2437 --- /dev/null +++ b/packages/dockview-core/src/gridview/baseComponentGridview.scss @@ -0,0 +1,4 @@ +.dv-root-wrapper { + height: 100%; + width: 100%; +} diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts index 2e4159a9b..12e877d2f 100644 --- a/packages/dockview-core/src/gridview/baseComponentGridview.ts +++ b/packages/dockview-core/src/gridview/baseComponentGridview.ts @@ -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 } 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 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(); }), diff --git a/packages/dockview-core/src/gridview/options.ts b/packages/dockview-core/src/gridview/options.ts index be37ce4d2..c40429358 100644 --- a/packages/dockview-core/src/gridview/options.ts +++ b/packages/dockview-core/src/gridview/options.ts @@ -17,5 +17,5 @@ export interface GridviewComponentOptions { }; frameworkComponentFactory?: FrameworkFactory; styles?: ISplitviewStyles; - parentElement?: HTMLElement; + parentElement: HTMLElement; } diff --git a/packages/dockview-core/src/paneview/options.ts b/packages/dockview-core/src/paneview/options.ts index 3523528d1..1d784e4f7 100644 --- a/packages/dockview-core/src/paneview/options.ts +++ b/packages/dockview-core/src/paneview/options.ts @@ -25,5 +25,5 @@ export interface PaneviewComponentOptions { }; disableDnd?: boolean; showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean; - parentElement?: HTMLElement; + parentElement: HTMLElement; } diff --git a/packages/dockview-core/src/resizable.ts b/packages/dockview-core/src/resizable.ts index 02df77be0..c05b4cb4b 100644 --- a/packages/dockview-core/src/resizable.ts +++ b/packages/dockview-core/src/resizable.ts @@ -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) => { diff --git a/packages/dockview-core/src/splitview/options.ts b/packages/dockview-core/src/splitview/options.ts index a0c179e97..823f5a688 100644 --- a/packages/dockview-core/src/splitview/options.ts +++ b/packages/dockview-core/src/splitview/options.ts @@ -28,5 +28,5 @@ export interface SplitviewComponentOptions extends SplitViewOptions { [componentName: string]: any; }; frameworkWrapper?: FrameworkFactory; - parentElement?: HTMLElement; + parentElement: HTMLElement; } diff --git a/packages/dockview-core/src/theme.scss b/packages/dockview-core/src/theme.scss index 6a10a1a35..007fc426e 100644 --- a/packages/dockview-core/src/theme.scss +++ b/packages/dockview-core/src/theme.scss @@ -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; diff --git a/packages/docs/sandboxes/resizecontainer-dockview/src/app.tsx b/packages/docs/sandboxes/resizecontainer-dockview/src/app.tsx index 95fb87945..25c397bc2 100644 --- a/packages/docs/sandboxes/resizecontainer-dockview/src/app.tsx +++ b/packages/docs/sandboxes/resizecontainer-dockview/src/app.tsx @@ -93,7 +93,7 @@ export const App: React.FC = (props: { theme?: string }) => { ); }; -const Container = () => { +const Container = (props: any) => { const [value, setValue] = React.useState('50'); return ( @@ -108,7 +108,7 @@ const Container = () => { value={value} />
- +
);