feat: framework support

This commit is contained in:
mathuo 2024-03-11 22:00:02 +00:00
parent e147255fcd
commit db747f1ead
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
8 changed files with 7 additions and 279 deletions

View File

@ -1,7 +1,7 @@
{
"name": "dockview-angular",
"version": "0.0.0-beta-0",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",
"split-view",

View File

@ -1,121 +0,0 @@
<script setup lang="ts">
import {
DockviewApi,
DockviewComponent,
type DockviewDndOverlayEvent,
type DockviewPanelRenderer,
type DroptargetOverlayModel,
type IContentRenderer,
type ITabRenderer,
type IWatermarkRenderer
} from 'dockview-core'
import { ref, onMounted, watch, onBeforeUnmount } from 'vue'
import {
VueContentRenderer,
VueTabRenderer,
VueWatermarkRenderer,
type ComponentInterface
} from './utils'
interface Props {
// onReady: (event: DockviewReadyEvent) => void;
components: Record<string, any>
tabComponents?: Record<string, any>
// watermarkComponent?: React.FunctionComponent<IWatermarkPanelProps>;
// onDidDrop?: (event: DockviewDidDropEvent) => void;
// onWillDrop?: (event: DockviewWillDropEvent) => void;
// showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
hideBorders?: boolean;
className?: string;
disableAutoResizing?: boolean;
// defaultTabComponent?: React.FunctionComponent<IDockviewPanelHeaderProps>;
// rightHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
// leftHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
// prefixHeaderActionsComponent?: React.FunctionComponent<IDockviewHeaderActionsProps>;
singleTabMode?: 'fullwidth' | 'default';
disableFloatingGroups?: boolean;
floatingGroupBounds?:
| 'boundedWithinViewport'
| {
minimumHeightWithinViewport?: number;
minimumWidthWithinViewport?: number;
};
debug?: boolean;
defaultRenderer?: DockviewPanelRenderer;
rootOverlayModel?: DroptargetOverlayModel
locked?: boolean;
disableDnd?: boolean;
}
interface Emits {
(event: 'ready', value: { api: DockviewApi }): void
(event: 'showDndOverlay', value: DockviewDndOverlayEvent):void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const el = ref<HTMLElement | null>(null)
const instance = ref<DockviewComponent | null>(null)
watch(() => props.components, (newValue, oldValue) => {
if (instance.value) {
instance.value.updateOptions({ components: newValue })
}
})
onMounted(() => {
if (!el.value) {
throw new Error('element is not mounted')
}
const dockview = new DockviewComponent({
parentElement: el.value,
frameworkComponentFactory: {
content: {
createComponent: (id: string, componentId: string, component: any): IContentRenderer => {
console.log('dockview-vue: createComponent')
return new VueContentRenderer(component as ComponentInterface)
}
},
tab: {
createComponent: (id: string, componentId: string, component: any): ITabRenderer => {
return new VueTabRenderer(component as ComponentInterface)
}
},
watermark: {
createComponent: (id: string, componentId: string, component: any): IWatermarkRenderer => {
return new VueWatermarkRenderer(component as ComponentInterface)
}
}
},
frameworkComponents: props.components,
disableAutoResizing: props.disableAutoResizing,
frameworkTabComponents: props.tabComponents,
singleTabMode: props.singleTabMode,
disableFloatingGroups: props.disableFloatingGroups,
floatingGroupBounds: props.floatingGroupBounds,
defaultRenderer: props.defaultRenderer,
debug: props.debug,
rootOverlayModel: props.rootOverlayModel,
locked: props.locked,
disableDnd: props.disableDnd,
})
instance.value = dockview
emit("ready", { api: new DockviewApi(dockview) })
})
onBeforeUnmount(() => {
if (instance.value) {
instance.value.dispose()
}
})
</script>
<template>
<div ref="el" />
</template>

View File

@ -1,151 +0,0 @@
import type {
DockviewGroupPanel,
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
IWatermarkRenderer,
PanelUpdateEvent,
Parameters,
WatermarkRendererInitParameters
} from 'dockview-core'
import { createVNode, type ComponentOptionsBase, render, cloneVNode, mergeProps } from 'vue'
export type ComponentInterface = ComponentOptionsBase<any, any, any, any, any, any, any, any>
/**
* TODO List
*
* 1. handle vue context-ish stuff (appContext? provides?)
*
*
*
* @see https://vuejs.org/api/render-function.html#clonevnode
* @see https://vuejs.org/api/render-function.html#mergeprops
*/
export function mountVueComponent(component: ComponentInterface, props: any, element: HTMLElement) {
let vNode = createVNode(component, props)
render(vNode, element)
return {
update: (newProps: any) => {
vNode = cloneVNode(vNode, mergeProps(props, newProps))
render(vNode, element)
},
dispose: () => {
render(null, element)
}
}
}
export class VueContentRenderer implements IContentRenderer {
private _element: HTMLElement
private _renderDisposable: { update: (props: any) => void; dispose: () => void } | undefined
get element(): HTMLElement {
return this._element
}
constructor(private readonly component: ComponentInterface) {
this._element = document.createElement('div')
this.element.className = 'dv-vue-part'
}
init(parameters: GroupPanelPartInitParameters): void {
const props = {
params: parameters.params,
api: parameters.api,
containerApi: parameters.containerApi
}
this._renderDisposable?.dispose()
this._renderDisposable = mountVueComponent(this.component, 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: ComponentInterface) {
this._element = document.createElement('div')
this.element.className = 'dv-vue-part'
}
init(parameters: GroupPanelPartInitParameters): void {
const props = {
params: parameters.params,
api: parameters.api,
containerApi: parameters.containerApi
}
this._renderDisposable?.dispose()
this._renderDisposable = mountVueComponent(this.component, props, this.element)
}
update(event: PanelUpdateEvent<Parameters>): void {
const params = event.params
// TODO: handle prop updates somehow?
this._renderDisposable?.update(params)
}
dispose(): void {
this._renderDisposable?.dispose()
}
}
export class VueWatermarkRenderer implements IWatermarkRenderer {
private _element: HTMLElement
private _renderDisposable: { update: (props: any) => void; dispose: () => void } | undefined
get element(): HTMLElement {
return this._element
}
constructor(private readonly component: ComponentInterface) {
this._element = document.createElement('div')
this.element.className = 'dv-vue-part'
}
init(parameters: WatermarkRendererInitParameters): void {
const props = {
group: parameters.group,
containerApi: parameters.containerApi
}
this._renderDisposable?.dispose()
this._renderDisposable = mountVueComponent(this.component, props, this.element)
}
updateParentGroup(group: DockviewGroupPanel, visible: boolean): void {
// TODO: make optional on interface
}
update(event: PanelUpdateEvent<Parameters>): void {
const params = event.params
// TODO: handle prop updates somehow?
this._renderDisposable?.update(params)
}
dispose(): void {
this._renderDisposable?.dispose()
}
}

View File

@ -1,7 +1,7 @@
{
"name": "dockview-core",
"version": "1.10.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",
"split-view",

View File

@ -1,7 +1,7 @@
{
"name": "dockview-react",
"version": "0.0.0-beta-0",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",
"split-view",
@ -56,4 +56,4 @@
"dependencies": {
"dockview": "^1.10.1"
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "dockview-vue",
"version": "0.0.0-beta-0",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",
"split-view",
@ -58,4 +58,4 @@
"dependencies": {
"dockview-core": "^1.10.1"
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "dockview",
"version": "1.10.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",
"split-view",