@next-buildr/editor 2.0.0 → 3.0.0-rc.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 (645) hide show
  1. package/README.md +7 -0
  2. package/UPGRADING.md +322 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/app/builder-editor.test.js +223 -18
  5. package/dist/app/config.d.ts +27 -4
  6. package/dist/app/config.d.ts.map +1 -1
  7. package/dist/app/config.js +4 -3
  8. package/dist/app/contracts.d.ts +40 -0
  9. package/dist/app/contracts.d.ts.map +1 -0
  10. package/dist/app/contracts.js +4 -0
  11. package/dist/app/editor-app.d.ts.map +1 -1
  12. package/dist/app/editor-app.js +316 -24
  13. package/dist/app/editor-app.test.js +144 -6
  14. package/dist/app/layout.d.ts +11 -2
  15. package/dist/app/layout.d.ts.map +1 -1
  16. package/dist/app/layout.js +170 -9
  17. package/dist/app/manifest.d.ts +7 -2
  18. package/dist/app/manifest.d.ts.map +1 -1
  19. package/dist/app/manifest.js +16 -4
  20. package/dist/app/shell-panels.d.ts +15 -0
  21. package/dist/app/shell-panels.d.ts.map +1 -1
  22. package/dist/app/small-screen.test.js +2 -2
  23. package/dist/app/stage-slots.d.ts +9 -0
  24. package/dist/app/stage-slots.d.ts.map +1 -0
  25. package/dist/app/stage-slots.js +10 -0
  26. package/dist/app/status-info.d.ts +2 -3
  27. package/dist/app/status-info.d.ts.map +1 -1
  28. package/dist/app/status-info.js +49 -16
  29. package/dist/canvas-host/canvas-frame.d.ts +13 -1
  30. package/dist/canvas-host/canvas-frame.d.ts.map +1 -1
  31. package/dist/canvas-host/canvas-frame.js +96 -8
  32. package/dist/canvas-host/canvas-frame.test.js +156 -3
  33. package/dist/canvas-host/host.d.ts +6 -0
  34. package/dist/canvas-host/host.d.ts.map +1 -1
  35. package/dist/canvas-host/host.js +116 -4
  36. package/dist/canvas-host/host.test.js +195 -6
  37. package/dist/clipboard/clipboard.d.ts +1 -1
  38. package/dist/clipboard/clipboard.d.ts.map +1 -1
  39. package/dist/clipboard/clipboard.js +5 -0
  40. package/dist/clipboard/clipboard.test.js +21 -1
  41. package/dist/clipboard/format.d.ts +3 -1
  42. package/dist/clipboard/format.d.ts.map +1 -1
  43. package/dist/clipboard/react.d.ts +1 -1
  44. package/dist/clipboard/react.d.ts.map +1 -1
  45. package/dist/clipboard/react.js +49 -3
  46. package/dist/dialogs/external-source.d.ts +15 -0
  47. package/dist/dialogs/external-source.d.ts.map +1 -0
  48. package/dist/dialogs/external-source.js +18 -0
  49. package/dist/dialogs/index.d.ts +4 -0
  50. package/dist/dialogs/index.d.ts.map +1 -1
  51. package/dist/dialogs/index.js +2 -0
  52. package/dist/dialogs/media-picker/index.d.ts +2 -2
  53. package/dist/dialogs/media-picker/index.d.ts.map +1 -1
  54. package/dist/dialogs/media-picker/index.js +1 -1
  55. package/dist/dialogs/media-picker/media-picker.d.ts +5 -0
  56. package/dist/dialogs/media-picker/media-picker.d.ts.map +1 -1
  57. package/dist/dialogs/media-picker/media-picker.js +67 -5
  58. package/dist/dialogs/media-picker/media-picker.test.js +72 -1
  59. package/dist/dialogs/media-picker/media-ref.d.ts +15 -0
  60. package/dist/dialogs/media-picker/media-ref.d.ts.map +1 -1
  61. package/dist/dialogs/media-picker/media-ref.js +29 -0
  62. package/dist/dialogs/remove-confirm.d.ts +14 -0
  63. package/dist/dialogs/remove-confirm.d.ts.map +1 -0
  64. package/dist/dialogs/remove-confirm.js +42 -0
  65. package/dist/dialogs/remove-confirm.test.d.ts +2 -0
  66. package/dist/dialogs/remove-confirm.test.d.ts.map +1 -0
  67. package/dist/dialogs/remove-confirm.test.js +118 -0
  68. package/dist/dnd/dnd-react.test.js +11 -2
  69. package/dist/dnd/dnd.test.js +23 -0
  70. package/dist/dnd/engine.d.ts +4 -2
  71. package/dist/dnd/engine.d.ts.map +1 -1
  72. package/dist/dnd/engine.js +6 -0
  73. package/dist/dnd/move-to-dialog.d.ts +4 -3
  74. package/dist/dnd/move-to-dialog.d.ts.map +1 -1
  75. package/dist/dnd/move-to-dialog.js +67 -10
  76. package/dist/dnd/react.d.ts.map +1 -1
  77. package/dist/dnd/react.js +5 -0
  78. package/dist/i18n/diagnostics.d.ts +22 -0
  79. package/dist/i18n/diagnostics.d.ts.map +1 -0
  80. package/dist/i18n/diagnostics.js +153 -0
  81. package/dist/i18n/diagnostics.test.d.ts +2 -0
  82. package/dist/i18n/diagnostics.test.d.ts.map +1 -0
  83. package/dist/i18n/diagnostics.test.js +74 -0
  84. package/dist/i18n/label-catalog.d.ts +20 -0
  85. package/dist/i18n/label-catalog.d.ts.map +1 -0
  86. package/dist/i18n/label-catalog.js +1 -0
  87. package/dist/i18n/locale-name.d.ts +7 -0
  88. package/dist/i18n/locale-name.d.ts.map +1 -0
  89. package/dist/i18n/locale-name.js +31 -0
  90. package/dist/i18n/localize-manifest.d.ts +11 -0
  91. package/dist/i18n/localize-manifest.d.ts.map +1 -0
  92. package/dist/i18n/localize-manifest.js +78 -0
  93. package/dist/i18n/localize-manifest.test.d.ts +2 -0
  94. package/dist/i18n/localize-manifest.test.d.ts.map +1 -0
  95. package/dist/i18n/localize-manifest.test.js +71 -0
  96. package/dist/messages/catalogs.test.d.ts +2 -0
  97. package/dist/messages/catalogs.test.d.ts.map +1 -0
  98. package/dist/messages/catalogs.test.js +80 -0
  99. package/dist/messages/en/app.d.ts +8 -0
  100. package/dist/messages/en/app.d.ts.map +1 -0
  101. package/dist/messages/en/app.js +7 -0
  102. package/dist/messages/en/blocks.d.ts +54 -0
  103. package/dist/messages/en/blocks.d.ts.map +1 -0
  104. package/dist/messages/en/blocks.js +53 -0
  105. package/dist/messages/en/canvas.d.ts +31 -0
  106. package/dist/messages/en/canvas.d.ts.map +1 -0
  107. package/dist/messages/en/canvas.js +30 -0
  108. package/dist/messages/en/clipboard.d.ts +13 -0
  109. package/dist/messages/en/clipboard.d.ts.map +1 -0
  110. package/dist/messages/en/clipboard.js +12 -0
  111. package/dist/messages/en/colorPicker.d.ts +20 -0
  112. package/dist/messages/en/colorPicker.d.ts.map +1 -0
  113. package/dist/messages/en/colorPicker.js +19 -0
  114. package/dist/messages/en/diagnostics.d.ts +40 -0
  115. package/dist/messages/en/diagnostics.d.ts.map +1 -0
  116. package/dist/messages/en/diagnostics.js +39 -0
  117. package/dist/messages/en/dialogs/common.d.ts +6 -0
  118. package/dist/messages/en/dialogs/common.d.ts.map +1 -0
  119. package/dist/messages/en/dialogs/common.js +5 -0
  120. package/dist/messages/en/dialogs/conflict.d.ts +15 -0
  121. package/dist/messages/en/dialogs/conflict.d.ts.map +1 -0
  122. package/dist/messages/en/dialogs/conflict.js +14 -0
  123. package/dist/messages/en/dialogs/delete.d.ts +19 -0
  124. package/dist/messages/en/dialogs/delete.d.ts.map +1 -0
  125. package/dist/messages/en/dialogs/delete.js +18 -0
  126. package/dist/messages/en/dialogs/pageOptions.d.ts +9 -0
  127. package/dist/messages/en/dialogs/pageOptions.d.ts.map +1 -0
  128. package/dist/messages/en/dialogs/pageOptions.js +8 -0
  129. package/dist/messages/en/dialogs/publish.d.ts +15 -0
  130. package/dist/messages/en/dialogs/publish.d.ts.map +1 -0
  131. package/dist/messages/en/dialogs/publish.js +14 -0
  132. package/dist/messages/en/dnd.d.ts +19 -0
  133. package/dist/messages/en/dnd.d.ts.map +1 -0
  134. package/dist/messages/en/dnd.js +18 -0
  135. package/dist/messages/en/editor.d.ts +30 -0
  136. package/dist/messages/en/editor.d.ts.map +1 -0
  137. package/dist/messages/en/editor.js +29 -0
  138. package/dist/messages/en/external.d.ts +6 -0
  139. package/dist/messages/en/external.d.ts.map +1 -0
  140. package/dist/messages/en/external.js +5 -0
  141. package/dist/messages/en/insert.d.ts +25 -0
  142. package/dist/messages/en/insert.d.ts.map +1 -0
  143. package/dist/messages/en/insert.js +24 -0
  144. package/dist/messages/en/inspector.d.ts +176 -0
  145. package/dist/messages/en/inspector.d.ts.map +1 -0
  146. package/dist/messages/en/inspector.js +175 -0
  147. package/dist/messages/en/issues.d.ts +36 -0
  148. package/dist/messages/en/issues.d.ts.map +1 -0
  149. package/dist/messages/en/issues.js +35 -0
  150. package/dist/messages/en/layers.d.ts +29 -0
  151. package/dist/messages/en/layers.d.ts.map +1 -0
  152. package/dist/messages/en/layers.js +28 -0
  153. package/dist/messages/en/leftPanel.d.ts +15 -0
  154. package/dist/messages/en/leftPanel.d.ts.map +1 -0
  155. package/dist/messages/en/leftPanel.js +14 -0
  156. package/dist/messages/en/list.d.ts +9 -0
  157. package/dist/messages/en/list.d.ts.map +1 -0
  158. package/dist/messages/en/list.js +8 -0
  159. package/dist/messages/en/locale.d.ts +4 -0
  160. package/dist/messages/en/locale.d.ts.map +1 -0
  161. package/dist/messages/en/locale.js +3 -0
  162. package/dist/messages/en/media.d.ts +51 -0
  163. package/dist/messages/en/media.d.ts.map +1 -0
  164. package/dist/messages/en/media.js +50 -0
  165. package/dist/messages/en/menu.d.ts +12 -0
  166. package/dist/messages/en/menu.d.ts.map +1 -0
  167. package/dist/messages/en/menu.js +11 -0
  168. package/dist/messages/en/patterns.d.ts +24 -0
  169. package/dist/messages/en/patterns.d.ts.map +1 -0
  170. package/dist/messages/en/patterns.js +23 -0
  171. package/dist/messages/en/preview.d.ts +8 -0
  172. package/dist/messages/en/preview.d.ts.map +1 -0
  173. package/dist/messages/en/preview.js +7 -0
  174. package/dist/messages/en/publish.d.ts +19 -0
  175. package/dist/messages/en/publish.d.ts.map +1 -0
  176. package/dist/messages/en/publish.js +18 -0
  177. package/dist/messages/en/richText.d.ts +21 -0
  178. package/dist/messages/en/richText.d.ts.map +1 -0
  179. package/dist/messages/en/richText.js +20 -0
  180. package/dist/messages/en/sample.d.ts +5 -0
  181. package/dist/messages/en/sample.d.ts.map +1 -0
  182. package/dist/messages/en/sample.js +4 -0
  183. package/dist/messages/en/save.d.ts +15 -0
  184. package/dist/messages/en/save.d.ts.map +1 -0
  185. package/dist/messages/en/save.js +14 -0
  186. package/dist/messages/en/shortcut.d.ts +36 -0
  187. package/dist/messages/en/shortcut.d.ts.map +1 -0
  188. package/dist/messages/en/shortcut.js +35 -0
  189. package/dist/messages/en/statusBar.d.ts +14 -0
  190. package/dist/messages/en/statusBar.d.ts.map +1 -0
  191. package/dist/messages/en/statusBar.js +13 -0
  192. package/dist/messages/en/structure.d.ts +28 -0
  193. package/dist/messages/en/structure.d.ts.map +1 -0
  194. package/dist/messages/en/structure.js +27 -0
  195. package/dist/messages/en/style.d.ts +168 -0
  196. package/dist/messages/en/style.d.ts.map +1 -0
  197. package/dist/messages/en/style.js +167 -0
  198. package/dist/messages/en/styleField.d.ts +301 -0
  199. package/dist/messages/en/styleField.d.ts.map +1 -0
  200. package/dist/messages/en/styleField.js +300 -0
  201. package/dist/messages/en/styleOption.d.ts +128 -0
  202. package/dist/messages/en/styleOption.d.ts.map +1 -0
  203. package/dist/messages/en/styleOption.js +127 -0
  204. package/dist/messages/en/styleSection.d.ts +16 -0
  205. package/dist/messages/en/styleSection.d.ts.map +1 -0
  206. package/dist/messages/en/styleSection.js +15 -0
  207. package/dist/messages/en/toast.d.ts +22 -0
  208. package/dist/messages/en/toast.d.ts.map +1 -0
  209. package/dist/messages/en/toast.js +21 -0
  210. package/dist/messages/en/toolbar.d.ts +47 -0
  211. package/dist/messages/en/toolbar.d.ts.map +1 -0
  212. package/dist/messages/en/toolbar.js +46 -0
  213. package/dist/messages/en/translation.d.ts +7 -0
  214. package/dist/messages/en/translation.d.ts.map +1 -0
  215. package/dist/messages/en/translation.js +6 -0
  216. package/dist/messages/en/ui.d.ts +4 -0
  217. package/dist/messages/en/ui.d.ts.map +1 -0
  218. package/dist/messages/en/ui.js +3 -0
  219. package/dist/messages/en/values.d.ts +45 -0
  220. package/dist/messages/en/values.d.ts.map +1 -0
  221. package/dist/messages/en/values.js +44 -0
  222. package/dist/messages/en.d.ts +1298 -202
  223. package/dist/messages/en.d.ts.map +1 -1
  224. package/dist/messages/en.js +82 -330
  225. package/dist/messages/index.d.ts +12 -0
  226. package/dist/messages/index.d.ts.map +1 -1
  227. package/dist/messages/index.js +28 -1
  228. package/dist/messages/pl/app.d.ts +8 -0
  229. package/dist/messages/pl/app.d.ts.map +1 -0
  230. package/dist/messages/pl/app.js +7 -0
  231. package/dist/messages/pl/blocks.d.ts +54 -0
  232. package/dist/messages/pl/blocks.d.ts.map +1 -0
  233. package/dist/messages/pl/blocks.js +53 -0
  234. package/dist/messages/pl/canvas.d.ts +31 -0
  235. package/dist/messages/pl/canvas.d.ts.map +1 -0
  236. package/dist/messages/pl/canvas.js +30 -0
  237. package/dist/messages/pl/clipboard.d.ts +13 -0
  238. package/dist/messages/pl/clipboard.d.ts.map +1 -0
  239. package/dist/messages/pl/clipboard.js +12 -0
  240. package/dist/messages/pl/colorPicker.d.ts +20 -0
  241. package/dist/messages/pl/colorPicker.d.ts.map +1 -0
  242. package/dist/messages/pl/colorPicker.js +19 -0
  243. package/dist/messages/pl/componentLabels.d.ts +9 -0
  244. package/dist/messages/pl/componentLabels.d.ts.map +1 -0
  245. package/dist/messages/pl/componentLabels.js +308 -0
  246. package/dist/messages/pl/diagnostics.d.ts +39 -0
  247. package/dist/messages/pl/diagnostics.d.ts.map +1 -0
  248. package/dist/messages/pl/diagnostics.js +38 -0
  249. package/dist/messages/pl/dialogs/common.d.ts +6 -0
  250. package/dist/messages/pl/dialogs/common.d.ts.map +1 -0
  251. package/dist/messages/pl/dialogs/common.js +5 -0
  252. package/dist/messages/pl/dialogs/conflict.d.ts +15 -0
  253. package/dist/messages/pl/dialogs/conflict.d.ts.map +1 -0
  254. package/dist/messages/pl/dialogs/conflict.js +14 -0
  255. package/dist/messages/pl/dialogs/delete.d.ts +19 -0
  256. package/dist/messages/pl/dialogs/delete.d.ts.map +1 -0
  257. package/dist/messages/pl/dialogs/delete.js +18 -0
  258. package/dist/messages/pl/dialogs/pageOptions.d.ts +9 -0
  259. package/dist/messages/pl/dialogs/pageOptions.d.ts.map +1 -0
  260. package/dist/messages/pl/dialogs/pageOptions.js +8 -0
  261. package/dist/messages/pl/dialogs/publish.d.ts +15 -0
  262. package/dist/messages/pl/dialogs/publish.d.ts.map +1 -0
  263. package/dist/messages/pl/dialogs/publish.js +14 -0
  264. package/dist/messages/pl/dnd.d.ts +19 -0
  265. package/dist/messages/pl/dnd.d.ts.map +1 -0
  266. package/dist/messages/pl/dnd.js +18 -0
  267. package/dist/messages/pl/editor.d.ts +30 -0
  268. package/dist/messages/pl/editor.d.ts.map +1 -0
  269. package/dist/messages/pl/editor.js +29 -0
  270. package/dist/messages/pl/external.d.ts +6 -0
  271. package/dist/messages/pl/external.d.ts.map +1 -0
  272. package/dist/messages/pl/external.js +5 -0
  273. package/dist/messages/pl/insert.d.ts +25 -0
  274. package/dist/messages/pl/insert.d.ts.map +1 -0
  275. package/dist/messages/pl/insert.js +24 -0
  276. package/dist/messages/pl/inspector.d.ts +176 -0
  277. package/dist/messages/pl/inspector.d.ts.map +1 -0
  278. package/dist/messages/pl/inspector.js +175 -0
  279. package/dist/messages/pl/issues.d.ts +36 -0
  280. package/dist/messages/pl/issues.d.ts.map +1 -0
  281. package/dist/messages/pl/issues.js +35 -0
  282. package/dist/messages/pl/layers.d.ts +29 -0
  283. package/dist/messages/pl/layers.d.ts.map +1 -0
  284. package/dist/messages/pl/layers.js +28 -0
  285. package/dist/messages/pl/leftPanel.d.ts +15 -0
  286. package/dist/messages/pl/leftPanel.d.ts.map +1 -0
  287. package/dist/messages/pl/leftPanel.js +14 -0
  288. package/dist/messages/pl/list.d.ts +9 -0
  289. package/dist/messages/pl/list.d.ts.map +1 -0
  290. package/dist/messages/pl/list.js +8 -0
  291. package/dist/messages/pl/locale.d.ts +4 -0
  292. package/dist/messages/pl/locale.d.ts.map +1 -0
  293. package/dist/messages/pl/locale.js +3 -0
  294. package/dist/messages/pl/media.d.ts +51 -0
  295. package/dist/messages/pl/media.d.ts.map +1 -0
  296. package/dist/messages/pl/media.js +50 -0
  297. package/dist/messages/pl/menu.d.ts +12 -0
  298. package/dist/messages/pl/menu.d.ts.map +1 -0
  299. package/dist/messages/pl/menu.js +11 -0
  300. package/dist/messages/pl/patterns.d.ts +24 -0
  301. package/dist/messages/pl/patterns.d.ts.map +1 -0
  302. package/dist/messages/pl/patterns.js +23 -0
  303. package/dist/messages/pl/preview.d.ts +8 -0
  304. package/dist/messages/pl/preview.d.ts.map +1 -0
  305. package/dist/messages/pl/preview.js +7 -0
  306. package/dist/messages/pl/publish.d.ts +19 -0
  307. package/dist/messages/pl/publish.d.ts.map +1 -0
  308. package/dist/messages/pl/publish.js +18 -0
  309. package/dist/messages/pl/richText.d.ts +21 -0
  310. package/dist/messages/pl/richText.d.ts.map +1 -0
  311. package/dist/messages/pl/richText.js +20 -0
  312. package/dist/messages/pl/sample.d.ts +5 -0
  313. package/dist/messages/pl/sample.d.ts.map +1 -0
  314. package/dist/messages/pl/sample.js +4 -0
  315. package/dist/messages/pl/save.d.ts +15 -0
  316. package/dist/messages/pl/save.d.ts.map +1 -0
  317. package/dist/messages/pl/save.js +14 -0
  318. package/dist/messages/pl/shortcut.d.ts +36 -0
  319. package/dist/messages/pl/shortcut.d.ts.map +1 -0
  320. package/dist/messages/pl/shortcut.js +35 -0
  321. package/dist/messages/pl/statusBar.d.ts +14 -0
  322. package/dist/messages/pl/statusBar.d.ts.map +1 -0
  323. package/dist/messages/pl/statusBar.js +13 -0
  324. package/dist/messages/pl/structure.d.ts +28 -0
  325. package/dist/messages/pl/structure.d.ts.map +1 -0
  326. package/dist/messages/pl/structure.js +27 -0
  327. package/dist/messages/pl/style.d.ts +168 -0
  328. package/dist/messages/pl/style.d.ts.map +1 -0
  329. package/dist/messages/pl/style.js +167 -0
  330. package/dist/messages/pl/styleField.d.ts +301 -0
  331. package/dist/messages/pl/styleField.d.ts.map +1 -0
  332. package/dist/messages/pl/styleField.js +300 -0
  333. package/dist/messages/pl/styleOption.d.ts +128 -0
  334. package/dist/messages/pl/styleOption.d.ts.map +1 -0
  335. package/dist/messages/pl/styleOption.js +127 -0
  336. package/dist/messages/pl/styleSection.d.ts +16 -0
  337. package/dist/messages/pl/styleSection.d.ts.map +1 -0
  338. package/dist/messages/pl/styleSection.js +15 -0
  339. package/dist/messages/pl/toast.d.ts +22 -0
  340. package/dist/messages/pl/toast.d.ts.map +1 -0
  341. package/dist/messages/pl/toast.js +21 -0
  342. package/dist/messages/pl/toolbar.d.ts +47 -0
  343. package/dist/messages/pl/toolbar.d.ts.map +1 -0
  344. package/dist/messages/pl/toolbar.js +46 -0
  345. package/dist/messages/pl/translation.d.ts +7 -0
  346. package/dist/messages/pl/translation.d.ts.map +1 -0
  347. package/dist/messages/pl/translation.js +6 -0
  348. package/dist/messages/pl/ui.d.ts +4 -0
  349. package/dist/messages/pl/ui.d.ts.map +1 -0
  350. package/dist/messages/pl/ui.js +3 -0
  351. package/dist/messages/pl/values.d.ts +45 -0
  352. package/dist/messages/pl/values.d.ts.map +1 -0
  353. package/dist/messages/pl/values.js +44 -0
  354. package/dist/messages/pl.d.ts.map +1 -1
  355. package/dist/messages/pl.js +82 -325
  356. package/dist/messages/plural.test.d.ts +2 -0
  357. package/dist/messages/plural.test.d.ts.map +1 -0
  358. package/dist/messages/plural.test.js +50 -0
  359. package/dist/panels/breadcrumbs/breadcrumbs.d.ts +1 -1
  360. package/dist/panels/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  361. package/dist/panels/breadcrumbs/breadcrumbs.js +10 -3
  362. package/dist/panels/breadcrumbs/breadcrumbs.test.js +9 -2
  363. package/dist/panels/index.d.ts +3 -0
  364. package/dist/panels/index.d.ts.map +1 -1
  365. package/dist/panels/index.js +1 -0
  366. package/dist/panels/insert/catalog.d.ts +21 -1
  367. package/dist/panels/insert/catalog.d.ts.map +1 -1
  368. package/dist/panels/insert/catalog.js +85 -3
  369. package/dist/panels/insert/catalog.order.test.js +106 -1
  370. package/dist/panels/insert/index.d.ts +1 -0
  371. package/dist/panels/insert/index.d.ts.map +1 -1
  372. package/dist/panels/insert/insert-panel.d.ts +14 -4
  373. package/dist/panels/insert/insert-panel.d.ts.map +1 -1
  374. package/dist/panels/insert/insert-panel.js +128 -69
  375. package/dist/panels/insert/insert-panel.test.js +278 -37
  376. package/dist/panels/insert/target.d.ts +5 -1
  377. package/dist/panels/insert/target.d.ts.map +1 -1
  378. package/dist/panels/insert/target.js +11 -1
  379. package/dist/panels/inspector/author-fields.d.ts +21 -0
  380. package/dist/panels/inspector/author-fields.d.ts.map +1 -0
  381. package/dist/panels/inspector/author-fields.js +191 -0
  382. package/dist/panels/inspector/author-fields.test.d.ts +2 -0
  383. package/dist/panels/inspector/author-fields.test.d.ts.map +1 -0
  384. package/dist/panels/inspector/author-fields.test.js +237 -0
  385. package/dist/panels/inspector/controls/external-link.d.ts +24 -0
  386. package/dist/panels/inspector/controls/external-link.d.ts.map +1 -0
  387. package/dist/panels/inspector/controls/external-link.js +43 -0
  388. package/dist/panels/inspector/controls/external-link.test.d.ts +2 -0
  389. package/dist/panels/inspector/controls/external-link.test.d.ts.map +1 -0
  390. package/dist/panels/inspector/controls/external-link.test.js +105 -0
  391. package/dist/panels/inspector/controls/index.d.ts +1 -0
  392. package/dist/panels/inspector/controls/index.d.ts.map +1 -1
  393. package/dist/panels/inspector/controls/index.js +1 -0
  394. package/dist/panels/inspector/controls/media.d.ts +3 -1
  395. package/dist/panels/inspector/controls/media.d.ts.map +1 -1
  396. package/dist/panels/inspector/controls/media.js +8 -3
  397. package/dist/panels/inspector/controls/rich-text.d.ts.map +1 -1
  398. package/dist/panels/inspector/controls/rich-text.js +36 -6
  399. package/dist/panels/inspector/controls/textarea.d.ts +7 -2
  400. package/dist/panels/inspector/controls/textarea.d.ts.map +1 -1
  401. package/dist/panels/inspector/controls/textarea.js +37 -2
  402. package/dist/panels/inspector/default-hint.d.ts +13 -0
  403. package/dist/panels/inspector/default-hint.d.ts.map +1 -0
  404. package/dist/panels/inspector/default-hint.js +30 -0
  405. package/dist/panels/inspector/default-hint.test.d.ts +2 -0
  406. package/dist/panels/inspector/default-hint.test.d.ts.map +1 -0
  407. package/dist/panels/inspector/default-hint.test.js +46 -0
  408. package/dist/panels/inspector/index.d.ts +3 -3
  409. package/dist/panels/inspector/index.d.ts.map +1 -1
  410. package/dist/panels/inspector/index.js +2 -2
  411. package/dist/panels/inspector/inspector.d.ts +20 -2
  412. package/dist/panels/inspector/inspector.d.ts.map +1 -1
  413. package/dist/panels/inspector/inspector.js +246 -26
  414. package/dist/panels/inspector/inspector.test.js +276 -11
  415. package/dist/panels/inspector/props-panel.d.ts +36 -0
  416. package/dist/panels/inspector/props-panel.d.ts.map +1 -1
  417. package/dist/panels/inspector/props-panel.js +99 -17
  418. package/dist/panels/inspector/props-panel.test.d.ts +2 -0
  419. package/dist/panels/inspector/props-panel.test.d.ts.map +1 -0
  420. package/dist/panels/inspector/props-panel.test.js +17 -0
  421. package/dist/panels/inspector/scrub-label.d.ts +14 -0
  422. package/dist/panels/inspector/scrub-label.d.ts.map +1 -0
  423. package/dist/panels/inspector/scrub-label.js +75 -0
  424. package/dist/panels/inspector/scrub-label.test.d.ts +2 -0
  425. package/dist/panels/inspector/scrub-label.test.d.ts.map +1 -0
  426. package/dist/panels/inspector/scrub-label.test.js +132 -0
  427. package/dist/panels/inspector/styles/background-media.d.ts +28 -0
  428. package/dist/panels/inspector/styles/background-media.d.ts.map +1 -0
  429. package/dist/panels/inspector/styles/background-media.js +78 -0
  430. package/dist/panels/inspector/styles/box-model.d.ts +13 -16
  431. package/dist/panels/inspector/styles/box-model.d.ts.map +1 -1
  432. package/dist/panels/inspector/styles/box-model.js +10 -25
  433. package/dist/panels/inspector/styles/color-input.d.ts +3 -0
  434. package/dist/panels/inspector/styles/color-input.d.ts.map +1 -0
  435. package/dist/panels/inspector/styles/color-input.js +72 -0
  436. package/dist/panels/inspector/styles/gradient-fields.d.ts +9 -0
  437. package/dist/panels/inspector/styles/gradient-fields.d.ts.map +1 -0
  438. package/dist/panels/inspector/styles/gradient-fields.js +50 -0
  439. package/dist/panels/inspector/styles/index.d.ts +2 -0
  440. package/dist/panels/inspector/styles/index.d.ts.map +1 -1
  441. package/dist/panels/inspector/styles/index.js +2 -0
  442. package/dist/panels/inspector/styles/model.d.ts +27 -5
  443. package/dist/panels/inspector/styles/model.d.ts.map +1 -1
  444. package/dist/panels/inspector/styles/model.js +101 -3
  445. package/dist/panels/inspector/styles/motion-rows.d.ts +17 -0
  446. package/dist/panels/inspector/styles/motion-rows.d.ts.map +1 -0
  447. package/dist/panels/inspector/styles/motion-rows.js +117 -0
  448. package/dist/panels/inspector/styles/number-input.d.ts +4 -0
  449. package/dist/panels/inspector/styles/number-input.d.ts.map +1 -0
  450. package/dist/panels/inspector/styles/number-input.js +12 -0
  451. package/dist/panels/inspector/styles/option-label.d.ts +7 -0
  452. package/dist/panels/inspector/styles/option-label.d.ts.map +1 -0
  453. package/dist/panels/inspector/styles/option-label.js +9 -0
  454. package/dist/panels/inspector/styles/property-label.d.ts +9 -0
  455. package/dist/panels/inspector/styles/property-label.d.ts.map +1 -0
  456. package/dist/panels/inspector/styles/property-label.js +11 -0
  457. package/dist/panels/inspector/styles/section-state.d.ts +22 -0
  458. package/dist/panels/inspector/styles/section-state.d.ts.map +1 -0
  459. package/dist/panels/inspector/styles/section-state.js +96 -0
  460. package/dist/panels/inspector/styles/section.d.ts +25 -0
  461. package/dist/panels/inspector/styles/section.d.ts.map +1 -0
  462. package/dist/panels/inspector/styles/section.js +43 -0
  463. package/dist/panels/inspector/styles/sections-context.d.ts +13 -0
  464. package/dist/panels/inspector/styles/sections-context.d.ts.map +1 -0
  465. package/dist/panels/inspector/styles/sections-context.js +19 -0
  466. package/dist/panels/inspector/styles/sections-context.test.d.ts +2 -0
  467. package/dist/panels/inspector/styles/sections-context.test.d.ts.map +1 -0
  468. package/dist/panels/inspector/styles/sections-context.test.js +18 -0
  469. package/dist/panels/inspector/styles/sections-toggle.d.ts +6 -0
  470. package/dist/panels/inspector/styles/sections-toggle.d.ts.map +1 -0
  471. package/dist/panels/inspector/styles/sections-toggle.js +18 -0
  472. package/dist/panels/inspector/styles/segments.d.ts +3 -0
  473. package/dist/panels/inspector/styles/segments.d.ts.map +1 -1
  474. package/dist/panels/inspector/styles/segments.js +11 -4
  475. package/dist/panels/inspector/styles/sides-editor.d.ts +1 -1
  476. package/dist/panels/inspector/styles/sides-editor.d.ts.map +1 -1
  477. package/dist/panels/inspector/styles/sides-editor.js +33 -4
  478. package/dist/panels/inspector/styles/style-inspector.d.ts +3 -1
  479. package/dist/panels/inspector/styles/style-inspector.d.ts.map +1 -1
  480. package/dist/panels/inspector/styles/style-inspector.js +610 -42
  481. package/dist/panels/inspector/styles/style-inspector.test.js +694 -14
  482. package/dist/panels/inspector/styles/token-picker.d.ts +1 -1
  483. package/dist/panels/inspector/styles/token-picker.d.ts.map +1 -1
  484. package/dist/panels/inspector/styles/token-picker.js +10 -3
  485. package/dist/panels/inspector/styles/widgets.d.ts +116 -0
  486. package/dist/panels/inspector/styles/widgets.d.ts.map +1 -0
  487. package/dist/panels/inspector/styles/widgets.js +304 -0
  488. package/dist/panels/inspector/styles/widgets.test.d.ts +2 -0
  489. package/dist/panels/inspector/styles/widgets.test.d.ts.map +1 -0
  490. package/dist/panels/inspector/styles/widgets.test.js +247 -0
  491. package/dist/panels/inspector/values/value-editor.d.ts +1 -1
  492. package/dist/panels/inspector/values/value-editor.d.ts.map +1 -1
  493. package/dist/panels/inspector/values/value-editor.js +9 -8
  494. package/dist/panels/inspector/values/values.test.js +9 -3
  495. package/dist/panels/issues/collect.d.ts +2 -0
  496. package/dist/panels/issues/collect.d.ts.map +1 -1
  497. package/dist/panels/issues/collect.js +1 -0
  498. package/dist/panels/issues/index.d.ts +1 -0
  499. package/dist/panels/issues/index.d.ts.map +1 -1
  500. package/dist/panels/issues/index.js +1 -0
  501. package/dist/panels/issues/issues-panel.d.ts +4 -3
  502. package/dist/panels/issues/issues-panel.d.ts.map +1 -1
  503. package/dist/panels/issues/issues-panel.js +22 -35
  504. package/dist/panels/issues/path.d.ts +7 -0
  505. package/dist/panels/issues/path.d.ts.map +1 -0
  506. package/dist/panels/issues/path.js +21 -0
  507. package/dist/panels/layers/flatten.d.ts +16 -2
  508. package/dist/panels/layers/flatten.d.ts.map +1 -1
  509. package/dist/panels/layers/flatten.js +48 -4
  510. package/dist/panels/layers/layers-panel.d.ts +5 -2
  511. package/dist/panels/layers/layers-panel.d.ts.map +1 -1
  512. package/dist/panels/layers/layers-panel.js +177 -35
  513. package/dist/panels/layers/layers-panel.test.js +173 -15
  514. package/dist/panels/left-panel.d.ts +17 -0
  515. package/dist/panels/left-panel.d.ts.map +1 -0
  516. package/dist/panels/left-panel.js +47 -0
  517. package/dist/panels/left-panel.test.d.ts +2 -0
  518. package/dist/panels/left-panel.test.d.ts.map +1 -0
  519. package/dist/panels/left-panel.test.js +77 -0
  520. package/dist/persistence/persistence.test.js +9 -3
  521. package/dist/persistence/react.d.ts.map +1 -1
  522. package/dist/persistence/react.js +2 -2
  523. package/dist/preview/preview.d.ts +8 -0
  524. package/dist/preview/preview.d.ts.map +1 -1
  525. package/dist/preview/preview.js +21 -1
  526. package/dist/preview/preview.test.js +18 -1
  527. package/dist/shortcuts/actions.d.ts +13 -2
  528. package/dist/shortcuts/actions.d.ts.map +1 -1
  529. package/dist/shortcuts/actions.js +70 -15
  530. package/dist/shortcuts/help.d.ts +11 -0
  531. package/dist/shortcuts/help.d.ts.map +1 -0
  532. package/dist/shortcuts/help.js +77 -0
  533. package/dist/shortcuts/index.d.ts +5 -2
  534. package/dist/shortcuts/index.d.ts.map +1 -1
  535. package/dist/shortcuts/index.js +3 -1
  536. package/dist/shortcuts/map.d.ts +1 -1
  537. package/dist/shortcuts/map.d.ts.map +1 -1
  538. package/dist/shortcuts/map.js +14 -8
  539. package/dist/shortcuts/navigation.d.ts +13 -0
  540. package/dist/shortcuts/navigation.d.ts.map +1 -0
  541. package/dist/shortcuts/navigation.js +48 -0
  542. package/dist/shortcuts/shortcuts.d.ts +12 -1
  543. package/dist/shortcuts/shortcuts.d.ts.map +1 -1
  544. package/dist/shortcuts/shortcuts.js +61 -14
  545. package/dist/shortcuts/shortcuts.test.js +206 -5
  546. package/dist/store/create-store.d.ts.map +1 -1
  547. package/dist/store/create-store.js +19 -1
  548. package/dist/store/index.d.ts +4 -1
  549. package/dist/store/index.d.ts.map +1 -1
  550. package/dist/store/index.js +3 -1
  551. package/dist/store/react.d.ts +4 -0
  552. package/dist/store/react.d.ts.map +1 -1
  553. package/dist/store/react.js +7 -0
  554. package/dist/store/store.test.js +24 -0
  555. package/dist/store/structure-lock.d.ts +16 -0
  556. package/dist/store/structure-lock.d.ts.map +1 -0
  557. package/dist/store/structure-lock.js +43 -0
  558. package/dist/store/structure-lock.test.d.ts +2 -0
  559. package/dist/store/structure-lock.test.d.ts.map +1 -0
  560. package/dist/store/structure-lock.test.js +49 -0
  561. package/dist/store/types.d.ts +9 -0
  562. package/dist/store/types.d.ts.map +1 -1
  563. package/dist/store/view.d.ts +20 -0
  564. package/dist/store/view.d.ts.map +1 -0
  565. package/dist/store/view.js +17 -0
  566. package/dist/store/view.test.d.ts +2 -0
  567. package/dist/store/view.test.d.ts.map +1 -0
  568. package/dist/store/view.test.js +103 -0
  569. package/dist/styles/tokens.test.js +88 -9
  570. package/dist/styles.css +4112 -586
  571. package/dist/toolbar/brand.d.ts +2 -2
  572. package/dist/toolbar/brand.d.ts.map +1 -1
  573. package/dist/toolbar/brand.js +4 -4
  574. package/dist/toolbar/breakpoint-control.d.ts +4 -0
  575. package/dist/toolbar/breakpoint-control.d.ts.map +1 -1
  576. package/dist/toolbar/breakpoint-control.js +11 -4
  577. package/dist/toolbar/editable-title.d.ts +4 -1
  578. package/dist/toolbar/editable-title.d.ts.map +1 -1
  579. package/dist/toolbar/editable-title.js +2 -2
  580. package/dist/toolbar/editable-title.test.js +10 -0
  581. package/dist/toolbar/locale-chip.d.ts +10 -0
  582. package/dist/toolbar/locale-chip.d.ts.map +1 -0
  583. package/dist/toolbar/locale-chip.js +27 -0
  584. package/dist/toolbar/locale-switcher.d.ts.map +1 -1
  585. package/dist/toolbar/locale-switcher.js +4 -1
  586. package/dist/toolbar/more-menu.d.ts +26 -4
  587. package/dist/toolbar/more-menu.d.ts.map +1 -1
  588. package/dist/toolbar/more-menu.js +60 -13
  589. package/dist/toolbar/page-chip.d.ts +10 -0
  590. package/dist/toolbar/page-chip.d.ts.map +1 -0
  591. package/dist/toolbar/page-chip.js +12 -0
  592. package/dist/toolbar/page-options-dialog.d.ts +16 -0
  593. package/dist/toolbar/page-options-dialog.d.ts.map +1 -0
  594. package/dist/toolbar/page-options-dialog.js +13 -0
  595. package/dist/toolbar/panel-toggles.d.ts +3 -2
  596. package/dist/toolbar/panel-toggles.d.ts.map +1 -1
  597. package/dist/toolbar/panel-toggles.js +9 -4
  598. package/dist/toolbar/publish-dialog.d.ts +3 -0
  599. package/dist/toolbar/publish-dialog.d.ts.map +1 -1
  600. package/dist/toolbar/publish-dialog.js +34 -7
  601. package/dist/toolbar/publish.test.js +63 -19
  602. package/dist/toolbar/safe-history.d.ts +3 -0
  603. package/dist/toolbar/safe-history.d.ts.map +1 -0
  604. package/dist/toolbar/safe-history.js +5 -0
  605. package/dist/toolbar/sample-picker.d.ts +24 -4
  606. package/dist/toolbar/sample-picker.d.ts.map +1 -1
  607. package/dist/toolbar/sample-picker.js +42 -18
  608. package/dist/toolbar/toolbar-centre.d.ts +3 -11
  609. package/dist/toolbar/toolbar-centre.d.ts.map +1 -1
  610. package/dist/toolbar/toolbar-centre.js +4 -5
  611. package/dist/toolbar/toolbar-left.d.ts +4 -7
  612. package/dist/toolbar/toolbar-left.d.ts.map +1 -1
  613. package/dist/toolbar/toolbar-left.js +13 -11
  614. package/dist/toolbar/toolbar-right.d.ts +21 -6
  615. package/dist/toolbar/toolbar-right.d.ts.map +1 -1
  616. package/dist/toolbar/toolbar-right.js +28 -14
  617. package/dist/toolbar/toolbar.d.ts +23 -17
  618. package/dist/toolbar/toolbar.d.ts.map +1 -1
  619. package/dist/toolbar/toolbar.js +28 -11
  620. package/dist/toolbar/toolbar.test.js +238 -23
  621. package/dist/toolbar/use-overflow-level.d.ts +2 -1
  622. package/dist/toolbar/use-overflow-level.d.ts.map +1 -1
  623. package/dist/toolbar/use-overflow-level.js +9 -3
  624. package/dist/toolbar/zoom-menu.d.ts +5 -1
  625. package/dist/toolbar/zoom-menu.d.ts.map +1 -1
  626. package/dist/toolbar/zoom-menu.js +3 -2
  627. package/dist/ui/icon.d.ts +53 -0
  628. package/dist/ui/icon.d.ts.map +1 -1
  629. package/dist/ui/icon.js +58 -1
  630. package/dist/ui/icon.test.js +101 -3
  631. package/dist/ui/index.d.ts +4 -3
  632. package/dist/ui/index.d.ts.map +1 -1
  633. package/dist/ui/index.js +3 -2
  634. package/dist/ui/primitives.d.ts +97 -14
  635. package/dist/ui/primitives.d.ts.map +1 -1
  636. package/dist/ui/primitives.js +108 -22
  637. package/dist/ui/primitives.test.js +204 -3
  638. package/dist/ui/structure-locked.d.ts +9 -0
  639. package/dist/ui/structure-locked.d.ts.map +1 -0
  640. package/dist/ui/structure-locked.js +28 -0
  641. package/dist/ui/toast.d.ts +3 -1
  642. package/dist/ui/toast.d.ts.map +1 -1
  643. package/dist/ui/toast.js +21 -5
  644. package/dist/ui/toast.test.js +34 -0
  645. package/package.json +6 -4
@@ -6,10 +6,12 @@ import { createRoot } from 'react-dom/client';
6
6
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
7
  import { MessagesProvider } from '../messages/index.js';
8
8
  import { createEditorStore, EditorStoreProvider } from '../store/index.js';
9
+ import { ToastProvider } from '../ui/index.js';
9
10
  import { comboOf, displayCombo, isTypingTarget, normalizeCombo } from './keys.js';
10
11
  import { DEFAULT_SHORTCUTS } from './map.js';
12
+ import { overlayOpen, parentSelection } from './navigation.js';
11
13
  import { createShortcutRegistry } from './registry.js';
12
- import { ShortcutProvider, useForwardedKeys } from './shortcuts.js';
14
+ import { ShortcutProvider, useForwardedKeys, useOpenShortcuts } from './shortcuts.js';
13
15
  globalThis.IS_REACT_ACT_ENVIRONMENT = true;
14
16
  const none = { shift: false, alt: false, ctrl: false, meta: false };
15
17
  const press = (key, mods = {}) => ({
@@ -121,6 +123,16 @@ const page = {
121
123
  capabilities: { root: true },
122
124
  };
123
125
  const registryMeta = createRegistryMeta({ components: [page, item] });
126
+ const nested = () => ({
127
+ schemaVersion: 1,
128
+ root: 'root',
129
+ nodes: {
130
+ root: { id: 'root', type: 'buildr/page', slots: { default: ['secAAAAAA1'] } },
131
+ secAAAAAA1: { id: 'secAAAAAA1', type: 'buildr/item', slots: { default: ['itemAAAAA1'] } },
132
+ itemAAAAA1: { id: 'itemAAAAA1', type: 'buildr/item' },
133
+ },
134
+ components: {},
135
+ });
124
136
  const fixture = () => ({
125
137
  schemaVersion: 1,
126
138
  root: 'root',
@@ -150,14 +162,16 @@ describe('ShortcutProvider', () => {
150
162
  forwarded = useForwardedKeys();
151
163
  return _jsx("input", { "aria-label": "field" });
152
164
  }
153
- async function mount() {
165
+ async function mount(extra = {}) {
154
166
  const store = createEditorStore({
155
- doc: fixture(),
167
+ doc: extra.doc ?? fixture(),
156
168
  registry: registryMeta,
157
169
  generateId: createSeededIdGenerator(5),
158
170
  validationDelayMs: null,
171
+ canUnlock: () => true,
159
172
  });
160
- await act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(EditorStoreProvider, { store: store, children: _jsx(ShortcutProvider, { platform: "other", actions: actions, children: _jsx(Probe, {}) }) }) })));
173
+ const shortcuts = (_jsx(ShortcutProvider, { platform: "other", actions: actions, ...(extra.callbacks ? { callbacks: extra.callbacks } : {}), ...(extra.onRemove ? { onRemove: extra.onRemove } : {}), children: _jsx(Probe, {}) }));
174
+ await act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(EditorStoreProvider, { store: store, children: extra.toasts ? _jsx(ToastProvider, { children: shortcuts }) : shortcuts }) })));
161
175
  return store;
162
176
  }
163
177
  const key = (target, init) => act(async () => {
@@ -185,6 +199,45 @@ describe('ShortcutProvider', () => {
185
199
  await key(document.body, { key: 'Z', ctrlKey: true, shiftKey: true });
186
200
  expect(order(store)).toEqual(['itemAAAAA1', 'itemCCCCC1']);
187
201
  });
202
+ it('refuses to delete, move or duplicate a block locked for structure, and says why', async () => {
203
+ const base = fixture();
204
+ const doc = {
205
+ ...base,
206
+ nodes: {
207
+ ...base.nodes,
208
+ itemBBBBB1: { id: 'itemBBBBB1', type: 'buildr/item', lock: { structure: true } },
209
+ },
210
+ };
211
+ const store = await mount({ doc, toasts: true });
212
+ const before = order(store);
213
+ act(() => store.select('itemBBBBB1'));
214
+ await key(document.body, { key: 'Delete' });
215
+ expect(container.textContent).toContain('This block is locked. Unlock it in the Structure panel.');
216
+ await key(document.body, { key: 'ArrowUp', altKey: true });
217
+ await key(document.body, { key: 'ArrowDown', altKey: true });
218
+ await key(document.body, { key: 'd', ctrlKey: true });
219
+ expect(order(store)).toEqual(before);
220
+ expect(Object.keys(store.getState().doc.nodes)).toHaveLength(4);
221
+ // The neighbour is not locked and still goes.
222
+ act(() => store.select('itemCCCCC1'));
223
+ await key(document.body, { key: 'Delete' });
224
+ expect(order(store)).toEqual(['itemAAAAA1', 'itemBBBBB1']);
225
+ });
226
+ it('toggles session outlines from UI and forwarded canvas keys', async () => {
227
+ const store = await mount();
228
+ container.classList.add('buildr-editor');
229
+ await key(container, { key: 'O', ctrlKey: true, shiftKey: true });
230
+ expect(store.view.getState().outlines).toBe(true);
231
+ act(() => {
232
+ forwarded(press('O', { ctrl: true, shift: true }));
233
+ });
234
+ expect(store.view.getState().outlines).toBe(false);
235
+ const outside = document.createElement('button');
236
+ document.body.append(outside);
237
+ await key(outside, { key: 'O', ctrlKey: true, shiftKey: true });
238
+ expect(store.view.getState().outlines).toBe(false);
239
+ expect(store.getState().docVersion).toBe(0);
240
+ });
188
241
  it('duplicates, moves and clears', async () => {
189
242
  const store = await mount();
190
243
  act(() => store.select('itemBBBBB1'));
@@ -258,6 +311,154 @@ describe('ShortcutProvider', () => {
258
311
  await key(document.body, { key: '?', shiftKey: true });
259
312
  const dialog = document.querySelector('[role=dialog]');
260
313
  expect(dialog?.textContent).toContain('Keyboard shortcuts');
261
- expect(dialog?.textContent).toContain('Ctrl+Shift+Z');
314
+ expect(dialog?.textContent).toContain('CtrlShiftZ');
315
+ });
316
+ const callbacks = () => ({
317
+ setDevice: vi.fn(),
318
+ togglePanels: vi.fn(),
319
+ toggleGuides: vi.fn(),
320
+ openShortcuts: vi.fn(),
321
+ focusBlockSearch: vi.fn(),
322
+ });
323
+ const openOverlay = (role) => {
324
+ const element = document.createElement('div');
325
+ element.setAttribute('role', role);
326
+ element.setAttribute('data-state', 'open');
327
+ document.body.append(element);
328
+ };
329
+ it('runs the UI-only shortcuts through the callbacks', async () => {
330
+ const cb = callbacks();
331
+ await mount({ callbacks: cb });
332
+ await key(document.body, { key: '1', ctrlKey: true });
333
+ await key(document.body, { key: '3', ctrlKey: true });
334
+ await key(document.body, { key: '.', ctrlKey: true });
335
+ await key(document.body, { key: 'O', ctrlKey: true, shiftKey: true });
336
+ await key(document.body, { key: '/' });
337
+ await key(document.body, { key: '?', shiftKey: true });
338
+ expect(cb.setDevice.mock.calls).toEqual([['1'], ['3']]);
339
+ expect(cb.togglePanels).toHaveBeenCalledOnce();
340
+ expect(cb.toggleGuides).toHaveBeenCalledOnce();
341
+ expect(cb.focusBlockSearch).toHaveBeenCalledOnce();
342
+ expect(cb.openShortcuts).toHaveBeenCalledOnce();
343
+ expect(document.querySelector('[role=dialog]')).toBeNull();
344
+ });
345
+ it('does nothing and keeps the key without callbacks', async () => {
346
+ await mount();
347
+ const event = new KeyboardEvent('keydown', { key: '/', bubbles: true, cancelable: true });
348
+ await act(async () => {
349
+ document.body.dispatchEvent(event);
350
+ });
351
+ expect(event.defaultPrevented).toBe(false);
352
+ });
353
+ it('keeps the UI-only keys out of text fields, dialogs and extra modifiers', async () => {
354
+ const cb = callbacks();
355
+ await mount({ callbacks: cb });
356
+ const field = container.querySelector('input');
357
+ await key(field, { key: '/' });
358
+ await key(field, { key: '1', ctrlKey: true });
359
+ await key(field, { key: '?', shiftKey: true });
360
+ await key(document.body, { key: '1', ctrlKey: true, altKey: true });
361
+ await key(document.body, { key: '/', ctrlKey: true });
362
+ openOverlay('dialog');
363
+ await key(document.body, { key: '.', ctrlKey: true });
364
+ await key(document.body, { key: '/' });
365
+ expect(cb.setDevice).not.toHaveBeenCalled();
366
+ expect(cb.focusBlockSearch).not.toHaveBeenCalled();
367
+ expect(cb.togglePanels).not.toHaveBeenCalled();
368
+ expect(cb.openShortcuts).not.toHaveBeenCalled();
369
+ });
370
+ it('selects the parent on Escape and clears at the top level', async () => {
371
+ const store = await mount({ doc: nested() });
372
+ act(() => store.select('itemAAAAA1'));
373
+ await key(document.body, { key: 'Escape' });
374
+ expect(store.getState().selectedIds).toEqual(['secAAAAAA1']);
375
+ await key(document.body, { key: 'Escape' });
376
+ expect(store.getState().selectedIds).toEqual([]);
377
+ });
378
+ it('leaves Escape to an open menu', async () => {
379
+ const store = await mount({ doc: nested() });
380
+ act(() => store.select('itemAAAAA1'));
381
+ openOverlay('menu');
382
+ expect(overlayOpen()).toBe(true);
383
+ await key(document.body, { key: 'Escape' });
384
+ expect(store.getState().selectedIds).toEqual(['itemAAAAA1']);
385
+ });
386
+ it('leaves every editing key to an open dialog or menu', async () => {
387
+ const store = await mount();
388
+ act(() => store.select('itemBBBBB1'));
389
+ openOverlay('dialog');
390
+ await key(document.body, { key: 'Delete' });
391
+ await key(document.body, { key: 'ArrowUp', altKey: true });
392
+ await key(document.body, { key: 'd', ctrlKey: true });
393
+ await key(document.body, { key: 's', ctrlKey: true });
394
+ expect(order(store)).toEqual(['itemAAAAA1', 'itemBBBBB1', 'itemCCCCC1']);
395
+ expect(actions.save).not.toHaveBeenCalled();
396
+ document.querySelector('[role=dialog]')?.remove();
397
+ const menu = document.createElement('div');
398
+ menu.setAttribute('role', 'menu');
399
+ const item = document.createElement('button');
400
+ menu.append(item);
401
+ document.body.append(menu);
402
+ await key(item, { key: 'Delete' });
403
+ expect(order(store)).toEqual(['itemAAAAA1', 'itemBBBBB1', 'itemCCCCC1']);
404
+ });
405
+ it('keeps the UI-only keys out of controls outside the editor', async () => {
406
+ const cb = callbacks();
407
+ await mount({ callbacks: cb });
408
+ const outside = document.createElement('button');
409
+ document.body.append(outside);
410
+ await key(outside, { key: '/' });
411
+ await key(outside, { key: '1', ctrlKey: true });
412
+ expect(cb.focusBlockSearch).not.toHaveBeenCalled();
413
+ expect(cb.setDevice).not.toHaveBeenCalled();
414
+ const inside = document.createElement('div');
415
+ inside.className = 'buildr-editor';
416
+ const control = document.createElement('button');
417
+ inside.append(control);
418
+ document.body.append(inside);
419
+ await key(control, { key: '/' });
420
+ expect(cb.focusBlockSearch).toHaveBeenCalledOnce();
421
+ });
422
+ it('opens the dialog directly through useOpenShortcuts', async () => {
423
+ let open;
424
+ function Opener() {
425
+ open = useOpenShortcuts();
426
+ return null;
427
+ }
428
+ const store = createEditorStore({
429
+ doc: fixture(),
430
+ registry: registryMeta,
431
+ generateId: createSeededIdGenerator(5),
432
+ validationDelayMs: null,
433
+ });
434
+ await act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(EditorStoreProvider, { store: store, children: _jsx(ShortcutProvider, { platform: "other", children: _jsx(Opener, {}) }) }) })));
435
+ await act(async () => open?.());
436
+ expect(document.querySelector('[role=dialog]')?.textContent).toContain('Keyboard shortcuts');
437
+ });
438
+ it('finds the parent of a node', () => {
439
+ const doc = nested();
440
+ expect(parentSelection(doc, ['itemAAAAA1'])).toBe('secAAAAAA1');
441
+ expect(parentSelection(doc, ['secAAAAAA1'])).toBeNull();
442
+ expect(parentSelection(doc, [])).toBeNull();
443
+ });
444
+ it('hands a removal to onRemove with hasDescendants instead of removing', async () => {
445
+ const onRemove = vi.fn();
446
+ const store = await mount({ doc: nested(), onRemove });
447
+ act(() => store.select('secAAAAAA1'));
448
+ await key(document.body, { key: 'Delete' });
449
+ expect(onRemove).toHaveBeenLastCalledWith({ ids: ['secAAAAAA1'], hasDescendants: true });
450
+ act(() => store.select('itemAAAAA1'));
451
+ await key(document.body, { key: 'Backspace' });
452
+ expect(onRemove).toHaveBeenLastCalledWith({ ids: ['itemAAAAA1'], hasDescendants: false });
453
+ expect(Object.keys(store.getState().doc.nodes)).toHaveLength(3);
454
+ });
455
+ it('shows the four groups and the Mac note in the help dialog', async () => {
456
+ await mount();
457
+ await key(document.body, { key: '?', shiftKey: true });
458
+ const text = document.querySelector('[role=dialog]')?.textContent ?? '';
459
+ for (const heading of ['General', 'Selection', 'Editing', 'View']) {
460
+ expect(text).toContain(heading);
461
+ }
462
+ expect(text).toContain('On a Mac use Cmd instead of Ctrl.');
262
463
  });
263
464
  });
@@ -1 +1 @@
1
- {"version":3,"file":"create-store.d.ts","sourceRoot":"","sources":["../../src/store/create-store.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAIV,WAAW,EACX,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAEpB,kFAAkF;AAClF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAmB/C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CA8O1E"}
1
+ {"version":3,"file":"create-store.d.ts","sourceRoot":"","sources":["../../src/store/create-store.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAIV,WAAW,EACX,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAGpB,kFAAkF;AAClF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAmB/C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAgQ1E"}
@@ -1,7 +1,8 @@
1
- import { err, generateId, ok, runA11y, validateDocument, } from '@next-buildr/core';
1
+ import { authorCodeEnabled, err, generateId, ok, runA11y, validateDocument, } from '@next-buildr/core';
2
2
  import { applyDocumentPatches, commandError, commandMergeKey, coreCommandHandlers, createCommandRegistry, createHistory, execute, executeBatch, } from '@next-buildr/core/commands';
3
3
  import { createStore } from 'zustand/vanilla';
4
4
  import { EMPTY_SELECTION, normalizeSelection, relativeNode, selectIn, } from './selection.js';
5
+ import { createViewStore } from './view.js';
5
6
  /** How long after the last change validation and the accessibility checks run. */
6
7
  export const DEFAULT_VALIDATION_DELAY_MS = 300;
7
8
  function defaultTimers() {
@@ -34,6 +35,7 @@ export function createEditorStore(options) {
34
35
  commands,
35
36
  generateId: options.generateId ?? generateId,
36
37
  canUnlock: options.canUnlock,
38
+ ...(options.capabilities !== undefined ? { capabilities: options.capabilities } : {}),
37
39
  checkInvariants: options.checkInvariants ?? false,
38
40
  };
39
41
  const timers = options.timers ?? defaultTimers();
@@ -136,9 +138,25 @@ export function createEditorStore(options) {
136
138
  api.setState(historyState());
137
139
  return result;
138
140
  };
141
+ const view = createViewStore();
142
+ // The insertion target is session presentation: it never points to a node that is gone (removed,
143
+ // undone away, replaced page) and it ends when the selection moves elsewhere.
144
+ api.subscribe((state, previous) => {
145
+ const target = view.getState().insertionTarget;
146
+ if (target === null)
147
+ return;
148
+ const moved = state.selectedIds !== previous.selectedIds &&
149
+ state.selectedIds.join() !== previous.selectedIds.join();
150
+ if (moved || !Object.hasOwn(state.doc.nodes, target.parentId)) {
151
+ view.getState().setInsertionTarget(null);
152
+ }
153
+ });
139
154
  const store = {
155
+ view,
140
156
  ...api,
141
157
  registry: options.registry,
158
+ canUnlock: options.canUnlock !== undefined,
159
+ authorCode: authorCodeEnabled(options.capabilities),
142
160
  history,
143
161
  dispatch: (command, options_) => run([command], options_),
144
162
  dispatchBatch: (commandList, options_) => run(commandList, options_),
@@ -1,9 +1,12 @@
1
1
  export { createEditorStore, DEFAULT_VALIDATION_DELAY_MS } from './create-store.ts';
2
2
  export type { LocaleState, LocaleStore } from './locale.ts';
3
3
  export { createLocaleStore, LocaleProvider, useLocaleState, useOptionalLocaleStore, } from './locale.ts';
4
- export { EditorStoreProvider, useEditor, useEditorState, useIsDirty, useNode, useNodeChildren, useSelectedNode, } from './react.tsx';
4
+ export { EditorStoreProvider, useEditor, useEditorState, useIsDirty, useNode, useNodeChildren, useSelectedNode, useViewState, } from './react.tsx';
5
5
  export type { SelectionMove, SelectMode } from './selection.ts';
6
6
  export { pathTo, relativeNode } from './selection.ts';
7
7
  export { selectChildren, selectIndex, selectIsDirty, selectNode, selectSelectedNode, selectSelectionPath, } from './selectors.ts';
8
+ export { isNodeStructureLocked, structureLockedIds, structureLockReason, } from './structure-lock.ts';
8
9
  export type { DispatchOptions, DocumentChange, EditorState, EditorStore, EditorStoreOptions, ValidationSnapshot, } from './types.ts';
10
+ export type { ViewState, ViewStore } from './view.ts';
11
+ export { createViewStore } from './view.ts';
9
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,UAAU,EACV,OAAO,EACP,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,UAAU,EACV,OAAO,EACP,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export { createEditorStore, DEFAULT_VALIDATION_DELAY_MS } from './create-store.js';
2
2
  export { createLocaleStore, LocaleProvider, useLocaleState, useOptionalLocaleStore, } from './locale.js';
3
- export { EditorStoreProvider, useEditor, useEditorState, useIsDirty, useNode, useNodeChildren, useSelectedNode, } from './react.js';
3
+ export { EditorStoreProvider, useEditor, useEditorState, useIsDirty, useNode, useNodeChildren, useSelectedNode, useViewState, } from './react.js';
4
4
  export { pathTo, relativeNode } from './selection.js';
5
5
  export { selectChildren, selectIndex, selectIsDirty, selectNode, selectSelectedNode, selectSelectionPath, } from './selectors.js';
6
+ export { isNodeStructureLocked, structureLockedIds, structureLockReason, } from './structure-lock.js';
7
+ export { createViewStore } from './view.js';
@@ -1,12 +1,15 @@
1
1
  import type { NodeId, PageNode, SlotName } from '@next-buildr/core';
2
2
  import { type ReactNode } from 'react';
3
3
  import type { EditorState, EditorStore } from './types.ts';
4
+ import type { ViewState } from './view.ts';
4
5
  export declare function EditorStoreProvider(props: {
5
6
  readonly store: EditorStore;
6
7
  readonly children: ReactNode;
7
8
  }): import("react").JSX.Element;
8
9
  /** The store itself, for reading it outside a render or calling its actions. */
9
10
  export declare function useEditor(): EditorStore;
11
+ /** The store when there is one; `undefined` outside a `<EditorStoreProvider>`. */
12
+ export declare function useOptionalEditor(): EditorStore | undefined;
10
13
  /** Subscribes to a part of the state; the component renders again only when that part changes. */
11
14
  export declare function useEditorState<T>(selector: (state: EditorState) => T): T;
12
15
  /** One node; the component renders again only when that node does. */
@@ -14,4 +17,5 @@ export declare function useNode(id: NodeId): PageNode | undefined;
14
17
  export declare function useSelectedNode(): PageNode | undefined;
15
18
  export declare function useNodeChildren(id: NodeId, slot?: SlotName): readonly NodeId[];
16
19
  export declare function useIsDirty(): boolean;
20
+ export declare function useViewState(): ViewState;
17
21
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/store/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B,+BAEA;AAED,gFAAgF;AAChF,wBAAgB,SAAS,IAAI,WAAW,CAIvC;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,CAAC,GAAG,CAAC,CAExE;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAExD;AAED,wBAAgB,eAAe,IAAI,QAAQ,GAAG,SAAS,CAEtD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,QAAoB,GAAG,SAAS,MAAM,EAAE,CAEzF;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/store/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAI3C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B,+BAEA;AAED,gFAAgF;AAChF,wBAAgB,SAAS,IAAI,WAAW,CAIvC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,SAAS,CAE3D;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,CAAC,GAAG,CAAC,CAExE;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAExD;AAED,wBAAgB,eAAe,IAAI,QAAQ,GAAG,SAAS,CAEtD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,QAAoB,GAAG,SAAS,MAAM,EAAE,CAEzF;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,YAAY,IAAI,SAAS,CAExC"}
@@ -13,6 +13,10 @@ export function useEditor() {
13
13
  throw new Error('useEditor must be used inside <EditorStoreProvider>');
14
14
  return store;
15
15
  }
16
+ /** The store when there is one; `undefined` outside a `<EditorStoreProvider>`. */
17
+ export function useOptionalEditor() {
18
+ return useContext(StoreContext);
19
+ }
16
20
  /** Subscribes to a part of the state; the component renders again only when that part changes. */
17
21
  export function useEditorState(selector) {
18
22
  return useStore(useEditor(), selector);
@@ -30,3 +34,6 @@ export function useNodeChildren(id, slot = 'default') {
30
34
  export function useIsDirty() {
31
35
  return useEditorState(selectIsDirty);
32
36
  }
37
+ export function useViewState() {
38
+ return useStore(useEditor().view);
39
+ }
@@ -117,6 +117,30 @@ describe('dispatch', () => {
117
117
  expect(textOf(store, 'textNodeB1')).toContain('B');
118
118
  });
119
119
  });
120
+ describe('unlocking', () => {
121
+ const lock = (value) => ({
122
+ type: 'node.setAttr',
123
+ payload: { id: 'boxNode001', key: 'lock', value },
124
+ });
125
+ const all = { structure: true, content: true, style: true };
126
+ it('lets a lock be set and removed when the host supplies canUnlock', () => {
127
+ const store = create({ canUnlock: () => true });
128
+ expect(store.canUnlock).toBe(true);
129
+ expect(store.dispatch(lock(all)).ok).toBe(true);
130
+ expect(store.dispatch(lock(null)).ok).toBe(true);
131
+ expect(selectNode(store.getState(), 'boxNode001')?.lock).toBeUndefined();
132
+ });
133
+ it('refuses to remove a lock without canUnlock', () => {
134
+ const store = create();
135
+ expect(store.canUnlock).toBe(false);
136
+ expect(store.dispatch(lock(all)).ok).toBe(true);
137
+ const result = store.dispatch(lock(null));
138
+ expect(result.ok).toBe(false);
139
+ if (!result.ok)
140
+ expect(result.error.code).toBe('command.unlock-not-permitted');
141
+ expect(selectNode(store.getState(), 'boxNode001')?.lock).toEqual(all);
142
+ });
143
+ });
120
144
  describe('undo and redo', () => {
121
145
  it('go back and forth, with the version always moving forward', () => {
122
146
  const store = create();
@@ -0,0 +1,16 @@
1
+ import { type BuilderDocument, type NodeId } from '@next-buildr/core';
2
+ /**
3
+ * Whether the block itself, or a block it sits in, is locked for structure (a layer "Lock"). Core
4
+ * checks `lock.structure` from a node's parent on, so a locked block could still be removed, moved
5
+ * or duplicated by itself; the editor refuses those for the block as well (docs/editor.md#layers).
6
+ * A lock above an editable `region` does not reach what is inside the region, as in the canvas host.
7
+ */
8
+ export declare function isNodeStructureLocked(doc: BuilderDocument, id: NodeId): boolean;
9
+ /** The ids among `ids` that `isNodeStructureLocked` holds for. The index is built once per call. */
10
+ export declare function structureLockedIds(doc: BuilderDocument, ids: readonly NodeId[]): NodeId[];
11
+ /**
12
+ * Why the blocks are refused: `self` when one of them carries the lock, `inherited` when each is
13
+ * only locked by a block it sits in (a lock stops at an editable `region`); `undefined` when none is locked.
14
+ */
15
+ export declare function structureLockReason(doc: BuilderDocument, ids: readonly NodeId[]): 'self' | 'inherited' | undefined;
16
+ //# sourceMappingURL=structure-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-lock.d.ts","sourceRoot":"","sources":["../../src/store/structure-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAe,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAgBnF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAG/E;AAED,oGAAoG;AACpG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAIzF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,SAAS,MAAM,EAAE,GACrB,MAAM,GAAG,WAAW,GAAG,SAAS,CAIlC"}
@@ -0,0 +1,43 @@
1
+ import { createIndex } from '@next-buildr/core';
2
+ function lockedWith(doc, index, id) {
3
+ if (!Object.hasOwn(doc.nodes, id))
4
+ return false;
5
+ let current = id;
6
+ while (current !== undefined) {
7
+ const node = doc.nodes[current];
8
+ if (node?.lock?.structure === true)
9
+ return true;
10
+ if (node?.region !== undefined)
11
+ return false;
12
+ current = index.parentOf[current];
13
+ }
14
+ return false;
15
+ }
16
+ /**
17
+ * Whether the block itself, or a block it sits in, is locked for structure (a layer "Lock"). Core
18
+ * checks `lock.structure` from a node's parent on, so a locked block could still be removed, moved
19
+ * or duplicated by itself; the editor refuses those for the block as well (docs/editor.md#layers).
20
+ * A lock above an editable `region` does not reach what is inside the region, as in the canvas host.
21
+ */
22
+ export function isNodeStructureLocked(doc, id) {
23
+ if (!Object.hasOwn(doc.nodes, id))
24
+ return false;
25
+ return lockedWith(doc, createIndex(doc), id);
26
+ }
27
+ /** The ids among `ids` that `isNodeStructureLocked` holds for. The index is built once per call. */
28
+ export function structureLockedIds(doc, ids) {
29
+ if (ids.length === 0)
30
+ return [];
31
+ const index = createIndex(doc);
32
+ return ids.filter((id) => lockedWith(doc, index, id));
33
+ }
34
+ /**
35
+ * Why the blocks are refused: `self` when one of them carries the lock, `inherited` when each is
36
+ * only locked by a block it sits in (a lock stops at an editable `region`); `undefined` when none is locked.
37
+ */
38
+ export function structureLockReason(doc, ids) {
39
+ const locked = structureLockedIds(doc, ids);
40
+ if (locked.length === 0)
41
+ return undefined;
42
+ return locked.some((id) => doc.nodes[id]?.lock?.structure === true) ? 'self' : 'inherited';
43
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=structure-lock.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-lock.test.d.ts","sourceRoot":"","sources":["../../src/store/structure-lock.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isNodeStructureLocked, structureLockedIds } from './structure-lock.js';
3
+ const doc = {
4
+ schemaVersion: 1,
5
+ root: 'root',
6
+ nodes: {
7
+ root: { id: 'root', type: 'buildr/page', slots: { default: ['lockedAAA1', 'openAAAA11'] } },
8
+ lockedAAA1: {
9
+ id: 'lockedAAA1',
10
+ type: 'buildr/box',
11
+ lock: { structure: true },
12
+ slots: { default: ['innerAAAA11', 'regionAAA1'] },
13
+ },
14
+ innerAAAA11: { id: 'innerAAAA11', type: 'buildr/box' },
15
+ regionAAA1: {
16
+ id: 'regionAAA1',
17
+ type: 'buildr/box',
18
+ region: 'main',
19
+ slots: { default: ['inRegion001'] },
20
+ },
21
+ inRegion001: { id: 'inRegion001', type: 'buildr/box' },
22
+ openAAAA11: { id: 'openAAAA11', type: 'buildr/box', lock: { content: true, style: true } },
23
+ },
24
+ components: {},
25
+ };
26
+ describe('isNodeStructureLocked', () => {
27
+ it('is true for the locked node itself', () => {
28
+ expect(isNodeStructureLocked(doc, 'lockedAAA1')).toBe(true);
29
+ });
30
+ it('is true for a node inside a locked one', () => {
31
+ expect(isNodeStructureLocked(doc, 'innerAAAA11')).toBe(true);
32
+ });
33
+ it('is false for a node locked only for content or style, and for an unlocked one', () => {
34
+ expect(isNodeStructureLocked(doc, 'openAAAA11')).toBe(false);
35
+ expect(isNodeStructureLocked(doc, 'root')).toBe(false);
36
+ });
37
+ it('does not reach into an editable region of a locked block', () => {
38
+ expect(isNodeStructureLocked(doc, 'inRegion001')).toBe(false);
39
+ });
40
+ it('is false for an id that is not in the document', () => {
41
+ expect(isNodeStructureLocked(doc, 'missingAAA1')).toBe(false);
42
+ });
43
+ it('filters ids', () => {
44
+ expect(structureLockedIds(doc, ['openAAAA11', 'innerAAAA11', 'lockedAAA1'])).toEqual([
45
+ 'innerAAAA11',
46
+ 'lockedAAA1',
47
+ ]);
48
+ });
49
+ });
@@ -2,6 +2,7 @@ import type { A11yIssue, BuilderDocument, IdGenerator, LocaleConfig, NodeId, Reg
2
2
  import type { Command, CommandEnv, CommandError, CommandRegistry, CommandResult, DocumentPatch, HistoryManager, HistoryOptions } from '@next-buildr/core/commands';
3
3
  import type { StoreApi } from 'zustand/vanilla';
4
4
  import type { SelectionMove, SelectMode } from './selection.ts';
5
+ import type { ViewStore } from './view.ts';
5
6
  /** Findings about the document as it is now, recomputed after it stops changing. */
6
7
  export interface ValidationSnapshot {
7
8
  /** The version of the document they describe. */
@@ -55,7 +56,10 @@ export interface EditorStoreOptions {
55
56
  /** The command set; the core commands by default. */
56
57
  readonly commands?: CommandRegistry;
57
58
  readonly generateId?: IdGenerator;
59
+ /** Lets a lock be weakened (`node.setAttr` `lock`); absent, every unlock is refused (`command.unlock-not-permitted`). */
58
60
  readonly canUnlock?: CommandEnv['canUnlock'];
61
+ /** What the host permits (`authorCode`, ADR-026); the commands refuse author code unless it is exactly `true`. */
62
+ readonly capabilities?: CommandEnv['capabilities'];
59
63
  /** Run `checkInvariants` after every command (a development aid); off by default. */
60
64
  readonly checkInvariants?: boolean;
61
65
  readonly readOnly?: boolean;
@@ -72,6 +76,11 @@ export interface EditorStoreOptions {
72
76
  }
73
77
  /** The store and what changes it. Every change to the document goes through `dispatch`, `undo`, `redo` or `replaceDocument`. */
74
78
  export interface EditorStore extends StoreApi<EditorState> {
79
+ readonly view: ViewStore;
80
+ /** Whether the host supplied `canUnlock`; without it a lock, once set, cannot be weakened. */
81
+ readonly canUnlock: boolean;
82
+ /** Whether the host permits author code (ADR-026): the Advanced fields and the Text HTML mode are shown and writable. */
83
+ readonly authorCode: boolean;
75
84
  /** The registry the commands run against; the palette asks it what may go where. */
76
85
  readonly registry: RegistryMeta;
77
86
  /** Runs a command (`execute`) on the document and records it in the history. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,MAAM,EACN,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;CACrC;AAED,4GAA4G;AAC5G,MAAM,WAAW,WAAW;IAE1B,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,uHAAuH;IACvH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAG3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAGvC,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,yFAAyF;IACzF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAGlC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACrD;AAED,yFAAyF;AACzF,MAAM,MAAM,cAAc,GACtB;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC;IAClC,yHAAyH;IACzH,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC7C,kHAAkH;IAClH,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACnD,qFAAqF;IACrF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QACtD,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;KACrC,CAAC;IACF,sGAAsG;IACtG,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5C;AAED,gIAAgI;AAChI,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAAC,WAAW,CAAC;IACxD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,yHAAyH;IACzH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC3F,uEAAuE;IACvE,aAAa,CACX,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,OAAO,CAAC,EAAE,eAAe,GACxB,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACvC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IACnE,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACnC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACnC,wDAAwD;IACxD,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvF,mHAAmH;IACnH,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,2FAA2F;IAC3F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/F,8DAA8D;IAC9D,YAAY,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3C,cAAc,IAAI,IAAI,CAAC;IACvB,gIAAgI;IAChI,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACpC,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACjE,oFAAoF;IACpF,WAAW,IAAI,kBAAkB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,oCAAoC;IACpC,OAAO,IAAI,IAAI,CAAC;CACjB"}
@@ -0,0 +1,20 @@
1
+ import type { NodeId } from '@next-buildr/core';
2
+ import { type StoreApi } from 'zustand/vanilla';
3
+ /** Session presentation only: never included in the document or persistence state. */
4
+ export interface ViewState {
5
+ readonly insertionTarget: {
6
+ readonly parentId: NodeId;
7
+ readonly slot: string;
8
+ readonly index: number;
9
+ } | null;
10
+ setInsertionTarget(target: ViewState['insertionTarget']): void;
11
+ readonly outlines: boolean;
12
+ readonly hiddenIds: readonly NodeId[];
13
+ toggleOutlines(): void;
14
+ setOutlines(outlines: boolean): void;
15
+ setHiddenIds(ids: readonly NodeId[]): void;
16
+ toggleHidden(id: NodeId): void;
17
+ }
18
+ export type ViewStore = StoreApi<ViewState>;
19
+ export declare function createViewStore(): ViewStore;
20
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/store/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,sFAAsF;AACtF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,eAAe,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI,CAAC;IACT,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC/D,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,cAAc,IAAI,IAAI,CAAC;IACvB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,YAAY,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAE5C,wBAAgB,eAAe,IAAI,SAAS,CAgB3C"}
@@ -0,0 +1,17 @@
1
+ import { createStore } from 'zustand/vanilla';
2
+ export function createViewStore() {
3
+ return createStore((set) => ({
4
+ insertionTarget: null,
5
+ setInsertionTarget: (insertionTarget) => set({ insertionTarget }),
6
+ outlines: false,
7
+ hiddenIds: [],
8
+ toggleOutlines: () => set((state) => ({ outlines: !state.outlines })),
9
+ setOutlines: (outlines) => set({ outlines }),
10
+ setHiddenIds: (ids) => set({ hiddenIds: [...new Set(ids)] }),
11
+ toggleHidden: (id) => set((state) => ({
12
+ hiddenIds: state.hiddenIds.includes(id)
13
+ ? state.hiddenIds.filter((hidden) => hidden !== id)
14
+ : [...state.hiddenIds, id],
15
+ })),
16
+ }));
17
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=view.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.test.d.ts","sourceRoot":"","sources":["../../src/store/view.test.ts"],"names":[],"mappings":""}