@flowgram-vue/playground-vue 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ Copyright (c) 2026 Crayon
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/dist/index.cjs ADDED
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables/use-playground-tools.ts","../src/layers/playground-content-layer.ts","../src/preset/playground-vue-preset.ts","../src/components/playground-vue.vue","../src/components/playground-vue-content.ts"],"names":["usePlayground","useConfigEntity","EditorStateConfigEntity","ref","EditorState","DisposableCollection","onBeforeUnmount","watch","computed","reactive","Layer","domUtils","h","injectable","backgroundPlugin","shortcutsPlugin","createPlaygroundPlugin","ctx","PlaygroundConfig","PlaygroundLayer","_createBlock","_createVNode","_withCtx","_renderSlot","defineComponent"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport {\n EditorState,\n EditorStateConfigEntity,\n type PlaygroundInteractiveType,\n useConfigEntity,\n usePlayground,\n} from '@flowgram-vue/core';\nimport { DisposableCollection } from '@flowgram-vue/utils';\nimport { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';\n\nexport interface PlaygroundToolsPropsType {\n /**\n * 最大缩放比,默认 2\n */\n maxZoom?: number;\n /**\n * 最小缩放比,默认 0.25\n */\n minZoom?: number;\n}\n\nexport interface PlaygroundTools {\n /**\n * 缩放 zoom 大小比例\n */\n zoom: number;\n /**\n * 放大\n */\n zoomin: (easing?: boolean) => void;\n /**\n * 缩小\n */\n zoomout: (easing?: boolean) => void;\n /**\n * 设置缩放比例\n */\n updateZoom: (newZoom: number, easing?: boolean, easingDuration?: number) => void;\n /**\n * 当前的交互模式, 鼠标友好模式 和 触摸板模式\n */\n interactiveType: PlaygroundInteractiveType;\n /**\n * 切换交互模式\n */\n toggleIneractiveType: () => void;\n}\n\nexport function usePlaygroundTools(props?: PlaygroundToolsPropsType): PlaygroundTools {\n const { maxZoom, minZoom } = props || {};\n const playground = usePlayground();\n const editorState = useConfigEntity(EditorStateConfigEntity, true);\n\n const zoom = ref(1);\n\n const handleZoomOut = (easing?: boolean) => {\n playground.config.zoomout(easing);\n };\n\n const handleZoomIn = (easing?: boolean) => {\n playground.config.zoomin(easing);\n };\n\n const handleUpdateZoom = (value: number, easing?: boolean, easingDuration?: number) => {\n playground.config.updateZoom(value, easing, easingDuration);\n };\n\n const handleToggleIneractiveType = () => {\n if (editorState.isMouseFriendlyMode()) {\n editorState.changeState(EditorState.STATE_SELECT.id);\n } else {\n editorState.changeState(EditorState.STATE_MOUSE_FRIENDLY_SELECT.id);\n }\n };\n\n const dispose = new DisposableCollection();\n dispose.push(playground.onZoom((z) => (zoom.value = z)));\n onBeforeUnmount(() => dispose.dispose());\n\n watch(\n () => [maxZoom, minZoom],\n () => {\n const config = playground.config.config;\n playground.config.updateConfig({\n maxZoom: maxZoom !== undefined ? maxZoom : config.maxZoom,\n minZoom: minZoom !== undefined ? minZoom : config.minZoom,\n });\n },\n { immediate: true }\n );\n\n const interactiveType = computed<PlaygroundInteractiveType>(() =>\n editorState.isMouseFriendlyMode() ? 'MOUSE' : 'PAD'\n );\n\n return reactive({\n zoomin: handleZoomIn,\n zoomout: handleZoomOut,\n updateZoom: handleUpdateZoom,\n zoom,\n interactiveType,\n toggleIneractiveType: handleToggleIneractiveType,\n }) as PlaygroundTools;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Layer } from '@flowgram-vue/core';\nimport { domUtils } from '@flowgram-vue/utils';\nimport { injectable } from 'inversify';\nimport { h, type CSSProperties, type VNode } from 'vue';\n\nexport interface PlaygroundVueContentProps {\n className?: string;\n style?: CSSProperties;\n children?: VNode | VNode[];\n}\n\n@injectable()\nexport class PlaygroundContentLayer extends Layer<PlaygroundVueContentProps> {\n static type = 'PlaygroundContentLayer';\n\n readonly node = domUtils.createDivWithClass(\n 'gedit-playground-layer gedit-playground-content-layer'\n );\n\n onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n onReady() {\n this.node.style.left = '0px';\n this.node.style.top = '0px';\n }\n\n updateOptions(opts: PlaygroundVueContentProps) {\n this.options = opts;\n this.render();\n }\n\n render() {\n return h(\n 'div',\n {\n class: this.options.className,\n style: { position: 'absolute', ...this.options.style },\n },\n this.options.children\n );\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport * as backgroundPlugin from '@flowgram-vue/background-plugin';\nimport {\n createPlaygroundPlugin,\n PlaygroundConfig,\n PlaygroundLayer,\n type Plugin,\n type PluginContext,\n type PluginsProvider,\n} from '@flowgram-vue/core';\nimport * as shortcutsPlugin from '@flowgram-vue/shortcuts-plugin';\n\nimport type {\n BackgroundLayerOptions,\n PlaygroundVueProps,\n ShortcutsRegistry,\n} from './playground-vue-props';\n\ntype BackgroundPluginExports = {\n createBackgroundPlugin?: (options: BackgroundLayerOptions) => Plugin;\n};\n\ntype ShortcutsPluginExports = {\n createShortcutsPlugin?: (options: {\n registerShortcuts: (registry: ShortcutsRegistry) => void;\n }) => Plugin;\n};\n\nexport function createPlaygroundVuePreset<CTX extends PluginContext = PluginContext>(\n opts: PlaygroundVueProps<CTX>,\n plugins: Plugin[] = []\n): PluginsProvider<CTX> {\n return (ctx: CTX) => {\n plugins = plugins.slice();\n const { createBackgroundPlugin } = backgroundPlugin as BackgroundPluginExports;\n const { createShortcutsPlugin } = shortcutsPlugin as ShortcutsPluginExports;\n /**\n * 注册背景 (放前面插入), 默认打开\n */\n if (opts.background || opts.background === undefined) {\n const backgroundOptions = typeof opts.background === 'object' ? opts.background : {};\n if (typeof createBackgroundPlugin === 'function') {\n plugins.push(createBackgroundPlugin(backgroundOptions));\n }\n }\n /**\n * 注册快捷键\n */\n if (opts.shortcuts && typeof createShortcutsPlugin === 'function') {\n plugins.push(\n createShortcutsPlugin({\n registerShortcuts: (registry) => opts.shortcuts!(registry, ctx),\n })\n );\n }\n /**\n * 注册三方插件\n */\n if (opts.plugins) {\n plugins.push(...opts.plugins(ctx));\n }\n /**\n * 画布生命周期注册\n */\n plugins.push(\n createPlaygroundPlugin<CTX>({\n onBind: (bindConfig) => {\n opts.onBind?.(bindConfig);\n },\n onInit: (ctx) => {\n const playgroundConfig = ctx.get<PlaygroundConfig>(PlaygroundConfig);\n if (opts.playground) {\n if (opts.playground.autoFocus !== undefined) {\n playgroundConfig.autoFocus = opts.playground.autoFocus;\n }\n if (opts.playground.autoResize !== undefined) {\n playgroundConfig.autoResize = opts.playground.autoResize;\n }\n }\n playgroundConfig.autoFocus = false;\n ctx.playground.registerLayer(PlaygroundLayer, opts.playground);\n if (opts.layers) {\n ctx.playground.registerLayers(...opts.layers);\n }\n if (opts.onInit) opts.onInit(ctx);\n },\n onReady(ctx) {\n if (opts.onReady) opts.onReady(ctx);\n },\n onAllLayersRendered() {\n if (opts.onAllLayersRendered) opts.onAllLayersRendered(ctx);\n },\n onDispose() {\n if (opts.onDispose) opts.onDispose(ctx);\n },\n containerModules: opts.containerModules || [],\n })\n );\n return plugins;\n };\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\nimport {\n createPlaygroundPlugin,\n PlaygroundVueProvider,\n PlaygroundVueRenderer,\n type PluginContext,\n} from '@flowgram-vue/core';\nimport { ref } from 'vue';\n\nimport { PlaygroundContentLayer } from '../layers/playground-content-layer';\nimport { createPlaygroundVuePreset, type PlaygroundVueProps } from '../preset';\n\ndefineOptions({ name: 'PlaygroundVue' });\n\nconst props = defineProps<PlaygroundVueProps>();\n\nconst providerRef = ref<PluginContext | null>(null);\n\nconst contentLoadPlugin = createPlaygroundPlugin({\n onInit(ctx) {\n ctx.playground.registerLayer(PlaygroundContentLayer);\n },\n});\n\nconst preset = createPlaygroundVuePreset(props, [contentLoadPlugin]);\n\ndefineExpose({\n get playground() {\n return providerRef.value?.playground as PluginContext['playground'];\n },\n get container() {\n return providerRef.value?.container as PluginContext['container'];\n },\n get: ((identifier) => providerRef.value?.get(identifier)) as PluginContext['get'],\n getAll: ((identifier) => providerRef.value?.getAll(identifier) ?? []) as PluginContext['getAll'],\n});\n</script>\n\n<template>\n <PlaygroundVueProvider\n ref=\"providerRef\"\n :plugins=\"preset\"\n :parent-container=\"props.parentContainer\"\n >\n <PlaygroundVueRenderer>\n <slot />\n </PlaygroundVueRenderer>\n </PlaygroundVueProvider>\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { usePlayground } from '@flowgram-vue/core';\nimport { defineComponent, type CSSProperties, type PropType } from 'vue';\n\nimport { PlaygroundContentLayer } from '../layers/playground-content-layer';\n\nexport const PlaygroundVueContent = defineComponent({\n name: 'PlaygroundVueContent',\n props: {\n className: String,\n style: Object as PropType<CSSProperties>,\n },\n setup(props, { slots }) {\n const playground = usePlayground();\n return () => {\n const layer = playground.getLayer(PlaygroundContentLayer);\n layer?.updateOptions({\n className: props.className,\n style: props.style,\n children: slots.default?.(),\n });\n return null;\n };\n },\n});\n"]}
@@ -0,0 +1 @@
1
+ export * from '../src/index';
package/dist/index.js ADDED
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables/use-playground-tools.ts","../src/layers/playground-content-layer.ts","../src/preset/playground-vue-preset.ts","../src/components/playground-vue.vue","../src/components/playground-vue-content.ts"],"names":["ctx","ref","createPlaygroundPlugin","_createBlock","_createVNode","_withCtx","_renderSlot","usePlayground"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport {\n EditorState,\n EditorStateConfigEntity,\n type PlaygroundInteractiveType,\n useConfigEntity,\n usePlayground,\n} from '@flowgram-vue/core';\nimport { DisposableCollection } from '@flowgram-vue/utils';\nimport { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';\n\nexport interface PlaygroundToolsPropsType {\n /**\n * 最大缩放比,默认 2\n */\n maxZoom?: number;\n /**\n * 最小缩放比,默认 0.25\n */\n minZoom?: number;\n}\n\nexport interface PlaygroundTools {\n /**\n * 缩放 zoom 大小比例\n */\n zoom: number;\n /**\n * 放大\n */\n zoomin: (easing?: boolean) => void;\n /**\n * 缩小\n */\n zoomout: (easing?: boolean) => void;\n /**\n * 设置缩放比例\n */\n updateZoom: (newZoom: number, easing?: boolean, easingDuration?: number) => void;\n /**\n * 当前的交互模式, 鼠标友好模式 和 触摸板模式\n */\n interactiveType: PlaygroundInteractiveType;\n /**\n * 切换交互模式\n */\n toggleIneractiveType: () => void;\n}\n\nexport function usePlaygroundTools(props?: PlaygroundToolsPropsType): PlaygroundTools {\n const { maxZoom, minZoom } = props || {};\n const playground = usePlayground();\n const editorState = useConfigEntity(EditorStateConfigEntity, true);\n\n const zoom = ref(1);\n\n const handleZoomOut = (easing?: boolean) => {\n playground.config.zoomout(easing);\n };\n\n const handleZoomIn = (easing?: boolean) => {\n playground.config.zoomin(easing);\n };\n\n const handleUpdateZoom = (value: number, easing?: boolean, easingDuration?: number) => {\n playground.config.updateZoom(value, easing, easingDuration);\n };\n\n const handleToggleIneractiveType = () => {\n if (editorState.isMouseFriendlyMode()) {\n editorState.changeState(EditorState.STATE_SELECT.id);\n } else {\n editorState.changeState(EditorState.STATE_MOUSE_FRIENDLY_SELECT.id);\n }\n };\n\n const dispose = new DisposableCollection();\n dispose.push(playground.onZoom((z) => (zoom.value = z)));\n onBeforeUnmount(() => dispose.dispose());\n\n watch(\n () => [maxZoom, minZoom],\n () => {\n const config = playground.config.config;\n playground.config.updateConfig({\n maxZoom: maxZoom !== undefined ? maxZoom : config.maxZoom,\n minZoom: minZoom !== undefined ? minZoom : config.minZoom,\n });\n },\n { immediate: true }\n );\n\n const interactiveType = computed<PlaygroundInteractiveType>(() =>\n editorState.isMouseFriendlyMode() ? 'MOUSE' : 'PAD'\n );\n\n return reactive({\n zoomin: handleZoomIn,\n zoomout: handleZoomOut,\n updateZoom: handleUpdateZoom,\n zoom,\n interactiveType,\n toggleIneractiveType: handleToggleIneractiveType,\n }) as PlaygroundTools;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Layer } from '@flowgram-vue/core';\nimport { domUtils } from '@flowgram-vue/utils';\nimport { injectable } from 'inversify';\nimport { h, type CSSProperties, type VNode } from 'vue';\n\nexport interface PlaygroundVueContentProps {\n className?: string;\n style?: CSSProperties;\n children?: VNode | VNode[];\n}\n\n@injectable()\nexport class PlaygroundContentLayer extends Layer<PlaygroundVueContentProps> {\n static type = 'PlaygroundContentLayer';\n\n readonly node = domUtils.createDivWithClass(\n 'gedit-playground-layer gedit-playground-content-layer'\n );\n\n onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n onReady() {\n this.node.style.left = '0px';\n this.node.style.top = '0px';\n }\n\n updateOptions(opts: PlaygroundVueContentProps) {\n this.options = opts;\n this.render();\n }\n\n render() {\n return h(\n 'div',\n {\n class: this.options.className,\n style: { position: 'absolute', ...this.options.style },\n },\n this.options.children\n );\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport * as backgroundPlugin from '@flowgram-vue/background-plugin';\nimport {\n createPlaygroundPlugin,\n PlaygroundConfig,\n PlaygroundLayer,\n type Plugin,\n type PluginContext,\n type PluginsProvider,\n} from '@flowgram-vue/core';\nimport * as shortcutsPlugin from '@flowgram-vue/shortcuts-plugin';\n\nimport type {\n BackgroundLayerOptions,\n PlaygroundVueProps,\n ShortcutsRegistry,\n} from './playground-vue-props';\n\ntype BackgroundPluginExports = {\n createBackgroundPlugin?: (options: BackgroundLayerOptions) => Plugin;\n};\n\ntype ShortcutsPluginExports = {\n createShortcutsPlugin?: (options: {\n registerShortcuts: (registry: ShortcutsRegistry) => void;\n }) => Plugin;\n};\n\nexport function createPlaygroundVuePreset<CTX extends PluginContext = PluginContext>(\n opts: PlaygroundVueProps<CTX>,\n plugins: Plugin[] = []\n): PluginsProvider<CTX> {\n return (ctx: CTX) => {\n plugins = plugins.slice();\n const { createBackgroundPlugin } = backgroundPlugin as BackgroundPluginExports;\n const { createShortcutsPlugin } = shortcutsPlugin as ShortcutsPluginExports;\n /**\n * 注册背景 (放前面插入), 默认打开\n */\n if (opts.background || opts.background === undefined) {\n const backgroundOptions = typeof opts.background === 'object' ? opts.background : {};\n if (typeof createBackgroundPlugin === 'function') {\n plugins.push(createBackgroundPlugin(backgroundOptions));\n }\n }\n /**\n * 注册快捷键\n */\n if (opts.shortcuts && typeof createShortcutsPlugin === 'function') {\n plugins.push(\n createShortcutsPlugin({\n registerShortcuts: (registry) => opts.shortcuts!(registry, ctx),\n })\n );\n }\n /**\n * 注册三方插件\n */\n if (opts.plugins) {\n plugins.push(...opts.plugins(ctx));\n }\n /**\n * 画布生命周期注册\n */\n plugins.push(\n createPlaygroundPlugin<CTX>({\n onBind: (bindConfig) => {\n opts.onBind?.(bindConfig);\n },\n onInit: (ctx) => {\n const playgroundConfig = ctx.get<PlaygroundConfig>(PlaygroundConfig);\n if (opts.playground) {\n if (opts.playground.autoFocus !== undefined) {\n playgroundConfig.autoFocus = opts.playground.autoFocus;\n }\n if (opts.playground.autoResize !== undefined) {\n playgroundConfig.autoResize = opts.playground.autoResize;\n }\n }\n playgroundConfig.autoFocus = false;\n ctx.playground.registerLayer(PlaygroundLayer, opts.playground);\n if (opts.layers) {\n ctx.playground.registerLayers(...opts.layers);\n }\n if (opts.onInit) opts.onInit(ctx);\n },\n onReady(ctx) {\n if (opts.onReady) opts.onReady(ctx);\n },\n onAllLayersRendered() {\n if (opts.onAllLayersRendered) opts.onAllLayersRendered(ctx);\n },\n onDispose() {\n if (opts.onDispose) opts.onDispose(ctx);\n },\n containerModules: opts.containerModules || [],\n })\n );\n return plugins;\n };\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\nimport {\n createPlaygroundPlugin,\n PlaygroundVueProvider,\n PlaygroundVueRenderer,\n type PluginContext,\n} from '@flowgram-vue/core';\nimport { ref } from 'vue';\n\nimport { PlaygroundContentLayer } from '../layers/playground-content-layer';\nimport { createPlaygroundVuePreset, type PlaygroundVueProps } from '../preset';\n\ndefineOptions({ name: 'PlaygroundVue' });\n\nconst props = defineProps<PlaygroundVueProps>();\n\nconst providerRef = ref<PluginContext | null>(null);\n\nconst contentLoadPlugin = createPlaygroundPlugin({\n onInit(ctx) {\n ctx.playground.registerLayer(PlaygroundContentLayer);\n },\n});\n\nconst preset = createPlaygroundVuePreset(props, [contentLoadPlugin]);\n\ndefineExpose({\n get playground() {\n return providerRef.value?.playground as PluginContext['playground'];\n },\n get container() {\n return providerRef.value?.container as PluginContext['container'];\n },\n get: ((identifier) => providerRef.value?.get(identifier)) as PluginContext['get'],\n getAll: ((identifier) => providerRef.value?.getAll(identifier) ?? []) as PluginContext['getAll'],\n});\n</script>\n\n<template>\n <PlaygroundVueProvider\n ref=\"providerRef\"\n :plugins=\"preset\"\n :parent-container=\"props.parentContainer\"\n >\n <PlaygroundVueRenderer>\n <slot />\n </PlaygroundVueRenderer>\n </PlaygroundVueProvider>\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { usePlayground } from '@flowgram-vue/core';\nimport { defineComponent, type CSSProperties, type PropType } from 'vue';\n\nimport { PlaygroundContentLayer } from '../layers/playground-content-layer';\n\nexport const PlaygroundVueContent = defineComponent({\n name: 'PlaygroundVueContent',\n props: {\n className: String,\n style: Object as PropType<CSSProperties>,\n },\n setup(props, { slots }) {\n const playground = usePlayground();\n return () => {\n const layer = playground.getLayer(PlaygroundContentLayer);\n layer?.updateOptions({\n className: props.className,\n style: props.style,\n children: slots.default?.(),\n });\n return null;\n };\n },\n});\n"]}
package/index.css ADDED
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ :root {
7
+ --g-selection-background: #4d53e8;
8
+ --g-editor-background: #f2f3f5;
9
+ --g-playground-select: var(--g-selection-background);
10
+ --g-playground-hover: var(--g-selection-background);
11
+ --g-playground-line: var(--g-selection-background);
12
+ --g-playground-blur: #999;
13
+ --g-playground-selectBox-outline: var(--g-selection-background);
14
+ --g-playground-selectBox-background: rgba(141, 144, 231, 0.1);
15
+ --g-playground-select-hover-background: rgba(77, 83, 232, 0.1);
16
+ --g-playground-select-control-size: 12px;
17
+ }
18
+
19
+ .gedit-playground {
20
+ position: absolute;
21
+ width: 100%;
22
+ height: 100%;
23
+ left: 0;
24
+ top: 0;
25
+ z-index: 10;
26
+ overflow: hidden;
27
+ user-select: none;
28
+ outline: none;
29
+ box-sizing: border-box;
30
+ background-color: var(--g-editor-background);
31
+ }
32
+
33
+ .gedit-playground-scroll-right {
34
+ position: absolute;
35
+ right: 2px;
36
+ height: 100vh;
37
+ width: 7px;
38
+ z-index: 10;
39
+ }
40
+
41
+ .gedit-playground-scroll-bottom {
42
+ position: absolute;
43
+ bottom: 2px;
44
+ width: 100vw;
45
+ height: 7px;
46
+ z-index: 10;
47
+ }
48
+
49
+ .gedit-playground-scroll-right-block {
50
+ position: absolute;
51
+ opacity: 0.3;
52
+ border-radius: 3.5px;
53
+ }
54
+
55
+ .gedit-playground-scroll-right-block:hover {
56
+ opacity: 0.6;
57
+ }
58
+
59
+ .gedit-playground-scroll-bottom-block {
60
+ position: absolute;
61
+ opacity: 0.3;
62
+ border-radius: 3.5px;
63
+ }
64
+
65
+ .gedit-playground-scroll-bottom-block:hover {
66
+ opacity: 0.6;
67
+ }
68
+
69
+ .gedit-playground-scroll-hidden {
70
+ opacity: 0;
71
+ }
72
+
73
+ .gedit-playground * {
74
+ box-sizing: border-box;
75
+ }
76
+
77
+ .gedit-playground-loading {
78
+ position: absolute;
79
+ color: white;
80
+ left: 50%;
81
+ top: 50%;
82
+ z-index: 100;
83
+ display: flex;
84
+ justify-content: center;
85
+ align-items: center;
86
+ transition: opacity 0.8s;
87
+ flex-direction: column;
88
+ text-align: center;
89
+ opacity: 0.8;
90
+ }
91
+
92
+ .gedit-hidden {
93
+ display: none;
94
+ }
95
+
96
+ .gedit-playground-pipeline {
97
+ position: absolute;
98
+ overflow: visible;
99
+ width: 100%;
100
+ height: 100%;
101
+ left: 0;
102
+ top: 0;
103
+ }
104
+
105
+ .gedit-playground-pipeline::before {
106
+ content: '';
107
+ position: absolute;
108
+ width: 1px;
109
+ height: 100%;
110
+ left: 0;
111
+ top: 0;
112
+ }
113
+
114
+ .gedit-playground-layer {
115
+ position: absolute;
116
+ overflow: visible;
117
+ }
118
+
119
+ .gedit-selector-box {
120
+ position: absolute;
121
+ left: 0;
122
+ top: 0;
123
+ width: 0;
124
+ height: 0;
125
+ z-index: 33;
126
+ outline: 1px solid var(--g-playground-selectBox-outline);
127
+ background-color: var(--g-playground-selectBox-background);
128
+ }
129
+
130
+ .gedit-selector-box-block {
131
+ position: absolute;
132
+ left: 0;
133
+ top: 0;
134
+ width: 0;
135
+ height: 0;
136
+ z-index: 9999;
137
+ display: none;
138
+ background-color: rgba(0, 0, 0, 0);
139
+ }
140
+
141
+ .gedit-selector-bounds-background {
142
+ position: absolute;
143
+ left: 0;
144
+ top: 0;
145
+ width: 0;
146
+ height: 0;
147
+ outline: 1px solid var(--g-playground-selectBox-outline);
148
+ background-color: #f0f4ff;
149
+ }
150
+
151
+ .gedit-selector-bounds-foreground {
152
+ position: absolute;
153
+ left: 0;
154
+ top: 0;
155
+ width: 0;
156
+ height: 0;
157
+ z-index: 33;
158
+ background: rgba(255, 255, 255, 0);
159
+ }
160
+
161
+ .gedit-grid-svg {
162
+ display: block;
163
+ position: absolute;
164
+ left: 20px;
165
+ top: 20px;
166
+ width: 0;
167
+ height: 0;
168
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@flowgram-vue/playground-vue",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "homepage": "https://flowgram.ai/",
7
+ "repository": "https://github.com/Crayon-hua/flowgram-vue",
8
+ "description": "Vue Playground mount for FlowGram (port of playground-react).",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./index.css": "./index.css"
16
+ },
17
+ "main": "./dist/index.cjs",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "src",
22
+ "dist",
23
+ "index.css"
24
+ ],
25
+ "dependencies": {
26
+ "inversify": "^6.0.1",
27
+ "reflect-metadata": "~0.2.2",
28
+ "@flowgram-vue/background-plugin": "0.2.0",
29
+ "@flowgram-vue/core": "0.2.0",
30
+ "@flowgram-vue/utils": "0.2.0",
31
+ "@flowgram-vue/shortcuts-plugin": "0.2.0"
32
+ },
33
+ "peerDependencies": {
34
+ "vue": "^3.3.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^20",
38
+ "@vitejs/plugin-vue": "^6.0.1",
39
+ "@vitest/coverage-v8": "^3.2.4",
40
+ "@vue/test-utils": "^2.4.6",
41
+ "eslint": "^9.0.0",
42
+ "jsdom": "^26.1.0",
43
+ "typescript": "^5.8.3",
44
+ "vitest": "^3.2.4",
45
+ "vue": "^3.5.18",
46
+ "@flowgram-vue/ts-config": "0.2.0",
47
+ "@flowgram-vue/build-config": "0.2.0",
48
+ "@flowgram-vue/eslint-config": "0.2.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public",
52
+ "registry": "https://registry.npmjs.org/"
53
+ },
54
+ "scripts": {
55
+ "build": "flowgram-build",
56
+ "test": "vitest run",
57
+ "lint": "eslint .",
58
+ "ts-check": "tsc --noEmit",
59
+ "type-check": "tsc --noEmit",
60
+ "build:fast": "flowgram-build --fast",
61
+ "build:watch": "flowgram-build --watch"
62
+ }
63
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { PluginContext } from '@flowgram-vue/core';
7
+
8
+ export { default as PlaygroundVue } from './playground-vue.vue';
9
+ export { PlaygroundVueContent } from './playground-vue-content';
10
+ export type { PlaygroundVueContentProps } from '../layers/playground-content-layer';
11
+
12
+ export type PlaygroundRef = PluginContext;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { usePlayground } from '@flowgram-vue/core';
7
+ import { defineComponent, type CSSProperties, type PropType } from 'vue';
8
+
9
+ import { PlaygroundContentLayer } from '../layers/playground-content-layer';
10
+
11
+ export const PlaygroundVueContent = defineComponent({
12
+ name: 'PlaygroundVueContent',
13
+ props: {
14
+ className: String,
15
+ style: Object as PropType<CSSProperties>,
16
+ },
17
+ setup(props, { slots }) {
18
+ const playground = usePlayground();
19
+ return () => {
20
+ const layer = playground.getLayer(PlaygroundContentLayer);
21
+ layer?.updateOptions({
22
+ className: props.className,
23
+ style: props.style,
24
+ children: slots.default?.(),
25
+ });
26
+ return null;
27
+ };
28
+ },
29
+ });
@@ -0,0 +1,53 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import {
7
+ createPlaygroundPlugin,
8
+ PlaygroundVueProvider,
9
+ PlaygroundVueRenderer,
10
+ type PluginContext,
11
+ } from '@flowgram-vue/core';
12
+ import { ref } from 'vue';
13
+
14
+ import { PlaygroundContentLayer } from '../layers/playground-content-layer';
15
+ import { createPlaygroundVuePreset, type PlaygroundVueProps } from '../preset';
16
+
17
+ defineOptions({ name: 'PlaygroundVue' });
18
+
19
+ const props = defineProps<PlaygroundVueProps>();
20
+
21
+ const providerRef = ref<PluginContext | null>(null);
22
+
23
+ const contentLoadPlugin = createPlaygroundPlugin({
24
+ onInit(ctx) {
25
+ ctx.playground.registerLayer(PlaygroundContentLayer);
26
+ },
27
+ });
28
+
29
+ const preset = createPlaygroundVuePreset(props, [contentLoadPlugin]);
30
+
31
+ defineExpose({
32
+ get playground() {
33
+ return providerRef.value?.playground as PluginContext['playground'];
34
+ },
35
+ get container() {
36
+ return providerRef.value?.container as PluginContext['container'];
37
+ },
38
+ get: ((identifier) => providerRef.value?.get(identifier)) as PluginContext['get'],
39
+ getAll: ((identifier) => providerRef.value?.getAll(identifier) ?? []) as PluginContext['getAll'],
40
+ });
41
+ </script>
42
+
43
+ <template>
44
+ <PlaygroundVueProvider
45
+ ref="providerRef"
46
+ :plugins="preset"
47
+ :parent-container="props.parentContainer"
48
+ >
49
+ <PlaygroundVueRenderer>
50
+ <slot />
51
+ </PlaygroundVueRenderer>
52
+ </PlaygroundVueProvider>
53
+ </template>
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { usePlaygroundTools } from './use-playground-tools';
7
+ export type { PlaygroundTools, PlaygroundToolsPropsType } from './use-playground-tools';
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ EditorState,
8
+ EditorStateConfigEntity,
9
+ type PlaygroundInteractiveType,
10
+ useConfigEntity,
11
+ usePlayground,
12
+ } from '@flowgram-vue/core';
13
+ import { DisposableCollection } from '@flowgram-vue/utils';
14
+ import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';
15
+
16
+ export interface PlaygroundToolsPropsType {
17
+ /**
18
+ * 最大缩放比,默认 2
19
+ */
20
+ maxZoom?: number;
21
+ /**
22
+ * 最小缩放比,默认 0.25
23
+ */
24
+ minZoom?: number;
25
+ }
26
+
27
+ export interface PlaygroundTools {
28
+ /**
29
+ * 缩放 zoom 大小比例
30
+ */
31
+ zoom: number;
32
+ /**
33
+ * 放大
34
+ */
35
+ zoomin: (easing?: boolean) => void;
36
+ /**
37
+ * 缩小
38
+ */
39
+ zoomout: (easing?: boolean) => void;
40
+ /**
41
+ * 设置缩放比例
42
+ */
43
+ updateZoom: (newZoom: number, easing?: boolean, easingDuration?: number) => void;
44
+ /**
45
+ * 当前的交互模式, 鼠标友好模式 和 触摸板模式
46
+ */
47
+ interactiveType: PlaygroundInteractiveType;
48
+ /**
49
+ * 切换交互模式
50
+ */
51
+ toggleIneractiveType: () => void;
52
+ }
53
+
54
+ export function usePlaygroundTools(props?: PlaygroundToolsPropsType): PlaygroundTools {
55
+ const { maxZoom, minZoom } = props || {};
56
+ const playground = usePlayground();
57
+ const editorState = useConfigEntity(EditorStateConfigEntity, true);
58
+
59
+ const zoom = ref(1);
60
+
61
+ const handleZoomOut = (easing?: boolean) => {
62
+ playground.config.zoomout(easing);
63
+ };
64
+
65
+ const handleZoomIn = (easing?: boolean) => {
66
+ playground.config.zoomin(easing);
67
+ };
68
+
69
+ const handleUpdateZoom = (value: number, easing?: boolean, easingDuration?: number) => {
70
+ playground.config.updateZoom(value, easing, easingDuration);
71
+ };
72
+
73
+ const handleToggleIneractiveType = () => {
74
+ if (editorState.isMouseFriendlyMode()) {
75
+ editorState.changeState(EditorState.STATE_SELECT.id);
76
+ } else {
77
+ editorState.changeState(EditorState.STATE_MOUSE_FRIENDLY_SELECT.id);
78
+ }
79
+ };
80
+
81
+ const dispose = new DisposableCollection();
82
+ dispose.push(playground.onZoom((z) => (zoom.value = z)));
83
+ onBeforeUnmount(() => dispose.dispose());
84
+
85
+ watch(
86
+ () => [maxZoom, minZoom],
87
+ () => {
88
+ const config = playground.config.config;
89
+ playground.config.updateConfig({
90
+ maxZoom: maxZoom !== undefined ? maxZoom : config.maxZoom,
91
+ minZoom: minZoom !== undefined ? minZoom : config.minZoom,
92
+ });
93
+ },
94
+ { immediate: true }
95
+ );
96
+
97
+ const interactiveType = computed<PlaygroundInteractiveType>(() =>
98
+ editorState.isMouseFriendlyMode() ? 'MOUSE' : 'PAD'
99
+ );
100
+
101
+ return reactive({
102
+ zoomin: handleZoomIn,
103
+ zoomout: handleZoomOut,
104
+ updateZoom: handleUpdateZoom,
105
+ zoom,
106
+ interactiveType,
107
+ toggleIneractiveType: handleToggleIneractiveType,
108
+ }) as PlaygroundTools;
109
+ }
package/src/env.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ declare module '*.vue' {
7
+ import type { DefineComponent } from 'vue';
8
+ const component: DefineComponent<object, object, unknown>;
9
+ export default component;
10
+ }
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import 'reflect-metadata';
7
+
8
+ /* 核心 模块导出 */
9
+ export { useRefresh, Emitter, Event, Disposable } from '@flowgram-vue/utils';
10
+ export * from '@flowgram-vue/core';
11
+
12
+ export { usePlaygroundTools } from './composables';
13
+ export type { PlaygroundTools, PlaygroundToolsPropsType } from './composables';
14
+ export {
15
+ PlaygroundVue,
16
+ PlaygroundVueContent,
17
+ type PlaygroundVueContentProps,
18
+ type PlaygroundRef,
19
+ } from './components';
20
+ export {
21
+ createPlaygroundVuePreset,
22
+ type PlaygroundVueProps,
23
+ type BackgroundLayerOptions,
24
+ type ShortcutsRegistry,
25
+ } from './preset';
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { Layer } from '@flowgram-vue/core';
7
+ import { domUtils } from '@flowgram-vue/utils';
8
+ import { injectable } from 'inversify';
9
+ import { h, type CSSProperties, type VNode } from 'vue';
10
+
11
+ export interface PlaygroundVueContentProps {
12
+ className?: string;
13
+ style?: CSSProperties;
14
+ children?: VNode | VNode[];
15
+ }
16
+
17
+ @injectable()
18
+ export class PlaygroundContentLayer extends Layer<PlaygroundVueContentProps> {
19
+ static type = 'PlaygroundContentLayer';
20
+
21
+ readonly node = domUtils.createDivWithClass(
22
+ 'gedit-playground-layer gedit-playground-content-layer'
23
+ );
24
+
25
+ onZoom(scale: number): void {
26
+ this.node.style.transform = `scale(${scale})`;
27
+ }
28
+
29
+ onReady() {
30
+ this.node.style.left = '0px';
31
+ this.node.style.top = '0px';
32
+ }
33
+
34
+ updateOptions(opts: PlaygroundVueContentProps) {
35
+ this.options = opts;
36
+ this.render();
37
+ }
38
+
39
+ render() {
40
+ return h(
41
+ 'div',
42
+ {
43
+ class: this.options.className,
44
+ style: { position: 'absolute', ...this.options.style },
45
+ },
46
+ this.options.children
47
+ );
48
+ }
49
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { createPlaygroundVuePreset } from './playground-vue-preset';
7
+ export type {
8
+ BackgroundLayerOptions,
9
+ PlaygroundVueProps,
10
+ ShortcutsRegistry,
11
+ } from './playground-vue-props';
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import * as backgroundPlugin from '@flowgram-vue/background-plugin';
7
+ import {
8
+ createPlaygroundPlugin,
9
+ PlaygroundConfig,
10
+ PlaygroundLayer,
11
+ type Plugin,
12
+ type PluginContext,
13
+ type PluginsProvider,
14
+ } from '@flowgram-vue/core';
15
+ import * as shortcutsPlugin from '@flowgram-vue/shortcuts-plugin';
16
+
17
+ import type {
18
+ BackgroundLayerOptions,
19
+ PlaygroundVueProps,
20
+ ShortcutsRegistry,
21
+ } from './playground-vue-props';
22
+
23
+ type BackgroundPluginExports = {
24
+ createBackgroundPlugin?: (options: BackgroundLayerOptions) => Plugin;
25
+ };
26
+
27
+ type ShortcutsPluginExports = {
28
+ createShortcutsPlugin?: (options: {
29
+ registerShortcuts: (registry: ShortcutsRegistry) => void;
30
+ }) => Plugin;
31
+ };
32
+
33
+ export function createPlaygroundVuePreset<CTX extends PluginContext = PluginContext>(
34
+ opts: PlaygroundVueProps<CTX>,
35
+ plugins: Plugin[] = []
36
+ ): PluginsProvider<CTX> {
37
+ return (ctx: CTX) => {
38
+ plugins = plugins.slice();
39
+ const { createBackgroundPlugin } = backgroundPlugin as BackgroundPluginExports;
40
+ const { createShortcutsPlugin } = shortcutsPlugin as ShortcutsPluginExports;
41
+ /**
42
+ * 注册背景 (放前面插入), 默认打开
43
+ */
44
+ if (opts.background || opts.background === undefined) {
45
+ const backgroundOptions = typeof opts.background === 'object' ? opts.background : {};
46
+ if (typeof createBackgroundPlugin === 'function') {
47
+ plugins.push(createBackgroundPlugin(backgroundOptions));
48
+ }
49
+ }
50
+ /**
51
+ * 注册快捷键
52
+ */
53
+ if (opts.shortcuts && typeof createShortcutsPlugin === 'function') {
54
+ plugins.push(
55
+ createShortcutsPlugin({
56
+ registerShortcuts: (registry) => opts.shortcuts!(registry, ctx),
57
+ })
58
+ );
59
+ }
60
+ /**
61
+ * 注册三方插件
62
+ */
63
+ if (opts.plugins) {
64
+ plugins.push(...opts.plugins(ctx));
65
+ }
66
+ /**
67
+ * 画布生命周期注册
68
+ */
69
+ plugins.push(
70
+ createPlaygroundPlugin<CTX>({
71
+ onBind: (bindConfig) => {
72
+ opts.onBind?.(bindConfig);
73
+ },
74
+ onInit: (ctx) => {
75
+ const playgroundConfig = ctx.get<PlaygroundConfig>(PlaygroundConfig);
76
+ if (opts.playground) {
77
+ if (opts.playground.autoFocus !== undefined) {
78
+ playgroundConfig.autoFocus = opts.playground.autoFocus;
79
+ }
80
+ if (opts.playground.autoResize !== undefined) {
81
+ playgroundConfig.autoResize = opts.playground.autoResize;
82
+ }
83
+ }
84
+ playgroundConfig.autoFocus = false;
85
+ ctx.playground.registerLayer(PlaygroundLayer, opts.playground);
86
+ if (opts.layers) {
87
+ ctx.playground.registerLayers(...opts.layers);
88
+ }
89
+ if (opts.onInit) opts.onInit(ctx);
90
+ },
91
+ onReady(ctx) {
92
+ if (opts.onReady) opts.onReady(ctx);
93
+ },
94
+ onAllLayersRendered() {
95
+ if (opts.onAllLayersRendered) opts.onAllLayersRendered(ctx);
96
+ },
97
+ onDispose() {
98
+ if (opts.onDispose) opts.onDispose(ctx);
99
+ },
100
+ containerModules: opts.containerModules || [],
101
+ })
102
+ );
103
+ return plugins;
104
+ };
105
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type {
7
+ LayerRegistry,
8
+ PlaygroundLayerOptions,
9
+ Plugin,
10
+ PluginBindConfig,
11
+ PluginContext,
12
+ } from '@flowgram-vue/core';
13
+ import type { interfaces } from 'inversify';
14
+ import type { VNodeChild } from 'vue';
15
+
16
+ /**
17
+ * Background options aligned with `@flowgram-vue/background-plugin`.
18
+ * Inlined until Wave 4 ships the plugin (Wave 0 stub has no named exports).
19
+ */
20
+ export interface BackgroundLayerOptions {
21
+ gridSize?: number;
22
+ dotSize?: number;
23
+ dotColor?: string;
24
+ dotOpacity?: number;
25
+ backgroundColor?: string;
26
+ dotFillColor?: string;
27
+ logo?: {
28
+ text?: string;
29
+ imageUrl?: string;
30
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
31
+ size?: 'small' | 'medium' | 'large' | number;
32
+ opacity?: number;
33
+ color?: string;
34
+ fontSize?: number;
35
+ fontFamily?: string;
36
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number;
37
+ offset?: { x: number; y: number };
38
+ neumorphism?: {
39
+ enabled?: boolean;
40
+ textColor?: string;
41
+ lightShadowColor?: string;
42
+ darkShadowColor?: string;
43
+ shadowOffset?: number;
44
+ shadowBlur?: number;
45
+ intensity?: number;
46
+ raised?: boolean;
47
+ };
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Shortcuts registry aligned with `@flowgram-vue/shortcuts-plugin`.
53
+ * Inlined until Wave 4 ships the plugin (Wave 0 stub has no named exports).
54
+ */
55
+ export interface ShortcutsRegistry {
56
+ shortcutsHandlers: unknown[];
57
+ addHandlers(...handlers: unknown[]): void;
58
+ addHandlersIfNotFound(...handlers: unknown[]): void;
59
+ removeHandler(commandId: string): void;
60
+ has(commandId: string): boolean;
61
+ }
62
+
63
+ /**
64
+ * 画布配置
65
+ */
66
+ export interface PlaygroundVueProps<CTX extends PluginContext = PluginContext> {
67
+ /**
68
+ * 背景开关,默认打开
69
+ */
70
+ background?: BackgroundLayerOptions | boolean;
71
+ /**
72
+ * 画布相关配置
73
+ */
74
+ playground?: PlaygroundLayerOptions & {
75
+ autoFocus?: boolean;
76
+ autoResize?: boolean;
77
+ };
78
+ /**
79
+ * 注册快捷键
80
+ */
81
+ shortcuts?: (shortcutsRegistry: ShortcutsRegistry, ctx: CTX) => void;
82
+ /**
83
+ * 插件 IOC 注册,等价于 containerModule
84
+ */
85
+ onBind?: (bindConfig: PluginBindConfig) => void;
86
+ /**
87
+ * 画布模块注册阶段
88
+ */
89
+ onInit?: (ctx: CTX) => void;
90
+ /**
91
+ * 画布事件注册阶段 (一般用于注册 dom 事件)
92
+ */
93
+ onReady?: (ctx: CTX) => void;
94
+ /**
95
+ * 画布所有 layer 第一次渲染完成后触发
96
+ */
97
+ onAllLayersRendered?: (ctx: CTX) => void;
98
+ /**
99
+ * 画布销毁阶段
100
+ */
101
+ onDispose?: (ctx: CTX) => void;
102
+ /**
103
+ * 插件扩展
104
+ */
105
+ plugins?: (ctx: CTX) => Plugin[];
106
+ /**
107
+ * 注册 layer
108
+ */
109
+ layers?: LayerRegistry[];
110
+ /**
111
+ * IOC 模块,用于更底层的插件扩展
112
+ */
113
+ containerModules?: interfaces.ContainerModule[];
114
+ /**
115
+ * 内容 slot(React 版的 children)。组件上请用默认插槽。
116
+ */
117
+ children?: VNodeChild;
118
+ /**
119
+ * 父 IOC 容器
120
+ */
121
+ parentContainer?: interfaces.Container;
122
+ }