@arronqzy/react-blueprint 1.0.18 → 1.0.21

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.
Files changed (43) hide show
  1. package/README.md +36 -26
  2. package/dist/blueprint.css +336 -54
  3. package/index.ts +23 -0
  4. package/package.json +5 -5
  5. package/src/BlueprintContextMenu.tsx +1 -1
  6. package/src/BlueprintNodeConfigSidebar.tsx +10 -2
  7. package/src/blueprint.css +336 -54
  8. package/src/components/ApiCollectionManagerDialog.tsx +448 -0
  9. package/src/components/BlueprintExecutionLogPanel.tsx +10 -2
  10. package/src/components/BlueprintLibrarySelect.tsx +1 -1
  11. package/src/components/BlueprintMetaDialog.tsx +1 -1
  12. package/src/components/BlueprintNodeSwitchTaskDialog.tsx +1 -1
  13. package/src/components/BlueprintPanelToolbar.tsx +10 -2
  14. package/src/components/ClockNodeConfigPanel.tsx +1 -1
  15. package/src/components/ConfigHintIcon.tsx +1 -1
  16. package/src/components/FetchNodeConfigPanel.tsx +314 -3
  17. package/src/components/FetchUrlAutocomplete.tsx +1 -1
  18. package/src/components/JsonLintTextarea.tsx +97 -0
  19. package/src/components/JsonNodeConfigPanel.tsx +14 -7
  20. package/src/components/LogicNodeConfigPanel.tsx +1 -1
  21. package/src/components/ScopeTemplateAutocompleteHost.tsx +4 -8
  22. package/src/components/StorageKeyAutocomplete.tsx +1 -1
  23. package/src/components/StorageNodeConfigPanel.tsx +1 -1
  24. package/src/components/ViewElementMultiSelect.tsx +1 -1
  25. package/src/edges/BlueprintSmoothEdge.tsx +2 -2
  26. package/src/graph/blueprint-graph.ts +9 -0
  27. package/src/graph/document.ts +12 -0
  28. package/src/graph/sync-edges.ts +2 -2
  29. package/src/hooks/useBlueprintFlowState.ts +1 -1
  30. package/src/index.tsx +41 -28
  31. package/src/library/api-collection-db.ts +98 -0
  32. package/src/library/api-collection-store.ts +139 -0
  33. package/src/nodes/AndFlowNode.tsx +4 -3
  34. package/src/nodes/BlueprintFlowNode.tsx +8 -3
  35. package/src/nodes/BlueprintNodeCard.tsx +137 -121
  36. package/src/nodes/BlueprintNodeShell.tsx +2 -1
  37. package/src/nodes/ClockFlowNode.tsx +1 -1
  38. package/src/nodes/EventFlowNode.tsx +1 -1
  39. package/src/nodes/FetchFlowNode.tsx +1 -1
  40. package/src/nodes/JsonFlowNode.tsx +1 -1
  41. package/src/nodes/LifecycleFlowNode.tsx +2 -1
  42. package/src/nodes/LogicFlowNode.tsx +1 -1
  43. package/src/nodes/StorageFlowNode.tsx +1 -1
package/src/blueprint.css CHANGED
@@ -14,13 +14,13 @@
14
14
  .bp-flow.react-flow,
15
15
  [data-workspace-region="blueprint"] .react-flow {
16
16
  --xy-background-color: transparent;
17
- --xy-edge-stroke: #2563eb;
18
- --xy-edge-stroke-width: 2.5;
19
- --xy-edge-stroke-selected: #1d4ed8;
20
- --xy-connectionline-stroke: #2563eb;
21
- --xy-connectionline-stroke-width: 2.5;
22
- --xy-handle-background-color: hsl(var(--primary));
23
- --xy-handle-border-color: hsl(var(--background));
17
+ --xy-edge-stroke: #94a3b8;
18
+ --xy-edge-stroke-width: 1.75;
19
+ --xy-edge-stroke-selected: #64748b;
20
+ --xy-connectionline-stroke: #94a3b8;
21
+ --xy-connectionline-stroke-width: 1.75;
22
+ --xy-handle-background-color: #ffffff;
23
+ --xy-handle-border-color: #94a3b8;
24
24
  background-color: transparent;
25
25
  }
26
26
 
@@ -73,16 +73,16 @@
73
73
  [data-workspace-region="blueprint"] .react-flow__edges path.react-flow__edge-path,
74
74
  [data-workspace-region="blueprint"] .react-flow__edges path.bp-edge-visible {
75
75
  fill: none !important;
76
- stroke: #2563eb !important;
77
- stroke-width: 2.5px !important;
76
+ stroke: #94a3b8 !important;
77
+ stroke-width: 1.75px !important;
78
78
  opacity: 1 !important;
79
79
  }
80
80
 
81
81
  .bp-canvas .react-flow__edge.selected path.react-flow__edge-path,
82
82
  .bp-flow .react-flow__edge.selected path.react-flow__edge-path,
83
83
  [data-workspace-region="blueprint"] .react-flow__edge.selected path.react-flow__edge-path {
84
- stroke: #1d4ed8 !important;
85
- stroke-width: 3px !important;
84
+ stroke: #64748b !important;
85
+ stroke-width: 2.25px !important;
86
86
  }
87
87
 
88
88
  .bp-canvas .react-flow__edge.bp-edge--signal-true path.react-flow__edge-path,
@@ -130,16 +130,16 @@
130
130
  .bp-canvas .react-flow__arrowhead polyline,
131
131
  .bp-flow .react-flow__arrowhead polyline,
132
132
  [data-workspace-region="blueprint"] .react-flow__arrowhead polyline {
133
- stroke: #2563eb;
134
- fill: #2563eb;
133
+ stroke: #94a3b8;
134
+ fill: #94a3b8;
135
135
  }
136
136
 
137
137
  .bp-canvas .react-flow__connection-path,
138
138
  .bp-flow .react-flow__connection-path,
139
139
  [data-workspace-region="blueprint"] .react-flow__connection-path {
140
140
  fill: none !important;
141
- stroke: #2563eb !important;
142
- stroke-width: 2.5px !important;
141
+ stroke: #94a3b8 !important;
142
+ stroke-width: 1.75px !important;
143
143
  }
144
144
 
145
145
  .bp-canvas .react-flow__edge-interaction,
@@ -167,95 +167,115 @@
167
167
  padding: 0;
168
168
  }
169
169
 
170
- /* 连接点:禁止 transform,避免覆盖 React Flow 的 translate(-50%, -50%) 定位 */
170
+ /* 以卡片壳为 handle 定位基准,避免挂到外层导致左右/垂直偏移 */
171
+ .bp-node {
172
+ position: relative;
173
+ display: block;
174
+ width: max-content;
175
+ min-height: 1px;
176
+ }
177
+
178
+ /* 连接点:显式锚定左右中线(勿覆盖 transform 以外的 RF 行为) */
171
179
  .bp-canvas .react-flow__handle.bp-flow-handle,
172
180
  .bp-flow .react-flow__handle.bp-flow-handle,
173
181
  [data-workspace-region="blueprint"] .react-flow__handle.bp-flow-handle {
182
+ position: absolute !important;
174
183
  z-index: 3;
175
- width: 10px;
176
- height: 10px;
177
- min-width: 10px;
178
- min-height: 10px;
179
- border: 2px solid hsl(var(--background)) !important;
184
+ width: 8px;
185
+ height: 8px;
186
+ min-width: 8px;
187
+ min-height: 8px;
188
+ border: 1.5px solid hsl(var(--card)) !important;
180
189
  border-radius: 9999px;
181
- background-color: hsl(var(--foreground) / 0.42) !important;
190
+ background-color: #ffffff !important;
191
+ box-shadow: 0 0 0 1px rgb(148 163 184 / 0.55);
192
+ pointer-events: all !important;
182
193
  transition:
183
194
  background-color 0.15s ease,
184
195
  border-color 0.15s ease,
185
196
  box-shadow 0.15s ease;
186
197
  }
187
198
 
199
+ .bp-node > .react-flow__handle.react-flow__handle-left,
200
+ .bp-node > .react-flow__handle[data-handlepos="left"] {
201
+ top: 50%;
202
+ left: 0;
203
+ right: auto;
204
+ bottom: auto;
205
+ transform: translate(-50%, -50%);
206
+ }
207
+
208
+ .bp-node > .react-flow__handle.react-flow__handle-right,
209
+ .bp-node > .react-flow__handle[data-handlepos="right"] {
210
+ top: 50%;
211
+ right: 0;
212
+ left: auto;
213
+ bottom: auto;
214
+ transform: translate(50%, -50%);
215
+ }
216
+
188
217
  .bp-canvas .react-flow__handle.bp-flow-handle:hover,
189
218
  .bp-flow .react-flow__handle.bp-flow-handle:hover,
190
219
  [data-workspace-region="blueprint"] .react-flow__handle.bp-flow-handle:hover {
191
- background-color: hsl(var(--primary)) !important;
192
- border-color: hsl(var(--background)) !important;
193
- box-shadow: 0 0 0 3px hsl(var(--primary) / 0.28);
220
+ background-color: #ffffff !important;
221
+ border-color: hsl(var(--primary)) !important;
222
+ box-shadow: 0 0 0 3px hsl(var(--primary) / 0.22);
194
223
  }
195
224
 
196
225
  .bp-canvas .react-flow__handle.bp-flow-handle--target,
197
226
  .bp-flow .react-flow__handle.bp-flow-handle--target,
198
227
  [data-workspace-region="blueprint"] .react-flow__handle.bp-flow-handle--target {
199
- background-color: hsl(var(--foreground) / 0.48) !important;
228
+ background-color: #ffffff !important;
200
229
  }
201
230
 
202
231
  .bp-canvas .react-flow__handle.bp-flow-handle--source,
203
232
  .bp-flow .react-flow__handle.bp-flow-handle--source,
204
233
  [data-workspace-region="blueprint"] .react-flow__handle.bp-flow-handle--source {
205
- background-color: hsl(var(--primary) / 0.72) !important;
234
+ background-color: #ffffff !important;
206
235
  }
207
236
 
208
237
  .bp-node--selected .bp-flow-handle {
209
- border-color: hsl(var(--card)) !important;
210
- box-shadow: 0 0 0 2px hsl(var(--primary) / 0.35);
211
- }
212
-
213
- .bp-node--selected .bp-flow-handle--target {
214
- background-color: hsl(var(--foreground) / 0.55) !important;
238
+ border-color: hsl(var(--primary) / 0.55) !important;
239
+ box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
215
240
  }
216
241
 
242
+ .bp-node--selected .bp-flow-handle--target,
217
243
  .bp-node--selected .bp-flow-handle--source {
218
- background-color: hsl(var(--primary)) !important;
244
+ background-color: #ffffff !important;
219
245
  }
220
246
 
221
247
  .bp-node--execution-true .bp-node-card {
222
- border-color: rgb(22 163 74 / 0.65);
248
+ border-color: rgb(22 163 74 / 0.55);
223
249
  box-shadow:
224
- 0 0 0 1px rgb(22 163 74 / 0.35),
225
- 0 4px 14px rgb(22 163 74 / 0.18);
250
+ 0 0 0 1px rgb(22 163 74 / 0.28),
251
+ 0 8px 24px rgb(22 163 74 / 0.14);
226
252
  }
227
253
 
228
254
  .bp-node--execution-true .bp-flow-handle {
229
- border-color: hsl(var(--card));
230
- box-shadow: 0 0 0 2px rgb(22 163 74 / 0.45);
231
- }
232
-
233
- .bp-node--execution-true .bp-flow-handle--source {
234
- background-color: #16a34a !important;
255
+ border-color: rgb(22 163 74 / 0.7) !important;
256
+ box-shadow: 0 0 0 2px rgb(22 163 74 / 0.28);
235
257
  }
236
258
 
259
+ .bp-node--execution-true .bp-flow-handle--source,
237
260
  .bp-node--execution-true .bp-flow-handle--target {
238
- background-color: rgb(22 163 74 / 0.55) !important;
261
+ background-color: #ffffff !important;
239
262
  }
240
263
 
241
264
  .bp-node--execution-false .bp-node-card {
242
- border-color: hsl(var(--destructive) / 0.65);
265
+ border-color: hsl(var(--destructive) / 0.55);
243
266
  box-shadow:
244
- 0 0 0 1px hsl(var(--destructive) / 0.4),
245
- 0 4px 14px hsl(var(--destructive) / 0.16);
267
+ 0 0 0 1px hsl(var(--destructive) / 0.3),
268
+ 0 8px 24px hsl(var(--destructive) / 0.12);
246
269
  }
247
270
 
248
271
  .bp-node--execution-false .bp-flow-handle {
249
- border-color: hsl(var(--card));
250
- box-shadow: 0 0 0 2px hsl(var(--destructive) / 0.4);
251
- }
252
-
253
- .bp-node--execution-false .bp-flow-handle--source {
254
- background-color: hsl(var(--destructive)) !important;
272
+ border-color: hsl(var(--destructive) / 0.65) !important;
273
+ box-shadow: 0 0 0 2px hsl(var(--destructive) / 0.25);
255
274
  }
256
275
 
276
+ .bp-node--execution-false .bp-flow-handle--source,
257
277
  .bp-node--execution-false .bp-flow-handle--target {
258
- background-color: hsl(var(--destructive) / 0.55) !important;
278
+ background-color: #ffffff !important;
259
279
  }
260
280
 
261
281
  /* 生命周期节点无输入口:隐藏任何左侧/目标连接点(含旧数据产生的幽灵 handle) */
@@ -325,3 +345,265 @@
325
345
  margin: 4px 0;
326
346
  background: hsl(var(--border));
327
347
  }
348
+
349
+ /* Soft UI 节点卡片(写入 CSS,避免 Tailwind content 未扫到 react-blueprint) */
350
+ .bp-node-card {
351
+ width: 200px;
352
+ overflow: hidden;
353
+ border-radius: 1rem;
354
+ border: 1px solid hsl(var(--border) / 0.7);
355
+ background: hsl(var(--card));
356
+ color: hsl(var(--card-foreground));
357
+ box-shadow: 0 8px 24px rgb(15 23 42 / 0.08);
358
+ cursor: grab;
359
+ transition:
360
+ box-shadow 0.15s ease,
361
+ border-color 0.15s ease;
362
+ }
363
+
364
+ .bp-node-card:active {
365
+ cursor: grabbing;
366
+ }
367
+
368
+ .bp-node-card.bp-node-card--selected {
369
+ border-color: hsl(var(--primary) / 0.7);
370
+ box-shadow:
371
+ 0 0 0 2px hsl(var(--primary) / 0.35),
372
+ 0 10px 28px hsl(var(--primary) / 0.18);
373
+ }
374
+
375
+ .bp-node-card__body {
376
+ display: flex;
377
+ width: 100%;
378
+ align-items: flex-start;
379
+ padding: 10px 12px;
380
+ border: none;
381
+ background: transparent;
382
+ color: inherit;
383
+ text-align: left;
384
+ cursor: inherit;
385
+ outline: none;
386
+ transition: background-color 0.15s ease;
387
+ }
388
+
389
+ .bp-node-card__body:hover {
390
+ background: hsl(var(--accent) / 0.25);
391
+ }
392
+
393
+ .bp-node-card__body:focus-visible {
394
+ box-shadow: inset 0 0 0 1px hsl(var(--primary));
395
+ }
396
+
397
+ .bp-node-card__content {
398
+ min-width: 0;
399
+ flex: 1;
400
+ }
401
+
402
+ .bp-node-card__title-row {
403
+ display: flex;
404
+ align-items: flex-start;
405
+ gap: 6px;
406
+ }
407
+
408
+ .bp-node-card__title {
409
+ min-width: 0;
410
+ flex: 1;
411
+ overflow: hidden;
412
+ text-overflow: ellipsis;
413
+ white-space: nowrap;
414
+ font-size: 13px;
415
+ font-weight: 600;
416
+ line-height: 1.35;
417
+ color: hsl(var(--foreground));
418
+ }
419
+
420
+ .bp-node-card__meta,
421
+ .bp-node-card__subtitle {
422
+ margin-top: 2px;
423
+ overflow: hidden;
424
+ text-overflow: ellipsis;
425
+ white-space: nowrap;
426
+ line-height: 1.3;
427
+ color: hsl(var(--muted-foreground));
428
+ }
429
+
430
+ .bp-node-card__meta {
431
+ font-size: 11px;
432
+ }
433
+
434
+ .bp-node-card__subtitle {
435
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
436
+ font-size: 10px;
437
+ opacity: 0.85;
438
+ }
439
+
440
+ .bp-node-card__badge {
441
+ flex-shrink: 0;
442
+ border-radius: 6px;
443
+ padding: 2px 6px;
444
+ font-size: 10px;
445
+ font-weight: 600;
446
+ line-height: 1;
447
+ }
448
+
449
+ .bp-node-icon {
450
+ display: flex;
451
+ flex-shrink: 0;
452
+ align-items: center;
453
+ justify-content: center;
454
+ width: 28px;
455
+ height: 28px;
456
+ margin-top: 2px;
457
+ margin-right: 10px;
458
+ border-radius: 8px;
459
+ }
460
+
461
+ .bp-node-icon svg {
462
+ width: 14px;
463
+ height: 14px;
464
+ }
465
+
466
+ .bp-node-icon--blueprint {
467
+ background: hsl(var(--primary) / 0.14);
468
+ color: hsl(var(--primary));
469
+ }
470
+
471
+ .bp-node-icon--view {
472
+ background: rgb(100 116 139 / 0.18);
473
+ color: rgb(71 85 105);
474
+ }
475
+
476
+ .bp-node-icon--logic {
477
+ background: rgb(14 165 233 / 0.15);
478
+ color: rgb(2 132 199);
479
+ }
480
+
481
+ .bp-node-icon--and {
482
+ background: rgb(99 102 241 / 0.15);
483
+ color: rgb(79 70 229);
484
+ }
485
+
486
+ .bp-node-icon--lifecycle {
487
+ background: rgb(245 158 11 / 0.15);
488
+ color: rgb(217 119 6);
489
+ }
490
+
491
+ .bp-node-icon--event {
492
+ background: rgb(217 70 239 / 0.15);
493
+ color: rgb(192 38 211);
494
+ }
495
+
496
+ .bp-node-icon--fetch {
497
+ background: rgb(139 92 246 / 0.15);
498
+ color: rgb(124 58 237);
499
+ }
500
+
501
+ .bp-node-icon--json {
502
+ background: rgb(20 184 166 / 0.15);
503
+ color: rgb(13 148 136);
504
+ }
505
+
506
+ .bp-node-icon--storage {
507
+ background: rgb(16 185 129 / 0.15);
508
+ color: rgb(5 150 105);
509
+ }
510
+
511
+ .bp-node-icon--clock {
512
+ background: rgb(244 63 94 / 0.15);
513
+ color: rgb(225 29 72);
514
+ }
515
+
516
+ .bp-node-card__badge--blueprint {
517
+ background: hsl(var(--primary) / 0.1);
518
+ color: hsl(var(--primary));
519
+ }
520
+
521
+ .bp-node-card__badge--view {
522
+ background: rgb(100 116 139 / 0.12);
523
+ color: rgb(51 65 85);
524
+ }
525
+
526
+ .bp-node-card__badge--logic {
527
+ background: rgb(14 165 233 / 0.1);
528
+ color: rgb(3 105 161);
529
+ }
530
+
531
+ .bp-node-card__badge--and {
532
+ background: rgb(99 102 241 / 0.1);
533
+ color: rgb(67 56 202);
534
+ }
535
+
536
+ .bp-node-card__badge--lifecycle {
537
+ background: rgb(245 158 11 / 0.1);
538
+ color: rgb(180 83 9);
539
+ }
540
+
541
+ .bp-node-card__badge--event {
542
+ background: rgb(217 70 239 / 0.1);
543
+ color: rgb(162 28 175);
544
+ }
545
+
546
+ .bp-node-card__badge--fetch {
547
+ background: rgb(139 92 246 / 0.1);
548
+ color: rgb(109 40 217);
549
+ }
550
+
551
+ .bp-node-card__badge--json {
552
+ background: rgb(20 184 166 / 0.1);
553
+ color: rgb(15 118 110);
554
+ }
555
+
556
+ .bp-node-card__badge--storage {
557
+ background: rgb(16 185 129 / 0.1);
558
+ color: rgb(4 120 87);
559
+ }
560
+
561
+ .bp-node-card__badge--clock {
562
+ background: rgb(244 63 94 / 0.1);
563
+ color: rgb(190 18 60);
564
+ }
565
+
566
+ .dark .bp-node-icon--logic,
567
+ :root.dark .bp-node-icon--logic {
568
+ color: rgb(125 211 252);
569
+ }
570
+
571
+ .dark .bp-node-icon--view,
572
+ :root.dark .bp-node-icon--view {
573
+ color: rgb(203 213 225);
574
+ }
575
+
576
+ .dark .bp-node-icon--and,
577
+ :root.dark .bp-node-icon--and {
578
+ color: rgb(165 180 252);
579
+ }
580
+
581
+ .dark .bp-node-icon--lifecycle,
582
+ :root.dark .bp-node-icon--lifecycle {
583
+ color: rgb(252 211 77);
584
+ }
585
+
586
+ .dark .bp-node-icon--event,
587
+ :root.dark .bp-node-icon--event {
588
+ color: rgb(240 171 252);
589
+ }
590
+
591
+ .dark .bp-node-icon--fetch,
592
+ :root.dark .bp-node-icon--fetch {
593
+ color: rgb(196 181 253);
594
+ }
595
+
596
+ .dark .bp-node-icon--json,
597
+ :root.dark .bp-node-icon--json {
598
+ color: rgb(94 234 212);
599
+ }
600
+
601
+ .dark .bp-node-icon--storage,
602
+ :root.dark .bp-node-icon--storage {
603
+ color: rgb(110 231 183);
604
+ }
605
+
606
+ .dark .bp-node-icon--clock,
607
+ :root.dark .bp-node-icon--clock {
608
+ color: rgb(253 164 175);
609
+ }