@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,148 @@
1
+ import { Button } from '#components/ui/button';
2
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '#components/ui/command';
3
+ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '#components/ui/dialog';
4
+ import { Input } from '#components/ui/input';
5
+ import { trpc } from '#trpc';
6
+ import { isOfType, type NodeData } from '@treenity/core';
7
+ import { useEffect, useRef, useState } from 'react';
8
+
9
+ export type TypeInfo = { type: string; label: string; description: string };
10
+
11
+ export async function loadTypes(): Promise<TypeInfo[]> {
12
+ const { items } = (await trpc.getChildren.query({ path: '/sys/types', limit: 0, depth: 99 })) as {
13
+ items: NodeData[];
14
+ total: number;
15
+ };
16
+ return items
17
+ .filter((n) => isOfType(n, 'type'))
18
+ .map((n) => {
19
+ const schema = n.schema as { $type: string; title?: string; description?: string } | undefined;
20
+ const typeName = n.$path.slice('/sys/types/'.length).replace(/\//g, '.');
21
+ return {
22
+ type: typeName,
23
+ label: schema?.title ?? typeName,
24
+ description: schema?.description ?? '',
25
+ };
26
+ });
27
+ }
28
+
29
+ function groupByNamespace(types: TypeInfo[]): Map<string, TypeInfo[]> {
30
+ const groups = new Map<string, TypeInfo[]>();
31
+ for (const t of types) {
32
+ const dotIdx = t.type.indexOf('.');
33
+ const ns = dotIdx === -1 ? 'core' : t.type.slice(0, dotIdx);
34
+ if (!groups.has(ns)) groups.set(ns, []);
35
+ groups.get(ns)!.push(t);
36
+ }
37
+ return groups;
38
+ }
39
+
40
+ export function TypePicker({
41
+ onSelect,
42
+ onCancel,
43
+ title = 'Create Node',
44
+ nameLabel = 'Node name',
45
+ action = 'Create',
46
+ autoName = false,
47
+ }: {
48
+ onSelect: (name: string, type: string) => void;
49
+ onCancel: () => void;
50
+ title?: string;
51
+ nameLabel?: string;
52
+ action?: string;
53
+ autoName?: boolean;
54
+ }) {
55
+ const [types, setTypes] = useState<TypeInfo[]>([]);
56
+ const [loading, setLoading] = useState(true);
57
+ const [error, setError] = useState<string | null>(null);
58
+ const [name, setName] = useState('');
59
+ const [nameManual, setNameManual] = useState(false);
60
+ const [selectedType, setSelectedType] = useState<string | null>(null);
61
+ const nameRef = useRef<HTMLInputElement>(null);
62
+
63
+ useEffect(() => {
64
+ loadTypes()
65
+ .then(setTypes)
66
+ .catch((err) => {
67
+ console.error('Failed to load types:', err);
68
+ setError('Failed to load types');
69
+ })
70
+ .finally(() => setLoading(false));
71
+ }, []);
72
+
73
+ function handleSelectType(type: string) {
74
+ setSelectedType(type);
75
+ if (autoName && !nameManual) {
76
+ const lastSegment = type.includes('.') ? type.slice(type.lastIndexOf('.') + 1) : type;
77
+ setName(lastSegment);
78
+ }
79
+ requestAnimationFrame(() => nameRef.current?.focus());
80
+ }
81
+
82
+ function handleSubmit() {
83
+ if (name && selectedType) onSelect(name, selectedType);
84
+ }
85
+
86
+ const groups = groupByNamespace(types);
87
+
88
+ return (
89
+ <Dialog open onOpenChange={(open) => { if (!open) onCancel(); }}>
90
+ <DialogContent className="p-0 gap-0 max-w-[380px]" showCloseButton={false}>
91
+ <DialogHeader className="px-4 pt-4 pb-2">
92
+ <DialogTitle className="text-[15px]">{title}</DialogTitle>
93
+ </DialogHeader>
94
+
95
+ <Command className="rounded-none border-none" shouldFilter>
96
+ <CommandInput placeholder="Search types..." />
97
+ <CommandList className="max-h-[280px]">
98
+ {loading && <div className="p-3 text-muted-foreground text-[13px]">Loading types...</div>}
99
+ {error && <div className="p-3 text-destructive text-[13px]">{error}</div>}
100
+ <CommandEmpty>No types found</CommandEmpty>
101
+ {[...groups.entries()].map(([ns, items]) => (
102
+ <CommandGroup key={ns} heading={ns}>
103
+ {items.map((t) => (
104
+ <CommandItem
105
+ key={t.type}
106
+ value={`${t.type} ${t.label} ${t.description}`}
107
+ onSelect={() => handleSelectType(t.type)}
108
+ className={selectedType === t.type ? 'bg-accent text-accent-foreground' : ''}
109
+ >
110
+ <div className="flex flex-col gap-0.5">
111
+ <div className="flex items-center gap-2">
112
+ <span className="font-mono text-[13px]">{t.type}</span>
113
+ {t.label !== t.type && <span className="text-muted-foreground text-[12px]">{t.label}</span>}
114
+ </div>
115
+ {t.description && (
116
+ <span className="text-[11px] text-muted-foreground/60 leading-tight">{t.description}</span>
117
+ )}
118
+ </div>
119
+ </CommandItem>
120
+ ))}
121
+ </CommandGroup>
122
+ ))}
123
+ </CommandList>
124
+ </Command>
125
+
126
+ <div className="px-4 py-3 border-t border-border">
127
+ <Input
128
+ ref={nameRef}
129
+ className="h-8 text-sm"
130
+ placeholder={nameLabel}
131
+ value={name}
132
+ onChange={(e) => { setName(e.target.value); setNameManual(true); }}
133
+ onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); handleSubmit(); } }}
134
+ />
135
+ </div>
136
+
137
+ <DialogFooter className="px-4 pb-4">
138
+ <Button variant="outline" onClick={onCancel}>Cancel</Button>
139
+ <Button disabled={!name || !selectedType} onClick={handleSubmit}>
140
+ {action}
141
+ {name ? ` "${name}"` : ''}
142
+ {selectedType ? ` as ${selectedType}` : ''}
143
+ </Button>
144
+ </DialogFooter>
145
+ </DialogContent>
146
+ </Dialog>
147
+ );
148
+ }
@@ -1,4 +1,4 @@
1
- import { type NodeData, register } from '@treenity/core/core';
1
+ import { type NodeData, register } from '@treenity/core';
2
2
  import { pathName } from './list-items';
3
3
  import { getComponents, getSchema } from './node-utils';
4
4
 
@@ -0,0 +1,2 @@
1
+ // Barrel: all react mod server registrations
2
+ // (none currently — react mods are client-only)
@@ -3,7 +3,7 @@
3
3
  import { Badge } from '#components/ui/badge';
4
4
  import { Button } from '#components/ui/button';
5
5
  import { Input } from '#components/ui/input';
6
- import { register } from '@treenity/core/core';
6
+ import { register } from '@treenity/core';
7
7
  import { X } from 'lucide-react';
8
8
  import { useState } from 'react';
9
9
 
@@ -1,7 +1,8 @@
1
1
  // Reusable type preview — Storybook-like: context switcher + live render + schema form editor
2
2
 
3
+ import { Button } from '#components/ui/button';
3
4
  import { Render, RenderContext } from '#context';
4
- import { type ComponentData, getContextsForType, type NodeData } from '@treenity/core/core';
5
+ import { type ComponentData, getContextsForType, type NodeData } from '@treenity/core';
5
6
  import { useMemo, useState } from 'react';
6
7
 
7
8
  // ── Mock data generator (by JSON Schema field type) ──
@@ -94,17 +95,15 @@ export function TypePreview({ typeName, properties }: {
94
95
  <div>
95
96
  <div className="flex gap-1.5 mb-2">
96
97
  {reactContexts.map(c => (
97
- <button
98
+ <Button
98
99
  key={c}
100
+ variant={previewCtx === c ? 'default' : 'outline'}
101
+ size="sm"
102
+ className="h-auto rounded-full px-2.5 py-0.5 text-xs font-mono"
99
103
  onClick={() => setPreviewCtx(prev => prev === c ? null : c)}
100
- className={`px-2.5 py-0.5 rounded-full text-xs font-mono border cursor-pointer transition-colors ${
101
- previewCtx === c
102
- ? 'bg-primary text-primary-foreground border-primary'
103
- : 'bg-muted border-border text-muted-foreground hover:border-primary/50'
104
- }`}
105
104
  >
106
105
  {c}
107
- </button>
106
+ </Button>
108
107
  ))}
109
108
  </div>
110
109
 
@@ -1,8 +1,9 @@
1
1
  // Ref node/component view — shows target path, resolve button, inline preview
2
2
 
3
+ import { Button } from '#components/ui/button';
3
4
  import { Render } from '#context';
4
5
  import { usePath } from '#hooks';
5
- import { type NodeData, register } from '@treenity/core/core';
6
+ import { type NodeData, register } from '@treenity/core';
6
7
  import { useState } from 'react';
7
8
 
8
9
  // ── Node-level view (for ref nodes like /sys/autostart/xxx) ──
@@ -45,20 +46,24 @@ function RefDisplay({ target, onSelect }: { target: string; onSelect?: (p: strin
45
46
  <span className="text-sm font-mono text-primary">{target}</span>
46
47
 
47
48
  {onSelect && (
48
- <button
49
- className="text-xs px-2 py-0.5 rounded bg-muted hover:bg-muted/80 text-foreground border border-border"
49
+ <Button
50
+ variant="outline"
51
+ size="sm"
52
+ className="h-auto px-2 py-0.5 text-xs"
50
53
  onClick={() => onSelect(target)}
51
54
  >
52
55
  Go to
53
- </button>
56
+ </Button>
54
57
  )}
55
58
 
56
- <button
57
- className="text-xs px-2 py-0.5 rounded bg-muted hover:bg-muted/80 text-foreground border border-border"
59
+ <Button
60
+ variant="outline"
61
+ size="sm"
62
+ className="h-auto px-2 py-0.5 text-xs"
58
63
  onClick={() => setResolved(!resolved)}
59
64
  >
60
65
  {resolved ? 'Collapse' : 'Resolve'}
61
- </button>
66
+ </Button>
62
67
  </div>
63
68
 
64
69
  {/* Resolved target */}
@@ -2,7 +2,7 @@
2
2
  // Any type without a specific react:form handler falls here via resolve('default', 'react:form')
3
3
 
4
4
  import { type RenderProps } from '#context';
5
- import { register, resolve } from '@treenity/core/core';
5
+ import { register, resolve } from '@treenity/core';
6
6
  import { createElement } from 'react';
7
7
 
8
8
  function DefaultSchemaForm({ value, onChange }: RenderProps) {
@@ -1,9 +1,9 @@
1
- import { type NodeData, R, S } from '@treenity/core/core';
1
+ import { type NodeData, A, R, S, W } from '@treenity/core';
2
2
  import { registerPrefab } from '@treenity/core/mod';
3
3
 
4
4
  registerPrefab('core', 'seed', [
5
5
  { $path: 'sys', $type: 'treenity.system' },
6
- { $path: 'auth', $type: 'dir' },
6
+ { $path: 'auth', $type: 'dir', $acl: [{ g: 'admins', p: R | W | A | S }, { g: 'public', p: 0 }] },
7
7
  { $path: 'auth/users', $type: 'mount-point',
8
8
  connection: { $type: 'connection', db: 'treenity', collection: 'users' },
9
9
  mount: { $type: 't.mount.mongo' },
@@ -20,6 +20,7 @@ registerPrefab('core', 'seed', [
20
20
  { $path: 'auth/sessions', $type: 'mount-point',
21
21
  connection: { $type: 'connection', db: 'treenity', collection: 'sessions' },
22
22
  mount: { $type: 't.mount.mongo' },
23
+ $acl: [{ g: 'admins', p: R | W | A | S }, { g: 'authenticated', p: 0 }, { g: 'public', p: 0 }],
23
24
  },
24
25
  { $path: 'mnt', $type: 'dir' },
25
26
  { $path: 'mnt/orders', $type: 't.mount.mongo',
@@ -1,6 +1,6 @@
1
1
  // Type node views — react + react:list + live preview
2
2
 
3
- import { getContextsForType, type NodeData, register } from '@treenity/core/core';
3
+ import { getContextsForType, type NodeData, register } from '@treenity/core';
4
4
  import { TypePreview } from './preview';
5
5
 
6
6
  // ── Helpers ──
@@ -3,7 +3,7 @@
3
3
  // Enables client to use the same combinators as server:
4
4
  // withSubscriptions(withCache(createRemoteTree(trpc)))
5
5
 
6
- import type { NodeData } from '@treenity/core/core';
6
+ import type { NodeData } from '@treenity/core';
7
7
  import type { Tree } from '@treenity/core/tree';
8
8
  import { defaultPatch } from '@treenity/core/tree/patch';
9
9
  import type { trpc } from './trpc';
package/src/root.css ADDED
@@ -0,0 +1,117 @@
1
+ /* Tailwind disabled — using CDN in index.html to avoid cross-package conflict */
2
+ /* @import 'tailwindcss'; */
3
+ /* @source "."; */
4
+ /* @source "../../src/mods"; */
5
+
6
+ /* Local fonts */
7
+ @font-face { font-family: 'Manrope'; src: url('/fonts/Manrope-Light.ttf'); font-weight: 300; font-display: swap; }
8
+ @font-face { font-family: 'Manrope'; src: url('/fonts/Manrope-Regular.ttf'); font-weight: 400; font-display: swap; }
9
+ @font-face { font-family: 'Manrope'; src: url('/fonts/Manrope-Medium.ttf'); font-weight: 500; font-display: swap; }
10
+ @font-face { font-family: 'Manrope'; src: url('/fonts/Manrope-SemiBold.ttf'); font-weight: 600; font-display: swap; }
11
+
12
+ /* shadcn/ui theme tokens — now in CDN (index.html), kept here for reference */
13
+ /* @theme inline extend { ... } — see index.html <style type="text/tailwindcss"> */
14
+
15
+ /* Tailwind theme tokens — unlayered :root beats CDN's layered output */
16
+ :root {
17
+ --color-background: #0d1117;
18
+ --color-foreground: #e6edf3;
19
+ --color-card: #161b22;
20
+ --color-card-foreground: #e6edf3;
21
+ --color-popover: #161b22;
22
+ --color-popover-foreground: #e6edf3;
23
+ --color-primary: #2ecc71;
24
+ --color-primary-foreground: #ffffff;
25
+ --color-secondary: #21262d;
26
+ --color-secondary-foreground: #e6edf3;
27
+ --color-muted: #161b22;
28
+ --color-muted-foreground: #7d8590;
29
+ --color-accent: rgba(46, 204, 113, 0.15);
30
+ --color-accent-foreground: #2ecc71;
31
+ --color-destructive: #f85149;
32
+ --color-destructive-foreground: #e6edf3;
33
+ --color-border: #30363d;
34
+ --color-input: #30363d;
35
+ --color-ring: #2ecc71;
36
+ --radius-sm: 4px;
37
+ --radius-md: 6px;
38
+ --radius-lg: 8px;
39
+
40
+ /* Legacy aliases */
41
+ --bg: var(--color-background);
42
+ --surface: var(--color-card);
43
+ --surface-2: var(--color-secondary);
44
+ --surface-3: var(--color-border);
45
+ --border: var(--color-border);
46
+ --border-subtle: var(--color-border);
47
+ --text: var(--color-foreground);
48
+ --text-2: var(--color-muted-foreground);
49
+ --text-3: color-mix(in srgb, var(--color-muted-foreground) 60%, transparent);
50
+ --accent: var(--color-primary);
51
+ --accent-subtle: var(--color-accent);
52
+ --danger: var(--color-destructive);
53
+ --danger-subtle: color-mix(in srgb, var(--color-destructive) 15%, transparent);
54
+ --success: #3fb950;
55
+ --success-subtle: rgba(63, 185, 80, 0.15);
56
+ --warning: #d29922;
57
+ --radius: var(--radius-md);
58
+ --radius-lg: var(--radius-lg);
59
+ --font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
60
+ --mono: 'SF Mono', SFMono-Regular, 'Cascadia Code', 'Fira Code', Consolas, monospace;
61
+ --transition: 0.15s ease;
62
+ }
63
+ @layer base {
64
+ *,
65
+ ::before,
66
+ ::after {
67
+ margin: 0;
68
+ padding: 0;
69
+ box-sizing: border-box;
70
+ border-color: var(--color-border);
71
+ }
72
+ }
73
+ html,
74
+ body {
75
+ height: 100%;
76
+ font-family: var(--font);
77
+ }
78
+ body {
79
+ background: var(--bg);
80
+ color: var(--text);
81
+ font-size: 14px;
82
+ line-height: 1.5;
83
+ }
84
+
85
+ @layer base {
86
+ input,
87
+ textarea,
88
+ select {
89
+ width: 100%;
90
+ padding: 4px 8px;
91
+ background: var(--bg);
92
+ border: 1px solid var(--border);
93
+ border-radius: var(--radius);
94
+ color: var(--text);
95
+ font-size: 12px;
96
+ font-family: var(--mono);
97
+ outline: none;
98
+ transition: border-color var(--transition);
99
+ }
100
+ input:focus,
101
+ textarea:focus,
102
+ select:focus {
103
+ border-color: var(--accent);
104
+ }
105
+ input:read-only {
106
+ color: var(--text-2);
107
+ cursor: default;
108
+ }
109
+ input:read-only:focus {
110
+ border-color: var(--border);
111
+ }
112
+ textarea {
113
+ min-height: 80px;
114
+ resize: vertical;
115
+ line-height: 1.5;
116
+ }
117
+ }
@@ -1,5 +1,5 @@
1
1
  // Lazy registry loader — fetches type nodes from /sys/types on demand
2
- import { type ContextHandlers, register, resolve } from '@treenity/core/core';
2
+ import { type ContextHandlers, register, resolve } from '@treenity/core';
3
3
  import type { TypeSchema } from '@treenity/core/schema/types';
4
4
  import { useEffect, useState } from 'react';
5
5
  import { trpc } from './trpc';
package/src/symbols.ts ADDED
@@ -0,0 +1,25 @@
1
+ // Symbol-based component location metadata.
2
+ // Stamped on deserialization (cache.put). Non-enumerable so they're
3
+ // invisible to structuredClone, spread, and JSON/keys/entries.
4
+
5
+ import { isComponent, type NodeData } from '@treenity/core';
6
+
7
+ export const $key = Symbol.for('treenity.$key');
8
+ export const $node = Symbol.for('treenity.$node');
9
+
10
+ function hide(obj: object, sym: symbol, value: unknown): void {
11
+ Object.defineProperty(obj, sym, { value, enumerable: false, writable: false, configurable: true });
12
+ }
13
+
14
+ export function stampNode(node: NodeData): void {
15
+ if ((node as any)[$node] === node) return;
16
+
17
+ hide(node, $key, '');
18
+ hide(node, $node, node);
19
+
20
+ for (const [k, v] of Object.entries(node)) {
21
+ if (k.startsWith('$') || !isComponent(v)) continue;
22
+ hide(v, $key, k);
23
+ hide(v, $node, node);
24
+ }
25
+ }