This commit is contained in:
mathuo 2024-03-10 20:20:53 +00:00
parent b25264e190
commit f93e5b613e
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
11 changed files with 373 additions and 228 deletions

View File

@ -7,7 +7,8 @@
"esbenp.prettier-vscode",
"redhat.vscode-yaml",
"dbaeumer.vscode-eslint",
"editorconfig.editorconfig"
"editorconfig.editorconfig",
"vue.volar"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []

View File

@ -18,6 +18,7 @@ import {
} from '../../dockview/components/titlebar/tabsContainer';
import { fromPartial } from '@total-typescript/shoehorn';
import { DockviewApi } from '../../api/component.api';
import { DockviewDndOverlayEvent } from '../../dockview/options';
class PanelContentPartTest implements IContentRenderer {
element: HTMLElement = document.createElement('div');
@ -2039,7 +2040,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 1000);
@ -2145,7 +2146,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 1000);
@ -2286,7 +2287,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 1000);
@ -2414,7 +2415,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 1000);
@ -2850,8 +2851,6 @@ describe('dockviewComponent', () => {
test('that external dnd events do not trigger the top-level center dnd target unless empty', () => {
const container = document.createElement('div');
const showDndOverlay = jest.fn().mockReturnValue(true);
const dockview = new DockviewComponent({
parentElement: container,
components: {
@ -2860,7 +2859,13 @@ describe('dockviewComponent', () => {
tabComponents: {
test_tab_id: PanelTabPartTest,
},
showDndOverlay: showDndOverlay,
});
let events: DockviewDndOverlayEvent[] = [];
dockview.onUnhandledDragOverEvent((e) => {
events.push(e);
e.accept();
});
dockview.layout(1000, 500);
@ -2900,13 +2905,11 @@ describe('dockviewComponent', () => {
});
fireEvent(dockview.element, eventLeft);
expect(showDndOverlay).toHaveBeenCalledWith({
nativeEvent: eventLeft,
position: 'left',
target: 'edge',
getData: getPanelData,
});
expect(showDndOverlay).toBeCalledTimes(1);
expect(events[0].nativeEvent).toBe(eventLeft);
expect(events[0].position).toBe('left');
expect(events[0].target).toBe('edge');
expect(events[0].getData).toBe(getPanelData);
expect(events.length).toBe(1);
// right
@ -2919,13 +2922,11 @@ describe('dockviewComponent', () => {
});
fireEvent(dockview.element, eventRight);
expect(showDndOverlay).toHaveBeenCalledWith({
nativeEvent: eventRight,
position: 'right',
target: 'edge',
getData: getPanelData,
});
expect(showDndOverlay).toBeCalledTimes(2);
expect(events[1].nativeEvent).toBe(eventRight);
expect(events[1].position).toBe('right');
expect(events[1].target).toBe('edge');
expect(events[1].getData).toBe(getPanelData);
expect(events.length).toBe(2);
// top
@ -2938,13 +2939,11 @@ describe('dockviewComponent', () => {
});
fireEvent(dockview.element, eventTop);
expect(showDndOverlay).toHaveBeenCalledWith({
nativeEvent: eventTop,
position: 'top',
target: 'edge',
getData: getPanelData,
});
expect(showDndOverlay).toBeCalledTimes(3);
expect(events[2].nativeEvent).toBe(eventTop);
expect(events[2].position).toBe('top');
expect(events[2].target).toBe('edge');
expect(events[2].getData).toBe(getPanelData);
expect(events.length).toBe(3);
// top
@ -2957,13 +2956,11 @@ describe('dockviewComponent', () => {
});
fireEvent(dockview.element, eventBottom);
expect(showDndOverlay).toHaveBeenCalledWith({
nativeEvent: eventBottom,
position: 'bottom',
target: 'edge',
getData: getPanelData,
});
expect(showDndOverlay).toBeCalledTimes(4);
expect(events[3].nativeEvent).toBe(eventBottom);
expect(events[3].position).toBe('bottom');
expect(events[3].target).toBe('edge');
expect(events[3].getData).toBe(getPanelData);
expect(events.length).toBe(4);
// center
@ -2977,7 +2974,7 @@ describe('dockviewComponent', () => {
fireEvent(dockview.element, eventCenter);
// expect not to be called for center
expect(showDndOverlay).toBeCalledTimes(4);
expect(events.length).toBe(4);
dockview.removePanel(panel1);
dockview.removePanel(panel2);
@ -2993,13 +2990,11 @@ describe('dockviewComponent', () => {
});
fireEvent(dockview.element, eventCenter2);
expect(showDndOverlay).toHaveBeenCalledWith({
nativeEvent: eventTop,
position: 'center',
target: 'edge',
getData: getPanelData,
});
expect(showDndOverlay).toBeCalledTimes(5);
expect(events[4].nativeEvent).toBe(eventCenter2);
expect(events[4].position).toBe('center');
expect(events[4].target).toBe('edge');
expect(events[4].getData).toBe(getPanelData);
expect(events.length).toBe(5);
});
test('that dragging a tab triggers onWillDragPanel', () => {
@ -4047,7 +4042,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4097,7 +4092,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4146,7 +4141,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4185,7 +4180,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4223,7 +4218,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4262,7 +4257,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4322,7 +4317,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4360,7 +4355,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4392,7 +4387,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4464,7 +4459,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
dockview.layout(1000, 500);
@ -4504,7 +4499,7 @@ describe('dockviewComponent', () => {
},
tabComponents: {
test_tab_id: PanelTabPartTest,
}
},
});
const api = new DockviewApi(dockview);

View File

@ -642,7 +642,6 @@ describe('dockviewGroupPanelModel', () => {
return {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
@ -650,6 +649,7 @@ describe('dockviewGroupPanelModel', () => {
onDidRemovePanel: jest.fn(),
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
@ -679,6 +679,12 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel
);
let counter = 0;
cut.onUnhandledDragOverEvent(() => {
counter++;
});
const element = container
.getElementsByClassName('content-container')
.item(0)!;
@ -691,7 +697,7 @@ describe('dockviewGroupPanelModel', () => {
fireEvent.dragEnter(element);
fireEvent.dragOver(element);
expect(accessor.options.showDndOverlay).toBeCalledTimes(1);
expect(counter).toBe(1);
expect(
element.getElementsByClassName('drop-target-dropzone').length
@ -703,7 +709,6 @@ describe('dockviewGroupPanelModel', () => {
return {
id: 'testcomponentid',
options: {
showDndOverlay: () => true,
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
@ -740,6 +745,10 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel
);
cut.onUnhandledDragOverEvent((e) => {
e.accept();
});
const element = container
.getElementsByClassName('content-container')
.item(0)!;
@ -795,7 +804,6 @@ describe('dockviewGroupPanelModel', () => {
return {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
@ -834,6 +842,12 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel
);
let counter = 0;
cut.onUnhandledDragOverEvent(() => {
counter++;
});
cut.openPanel(
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
@ -857,7 +871,7 @@ describe('dockviewGroupPanelModel', () => {
fireEvent.dragEnter(element);
fireEvent.dragOver(element);
expect(accessor.options.showDndOverlay).toBeCalledTimes(0);
expect(counter).toBe(0);
expect(
element.getElementsByClassName('drop-target-dropzone').length
@ -869,7 +883,6 @@ describe('dockviewGroupPanelModel', () => {
return {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
@ -908,6 +921,12 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel
);
let counter = 0;
cut.onUnhandledDragOverEvent(() => {
counter++;
});
cut.openPanel(
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
@ -936,7 +955,7 @@ describe('dockviewGroupPanelModel', () => {
fireEvent.dragEnter(element);
fireEvent.dragOver(element);
expect(accessor.options.showDndOverlay).toBeCalledTimes(0);
expect(counter).toBe(0);
expect(
element.getElementsByClassName('drop-target-dropzone').length
@ -948,7 +967,6 @@ describe('dockviewGroupPanelModel', () => {
return {
id: 'testcomponentid',
options: {
showDndOverlay: jest.fn(),
parentElement: document.createElement('div'),
},
getPanel: jest.fn(),
@ -987,6 +1005,12 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel
);
let counter = 0;
cut.onUnhandledDragOverEvent(() => {
counter++;
});
cut.openPanel(
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
@ -1015,7 +1039,7 @@ describe('dockviewGroupPanelModel', () => {
fireEvent.dragEnter(element);
fireEvent.dragOver(element);
expect(accessor.options.showDndOverlay).toBeCalledTimes(1);
expect(counter).toBe(1);
expect(
element.getElementsByClassName('drop-target-dropzone').length

View File

@ -36,3 +36,7 @@ export interface IWatermarkPanelProps {
containerApi: DockviewApi;
group?: IDockviewGroupPanel;
}
export interface DockviewReadyEvent {
api: DockviewApi;
}

View File

@ -43,6 +43,7 @@ export {
IDockviewHeaderActionsProps,
IGroupHeaderProps,
IWatermarkPanelProps,
DockviewReadyEvent,
} from './dockview/framework';
export * from './dockview/options';

View File

@ -1,162 +1,285 @@
<script setup lang="ts">
import {
DockviewApi,
DockviewComponent,
type IContentRenderer,
type ITabRenderer,
type IWatermarkRenderer,
type IDockviewPanelProps,
type IDockviewPanelHeaderProps,
type IGroupPanelBaseProps,
type IWatermarkPanelProps,
type DockviewOptions,
PROPERTY_KEYS,
type DockviewEvents,
type DockviewFrameworkOptions,
} from 'dockview-core'
import { ref, onMounted, defineProps, defineEmits, watch, onBeforeUnmount } from 'vue'
DockviewApi,
DockviewComponent,
type IContentRenderer,
type ITabRenderer,
type IWatermarkRenderer,
type IDockviewPanelProps,
type IDockviewPanelHeaderProps,
type IGroupPanelBaseProps,
type IWatermarkPanelProps,
type DockviewOptions,
PROPERTY_KEYS,
type DockviewFrameworkOptions,
type DockviewReadyEvent,
} from 'dockview-core';
import {
VueContentRenderer,
VueHeaderActionsRenderer,
VueTabRenderer,
VueWatermarkRenderer,
type VueComponent
} from '../utils'
ref,
onMounted,
defineProps,
defineEmits,
watch,
onBeforeUnmount,
} from 'vue';
import {
VueContentRenderer,
VueHeaderActionsRenderer,
VueTabRenderer,
VueWatermarkRenderer,
type VueComponent,
} from '../utils';
interface VueProps {
// onReady: (event: DockviewReadyEvent) => void;
components: Record<string, VueComponent<IDockviewPanelProps>>
tabComponents?: Record<string, VueComponent<IDockviewPanelHeaderProps>>
watermarkComponent?: VueComponent<IWatermarkPanelProps>;
// onDidDrop?: (event: DockviewDidDropEvent) => void;
// onWillDrop?: (event: DockviewWillDropEvent) => void;
// showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
className?: string;
defaultTabComponent?: VueComponent<IDockviewPanelHeaderProps>
rightHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>
leftHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>
prefixHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>
components: Record<string, VueComponent<IDockviewPanelProps>>;
tabComponents?: Record<string, VueComponent<IDockviewPanelHeaderProps>>;
watermarkComponent?: VueComponent<IWatermarkPanelProps>;
defaultTabComponent?: VueComponent<IDockviewPanelHeaderProps>;
rightHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>;
leftHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>;
prefixHeaderActionsComponent?: VueComponent<IGroupPanelBaseProps>;
}
type IDockviewVueProps = DockviewOptions & VueProps;
const VUE_PROPERTIES = (() => {
const _value: Record<keyof VueProps, undefined> = {
components: undefined,
tabComponents: undefined,
watermarkComponent: undefined,
defaultTabComponent: undefined,
rightHeaderActionsComponent: undefined,
leftHeaderActionsComponent: undefined,
prefixHeaderActionsComponent: undefined,
};
function extractCoreOptions(props: IDockviewVueProps): DockviewOptions {
const coreOptions = (PROPERTY_KEYS as (keyof DockviewOptions)[]).reduce(
(obj, key) => {
(obj as any)[key] = props[key]
return obj;
},
{} as Partial<DockviewOptions>
);
return coreOptions as DockviewOptions;
}
return Object.keys(_value) as (keyof VueProps)[];
})();
type VueEvents = {
onReady: (event: {api: DockviewApi}) => void;
ready: [event: DockviewReadyEvent];
};
const DEFAULT_REACT_TAB = 'props.defaultTabComponent';
export type IDockviewVueProps = DockviewOptions & VueProps;
function extractCoreOptions(props: IDockviewVueProps): DockviewOptions {
const coreOptions = (PROPERTY_KEYS as (keyof DockviewOptions)[]).reduce(
(obj, key) => {
(obj as any)[key] = props[key];
return obj;
},
{} as Partial<DockviewOptions>
);
return coreOptions as DockviewOptions;
}
type DockviewVueEvents = DockviewEvents & VueEvents;
const emit = defineEmits<VueEvents>();
const props = defineProps<IDockviewVueProps>();
interface TestEvents {
onDidChange: (event: string, a: number) => void;
onDidChange2?: (event: string, a: number) => void;
}
const el = ref<HTMLElement | null>(null);
const instance = ref<DockviewComponent | null>(null);
type StripEventSyntax<T> = T extends `on${infer E}` ? Uncapitalize<E> : T;
PROPERTY_KEYS.forEach((coreOptionKey) => {
watch(
() => props[coreOptionKey],
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({ [coreOptionKey]: newValue });
}
}
);
});
type FunctionValue<T extends (...args: any[]) => void> =
T extends (...args: infer G) => void ? G : never;
type Emitter<T extends Record<string, any>> = { [P in keyof T as StripEventSyntax<P>]-?:
FunctionValue<T[P]>
}
type VueEmits = Emitter<DockviewVueEvents>
const emit = defineEmits<VueEmits>();
const props = defineProps<IDockviewVueProps>()
const el = ref<HTMLElement | null>(null)
const instance = ref<DockviewComponent | null>(null)
PROPERTY_KEYS.forEach(coreOptionKey => {
watch(() => props[coreOptionKey], (newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({ [coreOptionKey]: newValue })
watch(
() => props.components,
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({ frameworkComponents: newValue });
}
}
})
})
);
watch(
() => [props.tabComponents, props.defaultTabComponent],
([newTabComponents, newDefaultTabComponent], oldValue) => {
if (instance.value) {
const frameworkTabComponents = newTabComponents ?? {};
if (newDefaultTabComponent) {
frameworkTabComponents[DEFAULT_REACT_TAB] =
newDefaultTabComponent;
}
instance.value.updateOptions({
defaultTabComponent: newDefaultTabComponent
? DEFAULT_REACT_TAB
: undefined,
frameworkTabComponents,
});
}
}
);
watch(
() => props.watermarkComponent,
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({
watermarkFrameworkComponent: newValue,
});
}
}
);
watch(
() => props.leftHeaderActionsComponent,
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({
headerLeftActionComponent: newValue
? (group) => {
return new VueHeaderActionsRenderer(
newValue as VueComponent,
group
);
}
: undefined,
});
}
}
);
watch(
() => props.rightHeaderActionsComponent,
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({
headerRightActionComponent: newValue
? (group) => {
return new VueHeaderActionsRenderer(
newValue as VueComponent,
group
);
}
: undefined,
});
}
}
);
watch(
() => props.prefixHeaderActionsComponent,
(newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({
headerPrefixActionComponent: newValue
? (group) => {
return new VueHeaderActionsRenderer(
newValue as VueComponent,
group
);
}
: undefined,
});
}
}
);
onMounted(() => {
if (!el.value) {
throw new Error('element is not mounted')
}
if (!el.value) {
throw new Error('element is not mounted');
}
const frameworkOptions: DockviewFrameworkOptions = {
parentElement: el.value,
frameworkComponentFactory: {
content: {
createComponent: (id: string, componentId: string, component: any): IContentRenderer => {
return new VueContentRenderer(component)
}
},
tab: {
createComponent: (id: string, componentId: string, component: any): ITabRenderer => {
return new VueTabRenderer(component)
}
},
watermark: {
createComponent: (id: string, componentId: string, component: any): IWatermarkRenderer => {
return new VueWatermarkRenderer(component)
}
},
// action: {
// createComponent: (id: string, componentId: string, component: any): IWatermarkRenderer => {
// return new VueHeaderActionRenderer(component)
// }
// }
},
frameworkComponents: props.components,
frameworkTabComponents: props.tabComponents,
headerLeftActionComponent: props.leftHeaderActionsComponent ? ((group) => {
return new VueHeaderActionsRenderer(
props.leftHeaderActionsComponent as VueComponent,
group);
}) : undefined,
headerPrefixActionComponent: props.prefixHeaderActionsComponent ? (group) => {
return new VueHeaderActionsRenderer(
props.prefixHeaderActionsComponent as VueComponent,
group);
} : undefined,
headerRightActionComponent: props.rightHeaderActionsComponent ? (group) => {
return new VueHeaderActionsRenderer(
props.rightHeaderActionsComponent as VueComponent,
group);
} : undefined,
}
const frameworkTabComponents = props.tabComponents ?? {};
const dockview = new DockviewComponent({
...extractCoreOptions(props),
...frameworkOptions
})
if (props.defaultTabComponent) {
frameworkTabComponents[DEFAULT_REACT_TAB] = props.defaultTabComponent;
}
instance.value = dockview
emit("ready", { api: new DockviewApi(dockview) })
})
const frameworkOptions: DockviewFrameworkOptions = {
parentElement: el.value,
frameworkComponentFactory: {
content: {
createComponent: (
id: string,
componentId: string,
component: any
): IContentRenderer => {
return new VueContentRenderer(component);
},
},
tab: {
createComponent: (
id: string,
componentId: string,
component: any
): ITabRenderer => {
return new VueTabRenderer(component);
},
},
watermark: {
createComponent: (
id: string,
componentId: string,
component: any
): IWatermarkRenderer => {
return new VueWatermarkRenderer(component);
},
},
// action: {
// createComponent: (id: string, componentId: string, component: any): IWatermarkRenderer => {
// return new VueHeaderActionRenderer(component)
// }
// }
},
frameworkComponents: props.components,
frameworkTabComponents,
headerLeftActionComponent: props.leftHeaderActionsComponent
? (group) => {
return new VueHeaderActionsRenderer(
props.leftHeaderActionsComponent as VueComponent,
group
);
}
: undefined,
headerPrefixActionComponent: props.prefixHeaderActionsComponent
? (group) => {
return new VueHeaderActionsRenderer(
props.prefixHeaderActionsComponent as VueComponent,
group
);
}
: undefined,
headerRightActionComponent: props.rightHeaderActionsComponent
? (group) => {
return new VueHeaderActionsRenderer(
props.rightHeaderActionsComponent as VueComponent,
group
);
}
: undefined,
defaultTabComponent: props.defaultTabComponent
? DEFAULT_REACT_TAB
: undefined,
};
const dockview = new DockviewComponent({
...extractCoreOptions(props),
...frameworkOptions,
});
instance.value = dockview;
emit('ready', { api: new DockviewApi(dockview) });
});
onBeforeUnmount(() => {
if (instance.value) {
instance.value.dispose()
}
})
if (instance.value) {
instance.value.dispose();
}
});
</script>
<template>
<div ref="el" />
<div ref="el" />
</template>

View File

@ -2,15 +2,18 @@ import * as React from 'react';
import { act, render, waitFor } from '@testing-library/react';
import {
DockviewApi,
DockviewReadyEvent,
IDockviewPanel,
IDockviewPanelProps,
} from 'dockview-core';
import { DockviewReact, DockviewReadyEvent } from '../../dockview/dockview';
import { PanelCollection } from '../../types';
import { DockviewReact } from '../../dockview/dockview';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IDockviewPanelProps>;
let components: Record<
string,
React.FunctionComponent<IDockviewPanelProps>
>;
beforeEach(() => {
components = {

View File

@ -6,11 +6,13 @@ import {
GridviewReact,
GridviewReadyEvent,
} from '../../gridview/gridview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IGridviewPanelProps>;
let components: Record<
string,
React.FunctionComponent<IGridviewPanelProps>
>
beforeEach(() => {
components = {

View File

@ -6,11 +6,13 @@ import {
PaneviewReact,
PaneviewReadyEvent,
} from '../../paneview/paneview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IPaneviewPanelProps>;
let components: Record<
string,
React.FunctionComponent<IPaneviewPanelProps>
>;
beforeEach(() => {
components = {

View File

@ -6,11 +6,13 @@ import {
SplitviewReact,
SplitviewReadyEvent,
} from '../../splitview/splitview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('splitview react', () => {
let components: PanelCollection<ISplitviewPanelProps>;
let components: Record<
string,
React.FunctionComponent<ISplitviewPanelProps>
>;
beforeEach(() => {
components = {

View File

@ -19,6 +19,7 @@ import {
DockviewFrameworkOptions,
IDockviewDisposable,
DockviewDndOverlayEvent,
DockviewReadyEvent,
} from 'dockview-core';
import { ReactPanelContentPart } from './reactContentPart';
import { ReactPanelHeaderPart } from './reactHeaderPart';
@ -44,27 +45,23 @@ function createGroupControlElement(
const DEFAULT_REACT_TAB = 'props.defaultTabComponent';
export interface DockviewReadyEvent {
api: DockviewApi;
}
export interface IDockviewReactProps extends DockviewOptions {
className?: string;
onReady: (event: DockviewReadyEvent) => void;
onDidDrop?: (event: DockviewDidDropEvent) => void;
onWillDrop?: (event: DockviewWillDropEvent) => void;
components: Record<string, React.FunctionComponent<IDockviewPanelProps>>;
tabComponents?: Record<
string,
React.FunctionComponent<IDockviewPanelHeaderProps>
>;
components: Record<string, React.FunctionComponent<IDockviewPanelProps>>;
watermarkComponent?: React.FunctionComponent<IWatermarkPanelProps>;
defaultTabComponent?: React.FunctionComponent<IDockviewPanelHeaderProps>;
rightHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
leftHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
prefixHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
//
showDndOverlay: (event: DockviewDndOverlayEvent) => boolean;
onReady: (event: DockviewReadyEvent) => void;
onDidDrop?: (event: DockviewDidDropEvent) => void;
onWillDrop?: (event: DockviewWillDropEvent) => void;
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
}
function extractCoreOptions(props: IDockviewReactProps): DockviewOptions {
@ -229,7 +226,7 @@ export const DockviewReact = React.forwardRef(
const disposable = dockviewRef.current.onUnhandledDragOverEvent(
(event) => {
if (props.showDndOverlay(event)) {
if (props.showDndOverlay?.(event)) {
event.accept();
}
}
@ -276,15 +273,6 @@ export const DockviewReact = React.forwardRef(
});
}, [props.watermarkComponent]);
React.useEffect(() => {
if (!dockviewRef.current) {
return;
}
dockviewRef.current.updateOptions({
frameworkTabComponents: props.tabComponents,
});
}, [props.tabComponents]);
React.useEffect(() => {
if (!dockviewRef.current) {
return;
@ -303,7 +291,7 @@ export const DockviewReact = React.forwardRef(
: undefined,
frameworkTabComponents,
});
}, [props.defaultTabComponent]);
}, [props.tabComponents, props.defaultTabComponent]);
React.useEffect(() => {
if (!dockviewRef.current) {