@flowgram-vue/group-plugin 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/layer-vue-provide.ts","../src/constant.ts","../src/components/group-render.vue","../src/composables/use-hover.ts","../src/components/group-box.vue","../src/groups-layer.ts","../src/registers/register-render.ts","../src/registers/register-layer.ts","../src/group-node-register.ts","../src/registers/register-group-node.ts","../src/registers/register-clean-groups.ts","../src/registers/index.ts","../src/create-group-plugin.ts"],"names":["defineComponent","provide","PlaygroundVueContainerKey","PlaygroundVueRefKey","Playground","h","GroupRenderer","GroupPluginRegister","useEntityFromContext","FlowNodeRenderData","document","useService","FlowDocument","computed","FlowGroupController","ref","delay","onMounted","onBeforeUnmount","watch","_openBlock","_createBlock","_resolveDynamicComponent","_createCommentVNode","_createElementBlock","_createElementVNode","_normalizeStyle","GroupsLayer","Layer","domUtils","Fragment","inject","FlowRendererRegistry","FlowGroupService","PlaygroundContainerFactory","observeEntity","FlowDocumentTransformerEntity","observeEntityDatas","FlowNodeEntity","FlowNodeTransformData","injectable","renderer","FlowNodeBaseType","FlowTransitionLineEnum","Point","FlowTransitionLabelEnum","definePluginCreator"],"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 { defineComponent, h, provide, type VNodeChild } from 'vue';\nimport type { interfaces } from 'inversify';\nimport {\n Playground,\n PlaygroundVueContainerKey,\n PlaygroundVueRefKey,\n type PlaygroundContainerFactory,\n} from '@flowgram-vue/core';\n\n/**\n * 给 Layer 独立 createApp 注入 playground 容器,使子组件里的 useService / usePlayground 可用。\n */\nexport const LayerVueProvide = defineComponent({\n name: 'LayerVueProvide',\n props: {\n factory: {\n type: Object,\n required: true,\n },\n },\n setup(props) {\n const factory = props.factory as PlaygroundContainerFactory;\n provide(PlaygroundVueContainerKey, factory as unknown as interfaces.Container);\n try {\n provide(PlaygroundVueRefKey, factory.get(Playground));\n } catch {\n // 测试容器可能重复 bind PlaygroundConfig,此时仅 provide container\n }\n },\n render() {\n return this.$slots.default?.();\n },\n});\n\nexport function wrapLayerRender(factory: PlaygroundContainerFactory, children: VNodeChild) {\n return h(LayerVueProvide, { factory }, () => children);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport enum GroupRenderer {\n GroupRender = 'group_render',\n GroupBox = 'group_box',\n}\n\nexport const PositionConfig = {\n paddingWithNote: 50, // note 留白大小\n padding: 10, // 无 label 的 padding\n paddingWithAddLabel: 20, // 有 label 的padding,如要放添加按钮\n headerHeight: 20, // 基础头部高度\n};\n\nexport enum GroupPluginRegister {\n GroupNode = 'registerGroupNode',\n Render = 'registerRender',\n Layer = 'registerLayer',\n CleanGroups = 'registerCleanGroups',\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';\n\nimport { delay, type Disposable, type Rectangle } from '@flowgram-vue/utils';\nimport {\n FlowDocument,\n FlowGroupController,\n FlowNodeEntity,\n FlowNodeRenderData,\n} from '@flowgram-vue/document';\nimport { useEntityFromContext, useService } from '@flowgram-vue/core';\n\nimport type { IGroupBoxHeader, IGroupNode } from '../type';\n\nconst props = defineProps<{\n groupNode: FlowNodeEntity;\n GroupNode: IGroupNode;\n GroupBoxHeader: IGroupBoxHeader;\n}>();\n\nfunction useCurrentDomNode(): HTMLDivElement {\n const entity = useEntityFromContext<FlowNodeEntity>();\n const renderData = entity.getData<FlowNodeRenderData>(FlowNodeRenderData);\n return renderData.node;\n}\n\nconst container = useCurrentDomNode();\nconst document = useService<FlowDocument>(FlowDocument);\nconst groupController = computed(() => FlowGroupController.create(props.groupNode));\n\nconst renderKey = ref(0);\nconst rendering = ref(true);\nconst collapsedCache = ref(groupController.value?.collapsed ?? false);\nlet disposer: Disposable | undefined;\n\nasync function rerender() {\n rendering.value = true;\n renderKey.value += 1;\n await delay(50);\n renderKey.value += 1;\n rendering.value = false;\n}\n\nonMounted(() => {\n disposer = document.renderTree.onTreeChange(() => {\n if (groupController.value?.collapsed !== collapsedCache.value) {\n collapsedCache.value = groupController.value?.collapsed ?? false;\n void rerender();\n }\n });\n\n if (groupController.value && !groupController.value.collapsed) {\n void rerender();\n }\n});\n\nonBeforeUnmount(() => {\n disposer?.dispose();\n});\n\nwatch(\n [() => groupController.value?.collapsed, rendering],\n () => {\n const controller = groupController.value;\n if (!controller) {\n return;\n }\n if (controller.collapsed) {\n Object.assign(container.style, {\n display: 'block',\n zIndex: '0',\n width: 'auto',\n height: 'auto',\n });\n return;\n }\n if (!rendering.value) {\n const bounds: Rectangle = controller.bounds;\n Object.assign(container.style, {\n width: `${bounds.width}px`,\n });\n }\n },\n { immediate: true }\n);\n</script>\n\n<template>\n <component\n :is=\"GroupNode\"\n v-if=\"groupController && groupController.collapsed\"\n :key=\"renderKey\"\n :group-node=\"groupNode\"\n :group-controller=\"groupController\"\n />\n <component\n :is=\"GroupBoxHeader\"\n v-else-if=\"groupController && !rendering\"\n :key=\"renderKey\"\n :group-controller=\"groupController\"\n :group-node=\"groupNode\"\n />\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { onBeforeUnmount, onMounted, ref } from 'vue';\n\nexport function useHover() {\n const elRef = ref<HTMLDivElement | null>(null);\n const hover = ref(false);\n\n const checkMouseOver = (event: MouseEvent) => {\n if (!elRef.value) {\n return;\n }\n const { left, top, right, bottom } = elRef.value.getBoundingClientRect();\n const isOver =\n event.clientX >= left &&\n event.clientX <= right &&\n event.clientY >= top &&\n event.clientY <= bottom;\n\n hover.value = isOver;\n };\n\n onMounted(() => {\n window.addEventListener('mousemove', checkMouseOver);\n });\n\n onBeforeUnmount(() => {\n window.removeEventListener('mousemove', checkMouseOver);\n });\n\n return {\n hover,\n elRef,\n };\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { computed, watch, type CSSProperties } from 'vue';\n\nimport type { Rectangle } from '@flowgram-vue/utils';\nimport { FlowGroupController, type FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { useHover } from '../composables/use-hover';\n\nconst props = defineProps<{\n groupNode: FlowNodeEntity;\n backgroundStyle?: (groupController: FlowGroupController) => CSSProperties;\n}>();\n\nconst groupController = computed(() => FlowGroupController.create(props.groupNode));\nconst { hover, elRef } = useHover();\n\nconst positionStyle = computed<CSSProperties>(() => {\n const bounds: Rectangle | undefined = groupController.value?.bounds;\n if (!bounds) {\n return {};\n }\n return {\n position: 'absolute',\n left: bounds.left,\n top: bounds.top,\n width: bounds.width,\n height: bounds.height,\n };\n});\n\nconst defaultBackgroundStyle = computed<CSSProperties>(() => ({\n borderRadius: 10,\n zIndex: -1,\n outline: `${hover.value ? 2 : 1}px solid rgb(97, 69, 211)`,\n backgroundColor: 'rgb(236 233 247)',\n}));\n\nconst backgroundStyle = computed(() =>\n props.backgroundStyle && groupController.value\n ? props.backgroundStyle(groupController.value)\n : defaultBackgroundStyle.value\n);\n\nwatch(hover, (value) => {\n if (groupController.value) {\n groupController.value.hovered = value;\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"groupController && !groupController.collapsed\"\n class=\"gedit-group-box\"\n :data-group-id=\"groupNode.id\"\n >\n <div\n ref=\"elRef\"\n class=\"gedit-group-background\"\n :style=\"{ ...positionStyle, ...backgroundStyle }\"\n />\n </div>\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Fragment, h, type Component } from 'vue';\nimport { inject, injectable } from 'inversify';\nimport { FlowRendererRegistry } from '@flowgram-vue/renderer';\nimport {\n FlowDocument,\n FlowDocumentTransformerEntity,\n FlowGroupController,\n FlowGroupService,\n FlowNodeEntity,\n FlowNodeRenderData,\n FlowNodeTransformData,\n} from '@flowgram-vue/document';\nimport { Layer, observeEntity, observeEntityDatas, PlaygroundContainerFactory } from '@flowgram-vue/core';\nimport { domUtils } from '@flowgram-vue/utils';\n\nimport { wrapLayerRender } from './layer-vue-provide';\nimport { GroupsLayerOptions, IGroupBox } from './type';\nimport { GroupRenderer } from './constant';\nimport { GroupBox } from './components';\n\n@injectable()\nexport class GroupsLayer extends Layer<GroupsLayerOptions> {\n public readonly node: HTMLElement;\n\n @inject(FlowDocument) protected document: FlowDocument;\n\n @inject(FlowRendererRegistry)\n protected readonly rendererRegistry: FlowRendererRegistry;\n\n @inject(FlowGroupService)\n protected readonly groupService: FlowGroupService;\n\n @inject(PlaygroundContainerFactory)\n protected readonly playgroundContainer: PlaygroundContainerFactory;\n\n @observeEntity(FlowDocumentTransformerEntity)\n readonly documentTransformer: FlowDocumentTransformerEntity;\n\n @observeEntityDatas(FlowNodeEntity, FlowNodeRenderData) _renderStates: FlowNodeRenderData[];\n\n @observeEntityDatas(FlowNodeEntity, FlowNodeTransformData) _transforms: FlowNodeTransformData[];\n\n private readonly className = 'gedit-groups-layer';\n\n constructor() {\n super();\n this.node = domUtils.createDivWithClass(this.className);\n this.node.style.zIndex = '0';\n }\n\n /** 缩放 */\n public onZoom(scale: number): void {\n this.node!.style.transform = `scale(${scale})`;\n }\n\n public render() {\n if (this.documentTransformer.loading) return null;\n this.documentTransformer.refresh();\n\n return wrapLayerRender(this.playgroundContainer, this.renderGroups());\n }\n\n /** 渲染分组 */\n protected renderGroups() {\n const Box = (this.renderer || GroupBox) as Component;\n return h(\n Fragment,\n null,\n this.groups.map((group) =>\n h(Box, {\n key: group.groupNode.id,\n groupNode: group.groupNode,\n backgroundStyle: this.options.groupBoxStyle,\n })\n )\n );\n }\n\n /** 所有分组 */\n protected get groups(): FlowGroupController[] {\n return this.groupService.getAllGroups();\n }\n\n protected get renderer(): IGroupBox | undefined {\n return this.rendererRegistry.tryToGetRendererComponent(GroupRenderer.GroupBox)\n ?.renderer as IGroupBox | undefined;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { defineComponent, h } from 'vue';\n\nimport { FlowRendererRegistry } from '@flowgram-vue/renderer';\nimport { FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupRenderer } from '../constant';\nimport { GroupRender } from '../components';\n\n/** 注册渲染组件 */\nexport const registerRender: IGroupPluginRegister = (ctx, opts) => {\n const rendererRegistry = ctx.get<FlowRendererRegistry>(FlowRendererRegistry);\n const renderer = defineComponent({\n name: 'GroupNodeRenderer',\n props: {\n node: {\n type: Object as () => FlowNodeEntity,\n required: true,\n },\n },\n setup(props) {\n return () =>\n h(GroupRender, {\n groupNode: props.node,\n GroupNode: opts.components!.GroupNode,\n GroupBoxHeader: opts.components!.GroupBoxHeader,\n });\n },\n });\n rendererRegistry.registerVueComponent(GroupRenderer.GroupRender, renderer);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupsLayer } from '../groups-layer';\n\n/** 注册背景层 */\nexport const registerLayer: IGroupPluginRegister = (ctx, opts) => {\n ctx.playground.registerLayer(GroupsLayer, opts);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { h } from 'vue';\n\nimport { IPoint, PaddingSchema, Point } from '@flowgram-vue/utils';\nimport {\n FlowGroupController,\n FlowNodeBaseType,\n FlowNodeRegistry,\n FlowNodeTransformData,\n FlowTransitionLabelEnum,\n type FlowTransitionLine,\n FlowTransitionLineEnum,\n} from '@flowgram-vue/document';\n\nimport { GroupRenderer, PositionConfig } from './constant';\n\nexport const GroupRegister: FlowNodeRegistry = {\n type: FlowNodeBaseType.GROUP,\n meta: {\n exportJSON: true,\n renderKey: GroupRenderer.GroupRender,\n positionConfig: PositionConfig,\n padding: (transform: FlowNodeTransformData): PaddingSchema => {\n const groupController = FlowGroupController.create(transform.entity);\n if (!groupController || groupController.collapsed || groupController.nodes.length === 0) {\n return {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n };\n }\n if (transform.entity.isVertical) {\n return {\n top: PositionConfig.paddingWithNote,\n bottom: PositionConfig.paddingWithAddLabel,\n left: PositionConfig.padding,\n right: PositionConfig.padding,\n };\n }\n return {\n top: PositionConfig.paddingWithNote,\n bottom: PositionConfig.padding,\n left: PositionConfig.padding,\n right: PositionConfig.paddingWithAddLabel,\n };\n },\n },\n formMeta: {\n render: () => h('div'),\n },\n getLines(transition) {\n const { transform } = transition;\n const lines: FlowTransitionLine[] = [];\n if (transform.firstChild) {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.inputPoint,\n to: transform.firstChild.inputPoint,\n });\n }\n if (transform.next) {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.outputPoint,\n to: transform.next.inputPoint,\n });\n } else {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.outputPoint,\n to: transform.parent!.outputPoint,\n });\n }\n return lines;\n },\n getDelta(transform: FlowNodeTransformData): IPoint | undefined {\n const groupController = FlowGroupController.create(transform.entity);\n if (!groupController || groupController.collapsed) {\n return;\n }\n if (transform.entity.isVertical) {\n return {\n x: 0,\n y: PositionConfig.paddingWithNote,\n };\n }\n return {\n x: PositionConfig.padding,\n y: 0,\n };\n },\n getInputPoint(transform: FlowNodeTransformData): IPoint {\n const child = transform.firstChild;\n if (!child) return transform.defaultInputPoint;\n if (transform.entity.isVertical) {\n return {\n x: child.inputPoint.x,\n y: transform.bounds.topCenter.y,\n };\n }\n return {\n x: transform.bounds.leftCenter.x,\n y: child.inputPoint.y,\n };\n },\n getOutputPoint(transform: FlowNodeTransformData): IPoint {\n const child = transform.lastChild;\n if (!child) return transform.defaultOutputPoint;\n if (transform.entity.isVertical) {\n return {\n x: child.outputPoint.x,\n y: child.outputPoint.y + PositionConfig.paddingWithAddLabel / 2,\n };\n }\n return {\n x: child.outputPoint.x + PositionConfig.paddingWithAddLabel / 2,\n y: child.outputPoint.y,\n };\n },\n getLabels(transition) {\n const { transform } = transition;\n if (transform.next) {\n if (transform.entity.isVertical) {\n return [\n {\n offset: Point.getMiddlePoint(\n Point.move(transform.outputPoint, {\n x: 0,\n y: PositionConfig.paddingWithAddLabel / 2,\n }),\n transform.next.inputPoint\n ),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n }\n return [\n {\n offset: Point.getMiddlePoint(\n Point.move(transform.outputPoint, { x: PositionConfig.paddingWithAddLabel / 2, y: 0 }),\n transform.next.inputPoint\n ),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n }\n return [\n {\n offset: transform.parent!.outputPoint,\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n },\n getOriginDeltaY(transform): number {\n const { children } = transform;\n if (children.length === 0) {\n return -transform.size.height * transform.origin.y;\n }\n // 这里要加上 y 轴的偏移\n return -transform.size.height * transform.origin.y - PositionConfig.paddingWithNote;\n },\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupRegister } from '../group-node-register';\n\n/** 注册分组节点 */\nexport const registerGroupNode: IGroupPluginRegister = ctx => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n document.registerFlowNodes(GroupRegister);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { FlowGroupService } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\n\n/** 注册清理分组逻辑 */\nexport const registerCleanGroups: IGroupPluginRegister = (ctx, _opts) => {\n const groupService = ctx.get<FlowGroupService>(FlowGroupService);\n const document = ctx.get<FlowDocument>(FlowDocument);\n\n const clearInvalidGroups = () => {\n groupService.getAllGroups().forEach(group => {\n if (group?.nodes.length !== 0) {\n return;\n }\n if (!group.groupNode.pre) {\n return;\n }\n groupService.deleteGroup(group.groupNode);\n });\n };\n\n document.originTree.onTreeChange(() => {\n setTimeout(() => {\n clearInvalidGroups();\n }, 0);\n });\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupPluginRegister } from '../constant';\nimport { registerRender } from './register-render';\nimport { registerLayer } from './register-layer';\nimport { registerGroupNode } from './register-group-node';\nimport { registerCleanGroups } from './register-clean-groups';\n\nexport const groupRegisters: Record<GroupPluginRegister, IGroupPluginRegister> = {\n [GroupPluginRegister.GroupNode]: registerGroupNode,\n [GroupPluginRegister.Render]: registerRender,\n [GroupPluginRegister.Layer]: registerLayer,\n [GroupPluginRegister.CleanGroups]: registerCleanGroups,\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator, PluginContext } from '@flowgram-vue/core';\n\nimport { CreateGroupPluginOptions } from './type';\nimport { groupRegisters } from './registers';\nimport { GroupPluginRegister } from './constant';\n\n/**\n * 分组插件\n */\nexport const createGroupPlugin = definePluginCreator<CreateGroupPluginOptions>({\n onInit: (ctx: PluginContext, opts: CreateGroupPluginOptions) => {\n const { registers: registerConfs = {} } = opts;\n Object.entries(groupRegisters).forEach(([key, register]) => {\n const registerName = key as GroupPluginRegister;\n const registerConf = registerConfs[registerName];\n if (registerConf === false) {\n return;\n }\n if (typeof registerConf === 'function') {\n registerConf(ctx, opts);\n return;\n }\n register(ctx, opts);\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/layer-vue-provide.ts","../src/constant.ts","../src/components/group-render.vue","../src/composables/use-hover.ts","../src/components/group-box.vue","../src/groups-layer.ts","../src/registers/register-render.ts","../src/registers/register-layer.ts","../src/group-node-register.ts","../src/registers/register-group-node.ts","../src/registers/register-clean-groups.ts","../src/registers/index.ts","../src/create-group-plugin.ts"],"names":["GroupRenderer","GroupPluginRegister","_openBlock","_createBlock","_resolveDynamicComponent","_createCommentVNode","ref","onMounted","onBeforeUnmount","computed","FlowGroupController","watch","_createElementBlock","_createElementVNode","_normalizeStyle","h","FlowDocument","FlowNodeRenderData","FlowRendererRegistry","defineComponent","FlowGroupService"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBO,IAAM,kBAAkB,eAAA,CAAgB;AAAA,EAC7C,IAAA,EAAM,iBAAA;AAAA,EACN,KAAA,EAAO;AAAA,IACL,OAAA,EAAS;AAAA,MACP,IAAA,EAAM,MAAA;AAAA,MACN,QAAA,EAAU;AAAA;AACZ,GACF;AAAA,EACA,MAAM,KAAA,EAAO;AACX,IAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,IAAA,OAAA,CAAQ,2BAA2B,OAA0C,CAAA;AAC7E,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,mBAAA,EAAqB,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAC,CAAA;AAAA,IACtD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AAAA,EACA,MAAA,GAAS;AACP,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,IAAU;AAAA,EAC/B;AACF,CAAC,CAAA;AAEM,SAAS,eAAA,CAAgB,SAAqC,QAAA,EAAsB;AACzF,EAAA,OAAO,EAAE,eAAA,EAAiB,EAAE,OAAA,EAAQ,EAAG,MAAM,QAAQ,CAAA;AACvD;;;ACpCO,IAAK,aAAA,qBAAAA,cAAAA,KAAL;AACL,EAAAA,eAAA,aAAA,CAAA,GAAc,cAAA;AACd,EAAAA,eAAA,UAAA,CAAA,GAAW,WAAA;AAFD,EAAA,OAAAA,cAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;AAKL,IAAM,cAAA,GAAiB;AAAA,EAC5B,eAAA,EAAiB,EAAA;AAAA;AAAA,EACjB,OAAA,EAAS,EAAA;AAAA;AAAA,EACT,mBAAA,EAAqB,EAAA;AAAA;AAAA,EACrB,YAAA,EAAc;AAAA;AAChB;AAEO,IAAK,mBAAA,qBAAAC,oBAAAA,KAAL;AACL,EAAAA,qBAAA,WAAA,CAAA,GAAY,mBAAA;AACZ,EAAAA,qBAAA,QAAA,CAAA,GAAS,gBAAA;AACT,EAAAA,qBAAA,OAAA,CAAA,GAAQ,eAAA;AACR,EAAAA,qBAAA,aAAA,CAAA,GAAc,qBAAA;AAJJ,EAAA,OAAAA,oBAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;;;;;;;;;;ACEZ,IAAA,MAAM,KAAA,GAAQ,OAAA;AAMd,IAAA,SAAS,iBAAA,GAAoC;AAC3C,MAAA,MAAM,SAAS,oBAAA,EAAqC;AACpD,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,CAA4B,kBAAkB,CAAA;AACxE,MAAA,OAAO,UAAA,CAAW,IAAA;AACpB,IAAA;AAEA,IAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,IAAA,MAAM,QAAA,GAAW,WAAyB,YAAY,CAAA;AACtD,IAAA,MAAM,kBAAkB,QAAA,CAAS,MAAM,oBAAoB,MAAA,CAAO,KAAA,CAAM,SAAS,CAAC,CAAA;AAElF,IAAA,MAAM,SAAA,GAAY,IAAI,CAAC,CAAA;AACvB,IAAA,MAAM,SAAA,GAAY,IAAI,IAAI,CAAA;AAC1B,IAAA,MAAM,cAAA,GAAiB,GAAA,CAAI,eAAA,CAAgB,KAAA,EAAO,aAAa,KAAK,CAAA;AACpE,IAAA,IAAI,QAAA;AAEJ,IAAA,eAAe,QAAA,GAAW;AACxB,MAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAClB,MAAA,SAAA,CAAU,KAAA,IAAS,CAAA;AACnB,MAAA,MAAM,MAAM,EAAE,CAAA;AACd,MAAA,SAAA,CAAU,KAAA,IAAS,CAAA;AACnB,MAAA,SAAA,CAAU,KAAA,GAAQ,KAAA;AACpB,IAAA;AAEA,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,QAAA,GAAW,QAAA,CAAS,UAAA,CAAW,YAAA,CAAa,MAAM;AAChD,QAAA,IAAI,eAAA,CAAgB,KAAA,EAAO,SAAA,KAAc,cAAA,CAAe,KAAA,EAAO;AAC7D,UAAA,cAAA,CAAe,KAAA,GAAQ,eAAA,CAAgB,KAAA,EAAO,SAAA,IAAa,KAAA;AAC3D,UAAA,KAAK,QAAA,EAAS;AAChB,QAAA;MACF,CAAC,CAAA;AAED,MAAA,IAAI,eAAA,CAAgB,KAAA,IAAS,CAAC,eAAA,CAAgB,MAAM,SAAA,EAAW;AAC7D,QAAA,KAAK,QAAA,EAAS;AAChB,MAAA;IACF,CAAC,CAAA;AAED,IAAA,eAAA,CAAgB,MAAM;AACpB,MAAA,QAAA,EAAU,OAAA,EAAQ;IACpB,CAAC,CAAA;AAED,IAAA,KAAA;AACE,MAAA,CAAC,MAAM,eAAA,CAAgB,KAAA,EAAO,SAAA,EAAW,SAAS,CAAA;MAClD,MAAM;AACJ,QAAA,MAAM,aAAa,eAAA,CAAgB,KAAA;AACnC,QAAA,IAAI,CAAC,UAAA,EAAY;AACf,UAAA;AACF,QAAA;AACA,QAAA,IAAI,WAAW,SAAA,EAAW;AACxB,UAAA,MAAA,CAAO,MAAA,CAAO,UAAU,KAAA,EAAO;YAC7B,OAAA,EAAS,OAAA;YACT,MAAA,EAAQ,GAAA;YACR,KAAA,EAAO,MAAA;YACP,MAAA,EAAQ;WACT,CAAA;AACD,UAAA;AACF,QAAA;AACA,QAAA,IAAI,CAAC,UAAU,KAAA,EAAO;AACpB,UAAA,MAAM,SAAoB,UAAA,CAAW,MAAA;AACrC,UAAA,MAAA,CAAO,MAAA,CAAO,UAAU,KAAA,EAAO;YAC7B,KAAA,EAAO,CAAA,EAAG,OAAO,KAAK,CAAA,EAAA;WACvB,CAAA;AACH,QAAA;AACF,MAAA,CAAA;AACA,MAAA,EAAE,WAAW,IAAA;AACf,KAAA;;;;;;;;;;;SAMU,MAAA,CAAA,eAAA,IAAmB,MAAA,CAAA,eAAA,CAAgB,SAAA,IAAAC,SAAA,IAF3CC,WAAA,CAMEC,uBAAA,CALK,MAAA,CAAA,SAAS,CAAA,EAAA;AAEb,IAAA,GAAA,EAAK,MAAA,CAAA,SAAA;AACL,IAAA,YAAA,EAAY,MAAA,CAAA,SAAA;AACZ,IAAA,kBAAA,EAAkB,MAAA,CAAA;AAAA,GAAA,EAAA,MAAA,CAAA,EAAA,CAAA,cAAA,kBAAA,CAAA,KAIR,MAAA,CAAA,eAAA,IAAe,CAAK,MAAA,CAAA,aAAAF,SAAA,EAAA,EAFjCC,YAMEC,uBAAA,CALK,MAAA,CAAA,cAAc,CAAA,EAAA;AAElB,IAAA,GAAA,EAAK,MAAA,CAAA,SAAA;AACL,IAAA,kBAAA,EAAkB,MAAA,CAAA,eAAA;AAClB,IAAA,YAAA,EAAY,MAAA,CAAA;GAAA,EAAA,IAAA,EAAA,GAAA,CAAA,kBAAA,EAAA,YAAA,CAAA,CAAA,IAAAC,kBAAA,CAAA,MAAA,EAAA,IAAA,CAAA;;;AClGV,SAAS,QAAA,GAAW;AACzB,EAAA,MAAM,KAAA,GAAQC,IAA2B,IAAI,CAAA;AAC7C,EAAA,MAAM,KAAA,GAAQA,IAAI,KAAK,CAAA;AAEvB,EAAA,MAAM,cAAA,GAAiB,CAAC,KAAA,KAAsB;AAC5C,IAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,EAAE,MAAM,GAAA,EAAK,KAAA,EAAO,QAAO,GAAI,KAAA,CAAM,MAAM,qBAAA,EAAsB;AACvE,IAAA,MAAM,MAAA,GACJ,KAAA,CAAM,OAAA,IAAW,IAAA,IACjB,KAAA,CAAM,OAAA,IAAW,KAAA,IACjB,KAAA,CAAM,OAAA,IAAW,GAAA,IACjB,KAAA,CAAM,OAAA,IAAW,MAAA;AAEnB,IAAA,KAAA,CAAM,KAAA,GAAQ,MAAA;AAAA,EAChB,CAAA;AAEA,EAAAC,UAAU,MAAM;AACd,IAAA,MAAA,CAAO,gBAAA,CAAiB,aAAa,cAAc,CAAA;AAAA,EACrD,CAAC,CAAA;AAED,EAAAC,gBAAgB,MAAM;AACpB,IAAA,MAAA,CAAO,mBAAA,CAAoB,aAAa,cAAc,CAAA;AAAA,EACxD,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA;AAAA,GACF;AACF;;;;;;;;;ACxBA,IAAA,MAAM,KAAA,GAAQ,OAAA;AAKd,IAAA,MAAM,kBAAkBC,QAAAA,CAAS,MAAMC,oBAAoB,MAAA,CAAO,KAAA,CAAM,SAAS,CAAC,CAAA;AAClF,IAAA,MAAM,EAAE,KAAA,EAAO,KAAA,EAAM,GAAI,QAAA,EAAS;AAElC,IAAA,MAAM,aAAA,GAAgBD,SAAwB,MAAM;AAClD,MAAA,MAAM,MAAA,GAAgC,gBAAgB,KAAA,EAAO,MAAA;AAC7D,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAO,EAAC;AACV,MAAA;AACA,MAAA,OAAO;QACL,QAAA,EAAU,UAAA;AACV,QAAA,IAAA,EAAM,MAAA,CAAO,IAAA;AACb,QAAA,GAAA,EAAK,MAAA,CAAO,GAAA;AACZ,QAAA,KAAA,EAAO,MAAA,CAAO,KAAA;AACd,QAAA,MAAA,EAAQ,MAAA,CAAO;AACjB,OAAA;IACF,CAAC,CAAA;AAED,IAAA,MAAM,sBAAA,GAAyBA,SAAwB,OAAO;MAC5D,YAAA,EAAc,EAAA;MACd,MAAA,EAAQ,EAAA;AACR,MAAA,OAAA,EAAS,CAAA,EAAG,KAAA,CAAM,KAAA,GAAQ,CAAA,GAAI,CAAC,CAAA,yBAAA,CAAA;MAC/B,eAAA,EAAiB;KACnB,CAAE,CAAA;AAEF,IAAA,MAAM,eAAA,GAAkBA,QAAAA;MAAS,MAC/B,KAAA,CAAM,mBAAmB,eAAA,CAAgB,KAAA,GACrC,MAAM,eAAA,CAAgB,eAAA,CAAgB,KAAK,CAAA,GAC3C,sBAAA,CAAuB;AAC7B,KAAA;AAEA,IAAAE,KAAAA,CAAM,KAAA,EAAO,CAAC,KAAA,KAAU;AACtB,MAAA,IAAI,gBAAgB,KAAA,EAAO;AACzB,QAAA,eAAA,CAAgB,MAAM,OAAA,GAAU,KAAA;AAClC,MAAA;IACF,CAAC,CAAA;;;;;;;;SAKS,MAAA,CAAA,eAAA,IAAe,CAAK,MAAA,CAAA,eAAA,CAAgB,aAAAT,SAAAA,EAAA,EAD5CU,mBAUM,KAAA,EAAA;IAAA,GAAA,EAAA,CAAA;IARJ,KAAA,EAAM,iBAAA;AACL,IAAA,eAAA,EAAe,OAAA,SAAA,CAAU;GAAA,EAAA;AAE1B,IAAAC,kBAAA;AAIE,MAAA,KAAA;AAAA,MAAA;QAHA,GAAA,EAAI,OAAA;QACJ,KAAA,EAAM,wBAAA;QACL,KAAA,EAAKC,cAAA,CAAA,EAAA,GAAO,MAAA,CAAA,eAAa,GAAK,MAAA,CAAA,iBAAe;AAAA,OAAA;;;;;;;;;;ACtC7C,IAAM,WAAA,GAAN,cAA0B,KAAA,CAA0B;AAAA,EAuBzD,WAAA,GAAc;AACZ,IAAA,KAAA,EAAM;AAHR,IAAA,IAAA,CAAiB,SAAA,GAAY,oBAAA;AAI3B,IAAA,IAAA,CAAK,IAAA,GAAO,QAAA,CAAS,kBAAA,CAAmB,IAAA,CAAK,SAAS,CAAA;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,GAAA;AAAA,EAC3B;AAAA;AAAA,EAGO,OAAO,KAAA,EAAqB;AACjC,IAAA,IAAA,CAAK,IAAA,CAAM,KAAA,CAAM,SAAA,GAAY,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA,CAAA;AAAA,EAC7C;AAAA,EAEO,MAAA,GAAS;AACd,IAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,OAAA,EAAS,OAAO,IAAA;AAC7C,IAAA,IAAA,CAAK,oBAAoB,OAAA,EAAQ;AAEjC,IAAA,OAAO,eAAA,CAAgB,IAAA,CAAK,mBAAA,EAAqB,IAAA,CAAK,cAAc,CAAA;AAAA,EACtE;AAAA;AAAA,EAGU,YAAA,GAAe;AACvB,IAAA,MAAM,GAAA,GAAO,KAAK,QAAA,IAAY,iBAAA;AAC9B,IAAA,OAAOC,CAAAA;AAAA,MACL,QAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAK,MAAA,CAAO,GAAA;AAAA,QAAI,CAAC,KAAA,KACfA,CAAAA,CAAE,GAAA,EAAK;AAAA,UACL,GAAA,EAAK,MAAM,SAAA,CAAU,EAAA;AAAA,UACrB,WAAW,KAAA,CAAM,SAAA;AAAA,UACjB,eAAA,EAAiB,KAAK,OAAA,CAAQ;AAAA,SAC/B;AAAA;AACH,KACF;AAAA,EACF;AAAA;AAAA,EAGA,IAAc,MAAA,GAAgC;AAC5C,IAAA,OAAO,IAAA,CAAK,aAAa,YAAA,EAAa;AAAA,EACxC;AAAA,EAEA,IAAc,QAAA,GAAkC;AAC9C,IAAA,OAAO,IAAA,CAAK,gBAAA,CAAiB,yBAAA,CAAA,WAAA,gBAAgD,EACzE,QAAA;AAAA,EACN;AACF;AA/DkC,eAAA,CAAA;AAAA,EAA/B,OAAOC,YAAY;AAAA,CAAA,EAHT,WAAA,CAGqB,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAGb,eAAA,CAAA;AAAA,EADlB,OAAO,oBAAoB;AAAA,CAAA,EALjB,WAAA,CAMQ,SAAA,EAAA,kBAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADlB,OAAO,gBAAgB;AAAA,CAAA,EARb,WAAA,CASQ,SAAA,EAAA,cAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADlB,OAAO,0BAA0B;AAAA,CAAA,EAXvB,WAAA,CAYQ,SAAA,EAAA,qBAAA,EAAA,CAAA,CAAA;AAGV,eAAA,CAAA;AAAA,EADR,cAAc,6BAA6B;AAAA,CAAA,EAdjC,WAAA,CAeF,SAAA,EAAA,qBAAA,EAAA,CAAA,CAAA;AAE+C,eAAA,CAAA;AAAA,EAAvD,kBAAA,CAAmB,gBAAgBC,kBAAkB;AAAA,CAAA,EAjB3C,WAAA,CAiB6C,SAAA,EAAA,eAAA,EAAA,CAAA,CAAA;AAEG,eAAA,CAAA;AAAA,EAA1D,kBAAA,CAAmB,gBAAgB,qBAAqB;AAAA,CAAA,EAnB9C,WAAA,CAmBgD,SAAA,EAAA,aAAA,EAAA,CAAA,CAAA;AAnBhD,WAAA,GAAN,eAAA,CAAA;AAAA,EADN,UAAA;AAAW,CAAA,EACC,WAAA,CAAA;ACXN,IAAM,cAAA,GAAuC,CAAC,GAAA,EAAK,IAAA,KAAS;AACjE,EAAA,MAAM,gBAAA,GAAmB,GAAA,CAAI,GAAA,CAA0BC,oBAAoB,CAAA;AAC3E,EAAA,MAAM,WAAWC,eAAAA,CAAgB;AAAA,IAC/B,IAAA,EAAM,mBAAA;AAAA,IACN,KAAA,EAAO;AAAA,MACL,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,MAAA;AAAA,QACN,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,MAAM,KAAA,EAAO;AACX,MAAA,OAAO,MACLJ,EAAE,oBAAA,EAAa;AAAA,QACb,WAAW,KAAA,CAAM,IAAA;AAAA,QACjB,SAAA,EAAW,KAAK,UAAA,CAAY,SAAA;AAAA,QAC5B,cAAA,EAAgB,KAAK,UAAA,CAAY;AAAA,OAClC,CAAA;AAAA,IACL;AAAA,GACD,CAAA;AACD,EAAA,gBAAA,CAAiB,uDAAgD,QAAQ,CAAA;AAC3E,CAAA;;;AC1BO,IAAM,aAAA,GAAsC,CAAC,GAAA,EAAK,IAAA,KAAS;AAChE,EAAA,GAAA,CAAI,UAAA,CAAW,aAAA,CAAc,WAAA,EAAa,IAAI,CAAA;AAChD,CAAA;ACSO,IAAM,aAAA,GAAkC;AAAA,EAC7C,MAAM,gBAAA,CAAiB,KAAA;AAAA,EACvB,IAAA,EAAM;AAAA,IACJ,UAAA,EAAY,IAAA;AAAA,IACZ,SAAA,EAAA,cAAA;AAAA,IACA,cAAA,EAAgB,cAAA;AAAA,IAChB,OAAA,EAAS,CAAC,SAAA,KAAoD;AAC5D,MAAA,MAAM,eAAA,GAAkBL,mBAAAA,CAAoB,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA;AACnE,MAAA,IAAI,CAAC,eAAA,IAAmB,eAAA,CAAgB,aAAa,eAAA,CAAgB,KAAA,CAAM,WAAW,CAAA,EAAG;AACvF,QAAA,OAAO;AAAA,UACL,GAAA,EAAK,CAAA;AAAA,UACL,MAAA,EAAQ,CAAA;AAAA,UACR,IAAA,EAAM,CAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACT;AAAA,MACF;AACA,MAAA,IAAI,SAAA,CAAU,OAAO,UAAA,EAAY;AAC/B,QAAA,OAAO;AAAA,UACL,KAAK,cAAA,CAAe,eAAA;AAAA,UACpB,QAAQ,cAAA,CAAe,mBAAA;AAAA,UACvB,MAAM,cAAA,CAAe,OAAA;AAAA,UACrB,OAAO,cAAA,CAAe;AAAA,SACxB;AAAA,MACF;AACA,MAAA,OAAO;AAAA,QACL,KAAK,cAAA,CAAe,eAAA;AAAA,QACpB,QAAQ,cAAA,CAAe,OAAA;AAAA,QACvB,MAAM,cAAA,CAAe,OAAA;AAAA,QACrB,OAAO,cAAA,CAAe;AAAA,OACxB;AAAA,IACF;AAAA,GACF;AAAA,EACA,QAAA,EAAU;AAAA,IACR,MAAA,EAAQ,MAAMK,CAAAA,CAAE,KAAK;AAAA,GACvB;AAAA,EACA,SAAS,UAAA,EAAY;AACnB,IAAA,MAAM,EAAE,WAAU,GAAI,UAAA;AACtB,IAAA,MAAM,QAA8B,EAAC;AACrC,IAAA,IAAI,UAAU,UAAA,EAAY;AACxB,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,MAAM,sBAAA,CAAuB,aAAA;AAAA,QAC7B,MAAM,SAAA,CAAU,UAAA;AAAA,QAChB,EAAA,EAAI,UAAU,UAAA,CAAW;AAAA,OAC1B,CAAA;AAAA,IACH;AACA,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,MAAM,sBAAA,CAAuB,aAAA;AAAA,QAC7B,MAAM,SAAA,CAAU,WAAA;AAAA,QAChB,EAAA,EAAI,UAAU,IAAA,CAAK;AAAA,OACpB,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,MAAM,sBAAA,CAAuB,aAAA;AAAA,QAC7B,MAAM,SAAA,CAAU,WAAA;AAAA,QAChB,EAAA,EAAI,UAAU,MAAA,CAAQ;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA,SAAS,SAAA,EAAsD;AAC7D,IAAA,MAAM,eAAA,GAAkBL,mBAAAA,CAAoB,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA;AACnE,IAAA,IAAI,CAAC,eAAA,IAAmB,eAAA,CAAgB,SAAA,EAAW;AACjD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAA,CAAU,OAAO,UAAA,EAAY;AAC/B,MAAA,OAAO;AAAA,QACL,CAAA,EAAG,CAAA;AAAA,QACH,GAAG,cAAA,CAAe;AAAA,OACpB;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,GAAG,cAAA,CAAe,OAAA;AAAA,MAClB,CAAA,EAAG;AAAA,KACL;AAAA,EACF,CAAA;AAAA,EACA,cAAc,SAAA,EAA0C;AACtD,IAAA,MAAM,QAAQ,SAAA,CAAU,UAAA;AACxB,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,SAAA,CAAU,iBAAA;AAC7B,IAAA,IAAI,SAAA,CAAU,OAAO,UAAA,EAAY;AAC/B,MAAA,OAAO;AAAA,QACL,CAAA,EAAG,MAAM,UAAA,CAAW,CAAA;AAAA,QACpB,CAAA,EAAG,SAAA,CAAU,MAAA,CAAO,SAAA,CAAU;AAAA,OAChC;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,SAAA,CAAU,MAAA,CAAO,UAAA,CAAW,CAAA;AAAA,MAC/B,CAAA,EAAG,MAAM,UAAA,CAAW;AAAA,KACtB;AAAA,EACF,CAAA;AAAA,EACA,eAAe,SAAA,EAA0C;AACvD,IAAA,MAAM,QAAQ,SAAA,CAAU,SAAA;AACxB,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,SAAA,CAAU,kBAAA;AAC7B,IAAA,IAAI,SAAA,CAAU,OAAO,UAAA,EAAY;AAC/B,MAAA,OAAO;AAAA,QACL,CAAA,EAAG,MAAM,WAAA,CAAY,CAAA;AAAA,QACrB,CAAA,EAAG,KAAA,CAAM,WAAA,CAAY,CAAA,GAAI,eAAe,mBAAA,GAAsB;AAAA,OAChE;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,KAAA,CAAM,WAAA,CAAY,CAAA,GAAI,eAAe,mBAAA,GAAsB,CAAA;AAAA,MAC9D,CAAA,EAAG,MAAM,WAAA,CAAY;AAAA,KACvB;AAAA,EACF,CAAA;AAAA,EACA,UAAU,UAAA,EAAY;AACpB,IAAA,MAAM,EAAE,WAAU,GAAI,UAAA;AACtB,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,IAAI,SAAA,CAAU,OAAO,UAAA,EAAY;AAC/B,QAAA,OAAO;AAAA,UACL;AAAA,YACE,QAAQ,KAAA,CAAM,cAAA;AAAA,cACZ,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa;AAAA,gBAChC,CAAA,EAAG,CAAA;AAAA,gBACH,CAAA,EAAG,eAAe,mBAAA,GAAsB;AAAA,eACzC,CAAA;AAAA,cACD,UAAU,IAAA,CAAK;AAAA,aACjB;AAAA,YACA,MAAM,uBAAA,CAAwB;AAAA;AAChC,SACF;AAAA,MACF;AACA,MAAA,OAAO;AAAA,QACL;AAAA,UACE,QAAQ,KAAA,CAAM,cAAA;AAAA,YACZ,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,EAAE,CAAA,EAAG,cAAA,CAAe,mBAAA,GAAsB,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,YACrF,UAAU,IAAA,CAAK;AAAA,WACjB;AAAA,UACA,MAAM,uBAAA,CAAwB;AAAA;AAChC,OACF;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL;AAAA,QACE,MAAA,EAAQ,UAAU,MAAA,CAAQ,WAAA;AAAA,QAC1B,MAAM,uBAAA,CAAwB;AAAA;AAChC,KACF;AAAA,EACF,CAAA;AAAA,EACA,gBAAgB,SAAA,EAAmB;AACjC,IAAA,MAAM,EAAE,UAAS,GAAI,SAAA;AACrB,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,OAAO,CAAC,SAAA,CAAU,IAAA,CAAK,MAAA,GAAS,UAAU,MAAA,CAAO,CAAA;AAAA,IACnD;AAEA,IAAA,OAAO,CAAC,SAAA,CAAU,IAAA,CAAK,SAAS,SAAA,CAAU,MAAA,CAAO,IAAI,cAAA,CAAe,eAAA;AAAA,EACtE;AACF;;;AC3JO,IAAM,oBAA0C,CAAA,GAAA,KAAO;AAC5D,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAkBM,YAAY,CAAA;AACnD,EAAA,QAAA,CAAS,kBAAkB,aAAa,CAAA;AAC1C,CAAA;ACHO,IAAM,mBAAA,GAA4C,CAAC,GAAA,EAAK,KAAA,KAAU;AACvE,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,GAAA,CAAsBI,gBAAgB,CAAA;AAC/D,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAkBJ,YAAY,CAAA;AAEnD,EAAA,MAAM,qBAAqB,MAAM;AAC/B,IAAA,YAAA,CAAa,YAAA,EAAa,CAAE,OAAA,CAAQ,CAAA,KAAA,KAAS;AAC3C,MAAA,IAAI,KAAA,EAAO,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,KAAA,CAAM,SAAA,CAAU,GAAA,EAAK;AACxB,QAAA;AAAA,MACF;AACA,MAAA,YAAA,CAAa,WAAA,CAAY,MAAM,SAAS,CAAA;AAAA,IAC1C,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,QAAA,CAAS,UAAA,CAAW,aAAa,MAAM;AACrC,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,kBAAA,EAAmB;AAAA,IACrB,GAAG,CAAC,CAAA;AAAA,EACN,CAAC,CAAA;AACH,CAAA;;;ACpBO,IAAM,cAAA,GAAoE;AAAA,EAC/E,uCAAiC,iBAAA;AAAA,EACjC,iCAA8B,cAAA;AAAA,EAC9B,+BAA6B,aAAA;AAAA,EAC7B,2CAAmC;AACrC,CAAA;;;ACHO,IAAM,oBAAoB,mBAAA,CAA8C;AAAA,EAC7E,MAAA,EAAQ,CAAC,GAAA,EAAoB,IAAA,KAAmC;AAC9D,IAAA,MAAM,EAAE,SAAA,EAAW,aAAA,GAAgB,IAAG,GAAI,IAAA;AAC1C,IAAA,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,QAAQ,CAAA,KAAM;AAC1D,MAAA,MAAM,YAAA,GAAe,GAAA;AACrB,MAAA,MAAM,YAAA,GAAe,cAAc,YAAY,CAAA;AAC/C,MAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,OAAO,iBAAiB,UAAA,EAAY;AACtC,QAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,QAAA;AAAA,MACF;AACA,MAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,IACpB,CAAC,CAAA;AAAA,EACH;AACF,CAAC","file":"index.js","sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { defineComponent, h, provide, type VNodeChild } from 'vue';\nimport type { interfaces } from 'inversify';\nimport {\n Playground,\n PlaygroundVueContainerKey,\n PlaygroundVueRefKey,\n type PlaygroundContainerFactory,\n} from '@flowgram-vue/core';\n\n/**\n * 给 Layer 独立 createApp 注入 playground 容器,使子组件里的 useService / usePlayground 可用。\n */\nexport const LayerVueProvide = defineComponent({\n name: 'LayerVueProvide',\n props: {\n factory: {\n type: Object,\n required: true,\n },\n },\n setup(props) {\n const factory = props.factory as PlaygroundContainerFactory;\n provide(PlaygroundVueContainerKey, factory as unknown as interfaces.Container);\n try {\n provide(PlaygroundVueRefKey, factory.get(Playground));\n } catch {\n // 测试容器可能重复 bind PlaygroundConfig,此时仅 provide container\n }\n },\n render() {\n return this.$slots.default?.();\n },\n});\n\nexport function wrapLayerRender(factory: PlaygroundContainerFactory, children: VNodeChild) {\n return h(LayerVueProvide, { factory }, () => children);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport enum GroupRenderer {\n GroupRender = 'group_render',\n GroupBox = 'group_box',\n}\n\nexport const PositionConfig = {\n paddingWithNote: 50, // note 留白大小\n padding: 10, // 无 label 的 padding\n paddingWithAddLabel: 20, // 有 label 的padding,如要放添加按钮\n headerHeight: 20, // 基础头部高度\n};\n\nexport enum GroupPluginRegister {\n GroupNode = 'registerGroupNode',\n Render = 'registerRender',\n Layer = 'registerLayer',\n CleanGroups = 'registerCleanGroups',\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';\n\nimport { delay, type Disposable, type Rectangle } from '@flowgram-vue/utils';\nimport {\n FlowDocument,\n FlowGroupController,\n FlowNodeEntity,\n FlowNodeRenderData,\n} from '@flowgram-vue/document';\nimport { useEntityFromContext, useService } from '@flowgram-vue/core';\n\nimport type { IGroupBoxHeader, IGroupNode } from '../type';\n\nconst props = defineProps<{\n groupNode: FlowNodeEntity;\n GroupNode: IGroupNode;\n GroupBoxHeader: IGroupBoxHeader;\n}>();\n\nfunction useCurrentDomNode(): HTMLDivElement {\n const entity = useEntityFromContext<FlowNodeEntity>();\n const renderData = entity.getData<FlowNodeRenderData>(FlowNodeRenderData);\n return renderData.node;\n}\n\nconst container = useCurrentDomNode();\nconst document = useService<FlowDocument>(FlowDocument);\nconst groupController = computed(() => FlowGroupController.create(props.groupNode));\n\nconst renderKey = ref(0);\nconst rendering = ref(true);\nconst collapsedCache = ref(groupController.value?.collapsed ?? false);\nlet disposer: Disposable | undefined;\n\nasync function rerender() {\n rendering.value = true;\n renderKey.value += 1;\n await delay(50);\n renderKey.value += 1;\n rendering.value = false;\n}\n\nonMounted(() => {\n disposer = document.renderTree.onTreeChange(() => {\n if (groupController.value?.collapsed !== collapsedCache.value) {\n collapsedCache.value = groupController.value?.collapsed ?? false;\n void rerender();\n }\n });\n\n if (groupController.value && !groupController.value.collapsed) {\n void rerender();\n }\n});\n\nonBeforeUnmount(() => {\n disposer?.dispose();\n});\n\nwatch(\n [() => groupController.value?.collapsed, rendering],\n () => {\n const controller = groupController.value;\n if (!controller) {\n return;\n }\n if (controller.collapsed) {\n Object.assign(container.style, {\n display: 'block',\n zIndex: '0',\n width: 'auto',\n height: 'auto',\n });\n return;\n }\n if (!rendering.value) {\n const bounds: Rectangle = controller.bounds;\n Object.assign(container.style, {\n width: `${bounds.width}px`,\n });\n }\n },\n { immediate: true }\n);\n</script>\n\n<template>\n <component\n :is=\"GroupNode\"\n v-if=\"groupController && groupController.collapsed\"\n :key=\"renderKey\"\n :group-node=\"groupNode\"\n :group-controller=\"groupController\"\n />\n <component\n :is=\"GroupBoxHeader\"\n v-else-if=\"groupController && !rendering\"\n :key=\"renderKey\"\n :group-controller=\"groupController\"\n :group-node=\"groupNode\"\n />\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { onBeforeUnmount, onMounted, ref } from 'vue';\n\nexport function useHover() {\n const elRef = ref<HTMLDivElement | null>(null);\n const hover = ref(false);\n\n const checkMouseOver = (event: MouseEvent) => {\n if (!elRef.value) {\n return;\n }\n const { left, top, right, bottom } = elRef.value.getBoundingClientRect();\n const isOver =\n event.clientX >= left &&\n event.clientX <= right &&\n event.clientY >= top &&\n event.clientY <= bottom;\n\n hover.value = isOver;\n };\n\n onMounted(() => {\n window.addEventListener('mousemove', checkMouseOver);\n });\n\n onBeforeUnmount(() => {\n window.removeEventListener('mousemove', checkMouseOver);\n });\n\n return {\n hover,\n elRef,\n };\n}\n","<script setup lang=\"ts\">\n/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { computed, watch, type CSSProperties } from 'vue';\n\nimport type { Rectangle } from '@flowgram-vue/utils';\nimport { FlowGroupController, type FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { useHover } from '../composables/use-hover';\n\nconst props = defineProps<{\n groupNode: FlowNodeEntity;\n backgroundStyle?: (groupController: FlowGroupController) => CSSProperties;\n}>();\n\nconst groupController = computed(() => FlowGroupController.create(props.groupNode));\nconst { hover, elRef } = useHover();\n\nconst positionStyle = computed<CSSProperties>(() => {\n const bounds: Rectangle | undefined = groupController.value?.bounds;\n if (!bounds) {\n return {};\n }\n return {\n position: 'absolute',\n left: bounds.left,\n top: bounds.top,\n width: bounds.width,\n height: bounds.height,\n };\n});\n\nconst defaultBackgroundStyle = computed<CSSProperties>(() => ({\n borderRadius: 10,\n zIndex: -1,\n outline: `${hover.value ? 2 : 1}px solid rgb(97, 69, 211)`,\n backgroundColor: 'rgb(236 233 247)',\n}));\n\nconst backgroundStyle = computed(() =>\n props.backgroundStyle && groupController.value\n ? props.backgroundStyle(groupController.value)\n : defaultBackgroundStyle.value\n);\n\nwatch(hover, (value) => {\n if (groupController.value) {\n groupController.value.hovered = value;\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"groupController && !groupController.collapsed\"\n class=\"gedit-group-box\"\n :data-group-id=\"groupNode.id\"\n >\n <div\n ref=\"elRef\"\n class=\"gedit-group-background\"\n :style=\"{ ...positionStyle, ...backgroundStyle }\"\n />\n </div>\n</template>\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Fragment, h, type Component } from 'vue';\nimport { inject, injectable } from 'inversify';\nimport { FlowRendererRegistry } from '@flowgram-vue/renderer';\nimport {\n FlowDocument,\n FlowDocumentTransformerEntity,\n FlowGroupController,\n FlowGroupService,\n FlowNodeEntity,\n FlowNodeRenderData,\n FlowNodeTransformData,\n} from '@flowgram-vue/document';\nimport { Layer, observeEntity, observeEntityDatas, PlaygroundContainerFactory } from '@flowgram-vue/core';\nimport { domUtils } from '@flowgram-vue/utils';\n\nimport { wrapLayerRender } from './layer-vue-provide';\nimport { GroupsLayerOptions, IGroupBox } from './type';\nimport { GroupRenderer } from './constant';\nimport { GroupBox } from './components';\n\n@injectable()\nexport class GroupsLayer extends Layer<GroupsLayerOptions> {\n public readonly node: HTMLElement;\n\n @inject(FlowDocument) protected document: FlowDocument;\n\n @inject(FlowRendererRegistry)\n protected readonly rendererRegistry: FlowRendererRegistry;\n\n @inject(FlowGroupService)\n protected readonly groupService: FlowGroupService;\n\n @inject(PlaygroundContainerFactory)\n protected readonly playgroundContainer: PlaygroundContainerFactory;\n\n @observeEntity(FlowDocumentTransformerEntity)\n readonly documentTransformer: FlowDocumentTransformerEntity;\n\n @observeEntityDatas(FlowNodeEntity, FlowNodeRenderData) _renderStates: FlowNodeRenderData[];\n\n @observeEntityDatas(FlowNodeEntity, FlowNodeTransformData) _transforms: FlowNodeTransformData[];\n\n private readonly className = 'gedit-groups-layer';\n\n constructor() {\n super();\n this.node = domUtils.createDivWithClass(this.className);\n this.node.style.zIndex = '0';\n }\n\n /** 缩放 */\n public onZoom(scale: number): void {\n this.node!.style.transform = `scale(${scale})`;\n }\n\n public render() {\n if (this.documentTransformer.loading) return null;\n this.documentTransformer.refresh();\n\n return wrapLayerRender(this.playgroundContainer, this.renderGroups());\n }\n\n /** 渲染分组 */\n protected renderGroups() {\n const Box = (this.renderer || GroupBox) as Component;\n return h(\n Fragment,\n null,\n this.groups.map((group) =>\n h(Box, {\n key: group.groupNode.id,\n groupNode: group.groupNode,\n backgroundStyle: this.options.groupBoxStyle,\n })\n )\n );\n }\n\n /** 所有分组 */\n protected get groups(): FlowGroupController[] {\n return this.groupService.getAllGroups();\n }\n\n protected get renderer(): IGroupBox | undefined {\n return this.rendererRegistry.tryToGetRendererComponent(GroupRenderer.GroupBox)\n ?.renderer as IGroupBox | undefined;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { defineComponent, h } from 'vue';\n\nimport { FlowRendererRegistry } from '@flowgram-vue/renderer';\nimport { FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupRenderer } from '../constant';\nimport { GroupRender } from '../components';\n\n/** 注册渲染组件 */\nexport const registerRender: IGroupPluginRegister = (ctx, opts) => {\n const rendererRegistry = ctx.get<FlowRendererRegistry>(FlowRendererRegistry);\n const renderer = defineComponent({\n name: 'GroupNodeRenderer',\n props: {\n node: {\n type: Object as () => FlowNodeEntity,\n required: true,\n },\n },\n setup(props) {\n return () =>\n h(GroupRender, {\n groupNode: props.node,\n GroupNode: opts.components!.GroupNode,\n GroupBoxHeader: opts.components!.GroupBoxHeader,\n });\n },\n });\n rendererRegistry.registerVueComponent(GroupRenderer.GroupRender, renderer);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupsLayer } from '../groups-layer';\n\n/** 注册背景层 */\nexport const registerLayer: IGroupPluginRegister = (ctx, opts) => {\n ctx.playground.registerLayer(GroupsLayer, opts);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { h } from 'vue';\n\nimport { IPoint, PaddingSchema, Point } from '@flowgram-vue/utils';\nimport {\n FlowGroupController,\n FlowNodeBaseType,\n FlowNodeRegistry,\n FlowNodeTransformData,\n FlowTransitionLabelEnum,\n type FlowTransitionLine,\n FlowTransitionLineEnum,\n} from '@flowgram-vue/document';\n\nimport { GroupRenderer, PositionConfig } from './constant';\n\nexport const GroupRegister: FlowNodeRegistry = {\n type: FlowNodeBaseType.GROUP,\n meta: {\n exportJSON: true,\n renderKey: GroupRenderer.GroupRender,\n positionConfig: PositionConfig,\n padding: (transform: FlowNodeTransformData): PaddingSchema => {\n const groupController = FlowGroupController.create(transform.entity);\n if (!groupController || groupController.collapsed || groupController.nodes.length === 0) {\n return {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n };\n }\n if (transform.entity.isVertical) {\n return {\n top: PositionConfig.paddingWithNote,\n bottom: PositionConfig.paddingWithAddLabel,\n left: PositionConfig.padding,\n right: PositionConfig.padding,\n };\n }\n return {\n top: PositionConfig.paddingWithNote,\n bottom: PositionConfig.padding,\n left: PositionConfig.padding,\n right: PositionConfig.paddingWithAddLabel,\n };\n },\n },\n formMeta: {\n render: () => h('div'),\n },\n getLines(transition) {\n const { transform } = transition;\n const lines: FlowTransitionLine[] = [];\n if (transform.firstChild) {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.inputPoint,\n to: transform.firstChild.inputPoint,\n });\n }\n if (transform.next) {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.outputPoint,\n to: transform.next.inputPoint,\n });\n } else {\n lines.push({\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: transform.outputPoint,\n to: transform.parent!.outputPoint,\n });\n }\n return lines;\n },\n getDelta(transform: FlowNodeTransformData): IPoint | undefined {\n const groupController = FlowGroupController.create(transform.entity);\n if (!groupController || groupController.collapsed) {\n return;\n }\n if (transform.entity.isVertical) {\n return {\n x: 0,\n y: PositionConfig.paddingWithNote,\n };\n }\n return {\n x: PositionConfig.padding,\n y: 0,\n };\n },\n getInputPoint(transform: FlowNodeTransformData): IPoint {\n const child = transform.firstChild;\n if (!child) return transform.defaultInputPoint;\n if (transform.entity.isVertical) {\n return {\n x: child.inputPoint.x,\n y: transform.bounds.topCenter.y,\n };\n }\n return {\n x: transform.bounds.leftCenter.x,\n y: child.inputPoint.y,\n };\n },\n getOutputPoint(transform: FlowNodeTransformData): IPoint {\n const child = transform.lastChild;\n if (!child) return transform.defaultOutputPoint;\n if (transform.entity.isVertical) {\n return {\n x: child.outputPoint.x,\n y: child.outputPoint.y + PositionConfig.paddingWithAddLabel / 2,\n };\n }\n return {\n x: child.outputPoint.x + PositionConfig.paddingWithAddLabel / 2,\n y: child.outputPoint.y,\n };\n },\n getLabels(transition) {\n const { transform } = transition;\n if (transform.next) {\n if (transform.entity.isVertical) {\n return [\n {\n offset: Point.getMiddlePoint(\n Point.move(transform.outputPoint, {\n x: 0,\n y: PositionConfig.paddingWithAddLabel / 2,\n }),\n transform.next.inputPoint\n ),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n }\n return [\n {\n offset: Point.getMiddlePoint(\n Point.move(transform.outputPoint, { x: PositionConfig.paddingWithAddLabel / 2, y: 0 }),\n transform.next.inputPoint\n ),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n }\n return [\n {\n offset: transform.parent!.outputPoint,\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ];\n },\n getOriginDeltaY(transform): number {\n const { children } = transform;\n if (children.length === 0) {\n return -transform.size.height * transform.origin.y;\n }\n // 这里要加上 y 轴的偏移\n return -transform.size.height * transform.origin.y - PositionConfig.paddingWithNote;\n },\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupRegister } from '../group-node-register';\n\n/** 注册分组节点 */\nexport const registerGroupNode: IGroupPluginRegister = ctx => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n document.registerFlowNodes(GroupRegister);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { FlowGroupService } from '@flowgram-vue/document';\n\nimport { IGroupPluginRegister } from '../type';\n\n/** 注册清理分组逻辑 */\nexport const registerCleanGroups: IGroupPluginRegister = (ctx, _opts) => {\n const groupService = ctx.get<FlowGroupService>(FlowGroupService);\n const document = ctx.get<FlowDocument>(FlowDocument);\n\n const clearInvalidGroups = () => {\n groupService.getAllGroups().forEach(group => {\n if (group?.nodes.length !== 0) {\n return;\n }\n if (!group.groupNode.pre) {\n return;\n }\n groupService.deleteGroup(group.groupNode);\n });\n };\n\n document.originTree.onTreeChange(() => {\n setTimeout(() => {\n clearInvalidGroups();\n }, 0);\n });\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IGroupPluginRegister } from '../type';\nimport { GroupPluginRegister } from '../constant';\nimport { registerRender } from './register-render';\nimport { registerLayer } from './register-layer';\nimport { registerGroupNode } from './register-group-node';\nimport { registerCleanGroups } from './register-clean-groups';\n\nexport const groupRegisters: Record<GroupPluginRegister, IGroupPluginRegister> = {\n [GroupPluginRegister.GroupNode]: registerGroupNode,\n [GroupPluginRegister.Render]: registerRender,\n [GroupPluginRegister.Layer]: registerLayer,\n [GroupPluginRegister.CleanGroups]: registerCleanGroups,\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator, PluginContext } from '@flowgram-vue/core';\n\nimport { CreateGroupPluginOptions } from './type';\nimport { groupRegisters } from './registers';\nimport { GroupPluginRegister } from './constant';\n\n/**\n * 分组插件\n */\nexport const createGroupPlugin = definePluginCreator<CreateGroupPluginOptions>({\n onInit: (ctx: PluginContext, opts: CreateGroupPluginOptions) => {\n const { registers: registerConfs = {} } = opts;\n Object.entries(groupRegisters).forEach(([key, register]) => {\n const registerName = key as GroupPluginRegister;\n const registerConf = registerConfs[registerName];\n if (registerConf === false) {\n return;\n }\n if (typeof registerConf === 'function') {\n registerConf(ctx, opts);\n return;\n }\n register(ctx, opts);\n });\n },\n});\n"]}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@flowgram-vue/group-plugin",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "homepage": "https://flowgram.ai/",
6
+ "repository": "https://github.com/Crayon-hua/flowgram-vue",
7
+ "license": "MIT",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "src",
20
+ "dist"
21
+ ],
22
+ "dependencies": {
23
+ "inversify": "^6.0.1",
24
+ "reflect-metadata": "~0.2.2",
25
+ "@flowgram-vue/core": "0.2.0",
26
+ "@flowgram-vue/renderer": "0.2.0",
27
+ "@flowgram-vue/utils": "0.2.0",
28
+ "@flowgram-vue/document": "0.2.0"
29
+ },
30
+ "peerDependencies": {
31
+ "vue": "^3.3.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20",
35
+ "@vitejs/plugin-vue": "^6.0.1",
36
+ "@vitest/coverage-v8": "^3.2.4",
37
+ "@vue/test-utils": "^2.4.6",
38
+ "eslint": "^9.0.0",
39
+ "jsdom": "^26.1.0",
40
+ "typescript": "^5.8.3",
41
+ "vitest": "^3.2.4",
42
+ "vue": "^3.5.18",
43
+ "@flowgram-vue/build-config": "0.2.0",
44
+ "@flowgram-vue/eslint-config": "0.2.0",
45
+ "@flowgram-vue/ts-config": "0.2.0"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "registry": "https://registry.npmjs.org/"
50
+ },
51
+ "scripts": {
52
+ "build": "flowgram-build",
53
+ "test": "vitest run --passWithNoTests",
54
+ "test:cov": "vitest run --coverage --passWithNoTests",
55
+ "lint": "eslint .",
56
+ "ts-check": "tsc --noEmit",
57
+ "type-check": "tsc --noEmit",
58
+ "build:fast": "flowgram-build --fast",
59
+ "build:watch": "flowgram-build --watch"
60
+ }
61
+ }
@@ -0,0 +1,68 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import { computed, watch, type CSSProperties } from 'vue';
8
+
9
+ import type { Rectangle } from '@flowgram-vue/utils';
10
+ import { FlowGroupController, type FlowNodeEntity } from '@flowgram-vue/document';
11
+
12
+ import { useHover } from '../composables/use-hover';
13
+
14
+ const props = defineProps<{
15
+ groupNode: FlowNodeEntity;
16
+ backgroundStyle?: (groupController: FlowGroupController) => CSSProperties;
17
+ }>();
18
+
19
+ const groupController = computed(() => FlowGroupController.create(props.groupNode));
20
+ const { hover, elRef } = useHover();
21
+
22
+ const positionStyle = computed<CSSProperties>(() => {
23
+ const bounds: Rectangle | undefined = groupController.value?.bounds;
24
+ if (!bounds) {
25
+ return {};
26
+ }
27
+ return {
28
+ position: 'absolute',
29
+ left: bounds.left,
30
+ top: bounds.top,
31
+ width: bounds.width,
32
+ height: bounds.height,
33
+ };
34
+ });
35
+
36
+ const defaultBackgroundStyle = computed<CSSProperties>(() => ({
37
+ borderRadius: 10,
38
+ zIndex: -1,
39
+ outline: `${hover.value ? 2 : 1}px solid rgb(97, 69, 211)`,
40
+ backgroundColor: 'rgb(236 233 247)',
41
+ }));
42
+
43
+ const backgroundStyle = computed(() =>
44
+ props.backgroundStyle && groupController.value
45
+ ? props.backgroundStyle(groupController.value)
46
+ : defaultBackgroundStyle.value
47
+ );
48
+
49
+ watch(hover, (value) => {
50
+ if (groupController.value) {
51
+ groupController.value.hovered = value;
52
+ }
53
+ });
54
+ </script>
55
+
56
+ <template>
57
+ <div
58
+ v-if="groupController && !groupController.collapsed"
59
+ class="gedit-group-box"
60
+ :data-group-id="groupNode.id"
61
+ >
62
+ <div
63
+ ref="elRef"
64
+ class="gedit-group-background"
65
+ :style="{ ...positionStyle, ...backgroundStyle }"
66
+ />
67
+ </div>
68
+ </template>
@@ -0,0 +1,108 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
8
+
9
+ import { delay, type Disposable, type Rectangle } from '@flowgram-vue/utils';
10
+ import {
11
+ FlowDocument,
12
+ FlowGroupController,
13
+ FlowNodeEntity,
14
+ FlowNodeRenderData,
15
+ } from '@flowgram-vue/document';
16
+ import { useEntityFromContext, useService } from '@flowgram-vue/core';
17
+
18
+ import type { IGroupBoxHeader, IGroupNode } from '../type';
19
+
20
+ const props = defineProps<{
21
+ groupNode: FlowNodeEntity;
22
+ GroupNode: IGroupNode;
23
+ GroupBoxHeader: IGroupBoxHeader;
24
+ }>();
25
+
26
+ function useCurrentDomNode(): HTMLDivElement {
27
+ const entity = useEntityFromContext<FlowNodeEntity>();
28
+ const renderData = entity.getData<FlowNodeRenderData>(FlowNodeRenderData);
29
+ return renderData.node;
30
+ }
31
+
32
+ const container = useCurrentDomNode();
33
+ const document = useService<FlowDocument>(FlowDocument);
34
+ const groupController = computed(() => FlowGroupController.create(props.groupNode));
35
+
36
+ const renderKey = ref(0);
37
+ const rendering = ref(true);
38
+ const collapsedCache = ref(groupController.value?.collapsed ?? false);
39
+ let disposer: Disposable | undefined;
40
+
41
+ async function rerender() {
42
+ rendering.value = true;
43
+ renderKey.value += 1;
44
+ await delay(50);
45
+ renderKey.value += 1;
46
+ rendering.value = false;
47
+ }
48
+
49
+ onMounted(() => {
50
+ disposer = document.renderTree.onTreeChange(() => {
51
+ if (groupController.value?.collapsed !== collapsedCache.value) {
52
+ collapsedCache.value = groupController.value?.collapsed ?? false;
53
+ void rerender();
54
+ }
55
+ });
56
+
57
+ if (groupController.value && !groupController.value.collapsed) {
58
+ void rerender();
59
+ }
60
+ });
61
+
62
+ onBeforeUnmount(() => {
63
+ disposer?.dispose();
64
+ });
65
+
66
+ watch(
67
+ [() => groupController.value?.collapsed, rendering],
68
+ () => {
69
+ const controller = groupController.value;
70
+ if (!controller) {
71
+ return;
72
+ }
73
+ if (controller.collapsed) {
74
+ Object.assign(container.style, {
75
+ display: 'block',
76
+ zIndex: '0',
77
+ width: 'auto',
78
+ height: 'auto',
79
+ });
80
+ return;
81
+ }
82
+ if (!rendering.value) {
83
+ const bounds: Rectangle = controller.bounds;
84
+ Object.assign(container.style, {
85
+ width: `${bounds.width}px`,
86
+ });
87
+ }
88
+ },
89
+ { immediate: true }
90
+ );
91
+ </script>
92
+
93
+ <template>
94
+ <component
95
+ :is="GroupNode"
96
+ v-if="groupController && groupController.collapsed"
97
+ :key="renderKey"
98
+ :group-node="groupNode"
99
+ :group-controller="groupController"
100
+ />
101
+ <component
102
+ :is="GroupBoxHeader"
103
+ v-else-if="groupController && !rendering"
104
+ :key="renderKey"
105
+ :group-controller="groupController"
106
+ :group-node="groupNode"
107
+ />
108
+ </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 { default as GroupRender } from './group-render.vue';
7
+ export { default as GroupBox } from './group-box.vue';
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { onBeforeUnmount, onMounted, ref } from 'vue';
7
+
8
+ export function useHover() {
9
+ const elRef = ref<HTMLDivElement | null>(null);
10
+ const hover = ref(false);
11
+
12
+ const checkMouseOver = (event: MouseEvent) => {
13
+ if (!elRef.value) {
14
+ return;
15
+ }
16
+ const { left, top, right, bottom } = elRef.value.getBoundingClientRect();
17
+ const isOver =
18
+ event.clientX >= left &&
19
+ event.clientX <= right &&
20
+ event.clientY >= top &&
21
+ event.clientY <= bottom;
22
+
23
+ hover.value = isOver;
24
+ };
25
+
26
+ onMounted(() => {
27
+ window.addEventListener('mousemove', checkMouseOver);
28
+ });
29
+
30
+ onBeforeUnmount(() => {
31
+ window.removeEventListener('mousemove', checkMouseOver);
32
+ });
33
+
34
+ return {
35
+ hover,
36
+ elRef,
37
+ };
38
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export enum GroupRenderer {
7
+ GroupRender = 'group_render',
8
+ GroupBox = 'group_box',
9
+ }
10
+
11
+ export const PositionConfig = {
12
+ paddingWithNote: 50, // note 留白大小
13
+ padding: 10, // 无 label 的 padding
14
+ paddingWithAddLabel: 20, // 有 label 的padding,如要放添加按钮
15
+ headerHeight: 20, // 基础头部高度
16
+ };
17
+
18
+ export enum GroupPluginRegister {
19
+ GroupNode = 'registerGroupNode',
20
+ Render = 'registerRender',
21
+ Layer = 'registerLayer',
22
+ CleanGroups = 'registerCleanGroups',
23
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { definePluginCreator, PluginContext } from '@flowgram-vue/core';
7
+
8
+ import { CreateGroupPluginOptions } from './type';
9
+ import { groupRegisters } from './registers';
10
+ import { GroupPluginRegister } from './constant';
11
+
12
+ /**
13
+ * 分组插件
14
+ */
15
+ export const createGroupPlugin = definePluginCreator<CreateGroupPluginOptions>({
16
+ onInit: (ctx: PluginContext, opts: CreateGroupPluginOptions) => {
17
+ const { registers: registerConfs = {} } = opts;
18
+ Object.entries(groupRegisters).forEach(([key, register]) => {
19
+ const registerName = key as GroupPluginRegister;
20
+ const registerConf = registerConfs[registerName];
21
+ if (registerConf === false) {
22
+ return;
23
+ }
24
+ if (typeof registerConf === 'function') {
25
+ registerConf(ctx, opts);
26
+ return;
27
+ }
28
+ register(ctx, opts);
29
+ });
30
+ },
31
+ });
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
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { h } from 'vue';
7
+
8
+ import { IPoint, PaddingSchema, Point } from '@flowgram-vue/utils';
9
+ import {
10
+ FlowGroupController,
11
+ FlowNodeBaseType,
12
+ FlowNodeRegistry,
13
+ FlowNodeTransformData,
14
+ FlowTransitionLabelEnum,
15
+ type FlowTransitionLine,
16
+ FlowTransitionLineEnum,
17
+ } from '@flowgram-vue/document';
18
+
19
+ import { GroupRenderer, PositionConfig } from './constant';
20
+
21
+ export const GroupRegister: FlowNodeRegistry = {
22
+ type: FlowNodeBaseType.GROUP,
23
+ meta: {
24
+ exportJSON: true,
25
+ renderKey: GroupRenderer.GroupRender,
26
+ positionConfig: PositionConfig,
27
+ padding: (transform: FlowNodeTransformData): PaddingSchema => {
28
+ const groupController = FlowGroupController.create(transform.entity);
29
+ if (!groupController || groupController.collapsed || groupController.nodes.length === 0) {
30
+ return {
31
+ top: 0,
32
+ bottom: 0,
33
+ left: 0,
34
+ right: 0,
35
+ };
36
+ }
37
+ if (transform.entity.isVertical) {
38
+ return {
39
+ top: PositionConfig.paddingWithNote,
40
+ bottom: PositionConfig.paddingWithAddLabel,
41
+ left: PositionConfig.padding,
42
+ right: PositionConfig.padding,
43
+ };
44
+ }
45
+ return {
46
+ top: PositionConfig.paddingWithNote,
47
+ bottom: PositionConfig.padding,
48
+ left: PositionConfig.padding,
49
+ right: PositionConfig.paddingWithAddLabel,
50
+ };
51
+ },
52
+ },
53
+ formMeta: {
54
+ render: () => h('div'),
55
+ },
56
+ getLines(transition) {
57
+ const { transform } = transition;
58
+ const lines: FlowTransitionLine[] = [];
59
+ if (transform.firstChild) {
60
+ lines.push({
61
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
62
+ from: transform.inputPoint,
63
+ to: transform.firstChild.inputPoint,
64
+ });
65
+ }
66
+ if (transform.next) {
67
+ lines.push({
68
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
69
+ from: transform.outputPoint,
70
+ to: transform.next.inputPoint,
71
+ });
72
+ } else {
73
+ lines.push({
74
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
75
+ from: transform.outputPoint,
76
+ to: transform.parent!.outputPoint,
77
+ });
78
+ }
79
+ return lines;
80
+ },
81
+ getDelta(transform: FlowNodeTransformData): IPoint | undefined {
82
+ const groupController = FlowGroupController.create(transform.entity);
83
+ if (!groupController || groupController.collapsed) {
84
+ return;
85
+ }
86
+ if (transform.entity.isVertical) {
87
+ return {
88
+ x: 0,
89
+ y: PositionConfig.paddingWithNote,
90
+ };
91
+ }
92
+ return {
93
+ x: PositionConfig.padding,
94
+ y: 0,
95
+ };
96
+ },
97
+ getInputPoint(transform: FlowNodeTransformData): IPoint {
98
+ const child = transform.firstChild;
99
+ if (!child) return transform.defaultInputPoint;
100
+ if (transform.entity.isVertical) {
101
+ return {
102
+ x: child.inputPoint.x,
103
+ y: transform.bounds.topCenter.y,
104
+ };
105
+ }
106
+ return {
107
+ x: transform.bounds.leftCenter.x,
108
+ y: child.inputPoint.y,
109
+ };
110
+ },
111
+ getOutputPoint(transform: FlowNodeTransformData): IPoint {
112
+ const child = transform.lastChild;
113
+ if (!child) return transform.defaultOutputPoint;
114
+ if (transform.entity.isVertical) {
115
+ return {
116
+ x: child.outputPoint.x,
117
+ y: child.outputPoint.y + PositionConfig.paddingWithAddLabel / 2,
118
+ };
119
+ }
120
+ return {
121
+ x: child.outputPoint.x + PositionConfig.paddingWithAddLabel / 2,
122
+ y: child.outputPoint.y,
123
+ };
124
+ },
125
+ getLabels(transition) {
126
+ const { transform } = transition;
127
+ if (transform.next) {
128
+ if (transform.entity.isVertical) {
129
+ return [
130
+ {
131
+ offset: Point.getMiddlePoint(
132
+ Point.move(transform.outputPoint, {
133
+ x: 0,
134
+ y: PositionConfig.paddingWithAddLabel / 2,
135
+ }),
136
+ transform.next.inputPoint
137
+ ),
138
+ type: FlowTransitionLabelEnum.ADDER_LABEL,
139
+ },
140
+ ];
141
+ }
142
+ return [
143
+ {
144
+ offset: Point.getMiddlePoint(
145
+ Point.move(transform.outputPoint, { x: PositionConfig.paddingWithAddLabel / 2, y: 0 }),
146
+ transform.next.inputPoint
147
+ ),
148
+ type: FlowTransitionLabelEnum.ADDER_LABEL,
149
+ },
150
+ ];
151
+ }
152
+ return [
153
+ {
154
+ offset: transform.parent!.outputPoint,
155
+ type: FlowTransitionLabelEnum.ADDER_LABEL,
156
+ },
157
+ ];
158
+ },
159
+ getOriginDeltaY(transform): number {
160
+ const { children } = transform;
161
+ if (children.length === 0) {
162
+ return -transform.size.height * transform.origin.y;
163
+ }
164
+ // 这里要加上 y 轴的偏移
165
+ return -transform.size.height * transform.origin.y - PositionConfig.paddingWithNote;
166
+ },
167
+ };
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { Fragment, h, type Component } from 'vue';
7
+ import { inject, injectable } from 'inversify';
8
+ import { FlowRendererRegistry } from '@flowgram-vue/renderer';
9
+ import {
10
+ FlowDocument,
11
+ FlowDocumentTransformerEntity,
12
+ FlowGroupController,
13
+ FlowGroupService,
14
+ FlowNodeEntity,
15
+ FlowNodeRenderData,
16
+ FlowNodeTransformData,
17
+ } from '@flowgram-vue/document';
18
+ import { Layer, observeEntity, observeEntityDatas, PlaygroundContainerFactory } from '@flowgram-vue/core';
19
+ import { domUtils } from '@flowgram-vue/utils';
20
+
21
+ import { wrapLayerRender } from './layer-vue-provide';
22
+ import { GroupsLayerOptions, IGroupBox } from './type';
23
+ import { GroupRenderer } from './constant';
24
+ import { GroupBox } from './components';
25
+
26
+ @injectable()
27
+ export class GroupsLayer extends Layer<GroupsLayerOptions> {
28
+ public readonly node: HTMLElement;
29
+
30
+ @inject(FlowDocument) protected document: FlowDocument;
31
+
32
+ @inject(FlowRendererRegistry)
33
+ protected readonly rendererRegistry: FlowRendererRegistry;
34
+
35
+ @inject(FlowGroupService)
36
+ protected readonly groupService: FlowGroupService;
37
+
38
+ @inject(PlaygroundContainerFactory)
39
+ protected readonly playgroundContainer: PlaygroundContainerFactory;
40
+
41
+ @observeEntity(FlowDocumentTransformerEntity)
42
+ readonly documentTransformer: FlowDocumentTransformerEntity;
43
+
44
+ @observeEntityDatas(FlowNodeEntity, FlowNodeRenderData) _renderStates: FlowNodeRenderData[];
45
+
46
+ @observeEntityDatas(FlowNodeEntity, FlowNodeTransformData) _transforms: FlowNodeTransformData[];
47
+
48
+ private readonly className = 'gedit-groups-layer';
49
+
50
+ constructor() {
51
+ super();
52
+ this.node = domUtils.createDivWithClass(this.className);
53
+ this.node.style.zIndex = '0';
54
+ }
55
+
56
+ /** 缩放 */
57
+ public onZoom(scale: number): void {
58
+ this.node!.style.transform = `scale(${scale})`;
59
+ }
60
+
61
+ public render() {
62
+ if (this.documentTransformer.loading) return null;
63
+ this.documentTransformer.refresh();
64
+
65
+ return wrapLayerRender(this.playgroundContainer, this.renderGroups());
66
+ }
67
+
68
+ /** 渲染分组 */
69
+ protected renderGroups() {
70
+ const Box = (this.renderer || GroupBox) as Component;
71
+ return h(
72
+ Fragment,
73
+ null,
74
+ this.groups.map((group) =>
75
+ h(Box, {
76
+ key: group.groupNode.id,
77
+ groupNode: group.groupNode,
78
+ backgroundStyle: this.options.groupBoxStyle,
79
+ })
80
+ )
81
+ );
82
+ }
83
+
84
+ /** 所有分组 */
85
+ protected get groups(): FlowGroupController[] {
86
+ return this.groupService.getAllGroups();
87
+ }
88
+
89
+ protected get renderer(): IGroupBox | undefined {
90
+ return this.rendererRegistry.tryToGetRendererComponent(GroupRenderer.GroupBox)
91
+ ?.renderer as IGroupBox | undefined;
92
+ }
93
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { FlowGroupController } from '@flowgram-vue/document';
7
+ export * from './groups-layer';
8
+ export * from './create-group-plugin';
9
+ export * from './type';
10
+ export * from './constant';
11
+ export * from './group-node-register';
12
+ export * from './components';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { defineComponent, h, provide, type VNodeChild } from 'vue';
7
+ import type { interfaces } from 'inversify';
8
+ import {
9
+ Playground,
10
+ PlaygroundVueContainerKey,
11
+ PlaygroundVueRefKey,
12
+ type PlaygroundContainerFactory,
13
+ } from '@flowgram-vue/core';
14
+
15
+ /**
16
+ * 给 Layer 独立 createApp 注入 playground 容器,使子组件里的 useService / usePlayground 可用。
17
+ */
18
+ export const LayerVueProvide = defineComponent({
19
+ name: 'LayerVueProvide',
20
+ props: {
21
+ factory: {
22
+ type: Object,
23
+ required: true,
24
+ },
25
+ },
26
+ setup(props) {
27
+ const factory = props.factory as PlaygroundContainerFactory;
28
+ provide(PlaygroundVueContainerKey, factory as unknown as interfaces.Container);
29
+ try {
30
+ provide(PlaygroundVueRefKey, factory.get(Playground));
31
+ } catch {
32
+ // 测试容器可能重复 bind PlaygroundConfig,此时仅 provide container
33
+ }
34
+ },
35
+ render() {
36
+ return this.$slots.default?.();
37
+ },
38
+ });
39
+
40
+ export function wrapLayerRender(factory: PlaygroundContainerFactory, children: VNodeChild) {
41
+ return h(LayerVueProvide, { factory }, () => children);
42
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { IGroupPluginRegister } from '../type';
7
+ import { GroupPluginRegister } from '../constant';
8
+ import { registerRender } from './register-render';
9
+ import { registerLayer } from './register-layer';
10
+ import { registerGroupNode } from './register-group-node';
11
+ import { registerCleanGroups } from './register-clean-groups';
12
+
13
+ export const groupRegisters: Record<GroupPluginRegister, IGroupPluginRegister> = {
14
+ [GroupPluginRegister.GroupNode]: registerGroupNode,
15
+ [GroupPluginRegister.Render]: registerRender,
16
+ [GroupPluginRegister.Layer]: registerLayer,
17
+ [GroupPluginRegister.CleanGroups]: registerCleanGroups,
18
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowDocument } from '@flowgram-vue/document';
7
+ import { FlowGroupService } from '@flowgram-vue/document';
8
+
9
+ import { IGroupPluginRegister } from '../type';
10
+
11
+ /** 注册清理分组逻辑 */
12
+ export const registerCleanGroups: IGroupPluginRegister = (ctx, _opts) => {
13
+ const groupService = ctx.get<FlowGroupService>(FlowGroupService);
14
+ const document = ctx.get<FlowDocument>(FlowDocument);
15
+
16
+ const clearInvalidGroups = () => {
17
+ groupService.getAllGroups().forEach(group => {
18
+ if (group?.nodes.length !== 0) {
19
+ return;
20
+ }
21
+ if (!group.groupNode.pre) {
22
+ return;
23
+ }
24
+ groupService.deleteGroup(group.groupNode);
25
+ });
26
+ };
27
+
28
+ document.originTree.onTreeChange(() => {
29
+ setTimeout(() => {
30
+ clearInvalidGroups();
31
+ }, 0);
32
+ });
33
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowDocument } from '@flowgram-vue/document';
7
+
8
+ import { IGroupPluginRegister } from '../type';
9
+ import { GroupRegister } from '../group-node-register';
10
+
11
+ /** 注册分组节点 */
12
+ export const registerGroupNode: IGroupPluginRegister = ctx => {
13
+ const document = ctx.get<FlowDocument>(FlowDocument);
14
+ document.registerFlowNodes(GroupRegister);
15
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { IGroupPluginRegister } from '../type';
7
+ import { GroupsLayer } from '../groups-layer';
8
+
9
+ /** 注册背景层 */
10
+ export const registerLayer: IGroupPluginRegister = (ctx, opts) => {
11
+ ctx.playground.registerLayer(GroupsLayer, opts);
12
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { defineComponent, h } from 'vue';
7
+
8
+ import { FlowRendererRegistry } from '@flowgram-vue/renderer';
9
+ import { FlowNodeEntity } from '@flowgram-vue/document';
10
+
11
+ import { IGroupPluginRegister } from '../type';
12
+ import { GroupRenderer } from '../constant';
13
+ import { GroupRender } from '../components';
14
+
15
+ /** 注册渲染组件 */
16
+ export const registerRender: IGroupPluginRegister = (ctx, opts) => {
17
+ const rendererRegistry = ctx.get<FlowRendererRegistry>(FlowRendererRegistry);
18
+ const renderer = defineComponent({
19
+ name: 'GroupNodeRenderer',
20
+ props: {
21
+ node: {
22
+ type: Object as () => FlowNodeEntity,
23
+ required: true,
24
+ },
25
+ },
26
+ setup(props) {
27
+ return () =>
28
+ h(GroupRender, {
29
+ groupNode: props.node,
30
+ GroupNode: opts.components!.GroupNode,
31
+ GroupBoxHeader: opts.components!.GroupBoxHeader,
32
+ });
33
+ },
34
+ });
35
+ rendererRegistry.registerVueComponent(GroupRenderer.GroupRender, renderer);
36
+ };
package/src/type.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { Component, CSSProperties } from 'vue';
7
+
8
+ import type { FlowNodeEntity } from '@flowgram-vue/document';
9
+ import type { FlowGroupController } from '@flowgram-vue/document';
10
+ import type { LayerOptions, PluginContext } from '@flowgram-vue/core';
11
+
12
+ import type { GroupPluginRegister } from './constant';
13
+
14
+ export type IGroupBox = Component<{
15
+ groupNode: FlowNodeEntity;
16
+ backgroundStyle?: (groupController: FlowGroupController) => CSSProperties;
17
+ }>;
18
+
19
+ export type IGroupRender = Component<{
20
+ groupNode: FlowNodeEntity;
21
+ GroupNode: IGroupNode;
22
+ GroupBoxHeader: IGroupBoxHeader;
23
+ }>;
24
+
25
+ export type IGroupNode = Component<{
26
+ groupNode: FlowNodeEntity;
27
+ groupController: FlowGroupController;
28
+ }>;
29
+
30
+ export type IGroupBoxHeader = Component<{
31
+ groupNode: FlowNodeEntity;
32
+ groupController: FlowGroupController;
33
+ }>;
34
+
35
+ export interface GroupsLayerOptions extends LayerOptions {
36
+ groupBoxStyle?: (groupController: FlowGroupController) => CSSProperties;
37
+ }
38
+
39
+ export type IGroupPluginRegister = (ctx: PluginContext, opts: CreateGroupPluginOptions) => void;
40
+
41
+ export type CreateGroupPluginOptions = GroupsLayerOptions & {
42
+ components?: {
43
+ GroupNode: IGroupNode;
44
+ GroupBoxHeader: IGroupBoxHeader;
45
+ };
46
+ registers?: {
47
+ [key in GroupPluginRegister]?: IGroupPluginRegister | boolean;
48
+ };
49
+ };