diff --git a/packages/dockview-core/src/dockview/dockviewComponent.scss b/packages/dockview-core/src/dockview/dockviewComponent.scss index 22261c1f4..f47d90bab 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.scss +++ b/packages/dockview-core/src/dockview/dockviewComponent.scss @@ -19,11 +19,15 @@ &.horizontal { > .view-container > .view { &:not(:last-child) { - border-right: var(--dv-group-gap-size) solid transparent; + .groupview { + border-right: var(--dv-group-gap-size) solid transparent; + } } &:not(:first-child) { - border-left: var(--dv-group-gap-size) solid transparent; + .groupview { + border-left: var(--dv-group-gap-size) solid transparent; + } } } } @@ -31,11 +35,16 @@ &.vertical { > .view-container > .view { &:not(:last-child) { - border-bottom: var(--dv-group-gap-size) solid transparent; + .groupview { + border-bottom: var(--dv-group-gap-size) solid + transparent; + } } &:not(:first-child) { - border-top: var(--dv-group-gap-size) solid transparent; + .groupview { + border-top: var(--dv-group-gap-size) solid transparent; + } } } } diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 4b85fcb74..8342faa9b 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -148,92 +148,6 @@ export interface SerializedDockview { popoutGroups?: SerializedPopoutGroup[]; } -function typeValidate3(data: GroupPanelViewState, path: string): void { - if (typeof data.id !== 'string') { - throw new Error(`${path}.id must be a string`); - } - - if ( - typeof data.activeView !== 'string' || - typeof data.activeView !== 'undefined' - ) { - throw new Error(`${path}.activeView must be a string of undefined`); - } -} - -function typeValidate2( - data: SerializedGridObject, - path: string -): void { - if (typeof data.size !== 'number' && typeof data.size !== 'undefined') { - throw new Error(`${path}.size must be a number or undefined`); - } - - if ( - typeof data.visible !== 'boolean' && - typeof data.visible !== 'undefined' - ) { - throw new Error(`${path}.visible must be a boolean or undefined`); - } - - if (data.type === 'leaf') { - if ( - typeof data.data !== 'object' || - data.data === null || - Array.isArray(data.data) - ) { - throw new Error('object must be a non-null object'); - } - - typeValidate3(data.data, `${path}.data`); - } else if (data.type === 'branch') { - if (!Array.isArray(data.data)) { - throw new Error(`${path}.data must be an array`); - } - } else { - throw new Error(`${path}.type must be onew of {'branch', 'leaf'}`); - } -} - -function typeValidate(data: SerializedDockview): void { - if (typeof data !== 'object' || data === null) { - throw new Error('object must be a non-null object'); - } - - const { grid, panels, activeGroup, floatingGroups } = data; - - if (typeof grid !== 'object' || grid === null) { - throw new Error("'.grid' must be a non-null object"); - } - - if (typeof grid.height !== 'number') { - throw new Error("'.grid.height' must be a number"); - } - - if (typeof grid.width !== 'number') { - throw new Error("'.grid.width' must be a number"); - } - - if (typeof grid.root !== 'object' || grid.root === null) { - throw new Error("'.grid.root' must be a non-null object"); - } - - if (grid.root.type !== 'branch') { - throw new Error(".grid.root.type must be of type 'branch'"); - } - - if ( - grid.orientation !== Orientation.HORIZONTAL && - grid.orientation !== Orientation.VERTICAL - ) { - throw new Error( - `'.grid.width' must be one of {${Orientation.HORIZONTAL}, ${Orientation.VERTICAL}}` - ); - } - - typeValidate2(grid.root, '.grid.root'); -} - type MoveGroupOptions = { from: { group: DockviewGroupPanel }; to: { group: DockviewGroupPanel; position: Position }; diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 5b1c7080a..5791730af 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -187,7 +187,7 @@ type AddPanelFloatingGroupUnion = { }; type AddPanelPositionUnion = { - floating: false | never; + floating: false; position: AddPanelPositionOptions; }; diff --git a/packages/dockview-core/src/dockview/types.ts b/packages/dockview-core/src/dockview/types.ts index da38ed544..8bff4e2fc 100644 --- a/packages/dockview-core/src/dockview/types.ts +++ b/packages/dockview-core/src/dockview/types.ts @@ -1,4 +1,3 @@ -import { IDockviewComponent } from './dockviewComponent'; import { DockviewPanelApi } from '../api/dockviewPanelApi'; import { PanelInitParameters, IPanel } from '../panel/types'; import { DockviewApi } from '../api/component.api'; @@ -22,46 +21,36 @@ export interface WatermarkRendererInitParameters { group?: IDockviewGroupPanel; } +type RendererMethodOptionalList = + | 'dispose' + | 'update' + | 'layout' + | 'toJSON' + | 'focus'; + export interface IWatermarkRenderer - extends Optional< - Omit, - 'dispose' | 'update' | 'layout' | 'toJSON' | 'focus' - > { + extends Optional, RendererMethodOptionalList> { readonly element: HTMLElement; init: (params: WatermarkRendererInitParameters) => void; updateParentGroup(group: DockviewGroupPanel, visible: boolean): void; } export interface ITabRenderer - extends Optional< - Omit, - 'dispose' | 'update' | 'layout' | 'toJSON' | 'focus' - > { + extends Optional, RendererMethodOptionalList> { readonly element: HTMLElement; init(parameters: GroupPanelPartInitParameters): void; } export interface IContentRenderer - extends Optional< - Omit, - 'dispose' | 'update' | 'layout' | 'toJSON' | 'focus' - > { + extends Optional, RendererMethodOptionalList> { readonly element: HTMLElement; init(parameters: GroupPanelPartInitParameters): void; } // watermark component -export interface WatermarkPartInitParameters { - accessor: IDockviewComponent; -} - // constructors -export interface WatermarkConstructor { - new (): IWatermarkRenderer; -} - export interface IGroupPanelInitParameters extends PanelInitParameters, HeaderPartInitParameters { diff --git a/packages/dockview-core/src/dockview/validate.ts b/packages/dockview-core/src/dockview/validate.ts new file mode 100644 index 000000000..8cf66a4bf --- /dev/null +++ b/packages/dockview-core/src/dockview/validate.ts @@ -0,0 +1,90 @@ +// import { SerializedGridObject } from '../gridview/gridview'; +// import { Orientation } from '../splitview/splitview'; +// import { SerializedDockview } from './dockviewComponent'; +// import { GroupPanelViewState } from './dockviewGroupPanelModel'; + +// function typeValidate3(data: GroupPanelViewState, path: string): void { +// if (typeof data.id !== 'string') { +// throw new Error(`${path}.id must be a string`); +// } + +// if ( +// typeof data.activeView !== 'string' || +// typeof data.activeView !== 'undefined' +// ) { +// throw new Error(`${path}.activeView must be a string of undefined`); +// } +// } + +// function typeValidate2( +// data: SerializedGridObject, +// path: string +// ): void { +// if (typeof data.size !== 'number' && typeof data.size !== 'undefined') { +// throw new Error(`${path}.size must be a number or undefined`); +// } + +// if ( +// typeof data.visible !== 'boolean' && +// typeof data.visible !== 'undefined' +// ) { +// throw new Error(`${path}.visible must be a boolean or undefined`); +// } + +// if (data.type === 'leaf') { +// if ( +// typeof data.data !== 'object' || +// data.data === null || +// Array.isArray(data.data) +// ) { +// throw new Error('object must be a non-null object'); +// } + +// typeValidate3(data.data, `${path}.data`); +// } else if (data.type === 'branch') { +// if (!Array.isArray(data.data)) { +// throw new Error(`${path}.data must be an array`); +// } +// } else { +// throw new Error(`${path}.type must be onew of {'branch', 'leaf'}`); +// } +// } + +// function typeValidate(data: SerializedDockview): void { +// if (typeof data !== 'object' || data === null) { +// throw new Error('object must be a non-null object'); +// } + +// const { grid, panels, activeGroup, floatingGroups } = data; + +// if (typeof grid !== 'object' || grid === null) { +// throw new Error("'.grid' must be a non-null object"); +// } + +// if (typeof grid.height !== 'number') { +// throw new Error("'.grid.height' must be a number"); +// } + +// if (typeof grid.width !== 'number') { +// throw new Error("'.grid.width' must be a number"); +// } + +// if (typeof grid.root !== 'object' || grid.root === null) { +// throw new Error("'.grid.root' must be a non-null object"); +// } + +// if (grid.root.type !== 'branch') { +// throw new Error(".grid.root.type must be of type 'branch'"); +// } + +// if ( +// grid.orientation !== Orientation.HORIZONTAL && +// grid.orientation !== Orientation.VERTICAL +// ) { +// throw new Error( +// `'.grid.width' must be one of {${Orientation.HORIZONTAL}, ${Orientation.VERTICAL}}` +// ); +// } + +// typeValidate2(grid.root, '.grid.root'); +// } diff --git a/packages/dockview-core/src/index.ts b/packages/dockview-core/src/index.ts index 74554d9e6..7c007deb6 100644 --- a/packages/dockview-core/src/index.ts +++ b/packages/dockview-core/src/index.ts @@ -1,14 +1,16 @@ export * from './dnd/dataTransfer'; /** - * Events, Emitters and Disposables are very common concepts that most codebases will contain. - * We export them with a 'Dockview' prefix here to prevent accidental use by others. + * Events, Emitters and Disposables are very common concepts that many codebases will contain, however we need + * to export them for dockview framework packages to use. + * To be a good citizen these are exported with a `Dockview` prefix to prevent accidental use by others. */ export { Emitter as DockviewEmitter, Event as DockviewEvent } from './events'; export { IDisposable as IDockviewDisposable, MutableDisposable as DockviewMutableDisposable, CompositeDisposable as DockviewCompositeDisposable, + Disposable as DockviewDisposable, } from './lifecycle'; export * from './panel/types'; diff --git a/packages/dockview/src/react.ts b/packages/dockview/src/react.ts index d91fdce16..85e82dbd0 100644 --- a/packages/dockview/src/react.ts +++ b/packages/dockview/src/react.ts @@ -1,6 +1,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { IFrameworkPart, IDockviewDisposable, Parameters } from 'dockview-core'; +import { + DockviewDisposable, + IFrameworkPart, + IDockviewDisposable, + Parameters, +} from 'dockview-core'; export interface ReactPortalStore { addPortal: (portal: React.ReactPortal) => IDockviewDisposable; @@ -174,19 +179,15 @@ export const usePortalsLifecycle: PortalLifecycleHook = () => { const addPortal = React.useCallback((portal: React.ReactPortal) => { setPortals((existingPortals) => [...existingPortals, portal]); let disposed = false; - return { - dispose: () => { - if (disposed) { - throw new Error( - 'invalid operation: resource already disposed' - ); - } - disposed = true; - setPortals((existingPortals) => - existingPortals.filter((p) => p !== portal) - ); - }, - }; + return DockviewDisposable.from(() => { + if (disposed) { + throw new Error('invalid operation: resource already disposed'); + } + disposed = true; + setPortals((existingPortals) => + existingPortals.filter((p) => p !== portal) + ); + }); }, []); return [portals, addPortal];