@next-buildr/editor 0.0.0-stage → 2.0.0

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 (471) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/app/builder-editor.d.ts +8 -0
  4. package/dist/app/builder-editor.d.ts.map +1 -0
  5. package/dist/app/builder-editor.js +14 -0
  6. package/dist/app/builder-editor.test.d.ts +2 -0
  7. package/dist/app/builder-editor.test.d.ts.map +1 -0
  8. package/dist/app/builder-editor.test.js +199 -0
  9. package/dist/app/config.d.ts +59 -0
  10. package/dist/app/config.d.ts.map +1 -0
  11. package/dist/app/config.js +18 -0
  12. package/dist/app/content-language.test.d.ts +2 -0
  13. package/dist/app/content-language.test.d.ts.map +1 -0
  14. package/dist/app/content-language.test.js +157 -0
  15. package/dist/app/editor-app.d.ts +17 -0
  16. package/dist/app/editor-app.d.ts.map +1 -0
  17. package/dist/app/editor-app.js +206 -0
  18. package/dist/app/editor-app.test.d.ts +2 -0
  19. package/dist/app/editor-app.test.d.ts.map +1 -0
  20. package/dist/app/editor-app.test.js +135 -0
  21. package/dist/app/layout.d.ts +32 -0
  22. package/dist/app/layout.d.ts.map +1 -0
  23. package/dist/app/layout.js +82 -0
  24. package/dist/app/manifest.d.ts +12 -0
  25. package/dist/app/manifest.d.ts.map +1 -0
  26. package/dist/app/manifest.js +17 -0
  27. package/dist/app/shell-panels.d.ts +15 -0
  28. package/dist/app/shell-panels.d.ts.map +1 -0
  29. package/dist/app/shell-panels.js +5 -0
  30. package/dist/app/small-screen.d.ts +12 -0
  31. package/dist/app/small-screen.d.ts.map +1 -0
  32. package/dist/app/small-screen.js +33 -0
  33. package/dist/app/small-screen.test.d.ts +2 -0
  34. package/dist/app/small-screen.test.d.ts.map +1 -0
  35. package/dist/app/small-screen.test.js +108 -0
  36. package/dist/app/status-info.d.ts +14 -0
  37. package/dist/app/status-info.d.ts.map +1 -0
  38. package/dist/app/status-info.js +34 -0
  39. package/dist/app/use-resizable.d.ts +34 -0
  40. package/dist/app/use-resizable.d.ts.map +1 -0
  41. package/dist/app/use-resizable.js +84 -0
  42. package/dist/canvas-host/canvas-frame.d.ts +53 -0
  43. package/dist/canvas-host/canvas-frame.d.ts.map +1 -0
  44. package/dist/canvas-host/canvas-frame.js +146 -0
  45. package/dist/canvas-host/canvas-frame.test.d.ts +2 -0
  46. package/dist/canvas-host/canvas-frame.test.d.ts.map +1 -0
  47. package/dist/canvas-host/canvas-frame.test.js +91 -0
  48. package/dist/canvas-host/host.d.ts +109 -0
  49. package/dist/canvas-host/host.d.ts.map +1 -0
  50. package/dist/canvas-host/host.js +293 -0
  51. package/dist/canvas-host/host.test.d.ts +2 -0
  52. package/dist/canvas-host/host.test.d.ts.map +1 -0
  53. package/dist/canvas-host/host.test.js +398 -0
  54. package/dist/canvas-host/index.d.ts +5 -0
  55. package/dist/canvas-host/index.d.ts.map +1 -0
  56. package/dist/canvas-host/index.js +2 -0
  57. package/dist/clipboard/clipboard.d.ts +38 -0
  58. package/dist/clipboard/clipboard.d.ts.map +1 -0
  59. package/dist/clipboard/clipboard.js +160 -0
  60. package/dist/clipboard/clipboard.test.d.ts +2 -0
  61. package/dist/clipboard/clipboard.test.d.ts.map +1 -0
  62. package/dist/clipboard/clipboard.test.js +457 -0
  63. package/dist/clipboard/format.d.ts +27 -0
  64. package/dist/clipboard/format.d.ts.map +1 -0
  65. package/dist/clipboard/format.js +37 -0
  66. package/dist/clipboard/index.d.ts +6 -0
  67. package/dist/clipboard/index.d.ts.map +1 -0
  68. package/dist/clipboard/index.js +3 -0
  69. package/dist/clipboard/react.d.ts +20 -0
  70. package/dist/clipboard/react.d.ts.map +1 -0
  71. package/dist/clipboard/react.js +71 -0
  72. package/dist/dialogs/index.d.ts +2 -0
  73. package/dist/dialogs/index.d.ts.map +1 -0
  74. package/dist/dialogs/index.js +1 -0
  75. package/dist/dialogs/media-picker/index.d.ts +7 -0
  76. package/dist/dialogs/media-picker/index.d.ts.map +1 -0
  77. package/dist/dialogs/media-picker/index.js +3 -0
  78. package/dist/dialogs/media-picker/library.d.ts +17 -0
  79. package/dist/dialogs/media-picker/library.d.ts.map +1 -0
  80. package/dist/dialogs/media-picker/library.js +9 -0
  81. package/dist/dialogs/media-picker/media-picker.d.ts +18 -0
  82. package/dist/dialogs/media-picker/media-picker.d.ts.map +1 -0
  83. package/dist/dialogs/media-picker/media-picker.js +99 -0
  84. package/dist/dialogs/media-picker/media-picker.test.d.ts +2 -0
  85. package/dist/dialogs/media-picker/media-picker.test.d.ts.map +1 -0
  86. package/dist/dialogs/media-picker/media-picker.test.js +161 -0
  87. package/dist/dialogs/media-picker/media-ref.d.ts +28 -0
  88. package/dist/dialogs/media-picker/media-ref.d.ts.map +1 -0
  89. package/dist/dialogs/media-picker/media-ref.js +52 -0
  90. package/dist/dnd/check.d.ts +8 -0
  91. package/dist/dnd/check.d.ts.map +1 -0
  92. package/dist/dnd/check.js +12 -0
  93. package/dist/dnd/destinations.d.ts +15 -0
  94. package/dist/dnd/destinations.d.ts.map +1 -0
  95. package/dist/dnd/destinations.js +43 -0
  96. package/dist/dnd/dnd-react.test.d.ts +2 -0
  97. package/dist/dnd/dnd-react.test.d.ts.map +1 -0
  98. package/dist/dnd/dnd-react.test.js +93 -0
  99. package/dist/dnd/dnd.test.d.ts +2 -0
  100. package/dist/dnd/dnd.test.d.ts.map +1 -0
  101. package/dist/dnd/dnd.test.js +327 -0
  102. package/dist/dnd/engine.d.ts +85 -0
  103. package/dist/dnd/engine.d.ts.map +1 -0
  104. package/dist/dnd/engine.js +185 -0
  105. package/dist/dnd/fragment.d.ts +6 -0
  106. package/dist/dnd/fragment.d.ts.map +1 -0
  107. package/dist/dnd/fragment.js +18 -0
  108. package/dist/dnd/geometry.d.ts +30 -0
  109. package/dist/dnd/geometry.d.ts.map +1 -0
  110. package/dist/dnd/geometry.js +31 -0
  111. package/dist/dnd/index.d.ts +14 -0
  112. package/dist/dnd/index.d.ts.map +1 -0
  113. package/dist/dnd/index.js +7 -0
  114. package/dist/dnd/move-to-dialog.d.ts +13 -0
  115. package/dist/dnd/move-to-dialog.d.ts.map +1 -0
  116. package/dist/dnd/move-to-dialog.js +30 -0
  117. package/dist/dnd/react.d.ts +43 -0
  118. package/dist/dnd/react.d.ts.map +1 -0
  119. package/dist/dnd/react.js +185 -0
  120. package/dist/dnd/tree-target.d.ts +29 -0
  121. package/dist/dnd/tree-target.d.ts.map +1 -0
  122. package/dist/dnd/tree-target.js +97 -0
  123. package/dist/fonts/LICENSE-inter.txt +93 -0
  124. package/dist/fonts/inter-latin-400-normal.woff2 +0 -0
  125. package/dist/fonts/inter-latin-500-normal.woff2 +0 -0
  126. package/dist/fonts/inter-latin-600-normal.woff2 +0 -0
  127. package/dist/fonts/inter-latin-ext-400-normal.woff2 +0 -0
  128. package/dist/fonts/inter-latin-ext-500-normal.woff2 +0 -0
  129. package/dist/fonts/inter-latin-ext-600-normal.woff2 +0 -0
  130. package/dist/index.d.ts +22 -0
  131. package/dist/index.d.ts.map +1 -0
  132. package/dist/index.js +21 -0
  133. package/dist/messages/en.d.ts +335 -0
  134. package/dist/messages/en.d.ts.map +1 -0
  135. package/dist/messages/en.js +332 -0
  136. package/dist/messages/index.d.ts +16 -0
  137. package/dist/messages/index.d.ts.map +1 -0
  138. package/dist/messages/index.js +22 -0
  139. package/dist/messages/pl.d.ts +3 -0
  140. package/dist/messages/pl.d.ts.map +1 -0
  141. package/dist/messages/pl.js +327 -0
  142. package/dist/panels/breadcrumbs/breadcrumbs.d.ts +6 -0
  143. package/dist/panels/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  144. package/dist/panels/breadcrumbs/breadcrumbs.js +24 -0
  145. package/dist/panels/breadcrumbs/breadcrumbs.test.d.ts +2 -0
  146. package/dist/panels/breadcrumbs/breadcrumbs.test.d.ts.map +1 -0
  147. package/dist/panels/breadcrumbs/breadcrumbs.test.js +56 -0
  148. package/dist/panels/index.d.ts +9 -0
  149. package/dist/panels/index.d.ts.map +1 -0
  150. package/dist/panels/index.js +6 -0
  151. package/dist/panels/insert/catalog.d.ts +30 -0
  152. package/dist/panels/insert/catalog.d.ts.map +1 -0
  153. package/dist/panels/insert/catalog.js +76 -0
  154. package/dist/panels/insert/catalog.order.test.d.ts +2 -0
  155. package/dist/panels/insert/catalog.order.test.d.ts.map +1 -0
  156. package/dist/panels/insert/catalog.order.test.js +17 -0
  157. package/dist/panels/insert/category-name.d.ts +4 -0
  158. package/dist/panels/insert/category-name.d.ts.map +1 -0
  159. package/dist/panels/insert/category-name.js +8 -0
  160. package/dist/panels/insert/index.d.ts +3 -0
  161. package/dist/panels/insert/index.d.ts.map +1 -0
  162. package/dist/panels/insert/index.js +2 -0
  163. package/dist/panels/insert/insert-panel.d.ts +7 -0
  164. package/dist/panels/insert/insert-panel.d.ts.map +1 -0
  165. package/dist/panels/insert/insert-panel.js +155 -0
  166. package/dist/panels/insert/insert-panel.test.d.ts +2 -0
  167. package/dist/panels/insert/insert-panel.test.d.ts.map +1 -0
  168. package/dist/panels/insert/insert-panel.test.js +323 -0
  169. package/dist/panels/insert/target.d.ts +17 -0
  170. package/dist/panels/insert/target.d.ts.map +1 -0
  171. package/dist/panels/insert/target.js +48 -0
  172. package/dist/panels/inspector/controls/boolean.d.ts +4 -0
  173. package/dist/panels/inspector/controls/boolean.d.ts.map +1 -0
  174. package/dist/panels/inspector/controls/boolean.js +4 -0
  175. package/dist/panels/inspector/controls/compound.d.ts +15 -0
  176. package/dist/panels/inspector/controls/compound.d.ts.map +1 -0
  177. package/dist/panels/inspector/controls/compound.js +99 -0
  178. package/dist/panels/inspector/controls/compound.test.d.ts +2 -0
  179. package/dist/panels/inspector/controls/compound.test.d.ts.map +1 -0
  180. package/dist/panels/inspector/controls/compound.test.js +195 -0
  181. package/dist/panels/inspector/controls/icon.d.ts +5 -0
  182. package/dist/panels/inspector/controls/icon.d.ts.map +1 -0
  183. package/dist/panels/inspector/controls/icon.js +6 -0
  184. package/dist/panels/inspector/controls/index.d.ts +13 -0
  185. package/dist/panels/inspector/controls/index.d.ts.map +1 -0
  186. package/dist/panels/inspector/controls/index.js +11 -0
  187. package/dist/panels/inspector/controls/label.d.ts +4 -0
  188. package/dist/panels/inspector/controls/label.d.ts.map +1 -0
  189. package/dist/panels/inspector/controls/label.js +8 -0
  190. package/dist/panels/inspector/controls/link.d.ts +5 -0
  191. package/dist/panels/inspector/controls/link.d.ts.map +1 -0
  192. package/dist/panels/inspector/controls/link.js +6 -0
  193. package/dist/panels/inspector/controls/media.d.ts +9 -0
  194. package/dist/panels/inspector/controls/media.d.ts.map +1 -0
  195. package/dist/panels/inspector/controls/media.js +21 -0
  196. package/dist/panels/inspector/controls/number.d.ts +10 -0
  197. package/dist/panels/inspector/controls/number.d.ts.map +1 -0
  198. package/dist/panels/inspector/controls/number.js +33 -0
  199. package/dist/panels/inspector/controls/rich-text-model.d.ts +20 -0
  200. package/dist/panels/inspector/controls/rich-text-model.d.ts.map +1 -0
  201. package/dist/panels/inspector/controls/rich-text-model.js +91 -0
  202. package/dist/panels/inspector/controls/rich-text.d.ts +10 -0
  203. package/dist/panels/inspector/controls/rich-text.d.ts.map +1 -0
  204. package/dist/panels/inspector/controls/rich-text.js +159 -0
  205. package/dist/panels/inspector/controls/select.d.ts +5 -0
  206. package/dist/panels/inspector/controls/select.d.ts.map +1 -0
  207. package/dist/panels/inspector/controls/select.js +16 -0
  208. package/dist/panels/inspector/controls/select.test.d.ts +2 -0
  209. package/dist/panels/inspector/controls/select.test.d.ts.map +1 -0
  210. package/dist/panels/inspector/controls/select.test.js +43 -0
  211. package/dist/panels/inspector/controls/text.d.ts +4 -0
  212. package/dist/panels/inspector/controls/text.d.ts.map +1 -0
  213. package/dist/panels/inspector/controls/text.js +5 -0
  214. package/dist/panels/inspector/controls/textarea.d.ts +4 -0
  215. package/dist/panels/inspector/controls/textarea.d.ts.map +1 -0
  216. package/dist/panels/inspector/controls/textarea.js +4 -0
  217. package/dist/panels/inspector/controls/types.d.ts +16 -0
  218. package/dist/panels/inspector/controls/types.d.ts.map +1 -0
  219. package/dist/panels/inspector/controls/types.js +1 -0
  220. package/dist/panels/inspector/index.d.ts +17 -0
  221. package/dist/panels/inspector/index.d.ts.map +1 -0
  222. package/dist/panels/inspector/index.js +9 -0
  223. package/dist/panels/inspector/inspector.d.ts +16 -0
  224. package/dist/panels/inspector/inspector.d.ts.map +1 -0
  225. package/dist/panels/inspector/inspector.js +116 -0
  226. package/dist/panels/inspector/inspector.test.d.ts +2 -0
  227. package/dist/panels/inspector/inspector.test.d.ts.map +1 -0
  228. package/dist/panels/inspector/inspector.test.js +328 -0
  229. package/dist/panels/inspector/props-panel.d.ts +26 -0
  230. package/dist/panels/inspector/props-panel.d.ts.map +1 -0
  231. package/dist/panels/inspector/props-panel.js +117 -0
  232. package/dist/panels/inspector/styles/box-model.d.ts +20 -0
  233. package/dist/panels/inspector/styles/box-model.d.ts.map +1 -0
  234. package/dist/panels/inspector/styles/box-model.js +31 -0
  235. package/dist/panels/inspector/styles/index.d.ts +5 -0
  236. package/dist/panels/inspector/styles/index.d.ts.map +1 -0
  237. package/dist/panels/inspector/styles/index.js +2 -0
  238. package/dist/panels/inspector/styles/model.d.ts +55 -0
  239. package/dist/panels/inspector/styles/model.d.ts.map +1 -0
  240. package/dist/panels/inspector/styles/model.js +111 -0
  241. package/dist/panels/inspector/styles/segments.d.ts +18 -0
  242. package/dist/panels/inspector/styles/segments.d.ts.map +1 -0
  243. package/dist/panels/inspector/styles/segments.js +75 -0
  244. package/dist/panels/inspector/styles/sides-editor.d.ts +34 -0
  245. package/dist/panels/inspector/styles/sides-editor.d.ts.map +1 -0
  246. package/dist/panels/inspector/styles/sides-editor.js +86 -0
  247. package/dist/panels/inspector/styles/style-inspector.d.ts +15 -0
  248. package/dist/panels/inspector/styles/style-inspector.d.ts.map +1 -0
  249. package/dist/panels/inspector/styles/style-inspector.js +219 -0
  250. package/dist/panels/inspector/styles/style-inspector.test.d.ts +2 -0
  251. package/dist/panels/inspector/styles/style-inspector.test.d.ts.map +1 -0
  252. package/dist/panels/inspector/styles/style-inspector.test.js +265 -0
  253. package/dist/panels/inspector/styles/token-picker.d.ts +15 -0
  254. package/dist/panels/inspector/styles/token-picker.d.ts.map +1 -0
  255. package/dist/panels/inspector/styles/token-picker.js +23 -0
  256. package/dist/panels/inspector/styles/use-style-value.d.ts +28 -0
  257. package/dist/panels/inspector/styles/use-style-value.d.ts.map +1 -0
  258. package/dist/panels/inspector/styles/use-style-value.js +51 -0
  259. package/dist/panels/inspector/value.d.ts +20 -0
  260. package/dist/panels/inspector/value.d.ts.map +1 -0
  261. package/dist/panels/inspector/value.js +32 -0
  262. package/dist/panels/inspector/values/analyze.d.ts +49 -0
  263. package/dist/panels/inspector/values/analyze.d.ts.map +1 -0
  264. package/dist/panels/inspector/values/analyze.js +115 -0
  265. package/dist/panels/inspector/values/data.d.ts +18 -0
  266. package/dist/panels/inspector/values/data.d.ts.map +1 -0
  267. package/dist/panels/inspector/values/data.js +10 -0
  268. package/dist/panels/inspector/values/translation.d.ts +20 -0
  269. package/dist/panels/inspector/values/translation.d.ts.map +1 -0
  270. package/dist/panels/inspector/values/translation.js +25 -0
  271. package/dist/panels/inspector/values/value-editor.d.ts +30 -0
  272. package/dist/panels/inspector/values/value-editor.d.ts.map +1 -0
  273. package/dist/panels/inspector/values/value-editor.js +191 -0
  274. package/dist/panels/inspector/values/values.test.d.ts +2 -0
  275. package/dist/panels/inspector/values/values.test.d.ts.map +1 -0
  276. package/dist/panels/inspector/values/values.test.js +173 -0
  277. package/dist/panels/issues/collect.d.ts +70 -0
  278. package/dist/panels/issues/collect.d.ts.map +1 -0
  279. package/dist/panels/issues/collect.js +96 -0
  280. package/dist/panels/issues/index.d.ts +5 -0
  281. package/dist/panels/issues/index.d.ts.map +1 -0
  282. package/dist/panels/issues/index.js +2 -0
  283. package/dist/panels/issues/issues-panel.d.ts +17 -0
  284. package/dist/panels/issues/issues-panel.d.ts.map +1 -0
  285. package/dist/panels/issues/issues-panel.js +77 -0
  286. package/dist/panels/layers/flatten.d.ts +28 -0
  287. package/dist/panels/layers/flatten.d.ts.map +1 -0
  288. package/dist/panels/layers/flatten.js +61 -0
  289. package/dist/panels/layers/layers-panel.d.ts +14 -0
  290. package/dist/panels/layers/layers-panel.d.ts.map +1 -0
  291. package/dist/panels/layers/layers-panel.js +428 -0
  292. package/dist/panels/layers/layers-panel.test.d.ts +2 -0
  293. package/dist/panels/layers/layers-panel.test.d.ts.map +1 -0
  294. package/dist/panels/layers/layers-panel.test.js +315 -0
  295. package/dist/persistence/controller.d.ts +55 -0
  296. package/dist/persistence/controller.d.ts.map +1 -0
  297. package/dist/persistence/controller.js +341 -0
  298. package/dist/persistence/index.d.ts +6 -0
  299. package/dist/persistence/index.d.ts.map +1 -0
  300. package/dist/persistence/index.js +3 -0
  301. package/dist/persistence/load.d.ts +35 -0
  302. package/dist/persistence/load.d.ts.map +1 -0
  303. package/dist/persistence/load.js +67 -0
  304. package/dist/persistence/persistence.test.d.ts +2 -0
  305. package/dist/persistence/persistence.test.d.ts.map +1 -0
  306. package/dist/persistence/persistence.test.js +483 -0
  307. package/dist/persistence/react.d.ts +18 -0
  308. package/dist/persistence/react.d.ts.map +1 -0
  309. package/dist/persistence/react.js +105 -0
  310. package/dist/persistence/types.d.ts +182 -0
  311. package/dist/persistence/types.d.ts.map +1 -0
  312. package/dist/persistence/types.js +1 -0
  313. package/dist/preview/index.d.ts +3 -0
  314. package/dist/preview/index.d.ts.map +1 -0
  315. package/dist/preview/index.js +2 -0
  316. package/dist/preview/prepare.d.ts +16 -0
  317. package/dist/preview/prepare.d.ts.map +1 -0
  318. package/dist/preview/prepare.js +21 -0
  319. package/dist/preview/preview.d.ts +27 -0
  320. package/dist/preview/preview.d.ts.map +1 -0
  321. package/dist/preview/preview.js +51 -0
  322. package/dist/preview/preview.test.d.ts +2 -0
  323. package/dist/preview/preview.test.d.ts.map +1 -0
  324. package/dist/preview/preview.test.js +129 -0
  325. package/dist/shortcuts/actions.d.ts +17 -0
  326. package/dist/shortcuts/actions.d.ts.map +1 -0
  327. package/dist/shortcuts/actions.js +85 -0
  328. package/dist/shortcuts/index.d.ts +11 -0
  329. package/dist/shortcuts/index.d.ts.map +1 -0
  330. package/dist/shortcuts/index.js +5 -0
  331. package/dist/shortcuts/keys.d.ts +29 -0
  332. package/dist/shortcuts/keys.d.ts.map +1 -0
  333. package/dist/shortcuts/keys.js +100 -0
  334. package/dist/shortcuts/map.d.ts +17 -0
  335. package/dist/shortcuts/map.d.ts.map +1 -0
  336. package/dist/shortcuts/map.js +31 -0
  337. package/dist/shortcuts/registry.d.ts +32 -0
  338. package/dist/shortcuts/registry.d.ts.map +1 -0
  339. package/dist/shortcuts/registry.js +53 -0
  340. package/dist/shortcuts/shortcuts.d.ts +32 -0
  341. package/dist/shortcuts/shortcuts.d.ts.map +1 -0
  342. package/dist/shortcuts/shortcuts.js +95 -0
  343. package/dist/shortcuts/shortcuts.test.d.ts +2 -0
  344. package/dist/shortcuts/shortcuts.test.d.ts.map +1 -0
  345. package/dist/shortcuts/shortcuts.test.js +263 -0
  346. package/dist/store/create-store.d.ts +13 -0
  347. package/dist/store/create-store.d.ts.map +1 -0
  348. package/dist/store/create-store.js +248 -0
  349. package/dist/store/index.d.ts +9 -0
  350. package/dist/store/index.d.ts.map +1 -0
  351. package/dist/store/index.js +5 -0
  352. package/dist/store/locale.d.ts +23 -0
  353. package/dist/store/locale.d.ts.map +1 -0
  354. package/dist/store/locale.js +31 -0
  355. package/dist/store/react.d.ts +17 -0
  356. package/dist/store/react.d.ts.map +1 -0
  357. package/dist/store/react.js +32 -0
  358. package/dist/store/selection.d.ts +32 -0
  359. package/dist/store/selection.d.ts.map +1 -0
  360. package/dist/store/selection.js +84 -0
  361. package/dist/store/selection.test.d.ts +2 -0
  362. package/dist/store/selection.test.d.ts.map +1 -0
  363. package/dist/store/selection.test.js +95 -0
  364. package/dist/store/selectors.d.ts +18 -0
  365. package/dist/store/selectors.d.ts.map +1 -0
  366. package/dist/store/selectors.js +39 -0
  367. package/dist/store/store.test.d.ts +2 -0
  368. package/dist/store/store.test.d.ts.map +1 -0
  369. package/dist/store/store.test.js +331 -0
  370. package/dist/store/types.d.ts +114 -0
  371. package/dist/store/types.d.ts.map +1 -0
  372. package/dist/store/types.js +1 -0
  373. package/dist/styles/tokens.test.d.ts +2 -0
  374. package/dist/styles/tokens.test.d.ts.map +1 -0
  375. package/dist/styles/tokens.test.js +199 -0
  376. package/dist/styles.css +2885 -0
  377. package/dist/toolbar/brand.d.ts +7 -0
  378. package/dist/toolbar/brand.d.ts.map +1 -0
  379. package/dist/toolbar/brand.js +11 -0
  380. package/dist/toolbar/breakpoint-control.d.ts +9 -0
  381. package/dist/toolbar/breakpoint-control.d.ts.map +1 -0
  382. package/dist/toolbar/breakpoint-control.js +23 -0
  383. package/dist/toolbar/editable-title.d.ts +14 -0
  384. package/dist/toolbar/editable-title.d.ts.map +1 -0
  385. package/dist/toolbar/editable-title.js +46 -0
  386. package/dist/toolbar/editable-title.test.d.ts +2 -0
  387. package/dist/toolbar/editable-title.test.d.ts.map +1 -0
  388. package/dist/toolbar/editable-title.test.js +53 -0
  389. package/dist/toolbar/index.d.ts +12 -0
  390. package/dist/toolbar/index.d.ts.map +1 -0
  391. package/dist/toolbar/index.js +5 -0
  392. package/dist/toolbar/locale-switcher.d.ts +10 -0
  393. package/dist/toolbar/locale-switcher.d.ts.map +1 -0
  394. package/dist/toolbar/locale-switcher.js +20 -0
  395. package/dist/toolbar/more-menu.d.ts +12 -0
  396. package/dist/toolbar/more-menu.d.ts.map +1 -0
  397. package/dist/toolbar/more-menu.js +47 -0
  398. package/dist/toolbar/panel-toggles.d.ts +9 -0
  399. package/dist/toolbar/panel-toggles.d.ts.map +1 -0
  400. package/dist/toolbar/panel-toggles.js +19 -0
  401. package/dist/toolbar/publish-dialog.d.ts +18 -0
  402. package/dist/toolbar/publish-dialog.d.ts.map +1 -0
  403. package/dist/toolbar/publish-dialog.js +49 -0
  404. package/dist/toolbar/publish.test.d.ts +2 -0
  405. package/dist/toolbar/publish.test.d.ts.map +1 -0
  406. package/dist/toolbar/publish.test.js +258 -0
  407. package/dist/toolbar/sample-picker.d.ts +18 -0
  408. package/dist/toolbar/sample-picker.d.ts.map +1 -0
  409. package/dist/toolbar/sample-picker.js +72 -0
  410. package/dist/toolbar/sample-picker.test.d.ts +2 -0
  411. package/dist/toolbar/sample-picker.test.d.ts.map +1 -0
  412. package/dist/toolbar/sample-picker.test.js +78 -0
  413. package/dist/toolbar/save-indicator.d.ts +8 -0
  414. package/dist/toolbar/save-indicator.d.ts.map +1 -0
  415. package/dist/toolbar/save-indicator.js +30 -0
  416. package/dist/toolbar/theme.d.ts +22 -0
  417. package/dist/toolbar/theme.d.ts.map +1 -0
  418. package/dist/toolbar/theme.js +46 -0
  419. package/dist/toolbar/theme.test.d.ts +2 -0
  420. package/dist/toolbar/theme.test.d.ts.map +1 -0
  421. package/dist/toolbar/theme.test.js +49 -0
  422. package/dist/toolbar/toolbar-centre.d.ts +13 -0
  423. package/dist/toolbar/toolbar-centre.d.ts.map +1 -0
  424. package/dist/toolbar/toolbar-centre.js +7 -0
  425. package/dist/toolbar/toolbar-left.d.ts +12 -0
  426. package/dist/toolbar/toolbar-left.d.ts.map +1 -0
  427. package/dist/toolbar/toolbar-left.js +16 -0
  428. package/dist/toolbar/toolbar-right.d.ts +19 -0
  429. package/dist/toolbar/toolbar-right.d.ts.map +1 -0
  430. package/dist/toolbar/toolbar-right.js +21 -0
  431. package/dist/toolbar/toolbar.d.ts +38 -0
  432. package/dist/toolbar/toolbar.d.ts.map +1 -0
  433. package/dist/toolbar/toolbar.js +27 -0
  434. package/dist/toolbar/toolbar.test.d.ts +2 -0
  435. package/dist/toolbar/toolbar.test.d.ts.map +1 -0
  436. package/dist/toolbar/toolbar.test.js +289 -0
  437. package/dist/toolbar/use-overflow-level.d.ts +9 -0
  438. package/dist/toolbar/use-overflow-level.d.ts.map +1 -0
  439. package/dist/toolbar/use-overflow-level.js +40 -0
  440. package/dist/toolbar/zoom-menu.d.ts +10 -0
  441. package/dist/toolbar/zoom-menu.d.ts.map +1 -0
  442. package/dist/toolbar/zoom-menu.js +17 -0
  443. package/dist/ui/icon.d.ts +102 -0
  444. package/dist/ui/icon.d.ts.map +1 -0
  445. package/dist/ui/icon.js +182 -0
  446. package/dist/ui/icon.test.d.ts +2 -0
  447. package/dist/ui/icon.test.d.ts.map +1 -0
  448. package/dist/ui/icon.test.js +115 -0
  449. package/dist/ui/index.d.ts +11 -0
  450. package/dist/ui/index.d.ts.map +1 -0
  451. package/dist/ui/index.js +5 -0
  452. package/dist/ui/panel.d.ts +18 -0
  453. package/dist/ui/panel.d.ts.map +1 -0
  454. package/dist/ui/panel.js +21 -0
  455. package/dist/ui/portal.d.ts +14 -0
  456. package/dist/ui/portal.d.ts.map +1 -0
  457. package/dist/ui/portal.js +14 -0
  458. package/dist/ui/primitives.d.ts +190 -0
  459. package/dist/ui/primitives.d.ts.map +1 -0
  460. package/dist/ui/primitives.js +164 -0
  461. package/dist/ui/primitives.test.d.ts +2 -0
  462. package/dist/ui/primitives.test.d.ts.map +1 -0
  463. package/dist/ui/primitives.test.js +215 -0
  464. package/dist/ui/toast.d.ts +39 -0
  465. package/dist/ui/toast.d.ts.map +1 -0
  466. package/dist/ui/toast.js +76 -0
  467. package/dist/ui/toast.test.d.ts +2 -0
  468. package/dist/ui/toast.test.d.ts.map +1 -0
  469. package/dist/ui/toast.test.js +95 -0
  470. package/package.json +66 -3
  471. package/README.md +0 -3
@@ -0,0 +1,327 @@
1
+ import { createRegistryMeta, createSeededIdGenerator, } from '@next-buildr/core';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import { flattenTree } from '../panels/layers/flatten.js';
4
+ import { createEditorStore } from '../store/index.js';
5
+ import { moveDestinations } from './destinations.js';
6
+ import { createDragEngine, DRAG_THRESHOLD, } from './engine.js';
7
+ import { fragmentFor } from './fragment.js';
8
+ import { autoscrollDelta, toCanvasPoint } from './geometry.js';
9
+ import { treeDropTarget } from './tree-target.js';
10
+ const base = {
11
+ type: 'buildr/leaf',
12
+ version: 1,
13
+ label: 'Leaf',
14
+ category: 'content',
15
+ props: {},
16
+ contentCategories: ['flow'],
17
+ styles: { groups: [] },
18
+ runtime: 'shared',
19
+ };
20
+ const box = {
21
+ ...base,
22
+ type: 'buildr/box',
23
+ label: 'Box',
24
+ slots: { default: {} },
25
+ };
26
+ const page = {
27
+ ...box,
28
+ type: 'buildr/page',
29
+ label: 'Page',
30
+ capabilities: { root: true },
31
+ };
32
+ const registry = createRegistryMeta({ components: [page, box, base] });
33
+ const fixture = () => ({
34
+ schemaVersion: 1,
35
+ root: 'root',
36
+ nodes: {
37
+ root: { id: 'root', type: 'buildr/page', slots: { default: ['boxAAAAAA1', 'leafBBBBB1'] } },
38
+ boxAAAAAA1: { id: 'boxAAAAAA1', type: 'buildr/box', slots: { default: ['leafCCCCC1'] } },
39
+ leafBBBBB1: { id: 'leafBBBBB1', type: 'buildr/leaf' },
40
+ leafCCCCC1: { id: 'leafCCCCC1', type: 'buildr/leaf' },
41
+ },
42
+ components: {},
43
+ });
44
+ const newStore = (doc = fixture()) => createEditorStore({
45
+ doc,
46
+ registry,
47
+ generateId: createSeededIdGenerator(7),
48
+ validationDelayMs: null,
49
+ });
50
+ const ROW = 28;
51
+ const all = (doc) => new Set(Object.keys(doc.nodes));
52
+ describe('fragmentFor', () => {
53
+ it('stamps the versions of the registry, not 1', () => {
54
+ const v2 = createRegistryMeta({ components: [page, { ...box, version: 2 }, base] });
55
+ const fragment = fragmentFor(v2, { kind: 'component', type: 'buildr/box' });
56
+ expect(fragment?.components).toEqual({ 'buildr/box': 2 });
57
+ });
58
+ });
59
+ describe('toCanvasPoint', () => {
60
+ it('subtracts the frame offset and divides by the zoom', () => {
61
+ const frame = { left: 100, top: 50, width: 640, height: 400 };
62
+ expect(toCanvasPoint({ x: 100, y: 50 }, frame)).toEqual({ x: 0, y: 0 });
63
+ expect(toCanvasPoint({ x: 420, y: 250 }, frame, 0.5)).toEqual({ x: 640, y: 400 });
64
+ expect(toCanvasPoint({ x: 150, y: 90 }, frame, 2)).toEqual({ x: 25, y: 20 });
65
+ });
66
+ it('gives nothing for a frame that is not laid out', () => {
67
+ const frame = { left: 0, top: 0, width: 0, height: 0 };
68
+ expect(toCanvasPoint({ x: 1, y: 1 }, frame, 0)).toBeUndefined();
69
+ expect(toCanvasPoint({ x: 1, y: 1 }, frame, Number.NaN)).toBeUndefined();
70
+ });
71
+ });
72
+ describe('autoscrollDelta', () => {
73
+ const region = { left: 0, top: 100, width: 200, height: 300 };
74
+ it('is zero in the middle and grows towards the edges', () => {
75
+ expect(autoscrollDelta(region, 250)).toBe(0);
76
+ const near = autoscrollDelta(region, 130);
77
+ const at = autoscrollDelta(region, 100);
78
+ expect(near).toBeLessThan(0);
79
+ expect(at).toBeLessThan(near);
80
+ expect(autoscrollDelta(region, 380)).toBeGreaterThan(0);
81
+ });
82
+ it('keeps scrolling at full speed past the edge', () => {
83
+ expect(autoscrollDelta(region, 20)).toBe(-24);
84
+ expect(autoscrollDelta(region, 900)).toBe(24);
85
+ });
86
+ });
87
+ describe('treeDropTarget', () => {
88
+ const rows = (doc = fixture()) => flattenTree(doc, all(doc));
89
+ // Rows: 0 root, 1 box, 2 leafC (in box), 3 leafB.
90
+ const at = (item, row, within, doc = fixture()) => treeDropTarget({
91
+ doc,
92
+ registry,
93
+ rows: rows(doc),
94
+ item,
95
+ y: row * ROW + within * ROW,
96
+ rowHeight: ROW,
97
+ });
98
+ it('drops before, inside and after the row under the pointer', () => {
99
+ const item = { kind: 'component', type: 'buildr/leaf' };
100
+ expect(at(item, 3, 0.1)?.target).toEqual({ parentId: 'root', slot: 'default', index: 1 });
101
+ expect(at(item, 3, 0.9)?.target).toEqual({ parentId: 'root', slot: 'default', index: 2 });
102
+ expect(at(item, 1, 0.5)?.target).toEqual({ parentId: 'boxAAAAAA1', slot: 'default', index: 1 });
103
+ });
104
+ it('falls back to the parent when a leaf cannot hold the item', () => {
105
+ const result = at({ kind: 'component', type: 'buildr/leaf' }, 3, 0.5);
106
+ expect(result?.target).toEqual({ parentId: 'root', slot: 'default', index: 2 });
107
+ });
108
+ it('only ever drops inside the root row', () => {
109
+ const result = at({ kind: 'component', type: 'buildr/leaf' }, 0, 0.05);
110
+ expect(result?.position).toBe('inside');
111
+ expect(result?.target?.parentId).toBe('root');
112
+ });
113
+ it('clamps a pointer past the last row', () => {
114
+ const result = treeDropTarget({
115
+ doc: fixture(),
116
+ registry,
117
+ rows: rows(),
118
+ item: { kind: 'component', type: 'buildr/leaf' },
119
+ y: 10_000,
120
+ rowHeight: ROW,
121
+ });
122
+ expect(result?.rowIndex).toBe(3);
123
+ });
124
+ it('refuses moving a node into itself and says why', () => {
125
+ const result = at({ kind: 'nodes', ids: ['boxAAAAAA1'] }, 2, 0.5);
126
+ // Inside the leaf is impossible; after it and after the box (its own place) are not offered.
127
+ expect(result?.target).toBeNull();
128
+ expect(result?.reason).toBeDefined();
129
+ });
130
+ it('refuses an unknown palette item', () => {
131
+ expect(at({ kind: 'component', type: 'nope/none' }, 3, 0.5)?.target).toBeNull();
132
+ });
133
+ it('gives nothing for an empty list', () => {
134
+ expect(treeDropTarget({
135
+ doc: fixture(),
136
+ registry,
137
+ rows: [],
138
+ item: { kind: 'nodes', ids: ['leafBBBBB1'] },
139
+ y: 0,
140
+ rowHeight: ROW,
141
+ })).toBeUndefined();
142
+ });
143
+ });
144
+ describe('moveDestinations', () => {
145
+ it('lists the slots the rules accept, never inside the moved node', () => {
146
+ const doc = fixture();
147
+ const list = moveDestinations(doc, registry, ['boxAAAAAA1']);
148
+ expect(list.map((d) => d.parentId)).toEqual(['root']);
149
+ const leaf = moveDestinations(doc, registry, ['leafCCCCC1']).map((d) => d.parentId);
150
+ expect(leaf).toEqual(['root', 'boxAAAAAA1']);
151
+ });
152
+ it('gives nothing for the root or an unknown id', () => {
153
+ expect(moveDestinations(fixture(), registry, ['root', 'zzzzzzzzzz'])).toEqual([]);
154
+ });
155
+ });
156
+ describe('createDragEngine', () => {
157
+ function setup(options = {}) {
158
+ const store = newStore();
159
+ const host = { dndOver: vi.fn(), dndLeave: vi.fn() };
160
+ const frames = [];
161
+ const canvas = {
162
+ frame: { left: 300, top: 0, width: 600, height: 600 },
163
+ scale: options.canvasScale ?? 1,
164
+ };
165
+ const rows = flattenTree(store.getState().doc, all(store.getState().doc));
166
+ const tree = {
167
+ viewport: { left: 0, top: 0, width: 280, height: 400 },
168
+ scrollTop: 0,
169
+ rows,
170
+ rowHeight: ROW,
171
+ };
172
+ const engine = createDragEngine({
173
+ store,
174
+ host: () => host,
175
+ surfaces: { canvas: () => canvas, tree: () => tree },
176
+ raf: (cb) => frames.push(cb),
177
+ caf: () => undefined,
178
+ });
179
+ const flush = () => {
180
+ const pending = frames.splice(0);
181
+ for (const cb of pending)
182
+ cb();
183
+ };
184
+ return { store, host, engine, flush };
185
+ }
186
+ const leaf = { kind: 'component', type: 'buildr/leaf' };
187
+ it('stays a click until the pointer moves past the threshold', () => {
188
+ const { engine } = setup();
189
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
190
+ engine.move({ x: 10 + DRAG_THRESHOLD - 1, y: 10 });
191
+ expect(engine.state.getState().phase).toBe('pending');
192
+ expect(engine.release()).toBe(false);
193
+ expect(engine.state.getState().phase).toBe('idle');
194
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
195
+ engine.move({ x: 10 + DRAG_THRESHOLD, y: 10 });
196
+ expect(engine.state.getState().phase).toBe('dragging');
197
+ });
198
+ it('forwards the pointer to the canvas once per frame, translated for offset and zoom', () => {
199
+ const { engine, host, flush } = setup({ canvasScale: 0.5 });
200
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
201
+ engine.move({ x: 320, y: 40 });
202
+ engine.move({ x: 400, y: 100 });
203
+ engine.move({ x: 500, y: 200 });
204
+ expect(host.dndOver).not.toHaveBeenCalled();
205
+ flush();
206
+ expect(host.dndOver).toHaveBeenCalledTimes(1);
207
+ expect(host.dndOver).toHaveBeenCalledWith({ x: 400, y: 400 }, leaf);
208
+ expect(engine.state.getState().over).toBe('canvas');
209
+ });
210
+ it('drops what the canvas chose and selects the new node', () => {
211
+ const { engine, store } = setup();
212
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
213
+ engine.move({ x: 400, y: 100 });
214
+ engine.receiveTarget({ parentId: 'root', slot: 'default', index: 1 });
215
+ expect(engine.release()).toBe(true);
216
+ const children = store.getState().doc.nodes['root']?.slots?.['default'] ?? [];
217
+ expect(children).toHaveLength(3);
218
+ expect(store.getState().selectedIds).toEqual([children[1]]);
219
+ expect(engine.state.getState().phase).toBe('idle');
220
+ });
221
+ it('tells the canvas the drag is over, also when it is cancelled', () => {
222
+ const { engine, host, flush } = setup();
223
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
224
+ engine.move({ x: 400, y: 100 });
225
+ flush();
226
+ engine.cancel();
227
+ expect(host.dndLeave).toHaveBeenCalledTimes(1);
228
+ expect(engine.state.getState().phase).toBe('idle');
229
+ });
230
+ it('does not drop where the canvas refused', () => {
231
+ const { engine, store } = setup();
232
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
233
+ engine.move({ x: 400, y: 100 });
234
+ engine.receiveTarget(null, { code: 'x', message: 'no' });
235
+ expect(engine.release()).toBe(false);
236
+ expect(store.getState().doc.nodes['root']?.slots?.['default']).toHaveLength(2);
237
+ });
238
+ it('ignores a target that arrives after the drag ended', () => {
239
+ const { engine } = setup();
240
+ engine.receiveTarget({ parentId: 'root', slot: 'default', index: 0 });
241
+ expect(engine.state.getState().target).toBeNull();
242
+ });
243
+ it('moves nodes within the tree', () => {
244
+ const { engine, store } = setup();
245
+ engine.press({ kind: 'nodes', ids: ['leafBBBBB1'] }, 'Leaf', { x: 20, y: 3 * ROW + 14 });
246
+ // Over the top edge of the first box row: before it.
247
+ engine.move({ x: 20, y: 1 * ROW + 2 });
248
+ expect(engine.state.getState().over).toBe('tree');
249
+ expect(engine.state.getState().target).toEqual({
250
+ parentId: 'root',
251
+ slot: 'default',
252
+ index: 0,
253
+ });
254
+ expect(engine.release()).toBe(true);
255
+ expect(store.getState().doc.nodes['root']?.slots?.['default']).toEqual([
256
+ 'leafBBBBB1',
257
+ 'boxAAAAAA1',
258
+ ]);
259
+ });
260
+ it('refuses a drop into the node itself and keeps the document', () => {
261
+ const { engine, store } = setup();
262
+ const before = store.getState().doc;
263
+ engine.press({ kind: 'nodes', ids: ['boxAAAAAA1'] }, 'Box', { x: 20, y: 1 * ROW + 14 });
264
+ engine.move({ x: 20, y: 2 * ROW + 14 });
265
+ expect(engine.state.getState().target).toBeNull();
266
+ expect(engine.state.getState().reason).not.toBeNull();
267
+ expect(engine.release()).toBe(false);
268
+ expect(store.getState().doc).toBe(before);
269
+ });
270
+ it('never drops into a read-only document', () => {
271
+ const { engine, store } = setup();
272
+ store.setReadOnly(true);
273
+ const before = store.getState().doc;
274
+ engine.press({ kind: 'nodes', ids: ['leafBBBBB1'] }, 'Leaf', { x: 20, y: 3 * ROW + 14 });
275
+ engine.move({ x: 20, y: 1 * ROW + 2 });
276
+ expect(engine.release()).toBe(false);
277
+ expect(store.getState().doc).toBe(before);
278
+ expect(engine.state.getState().error).toBe('readOnly');
279
+ });
280
+ it('moves nodes by a direct drop (the Move to dialog)', () => {
281
+ const { engine, store } = setup();
282
+ const result = engine.drop({ kind: 'nodes', ids: ['leafBBBBB1'] }, { parentId: 'boxAAAAAA1', slot: 'default', index: 1 });
283
+ expect(result.ok).toBe(true);
284
+ expect(store.getState().doc.nodes['boxAAAAAA1']?.slots?.['default']).toEqual([
285
+ 'leafCCCCC1',
286
+ 'leafBBBBB1',
287
+ ]);
288
+ });
289
+ it('leaves the canvas when the pointer goes to the tree', () => {
290
+ const { engine, host, flush } = setup();
291
+ engine.press(leaf, 'Leaf', { x: 10, y: 10 });
292
+ engine.move({ x: 400, y: 100 });
293
+ flush();
294
+ engine.move({ x: 20, y: 3 * ROW + 14 });
295
+ expect(host.dndLeave).toHaveBeenCalledTimes(1);
296
+ expect(engine.state.getState().over).toBe('tree');
297
+ });
298
+ });
299
+ describe('performance', () => {
300
+ it('finds a drop target in a 1000-node tree well within a frame', () => {
301
+ const nodes = {};
302
+ const ids = [];
303
+ for (let i = 0; i < 999; i++) {
304
+ const id = `n${String(i).padStart(9, '0')}`;
305
+ ids.push(id);
306
+ nodes[id] = { id, type: 'buildr/leaf' };
307
+ }
308
+ nodes['root'] = { id: 'root', type: 'buildr/page', slots: { default: ids } };
309
+ const doc = { schemaVersion: 1, root: 'root', nodes, components: {} };
310
+ const rows = flattenTree(doc, new Set(['root']));
311
+ const run = () => treeDropTarget({
312
+ doc,
313
+ registry,
314
+ rows,
315
+ item: { kind: 'nodes', ids: [ids[10]] },
316
+ y: 500 * ROW + 20,
317
+ rowHeight: ROW,
318
+ });
319
+ run();
320
+ const start = performance.now();
321
+ for (let i = 0; i < 20; i++)
322
+ run();
323
+ const each = (performance.now() - start) / 20;
324
+ // A frame is 16 ms; the budget leaves room for slow CI.
325
+ expect(each).toBeLessThan(12);
326
+ });
327
+ });
@@ -0,0 +1,85 @@
1
+ import type { DragItem, DropTarget, Reason } from '@next-buildr/core';
2
+ import { type StoreApi } from 'zustand/vanilla';
3
+ import type { LayerRow } from '../panels/layers/flatten.ts';
4
+ import type { EditorStore } from '../store/index.ts';
5
+ import { type Point, type Rect } from './geometry.ts';
6
+ import { type TreeDropResult } from './tree-target.ts';
7
+ /** The pointer moves this far (pixels) before a press becomes a drag: a click stays a click. */
8
+ export declare const DRAG_THRESHOLD = 4;
9
+ /** The part of the canvas host a drag talks to. */
10
+ export interface DragHost {
11
+ dndOver(point: Point, item: DragItem): void;
12
+ dndLeave(): void;
13
+ }
14
+ /** The canvas as the pointer sees it: where its frame is in the window and how far it is zoomed. */
15
+ export interface CanvasSurface {
16
+ readonly frame: Rect;
17
+ readonly scale: number;
18
+ }
19
+ /** The layers tree as the pointer sees it. */
20
+ export interface TreeSurface {
21
+ /** The scrolling viewport of the list, in window coordinates. */
22
+ readonly viewport: Rect;
23
+ readonly scrollTop: number;
24
+ readonly rows: readonly LayerRow[];
25
+ readonly rowHeight: number;
26
+ }
27
+ export interface DragSurfaces {
28
+ canvas(): CanvasSurface | undefined;
29
+ tree(): TreeSurface | undefined;
30
+ }
31
+ export type DragPhase = 'idle' | 'pending' | 'dragging';
32
+ export type DragOver = 'canvas' | 'tree' | null;
33
+ export interface DragState {
34
+ readonly phase: DragPhase;
35
+ readonly item: DragItem | null;
36
+ /** What the ghost says (a component's name, the number of nodes). */
37
+ readonly label: string;
38
+ readonly pointer: Point | null;
39
+ readonly over: DragOver;
40
+ /** The gap the item would land in, or `null` where it may not be dropped. */
41
+ readonly target: DropTarget | null;
42
+ readonly reason: Reason | null;
43
+ /** Set while over the tree: which row and side the indicator is drawn on. */
44
+ readonly tree: Pick<TreeDropResult, 'rowIndex' | 'position'> | null;
45
+ /** The message of the last drop the commands refused. */
46
+ readonly error: string | null;
47
+ }
48
+ export interface DragEngineOptions {
49
+ readonly store: EditorStore;
50
+ readonly host: () => DragHost | undefined;
51
+ readonly surfaces: DragSurfaces;
52
+ readonly raf?: (callback: () => void) => number;
53
+ readonly caf?: (handle: number) => void;
54
+ }
55
+ export interface DragEngine {
56
+ readonly state: StoreApi<DragState>;
57
+ /** A pointer went down on something draggable; nothing happens until it moves. */
58
+ press(item: DragItem, label: string, at: Point): void;
59
+ move(at: Point): void;
60
+ /** The pointer went up: drops where the drag stands. Returns whether something was dropped. */
61
+ release(): boolean;
62
+ cancel(): void;
63
+ /** The canvas answered a `dnd:over` (protocol `dnd:target`). */
64
+ receiveTarget(target: DropTarget | null, reason?: Reason): void;
65
+ /** Applies a drop directly (the "Move to…" dialog and the keyboard use it). */
66
+ drop(item: DragItem, target: DropTarget): {
67
+ ok: true;
68
+ } | {
69
+ ok: false;
70
+ message: string;
71
+ };
72
+ dispose(): void;
73
+ }
74
+ export declare const IDLE_STATE: DragState;
75
+ /**
76
+ * The drag-and-drop engine (docs/editor.md#drag-and-drop-pb-086), free of React: a small state
77
+ * machine (idle → pending → dragging), a hit-test of the pointer against the two drop surfaces, and
78
+ * the drop itself. Over the canvas the pointer is translated into the canvas' coordinates (the frame
79
+ * offset and the zoom) and forwarded once per animation frame; the canvas answers with the target
80
+ * (`dnd:target`, computed by `computeDropTarget` where the layout is). Over the tree the target comes
81
+ * from `treeDropTarget` right here. A drop always goes through the commands, `node.insert` or
82
+ * `node.move`, which check the rules again, so a stale or hostile target can do no harm.
83
+ */
84
+ export declare function createDragEngine(options: DragEngineOptions): DragEngine;
85
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/dnd/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { createStore } from 'zustand/vanilla';
2
+ import { fragmentFor } from './fragment.js';
3
+ import { rectContains, toCanvasPoint } from './geometry.js';
4
+ import { treeDropTarget } from './tree-target.js';
5
+ /** The pointer moves this far (pixels) before a press becomes a drag: a click stays a click. */
6
+ export const DRAG_THRESHOLD = 4;
7
+ export const IDLE_STATE = {
8
+ phase: 'idle',
9
+ item: null,
10
+ label: '',
11
+ pointer: null,
12
+ over: null,
13
+ target: null,
14
+ reason: null,
15
+ tree: null,
16
+ error: null,
17
+ };
18
+ /**
19
+ * The drag-and-drop engine (docs/editor.md#drag-and-drop-pb-086), free of React: a small state
20
+ * machine (idle → pending → dragging), a hit-test of the pointer against the two drop surfaces, and
21
+ * the drop itself. Over the canvas the pointer is translated into the canvas' coordinates (the frame
22
+ * offset and the zoom) and forwarded once per animation frame; the canvas answers with the target
23
+ * (`dnd:target`, computed by `computeDropTarget` where the layout is). Over the tree the target comes
24
+ * from `treeDropTarget` right here. A drop always goes through the commands, `node.insert` or
25
+ * `node.move`, which check the rules again, so a stale or hostile target can do no harm.
26
+ */
27
+ export function createDragEngine(options) {
28
+ const { store, surfaces } = options;
29
+ const raf = options.raf ?? ((cb) => requestAnimationFrame(cb));
30
+ const caf = options.caf ?? ((handle) => cancelAnimationFrame(handle));
31
+ const state = createStore(() => IDLE_STATE);
32
+ let origin = null;
33
+ let frame = null;
34
+ let pendingOver = null;
35
+ let forwarding = false;
36
+ const set = (patch) => state.setState(patch);
37
+ function stopForwarding() {
38
+ if (frame !== null) {
39
+ caf(frame);
40
+ frame = null;
41
+ }
42
+ pendingOver = null;
43
+ if (forwarding) {
44
+ forwarding = false;
45
+ options.host()?.dndLeave();
46
+ }
47
+ }
48
+ function reset() {
49
+ stopForwarding();
50
+ origin = null;
51
+ state.setState(IDLE_STATE, true);
52
+ }
53
+ function forward(point, item) {
54
+ pendingOver = { point, item };
55
+ forwarding = true;
56
+ if (frame !== null)
57
+ return;
58
+ frame = raf(() => {
59
+ frame = null;
60
+ const next = pendingOver;
61
+ pendingOver = null;
62
+ if (next !== null)
63
+ options.host()?.dndOver(next.point, next.item);
64
+ });
65
+ }
66
+ function hover(at) {
67
+ const current = state.getState();
68
+ const item = current.item;
69
+ if (item === null)
70
+ return;
71
+ const canvas = surfaces.canvas();
72
+ if (canvas !== undefined && rectContains(canvas.frame, at)) {
73
+ const point = toCanvasPoint(at, canvas.frame, canvas.scale);
74
+ if (point !== undefined) {
75
+ // The canvas decides the target; what was there stays until it answers.
76
+ forward(point, item);
77
+ set({
78
+ pointer: at,
79
+ over: 'canvas',
80
+ tree: null,
81
+ ...(current.over === 'canvas' ? {} : { target: null, reason: null }),
82
+ });
83
+ return;
84
+ }
85
+ }
86
+ const tree = surfaces.tree();
87
+ if (tree !== undefined && rectContains(tree.viewport, at)) {
88
+ if (forwarding) {
89
+ stopForwarding();
90
+ }
91
+ const { doc } = store.getState();
92
+ const result = treeDropTarget({
93
+ doc,
94
+ registry: store.registry,
95
+ rows: tree.rows,
96
+ item,
97
+ y: at.y - tree.viewport.top + tree.scrollTop,
98
+ rowHeight: tree.rowHeight,
99
+ });
100
+ set({
101
+ pointer: at,
102
+ over: 'tree',
103
+ target: result?.target ?? null,
104
+ reason: result?.reason ?? null,
105
+ tree: result === undefined ? null : { rowIndex: result.rowIndex, position: result.position },
106
+ });
107
+ return;
108
+ }
109
+ stopForwarding();
110
+ set({ pointer: at, over: null, target: null, reason: null, tree: null });
111
+ }
112
+ function drop(item, target) {
113
+ const snapshot = store.getState();
114
+ if (snapshot.readOnly)
115
+ return { ok: false, message: 'readOnly' };
116
+ if (item.kind === 'nodes') {
117
+ const ids = item.ids.filter((id) => id !== snapshot.doc.root && Object.hasOwn(snapshot.doc.nodes, id));
118
+ if (ids.length === 0)
119
+ return { ok: false, message: 'nothingToMove' };
120
+ const result = store.dispatch({ type: 'node.move', payload: { ids, ...target } });
121
+ return result.ok ? { ok: true } : { ok: false, message: result.error.message };
122
+ }
123
+ const fragment = fragmentFor(store.registry, item);
124
+ if (fragment === undefined)
125
+ return { ok: false, message: 'unknownItem' };
126
+ const result = store.dispatch({ type: 'node.insert', payload: { ...target, fragment } });
127
+ if (!result.ok)
128
+ return { ok: false, message: result.error.message };
129
+ // The command gives the fragment fresh ids; the new node is the one now at the target position.
130
+ const created = store.getState().doc.nodes[target.parentId]?.slots?.[target.slot]?.[target.index];
131
+ if (created !== undefined)
132
+ store.select(created);
133
+ return { ok: true };
134
+ }
135
+ return {
136
+ state,
137
+ press(item, label, at) {
138
+ reset();
139
+ origin = at;
140
+ state.setState({ ...IDLE_STATE, phase: 'pending', item, label, pointer: at }, true);
141
+ },
142
+ move(at) {
143
+ const current = state.getState();
144
+ if (current.phase === 'idle' || origin === null)
145
+ return;
146
+ if (current.phase === 'pending') {
147
+ if (Math.hypot(at.x - origin.x, at.y - origin.y) < DRAG_THRESHOLD)
148
+ return;
149
+ set({ phase: 'dragging' });
150
+ }
151
+ hover(at);
152
+ },
153
+ release() {
154
+ const current = state.getState();
155
+ const { item, target, phase } = current;
156
+ if (phase !== 'dragging' || item === null) {
157
+ reset();
158
+ return false;
159
+ }
160
+ // A drop is applied before the canvas is told the drag is over.
161
+ let dropped = false;
162
+ let error = null;
163
+ if (target !== null) {
164
+ const result = drop(item, target);
165
+ dropped = result.ok;
166
+ if (!result.ok)
167
+ error = result.message;
168
+ }
169
+ reset();
170
+ if (error !== null)
171
+ set({ error });
172
+ return dropped;
173
+ },
174
+ cancel: reset,
175
+ receiveTarget(target, reason) {
176
+ // Answers that arrive after the drag ended or while over the tree are stale.
177
+ const current = state.getState();
178
+ if (current.phase !== 'dragging' || current.over !== 'canvas')
179
+ return;
180
+ set({ target, reason: reason === undefined ? null : reason });
181
+ },
182
+ drop,
183
+ dispose: reset,
184
+ };
185
+ }
@@ -0,0 +1,6 @@
1
+ import { type BuilderFragment, type DragItem, type RegistryMeta } from '@next-buildr/core';
2
+ /** What dropping a palette item inserts: a template's tree, or a component with its defaults. */
3
+ export declare function fragmentFor(registry: RegistryMeta, item: Exclude<DragItem, {
4
+ kind: 'nodes';
5
+ }>): BuilderFragment | undefined;
6
+ //# sourceMappingURL=fragment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fragment.d.ts","sourceRoot":"","sources":["../../src/dnd/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,QAAQ,EAGb,KAAK,YAAY,EAElB,MAAM,mBAAmB,CAAC;AAE3B,iGAAiG;AACjG,wBAAgB,WAAW,CACzB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,GACzC,eAAe,GAAG,SAAS,CAkB7B"}
@@ -0,0 +1,18 @@
1
+ import { fromTree, instantiateTemplate, registryVersions, } from '@next-buildr/core';
2
+ /** What dropping a palette item inserts: a template's tree, or a component with its defaults. */
3
+ export function fragmentFor(registry, item) {
4
+ const versions = registryVersions(registry);
5
+ if (item.kind === 'template') {
6
+ const definition = registry.getTemplate(item.id);
7
+ return definition === undefined
8
+ ? undefined
9
+ : instantiateTemplate(definition, undefined, undefined, versions);
10
+ }
11
+ const meta = registry.get(item.type);
12
+ if (meta === undefined)
13
+ return undefined;
14
+ return fromTree({
15
+ type: meta.type,
16
+ ...(meta.defaults?.slots !== undefined ? { slots: meta.defaults.slots } : {}),
17
+ }, undefined, versions);
18
+ }
@@ -0,0 +1,30 @@
1
+ export interface Point {
2
+ readonly x: number;
3
+ readonly y: number;
4
+ }
5
+ export interface Rect {
6
+ readonly left: number;
7
+ readonly top: number;
8
+ readonly width: number;
9
+ readonly height: number;
10
+ }
11
+ export declare const rectContains: (rect: Rect, point: Point) => boolean;
12
+ /**
13
+ * A pointer position in the window (`clientX/Y`) as the canvas sees it: relative to the frame's
14
+ * top-left corner and divided by the zoom the frame is shown at (`scale` 0.5 means the page is drawn
15
+ * at half size). A frame that is not laid out (zero scale) gives `undefined` rather than infinity.
16
+ */
17
+ export declare function toCanvasPoint(client: Point, frame: Rect, scale?: number): Point | undefined;
18
+ export interface AutoscrollOptions {
19
+ /** How close to an edge, in pixels, scrolling starts. */
20
+ readonly edge?: number;
21
+ /** Pixels per frame at the very edge. */
22
+ readonly maxSpeed?: number;
23
+ }
24
+ /**
25
+ * How far to scroll a region this frame while a drag is near its top or bottom edge: 0 in the
26
+ * middle, growing linearly to `maxSpeed` at the edge (and past it, so a pointer that left the
27
+ * region keeps scrolling), negative upwards.
28
+ */
29
+ export declare function autoscrollDelta(region: Rect, pointerY: number, { edge, maxSpeed }?: AutoscrollOptions): number;
30
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/dnd/geometry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,SAAU,IAAI,SAAS,KAAK,KAAG,OAItB,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,SAAI,GAAG,KAAK,GAAG,SAAS,CAGtF;AAED,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,EACZ,QAAQ,EAAE,MAAM,EAChB,EAAE,IAAS,EAAE,QAAa,EAAE,GAAE,iBAAsB,GACnD,MAAM,CAQR"}