diff --git a/package.json b/package.json index b8c44af7e..17bcfe6d0 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@typescript-eslint/parser": "^6.17.0", "@vitejs/plugin-vue": "^5.0.4", "@vue/tsconfig": "^0.5.1", + "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.56.0", "fs-extra": "^11.2.0", @@ -71,6 +72,7 @@ "typescript": "^5.3.3", "vite": "^5.1.5", "vue": "^3.4.21", + "vue-sfc-loader": "^0.1.0", "vue-tsc": "^2.0.5" }, "engines": { diff --git a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts index c72d990f6..33d97b8a6 100644 --- a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts @@ -1,12 +1,17 @@ import { Position, positionToDirection } from '../dnd/droptarget'; import { DockviewComponent } from '../dockview/dockviewComponent'; import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel'; -import { DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel'; +import { + DockviewGroupChangeEvent, + DockviewGroupLocation, +} from '../dockview/dockviewGroupPanelModel'; import { Emitter, Event } from '../events'; +import { MutableDisposable } from '../lifecycle'; import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi'; export interface DockviewGroupPanelApi extends GridviewPanelApi { readonly onDidLocationChange: Event; + readonly onDidActivePanelChange: Event; readonly location: DockviewGroupLocation; /** * If you require the Window object @@ -27,6 +32,8 @@ export interface DockviewGroupPanelFloatingChangeEvent { const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized'; export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { + private readonly _mutableDisposable = new MutableDisposable(); + private _group: DockviewGroupPanel | undefined; readonly _onDidLocationChange = @@ -34,6 +41,10 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { readonly onDidLocationChange: Event = this._onDidLocationChange.event; + private readonly _onDidActivePanelChange = + new Emitter(); + readonly onDidActivePanelChange = this._onDidActivePanelChange.event; + get location(): DockviewGroupLocation { if (!this._group) { throw new Error(NOT_INITIALIZED_MESSAGE); @@ -44,7 +55,11 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { constructor(id: string, private readonly accessor: DockviewComponent) { super(id, '__dockviewgroup__'); - this.addDisposables(this._onDidLocationChange); + this.addDisposables( + this._onDidLocationChange, + this._onDidActivePanelChange, + this._mutableDisposable + ); } close(): void { @@ -116,5 +131,19 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { initialize(group: DockviewGroupPanel): void { this._group = group; + + /** + * TODO: Annoying initialization order caveat + * + * Due to the order on initialization we know that the model isn't defined until later in the same stack-frame of setup. + * By queuing a microtask we can ensure the setup is completed within the same stack-frame, but after everything else has + * finished ensuring the `model` is defined. + */ + queueMicrotask(() => { + this._mutableDisposable.value = + this._group!.model.onDidActivePanelChange((event) => { + this._onDidActivePanelChange.fire(event); + }); + }); } } diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 5f6c8e0e5..2fad3a181 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -1039,11 +1039,11 @@ export class DockviewComponent updateOptions(options: Partial): void { const changed_floatingGroupBounds = - options.floatingGroupBounds !== undefined && + 'floatingGroupBounds' in options && options.floatingGroupBounds !== this.options.floatingGroupBounds; const changed_rootOverlayOptions = - options.rootOverlayModel !== undefined && + 'rootOverlayModel' in options && options.rootOverlayModel !== this.options.rootOverlayModel; this._options = { ...this.options, ...options }; diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index e4b97f59f..556e77e59 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -537,6 +537,7 @@ export class DockviewGroupPanelModel this._rightHeaderActions.init({ containerApi: this._api, api: this.groupPanel.api, + group: this.groupPanel, }); this.tabsContainer.setRightActionsElement( this._rightHeaderActions.element @@ -552,6 +553,7 @@ export class DockviewGroupPanelModel this._leftHeaderActions.init({ containerApi: this._api, api: this.groupPanel.api, + group: this.groupPanel, }); this.tabsContainer.setLeftActionsElement( this._leftHeaderActions.element @@ -567,6 +569,7 @@ export class DockviewGroupPanelModel this._prefixHeaderActions.init({ containerApi: this._api, api: this.groupPanel.api, + group: this.groupPanel, }); this.tabsContainer.setPrefixActionsElement( this._prefixHeaderActions.element @@ -845,10 +848,8 @@ export class DockviewGroupPanelModel this._panels.splice(index, 1); if (this.mostRecentlyUsed.includes(panel)) { - this.mostRecentlyUsed.splice( - this.mostRecentlyUsed.indexOf(panel), - 1 - ); + const index = this.mostRecentlyUsed.indexOf(panel); + this.mostRecentlyUsed.splice(index, 1); } const disposable = this._panelDisposables.get(panel.id); diff --git a/packages/dockview-core/src/dockview/framework.ts b/packages/dockview-core/src/dockview/framework.ts index 0166e477f..bd6ccaff5 100644 --- a/packages/dockview-core/src/dockview/framework.ts +++ b/packages/dockview-core/src/dockview/framework.ts @@ -30,6 +30,7 @@ export interface IDockviewHeaderActionsProps { export interface IGroupHeaderProps { api: DockviewGroupPanelApi; containerApi: DockviewApi; + group: IDockviewGroupPanel; } export interface IWatermarkPanelProps { diff --git a/packages/dockview-vue/src/dockview/dockview.vue b/packages/dockview-vue/src/dockview/dockview.vue index e1fe4c3ff..eb1d2c098 100644 --- a/packages/dockview-vue/src/dockview/dockview.vue +++ b/packages/dockview-vue/src/dockview/dockview.vue @@ -21,6 +21,9 @@ import { defineEmits, watch, onBeforeUnmount, + markRaw, + toRaw, + getCurrentInstance, } from 'vue'; import { VueContentRenderer, @@ -75,11 +78,18 @@ function extractCoreOptions(props: IDockviewVueProps): DockviewOptions { } const emit = defineEmits(); + + +/** + * Anything here that is a Vue.js component should not be reactive + * i.e. markRaw(toRaw(...)) + */ const props = defineProps(); const el = ref(null); const instance = ref(null); + PROPERTY_KEYS.forEach((coreOptionKey) => { watch( () => props[coreOptionKey], @@ -141,6 +151,7 @@ watch( ? (group) => { return new VueHeaderActionsRenderer( newValue as VueComponent, + getCurrentInstance()!, group ); } @@ -159,6 +170,7 @@ watch( ? (group) => { return new VueHeaderActionsRenderer( newValue as VueComponent, + getCurrentInstance()!, group ); } @@ -176,7 +188,7 @@ watch( headerPrefixActionComponent: newValue ? (group) => { return new VueHeaderActionsRenderer( - newValue as VueComponent, + newValue as VueComponent,getCurrentInstance()!, group ); } @@ -206,7 +218,7 @@ onMounted(() => { componentId: string, component: any ): IContentRenderer => { - return new VueContentRenderer(component); + return new VueContentRenderer(component,getCurrentInstance()!); }, }, tab: { @@ -215,7 +227,7 @@ onMounted(() => { componentId: string, component: any ): ITabRenderer => { - return new VueTabRenderer(component); + return new VueTabRenderer(component,getCurrentInstance()!); }, }, watermark: { @@ -224,7 +236,7 @@ onMounted(() => { componentId: string, component: any ): IWatermarkRenderer => { - return new VueWatermarkRenderer(component); + return new VueWatermarkRenderer(component,getCurrentInstance()!); }, }, // action: { @@ -238,7 +250,7 @@ onMounted(() => { headerLeftActionComponent: props.leftHeaderActionsComponent ? (group) => { return new VueHeaderActionsRenderer( - props.leftHeaderActionsComponent as VueComponent, + props.leftHeaderActionsComponent as VueComponent,getCurrentInstance()!, group ); } @@ -246,7 +258,7 @@ onMounted(() => { headerPrefixActionComponent: props.prefixHeaderActionsComponent ? (group) => { return new VueHeaderActionsRenderer( - props.prefixHeaderActionsComponent as VueComponent, + props.prefixHeaderActionsComponent as VueComponent,getCurrentInstance()!, group ); } @@ -254,7 +266,7 @@ onMounted(() => { headerRightActionComponent: props.rightHeaderActionsComponent ? (group) => { return new VueHeaderActionsRenderer( - props.rightHeaderActionsComponent as VueComponent, + props.rightHeaderActionsComponent as VueComponent,getCurrentInstance()!, group ); } @@ -270,7 +282,25 @@ onMounted(() => { ...frameworkOptions, }); - instance.value = dockview; + const { clientWidth, clientHeight } = el.value; + dockview.layout(clientWidth, clientHeight); + + /** + * !!! THIS IS VERY IMPORTANT + * + * Since we store a reference to `DockviewComponent` within the Vue.js world Vue.js will 'deeply Proxyify' the object + * since this is how Vue.js does its reactivity magic. + * + * We do not want Vue.js to touch the `DockviewComponent` reference since it does not need to be reactive in accordance + * to the Vue.js reactivity model and since `DockviewComponent` is written in plain TypeScript allowing Vue.js + * to proxify the reference will cause all kinds of unexpected issues + * + * @see https://vuejs.org/guide/extras/reactivity-in-depth.html + * @see https://vuejs.org/api/reactivity-advanced.html#markraw + */ + instance.value = markRaw(dockview); + + emit('ready', { api: new DockviewApi(dockview) }); }); diff --git a/packages/dockview-vue/src/utils.ts b/packages/dockview-vue/src/utils.ts index f3965b634..978370038 100644 --- a/packages/dockview-vue/src/utils.ts +++ b/packages/dockview-vue/src/utils.ts @@ -1,9 +1,8 @@ import type { - DockviewApi, DockviewGroupPanel, - DockviewGroupPanelApi, GroupPanelPartInitParameters, IContentRenderer, + IGroupHeaderProps, IHeaderActionsRenderer, ITabRenderer, IWatermarkRenderer, @@ -18,6 +17,7 @@ import { cloneVNode, mergeProps, type DefineComponent, + type ComponentInternalInstance, } from 'vue'; export type ComponentInterface = ComponentOptionsBase< @@ -45,16 +45,22 @@ export type VueComponent = DefineComponent; */ export function mountVueComponent>( component: VueComponent, + parent: ComponentInternalInstance, props: T, element: HTMLElement ) { - let vNode = createVNode(component, props); + let vNode = createVNode(component, Object.freeze(props)); + + vNode.appContext = parent.appContext; render(vNode, element); + let runningProps = props; + return { update: (newProps: any) => { - vNode = cloneVNode(vNode, mergeProps(props, newProps)); + runningProps = { ...props, newProps }; + vNode = cloneVNode(vNode, Object.freeze(runningProps)); render(vNode, element); }, dispose: () => { @@ -73,7 +79,10 @@ export class VueContentRenderer implements IContentRenderer { return this._element; } - constructor(private readonly component: VueComponent) { + 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%'; @@ -90,6 +99,7 @@ export class VueContentRenderer implements IContentRenderer { this._renderDisposable?.dispose(); this._renderDisposable = mountVueComponent( this.component, + this.parent, props, this.element ); @@ -120,7 +130,10 @@ export class VueTabRenderer implements ITabRenderer { return this._element; } - constructor(private readonly component: VueComponent) { + 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%'; @@ -137,6 +150,7 @@ export class VueTabRenderer implements ITabRenderer { this._renderDisposable?.dispose(); this._renderDisposable = mountVueComponent( this.component, + this.parent, props, this.element ); @@ -163,7 +177,10 @@ export class VueWatermarkRenderer implements IWatermarkRenderer { return this._element; } - constructor(private readonly component: VueComponent) { + 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%'; @@ -179,6 +196,7 @@ export class VueWatermarkRenderer implements IWatermarkRenderer { this._renderDisposable?.dispose(); this._renderDisposable = mountVueComponent( this.component, + this.parent, props, this.element ); @@ -211,32 +229,27 @@ export class VueHeaderActionsRenderer implements IHeaderActionsRenderer { constructor( private readonly component: VueComponent, + private readonly parent: ComponentInternalInstance, group: DockviewGroupPanel ) { this._element = document.createElement('div'); this.element.className = 'dv-vue-header-action-part'; + this._element.style.width = '100%'; + this._element.style.height = '100%'; } - init(params: { - containerApi: DockviewApi; - api: DockviewGroupPanelApi; - }): void { - console.log('meeee', this.component); - const props = { - api: params.api, - containerApi: params.containerApi, - }; - + init(params: IGroupHeaderProps): void { + console.log(params); this._renderDisposable?.dispose(); this._renderDisposable = mountVueComponent( this.component, - props, + this.parent, + { ...params }, this.element ); } dispose(): void { - console.log('dispose'); this._renderDisposable?.dispose(); } } diff --git a/packages/dockview/src/dockview/dockview.tsx b/packages/dockview/src/dockview/dockview.tsx index a4a13c176..039fe610a 100644 --- a/packages/dockview/src/dockview/dockview.tsx +++ b/packages/dockview/src/dockview/dockview.tsx @@ -129,24 +129,29 @@ export const DockviewReact = React.forwardRef( const prevProps = React.useRef>({}); - React.useEffect(() => { - const changes: Partial = {}; + React.useEffect( + () => { + const changes: Partial = {}; - Object.keys(PROPERTY_KEYS).forEach((propKey) => { - const key = propKey as keyof DockviewOptions; - const propValue = props[key]; + PROPERTY_KEYS.forEach((propKey) => { + const key = propKey as keyof DockviewOptions; + const propValue = props[key]; - if (propValue !== prevProps.current[key]) { - changes[key] = propValue as any; + if (propValue !== prevProps.current[key]) { + changes[key] = propValue as any; + } + }); + + if (dockviewRef.current) { + dockviewRef.current.updateOptions(changes); + } else { + // not yet fully initialized } - }); - if (dockviewRef.current) { - dockviewRef.current.updateOptions(changes); - } else { - // not yet fully initialized - } - }, PROPERTY_KEYS.map((key) => props[key]).filter(Boolean)); + prevProps.current = props; + }, + PROPERTY_KEYS.map((key) => props[key]) + ); React.useEffect(() => { if (!domRef.current) { diff --git a/packages/docs/blog/2024-04-05-dockview-1.12.0.md b/packages/docs/blog/2024-04-05-dockview-1.12.0.md deleted file mode 100644 index 91a8186b4..000000000 --- a/packages/docs/blog/2024-04-05-dockview-1.12.0.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -slug: dockview-1.12.0-release -title: Dockview 1.12.0 -tags: [release] ---- - -# Release Notes - -Please reference docs @ [dockview.dev](https://dockview.dev). - -## 🛠 Miscs - -- Create framework packages in preperation for multiple framework support - These are still in active development and will be offical support soon. - - - Create `dockview-react` package - - Create `dockview-angular` package - - Create `dockview-vue` package - -- Move various type definitions from `dockview` to `dockview-core` in preperation for multiple framework support - - - Move `IGroupPanelBaseProps` from `dockview` to `dockview-core` - - Move `IDockviewPanelHeaderProps` from `dockview` to `dockview-core` - - Move `IDockviewPanelProps` from `dockview` to `dockview-core` - - Move `IDockviewHeaderActionsProps ` from `dockview` to `dockview-core` - - Move `IGroupHeaderProps` from `dockview` to `dockview-core` - - Move `IWatermarkPanelProps` from `dockview` to `dockview-core` - - Move `DockviewReadyEvent` from `dockview` to `dockview-core` - -- Depreciate `dockview` (React) `canDisplayOverlay` in favour of the `onUnhandledDragOverEvent` api event - -## 🔥 Breaking changes - -- Replace `dockview-core` DockviewComponent `canDisplayOverlay` option with `onUnhandledDragOverEvent` event -- Rename `createRightHeaderActionsElement` to `headerRightActionComponent` -- Rename `createLeftHeaderActionsElement` to `headerLeftActionComponent` -- Rename `createPrefixHeaderActionsElement` to `headerPrefixActionComponent` diff --git a/packages/docs/blog/2024-04-19-dockview-1.13.0.md b/packages/docs/blog/2024-04-19-dockview-1.13.0.md new file mode 100644 index 000000000..ebb51619e --- /dev/null +++ b/packages/docs/blog/2024-04-19-dockview-1.13.0.md @@ -0,0 +1,41 @@ +--- +slug: dockview-1.13.0-release +title: Dockview 1.13.0 +tags: [release] +--- + +# Release Notes + +Please reference docs @ [dockview.dev](https://dockview.dev). + +## 🚀 Features + +- Add `onDidActivePanelChange` event to group api [#541](https://github.com/mathuo/dockview/pull/541) + +## 🛠 Miscs + +- Create framework packages in preperation for multiple framework support [#541](https://github.com/mathuo/dockview/pull/541) + These are still in active development and will be offically support soon. + + - Create `dockview-react` package + - Create `dockview-angular` package + - Create `dockview-vue` package + +- Move various type definitions from `dockview` to `dockview-core` in preperation for multiple framework support [#541](https://github.com/mathuo/dockview/pull/541) + + - Move `IGroupPanelBaseProps` from `dockview` to `dockview-core` + - Move `IDockviewPanelHeaderProps` from `dockview` to `dockview-core` + - Move `IDockviewPanelProps` from `dockview` to `dockview-core` + - Move `IDockviewHeaderActionsProps ` from `dockview` to `dockview-core` + - Move `IGroupHeaderProps` from `dockview` to `dockview-core` + - Move `IWatermarkPanelProps` from `dockview` to `dockview-core` + - Move `DockviewReadyEvent` from `dockview` to `dockview-core` + +- [dockview] Depreciate `canDisplayOverlay` in favour of the `onUnhandledDragOverEvent` api event [#541](https://github.com/mathuo/dockview/pull/541) + +## 🔥 Breaking changes + +- [dockview-core] Replace DockviewComponent `canDisplayOverlay` option with `onUnhandledDragOverEvent` event [#541](https://github.com/mathuo/dockview/pull/541) +- [dockview-core] Rename `createRightHeaderActionsElement` to `headerRightActionComponent` [#541](https://github.com/mathuo/dockview/pull/541) +- [dockview-core] Rename `createLeftHeaderActionsElement` to `headerLeftActionComponent` [#541](https://github.com/mathuo/dockview/pull/541) +- [dockview-core] Rename `createPrefixHeaderActionsElement` to `headerPrefixActionComponent` [#541](https://github.com/mathuo/dockview/pull/541) diff --git a/packages/docs/docs/advanced/nested.mdx b/packages/docs/docs/advanced/nested.mdx index 996a0e37e..49161a44a 100644 --- a/packages/docs/docs/advanced/nested.mdx +++ b/packages/docs/docs/advanced/nested.mdx @@ -3,12 +3,11 @@ title: Nested Instances --- -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import NestedDockview from '@site/sandboxes/nested-dockview/src/app'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; # Nested Dockviews You can safely create multiple dockview instances within one page and nest dockviews within other dockviews. If you wish to interact with the drop event from one dockview instance in another dockview instance you can implement the `showDndOverlay` and `onDidDrop` props on `DockviewReact`. - + diff --git a/packages/docs/docs/core/groups/constraints.mdx b/packages/docs/docs/core/groups/constraints.mdx index 583a89a7f..db8e2de2a 100644 --- a/packages/docs/docs/core/groups/constraints.mdx +++ b/packages/docs/docs/core/groups/constraints.mdx @@ -2,7 +2,6 @@ title: Constraints --- -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef' :::warning @@ -13,5 +12,5 @@ Constraints come with several caveats. They are not serialized with layouts and ## Live Example - + diff --git a/packages/docs/docs/core/groups/controls.mdx b/packages/docs/docs/core/groups/controls.mdx index fa6fd2719..d2ff406f4 100644 --- a/packages/docs/docs/core/groups/controls.mdx +++ b/packages/docs/docs/core/groups/controls.mdx @@ -2,7 +2,6 @@ title: Group Controls --- -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef'; This section describes how you can customize the header component of each group. @@ -39,5 +38,5 @@ return + diff --git a/packages/docs/docs/core/groups/floatingGroups.mdx b/packages/docs/docs/core/groups/floatingGroups.mdx index c2a8d338b..991ebd137 100644 --- a/packages/docs/docs/core/groups/floatingGroups.mdx +++ b/packages/docs/docs/core/groups/floatingGroups.mdx @@ -3,7 +3,6 @@ title: Floating Groups --- import useBaseUrl from '@docusaurus/useBaseUrl'; -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef'; This section describes floating groups. @@ -76,4 +75,4 @@ You can check whether a group is floating via the `group.api.location` property. ## Live Example - + diff --git a/packages/docs/docs/core/groups/hiddenHeader.mdx b/packages/docs/docs/core/groups/hiddenHeader.mdx index 0d95cd496..1e65109ff 100644 --- a/packages/docs/docs/core/groups/hiddenHeader.mdx +++ b/packages/docs/docs/core/groups/hiddenHeader.mdx @@ -3,7 +3,6 @@ title: Hidden Header --- import useBaseUrl from '@docusaurus/useBaseUrl'; -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef'; You may wish to hide the header section of a group. This can achieved through the `hidden` variable on `panel.group.header`. diff --git a/packages/docs/docs/core/groups/locked.mdx b/packages/docs/docs/core/groups/locked.mdx index e2a9ee92e..5b74ad8b5 100644 --- a/packages/docs/docs/core/groups/locked.mdx +++ b/packages/docs/docs/core/groups/locked.mdx @@ -2,8 +2,7 @@ title: Locked Groups --- -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import DockviewLockedGroup from '@site/sandboxes/lockedgroup-dockview/src/app'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; ## Locked group @@ -21,7 +20,4 @@ panel.group.locked = 'no-drop-target'; Use `true` to keep drop zones top, right, bottom, left for the group. Use `no-drop-target` to disable all drop zones. For you to get a better understanding of what this means, try and drag the panels in the example below to the locked groups. - + diff --git a/packages/docs/docs/core/groups/maxmizedGroups.mdx b/packages/docs/docs/core/groups/maxmizedGroups.mdx index 109383306..bdefa8519 100644 --- a/packages/docs/docs/core/groups/maxmizedGroups.mdx +++ b/packages/docs/docs/core/groups/maxmizedGroups.mdx @@ -3,7 +3,6 @@ title: Maximized Groups --- import { DocRef } from '@site/src/components/ui/reference/docRef'; -import LiveExample from '@site/src/components/ui/exampleFrame'; This section described how to maxmimize groups. @@ -51,7 +50,7 @@ The methods exist on the panel `api` object for convenience. ## Live Examples - + diff --git a/packages/docs/docs/core/groups/popoutGroups.mdx b/packages/docs/docs/core/groups/popoutGroups.mdx index 6cb5ffdb9..7472a4d05 100644 --- a/packages/docs/docs/core/groups/popoutGroups.mdx +++ b/packages/docs/docs/core/groups/popoutGroups.mdx @@ -2,7 +2,6 @@ title: Popout Windows --- -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef'; This section describes have to create popout windows. @@ -57,4 +56,4 @@ in it's original location within the grid. If the dock cannot determine the orig choose a new location. - + diff --git a/packages/docs/docs/core/groups/resizing.mdx b/packages/docs/docs/core/groups/resizing.mdx index 2b0cb4b42..1e527cc1d 100644 --- a/packages/docs/docs/core/groups/resizing.mdx +++ b/packages/docs/docs/core/groups/resizing.mdx @@ -2,7 +2,6 @@ title: Resizing --- -import LiveExample from '@site/src/components/ui/exampleFrame'; import { DocRef } from '@site/src/components/ui/reference/docRef'; @@ -34,4 +33,4 @@ props.api.group.api.setSize({ You can see an example invoking both approaches below. - + diff --git a/packages/docs/docs/core/locked.mdx b/packages/docs/docs/core/locked.mdx index 82a65a515..65d170d64 100644 --- a/packages/docs/docs/core/locked.mdx +++ b/packages/docs/docs/core/locked.mdx @@ -5,7 +5,6 @@ title: Locked import useBaseUrl from '@docusaurus/useBaseUrl'; import { DocRef } from '@site/src/components/ui/reference/docRef'; -import LiveExample from '@site/src/components/ui/exampleFrame'; This section describes how to lock the dock to prevent movement. @@ -13,4 +12,4 @@ This section describes how to lock the dock to prevent movement. You may want to combine this with `disableDnd={true}` to provide a locked grid with no dnd funtionality. See [Disable Dnd](/docs/core/dnd/disable) for more. ::: - + diff --git a/packages/docs/docs/core/overview.mdx b/packages/docs/docs/core/overview.mdx index e63b7cda4..c0f2e0dfa 100644 --- a/packages/docs/docs/core/overview.mdx +++ b/packages/docs/docs/core/overview.mdx @@ -3,8 +3,6 @@ title: Overview sidebar_position: 0 --- -import LiveExample from '@site/src/components/ui/exampleFrame'; - This section provided a core overview. The component takes a collection of [Options](/docs/api/dockview/options) as inputs and @@ -33,10 +31,3 @@ const component = new DockviewComponent({ ``` -## Container Resizing - -The component will automatically resize to it's container. - - - -# Disposal Pattern diff --git a/packages/docs/docs/core/panels/add.mdx b/packages/docs/docs/core/panels/add.mdx index 70685a319..ab1142b47 100644 --- a/packages/docs/docs/core/panels/add.mdx +++ b/packages/docs/docs/core/panels/add.mdx @@ -4,7 +4,7 @@ sidebar_position: 1 --- import { DocRef } from '@site/src/components/ui/reference/docRef'; -import LiveExample from '@site/src/components/ui/exampleFrame'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; This section describes how to add a new panel and the options you can provide. @@ -48,7 +48,7 @@ api.addPanel({ api.setTitle('my_new_custom_title'); ``` - + ## Provide a custom Tab renderer diff --git a/packages/docs/docs/core/panels/rendering.mdx b/packages/docs/docs/core/panels/rendering.mdx index ca412e95f..0b4d50ac1 100644 --- a/packages/docs/docs/core/panels/rendering.mdx +++ b/packages/docs/docs/core/panels/rendering.mdx @@ -4,11 +4,9 @@ sidebar_postiion: 5 --- import { MultiFrameworkContainer } from '@site/src/components/ui/container'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app'; -import LiveExample from '@site/src/components/ui/exampleFrame'; - - Rendering type is an important consideration when creating your application and whether your panels should be destroyed when hidden. :::info @@ -70,7 +68,7 @@ api.addPanel({ ## Live Example - + By default `DockviewReact` only adds to the DOM those panels that are visible, @@ -130,3 +128,4 @@ Toggling the checkbox you can see that when you only render those panels which a sandboxId="rendering-dockview" react={RenderingDockview} /> + diff --git a/packages/docs/docs/core/panels/resizing.mdx b/packages/docs/docs/core/panels/resizing.mdx index 0c0fd720d..99b163256 100644 --- a/packages/docs/docs/core/panels/resizing.mdx +++ b/packages/docs/docs/core/panels/resizing.mdx @@ -4,7 +4,7 @@ title: Resizing This section describes how to programatically resize a panel. -import LiveExample from '@site/src/components/ui/exampleFrame'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; import { DocRef } from '@site/src/components/ui/reference/docRef'; @@ -37,4 +37,4 @@ props.api.group.api.setSize({ You can see an example invoking both approaches below. - + diff --git a/packages/docs/docs/core/panels/tabs.mdx b/packages/docs/docs/core/panels/tabs.mdx index b6ba80a7b..224052fc7 100644 --- a/packages/docs/docs/core/panels/tabs.mdx +++ b/packages/docs/docs/core/panels/tabs.mdx @@ -4,7 +4,7 @@ sidebar_position: 2 --- import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import CustomHeadersDockview from '@site/sandboxes/customheader-dockview/src/app'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; import DockviewNative from '@site/sandboxes/fullwidthtab-dockview/src/app'; import { attach as attachNativeDockview } from '@site/sandboxes/javascript/fullwidthtab-dockview/src/app'; import { DocRef } from '@site/src/components/ui/reference/docRef'; @@ -99,10 +99,7 @@ As a simple example the below attaches a custom event handler for the context me The below example uses a custom tab renderer to reigster a popover when the user right clicked on a tab. This still makes use of the `DockviewDefaultTab` since it's only a minor change. - + ## Full Width Tab @@ -126,15 +123,7 @@ return typescript={attachNativeDockview} /> -import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app'; -import { attach as attachTabHeightDockview } from '@site/sandboxes/javascript/tabheight-dockview/src/app'; - ## Tab Height Tab height can be controlled through CSS. - diff --git a/packages/docs/docs/core/panels/update.mdx b/packages/docs/docs/core/panels/update.mdx index f12889027..ff07c7ebf 100644 --- a/packages/docs/docs/core/panels/update.mdx +++ b/packages/docs/docs/core/panels/update.mdx @@ -43,4 +43,4 @@ panel.api.updateParameters({ ## Live Example - + diff --git a/packages/docs/docs/core/scrollbars.mdx b/packages/docs/docs/core/scrollbars.mdx index a46c5f7cd..b8e23d72c 100644 --- a/packages/docs/docs/core/scrollbars.mdx +++ b/packages/docs/docs/core/scrollbars.mdx @@ -2,8 +2,6 @@ title: Scrolling --- -import LiveExample from '@site/src/components/ui/exampleFrame'; - It's important to understand how to configure the scrollbar within a panel. A panel will appear with a scrollbar if the the contents of your view has a fixed height. @@ -17,4 +15,4 @@ The following example contains three views: - **Panel 2** (`height: 2000px`): A scrollbar does appear since a fixed height has been used. - **Panel 3**: `height: 100%` and a child component with `overflow: auto` which will enable scrollbars. - + diff --git a/packages/docs/docs/core/state/load.mdx b/packages/docs/docs/core/state/load.mdx index 483f1cf6c..abb23e868 100644 --- a/packages/docs/docs/core/state/load.mdx +++ b/packages/docs/docs/core/state/load.mdx @@ -2,8 +2,7 @@ title: Loading State --- -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import LiveExample from '@site/src/components/ui/exampleFrame'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; import { DocRef } from '@site/src/components/ui/reference/docRef'; This section described loading a dock layout. @@ -43,5 +42,6 @@ return ; # Live Example - + + diff --git a/packages/docs/docs/core/state/save.mdx b/packages/docs/docs/core/state/save.mdx index 008480a31..6e40268fe 100644 --- a/packages/docs/docs/core/state/save.mdx +++ b/packages/docs/docs/core/state/save.mdx @@ -2,9 +2,7 @@ title: Saving State --- - -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; -import LiveExample from '@site/src/components/ui/exampleFrame'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; import { DocRef } from '@site/src/components/ui/reference/docRef'; This section describes how to serialize a dockview instance. @@ -39,5 +37,4 @@ return # Live Example - - + diff --git a/packages/docs/docs/core/watermark.mdx b/packages/docs/docs/core/watermark.mdx index 091ab7aba..7efa35359 100644 --- a/packages/docs/docs/core/watermark.mdx +++ b/packages/docs/docs/core/watermark.mdx @@ -5,7 +5,6 @@ title: Watermark import useBaseUrl from '@docusaurus/useBaseUrl'; import { DocRef } from '@site/src/components/ui/reference/docRef'; -import LiveExample from '@site/src/components/ui/exampleFrame'; When there is nothing else to display. @@ -28,4 +27,4 @@ The following properties can be set to configure the behaviours of floating grou ## Live Examples - + diff --git a/packages/docs/docs/other/tabview.mdx b/packages/docs/docs/other/tabview.mdx index 2505ede8e..51a44ce0f 100644 --- a/packages/docs/docs/other/tabview.mdx +++ b/packages/docs/docs/other/tabview.mdx @@ -5,6 +5,4 @@ sidebar_position: 3 A *tabview* can be created using a dock and preventing some default behaviours. -import LiveExample from '@site/src/components/ui/exampleFrame'; - - + diff --git a/packages/docs/docs/overview/getStarted/installation.mdx b/packages/docs/docs/overview/getStarted/installation.mdx index 4fc04b1ac..bd410fc0b 100644 --- a/packages/docs/docs/overview/getStarted/installation.mdx +++ b/packages/docs/docs/overview/getStarted/installation.mdx @@ -7,7 +7,7 @@ sidebar_position: 0 Learn how to install Dockview for a selection of frameworks. -Firstly, install the `dockvire-core` library: +Firstly, install the `dockview-core` library: ```sh npm install dockview-core @@ -22,8 +22,3 @@ npm install dockview ``` -import { IsolatedCodeExample } from '@site/src/components/ui/isolatedCodeExample'; - - - - diff --git a/packages/docs/old_docs_DELETE_SOON/components/gridview/gridview.mdx b/packages/docs/old_docs_DELETE_SOON/components/gridview/gridview.mdx index 5d61ed21a..d80e97740 100644 --- a/packages/docs/old_docs_DELETE_SOON/components/gridview/gridview.mdx +++ b/packages/docs/old_docs_DELETE_SOON/components/gridview/gridview.mdx @@ -5,9 +5,7 @@ description: Gridview Documentation import { MultiFrameworkContainer } from '@site/src/components/ui/container'; import SimpleGridview from '@site/sandboxes/simple-gridview/src/app'; import EditorGridview from '@site/sandboxes/editor-gridview/src/app'; -// import SimpleGridview from '@site/sandboxes/simple-gridview/src/app'; import { EventsGridview } from '@site/src/components/gridview/events'; -// import IDEExample from '@site/sandboxes/ide-example/src/app'; import Link from '@docusaurus/Link'; import { DocRef } from '@site/src/components/ui/reference/docRef'; diff --git a/packages/docs/old_docs_DELETE_SOON/components/intro.mdx b/packages/docs/old_docs_DELETE_SOON/components/intro.mdx index d54f2e272..e725de003 100644 --- a/packages/docs/old_docs_DELETE_SOON/components/intro.mdx +++ b/packages/docs/old_docs_DELETE_SOON/components/intro.mdx @@ -4,10 +4,9 @@ sidebar_position: 0 --- import { MultiFrameworkContainer } from '@site/src/components/ui/container'; +import { CodeRunner } from '@site/src/components/ui/codeRunner'; -import SimpleDockview from '@site/sandboxes/simple-dockview/src/app'; import DockviewExampleApp from '@site/sandboxes/example-app-dockview/src/app'; -import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app'; +
@@ -60,19 +55,3 @@ const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => { return
{`My first panel has the title: ${props.params.title}`}
; }; ``` - - - - - - - - - - - - - - - - diff --git a/packages/docs/old_docs_DELETE_SOON/index.mdx b/packages/docs/old_docs_DELETE_SOON/index.mdx index f16129c6f..aa113ad9c 100644 --- a/packages/docs/old_docs_DELETE_SOON/index.mdx +++ b/packages/docs/old_docs_DELETE_SOON/index.mdx @@ -4,12 +4,9 @@ description: A zero dependency layout manager supporting ReactJS and Vanilla Typ title: Introduction --- -import { MultiFrameworkContainer } from '@site/src/components/ui/container'; - import { SimpleSplitview } from '@site/src/components/simpleSplitview'; import { SimpleGridview } from '@site/src/components/simpleGridview'; import { SimplePaneview } from '@site/src/components/simplePaneview'; -// import DockviewDemo from '@site/sandboxes/demo-dockview/src/app'; import Link from '@docusaurus/Link'; **dockview** is a zero dependency layout manager that supports tab, grids and splitviews. @@ -35,11 +32,6 @@ There are 4 components you may want to use:

Dockview

-{/* */}

Splitview

diff --git a/packages/docs/package.json b/packages/docs/package.json index 97a495a8c..305149b07 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -5,11 +5,13 @@ "scripts": { "build": "npm run create-templates && docusaurus build", "clear": "docusaurus clear", - "start": "docusaurus start", + "start": "concurrently \"docusaurus start\" \"npm run start-esm-server\"", + "start-esm-server": "node web-server/index.mjs", "swizzle": "docusaurus swizzle @docusaurus/theme-classic", "docs:version": "docusaurus docs:version", "typecheck": "tsc", - "create-templates": "node scripts/buildTemplates.mjs" + "create-templates": "node scripts/buildTemplates.mjs", + "create-templates:local": "node scripts/buildTemplates.mjs --local" }, "browserslist": { "production": [ diff --git a/packages/docs/scripts/buildTemplates.mjs b/packages/docs/scripts/buildTemplates.mjs index ff02fad89..2cda726fb 100644 --- a/packages/docs/scripts/buildTemplates.mjs +++ b/packages/docs/scripts/buildTemplates.mjs @@ -1,5 +1,6 @@ import fs from 'fs-extra'; import * as path from 'path'; +import { argv } from 'process'; import { fileURLToPath } from 'url'; @@ -8,7 +9,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const REACT_VERSION = '18.2.0'; const VUE_VERSION = '3.4.21'; const DOCKVIEW_VERSION = '1.11.0'; -const USE_LOCAL_CDN = true; +const USE_LOCAL_CDN = argv.slice(2).includes('--local'); const local = 'http://localhost:1111'; @@ -35,7 +36,7 @@ const DOCKVIEW_CDN = { 'dockview-vue': `${local}/dockview-vue/dist/dockview-vue.es.js`, }, }, - js: { + typescript: { remote: { 'dockview-core': `https://cdn.jsdelivr.net/npm/dockview-core@${DOCKVIEW_VERSION}/dist/dockview-core.esm.js`, 'dockview-core/': `https://cdn.jsdelivr.net/npm/dockview-core@${DOCKVIEW_VERSION}/`, @@ -57,8 +58,9 @@ const IMPORTS_PATHS = { vue: { vue: `https://cdn.jsdelivr.net/npm/vue@${VUE_VERSION}/dist/vue.esm-browser.js`, '@vue/reactivity': `https://esm.sh/@vue/reactivity@${VUE_VERSION}`, + 'vue-sfc-loader': `https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.9.5/dist/vue3-sfc-loader.js`, }, - js: {}, + typescript: {}, angular: {}, }; @@ -82,7 +84,7 @@ const input_dir = path.join(__dirname, '../templates'); const output = path.join(__dirname, '../static/templates'); const COMPONENTS = ['dockview']; -const FRAMEWORKS = ['react', 'vue']; +const FRAMEWORKS = ['react', 'vue', 'typescript']; const list = []; diff --git a/packages/docs/src/components/HomepageFeatures/introduction.tsx b/packages/docs/src/components/HomepageFeatures/introduction.tsx index b73baa448..a9068e808 100644 --- a/packages/docs/src/components/HomepageFeatures/introduction.tsx +++ b/packages/docs/src/components/HomepageFeatures/introduction.tsx @@ -3,7 +3,6 @@ import HomepageFeatures from '.'; import { BrowserHeader } from '../ui/browserHeader'; import { MultiFrameworkContainer } from '../ui/container'; import * as React from 'react'; -// import DockviewDemo from '@site/sandboxes/demo-dockview/src/app'; import DockviewDemo2 from '@site/sandboxes/dockview-app/src/app'; export const Introduction = () => { @@ -25,11 +24,6 @@ export const Introduction = () => {
- {/* */}
diff --git a/packages/docs/src/components/frameworkSpecific.tsx b/packages/docs/src/components/frameworkSpecific.tsx index da6690e26..cd4cc3d2b 100644 --- a/packages/docs/src/components/frameworkSpecific.tsx +++ b/packages/docs/src/components/frameworkSpecific.tsx @@ -11,7 +11,7 @@ const frameworks = [ const activeFrameworkGlobal = new DockviewEmitter({ replay: true }); -function useActiveFramework(): [string, (value: string) => void] { +export function useActiveFramework(): [string, (value: string) => void] { const [value, setValue] = React.useState( localStorage.getItem('dv-docs-framework') ?? frameworks[0].value ); diff --git a/packages/docs/src/components/ui/codeRunner.tsx b/packages/docs/src/components/ui/codeRunner.tsx new file mode 100644 index 000000000..8b930b2cc --- /dev/null +++ b/packages/docs/src/components/ui/codeRunner.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import { useActiveFramework } from '../frameworkSpecific'; +import BrowserOnly from '@docusaurus/BrowserOnly'; + +const BASE_SANDBOX_URL = + 'https://codesandbox.io/s/github/mathuo/dockview/tree/master/packages/docs'; + +export const _CodeRunner = (props: { + id: string; + framework: string; + height: number; +}) => { + useActiveFramework(); + + const sandboxUrl = `${BASE_SANDBOX_URL}/templates/${props.id}/${props.framework}`; + const path = `/templates/${props.id}/${props.framework}/index.html`; + return ( +
+