mirror of
https://github.com/mathuo/dockview
synced 2025-08-27 04:26:36 +00:00
tmp
This commit is contained in:
parent
b25264e190
commit
f93e5b613e
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -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": []
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -36,3 +36,7 @@ export interface IWatermarkPanelProps {
|
||||
containerApi: DockviewApi;
|
||||
group?: IDockviewGroupPanel;
|
||||
}
|
||||
|
||||
export interface DockviewReadyEvent {
|
||||
api: DockviewApi;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ export {
|
||||
IDockviewHeaderActionsProps,
|
||||
IGroupHeaderProps,
|
||||
IWatermarkPanelProps,
|
||||
DockviewReadyEvent,
|
||||
} from './dockview/framework';
|
||||
|
||||
export * from './dockview/options';
|
||||
|
@ -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>
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user