mirror of
https://github.com/mathuo/dockview
synced 2025-02-02 14:35:46 +00:00
feat: vue3 fixes
This commit is contained in:
parent
26cd1cc1cc
commit
0ae16cf444
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/dockview-core",
|
"packages/dockview-core",
|
||||||
|
"packages/dockview-vue",
|
||||||
"packages/dockview"
|
"packages/dockview"
|
||||||
],
|
],
|
||||||
"sandboxes": [
|
"sandboxes": [
|
||||||
|
@ -137,13 +137,6 @@ export class DockviewPanel
|
|||||||
|
|
||||||
if (didTitleChange) {
|
if (didTitleChange) {
|
||||||
this._title = title;
|
this._title = title;
|
||||||
|
|
||||||
this.view.update({
|
|
||||||
params: {
|
|
||||||
params: this._params,
|
|
||||||
title: this.title,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.api._onDidTitleChange.fire({ title });
|
this.api._onDidTitleChange.fire({ title });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,10 +171,7 @@ export class DockviewPanel
|
|||||||
|
|
||||||
// update the view with the updated props
|
// update the view with the updated props
|
||||||
this.view.update({
|
this.view.update({
|
||||||
params: {
|
|
||||||
params: this._params,
|
params: this._params,
|
||||||
title: this.title,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ const config: JestConfigWithTsJest = {
|
|||||||
preset: 'ts-jest',
|
preset: 'ts-jest',
|
||||||
roots: ['<rootDir>/packages/dockview-vue'],
|
roots: ['<rootDir>/packages/dockview-vue'],
|
||||||
modulePaths: ['<rootDir>/packages/dockview-vue/src'],
|
modulePaths: ['<rootDir>/packages/dockview-vue/src'],
|
||||||
displayName: { name: 'dockview', color: 'blue' },
|
displayName: { name: 'dockview-vue', color: 'blue' },
|
||||||
rootDir: '../../',
|
rootDir: '../../',
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
'<rootDir>/packages/dockview-vue/src/**/*.{js,jsx,ts,tsx}',
|
'<rootDir>/packages/dockview-vue/src/**/*.{js,jsx,ts,tsx}',
|
||||||
|
@ -18,9 +18,8 @@ import {
|
|||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import {
|
import {
|
||||||
VueContentRenderer,
|
|
||||||
VueHeaderActionsRenderer,
|
VueHeaderActionsRenderer,
|
||||||
VueTabRenderer,
|
VueRenderer,
|
||||||
VueWatermarkRenderer,
|
VueWatermarkRenderer,
|
||||||
findComponent,
|
findComponent,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
@ -81,7 +80,7 @@ onMounted(() => {
|
|||||||
getCurrentInstance()!,
|
getCurrentInstance()!,
|
||||||
options.name
|
options.name
|
||||||
);
|
);
|
||||||
return new VueContentRenderer(component!, getCurrentInstance()!);
|
return new VueRenderer(component!, getCurrentInstance()!);
|
||||||
},
|
},
|
||||||
createTabComponent(options) {
|
createTabComponent(options) {
|
||||||
let component = findComponent(getCurrentInstance()!, options.name);
|
let component = findComponent(getCurrentInstance()!, options.name);
|
||||||
@ -94,7 +93,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (component) {
|
if (component) {
|
||||||
return new VueTabRenderer(component, getCurrentInstance()!);
|
return new VueRenderer(component, getCurrentInstance()!);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
@ -175,8 +174,6 @@ onMounted(() => {
|
|||||||
*/
|
*/
|
||||||
instance.value = markRaw(dockview);
|
instance.value = markRaw(dockview);
|
||||||
|
|
||||||
console.log(getCurrentInstance());
|
|
||||||
|
|
||||||
emit('ready', { api: new DockviewApi(dockview) });
|
emit('ready', { api: new DockviewApi(dockview) });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
|
DockviewApi,
|
||||||
DockviewGroupPanel,
|
DockviewGroupPanel,
|
||||||
|
DockviewPanelApi,
|
||||||
GroupPanelPartInitParameters,
|
GroupPanelPartInitParameters,
|
||||||
IContentRenderer,
|
IContentRenderer,
|
||||||
IDockviewPanelHeaderProps,
|
IDockviewPanelHeaderProps,
|
||||||
@ -84,8 +86,8 @@ export function mountVueComponent<T extends Record<string, any>>(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
update: (newProps: any) => {
|
update: (newProps: any) => {
|
||||||
runningProps = { ...props, newProps };
|
runningProps = { ...props, ...newProps };
|
||||||
vNode = cloneVNode(vNode, Object.freeze(runningProps));
|
vNode = cloneVNode(vNode, runningProps);
|
||||||
render(vNode, element);
|
render(vNode, element);
|
||||||
},
|
},
|
||||||
dispose: () => {
|
dispose: () => {
|
||||||
@ -94,11 +96,13 @@ export function mountVueComponent<T extends Record<string, any>>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VueContentRenderer implements IContentRenderer {
|
export class VueRenderer implements ITabRenderer, IContentRenderer {
|
||||||
private _element: HTMLElement;
|
private _element: HTMLElement;
|
||||||
private _renderDisposable:
|
private _renderDisposable:
|
||||||
| { update: (props: any) => void; dispose: () => void }
|
| { update: (props: any) => void; dispose: () => void }
|
||||||
| undefined;
|
| undefined;
|
||||||
|
private _api: DockviewPanelApi | undefined;
|
||||||
|
private _containerApi: DockviewApi | undefined;
|
||||||
|
|
||||||
get element(): HTMLElement {
|
get element(): HTMLElement {
|
||||||
return this._element;
|
return this._element;
|
||||||
@ -115,57 +119,9 @@ export class VueContentRenderer implements IContentRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(parameters: GroupPanelPartInitParameters): void {
|
init(parameters: GroupPanelPartInitParameters): void {
|
||||||
const props: IDockviewPanelProps = {
|
this._api = parameters.api;
|
||||||
params: parameters.params,
|
this._containerApi = parameters.containerApi;
|
||||||
api: parameters.api,
|
|
||||||
containerApi: parameters.containerApi,
|
|
||||||
};
|
|
||||||
|
|
||||||
this._renderDisposable?.dispose();
|
|
||||||
this._renderDisposable = mountVueComponent(
|
|
||||||
this.component,
|
|
||||||
this.parent,
|
|
||||||
{ params: props },
|
|
||||||
this.element
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(event: PanelUpdateEvent<Parameters>): void {
|
|
||||||
const params = event.params;
|
|
||||||
// TODO: handle prop updates somehow?
|
|
||||||
this._renderDisposable?.update(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
focus(): void {
|
|
||||||
// TODO: make optional on interface
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose(): void {
|
|
||||||
this._renderDisposable?.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VueTabRenderer implements ITabRenderer {
|
|
||||||
private _element: HTMLElement;
|
|
||||||
private _renderDisposable:
|
|
||||||
| { update: (props: any) => void; dispose: () => void }
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
get element(): HTMLElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private readonly component: VueComponent,
|
|
||||||
private readonly parent: ComponentInternalInstance
|
|
||||||
) {
|
|
||||||
this._element = document.createElement('div');
|
|
||||||
this.element.className = 'dv-vue-part';
|
|
||||||
this.element.style.height = '100%';
|
|
||||||
this.element.style.width = '100%';
|
|
||||||
}
|
|
||||||
|
|
||||||
init(parameters: GroupPanelPartInitParameters): void {
|
|
||||||
const props: IDockviewPanelHeaderProps = {
|
const props: IDockviewPanelHeaderProps = {
|
||||||
params: parameters.params,
|
params: parameters.params,
|
||||||
api: parameters.api,
|
api: parameters.api,
|
||||||
@ -182,9 +138,19 @@ export class VueTabRenderer implements ITabRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(event: PanelUpdateEvent<Parameters>): void {
|
update(event: PanelUpdateEvent<Parameters>): void {
|
||||||
|
if (!this._api || !this._containerApi) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const params = event.params;
|
const params = event.params;
|
||||||
// TODO: handle prop updates somehow?
|
// TODO: handle prop updates somehow?
|
||||||
this._renderDisposable?.update(params);
|
this._renderDisposable?.update({
|
||||||
|
params: {
|
||||||
|
params: params,
|
||||||
|
api: this._api,
|
||||||
|
containerApi: this._containerApi,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
@ -232,9 +198,7 @@ export class VueWatermarkRenderer implements IWatermarkRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(event: PanelUpdateEvent<Parameters>): void {
|
update(event: PanelUpdateEvent<Parameters>): void {
|
||||||
const params = event.params;
|
// noop
|
||||||
// TODO: handle prop updates somehow?
|
|
||||||
this._renderDisposable?.update(params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
|
@ -3,8 +3,6 @@ import {
|
|||||||
DockviewComponent,
|
DockviewComponent,
|
||||||
DockviewWillDropEvent,
|
DockviewWillDropEvent,
|
||||||
DockviewApi,
|
DockviewApi,
|
||||||
IContentRenderer,
|
|
||||||
ITabRenderer,
|
|
||||||
DockviewGroupPanel,
|
DockviewGroupPanel,
|
||||||
IHeaderActionsRenderer,
|
IHeaderActionsRenderer,
|
||||||
DockviewDidDropEvent,
|
DockviewDidDropEvent,
|
||||||
@ -16,7 +14,6 @@ import {
|
|||||||
PROPERTY_KEYS,
|
PROPERTY_KEYS,
|
||||||
DockviewComponentOptions,
|
DockviewComponentOptions,
|
||||||
DockviewFrameworkOptions,
|
DockviewFrameworkOptions,
|
||||||
IDockviewDisposable,
|
|
||||||
DockviewDndOverlayEvent,
|
DockviewDndOverlayEvent,
|
||||||
DockviewReadyEvent,
|
DockviewReadyEvent,
|
||||||
} from 'dockview-core';
|
} from 'dockview-core';
|
||||||
|
@ -52,7 +52,7 @@ export class ReactPanelContentPart implements IContentRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(event: PanelUpdateEvent) {
|
public update(event: PanelUpdateEvent) {
|
||||||
this.part?.update(event.params);
|
this.part?.update({ params: event.params });
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(_width: number, _height: number): void {
|
public layout(_width: number, _height: number): void {
|
||||||
|
@ -44,7 +44,7 @@ export class ReactPanelHeaderPart implements ITabRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(event: PanelUpdateEvent): void {
|
public update(event: PanelUpdateEvent): void {
|
||||||
this.part?.update(event.params);
|
this.part?.update({ params: event.params });
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(_width: number, _height: number): void {
|
public layout(_width: number, _height: number): void {
|
||||||
|
@ -22,12 +22,21 @@ function onReady(event: DockviewReadyEvent) {
|
|||||||
```
|
```
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
<FrameworkSpecific framework='Vue'>
|
||||||
<FrameworkSpecific framework='JavaScript'>
|
|
||||||
```tsx
|
```tsx
|
||||||
const component = new DockviewComponent({
|
const App = {
|
||||||
/** options */
|
name: 'App',
|
||||||
});
|
methods: {
|
||||||
|
onReady(event: DockviewReadyEvent) {
|
||||||
|
const api: DockviewApi = event.api;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<dockview-vue
|
||||||
|
@ready="onReady"
|
||||||
|
>
|
||||||
|
</dockview-vue>`,
|
||||||
|
};
|
||||||
```
|
```
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
@ -39,6 +39,37 @@ return <DockviewReact components={components}/>
|
|||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameworkSpecific framework='Vue'>
|
||||||
|
```tsx
|
||||||
|
const App = {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
'component_1': VueComponent1,
|
||||||
|
'component_2': VueComponent2,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onReady(event: DockviewReadyEvent) {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'component_1'
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'component_2'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<dockview-vue
|
||||||
|
@ready="onReady"
|
||||||
|
>
|
||||||
|
</dockview-vue>`,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
|
||||||
Each panel has an [api](/docs/api/dockview/panelApi) which is used to control specific
|
Each panel has an [api](/docs/api/dockview/panelApi) which is used to control specific
|
||||||
features on that individual panel.
|
features on that individual panel.
|
||||||
The panel also has access the [group api](/docs/api/dockview/groupApi) and the container
|
The panel also has access the [group api](/docs/api/dockview/groupApi) and the container
|
||||||
|
@ -31,6 +31,32 @@ return <DockviewReact tabComponents={tabComponents}/>
|
|||||||
```
|
```
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
<FrameworkSpecific framework='Vue'>
|
||||||
|
```tsx
|
||||||
|
const App = {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
'component_1': VueComponent1,
|
||||||
|
'tab_1': VueComponent2,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onReady(event: DockviewReadyEvent) {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'component_1',
|
||||||
|
tabComponent: 'tab_1'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<dockview-vue
|
||||||
|
@ready="onReady"
|
||||||
|
>
|
||||||
|
</dockview-vue>`,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
</FrameworkSpecific>
|
||||||
|
|
||||||
<FrameworkSpecific framework='JavaScript'>
|
<FrameworkSpecific framework='JavaScript'>
|
||||||
not implemented
|
not implemented
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
@ -51,6 +77,32 @@ return <DockviewReact defaultTabRenderer={CustomTabRenderer}/>
|
|||||||
```
|
```
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
|
||||||
|
<FrameworkSpecific framework='Vue'>
|
||||||
|
```tsx
|
||||||
|
const App = {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
'component_1': VueComponent1,
|
||||||
|
'tab_1': VueComponent2,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onReady(event: DockviewReadyEvent) {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'component_1',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<dockview-vue
|
||||||
|
@ready="onReady"
|
||||||
|
:defaultTabRenderer='tab_1'
|
||||||
|
>
|
||||||
|
</dockview-vue>`,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
</FrameworkSpecific>
|
||||||
|
|
||||||
<FrameworkSpecific framework='JavaScript'>
|
<FrameworkSpecific framework='JavaScript'>
|
||||||
not implemented
|
not implemented
|
||||||
</FrameworkSpecific>
|
</FrameworkSpecific>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@ const Panel = defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const disposable = this.api.onDidTitleChange(() => {
|
const disposable = this.params.api.onDidTitleChange(() => {
|
||||||
this.title = this.api.title;
|
this.title = this.api.title;
|
||||||
});
|
});
|
||||||
this.title = this.api.title;
|
this.title = this.api.title;
|
||||||
@ -64,14 +64,16 @@ const Tab = defineComponent({
|
|||||||
name: 'Tab',
|
name: 'Tab',
|
||||||
props: {
|
props: {
|
||||||
params: {
|
params: {
|
||||||
type: Object as PropType<IDockviewPanelHeaderProps>,
|
type: Object as PropType<
|
||||||
|
IDockviewPanelHeaderProps<{ myValue: number }>
|
||||||
|
>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: '',
|
title: '',
|
||||||
value: null,
|
value: this.params.params.myValue,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -80,11 +82,12 @@ const Tab = defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const disposable2 = this.params.api.onDidParametersChange(() => {
|
const disposable2 = this.params.api.onDidParametersChange(() => {
|
||||||
this.value = this.params.myValue;
|
console.log(this.params);
|
||||||
|
this.value = this.params.params.myValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.title = this.api.title;
|
this.title = this.api.title;
|
||||||
this.value = this.params.myValue;
|
this.value = this.params.params.myValue;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
|
@ -50,15 +50,27 @@ fs.writeFileSync(
|
|||||||
|
|
||||||
// dockview
|
// dockview
|
||||||
|
|
||||||
const dockviewPath = path.join(rootDir, 'packages', 'dockview', 'package.json');
|
const depPackages = ['dockview', 'dockview-vue'];
|
||||||
|
|
||||||
|
for (const depPackage of depPackages) {
|
||||||
|
const dockviewPath = path.join(
|
||||||
|
rootDir,
|
||||||
|
'packages',
|
||||||
|
depPackage,
|
||||||
|
'package.json'
|
||||||
|
);
|
||||||
const dockviewPackageJson = JSON.parse(
|
const dockviewPackageJson = JSON.parse(
|
||||||
fs.readFileSync(dockviewPath).toString()
|
fs.readFileSync(dockviewPath).toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
dockviewPackageJson.version = version;
|
dockviewPackageJson.version = version;
|
||||||
dockviewPackageJson.dependencies['dockview-core'] = dockviewPackageJson.version;
|
dockviewPackageJson.dependencies['dockview-core'] =
|
||||||
|
dockviewPackageJson.version;
|
||||||
|
|
||||||
fs.writeFileSync(dockviewPath, JSON.stringify(dockviewPackageJson, null, 4));
|
fs.writeFileSync(
|
||||||
|
dockviewPath,
|
||||||
|
JSON.stringify(dockviewPackageJson, null, 4)
|
||||||
|
);
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
|
|
||||||
@ -67,5 +79,6 @@ const dv = JSON.parse(fs.readFileSync(dockviewPath).toString());
|
|||||||
|
|
||||||
console.log(`dockview-core version: ${dvCore.version}`);
|
console.log(`dockview-core version: ${dvCore.version}`);
|
||||||
console.log(
|
console.log(
|
||||||
`dockview version: ${dv.version} dockview-core dependency version: ${dv.dependencies['dockview-core']}`
|
`${depPackage} version: ${dv.version} dockview-core dependency version: ${dv.dependencies['dockview-core']}`
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "./packages/dockview-core"
|
"path": "./packages/dockview-core"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./packages/dockview-vue"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user