@flowgram.ai/free-container-plugin 0.1.8 → 0.1.15

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/dist/esm/index.js CHANGED
@@ -9,350 +9,6 @@ var __decorateClass = (decorators, target, key, kind) => {
9
9
  return result;
10
10
  };
11
11
 
12
- // src/container-node-render/constant.ts
13
- var ContainerNodeRenderKey = "container-node-render-key";
14
-
15
- // src/container-node-render/render.tsx
16
- import React7 from "react";
17
-
18
- // src/container-node-render/components/header/index.tsx
19
- import React from "react";
20
- import { useNodeRender } from "@flowgram.ai/free-layout-core";
21
-
22
- // src/container-node-render/components/header/style.ts
23
- import styled from "styled-components";
24
- var ContainerNodeHeaderStyle = styled.div`
25
- z-index: 0;
26
-
27
- display: flex;
28
- gap: 8px;
29
- align-items: center;
30
- justify-content: flex-start;
31
-
32
- width: 100%;
33
- height: auto;
34
-
35
- border-radius: 8px 8px 0 0;
36
-
37
- .container-node-logo {
38
- position: relative;
39
-
40
- flex-shrink: 0;
41
-
42
- width: 24px;
43
- height: 24px;
44
-
45
- border-radius: 4px;
46
-
47
- &::after {
48
- content: '';
49
-
50
- position: absolute;
51
- top: 0;
52
- left: 0;
53
-
54
- display: block;
55
-
56
- width: 100%;
57
- height: 100%;
58
-
59
- border-radius: 4px;
60
- box-shadow: inset 0 0 0 1px var(--coz-stroke-plus);
61
- }
62
-
63
- > img {
64
- width: 24px;
65
- height: 24px;
66
- border-radius: 4px;
67
- }
68
- }
69
-
70
- .container-node-title {
71
- margin: 0;
72
- padding: 0;
73
-
74
- font-size: 16px;
75
- font-weight: 500;
76
- font-style: normal;
77
- line-height: 22px;
78
- color: var(--coz-fg-primary, rgba(6, 7, 9, 80%));
79
- text-overflow: ellipsis;
80
- }
81
-
82
- .container-node-tooltip {
83
- height: 100%;
84
- }
85
-
86
- .container-node-tooltip-icon {
87
- display: flex;
88
- align-items: center;
89
-
90
- width: 16px;
91
- height: 100%;
92
-
93
- color: #a7a9b0;
94
- }
95
- `;
96
-
97
- // src/container-node-render/components/header/index.tsx
98
- var ContainerNodeHeader = ({ children }) => {
99
- const { startDrag, onFocus, onBlur } = useNodeRender();
100
- return /* @__PURE__ */ React.createElement(
101
- ContainerNodeHeaderStyle,
102
- {
103
- className: "container-node-header",
104
- draggable: true,
105
- onMouseDown: (e) => {
106
- startDrag(e);
107
- },
108
- onFocus,
109
- onBlur
110
- },
111
- children
112
- );
113
- };
114
-
115
- // src/container-node-render/components/background/index.tsx
116
- import React2 from "react";
117
- import { useNodeRender as useNodeRender2 } from "@flowgram.ai/free-layout-core";
118
-
119
- // src/container-node-render/components/background/style.ts
120
- import styled2 from "styled-components";
121
- var ContainerNodeBackgroundStyle = styled2.div`
122
- position: absolute;
123
- inset: 56px 18px 18px;
124
- `;
125
-
126
- // src/container-node-render/components/background/index.tsx
127
- var ContainerNodeBackground = () => {
128
- const { node } = useNodeRender2();
129
- return /* @__PURE__ */ React2.createElement(
130
- ContainerNodeBackgroundStyle,
131
- {
132
- className: "container-node-background",
133
- "data-flow-editor-selectable": "true"
134
- },
135
- /* @__PURE__ */ React2.createElement("svg", { width: "100%", height: "100%" }, /* @__PURE__ */ React2.createElement(
136
- "pattern",
137
- {
138
- id: "container-node-dot-pattern",
139
- width: "20",
140
- height: "20",
141
- patternUnits: "userSpaceOnUse"
142
- },
143
- /* @__PURE__ */ React2.createElement("circle", { cx: "1", cy: "1", r: "1", stroke: "#eceeef", fillOpacity: "0.5" })
144
- ), /* @__PURE__ */ React2.createElement(
145
- "rect",
146
- {
147
- width: "100%",
148
- height: "100%",
149
- fill: "url(#container-node-dot-pattern)",
150
- "data-node-panel-container": node.id
151
- }
152
- ))
153
- );
154
- };
155
-
156
- // src/container-node-render/components/container/index.tsx
157
- import React3, { useEffect, useState } from "react";
158
- import { useNodeRender as useNodeRender4, WorkflowNodePortsData } from "@flowgram.ai/free-layout-core";
159
- import { FlowNodeTransformData } from "@flowgram.ai/document";
160
-
161
- // src/container-node-render/hooks/use-render-props.ts
162
- import { useNodeRender as useNodeRender3 } from "@flowgram.ai/free-layout-core";
163
- var useContainerNodeRenderProps = () => {
164
- const { node } = useNodeRender3();
165
- const nodeMeta = node.getNodeMeta();
166
- const {
167
- title = "",
168
- tooltip,
169
- renderPorts = [],
170
- style = {}
171
- } = nodeMeta?.renderContainerNode?.() ?? {};
172
- return {
173
- title,
174
- tooltip,
175
- renderPorts,
176
- style
177
- };
178
- };
179
-
180
- // src/container-node-render/components/container/style.ts
181
- import styled3 from "styled-components";
182
- var ContainerNodeContainerStyle = styled3.div`
183
- display: flex;
184
- align-items: flex-start;
185
-
186
- box-sizing: border-box;
187
- min-width: 400px;
188
- min-height: 300px;
189
-
190
- background-color: #f2f3f5;
191
- border-radius: 8px;
192
- outline: 1px solid var(--coz-stroke-plus, rgba(6, 7, 9, 15%));
193
-
194
- .container-node-container-selected {
195
- outline: 1px solid var(--coz-stroke-hglt, #4e40e5);
196
- }
197
- `;
198
-
199
- // src/container-node-render/components/container/index.tsx
200
- var ContainerNodeContainer = ({ children }) => {
201
- const { node, selected, selectNode, nodeRef } = useNodeRender4();
202
- const nodeMeta = node.getNodeMeta();
203
- const { size = { width: 300, height: 200 } } = nodeMeta;
204
- const { style = {} } = useContainerNodeRenderProps();
205
- const transform = node.getData(FlowNodeTransformData);
206
- const [width, setWidth] = useState(size.width);
207
- const [height, setHeight] = useState(size.height);
208
- const updatePorts = () => {
209
- const portsData = node.getData(WorkflowNodePortsData);
210
- portsData.updateDynamicPorts();
211
- };
212
- const updateSize = () => {
213
- if (node.blocks.length === 0) {
214
- setWidth(size.width);
215
- setHeight(size.height);
216
- return;
217
- }
218
- setWidth(transform.bounds.width);
219
- setHeight(transform.bounds.height);
220
- };
221
- useEffect(() => {
222
- const dispose = transform.onDataChange(() => {
223
- updateSize();
224
- updatePorts();
225
- });
226
- return () => dispose.dispose();
227
- }, [transform, width, height]);
228
- useEffect(() => {
229
- updateSize();
230
- }, []);
231
- return /* @__PURE__ */ React3.createElement(
232
- ContainerNodeContainerStyle,
233
- {
234
- className: "container-node-container",
235
- style: {
236
- width,
237
- height,
238
- outline: selected ? "1px solid var(--coz-stroke-hglt, #4E40E5)" : "",
239
- ...style
240
- },
241
- ref: nodeRef,
242
- "data-node-selected": String(selected),
243
- onMouseDown: selectNode,
244
- onClick: (e) => {
245
- selectNode(e);
246
- }
247
- },
248
- children
249
- );
250
- };
251
-
252
- // src/container-node-render/components/border/index.tsx
253
- import React4 from "react";
254
- import { useNodeRender as useNodeRender5 } from "@flowgram.ai/free-layout-core";
255
- import { FlowNodeTransformData as FlowNodeTransformData2 } from "@flowgram.ai/document";
256
-
257
- // src/container-node-render/components/border/style.ts
258
- import styled4 from "styled-components";
259
- var ContainerNodeBorderStyle = styled4.div`
260
- pointer-events: none;
261
-
262
- position: absolute;
263
-
264
- display: flex;
265
- align-items: center;
266
-
267
- width: 100%;
268
- height: 100%;
269
-
270
- background-color: transparent;
271
- border: 1px solid var(--coz-stroke-plus, rgba(6, 7, 9, 15%));
272
- border-color: var(--coz-bg-plus, rgb(249, 249, 249));
273
- border-style: solid;
274
- border-width: 8px;
275
- border-radius: 8px;
276
- box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 4%), 0 4px 12px 0 rgba(0, 0, 0, 2%);
277
-
278
- &::before {
279
- content: '';
280
-
281
- position: absolute;
282
- z-index: 0;
283
- inset: -4px;
284
-
285
- background-color: transparent;
286
- border-color: var(--coz-bg-plus, rgb(249, 249, 249));
287
- border-style: solid;
288
- border-width: 4px;
289
- border-radius: 8px;
290
- }
291
- `;
292
-
293
- // src/container-node-render/components/border/index.tsx
294
- var ContainerNodeBorder = () => {
295
- const { node } = useNodeRender5();
296
- const transformData = node.getData(FlowNodeTransformData2);
297
- const topWidth = Math.max(transformData.padding.top - 50, 50);
298
- return /* @__PURE__ */ React4.createElement(
299
- ContainerNodeBorderStyle,
300
- {
301
- className: "container-node-border",
302
- style: {
303
- borderTopWidth: topWidth
304
- }
305
- }
306
- );
307
- };
308
-
309
- // src/container-node-render/components/ports/index.tsx
310
- import React5, { useEffect as useEffect2 } from "react";
311
- import { WorkflowPortRender } from "@flowgram.ai/free-lines-plugin";
312
- import { WorkflowNodePortsData as WorkflowNodePortsData2, useNodeRender as useNodeRender6 } from "@flowgram.ai/free-layout-core";
313
- var ContainerNodePorts = () => {
314
- const { node, ports } = useNodeRender6();
315
- const { renderPorts } = useContainerNodeRenderProps();
316
- useEffect2(() => {
317
- const portsData = node.getData(WorkflowNodePortsData2);
318
- portsData.updateDynamicPorts();
319
- }, [node]);
320
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, renderPorts.map((p) => /* @__PURE__ */ React5.createElement(
321
- "div",
322
- {
323
- key: `canvas-port${p.id}`,
324
- className: "container-node-port",
325
- "data-port-id": p.id,
326
- "data-port-type": p.type,
327
- style: p.style
328
- }
329
- )), ports.map((p) => /* @__PURE__ */ React5.createElement(WorkflowPortRender, { key: p.id, entity: p })));
330
- };
331
-
332
- // src/container-node-render/components/form/index.tsx
333
- import React6 from "react";
334
- import { useNodeRender as useNodeRender7 } from "@flowgram.ai/free-layout-core";
335
-
336
- // src/container-node-render/components/form/style.ts
337
- import styled5 from "styled-components";
338
- var ContainerNodeFormStyle = styled5.div`
339
- background-color: #fff;
340
- border-radius: 8px 8px 0 0;
341
- width: 100%;
342
- `;
343
-
344
- // src/container-node-render/components/form/index.tsx
345
- var ContainerNodeForm = () => {
346
- const { form } = useNodeRender7();
347
- if (!form) {
348
- return null;
349
- }
350
- return /* @__PURE__ */ React6.createElement(ContainerNodeFormStyle, null, form.render());
351
- };
352
-
353
- // src/container-node-render/render.tsx
354
- var ContainerNodeRender = ({ content }) => /* @__PURE__ */ React7.createElement(ContainerNodeContainer, null, /* @__PURE__ */ React7.createElement(ContainerNodeBackground, null), /* @__PURE__ */ React7.createElement(ContainerNodeBorder, null), /* @__PURE__ */ React7.createElement(ContainerNodeHeader, null, content), /* @__PURE__ */ React7.createElement(ContainerNodePorts, null));
355
-
356
12
  // src/node-into-container/constant.ts
357
13
  var NodeIntoContainerType = /* @__PURE__ */ ((NodeIntoContainerType2) => {
358
14
  NodeIntoContainerType2["In"] = "in";
@@ -376,7 +32,7 @@ import {
376
32
  WorkflowSelectService
377
33
  } from "@flowgram.ai/free-layout-core";
378
34
  import { HistoryService } from "@flowgram.ai/free-history-plugin";
379
- import { FlowNodeTransformData as FlowNodeTransformData3, FlowNodeRenderData } from "@flowgram.ai/document";
35
+ import { FlowNodeTransformData, FlowNodeRenderData } from "@flowgram.ai/document";
380
36
  import { PlaygroundConfigEntity, TransformData } from "@flowgram.ai/core";
381
37
  var NodeIntoContainerService = class {
382
38
  constructor() {
@@ -440,6 +96,13 @@ var NodeIntoContainerService = class {
440
96
  if (!parentNode || !containerNode || !this.isContainer(parentNode)) {
441
97
  return false;
442
98
  }
99
+ const canDrop = this.dragService.canDropToNode({
100
+ dragNodeType: node.flowNodeType,
101
+ dropNode: containerNode
102
+ });
103
+ if (!canDrop.allowDrop) {
104
+ return false;
105
+ }
443
106
  return true;
444
107
  }
445
108
  /** 初始化状态 */
@@ -555,7 +218,7 @@ var NodeIntoContainerService = class {
555
218
  const renderData2 = this.state.dropNode.getData(FlowNodeRenderData);
556
219
  const renderDom2 = renderData2.node?.children?.[0];
557
220
  if (renderDom2) {
558
- renderDom2.style.outline = "";
221
+ renderDom2.classList.remove("selected");
559
222
  }
560
223
  }
561
224
  this.state.dropNode = dropNode;
@@ -565,12 +228,12 @@ var NodeIntoContainerService = class {
565
228
  const renderData = dropNode.getData(FlowNodeRenderData);
566
229
  const renderDom = renderData.node?.children?.[0];
567
230
  if (renderDom) {
568
- renderDom.style.outline = "1px solid var(--coz-stroke-hglt,#4e40e5)";
231
+ renderDom.classList.add("selected");
569
232
  }
570
233
  }
571
234
  /** 获取容器节点transforms */
572
235
  getContainerTransforms() {
573
- return this.document.getRenderDatas(FlowNodeTransformData3, false).filter((transform) => {
236
+ return this.document.getRenderDatas(FlowNodeTransformData, false).filter((transform) => {
574
237
  const { entity } = transform;
575
238
  if (entity.originParent) {
576
239
  return entity.getNodeMeta().selectable && entity.originParent.getNodeMeta().selectable;
@@ -679,9 +342,169 @@ NodeIntoContainerService = __decorateClass([
679
342
  injectable()
680
343
  ], NodeIntoContainerService);
681
344
 
345
+ // src/sub-canvas/hooks/use-node-size.ts
346
+ import { useState, useEffect } from "react";
347
+ import {
348
+ useCurrentEntity,
349
+ WorkflowNodePortsData
350
+ } from "@flowgram.ai/free-layout-core";
351
+ import { FlowNodeTransformData as FlowNodeTransformData2 } from "@flowgram.ai/document";
352
+ var useNodeSize = () => {
353
+ const node = useCurrentEntity();
354
+ const nodeMeta = node.getNodeMeta();
355
+ const { size = { width: 300, height: 200 }, isContainer } = nodeMeta;
356
+ const transform = node.getData(FlowNodeTransformData2);
357
+ const [width, setWidth] = useState(size.width);
358
+ const [height, setHeight] = useState(size.height);
359
+ const updatePorts = () => {
360
+ const portsData = node.getData(WorkflowNodePortsData);
361
+ portsData.updateDynamicPorts();
362
+ };
363
+ const updateSize = () => {
364
+ if (node.blocks.length === 0) {
365
+ setWidth(size.width);
366
+ setHeight(size.height);
367
+ return;
368
+ }
369
+ setWidth(transform.bounds.width);
370
+ setHeight(transform.bounds.height);
371
+ };
372
+ useEffect(() => {
373
+ const dispose = transform.onDataChange(() => {
374
+ updateSize();
375
+ updatePorts();
376
+ });
377
+ return () => dispose.dispose();
378
+ }, [transform, width, height]);
379
+ useEffect(() => {
380
+ updateSize();
381
+ }, []);
382
+ if (!isContainer) {
383
+ return;
384
+ }
385
+ return {
386
+ width,
387
+ height
388
+ };
389
+ };
390
+
391
+ // src/sub-canvas/components/background/index.tsx
392
+ import React from "react";
393
+ import { useCurrentEntity as useCurrentEntity2 } from "@flowgram.ai/free-layout-core";
394
+
395
+ // src/sub-canvas/components/background/style.ts
396
+ import styled from "styled-components";
397
+ var SubCanvasBackgroundStyle = styled.div`
398
+ width: 100%;
399
+ height: 100%;
400
+ inset: 56px 18px 18px;
401
+ background-color: #f2f3f5;
402
+ `;
403
+
404
+ // src/sub-canvas/components/background/index.tsx
405
+ var SubCanvasBackground = () => {
406
+ const node = useCurrentEntity2();
407
+ return /* @__PURE__ */ React.createElement(SubCanvasBackgroundStyle, { className: "sub-canvas-background", "data-flow-editor-selectable": "true" }, /* @__PURE__ */ React.createElement("svg", { width: "100%", height: "100%" }, /* @__PURE__ */ React.createElement("pattern", { id: "sub-canvas-dot-pattern", width: "20", height: "20", patternUnits: "userSpaceOnUse" }, /* @__PURE__ */ React.createElement("circle", { cx: "1", cy: "1", r: "1", stroke: "#eceeef", fillOpacity: "0.5" })), /* @__PURE__ */ React.createElement(
408
+ "rect",
409
+ {
410
+ width: "100%",
411
+ height: "100%",
412
+ fill: "url(#sub-canvas-dot-pattern)",
413
+ "data-node-panel-container": node.id
414
+ }
415
+ )));
416
+ };
417
+
418
+ // src/sub-canvas/components/border/index.tsx
419
+ import React2 from "react";
420
+
421
+ // src/sub-canvas/components/border/style.ts
422
+ import styled2 from "styled-components";
423
+ var SubCanvasBorderStyle = styled2.div`
424
+ pointer-events: none;
425
+
426
+ position: relative;
427
+
428
+ display: flex;
429
+ align-items: center;
430
+
431
+ width: 100%;
432
+ height: 100%;
433
+
434
+ background-color: transparent;
435
+ border: 1px solid var(--coz-stroke-plus, rgba(6, 7, 9, 15%));
436
+ border-color: var(--coz-bg-plus, rgb(249, 249, 249));
437
+ border-style: solid;
438
+ border-width: 8px;
439
+ border-radius: 8px;
440
+
441
+ &::before {
442
+ content: '';
443
+
444
+ position: absolute;
445
+ z-index: 0;
446
+ inset: -4px;
447
+
448
+ background-color: transparent;
449
+ border-color: var(--coz-bg-plus, rgb(249, 249, 249));
450
+ border-style: solid;
451
+ border-width: 4px;
452
+ border-radius: 8px;
453
+ }
454
+ `;
455
+
456
+ // src/sub-canvas/components/border/index.tsx
457
+ var SubCanvasBorder = ({ style, children }) => /* @__PURE__ */ React2.createElement(
458
+ SubCanvasBorderStyle,
459
+ {
460
+ className: "sub-canvas-border",
461
+ style: {
462
+ ...style
463
+ }
464
+ },
465
+ children
466
+ );
467
+
468
+ // src/sub-canvas/components/render/index.tsx
469
+ import React3, { useLayoutEffect } from "react";
470
+ import { useCurrentEntity as useCurrentEntity3 } from "@flowgram.ai/free-layout-core";
471
+
472
+ // src/sub-canvas/components/render/style.ts
473
+ import styled3 from "styled-components";
474
+ var SubCanvasRenderStyle = styled3.div`
475
+ width: 100%;
476
+ height: 100%;
477
+ `;
478
+
479
+ // src/sub-canvas/components/render/index.tsx
480
+ var SubCanvasRender = ({ className, style }) => {
481
+ const node = useCurrentEntity3();
482
+ const nodeSize = useNodeSize();
483
+ const { height, width } = nodeSize ?? {};
484
+ const nodeHeight = nodeSize?.height ?? 0;
485
+ const { padding } = node.transform;
486
+ useLayoutEffect(() => {
487
+ node.renderData.node.style.width = width + "px";
488
+ node.renderData.node.style.height = height + "px";
489
+ }, [height, width]);
490
+ return /* @__PURE__ */ React3.createElement(
491
+ SubCanvasRenderStyle,
492
+ {
493
+ className: `sub-canvas-render ${className ?? ""}`,
494
+ style: {
495
+ height: nodeHeight - padding.top,
496
+ ...style
497
+ },
498
+ "data-flow-editor-selectable": "true",
499
+ onDragStart: (e) => {
500
+ e.stopPropagation();
501
+ }
502
+ },
503
+ /* @__PURE__ */ React3.createElement(SubCanvasBorder, null, /* @__PURE__ */ React3.createElement(SubCanvasBackground, null))
504
+ );
505
+ };
506
+
682
507
  // src/plugin.tsx
683
- import React8 from "react";
684
- import { FlowRendererRegistry } from "@flowgram.ai/renderer";
685
508
  import { definePluginCreator } from "@flowgram.ai/core";
686
509
  var createContainerNodePlugin = definePluginCreator({
687
510
  onBind: ({ bind }) => {
@@ -689,8 +512,6 @@ var createContainerNodePlugin = definePluginCreator({
689
512
  },
690
513
  onInit(ctx, options) {
691
514
  ctx.get(NodeIntoContainerService).init();
692
- const registry = ctx.get(FlowRendererRegistry);
693
- registry.registerReactComponent(ContainerNodeRenderKey, (props) => /* @__PURE__ */ React8.createElement(ContainerNodeRender, { ...props, content: options.renderContent }));
694
515
  },
695
516
  onReady(ctx, options) {
696
517
  if (options.disableNodeIntoContainer !== true) {
@@ -702,16 +523,12 @@ var createContainerNodePlugin = definePluginCreator({
702
523
  }
703
524
  });
704
525
  export {
705
- ContainerNodeBackground,
706
- ContainerNodeBorder,
707
- ContainerNodeContainer,
708
- ContainerNodeForm,
709
- ContainerNodeHeader,
710
- ContainerNodePorts,
711
- ContainerNodeRender,
712
- ContainerNodeRenderKey,
713
526
  NodeIntoContainerService,
714
527
  NodeIntoContainerType,
715
- createContainerNodePlugin
528
+ SubCanvasBackground,
529
+ SubCanvasBorder,
530
+ SubCanvasRender,
531
+ createContainerNodePlugin,
532
+ useNodeSize
716
533
  };
717
534
  //# sourceMappingURL=index.js.map