@logicflow/vue-node-registry 1.2.0-alpha.7 → 1.2.1

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/src/registry.ts DELETED
@@ -1,43 +0,0 @@
1
- import LogicFlow from '@logicflow/core'
2
- import { VueNodeView } from './view'
3
- import { VueNodeModel } from './model'
4
-
5
- import RegisterConfig = LogicFlow.RegisterConfig
6
-
7
- export type VueNodeConfig = {
8
- type: string
9
- component: any
10
- effect?: (keyof LogicFlow.PropertiesType)[]
11
- } & Partial<RegisterConfig>
12
-
13
- export const vueNodesMap: Record<
14
- string,
15
- {
16
- component: any
17
- effect?: (keyof LogicFlow.PropertiesType)[]
18
- }
19
- > = {}
20
-
21
- export function register(config: VueNodeConfig, lf: LogicFlow) {
22
- const {
23
- type,
24
- component,
25
- effect,
26
- view: CustomNodeView,
27
- model: CustomNodeModel,
28
- } = config
29
-
30
- if (!type) {
31
- throw new Error('You should specify type in config')
32
- }
33
- vueNodesMap[type] = {
34
- component,
35
- effect,
36
- }
37
-
38
- lf.register({
39
- type,
40
- view: CustomNodeView || VueNodeView,
41
- model: CustomNodeModel || VueNodeModel,
42
- })
43
- }
@@ -1,140 +0,0 @@
1
- .lf-vue-node-container {
2
- position: relative;
3
- display: flex;
4
- flex-direction: column;
5
- box-sizing: border-box;
6
- padding: 6px;
7
- color: #474747;
8
- border-radius: 12px;
9
- box-shadow: 0 0 10px #cad2e15f;
10
- }
11
-
12
- .lf-vue-node-content-wrap {
13
- display: flex;
14
- flex: 1 1 auto;
15
- justify-content: center;
16
- }
17
-
18
- .lf-vue-node-title {
19
- display: flex;
20
- align-items: flex-start;
21
- justify-content: space-between;
22
- box-sizing: border-box;
23
- margin-bottom: 4px;
24
- padding: 0 8px;
25
- backdrop-filter: saturate(180%) blur(4px);
26
-
27
- &-expanded {
28
- margin-bottom: 6px;
29
- padding-bottom: 8px;
30
- border-bottom: 1px solid #eaeaea;
31
- }
32
- }
33
-
34
- @supports not (backdrop-filter: blur(1px)) {
35
- .lf-vue-node-title {
36
- backdrop-filter: none;
37
- }
38
- }
39
-
40
- .lf-vue-node-title-left {
41
- display: flex;
42
- gap: 6px;
43
- align-items: center;
44
- min-width: 0;
45
- }
46
-
47
- .lf-vue-node-title-icon {
48
- display: inline-block;
49
- width: 16px;
50
- height: 16px;
51
- color: #666;
52
- font-style: normal;
53
- line-height: 16px;
54
- text-align: center;
55
- }
56
-
57
- .lf-vue-node-title-text {
58
- overflow: hidden;
59
- color: #333;
60
- font-weight: 500;
61
- font-size: 14px;
62
- white-space: nowrap;
63
- text-overflow: ellipsis;
64
- }
65
-
66
- .lf-vue-node-title-actions {
67
- display: flex;
68
- gap: 6px;
69
- align-items: center;
70
- }
71
-
72
- .lf-vue-node-title-expand,
73
- .lf-vue-node-title-more {
74
- display: inline-flex;
75
- align-items: center;
76
- justify-content: center;
77
- width: 20px;
78
- height: 20px;
79
- padding: 2px;
80
- background: transparent;
81
- border: none;
82
- border-radius: 4px;
83
- cursor: pointer;
84
- transition: background 0.15s ease;
85
- appearance: none;
86
- }
87
-
88
- .lf-vue-node-title-expand:hover,
89
- .lf-vue-node-title-more:hover {
90
- background: rgb(0 0 0 / 6%);
91
- }
92
-
93
- .lf-vue-node-title-expand-icon {
94
- color: #666;
95
- font-style: normal;
96
- transition: transform 0.3s ease;
97
- }
98
-
99
- .lf-vue-node-title-more-icon {
100
- color: #666;
101
- font-style: normal;
102
- }
103
-
104
- .lf-vue-node-title-tooltip {
105
- position: absolute;
106
- top: -50px;
107
- right: -135px;
108
- min-width: 120px;
109
- max-width: 240px;
110
- padding: 6px 8px;
111
- background: #fff;
112
- border: 1px solid rgb(0 0 0 / 10%);
113
- border-radius: 6px;
114
- box-shadow: 0 6px 20px rgb(0 0 0 / 12%);
115
- transform: translateY(calc(100% + 4px));
116
- transition:
117
- opacity 0.15s ease,
118
- transform 0.15s ease;
119
- }
120
-
121
- .lf-vue-node-title-tooltip-list {
122
- display: flex;
123
- flex-direction: column;
124
- gap: 4px;
125
- }
126
-
127
- .lf-vue-node-title-tooltip-item {
128
- display: flex;
129
- align-items: center;
130
- justify-content: flex-start;
131
- padding: 6px;
132
- color: #333;
133
- font-size: 12px;
134
- border-radius: 4px;
135
- cursor: pointer;
136
- }
137
-
138
- .lf-vue-node-title-tooltip-item:hover {
139
- background: rgb(0 0 0 / 5%);
140
- }
package/src/style/raw.ts DELETED
@@ -1,129 +0,0 @@
1
- /* eslint-disable */
2
-
3
- /**
4
- * Auto generated file, do not modify it!
5
- */
6
-
7
- export const content = `.lf-vue-node-container {
8
- position: relative;
9
- display: flex;
10
- flex-direction: column;
11
- box-sizing: border-box;
12
- padding: 6px;
13
- color: #474747;
14
- border-radius: 12px;
15
- box-shadow: 0 0 10px #cad2e15f;
16
- }
17
- .lf-vue-node-content-wrap {
18
- display: flex;
19
- flex: 1 1 auto;
20
- justify-content: center;
21
- }
22
- .lf-vue-node-title {
23
- display: flex;
24
- align-items: flex-start;
25
- justify-content: space-between;
26
- box-sizing: border-box;
27
- margin-bottom: 4px;
28
- padding: 0 8px;
29
- backdrop-filter: saturate(180%) blur(4px);
30
- }
31
- .lf-vue-node-title-expanded {
32
- margin-bottom: 6px;
33
- padding-bottom: 8px;
34
- border-bottom: 1px solid #eaeaea;
35
- }
36
- @supports not (backdrop-filter: blur(1px)) {
37
- .lf-vue-node-title {
38
- backdrop-filter: none;
39
- }
40
- }
41
- .lf-vue-node-title-left {
42
- display: flex;
43
- gap: 6px;
44
- align-items: center;
45
- min-width: 0;
46
- }
47
- .lf-vue-node-title-icon {
48
- display: inline-block;
49
- width: 16px;
50
- height: 16px;
51
- color: #666;
52
- font-style: normal;
53
- line-height: 16px;
54
- text-align: center;
55
- }
56
- .lf-vue-node-title-text {
57
- overflow: hidden;
58
- color: #333;
59
- font-weight: 500;
60
- font-size: 14px;
61
- white-space: nowrap;
62
- text-overflow: ellipsis;
63
- }
64
- .lf-vue-node-title-actions {
65
- display: flex;
66
- gap: 6px;
67
- align-items: center;
68
- }
69
- .lf-vue-node-title-expand,
70
- .lf-vue-node-title-more {
71
- display: inline-flex;
72
- align-items: center;
73
- justify-content: center;
74
- width: 20px;
75
- height: 20px;
76
- padding: 2px;
77
- background: transparent;
78
- border: none;
79
- border-radius: 4px;
80
- cursor: pointer;
81
- transition: background 0.15s ease;
82
- appearance: none;
83
- }
84
- .lf-vue-node-title-expand:hover,
85
- .lf-vue-node-title-more:hover {
86
- background: rgba(0, 0, 0, 0.06);
87
- }
88
- .lf-vue-node-title-expand-icon {
89
- color: #666;
90
- font-style: normal;
91
- transition: transform 0.3s ease;
92
- }
93
- .lf-vue-node-title-more-icon {
94
- color: #666;
95
- font-style: normal;
96
- }
97
- .lf-vue-node-title-tooltip {
98
- position: absolute;
99
- top: -50px;
100
- right: -135px;
101
- min-width: 120px;
102
- max-width: 240px;
103
- padding: 6px 8px;
104
- background: #fff;
105
- border: 1px solid rgba(0, 0, 0, 0.1);
106
- border-radius: 6px;
107
- box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
108
- transform: translateY(calc(100% + 4px));
109
- transition: opacity 0.15s ease, transform 0.15s ease;
110
- }
111
- .lf-vue-node-title-tooltip-list {
112
- display: flex;
113
- flex-direction: column;
114
- gap: 4px;
115
- }
116
- .lf-vue-node-title-tooltip-item {
117
- display: flex;
118
- align-items: center;
119
- justify-content: flex-start;
120
- padding: 6px;
121
- color: #333;
122
- font-size: 12px;
123
- border-radius: 4px;
124
- cursor: pointer;
125
- }
126
- .lf-vue-node-title-tooltip-item:hover {
127
- background: rgba(0, 0, 0, 0.05);
128
- }
129
- `
package/src/teleport.ts DELETED
@@ -1,155 +0,0 @@
1
- import { BaseNodeModel, GraphModel } from '@logicflow/core'
2
- import {
3
- defineComponent,
4
- h,
5
- createApp,
6
- reactive,
7
- isVue3,
8
- Teleport,
9
- markRaw,
10
- Fragment,
11
- } from 'vue-demi'
12
-
13
- let active = false
14
- const appInstances = new Map<string, InstanceType<any>>()
15
- const appNodesMap = new Map<string, any>() // 用于储存当前流程图节点id当节点都销毁时同时卸载vueApp实例
16
- const items = reactive<{ [key: string]: any }>({})
17
-
18
- export function connect(
19
- id: string,
20
- component: any,
21
- container: HTMLDivElement,
22
- node: BaseNodeModel,
23
- graph: GraphModel,
24
- ) {
25
- if (active) {
26
- if (graph.isMiniMap) {
27
- createTeleportContainer(container, graph.flowId)
28
- }
29
- items[id] = markRaw(
30
- defineComponent({
31
- render: () =>
32
- h(Teleport, { to: container } as any, [
33
- h(component, { node, graph }),
34
- ]),
35
- provide: () => ({
36
- getNode: () => node,
37
- getGraph: () => graph,
38
- }),
39
- }),
40
- )
41
- }
42
- }
43
-
44
- export function disconnect(id: string, flowId: string) {
45
- if (active) {
46
- delete items[id]
47
- if (appInstances.has(flowId)) {
48
- const appNodeList = appNodesMap.get(flowId) || []
49
- const index = appNodeList.indexOf(id)
50
- if (index > -1) {
51
- appNodeList.splice(index, 1)
52
- if (appNodeList.length === 0) {
53
- destroyTeleportContainer(flowId)
54
- } else {
55
- appNodesMap.set(flowId, appNodeList)
56
- }
57
- }
58
- }
59
- }
60
- }
61
-
62
- export function isActive() {
63
- return active
64
- }
65
-
66
- export function getTeleport(): any {
67
- if (!isVue3) {
68
- throw new Error('teleport is only available in Vue3')
69
- }
70
- active = true
71
-
72
- return defineComponent({
73
- props: {
74
- flowId: {
75
- type: String,
76
- required: true,
77
- },
78
- },
79
- setup(props) {
80
- return () => {
81
- const children: Record<string, any>[] = []
82
- Object.keys(items).forEach((id) => {
83
- // https://github.com/didi/LogicFlow/issues/1768
84
- // 多个不同的VueNodeView都会connect注册到items中,因此items存储了可能有多个flowId流程图的数据
85
- // 当使用多个LogicFlow时,会创建多个flowId + 同时使用KeepAlive
86
- // 每一次items改变,会触发不同flowId持有的setup()执行,由于每次setup()执行就是遍历items,因此存在多次重复渲染元素的问题
87
- // 即items[0]会在Page1的setup()执行,items[0]也会在Page2的setup()执行,从而生成两个items[0]
88
-
89
- // 比对当前界面显示的flowId,只更新items[当前页面flowId:nodeId]的数据
90
- // 比如items[0]属于Page1的数据,那么Page2无论active=true/false,都无法执行items[0]
91
-
92
- if (id.startsWith(props.flowId)) {
93
- if (appInstances.has(props.flowId)) {
94
- const appNodeList = appNodesMap.get(props.flowId) || []
95
- if (!appNodeList.includes(id)) {
96
- appNodeList.push(id)
97
- appNodesMap.set(props.flowId, appNodeList)
98
- }
99
- }
100
- children.push(items[id])
101
- }
102
- })
103
- return h(
104
- Fragment,
105
- {},
106
- children.map((item) => h(item)),
107
- )
108
- }
109
- },
110
- })
111
- }
112
-
113
- /**
114
- * 创建并挂载 Teleport 容器组件
115
- * @param container 目标容器元素
116
- * @param flowId 当前流程图的唯一标识
117
- */
118
- export function createTeleportContainer(
119
- container: HTMLElement,
120
- flowId: string | undefined,
121
- ): void {
122
- if (!isVue3 || !flowId || !container || !active) return
123
-
124
- // 获取 Teleport 组件
125
- const TeleportContainer = getTeleport()
126
-
127
- // 不重新创建 Teleport 容器组件
128
- if (appInstances.has(flowId)) {
129
- return
130
- }
131
-
132
- // ✅ 1. 创建独立容器放到目标容器中
133
- const mountPoint = document.createElement('div')
134
- container.appendChild(mountPoint)
135
-
136
- // ✅ 2. 创建并挂载 Vue 应用到新容器
137
- const app = createApp(TeleportContainer, { flowId })
138
- app.mount(mountPoint)
139
-
140
- appInstances.set(flowId, app)
141
- appNodesMap.set(flowId, [])
142
- }
143
- /**
144
- * 卸载 Teleport 容器组件
145
- * @param flowId 需要卸载流程图的唯一标识
146
- */
147
- export function destroyTeleportContainer(flowId: string | undefined): void {
148
- if (!isVue3 || !flowId || !active) return
149
- const app = appInstances.get(flowId)
150
- if (app) {
151
- app.unmount()
152
- appInstances.delete(flowId)
153
- appNodesMap.delete(flowId)
154
- }
155
- }
package/src/utils/size.ts DELETED
@@ -1,22 +0,0 @@
1
- export function computeBaseHeight(
2
- measuredHeight: number,
3
- _showTitle?: boolean,
4
- _titleHeight?: number,
5
- ) {
6
- const extra = _showTitle
7
- ? typeof _titleHeight === 'number'
8
- ? _titleHeight
9
- : 28
10
- : 0
11
- return Math.max(1, Math.round(measuredHeight) - extra)
12
- }
13
-
14
- export function shouldUpdateSize(
15
- prevW?: number,
16
- prevH?: number,
17
- w?: number,
18
- h?: number,
19
- ) {
20
- if (!w || !h) return false
21
- return !(prevW === Math.round(w) && prevH === Math.round(h))
22
- }