pict-section-flow 0.0.10 → 0.0.13

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 (88) hide show
  1. package/.claude/launch.json +1 -1
  2. package/README.md +176 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/Architecture.md +303 -0
  5. package/docs/Custom-Styling.md +275 -0
  6. package/docs/Data_Model.md +158 -0
  7. package/docs/Event_System.md +156 -0
  8. package/docs/Getting_Started.md +237 -0
  9. package/docs/Implementation_Reference.md +528 -0
  10. package/docs/Layout_Persistence.md +117 -0
  11. package/docs/README.md +115 -52
  12. package/docs/_cover.md +11 -0
  13. package/docs/_sidebar.md +52 -0
  14. package/docs/_topbar.md +8 -0
  15. package/docs/api/PictFlowCard.md +216 -0
  16. package/docs/api/PictFlowCardPropertiesPanel.md +235 -0
  17. package/docs/api/addConnection.md +101 -0
  18. package/docs/api/addNode.md +137 -0
  19. package/docs/api/autoLayout.md +77 -0
  20. package/docs/api/getFlowData.md +112 -0
  21. package/docs/api/marshalToView.md +95 -0
  22. package/docs/api/openPanel.md +128 -0
  23. package/docs/api/registerHandler.md +174 -0
  24. package/docs/api/registerNodeType.md +142 -0
  25. package/docs/api/removeConnection.md +57 -0
  26. package/docs/api/removeNode.md +80 -0
  27. package/docs/api/saveLayout.md +152 -0
  28. package/docs/api/screenToSVGCoords.md +68 -0
  29. package/docs/api/selectNode.md +116 -0
  30. package/docs/api/setTheme.md +168 -0
  31. package/docs/api/setZoom.md +97 -0
  32. package/docs/api/toggleFullscreen.md +68 -0
  33. package/docs/card-help/EACH.md +19 -0
  34. package/docs/card-help/FREAD.md +24 -0
  35. package/docs/card-help/FWRITE.md +24 -0
  36. package/docs/card-help/GET.md +22 -0
  37. package/docs/card-help/ITE.md +23 -0
  38. package/docs/card-help/LOG.md +23 -0
  39. package/docs/card-help/NOTE.md +17 -0
  40. package/docs/card-help/PREV.md +18 -0
  41. package/docs/card-help/SET.md +27 -0
  42. package/docs/card-help/SPKL.md +22 -0
  43. package/docs/card-help/STAT.md +23 -0
  44. package/docs/card-help/SW.md +25 -0
  45. package/docs/css/docuserve.css +73 -0
  46. package/docs/index.html +39 -0
  47. package/docs/retold-catalog.json +169 -0
  48. package/docs/retold-keyword-index.json +13942 -0
  49. package/example_applications/simple_cards/package.json +1 -0
  50. package/example_applications/simple_cards/source/card-help-content.js +16 -0
  51. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +2 -0
  52. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +2 -0
  53. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +2 -0
  54. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +2 -0
  55. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +2 -0
  56. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +2 -0
  57. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +2 -0
  58. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +2 -0
  59. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +2 -0
  60. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +2 -0
  61. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +2 -0
  62. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +2 -0
  63. package/package.json +11 -7
  64. package/scripts/generate-card-help.js +214 -0
  65. package/source/Pict-Section-Flow.js +4 -0
  66. package/source/PictFlowCard.js +3 -1
  67. package/source/providers/PictProvider-Flow-CSS.js +245 -152
  68. package/source/providers/PictProvider-Flow-ConnectorShapes.js +24 -0
  69. package/source/providers/PictProvider-Flow-Geometry.js +195 -38
  70. package/source/providers/PictProvider-Flow-PanelChrome.js +14 -12
  71. package/source/services/PictService-Flow-ConnectionHandleManager.js +263 -0
  72. package/source/services/PictService-Flow-ConnectionRenderer.js +134 -183
  73. package/source/services/PictService-Flow-DataManager.js +338 -0
  74. package/source/services/PictService-Flow-InteractionManager.js +165 -7
  75. package/source/services/PictService-Flow-PathGenerator.js +282 -0
  76. package/source/services/PictService-Flow-PortRenderer.js +269 -0
  77. package/source/services/PictService-Flow-RenderManager.js +281 -0
  78. package/source/services/PictService-Flow-Tether.js +6 -42
  79. package/source/views/PictView-Flow-Node.js +2 -220
  80. package/source/views/PictView-Flow-PropertiesPanel.js +89 -44
  81. package/source/views/PictView-Flow.js +130 -882
  82. package/test/ConnectionHandleManager_tests.js +717 -0
  83. package/test/ConnectionRenderer_tests.js +591 -0
  84. package/test/DataManager_tests.js +859 -0
  85. package/test/Geometry_tests.js +767 -0
  86. package/test/PathGenerator_tests.js +978 -0
  87. package/test/PortRenderer_tests.js +367 -0
  88. package/test/RenderManager_tests.js +756 -0
@@ -207,17 +207,21 @@ class PictViewFlowPropertiesPanel extends libPictView
207
207
 
208
208
  let tmpBody = tmpPanelChromeProvider.createPanelForeignObject(pPanelData, pPanelsLayer);
209
209
 
210
- // Render the panel content via the panel type implementation
210
+ // Render the panel content into the Properties tab pane
211
211
  if (tmpBody)
212
212
  {
213
213
  this._renderPanelContent(pPanelData, tmpBody);
214
214
  }
215
215
 
216
- // Render the collapsible node properties editor at the bottom of the panel
217
216
  let tmpFO = pPanelsLayer.querySelector(`[data-panel-hash="${pPanelData.Hash}"]`);
218
217
  if (tmpFO)
219
218
  {
220
- this._renderNodePropsEditor(pPanelData, tmpFO);
219
+ // Render appearance and help tabs
220
+ this._renderAppearanceTab(pPanelData, tmpFO);
221
+ this._renderHelpTab(pPanelData, tmpFO);
222
+
223
+ // Wire up tab switching
224
+ this._wireTabSwitching(tmpFO);
221
225
  }
222
226
  }
223
227
 
@@ -516,20 +520,18 @@ class PictViewFlowPropertiesPanel extends libPictView
516
520
  }
517
521
 
518
522
  /**
519
- * Render the collapsible node properties editor into a panel's foreignObject.
520
- * Populates the editor fields with current node values and wires up live
521
- * change handlers for immediate visual feedback.
523
+ * Render the Appearance tab content with node property editor fields.
522
524
  *
523
525
  * @param {Object} pPanelData - Panel data from OpenPanels
524
526
  * @param {Element} pForeignObject - The panel's SVG foreignObject element
525
527
  */
526
- _renderNodePropsEditor(pPanelData, pForeignObject)
528
+ _renderAppearanceTab(pPanelData, pForeignObject)
527
529
  {
528
530
  let tmpNodeData = this._FlowView.getNode(pPanelData.NodeHash);
529
531
  if (!tmpNodeData) return;
530
532
 
531
- let tmpPropsBody = pForeignObject.querySelector('.pict-flow-panel-node-props-body');
532
- if (!tmpPropsBody) return;
533
+ let tmpAppearancePane = pForeignObject.querySelector('.pict-flow-panel-tab-pane[data-tab="appearance"]');
534
+ if (!tmpAppearancePane) return;
533
535
 
534
536
  // Build the template record with safe defaults for Style values
535
537
  let tmpStyle = tmpNodeData.Style || {};
@@ -560,43 +562,10 @@ class PictViewFlowPropertiesPanel extends libPictView
560
562
  TitleBarColorValue: tmpStyle.TitleBarColor || tmpDefaultTitleBarColor
561
563
  };
562
564
 
563
- tmpPropsBody.innerHTML = this.pict.parseTemplateByHash('Flow-NodeProps-Editor', tmpRecord);
564
-
565
- // Wire up the expand/collapse toggle with dynamic panel height adjustment
566
- let tmpHeader = pForeignObject.querySelector('.pict-flow-panel-node-props-header');
567
- if (tmpHeader)
568
- {
569
- // Store the original panel height before the section was expanded
570
- let tmpOriginalHeight = parseInt(pForeignObject.getAttribute('height'), 10) || 200;
571
-
572
- tmpHeader.addEventListener('click', (pEvent) =>
573
- {
574
- pEvent.stopPropagation();
575
- let tmpIsExpanded = tmpPropsBody.style.display !== 'none';
576
- tmpPropsBody.style.display = tmpIsExpanded ? 'none' : 'block';
577
- let tmpChevron = tmpHeader.querySelector('.pict-flow-panel-node-props-chevron');
578
- if (tmpChevron)
579
- {
580
- tmpChevron.classList.toggle('expanded', !tmpIsExpanded);
581
- }
582
-
583
- // Resize the foreignObject to accommodate the expanded/collapsed section
584
- let tmpEditorHeight = tmpIsExpanded ? 0 : tmpPropsBody.scrollHeight;
585
- let tmpNewHeight = tmpOriginalHeight + tmpEditorHeight;
586
- pForeignObject.setAttribute('height', String(tmpNewHeight));
587
-
588
- // Update the panel data so tethers and position tracking stay in sync
589
- let tmpPanelDataEntry = this._FlowView._FlowData.OpenPanels.find(
590
- (pPanel) => pPanel.Hash === pPanelData.Hash);
591
- if (tmpPanelDataEntry)
592
- {
593
- tmpPanelDataEntry.Height = tmpNewHeight;
594
- }
595
- });
596
- }
565
+ tmpAppearancePane.innerHTML = this.pict.parseTemplateByHash('Flow-NodeProps-Editor', tmpRecord);
597
566
 
598
567
  // Wire up live change handlers on all input fields
599
- let tmpInputs = tmpPropsBody.querySelectorAll('.pict-flow-node-props-input');
568
+ let tmpInputs = tmpAppearancePane.querySelectorAll('.pict-flow-node-props-input');
600
569
  for (let i = 0; i < tmpInputs.length; i++)
601
570
  {
602
571
  let tmpInput = tmpInputs[i];
@@ -613,6 +582,82 @@ class PictViewFlowPropertiesPanel extends libPictView
613
582
  }
614
583
  }
615
584
 
585
+ /**
586
+ * Render the Help tab content if help text is defined on the node type.
587
+ * Shows the Help tab button only when help content is available.
588
+ *
589
+ * @param {Object} pPanelData - Panel data from OpenPanels
590
+ * @param {Element} pForeignObject - The panel's SVG foreignObject element
591
+ */
592
+ _renderHelpTab(pPanelData, pForeignObject)
593
+ {
594
+ let tmpNodeData = this._FlowView.getNode(pPanelData.NodeHash);
595
+ if (!tmpNodeData) return;
596
+
597
+ let tmpNodeTypeConfig = this._FlowView._NodeTypeProvider.getNodeType(tmpNodeData.Type);
598
+ if (!tmpNodeTypeConfig) return;
599
+
600
+ let tmpHelpText = (tmpNodeTypeConfig.CardMetadata && tmpNodeTypeConfig.CardMetadata.Help)
601
+ ? tmpNodeTypeConfig.CardMetadata.Help
602
+ : null;
603
+
604
+ if (!tmpHelpText) return;
605
+
606
+ // Show the Help tab button
607
+ let tmpHelpTabButton = pForeignObject.querySelector('.pict-flow-panel-tab[data-tab-target="help"]');
608
+ if (tmpHelpTabButton)
609
+ {
610
+ tmpHelpTabButton.style.display = '';
611
+ }
612
+
613
+ // Render help content into the help pane
614
+ let tmpHelpPane = pForeignObject.querySelector('.pict-flow-panel-tab-pane[data-tab="help"]');
615
+ if (tmpHelpPane)
616
+ {
617
+ tmpHelpPane.innerHTML = '<div class="pict-flow-panel-help-content">' + tmpHelpText + '</div>';
618
+ }
619
+ }
620
+
621
+ /**
622
+ * Wire up tab switching on all tab buttons within a panel foreignObject.
623
+ *
624
+ * @param {Element} pForeignObject - The panel's SVG foreignObject element
625
+ */
626
+ _wireTabSwitching(pForeignObject)
627
+ {
628
+ let tmpTabs = pForeignObject.querySelectorAll('.pict-flow-panel-tab');
629
+ let tmpPanes = pForeignObject.querySelectorAll('.pict-flow-panel-tab-pane');
630
+
631
+ for (let i = 0; i < tmpTabs.length; i++)
632
+ {
633
+ tmpTabs[i].addEventListener('click', (pEvent) =>
634
+ {
635
+ pEvent.stopPropagation();
636
+ let tmpTarget = pEvent.currentTarget.getAttribute('data-tab-target');
637
+
638
+ // Deactivate all tabs and panes
639
+ for (let j = 0; j < tmpTabs.length; j++)
640
+ {
641
+ tmpTabs[j].classList.remove('active');
642
+ }
643
+ for (let j = 0; j < tmpPanes.length; j++)
644
+ {
645
+ tmpPanes[j].classList.remove('active');
646
+ tmpPanes[j].style.display = 'none';
647
+ }
648
+
649
+ // Activate the selected tab and pane
650
+ pEvent.currentTarget.classList.add('active');
651
+ let tmpTargetPane = pForeignObject.querySelector('.pict-flow-panel-tab-pane[data-tab="' + tmpTarget + '"]');
652
+ if (tmpTargetPane)
653
+ {
654
+ tmpTargetPane.classList.add('active');
655
+ tmpTargetPane.style.display = 'block';
656
+ }
657
+ });
658
+ }
659
+ }
660
+
616
661
  /**
617
662
  * Apply a node property change from the properties editor and re-render.
618
663
  *