diff --git a/packages/dockview/src/__tests__/react/react.spec.tsx b/packages/dockview/src/__tests__/react/react.spec.tsx new file mode 100644 index 000000000..4bd7dbbf2 --- /dev/null +++ b/packages/dockview/src/__tests__/react/react.spec.tsx @@ -0,0 +1,86 @@ +import { ReactPart } from '../../react/react'; +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; + +interface TestInterface { + valueA: string; + valueB: number; +} + +describe('react', () => { + describe('ReactPart', () => { + test('update underlying component via ReactPart class', () => { + let api: ReactPart; + + const onReady = (_api: ReactPart) => { + api = _api; + }; + + render(); + + expect(api).toBeTruthy(); + + expect(screen.getByTestId('valueA').textContent).toBe('stringA'); + expect(screen.getByTestId('valueB').textContent).toBe('42'); + + api.update({ valueB: '32' }); + + expect(screen.getByTestId('valueA').textContent).toBe('stringA'); + expect(screen.getByTestId('valueB').textContent).toBe('32'); + + api.update({ valueA: 'anotherStringA', valueB: '22' }); + + expect(screen.getByTestId('valueA').textContent).toBe( + 'anotherStringA' + ); + expect(screen.getByTestId('valueB').textContent).toBe('22'); + }); + }); +}); + +const Component = (props: TestInterface) => { + return ( +
+
{props.valueA}
+
{props.valueB}
+
+ ); +}; + +const TestWrapper = (props: { + component: React.FunctionComponent; + onReady: (api: ReactPart) => void; +}) => { + const [portal, setPortal] = React.useState([]); + const ref = React.useRef(null); + + React.useEffect(() => { + const cut = new ReactPart( + ref.current, + { + addPortal: (portal: React.ReactPortal) => { + setPortal((_) => [..._, portal]); + + return { + dispose: () => { + setPortal((_) => _.filter((_) => _ !== portal)); + }, + }; + }, + }, + props.component, + { + valueA: 'stringA', + valueB: 42, + } + ); + + props.onReady(cut); + + return () => { + cut.dispose(); + }; + }, []); + + return
{portal}
; +}; diff --git a/packages/dockview/src/dnd/abstractDragHandler.ts b/packages/dockview/src/dnd/abstractDragHandler.ts index b6fc1d288..57611330a 100644 --- a/packages/dockview/src/dnd/abstractDragHandler.ts +++ b/packages/dockview/src/dnd/abstractDragHandler.ts @@ -2,7 +2,6 @@ import { getElementsByTagName } from '../dom'; import { addDisposableListener, Emitter } from '../events'; import { focusedElement } from '../focusedElement'; import { CompositeDisposable, IDisposable } from '../lifecycle'; -import { DATA_KEY, LocalSelectionTransfer } from './dataTransfer'; export abstract class DragHandler extends CompositeDisposable { private iframes: HTMLElement[] = []; diff --git a/packages/dockview/src/dockview/dockviewComponent.ts b/packages/dockview/src/dockview/dockviewComponent.ts index 343294ff3..dfbbde81c 100644 --- a/packages/dockview/src/dockview/dockviewComponent.ts +++ b/packages/dockview/src/dockview/dockviewComponent.ts @@ -103,17 +103,6 @@ export interface IDockviewComponent extends IBaseGrid { onTabContextMenu: Event; moveToNext(options?: MovementOptions): void; moveToPrevious(options?: MovementOptions): void; - // createDragTarget( - // target: { - // element: HTMLElement; - // content: string; - // }, - // options: (() => PanelOptions) | PanelOptions - // ): IDisposable; - // addDndHandle( - // type: string, - // cb: (event: LayoutDropEvent) => PanelOptions - // ): void; setActivePanel(panel: IGroupPanel): void; focus(): void; toJSON(): SerializedDockview; @@ -138,13 +127,8 @@ export class DockviewComponent readonly onTabContextMenu: Event = this._onTabContextMenu.event; // everything else - // private drag = new MutableDisposable(); private _deserializer: IPanelDeserializer | undefined; private panelState: State = {}; - // private registry = new Map< - // string, - // (event: LayoutDropEvent) => PanelOptions - // >(); private _api: DockviewApi; private _options: DockviewComponentOptions; @@ -229,13 +213,6 @@ export class DockviewComponent this.layout(this.gridview.width, this.gridview.height, true); } - // addDndHandle( - // type: string, - // cb: (event: LayoutDropEvent) => PanelOptions - // ): void { - // this.registry.set(type, cb); - // } - focus(): void { this.activeGroup?.focus(); } @@ -244,58 +221,6 @@ export class DockviewComponent return this._panels.get(id)?.value; } - // createDragTarget( - // target: { - // element: HTMLElement; - // content: string; - // }, - // options: (() => PanelOptions) | PanelOptions - // ): IDisposable { - // return new CompositeDisposable( - // addDisposableListener(target.element, 'dragstart', (event) => { - // if (!event.dataTransfer) { - // throw new Error('unsupported'); - // } - - // const panelOptions = - // typeof options === 'function' ? options() : options; - - // const panel = this.panels.get(panelOptions.id)?.value; - // if (panel) { - // this.drag.value = panel.group!.model.startActiveDrag(panel); - // } - - // const data = JSON.stringify({ - // type: DragType.EXTERNAL, - // ...panelOptions, - // }); - - // LocalSelectionTransfer.getInstance().setData([data], this.id); - - // event.dataTransfer.effectAllowed = 'move'; - - // const dragImage = document.createElement('div'); - // dragImage.textContent = target.content; - // dragImage.classList.add('custom-dragging'); - - // document.body.appendChild(dragImage); - // event.dataTransfer.setDragImage( - // dragImage, - // event.offsetX, - // event.offsetY - // ); - // setTimeout(() => document.body.removeChild(dragImage), 0); - - // event.dataTransfer.setData(DATA_KEY, data); - // }), - // addDisposableListener(this.element, 'dragend', (ev) => { - // // drop events fire before dragend so we can remove this safely - // LocalSelectionTransfer.getInstance().clearData(this.id); - // this.drag.dispose(); - // }) - // ); - // } - setActivePanel(panel: IGroupPanel): void { if (!panel.group) { throw new Error(`Panel ${panel.id} has no associated group`); @@ -394,8 +319,6 @@ export class DockviewComponent const data = this.gridview.serialize(); - // const state = { ...this.panelState }; - const panels = Array.from(this._panels.values()).reduce( (collection, panel) => { if (!this.panelState[panel.value.id]) { @@ -736,7 +659,7 @@ export class DockviewComponent const dirtyPanels = Array.from(this.dirtyPanels); if (dirtyPanels.length === 0) { - // console.debug('[layout#syncConfigs] no dirty panels'); + // } this.dirtyPanels.clear(); diff --git a/packages/dockview/src/gridview/gridview.ts b/packages/dockview/src/gridview/gridview.ts index 236650b11..8dd1f95e4 100644 --- a/packages/dockview/src/gridview/gridview.ts +++ b/packages/dockview/src/gridview/gridview.ts @@ -419,13 +419,13 @@ export class Gridview implements IDisposable { for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; - const cachedVisibleSize = node.getChildCachedVisibleSize(i); + const nodeCachedVisibleSize = node.getChildCachedVisibleSize(i); children.push( this._getViews( child, orthogonal(orientation), - cachedVisibleSize + nodeCachedVisibleSize ) ); } @@ -643,7 +643,7 @@ export class Gridview implements IDisposable { const isSiblingVisible = parent.isChildVisible(0); parent.removeChild(0, sizing); - const sizes = grandParent.children.map((_, i) => + const sizes = grandParent.children.map((size, i) => grandParent.getChildSize(i) ); grandParent.removeChild(parentIndex, sizing); diff --git a/packages/dockview/src/groupview/groupview.ts b/packages/dockview/src/groupview/groupview.ts index 2b93af8c2..3b1e75a46 100644 --- a/packages/dockview/src/groupview/groupview.ts +++ b/packages/dockview/src/groupview/groupview.ts @@ -1,8 +1,7 @@ import { DockviewApi } from '../api/component.api'; import { timeoutAsPromise } from '../async'; import { getPanelData } from '../dnd/dataTransfer'; -import { Position } from '../dnd/droptarget'; -import { Droptarget } from '../dnd/droptarget'; +import { Droptarget, Position } from '../dnd/droptarget'; import { DockviewComponent, IDockviewComponent, diff --git a/packages/dockview/src/paneview/draggablePaneviewPanel.ts b/packages/dockview/src/paneview/draggablePaneviewPanel.ts index b26436fda..d316366ee 100644 --- a/packages/dockview/src/paneview/draggablePaneviewPanel.ts +++ b/packages/dockview/src/paneview/draggablePaneviewPanel.ts @@ -112,9 +112,9 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel { const containerApi = (this.params! as PanePanelInitParameter) .containerApi; - const id = data.paneId; + const panelId = data.paneId; - const existingPanel = containerApi.getPanel(id); + const existingPanel = containerApi.getPanel(panelId); if (!existingPanel) { this._onDidDrop.fire({ ...event, diff --git a/packages/dockview/src/paneview/paneviewPanel.ts b/packages/dockview/src/paneview/paneviewPanel.ts index 555731dd2..c098cb6cd 100644 --- a/packages/dockview/src/paneview/paneviewPanel.ts +++ b/packages/dockview/src/paneview/paneviewPanel.ts @@ -176,8 +176,10 @@ export abstract class PaneviewPanel this.addDisposables( this._onDidChangeExpansionState, - this.onDidChangeExpansionState((isExpanded) => { - this.api._onDidExpansionChange.fire({ isExpanded }); + this.onDidChangeExpansionState((isPanelExpanded) => { + this.api._onDidExpansionChange.fire({ + isExpanded: isPanelExpanded, + }); }) ); diff --git a/packages/dockview/src/react/react.ts b/packages/dockview/src/react/react.ts index 8035bd110..4024031af 100644 --- a/packages/dockview/src/react/react.ts +++ b/packages/dockview/src/react/react.ts @@ -49,13 +49,6 @@ const ReactComponentBridge: React.ForwardRefRenderFunction< [] ); - React.useEffect(() => { - // console.debug('[reactwrapper] component mounted '); - return () => { - // console.debug('[reactwrapper] component unmounted '); - }; - }, []); - return React.createElement(props.component, _props.current); }; ReactComponentBridge.displayName = 'DockviewReactJsBridge';