@treenity/react 3.0.0 → 3.0.2

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 (379) hide show
  1. package/README.md +91 -0
  2. package/dist/AclEditor.d.ts +1 -1
  3. package/dist/AclEditor.d.ts.map +1 -1
  4. package/dist/AclEditor.js +5 -5
  5. package/dist/AclEditor.js.map +1 -1
  6. package/dist/ActionCards.d.ts +9 -0
  7. package/dist/ActionCards.d.ts.map +1 -0
  8. package/dist/ActionCards.js +96 -0
  9. package/dist/ActionCards.js.map +1 -0
  10. package/dist/App.d.ts.map +1 -1
  11. package/dist/App.js +97 -185
  12. package/dist/App.js.map +1 -1
  13. package/dist/ComponentSection.d.ts +15 -0
  14. package/dist/ComponentSection.d.ts.map +1 -0
  15. package/dist/ComponentSection.js +25 -0
  16. package/dist/ComponentSection.js.map +1 -0
  17. package/dist/ErrorBoundary.d.ts +18 -0
  18. package/dist/ErrorBoundary.d.ts.map +1 -0
  19. package/dist/ErrorBoundary.js +18 -0
  20. package/dist/ErrorBoundary.js.map +1 -0
  21. package/dist/Inspector.d.ts +1 -0
  22. package/dist/Inspector.d.ts.map +1 -1
  23. package/dist/Inspector.js +22 -347
  24. package/dist/Inspector.js.map +1 -1
  25. package/dist/Login.d.ts +8 -0
  26. package/dist/Login.d.ts.map +1 -0
  27. package/dist/Login.js +45 -0
  28. package/dist/Login.js.map +1 -0
  29. package/dist/NodeEditor.d.ts +11 -0
  30. package/dist/NodeEditor.d.ts.map +1 -0
  31. package/dist/NodeEditor.js +157 -0
  32. package/dist/NodeEditor.js.map +1 -0
  33. package/dist/Tree.d.ts +1 -0
  34. package/dist/Tree.d.ts.map +1 -1
  35. package/dist/Tree.js +8 -27
  36. package/dist/Tree.js.map +1 -1
  37. package/dist/bind/engine.js +1 -1
  38. package/dist/bind/engine.js.map +1 -1
  39. package/dist/bind/eval.d.ts +1 -1
  40. package/dist/bind/eval.d.ts.map +1 -1
  41. package/dist/bind/hook.d.ts +1 -1
  42. package/dist/bind/hook.d.ts.map +1 -1
  43. package/dist/bind/hook.js +1 -1
  44. package/dist/bind/hook.js.map +1 -1
  45. package/dist/cache.d.ts +1 -1
  46. package/dist/cache.d.ts.map +1 -1
  47. package/dist/cache.js +9 -0
  48. package/dist/cache.js.map +1 -1
  49. package/dist/client-tree.d.ts +1 -2
  50. package/dist/client-tree.d.ts.map +1 -1
  51. package/dist/client-tree.js +12 -5
  52. package/dist/client-tree.js.map +1 -1
  53. package/dist/client.d.ts +1 -1
  54. package/dist/client.d.ts.map +1 -1
  55. package/dist/client.js +2 -4
  56. package/dist/client.js.map +1 -1
  57. package/dist/components/ConfirmDialog.d.ts +9 -0
  58. package/dist/components/ConfirmDialog.d.ts.map +1 -0
  59. package/dist/components/ConfirmDialog.js +6 -0
  60. package/dist/components/ConfirmDialog.js.map +1 -0
  61. package/dist/components/ConfirmPopover.d.ts +8 -0
  62. package/dist/components/ConfirmPopover.d.ts.map +1 -0
  63. package/dist/components/ConfirmPopover.js +9 -0
  64. package/dist/components/ConfirmPopover.js.map +1 -0
  65. package/dist/components/PathBreadcrumb.d.ts +5 -0
  66. package/dist/components/PathBreadcrumb.d.ts.map +1 -0
  67. package/dist/components/PathBreadcrumb.js +16 -0
  68. package/dist/components/PathBreadcrumb.js.map +1 -0
  69. package/dist/components/lib/utils.d.ts +3 -0
  70. package/dist/components/lib/utils.d.ts.map +1 -0
  71. package/dist/components/lib/utils.js +6 -0
  72. package/dist/components/lib/utils.js.map +1 -0
  73. package/dist/components/ui/accordion.js +1 -1
  74. package/dist/components/ui/accordion.js.map +1 -1
  75. package/dist/components/ui/alert-dialog.d.ts +19 -0
  76. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  77. package/dist/components/ui/alert-dialog.js +42 -0
  78. package/dist/components/ui/alert-dialog.js.map +1 -0
  79. package/dist/components/ui/badge.js +1 -1
  80. package/dist/components/ui/badge.js.map +1 -1
  81. package/dist/components/ui/breadcrumb.d.ts +12 -0
  82. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  83. package/dist/components/ui/breadcrumb.js +28 -0
  84. package/dist/components/ui/breadcrumb.js.map +1 -0
  85. package/dist/components/ui/button.d.ts +8 -7
  86. package/dist/components/ui/button.d.ts.map +1 -1
  87. package/dist/components/ui/button.js +25 -20
  88. package/dist/components/ui/button.js.map +1 -1
  89. package/dist/components/ui/card.d.ts +10 -0
  90. package/dist/components/ui/card.d.ts.map +1 -0
  91. package/dist/components/ui/card.js +25 -0
  92. package/dist/components/ui/card.js.map +1 -0
  93. package/dist/components/ui/checkbox.js +1 -1
  94. package/dist/components/ui/checkbox.js.map +1 -1
  95. package/dist/components/ui/collapsible.d.ts +6 -0
  96. package/dist/components/ui/collapsible.d.ts.map +1 -0
  97. package/dist/components/ui/collapsible.js +13 -0
  98. package/dist/components/ui/collapsible.js.map +1 -0
  99. package/dist/components/ui/command.d.ts +19 -0
  100. package/dist/components/ui/command.d.ts.map +1 -0
  101. package/dist/components/ui/command.js +35 -0
  102. package/dist/components/ui/command.js.map +1 -0
  103. package/dist/components/ui/dialog.d.ts.map +1 -1
  104. package/dist/components/ui/dialog.js +1 -1
  105. package/dist/components/ui/dialog.js.map +1 -1
  106. package/dist/components/ui/drawer.js +1 -1
  107. package/dist/components/ui/drawer.js.map +1 -1
  108. package/dist/components/ui/dropdown-menu.d.ts +26 -0
  109. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  110. package/dist/components/ui/dropdown-menu.js +52 -0
  111. package/dist/components/ui/dropdown-menu.js.map +1 -0
  112. package/dist/components/ui/form-field.d.ts +7 -0
  113. package/dist/components/ui/form-field.d.ts.map +1 -0
  114. package/dist/components/ui/form-field.js +17 -0
  115. package/dist/components/ui/form-field.js.map +1 -0
  116. package/dist/components/ui/input.js +1 -1
  117. package/dist/components/ui/input.js.map +1 -1
  118. package/dist/components/ui/label.js +1 -1
  119. package/dist/components/ui/label.js.map +1 -1
  120. package/dist/components/ui/pagination.d.ts +14 -0
  121. package/dist/components/ui/pagination.d.ts.map +1 -0
  122. package/dist/components/ui/pagination.js +30 -0
  123. package/dist/components/ui/pagination.js.map +1 -0
  124. package/dist/components/ui/popover.js +2 -2
  125. package/dist/components/ui/popover.js.map +1 -1
  126. package/dist/components/ui/progress.js +1 -1
  127. package/dist/components/ui/progress.js.map +1 -1
  128. package/dist/components/ui/resizable.d.ts +8 -0
  129. package/dist/components/ui/resizable.d.ts.map +1 -0
  130. package/dist/components/ui/resizable.js +14 -0
  131. package/dist/components/ui/resizable.js.map +1 -0
  132. package/dist/components/ui/scroll-area.d.ts +6 -0
  133. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  134. package/dist/components/ui/scroll-area.js +13 -0
  135. package/dist/components/ui/scroll-area.js.map +1 -0
  136. package/dist/components/ui/select.js +1 -1
  137. package/dist/components/ui/select.js.map +1 -1
  138. package/dist/components/ui/separator.d.ts +5 -0
  139. package/dist/components/ui/separator.d.ts.map +1 -0
  140. package/dist/components/ui/separator.js +9 -0
  141. package/dist/components/ui/separator.js.map +1 -0
  142. package/dist/components/ui/sheet.d.ts +15 -0
  143. package/dist/components/ui/sheet.d.ts.map +1 -0
  144. package/dist/components/ui/sheet.js +40 -0
  145. package/dist/components/ui/sheet.js.map +1 -0
  146. package/dist/components/ui/skeleton.d.ts +3 -0
  147. package/dist/components/ui/skeleton.d.ts.map +1 -0
  148. package/dist/components/ui/skeleton.js +7 -0
  149. package/dist/components/ui/skeleton.js.map +1 -0
  150. package/dist/components/ui/slider.js +1 -1
  151. package/dist/components/ui/slider.js.map +1 -1
  152. package/dist/components/ui/switch.js +1 -1
  153. package/dist/components/ui/switch.js.map +1 -1
  154. package/dist/components/ui/table.d.ts +11 -0
  155. package/dist/components/ui/table.d.ts.map +1 -0
  156. package/dist/components/ui/table.js +29 -0
  157. package/dist/components/ui/table.js.map +1 -0
  158. package/dist/components/ui/tabs.d.ts +12 -0
  159. package/dist/components/ui/tabs.d.ts.map +1 -0
  160. package/dist/components/ui/tabs.js +29 -0
  161. package/dist/components/ui/tabs.js.map +1 -0
  162. package/dist/components/ui/textarea.js +2 -2
  163. package/dist/components/ui/textarea.js.map +1 -1
  164. package/dist/components/ui/toggle-group.d.ts +10 -0
  165. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  166. package/dist/components/ui/toggle-group.js +23 -0
  167. package/dist/components/ui/toggle-group.js.map +1 -0
  168. package/dist/components/ui/toggle.d.ts +10 -0
  169. package/dist/components/ui/toggle.d.ts.map +1 -0
  170. package/dist/components/ui/toggle.js +27 -0
  171. package/dist/components/ui/toggle.js.map +1 -0
  172. package/dist/components/ui/tooltip.js +1 -1
  173. package/dist/components/ui/tooltip.js.map +1 -1
  174. package/dist/context/index.d.ts +27 -10
  175. package/dist/context/index.d.ts.map +1 -1
  176. package/dist/context/index.js +43 -36
  177. package/dist/context/index.js.map +1 -1
  178. package/dist/events.d.ts +12 -0
  179. package/dist/events.d.ts.map +1 -0
  180. package/dist/events.js +123 -0
  181. package/dist/events.js.map +1 -0
  182. package/dist/fiber-tree.d.ts +3 -0
  183. package/dist/fiber-tree.d.ts.map +1 -0
  184. package/dist/fiber-tree.js +93 -0
  185. package/dist/fiber-tree.js.map +1 -0
  186. package/dist/hooks.d.ts +14 -2
  187. package/dist/hooks.d.ts.map +1 -1
  188. package/dist/hooks.js +146 -11
  189. package/dist/hooks.js.map +1 -1
  190. package/dist/idb.d.ts +1 -1
  191. package/dist/idb.d.ts.map +1 -1
  192. package/dist/lib/minimd.d.ts.map +1 -1
  193. package/dist/lib/minimd.js +8 -1
  194. package/dist/lib/minimd.js.map +1 -1
  195. package/dist/lib/sanitize-href.d.ts +3 -0
  196. package/dist/lib/sanitize-href.d.ts.map +1 -0
  197. package/dist/lib/sanitize-href.js +14 -0
  198. package/dist/lib/sanitize-href.js.map +1 -0
  199. package/dist/lib/to-plain.d.ts +2 -0
  200. package/dist/lib/to-plain.d.ts.map +1 -0
  201. package/dist/lib/to-plain.js +21 -0
  202. package/dist/lib/to-plain.js.map +1 -0
  203. package/dist/main.d.ts +1 -1
  204. package/dist/main.d.ts.map +1 -1
  205. package/dist/main.js +11 -4
  206. package/dist/main.js.map +1 -1
  207. package/dist/mods/clients.d.ts +3 -0
  208. package/dist/mods/clients.d.ts.map +1 -0
  209. package/dist/mods/clients.js +4 -0
  210. package/dist/mods/clients.js.map +1 -0
  211. package/dist/mods/editor-ui/FieldLabel.d.ts +15 -0
  212. package/dist/mods/editor-ui/FieldLabel.d.ts.map +1 -0
  213. package/dist/mods/editor-ui/FieldLabel.js +56 -0
  214. package/dist/mods/editor-ui/FieldLabel.js.map +1 -0
  215. package/dist/mods/editor-ui/client.d.ts +1 -1
  216. package/dist/mods/editor-ui/client.d.ts.map +1 -1
  217. package/dist/mods/editor-ui/client.js +1 -1
  218. package/dist/mods/editor-ui/client.js.map +1 -1
  219. package/dist/mods/editor-ui/default-edit.d.ts +2 -0
  220. package/dist/mods/editor-ui/default-edit.d.ts.map +1 -0
  221. package/dist/mods/editor-ui/default-edit.js +56 -0
  222. package/dist/mods/editor-ui/default-edit.js.map +1 -0
  223. package/dist/mods/editor-ui/default-view.d.ts +8 -1
  224. package/dist/mods/editor-ui/default-view.d.ts.map +1 -1
  225. package/dist/mods/editor-ui/default-view.js +8 -5
  226. package/dist/mods/editor-ui/default-view.js.map +1 -1
  227. package/dist/mods/editor-ui/dir-view.js +0 -2
  228. package/dist/mods/editor-ui/dir-view.js.map +1 -1
  229. package/dist/mods/editor-ui/empty-placeholder.d.ts +5 -0
  230. package/dist/mods/editor-ui/empty-placeholder.d.ts.map +1 -0
  231. package/dist/mods/editor-ui/empty-placeholder.js +14 -0
  232. package/dist/mods/editor-ui/empty-placeholder.js.map +1 -0
  233. package/dist/mods/editor-ui/form-field.d.ts +17 -0
  234. package/dist/mods/editor-ui/form-field.d.ts.map +1 -0
  235. package/dist/mods/editor-ui/form-field.js +69 -0
  236. package/dist/mods/editor-ui/form-field.js.map +1 -0
  237. package/dist/mods/editor-ui/form-fields.d.ts +1 -2
  238. package/dist/mods/editor-ui/form-fields.d.ts.map +1 -1
  239. package/dist/mods/editor-ui/form-fields.js +56 -60
  240. package/dist/mods/editor-ui/form-fields.js.map +1 -1
  241. package/dist/mods/editor-ui/layout-view.js +3 -2
  242. package/dist/mods/editor-ui/layout-view.js.map +1 -1
  243. package/dist/mods/editor-ui/list-items.js +1 -1
  244. package/dist/mods/editor-ui/list-items.js.map +1 -1
  245. package/dist/mods/editor-ui/node-utils.d.ts +2 -2
  246. package/dist/mods/editor-ui/node-utils.d.ts.map +1 -1
  247. package/dist/mods/editor-ui/node-utils.js +4 -5
  248. package/dist/mods/editor-ui/node-utils.js.map +1 -1
  249. package/dist/mods/editor-ui/type-picker.d.ts +15 -0
  250. package/dist/mods/editor-ui/type-picker.d.ts.map +1 -0
  251. package/dist/mods/editor-ui/type-picker.js +70 -0
  252. package/dist/mods/editor-ui/type-picker.js.map +1 -0
  253. package/dist/mods/editor-ui/user-view.js +1 -1
  254. package/dist/mods/editor-ui/user-view.js.map +1 -1
  255. package/dist/mods/servers.d.ts +1 -0
  256. package/dist/mods/servers.d.ts.map +1 -0
  257. package/dist/mods/servers.js +4 -0
  258. package/dist/mods/servers.js.map +1 -0
  259. package/dist/mods/treenity/groups/index.js +1 -1
  260. package/dist/mods/treenity/groups/index.js.map +1 -1
  261. package/dist/mods/treenity/preview.d.ts.map +1 -1
  262. package/dist/mods/treenity/preview.js +3 -4
  263. package/dist/mods/treenity/preview.js.map +1 -1
  264. package/dist/mods/treenity/ref-view.js +3 -2
  265. package/dist/mods/treenity/ref-view.js.map +1 -1
  266. package/dist/mods/treenity/schema-form.js +1 -1
  267. package/dist/mods/treenity/schema-form.js.map +1 -1
  268. package/dist/mods/treenity/seed.js +3 -2
  269. package/dist/mods/treenity/seed.js.map +1 -1
  270. package/dist/mods/treenity/type-view.js +1 -1
  271. package/dist/mods/treenity/type-view.js.map +1 -1
  272. package/dist/schema-loader.d.ts +1 -1
  273. package/dist/schema-loader.d.ts.map +1 -1
  274. package/dist/schema-loader.js +1 -1
  275. package/dist/schema-loader.js.map +1 -1
  276. package/dist/symbols.d.ts +5 -0
  277. package/dist/symbols.d.ts.map +1 -0
  278. package/dist/symbols.js +22 -0
  279. package/dist/symbols.js.map +1 -0
  280. package/dist/trpc.d.ts +10 -3
  281. package/dist/trpc.d.ts.map +1 -1
  282. package/package.json +76 -8
  283. package/src/AclEditor.tsx +11 -18
  284. package/src/ActionCards.tsx +224 -0
  285. package/src/App.tsx +232 -385
  286. package/src/ComponentSection.tsx +113 -0
  287. package/src/ErrorBoundary.tsx +40 -0
  288. package/src/Inspector.css +54 -0
  289. package/src/Inspector.tsx +73 -793
  290. package/src/Login.tsx +97 -0
  291. package/src/NodeEditor.tsx +300 -0
  292. package/src/Tree.css +91 -0
  293. package/src/Tree.tsx +40 -43
  294. package/src/bind/engine.ts +1 -1
  295. package/src/bind/eval.ts +1 -1
  296. package/src/bind/hook.ts +1 -1
  297. package/src/bind/pipes.ts +1 -1
  298. package/src/cache.ts +12 -1
  299. package/src/client-tree.ts +18 -12
  300. package/src/client.ts +2 -4
  301. package/src/components/ConfirmDialog.tsx +34 -0
  302. package/src/components/ConfirmPopover.tsx +41 -0
  303. package/src/components/PathBreadcrumb.tsx +36 -0
  304. package/src/components/lib/utils.ts +6 -0
  305. package/src/components/lib/utils.ts.bak +6 -0
  306. package/src/components/ui/accordion.tsx +1 -1
  307. package/src/components/ui/alert-dialog.tsx +189 -0
  308. package/src/components/ui/badge.tsx +1 -1
  309. package/src/components/ui/breadcrumb.tsx +108 -0
  310. package/src/components/ui/button.tsx +51 -30
  311. package/src/components/ui/card.tsx +91 -0
  312. package/src/components/ui/checkbox.tsx +1 -1
  313. package/src/components/ui/collapsible.tsx +31 -0
  314. package/src/components/ui/command.tsx +177 -0
  315. package/src/components/ui/dialog.tsx +1 -2
  316. package/src/components/ui/drawer.tsx +1 -1
  317. package/src/components/ui/dropdown-menu.tsx +256 -0
  318. package/src/components/ui/form-field.tsx +37 -0
  319. package/src/components/ui/input.tsx +1 -1
  320. package/src/components/ui/label.tsx +1 -1
  321. package/src/components/ui/pagination.tsx +122 -0
  322. package/src/components/ui/popover.tsx +2 -2
  323. package/src/components/ui/progress.tsx +1 -1
  324. package/src/components/ui/resizable.tsx +47 -0
  325. package/src/components/ui/scroll-area.tsx +55 -0
  326. package/src/components/ui/select.tsx +1 -1
  327. package/src/components/ui/separator.tsx +27 -0
  328. package/src/components/ui/sheet.tsx +140 -0
  329. package/src/components/ui/skeleton.tsx +13 -0
  330. package/src/components/ui/slider.tsx +1 -1
  331. package/src/components/ui/switch.tsx +1 -1
  332. package/src/components/ui/table.tsx +115 -0
  333. package/src/components/ui/tabs.tsx +88 -0
  334. package/src/components/ui/textarea.tsx +2 -2
  335. package/src/components/ui/toggle-group.tsx +82 -0
  336. package/src/components/ui/toggle.tsx +46 -0
  337. package/src/components/ui/tooltip.tsx +1 -1
  338. package/src/context/index.tsx +75 -42
  339. package/src/events.ts +121 -0
  340. package/src/fiber-tree.ts +112 -0
  341. package/src/hooks.ts +161 -13
  342. package/src/idb.ts +1 -1
  343. package/src/lib/minimd.ts +7 -1
  344. package/src/lib/sanitize-href.ts +13 -0
  345. package/src/lib/to-plain.ts +21 -0
  346. package/src/main.tsx +14 -4
  347. package/src/mods/clients.ts +3 -0
  348. package/src/mods/editor-ui/FieldLabel.tsx +125 -0
  349. package/src/mods/editor-ui/client.ts +1 -1
  350. package/src/mods/editor-ui/default-edit.tsx +101 -0
  351. package/src/mods/editor-ui/default-view.tsx +13 -8
  352. package/src/mods/editor-ui/dir-view.tsx +2 -2
  353. package/src/mods/editor-ui/editor-ui.css +174 -0
  354. package/src/mods/editor-ui/empty-placeholder.tsx +39 -0
  355. package/src/mods/editor-ui/form-field.tsx +146 -0
  356. package/src/mods/editor-ui/form-fields.tsx +132 -113
  357. package/src/mods/editor-ui/layout-view.tsx +4 -2
  358. package/src/mods/editor-ui/list-items.tsx +2 -2
  359. package/src/mods/editor-ui/node-utils.ts +4 -5
  360. package/src/mods/editor-ui/type-picker.tsx +148 -0
  361. package/src/mods/editor-ui/user-view.tsx +1 -1
  362. package/src/mods/servers.ts +2 -0
  363. package/src/mods/treenity/groups/index.tsx +1 -1
  364. package/src/mods/treenity/preview.tsx +7 -8
  365. package/src/mods/treenity/ref-view.tsx +12 -7
  366. package/src/mods/treenity/schema-form.tsx +1 -1
  367. package/src/mods/treenity/seed.ts +3 -2
  368. package/src/mods/treenity/type-view.tsx +1 -1
  369. package/src/remote-tree.ts +1 -1
  370. package/src/root.css +117 -0
  371. package/src/schema-loader.ts +1 -1
  372. package/src/symbols.ts +25 -0
  373. package/src/bind/bind.test.ts +0 -316
  374. package/src/cache.test.ts +0 -139
  375. package/src/client-tree.test.ts +0 -116
  376. package/src/index.html +0 -14
  377. package/src/remote-tree.test.ts +0 -142
  378. package/src/style.css +0 -1269
  379. package/src/vite-env.d.ts +0 -3
@@ -0,0 +1,174 @@
1
+ /* Form fields */
2
+ .field {
3
+ display: flex;
4
+ align-items: center;
5
+ gap: 8px;
6
+ margin-bottom: 4px;
7
+ }
8
+ .field:last-child {
9
+ margin-bottom: 0;
10
+ }
11
+ .field label {
12
+ font-size: 11px;
13
+ font-weight: 500;
14
+ color: var(--text-2);
15
+ width: 60px;
16
+ flex-shrink: 0;
17
+ white-space: nowrap;
18
+ position: relative;
19
+ }
20
+ .field:has(textarea),
21
+ .field.stack {
22
+ flex-direction: column;
23
+ align-items: stretch;
24
+ }
25
+ .field:has(textarea) label,
26
+ .field.stack label {
27
+ min-width: unset;
28
+ margin-bottom: 3px;
29
+ }
30
+
31
+ /* Component data view — shows field values in default view */
32
+ .comp-view-card {
33
+ background: var(--surface);
34
+ border: 1px solid var(--border);
35
+ border-radius: var(--radius-lg);
36
+ padding: 14px 16px;
37
+ margin-bottom: 12px;
38
+ }
39
+ .comp-view-header {
40
+ font-size: 11px;
41
+ font-weight: 600;
42
+ color: var(--text-3);
43
+ text-transform: uppercase;
44
+ letter-spacing: 0.5px;
45
+ margin-bottom: 10px;
46
+ display: flex;
47
+ align-items: center;
48
+ gap: 8px;
49
+ }
50
+ .comp-view-header .comp-type {
51
+ font-family: var(--mono);
52
+ color: var(--accent);
53
+ background: var(--accent-subtle);
54
+ padding: 1px 6px;
55
+ border-radius: 10px;
56
+ font-size: 10px;
57
+ text-transform: none;
58
+ }
59
+ .comp-view-row {
60
+ display: flex;
61
+ gap: 8px;
62
+ font-size: 13px;
63
+ padding: 3px 0;
64
+ }
65
+ .comp-view-label {
66
+ color: var(--text-3);
67
+ min-width: 80px;
68
+ flex-shrink: 0;
69
+ }
70
+ .comp-view-value {
71
+ color: var(--text);
72
+ word-break: break-word;
73
+ }
74
+
75
+ /* Info bar — compact chips for components and fields */
76
+ .node-info-bar {
77
+ display: flex;
78
+ flex-wrap: wrap;
79
+ gap: 8px;
80
+ margin-bottom: 20px;
81
+ }
82
+ .node-info-chip {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: 6px;
86
+ padding: 4px 10px;
87
+ border-radius: 16px;
88
+ background: var(--surface);
89
+ border: 1px solid var(--border);
90
+ font-size: 12px;
91
+ }
92
+ .node-info-chip-label {
93
+ color: var(--text-2);
94
+ font-weight: 500;
95
+ }
96
+ .node-info-chip.data .node-info-chip-val {
97
+ color: var(--text);
98
+ max-width: 120px;
99
+ overflow: hidden;
100
+ text-overflow: ellipsis;
101
+ white-space: nowrap;
102
+ }
103
+
104
+ /* Children grid — file explorer cards with staggered reveal */
105
+ .children-grid {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 2px;
109
+ }
110
+
111
+ .child-card {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 12px;
115
+ padding: 10px 14px;
116
+ border-radius: var(--radius);
117
+ cursor: pointer;
118
+ transition: all var(--transition);
119
+ }
120
+ .child-card:hover {
121
+ background: var(--surface);
122
+ }
123
+
124
+ .child-icon {
125
+ width: 32px;
126
+ height: 32px;
127
+ border-radius: 8px;
128
+ background: var(--surface-2);
129
+ border: 1px solid var(--border);
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ font-size: 13px;
134
+ font-weight: 600;
135
+ color: var(--text-2);
136
+ flex-shrink: 0;
137
+ }
138
+ .child-info {
139
+ flex: 1;
140
+ min-width: 0;
141
+ }
142
+ .child-name {
143
+ display: block;
144
+ font-size: 13px;
145
+ font-weight: 500;
146
+ color: var(--text);
147
+ overflow: hidden;
148
+ text-overflow: ellipsis;
149
+ white-space: nowrap;
150
+ }
151
+ .child-type {
152
+ display: block;
153
+ font-size: 11px;
154
+ color: var(--text-3);
155
+ font-family: var(--mono);
156
+ margin-top: 1px;
157
+ }
158
+ .child-chevron {
159
+ color: var(--text-3);
160
+ font-size: 18px;
161
+ flex-shrink: 0;
162
+ transition: transform var(--transition);
163
+ }
164
+ .child-card:hover .child-chevron {
165
+ transform: translateX(2px);
166
+ color: var(--text-2);
167
+ }
168
+
169
+ .node-empty {
170
+ color: var(--text-3);
171
+ font-size: 13px;
172
+ padding: 40px;
173
+ text-align: center;
174
+ }
@@ -0,0 +1,39 @@
1
+ import { Button } from '#components/ui/button';
2
+ import { set } from '#hooks';
3
+ import type { NodeData } from '@treenity/core';
4
+ import { Plus } from 'lucide-react';
5
+ import { useState } from 'react';
6
+ import { TypePicker } from './type-picker';
7
+
8
+ export function EmptyNodePlaceholder({ value }: { value: NodeData }) {
9
+ const [picking, setPicking] = useState(false);
10
+
11
+ return (
12
+ <div className="flex flex-col items-center justify-center gap-3 py-12 px-6">
13
+ <div className="text-[13px] text-[--text-3]">Empty node</div>
14
+ <Button
15
+ variant="outline"
16
+ size="sm"
17
+ onClick={() => setPicking(true)}
18
+ className="text-[12px] text-[--text-3] hover:text-[--accent] hover:bg-[--accent]/10"
19
+ >
20
+ <Plus className="w-3.5 h-3.5" />
21
+ Add Component
22
+ </Button>
23
+
24
+ {picking && (
25
+ <TypePicker
26
+ title="Add Component"
27
+ nameLabel="Component name"
28
+ action="Add"
29
+ autoName
30
+ onCancel={() => setPicking(false)}
31
+ onSelect={async (name, type) => {
32
+ setPicking(false);
33
+ await set({ ...value, [name]: { $type: type } });
34
+ }}
35
+ />
36
+ )}
37
+ </div>
38
+ );
39
+ }
@@ -0,0 +1,146 @@
1
+ import { Button } from '#components/ui/button';
2
+ import { Input } from '#components/ui/input';
3
+ import { Textarea } from '#components/ui/textarea';
4
+ import { isRef, resolveExact } from '@treenity/core';
5
+ import { createElement, useState } from 'react';
6
+ import { FieldLabel, RefEditor } from './FieldLabel';
7
+
8
+ export function renderField(
9
+ name: string,
10
+ fieldSchema: {
11
+ type: string;
12
+ label: string;
13
+ placeholder?: string;
14
+ readOnly?: boolean;
15
+ enum?: string[];
16
+ items?: { type?: string; properties?: Record<string, unknown> };
17
+ refType?: string;
18
+ },
19
+ data: Record<string, unknown>,
20
+ setData: (fn: (prev: Record<string, unknown>) => Record<string, unknown>) => void,
21
+ ) {
22
+ if (!fieldSchema.type) return null;
23
+
24
+ const rawValue = data[name];
25
+ const isRefValue = rawValue && typeof rawValue === 'object' && isRef(rawValue);
26
+
27
+ // If value is a $ref/$map, show ref editor instead of the normal field handler
28
+ if (isRefValue) {
29
+ const onFieldChange = fieldSchema.readOnly
30
+ ? undefined
31
+ : (next: unknown) => setData((prev) => ({ ...prev, [name]: next }));
32
+ return (
33
+ <div key={name} className="field">
34
+ <FieldLabel label={fieldSchema.label} value={rawValue} onChange={onFieldChange} />
35
+ {onFieldChange && (
36
+ <RefEditor value={rawValue as { $ref: string; $map?: string }} onChange={onFieldChange} />
37
+ )}
38
+ </div>
39
+ );
40
+ }
41
+
42
+ const ctx = fieldSchema.readOnly ? 'react' : 'react:form';
43
+ const handler = resolveExact(fieldSchema.type, ctx) ?? resolveExact('string', ctx);
44
+ if (!handler)
45
+ return (
46
+ <div key={name} className="text-destructive text-xs">
47
+ No form handler: {fieldSchema.type}
48
+ </div>
49
+ );
50
+
51
+ const fieldData: { $type: string; [k: string]: unknown } = {
52
+ $type: fieldSchema.type,
53
+ value: rawValue,
54
+ label: fieldSchema.label,
55
+ placeholder: fieldSchema.placeholder,
56
+ };
57
+ if (fieldSchema.items) fieldData.items = fieldSchema.items;
58
+ if (fieldSchema.enum) fieldData.enum = fieldSchema.enum;
59
+ if (fieldSchema.refType) fieldData.refType = fieldSchema.refType;
60
+
61
+ const isComplex = fieldSchema.type === 'object' || fieldSchema.type === 'array';
62
+ const onFieldChange = fieldSchema.readOnly
63
+ ? undefined
64
+ : (next: unknown) => setData((prev) => ({ ...prev, [name]: (next as { value: unknown }).value }));
65
+
66
+ return (
67
+ <div key={name} className={isComplex ? 'field stack' : 'field'}>
68
+ {fieldSchema.type !== 'boolean' && (
69
+ <FieldLabel
70
+ label={fieldSchema.label}
71
+ value={rawValue}
72
+ onChange={fieldSchema.readOnly ? undefined : (next: unknown) => setData((prev) => ({ ...prev, [name]: next }))}
73
+ />
74
+ )}
75
+ {createElement(handler as any, {
76
+ value: fieldData,
77
+ onChange: onFieldChange,
78
+ })}
79
+ </div>
80
+ );
81
+ }
82
+
83
+ export function StringArrayField({
84
+ value,
85
+ onChange,
86
+ }: {
87
+ value: unknown[];
88
+ onChange: (next: unknown[]) => void;
89
+ }) {
90
+ const [input, setInput] = useState('');
91
+ const isStrings = value.every((v) => typeof v === 'string');
92
+
93
+ if (!isStrings) {
94
+ return (
95
+ <Textarea
96
+ className="min-h-16 text-xs font-mono"
97
+ value={JSON.stringify(value, null, 2)}
98
+ onChange={(e) => {
99
+ try {
100
+ onChange(JSON.parse(e.target.value));
101
+ } catch {
102
+ /* typing */
103
+ }
104
+ }}
105
+ />
106
+ );
107
+ }
108
+
109
+ const tags = value as string[];
110
+ return (
111
+ <div className="flex-1 space-y-1">
112
+ <div className="flex flex-wrap gap-1">
113
+ {tags.map((tag, i) => (
114
+ <span
115
+ key={i}
116
+ className="inline-flex items-center gap-0.5 text-[11px] font-mono bg-muted text-foreground/70 px-1.5 py-0.5 rounded"
117
+ >
118
+ {tag}
119
+ <Button
120
+ variant="ghost"
121
+ size="icon"
122
+ type="button"
123
+ className="h-5 w-5 p-0 ml-0.5 text-muted-foreground/40 hover:text-foreground leading-none"
124
+ onClick={() => onChange(tags.filter((_, j) => j !== i))}
125
+ >
126
+ x
127
+ </Button>
128
+ </span>
129
+ ))}
130
+ </div>
131
+ <Input
132
+ className="h-7 text-xs w-full"
133
+ placeholder="Add item..."
134
+ value={input}
135
+ onChange={(e) => setInput(e.target.value)}
136
+ onKeyDown={(e) => {
137
+ if (e.key !== 'Enter') return;
138
+ e.preventDefault();
139
+ const t = input.trim();
140
+ if (t && !tags.includes(t)) onChange([...tags, t]);
141
+ setInput('');
142
+ }}
143
+ />
144
+ </div>
145
+ );
146
+ }