@foresthubai/workflow-builder 0.4.3 → 0.4.5

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 (414) hide show
  1. package/LICENSE +661 -661
  2. package/NOTICE +16 -16
  3. package/README.md +110 -110
  4. package/dist/BuilderLayout.d.ts.map +1 -1
  5. package/dist/BuilderLayout.js +52 -61
  6. package/dist/BuilderLayout.js.map +1 -1
  7. package/dist/Canvas.d.ts.map +1 -1
  8. package/dist/Canvas.js +10 -3
  9. package/dist/Canvas.js.map +1 -1
  10. package/dist/CanvasEditor.d.ts.map +1 -1
  11. package/dist/CanvasEditor.js.map +1 -1
  12. package/dist/CanvasTabsToolbar.d.ts.map +1 -1
  13. package/dist/CanvasTabsToolbar.js +3 -0
  14. package/dist/CanvasTabsToolbar.js.map +1 -1
  15. package/dist/RightConfigPanel.d.ts.map +1 -1
  16. package/dist/RightConfigPanel.js +3 -0
  17. package/dist/RightConfigPanel.js.map +1 -1
  18. package/dist/WorkflowBuilder.d.ts +7 -13
  19. package/dist/WorkflowBuilder.d.ts.map +1 -1
  20. package/dist/WorkflowBuilder.js +25 -13
  21. package/dist/WorkflowBuilder.js.map +1 -1
  22. package/dist/cn.d.ts.map +1 -1
  23. package/dist/cn.js +3 -0
  24. package/dist/cn.js.map +1 -1
  25. package/dist/components/ui/add-button.d.ts.map +1 -1
  26. package/dist/components/ui/add-button.js +3 -0
  27. package/dist/components/ui/add-button.js.map +1 -1
  28. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  29. package/dist/components/ui/alert-dialog.js +3 -0
  30. package/dist/components/ui/alert-dialog.js.map +1 -1
  31. package/dist/components/ui/alert.d.ts.map +1 -1
  32. package/dist/components/ui/alert.js +3 -0
  33. package/dist/components/ui/alert.js.map +1 -1
  34. package/dist/components/ui/badge.d.ts.map +1 -1
  35. package/dist/components/ui/badge.js.map +1 -1
  36. package/dist/components/ui/button.d.ts.map +1 -1
  37. package/dist/components/ui/button.js +3 -0
  38. package/dist/components/ui/button.js.map +1 -1
  39. package/dist/components/ui/card.d.ts.map +1 -1
  40. package/dist/components/ui/card.js +3 -0
  41. package/dist/components/ui/card.js.map +1 -1
  42. package/dist/components/ui/checkbox.d.ts.map +1 -1
  43. package/dist/components/ui/checkbox.js +3 -0
  44. package/dist/components/ui/checkbox.js.map +1 -1
  45. package/dist/components/ui/collapsible.d.ts.map +1 -1
  46. package/dist/components/ui/collapsible.js +3 -0
  47. package/dist/components/ui/collapsible.js.map +1 -1
  48. package/dist/components/ui/command.d.ts +2 -2
  49. package/dist/components/ui/command.d.ts.map +1 -1
  50. package/dist/components/ui/command.js +3 -0
  51. package/dist/components/ui/command.js.map +1 -1
  52. package/dist/components/ui/delete-button.d.ts.map +1 -1
  53. package/dist/components/ui/delete-button.js +3 -0
  54. package/dist/components/ui/delete-button.js.map +1 -1
  55. package/dist/components/ui/dialog.d.ts.map +1 -1
  56. package/dist/components/ui/dialog.js +3 -0
  57. package/dist/components/ui/dialog.js.map +1 -1
  58. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  59. package/dist/components/ui/dropdown-menu.js +3 -0
  60. package/dist/components/ui/dropdown-menu.js.map +1 -1
  61. package/dist/components/ui/input.d.ts +1 -1
  62. package/dist/components/ui/input.d.ts.map +1 -1
  63. package/dist/components/ui/input.js +3 -0
  64. package/dist/components/ui/input.js.map +1 -1
  65. package/dist/components/ui/label.d.ts.map +1 -1
  66. package/dist/components/ui/label.js +3 -0
  67. package/dist/components/ui/label.js.map +1 -1
  68. package/dist/components/ui/readonly-banner.d.ts.map +1 -1
  69. package/dist/components/ui/readonly-banner.js +3 -0
  70. package/dist/components/ui/readonly-banner.js.map +1 -1
  71. package/dist/components/ui/resizable.d.ts +1 -1
  72. package/dist/components/ui/resizable.d.ts.map +1 -1
  73. package/dist/components/ui/resizable.js +3 -0
  74. package/dist/components/ui/resizable.js.map +1 -1
  75. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  76. package/dist/components/ui/scroll-area.js +3 -0
  77. package/dist/components/ui/scroll-area.js.map +1 -1
  78. package/dist/components/ui/select.d.ts.map +1 -1
  79. package/dist/components/ui/select.js +3 -0
  80. package/dist/components/ui/select.js.map +1 -1
  81. package/dist/components/ui/separator.d.ts.map +1 -1
  82. package/dist/components/ui/separator.js +3 -0
  83. package/dist/components/ui/separator.js.map +1 -1
  84. package/dist/components/ui/switch.d.ts.map +1 -1
  85. package/dist/components/ui/switch.js +3 -0
  86. package/dist/components/ui/switch.js.map +1 -1
  87. package/dist/components/ui/textarea.d.ts +1 -1
  88. package/dist/components/ui/textarea.d.ts.map +1 -1
  89. package/dist/components/ui/textarea.js +3 -0
  90. package/dist/components/ui/textarea.js.map +1 -1
  91. package/dist/components/ui/toast.d.ts.map +1 -1
  92. package/dist/components/ui/toast.js +3 -0
  93. package/dist/components/ui/toast.js.map +1 -1
  94. package/dist/components/ui/toaster.d.ts.map +1 -1
  95. package/dist/components/ui/toaster.js +3 -0
  96. package/dist/components/ui/toaster.js.map +1 -1
  97. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  98. package/dist/components/ui/toggle-group.js +3 -0
  99. package/dist/components/ui/toggle-group.js.map +1 -1
  100. package/dist/components/ui/toggle.d.ts.map +1 -1
  101. package/dist/components/ui/toggle.js +3 -0
  102. package/dist/components/ui/toggle.js.map +1 -1
  103. package/dist/components/ui/tooltip.d.ts.map +1 -1
  104. package/dist/components/ui/tooltip.js +3 -0
  105. package/dist/components/ui/tooltip.js.map +1 -1
  106. package/dist/dialogs/NodePickerDialog.d.ts.map +1 -1
  107. package/dist/dialogs/NodePickerDialog.js +3 -0
  108. package/dist/dialogs/NodePickerDialog.js.map +1 -1
  109. package/dist/dialogs/ValidationDialog.d.ts.map +1 -1
  110. package/dist/dialogs/ValidationDialog.js +3 -0
  111. package/dist/dialogs/ValidationDialog.js.map +1 -1
  112. package/dist/graph/BaseNode.d.ts.map +1 -1
  113. package/dist/graph/BaseNode.js +21 -16
  114. package/dist/graph/BaseNode.js.map +1 -1
  115. package/dist/graph/CustomEdge.d.ts.map +1 -1
  116. package/dist/graph/CustomEdge.js +4 -1
  117. package/dist/graph/CustomEdge.js.map +1 -1
  118. package/dist/graph/CustomNode.d.ts.map +1 -1
  119. package/dist/graph/CustomNode.js +3 -0
  120. package/dist/graph/CustomNode.js.map +1 -1
  121. package/dist/graph/FunctionCallNode.d.ts.map +1 -1
  122. package/dist/graph/FunctionCallNode.js.map +1 -1
  123. package/dist/graph/PortHandle.d.ts.map +1 -1
  124. package/dist/graph/PortHandle.js.map +1 -1
  125. package/dist/graph/reactFlowRegistry.d.ts.map +1 -1
  126. package/dist/graph/reactFlowRegistry.js +3 -0
  127. package/dist/graph/reactFlowRegistry.js.map +1 -1
  128. package/dist/hooks/use-toast.d.ts.map +1 -1
  129. package/dist/hooks/use-toast.js +3 -0
  130. package/dist/hooks/use-toast.js.map +1 -1
  131. package/dist/hooks/useAvailableVariables.d.ts.map +1 -1
  132. package/dist/hooks/useAvailableVariables.js +3 -0
  133. package/dist/hooks/useAvailableVariables.js.map +1 -1
  134. package/dist/hooks/useCanvasHistory.d.ts.map +1 -1
  135. package/dist/hooks/useCanvasHistory.js +3 -0
  136. package/dist/hooks/useCanvasHistory.js.map +1 -1
  137. package/dist/hooks/useCanvasTabs.d.ts.map +1 -1
  138. package/dist/hooks/useCanvasTabs.js +3 -0
  139. package/dist/hooks/useCanvasTabs.js.map +1 -1
  140. package/dist/hooks/useFunctionDiagnosticsSync.d.ts.map +1 -1
  141. package/dist/hooks/useFunctionDiagnosticsSync.js +3 -0
  142. package/dist/hooks/useFunctionDiagnosticsSync.js.map +1 -1
  143. package/dist/hooks/useFunctionRegistry.d.ts.map +1 -1
  144. package/dist/hooks/useFunctionRegistry.js +3 -0
  145. package/dist/hooks/useFunctionRegistry.js.map +1 -1
  146. package/dist/hooks/useFunctions.d.ts.map +1 -1
  147. package/dist/hooks/useFunctions.js +3 -0
  148. package/dist/hooks/useFunctions.js.map +1 -1
  149. package/dist/hooks/useGraph.d.ts.map +1 -1
  150. package/dist/hooks/useGraph.js +3 -0
  151. package/dist/hooks/useGraph.js.map +1 -1
  152. package/dist/hooks/useNodeDefinitions.d.ts.map +1 -1
  153. package/dist/hooks/useNodeDefinitions.js +3 -0
  154. package/dist/hooks/useNodeDefinitions.js.map +1 -1
  155. package/dist/hooks/useParamErrors.d.ts.map +1 -1
  156. package/dist/hooks/useParamErrors.js +3 -0
  157. package/dist/hooks/useParamErrors.js.map +1 -1
  158. package/dist/hooks/useResolvedTheme.d.ts.map +1 -1
  159. package/dist/hooks/useResolvedTheme.js +3 -0
  160. package/dist/hooks/useResolvedTheme.js.map +1 -1
  161. package/dist/hooks/useResourceDiagnosticsSync.d.ts.map +1 -1
  162. package/dist/hooks/useResourceDiagnosticsSync.js +3 -0
  163. package/dist/hooks/useResourceDiagnosticsSync.js.map +1 -1
  164. package/dist/hooks/useSuppressThemeTransition.d.ts.map +1 -1
  165. package/dist/hooks/useSuppressThemeTransition.js +3 -0
  166. package/dist/hooks/useSuppressThemeTransition.js.map +1 -1
  167. package/dist/hooks/useWorkflowSerialization.d.ts.map +1 -1
  168. package/dist/hooks/useWorkflowSerialization.js +3 -0
  169. package/dist/hooks/useWorkflowSerialization.js.map +1 -1
  170. package/dist/i18n/index.d.ts.map +1 -1
  171. package/dist/i18n/index.js +3 -0
  172. package/dist/i18n/index.js.map +1 -1
  173. package/dist/index.d.ts +1 -1
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +3 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/inputs/ExpressionInput.d.ts.map +1 -1
  178. package/dist/inputs/ExpressionInput.js +3 -0
  179. package/dist/inputs/ExpressionInput.js.map +1 -1
  180. package/dist/inputs/ParameterEditor.d.ts.map +1 -1
  181. package/dist/inputs/ParameterEditor.js +3 -0
  182. package/dist/inputs/ParameterEditor.js.map +1 -1
  183. package/dist/inputs/PortSection.d.ts.map +1 -1
  184. package/dist/inputs/PortSection.js.map +1 -1
  185. package/dist/mode.d.ts +11 -0
  186. package/dist/mode.d.ts.map +1 -0
  187. package/dist/mode.js +8 -0
  188. package/dist/mode.js.map +1 -0
  189. package/dist/panels/BuilderSidebar.d.ts.map +1 -1
  190. package/dist/panels/BuilderSidebar.js +3 -0
  191. package/dist/panels/BuilderSidebar.js.map +1 -1
  192. package/dist/panels/ChannelConfigPanel.d.ts.map +1 -1
  193. package/dist/panels/ChannelConfigPanel.js +3 -0
  194. package/dist/panels/ChannelConfigPanel.js.map +1 -1
  195. package/dist/panels/ChannelsPanel.d.ts.map +1 -1
  196. package/dist/panels/ChannelsPanel.js +3 -0
  197. package/dist/panels/ChannelsPanel.js.map +1 -1
  198. package/dist/panels/DebugConsolePanel.d.ts.map +1 -1
  199. package/dist/panels/DebugConsolePanel.js +3 -0
  200. package/dist/panels/DebugConsolePanel.js.map +1 -1
  201. package/dist/panels/DebugContextPanel.d.ts.map +1 -1
  202. package/dist/panels/DebugContextPanel.js +3 -0
  203. package/dist/panels/DebugContextPanel.js.map +1 -1
  204. package/dist/panels/DebugExternalIOPanel.d.ts.map +1 -1
  205. package/dist/panels/DebugExternalIOPanel.js +3 -0
  206. package/dist/panels/DebugExternalIOPanel.js.map +1 -1
  207. package/dist/panels/DiagnosticsPanel.d.ts.map +1 -1
  208. package/dist/panels/DiagnosticsPanel.js +3 -0
  209. package/dist/panels/DiagnosticsPanel.js.map +1 -1
  210. package/dist/panels/EdgeConfigPanel.d.ts.map +1 -1
  211. package/dist/panels/EdgeConfigPanel.js +4 -1
  212. package/dist/panels/EdgeConfigPanel.js.map +1 -1
  213. package/dist/panels/FunctionConfigPanel.d.ts.map +1 -1
  214. package/dist/panels/FunctionConfigPanel.js +4 -1
  215. package/dist/panels/FunctionConfigPanel.js.map +1 -1
  216. package/dist/panels/FunctionListPanel.d.ts.map +1 -1
  217. package/dist/panels/FunctionListPanel.js +3 -0
  218. package/dist/panels/FunctionListPanel.js.map +1 -1
  219. package/dist/panels/MemoryConfigPanel.d.ts.map +1 -1
  220. package/dist/panels/MemoryConfigPanel.js +3 -0
  221. package/dist/panels/MemoryConfigPanel.js.map +1 -1
  222. package/dist/panels/MemoryPanel.d.ts.map +1 -1
  223. package/dist/panels/MemoryPanel.js +3 -0
  224. package/dist/panels/MemoryPanel.js.map +1 -1
  225. package/dist/panels/ModelConfigPanel.d.ts.map +1 -1
  226. package/dist/panels/ModelConfigPanel.js +3 -0
  227. package/dist/panels/ModelConfigPanel.js.map +1 -1
  228. package/dist/panels/ModelsPanel.d.ts.map +1 -1
  229. package/dist/panels/ModelsPanel.js +3 -0
  230. package/dist/panels/ModelsPanel.js.map +1 -1
  231. package/dist/panels/NodeConfigPanel.d.ts.map +1 -1
  232. package/dist/panels/NodeConfigPanel.js +4 -1
  233. package/dist/panels/NodeConfigPanel.js.map +1 -1
  234. package/dist/panels/NodeLibrary.d.ts.map +1 -1
  235. package/dist/panels/NodeLibrary.js +4 -1
  236. package/dist/panels/NodeLibrary.js.map +1 -1
  237. package/dist/panels/ResourceConfigPanel.d.ts.map +1 -1
  238. package/dist/panels/ResourceConfigPanel.js +4 -1
  239. package/dist/panels/ResourceConfigPanel.js.map +1 -1
  240. package/dist/panels/ResourceListPanel.d.ts.map +1 -1
  241. package/dist/panels/ResourceListPanel.js +4 -1
  242. package/dist/panels/ResourceListPanel.js.map +1 -1
  243. package/dist/panels/VariableConfigPanel.d.ts.map +1 -1
  244. package/dist/panels/VariableConfigPanel.js +4 -1
  245. package/dist/panels/VariableConfigPanel.js.map +1 -1
  246. package/dist/panels/VariablesPanel.d.ts.map +1 -1
  247. package/dist/panels/VariablesPanel.js +4 -1
  248. package/dist/panels/VariablesPanel.js.map +1 -1
  249. package/dist/stores/canvasStore.d.ts.map +1 -1
  250. package/dist/stores/canvasStore.js +3 -0
  251. package/dist/stores/canvasStore.js.map +1 -1
  252. package/dist/stores/debugStore.d.ts.map +1 -1
  253. package/dist/stores/debugStore.js +3 -0
  254. package/dist/stores/debugStore.js.map +1 -1
  255. package/dist/stores/diagnosticsStore.d.ts.map +1 -1
  256. package/dist/stores/diagnosticsStore.js +3 -0
  257. package/dist/stores/diagnosticsStore.js.map +1 -1
  258. package/dist/stores/editorStore.d.ts +1 -1
  259. package/dist/stores/editorStore.d.ts.map +1 -1
  260. package/dist/stores/editorStore.js +3 -0
  261. package/dist/stores/editorStore.js.map +1 -1
  262. package/dist/utils/categoryConstants.d.ts.map +1 -1
  263. package/dist/utils/categoryConstants.js +3 -0
  264. package/dist/utils/categoryConstants.js.map +1 -1
  265. package/dist/utils/channelOperations.d.ts.map +1 -1
  266. package/dist/utils/channelOperations.js +3 -0
  267. package/dist/utils/channelOperations.js.map +1 -1
  268. package/dist/utils/connectionRules.d.ts +3 -1
  269. package/dist/utils/connectionRules.d.ts.map +1 -1
  270. package/dist/utils/connectionRules.js +11 -16
  271. package/dist/utils/connectionRules.js.map +1 -1
  272. package/dist/utils/functionOperations.d.ts.map +1 -1
  273. package/dist/utils/functionOperations.js +3 -0
  274. package/dist/utils/functionOperations.js.map +1 -1
  275. package/dist/utils/graphOperations.d.ts.map +1 -1
  276. package/dist/utils/graphOperations.js +3 -0
  277. package/dist/utils/graphOperations.js.map +1 -1
  278. package/dist/utils/history.d.ts.map +1 -1
  279. package/dist/utils/history.js +4 -1
  280. package/dist/utils/history.js.map +1 -1
  281. package/dist/utils/memoryOperations.d.ts.map +1 -1
  282. package/dist/utils/memoryOperations.js +3 -0
  283. package/dist/utils/memoryOperations.js.map +1 -1
  284. package/dist/utils/migrateFunctionNodes.d.ts.map +1 -1
  285. package/dist/utils/migrateFunctionNodes.js +3 -0
  286. package/dist/utils/migrateFunctionNodes.js.map +1 -1
  287. package/dist/utils/modelOperations.d.ts.map +1 -1
  288. package/dist/utils/modelOperations.js +3 -0
  289. package/dist/utils/modelOperations.js.map +1 -1
  290. package/dist/utils/paramDisplay.d.ts.map +1 -1
  291. package/dist/utils/paramDisplay.js +3 -0
  292. package/dist/utils/paramDisplay.js.map +1 -1
  293. package/dist/utils/resourceHelpers.d.ts.map +1 -1
  294. package/dist/utils/resourceHelpers.js +3 -0
  295. package/dist/utils/resourceHelpers.js.map +1 -1
  296. package/dist/utils/translation.d.ts.map +1 -1
  297. package/dist/utils/translation.js +3 -0
  298. package/dist/utils/translation.js.map +1 -1
  299. package/dist/utils/variableOperations.d.ts.map +1 -1
  300. package/dist/utils/variableOperations.js +3 -0
  301. package/dist/utils/variableOperations.js.map +1 -1
  302. package/package.json +2 -2
  303. package/src/BuilderLayout.tsx +338 -345
  304. package/src/Canvas.tsx +270 -261
  305. package/src/CanvasEditor.tsx +146 -142
  306. package/src/CanvasTabsToolbar.tsx +180 -176
  307. package/src/RightConfigPanel.tsx +270 -266
  308. package/src/WorkflowBuilder.tsx +423 -408
  309. package/src/cn.ts +10 -6
  310. package/src/components/ui/add-button.tsx +43 -39
  311. package/src/components/ui/alert-dialog.tsx +145 -141
  312. package/src/components/ui/alert.tsx +63 -59
  313. package/src/components/ui/badge.tsx +40 -36
  314. package/src/components/ui/button.tsx +89 -85
  315. package/src/components/ui/card.tsx +83 -79
  316. package/src/components/ui/checkbox.tsx +32 -28
  317. package/src/components/ui/collapsible.tsx +13 -9
  318. package/src/components/ui/command.tsx +157 -153
  319. package/src/components/ui/delete-button.tsx +27 -23
  320. package/src/components/ui/dialog.tsx +129 -125
  321. package/src/components/ui/dropdown-menu.tsx +202 -198
  322. package/src/components/ui/input.tsx +59 -55
  323. package/src/components/ui/label.tsx +28 -24
  324. package/src/components/ui/readonly-banner.tsx +19 -15
  325. package/src/components/ui/resizable.tsx +47 -43
  326. package/src/components/ui/scroll-area.tsx +106 -102
  327. package/src/components/ui/select.tsx +164 -160
  328. package/src/components/ui/separator.tsx +33 -29
  329. package/src/components/ui/switch.tsx +31 -27
  330. package/src/components/ui/textarea.tsx +55 -51
  331. package/src/components/ui/toast.tsx +131 -127
  332. package/src/components/ui/toaster.tsx +37 -33
  333. package/src/components/ui/toggle-group.tsx +63 -59
  334. package/src/components/ui/toggle.tsx +47 -43
  335. package/src/components/ui/tooltip.tsx +36 -32
  336. package/src/dialogs/NodePickerDialog.tsx +88 -84
  337. package/src/dialogs/ValidationDialog.tsx +188 -184
  338. package/src/graph/BaseNode.tsx +563 -557
  339. package/src/graph/CustomEdge.tsx +189 -185
  340. package/src/graph/CustomNode.tsx +20 -16
  341. package/src/graph/FunctionCallNode.tsx +34 -30
  342. package/src/graph/PortHandle.tsx +193 -189
  343. package/src/graph/reactFlowRegistry.ts +30 -26
  344. package/src/hooks/use-toast.ts +129 -125
  345. package/src/hooks/useAvailableVariables.ts +24 -20
  346. package/src/hooks/useCanvasHistory.ts +26 -22
  347. package/src/hooks/useCanvasTabs.ts +172 -168
  348. package/src/hooks/useFunctionDiagnosticsSync.ts +44 -40
  349. package/src/hooks/useFunctionRegistry.ts +30 -26
  350. package/src/hooks/useFunctions.ts +48 -44
  351. package/src/hooks/useGraph.ts +165 -161
  352. package/src/hooks/useNodeDefinitions.ts +86 -82
  353. package/src/hooks/useParamErrors.ts +30 -26
  354. package/src/hooks/useResolvedTheme.ts +34 -30
  355. package/src/hooks/useResourceDiagnosticsSync.ts +62 -58
  356. package/src/hooks/useSuppressThemeTransition.ts +83 -79
  357. package/src/hooks/useWorkflowSerialization.ts +145 -141
  358. package/src/i18n/index.ts +57 -53
  359. package/src/i18n/locales/de.json +501 -501
  360. package/src/i18n/locales/en.json +557 -557
  361. package/src/index.ts +31 -27
  362. package/src/inputs/ExpressionInput.tsx +301 -297
  363. package/src/inputs/ParameterEditor.tsx +519 -515
  364. package/src/inputs/PortSection.tsx +148 -144
  365. package/src/mode.ts +15 -0
  366. package/src/panels/BuilderSidebar.tsx +305 -301
  367. package/src/panels/ChannelConfigPanel.tsx +53 -49
  368. package/src/panels/ChannelsPanel.tsx +32 -28
  369. package/src/panels/DebugConsolePanel.tsx +77 -73
  370. package/src/panels/DebugContextPanel.tsx +81 -77
  371. package/src/panels/DebugExternalIOPanel.tsx +184 -180
  372. package/src/panels/DiagnosticsPanel.tsx +174 -170
  373. package/src/panels/EdgeConfigPanel.tsx +108 -104
  374. package/src/panels/FunctionConfigPanel.tsx +183 -179
  375. package/src/panels/FunctionListPanel.tsx +49 -45
  376. package/src/panels/MemoryConfigPanel.tsx +59 -55
  377. package/src/panels/MemoryPanel.tsx +44 -40
  378. package/src/panels/ModelConfigPanel.tsx +45 -41
  379. package/src/panels/ModelsPanel.tsx +40 -36
  380. package/src/panels/NodeConfigPanel.tsx +634 -630
  381. package/src/panels/NodeLibrary.tsx +292 -288
  382. package/src/panels/ResourceConfigPanel.tsx +136 -132
  383. package/src/panels/ResourceListPanel.tsx +117 -113
  384. package/src/panels/VariableConfigPanel.tsx +165 -161
  385. package/src/panels/VariablesPanel.tsx +149 -145
  386. package/src/stores/canvasStore.test.ts +48 -44
  387. package/src/stores/canvasStore.ts +249 -245
  388. package/src/stores/debugStore.ts +78 -74
  389. package/src/stores/diagnosticsStore.ts +134 -130
  390. package/src/stores/editorStore.ts +194 -190
  391. package/src/styles/index.css +526 -526
  392. package/src/utils/categoryConstants.ts +30 -26
  393. package/src/utils/channelOperations.ts +90 -86
  394. package/src/utils/connectionRules.ts +140 -137
  395. package/src/utils/functionOperations.ts +183 -179
  396. package/src/utils/graphOperations.ts +554 -550
  397. package/src/utils/history.test.ts +92 -0
  398. package/src/utils/history.ts +211 -207
  399. package/src/utils/memoryOperations.ts +61 -57
  400. package/src/utils/migrateFunctionNodes.ts +111 -107
  401. package/src/utils/modelOperations.ts +59 -55
  402. package/src/utils/paramDisplay.ts +75 -71
  403. package/src/utils/resourceHelpers.ts +36 -32
  404. package/src/utils/translation.ts +32 -28
  405. package/src/utils/variableOperations.ts +79 -75
  406. package/tailwind-preset.ts +170 -166
  407. package/dist/lib/utils.d.ts +0 -3
  408. package/dist/lib/utils.d.ts.map +0 -1
  409. package/dist/lib/utils.js +0 -6
  410. package/dist/lib/utils.js.map +0 -1
  411. package/dist/toolbars/CanvasTabsToolbar.d.ts +0 -11
  412. package/dist/toolbars/CanvasTabsToolbar.d.ts.map +0 -1
  413. package/dist/toolbars/CanvasTabsToolbar.js +0 -101
  414. package/dist/toolbars/CanvasTabsToolbar.js.map +0 -1
@@ -1,43 +1,47 @@
1
- import { GripVertical } from "lucide-react"
2
- import * as ResizablePrimitive from "react-resizable-panels"
3
-
4
- import { cn } from "../../cn"
5
-
6
- const ResizablePanelGroup = ({
7
- className,
8
- ...props
9
- }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
10
- <ResizablePrimitive.PanelGroup
11
- className={cn(
12
- "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
13
- className
14
- )}
15
- {...props}
16
- />
17
- )
18
-
19
- const ResizablePanel = ResizablePrimitive.Panel
20
-
21
- const ResizableHandle = ({
22
- withHandle,
23
- className,
24
- ...props
25
- }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
26
- withHandle?: boolean
27
- }) => (
28
- <ResizablePrimitive.PanelResizeHandle
29
- className={cn(
30
- "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
31
- className
32
- )}
33
- {...props}
34
- >
35
- {withHandle && (
36
- <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
37
- <GripVertical className="h-2.5 w-2.5" />
38
- </div>
39
- )}
40
- </ResizablePrimitive.PanelResizeHandle>
41
- )
42
-
43
- export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (c) 2026 ForestHub. All rights reserved.
3
+ // For commercial licensing, contact root@foresthub.ai
4
+
5
+ import { GripVertical } from "lucide-react"
6
+ import * as ResizablePrimitive from "react-resizable-panels"
7
+
8
+ import { cn } from "../../cn"
9
+
10
+ const ResizablePanelGroup = ({
11
+ className,
12
+ ...props
13
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
14
+ <ResizablePrimitive.PanelGroup
15
+ className={cn(
16
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+
23
+ const ResizablePanel = ResizablePrimitive.Panel
24
+
25
+ const ResizableHandle = ({
26
+ withHandle,
27
+ className,
28
+ ...props
29
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
30
+ withHandle?: boolean
31
+ }) => (
32
+ <ResizablePrimitive.PanelResizeHandle
33
+ className={cn(
34
+ "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
35
+ className
36
+ )}
37
+ {...props}
38
+ >
39
+ {withHandle && (
40
+ <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
41
+ <GripVertical className="h-2.5 w-2.5" />
42
+ </div>
43
+ )}
44
+ </ResizablePrimitive.PanelResizeHandle>
45
+ )
46
+
47
+ export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
@@ -1,102 +1,106 @@
1
- import * as React from "react";
2
- import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3
-
4
- import { cn } from "../../cn";
5
-
6
- /**
7
- * Radix-backed overlay scrollbar — the builder's canonical scrollable surface.
8
- *
9
- * Why Radix and not the native `::-webkit-scrollbar`:
10
- * - Overlay positioning. The scrollbar is an absolutely-positioned div outside
11
- * the content flow, so it never subtracts width from content (no reflow when
12
- * it appears, no inconsistency between panels with and without overflow).
13
- * - `type="hover"`: scrollbar fades in only while the pointer is over the
14
- * panel, fades out otherwise quiet by default.
15
- * - Thumb is semi-transparent so any content the scrollbar floats over stays
16
- * legible (the user explicitly wanted this).
17
- * - No arrow buttons. Just a thumb on a transparent track.
18
- *
19
- * The native CSS scrollbar rules in styles/index.css remain in place as a
20
- * fallback for tiny scrollable surfaces (dropdown menu lists, select popovers,
21
- * dialog bodies) where wrapping in a ScrollArea is overkill.
22
- *
23
- * `viewportRef` exposes the inner scrollable element for callers that need
24
- * imperative scroll (e.g. DebugConsolePanel auto-scrolling to bottom on new
25
- * entries). The Root forwardRef points to the outer container, which is *not*
26
- * the element with `overflow: scroll`.
27
- */
28
- interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
29
- viewportRef?: React.Ref<HTMLDivElement>;
30
- /** Inner padding applied to the Viewport usually what callers want when
31
- * replacing a `overflow-y-auto p-3` div, since Radix's Root cannot itself
32
- * carry the padding (it must clip cleanly for the overlay scrollbar). */
33
- viewportClassName?: string;
34
- }
35
-
36
- const ScrollArea = React.forwardRef<React.ElementRef<typeof ScrollAreaPrimitive.Root>, ScrollAreaProps>(
37
- ({ className, children, viewportRef, viewportClassName, type = "hover", ...props }, ref) => (
38
- <ScrollAreaPrimitive.Root
39
- ref={ref}
40
- type={type}
41
- className={cn("relative overflow-hidden", className)}
42
- {...props}
43
- >
44
- <ScrollAreaPrimitive.Viewport
45
- ref={viewportRef}
46
- className={cn("h-full w-full rounded-[inherit]", viewportClassName)}
47
- >
48
- {children}
49
- </ScrollAreaPrimitive.Viewport>
50
- <ScrollBar />
51
- <ScrollBar orientation="horizontal" />
52
- <ScrollAreaPrimitive.Corner className="bg-transparent" />
53
- </ScrollAreaPrimitive.Root>
54
- ),
55
- );
56
- ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
57
-
58
- /**
59
- * Themed thin scrollbar. 6px to match the native fallback, transparent track,
60
- * thumb tinted with --muted-foreground at low opacity bumping on hover. No
61
- * padding/border (the prior `p-[1px]` + transparent border was what gave it
62
- * the inset look people noticed against the native bar in other panels).
63
- *
64
- * The opacity transitions are driven by Radix's `data-state` on the scrollbar
65
- * itself (`visible` / `hidden`), which `type="hover"` flips based on pointer
66
- * position + overflow presence.
67
- */
68
- const ScrollBar = React.forwardRef<
69
- React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
70
- React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
71
- >(({ className, orientation = "vertical", ...props }, ref) => (
72
- // forceMount keeps the scrollbar in the DOM when Radix flips it to
73
- // data-state="hidden", so the opacity transition has something to animate.
74
- // Without it Radix unmounts the element after its hide delay and the bar
75
- // vanishes instantly instead of fading. The hidden bar is `pointer-events:
76
- // none` via opacity-0 + Radix not rendering interactive surfaces while
77
- // hidden, so this doesn't trap clicks.
78
- <ScrollAreaPrimitive.ScrollAreaScrollbar
79
- ref={ref}
80
- forceMount
81
- orientation={orientation}
82
- className={cn(
83
- "flex touch-none select-none transition-opacity duration-200",
84
- "data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",
85
- "data-[state=hidden]:pointer-events-none",
86
- orientation === "vertical" && "h-full w-1.5",
87
- orientation === "horizontal" && "h-1.5 flex-col w-full",
88
- className,
89
- )}
90
- {...props}
91
- >
92
- <ScrollAreaPrimitive.ScrollAreaThumb
93
- className={cn(
94
- "relative flex-1 rounded-full bg-muted-foreground/30 transition-colors",
95
- "hover:bg-muted-foreground/55",
96
- )}
97
- />
98
- </ScrollAreaPrimitive.ScrollAreaScrollbar>
99
- ));
100
- ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
101
-
102
- export { ScrollArea, ScrollBar };
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (c) 2026 ForestHub. All rights reserved.
3
+ // For commercial licensing, contact root@foresthub.ai
4
+
5
+ import * as React from "react";
6
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
7
+
8
+ import { cn } from "../../cn";
9
+
10
+ /**
11
+ * Radix-backed overlay scrollbar the builder's canonical scrollable surface.
12
+ *
13
+ * Why Radix and not the native `::-webkit-scrollbar`:
14
+ * - Overlay positioning. The scrollbar is an absolutely-positioned div outside
15
+ * the content flow, so it never subtracts width from content (no reflow when
16
+ * it appears, no inconsistency between panels with and without overflow).
17
+ * - `type="hover"`: scrollbar fades in only while the pointer is over the
18
+ * panel, fades out otherwise — quiet by default.
19
+ * - Thumb is semi-transparent so any content the scrollbar floats over stays
20
+ * legible (the user explicitly wanted this).
21
+ * - No arrow buttons. Just a thumb on a transparent track.
22
+ *
23
+ * The native CSS scrollbar rules in styles/index.css remain in place as a
24
+ * fallback for tiny scrollable surfaces (dropdown menu lists, select popovers,
25
+ * dialog bodies) where wrapping in a ScrollArea is overkill.
26
+ *
27
+ * `viewportRef` exposes the inner scrollable element for callers that need
28
+ * imperative scroll (e.g. DebugConsolePanel auto-scrolling to bottom on new
29
+ * entries). The Root forwardRef points to the outer container, which is *not*
30
+ * the element with `overflow: scroll`.
31
+ */
32
+ interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
33
+ viewportRef?: React.Ref<HTMLDivElement>;
34
+ /** Inner padding applied to the Viewport — usually what callers want when
35
+ * replacing a `overflow-y-auto p-3` div, since Radix's Root cannot itself
36
+ * carry the padding (it must clip cleanly for the overlay scrollbar). */
37
+ viewportClassName?: string;
38
+ }
39
+
40
+ const ScrollArea = React.forwardRef<React.ElementRef<typeof ScrollAreaPrimitive.Root>, ScrollAreaProps>(
41
+ ({ className, children, viewportRef, viewportClassName, type = "hover", ...props }, ref) => (
42
+ <ScrollAreaPrimitive.Root
43
+ ref={ref}
44
+ type={type}
45
+ className={cn("relative overflow-hidden", className)}
46
+ {...props}
47
+ >
48
+ <ScrollAreaPrimitive.Viewport
49
+ ref={viewportRef}
50
+ className={cn("h-full w-full rounded-[inherit]", viewportClassName)}
51
+ >
52
+ {children}
53
+ </ScrollAreaPrimitive.Viewport>
54
+ <ScrollBar />
55
+ <ScrollBar orientation="horizontal" />
56
+ <ScrollAreaPrimitive.Corner className="bg-transparent" />
57
+ </ScrollAreaPrimitive.Root>
58
+ ),
59
+ );
60
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
61
+
62
+ /**
63
+ * Themed thin scrollbar. 6px to match the native fallback, transparent track,
64
+ * thumb tinted with --muted-foreground at low opacity bumping on hover. No
65
+ * padding/border (the prior `p-[1px]` + transparent border was what gave it
66
+ * the inset look people noticed against the native bar in other panels).
67
+ *
68
+ * The opacity transitions are driven by Radix's `data-state` on the scrollbar
69
+ * itself (`visible` / `hidden`), which `type="hover"` flips based on pointer
70
+ * position + overflow presence.
71
+ */
72
+ const ScrollBar = React.forwardRef<
73
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
74
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
75
+ >(({ className, orientation = "vertical", ...props }, ref) => (
76
+ // forceMount keeps the scrollbar in the DOM when Radix flips it to
77
+ // data-state="hidden", so the opacity transition has something to animate.
78
+ // Without it Radix unmounts the element after its hide delay and the bar
79
+ // vanishes instantly instead of fading. The hidden bar is `pointer-events:
80
+ // none` via opacity-0 + Radix not rendering interactive surfaces while
81
+ // hidden, so this doesn't trap clicks.
82
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
83
+ ref={ref}
84
+ forceMount
85
+ orientation={orientation}
86
+ className={cn(
87
+ "flex touch-none select-none transition-opacity duration-200",
88
+ "data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",
89
+ "data-[state=hidden]:pointer-events-none",
90
+ orientation === "vertical" && "h-full w-1.5",
91
+ orientation === "horizontal" && "h-1.5 flex-col w-full",
92
+ className,
93
+ )}
94
+ {...props}
95
+ >
96
+ <ScrollAreaPrimitive.ScrollAreaThumb
97
+ className={cn(
98
+ "relative flex-1 rounded-full bg-muted-foreground/30 transition-colors",
99
+ "hover:bg-muted-foreground/55",
100
+ )}
101
+ />
102
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
103
+ ));
104
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
105
+
106
+ export { ScrollArea, ScrollBar };
@@ -1,160 +1,164 @@
1
- import * as React from "react"
2
- import * as SelectPrimitive from "@radix-ui/react-select"
3
- import { Check, ChevronDown, ChevronUp } from "lucide-react"
4
-
5
- import { cn } from "../../cn"
6
-
7
- const Select = SelectPrimitive.Root
8
-
9
- const SelectGroup = SelectPrimitive.Group
10
-
11
- const SelectValue = SelectPrimitive.Value
12
-
13
- const SelectTrigger = React.forwardRef<
14
- React.ElementRef<typeof SelectPrimitive.Trigger>,
15
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
16
- >(({ className, children, ...props }, ref) => (
17
- <SelectPrimitive.Trigger
18
- ref={ref}
19
- className={cn(
20
- "flex h-10 w-full items-center justify-between rounded-md border border-input bg-field px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
21
- className
22
- )}
23
- {...props}
24
- >
25
- {children}
26
- <SelectPrimitive.Icon asChild>
27
- <ChevronDown className="h-4 w-4 opacity-50" />
28
- </SelectPrimitive.Icon>
29
- </SelectPrimitive.Trigger>
30
- ))
31
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
32
-
33
- const SelectScrollUpButton = React.forwardRef<
34
- React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
35
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
36
- >(({ className, ...props }, ref) => (
37
- <SelectPrimitive.ScrollUpButton
38
- ref={ref}
39
- className={cn(
40
- "flex cursor-default items-center justify-center py-1",
41
- className
42
- )}
43
- {...props}
44
- >
45
- <ChevronUp className="h-4 w-4" />
46
- </SelectPrimitive.ScrollUpButton>
47
- ))
48
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
49
-
50
- const SelectScrollDownButton = React.forwardRef<
51
- React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
52
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
53
- >(({ className, ...props }, ref) => (
54
- <SelectPrimitive.ScrollDownButton
55
- ref={ref}
56
- className={cn(
57
- "flex cursor-default items-center justify-center py-1",
58
- className
59
- )}
60
- {...props}
61
- >
62
- <ChevronDown className="h-4 w-4" />
63
- </SelectPrimitive.ScrollDownButton>
64
- ))
65
- SelectScrollDownButton.displayName =
66
- SelectPrimitive.ScrollDownButton.displayName
67
-
68
- const SelectContent = React.forwardRef<
69
- React.ElementRef<typeof SelectPrimitive.Content>,
70
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
71
- >(({ className, children, position = "popper", ...props }, ref) => (
72
- <SelectPrimitive.Portal>
73
- <SelectPrimitive.Content
74
- ref={ref}
75
- className={cn(
76
- // font-sans + fh-builder-portal: portaled to <body>, outside the builder
77
- // root — pin the font and opt into the themed scrollbar explicitly.
78
- "fh-builder-portal font-sans relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
79
- position === "popper" &&
80
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
81
- className
82
- )}
83
- position={position}
84
- {...props}
85
- >
86
- <SelectScrollUpButton />
87
- <SelectPrimitive.Viewport
88
- className={cn(
89
- "p-1",
90
- position === "popper" &&
91
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
92
- )}
93
- >
94
- {children}
95
- </SelectPrimitive.Viewport>
96
- <SelectScrollDownButton />
97
- </SelectPrimitive.Content>
98
- </SelectPrimitive.Portal>
99
- ))
100
- SelectContent.displayName = SelectPrimitive.Content.displayName
101
-
102
- const SelectLabel = React.forwardRef<
103
- React.ElementRef<typeof SelectPrimitive.Label>,
104
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
105
- >(({ className, ...props }, ref) => (
106
- <SelectPrimitive.Label
107
- ref={ref}
108
- className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
109
- {...props}
110
- />
111
- ))
112
- SelectLabel.displayName = SelectPrimitive.Label.displayName
113
-
114
- const SelectItem = React.forwardRef<
115
- React.ElementRef<typeof SelectPrimitive.Item>,
116
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
117
- >(({ className, children, ...props }, ref) => (
118
- <SelectPrimitive.Item
119
- ref={ref}
120
- className={cn(
121
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
122
- className
123
- )}
124
- {...props}
125
- >
126
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127
- <SelectPrimitive.ItemIndicator>
128
- <Check className="h-4 w-4" />
129
- </SelectPrimitive.ItemIndicator>
130
- </span>
131
-
132
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
133
- </SelectPrimitive.Item>
134
- ))
135
- SelectItem.displayName = SelectPrimitive.Item.displayName
136
-
137
- const SelectSeparator = React.forwardRef<
138
- React.ElementRef<typeof SelectPrimitive.Separator>,
139
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
140
- >(({ className, ...props }, ref) => (
141
- <SelectPrimitive.Separator
142
- ref={ref}
143
- className={cn("-mx-1 my-1 h-px bg-muted", className)}
144
- {...props}
145
- />
146
- ))
147
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName
148
-
149
- export {
150
- Select,
151
- SelectGroup,
152
- SelectValue,
153
- SelectTrigger,
154
- SelectContent,
155
- SelectLabel,
156
- SelectItem,
157
- SelectSeparator,
158
- SelectScrollUpButton,
159
- SelectScrollDownButton,
160
- }
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (c) 2026 ForestHub. All rights reserved.
3
+ // For commercial licensing, contact root@foresthub.ai
4
+
5
+ import * as React from "react"
6
+ import * as SelectPrimitive from "@radix-ui/react-select"
7
+ import { Check, ChevronDown, ChevronUp } from "lucide-react"
8
+
9
+ import { cn } from "../../cn"
10
+
11
+ const Select = SelectPrimitive.Root
12
+
13
+ const SelectGroup = SelectPrimitive.Group
14
+
15
+ const SelectValue = SelectPrimitive.Value
16
+
17
+ const SelectTrigger = React.forwardRef<
18
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
19
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
20
+ >(({ className, children, ...props }, ref) => (
21
+ <SelectPrimitive.Trigger
22
+ ref={ref}
23
+ className={cn(
24
+ "flex h-10 w-full items-center justify-between rounded-md border border-input bg-field px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
25
+ className
26
+ )}
27
+ {...props}
28
+ >
29
+ {children}
30
+ <SelectPrimitive.Icon asChild>
31
+ <ChevronDown className="h-4 w-4 opacity-50" />
32
+ </SelectPrimitive.Icon>
33
+ </SelectPrimitive.Trigger>
34
+ ))
35
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
36
+
37
+ const SelectScrollUpButton = React.forwardRef<
38
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
39
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
40
+ >(({ className, ...props }, ref) => (
41
+ <SelectPrimitive.ScrollUpButton
42
+ ref={ref}
43
+ className={cn(
44
+ "flex cursor-default items-center justify-center py-1",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ <ChevronUp className="h-4 w-4" />
50
+ </SelectPrimitive.ScrollUpButton>
51
+ ))
52
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
53
+
54
+ const SelectScrollDownButton = React.forwardRef<
55
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
56
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
57
+ >(({ className, ...props }, ref) => (
58
+ <SelectPrimitive.ScrollDownButton
59
+ ref={ref}
60
+ className={cn(
61
+ "flex cursor-default items-center justify-center py-1",
62
+ className
63
+ )}
64
+ {...props}
65
+ >
66
+ <ChevronDown className="h-4 w-4" />
67
+ </SelectPrimitive.ScrollDownButton>
68
+ ))
69
+ SelectScrollDownButton.displayName =
70
+ SelectPrimitive.ScrollDownButton.displayName
71
+
72
+ const SelectContent = React.forwardRef<
73
+ React.ElementRef<typeof SelectPrimitive.Content>,
74
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
75
+ >(({ className, children, position = "popper", ...props }, ref) => (
76
+ <SelectPrimitive.Portal>
77
+ <SelectPrimitive.Content
78
+ ref={ref}
79
+ className={cn(
80
+ // font-sans + fh-builder-portal: portaled to <body>, outside the builder
81
+ // root — pin the font and opt into the themed scrollbar explicitly.
82
+ "fh-builder-portal font-sans relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
83
+ position === "popper" &&
84
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
85
+ className
86
+ )}
87
+ position={position}
88
+ {...props}
89
+ >
90
+ <SelectScrollUpButton />
91
+ <SelectPrimitive.Viewport
92
+ className={cn(
93
+ "p-1",
94
+ position === "popper" &&
95
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
96
+ )}
97
+ >
98
+ {children}
99
+ </SelectPrimitive.Viewport>
100
+ <SelectScrollDownButton />
101
+ </SelectPrimitive.Content>
102
+ </SelectPrimitive.Portal>
103
+ ))
104
+ SelectContent.displayName = SelectPrimitive.Content.displayName
105
+
106
+ const SelectLabel = React.forwardRef<
107
+ React.ElementRef<typeof SelectPrimitive.Label>,
108
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
109
+ >(({ className, ...props }, ref) => (
110
+ <SelectPrimitive.Label
111
+ ref={ref}
112
+ className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
113
+ {...props}
114
+ />
115
+ ))
116
+ SelectLabel.displayName = SelectPrimitive.Label.displayName
117
+
118
+ const SelectItem = React.forwardRef<
119
+ React.ElementRef<typeof SelectPrimitive.Item>,
120
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
121
+ >(({ className, children, ...props }, ref) => (
122
+ <SelectPrimitive.Item
123
+ ref={ref}
124
+ className={cn(
125
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
126
+ className
127
+ )}
128
+ {...props}
129
+ >
130
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
131
+ <SelectPrimitive.ItemIndicator>
132
+ <Check className="h-4 w-4" />
133
+ </SelectPrimitive.ItemIndicator>
134
+ </span>
135
+
136
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
137
+ </SelectPrimitive.Item>
138
+ ))
139
+ SelectItem.displayName = SelectPrimitive.Item.displayName
140
+
141
+ const SelectSeparator = React.forwardRef<
142
+ React.ElementRef<typeof SelectPrimitive.Separator>,
143
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
144
+ >(({ className, ...props }, ref) => (
145
+ <SelectPrimitive.Separator
146
+ ref={ref}
147
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
148
+ {...props}
149
+ />
150
+ ))
151
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName
152
+
153
+ export {
154
+ Select,
155
+ SelectGroup,
156
+ SelectValue,
157
+ SelectTrigger,
158
+ SelectContent,
159
+ SelectLabel,
160
+ SelectItem,
161
+ SelectSeparator,
162
+ SelectScrollUpButton,
163
+ SelectScrollDownButton,
164
+ }