@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,258 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // @vitest-environment jsdom
3
+ import { createRegistryMeta, createSeededIdGenerator, p, s, } from '@next-buildr/core';
4
+ import { act } from 'react';
5
+ import { createRoot } from 'react-dom/client';
6
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
+ import { MessagesProvider } from '../messages/index.js';
8
+ import { collectIssues, countIssues, filterIssues, IssuesPanel, publishGate, } from '../panels/issues/index.js';
9
+ import { createPersistence, PersistenceProvider, } from '../persistence/index.js';
10
+ import { createEditorStore, EditorStoreProvider } from '../store/index.js';
11
+ import { ToastProvider } from '../ui/index.js';
12
+ import { PublishDialog } from './publish-dialog.js';
13
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
14
+ const widget = {
15
+ type: 'buildr/widget',
16
+ version: 1,
17
+ label: 'Widget',
18
+ category: 'content',
19
+ props: { count: p.number({ default: 1, min: 0, max: 10 }) },
20
+ contentCategories: ['flow'],
21
+ styles: { groups: [] },
22
+ runtime: 'shared',
23
+ slots: { default: {} },
24
+ };
25
+ const page = {
26
+ ...widget,
27
+ type: 'buildr/page',
28
+ label: 'Page',
29
+ props: {},
30
+ capabilities: { root: true },
31
+ };
32
+ const registry = createRegistryMeta({ components: [page, widget] });
33
+ /** `count` is a string where a number is expected: an error, but the page still renders. */
34
+ const versions = { 'buildr/page': 1, 'buildr/widget': 1 };
35
+ const broken = () => ({
36
+ schemaVersion: 1,
37
+ root: 'root',
38
+ nodes: {
39
+ root: { id: 'root', type: 'buildr/page', slots: { default: ['widget0001'] } },
40
+ widget0001: { id: 'widget0001', type: 'buildr/widget', props: { count: s('many') } },
41
+ },
42
+ components: versions,
43
+ });
44
+ /** No version recorded for the components: the document is damaged. */
45
+ const corrupt = () => ({ ...broken(), components: {} });
46
+ const clean = () => ({
47
+ ...broken(),
48
+ nodes: {
49
+ ...broken().nodes,
50
+ widget0001: { id: 'widget0001', type: 'buildr/widget' },
51
+ },
52
+ });
53
+ const item = (over) => ({
54
+ key: 'k',
55
+ source: 'validation',
56
+ severity: 'warning',
57
+ code: 'x',
58
+ message: 'm',
59
+ blocking: false,
60
+ ...over,
61
+ });
62
+ describe('issue collection and the publish gate', () => {
63
+ it('orders worst first and drops nodes that are gone', () => {
64
+ const items = collectIssues({
65
+ doc: clean(),
66
+ validation: [
67
+ {
68
+ code: 'a',
69
+ message: 'gone',
70
+ severity: 'warning',
71
+ blocking: false,
72
+ path: ['nodes', 'nope'],
73
+ },
74
+ {
75
+ code: 'b',
76
+ message: 'here',
77
+ severity: 'error',
78
+ blocking: false,
79
+ path: ['nodes', 'widget0001', 'props'],
80
+ },
81
+ ],
82
+ a11y: [{ ruleId: 'r', severity: 'info', nodeId: 'widget0001', message: 'note' }],
83
+ });
84
+ expect(items.map((entry) => entry.message)).toEqual(['here', 'gone', 'note']);
85
+ expect(items[0]?.nodeId).toBe('widget0001');
86
+ expect(items[1]?.nodeId).toBeUndefined();
87
+ expect(countIssues(items)).toEqual({ all: 3, error: 1, warning: 1, info: 1 });
88
+ expect(filterIssues(items, 'warning')).toHaveLength(1);
89
+ });
90
+ it('blocks on corruption always and on errors only under the block policy', () => {
91
+ const error = [item({ severity: 'error' })];
92
+ expect(publishGate(error).blocked).toBe(false);
93
+ expect(publishGate(error, 'warn').blocked).toBe(false);
94
+ expect(publishGate(error, 'block')).toMatchObject({ blocked: true, reason: 'errors' });
95
+ expect(publishGate([item({ blocking: true, severity: 'error' })], 'warn')).toMatchObject({
96
+ blocked: true,
97
+ reason: 'blocking',
98
+ });
99
+ expect(publishGate([item({})], 'block').blocked).toBe(false);
100
+ });
101
+ });
102
+ describe('the Issues panel and the publish dialog', () => {
103
+ let container;
104
+ let root;
105
+ beforeEach(() => {
106
+ container = document.createElement('div');
107
+ document.body.append(container);
108
+ root = createRoot(container);
109
+ });
110
+ afterEach(() => {
111
+ act(() => root.unmount());
112
+ document.body.innerHTML = '';
113
+ });
114
+ function setup(doc, policy, publishResult) {
115
+ const publish = vi.fn(async () => publishResult ?? { ok: true, revision: 3, updatedAt: 't3' });
116
+ const adapter = {
117
+ save: async () => ({ ok: true, revision: 2, updatedAt: 't2' }),
118
+ publish,
119
+ };
120
+ const store = createEditorStore({
121
+ doc,
122
+ registry,
123
+ generateId: createSeededIdGenerator(5),
124
+ validationDelayMs: null,
125
+ });
126
+ const controller = createPersistence({
127
+ store,
128
+ adapter,
129
+ ref: { collection: 'pages', id: '1' },
130
+ revision: 1,
131
+ });
132
+ const view = async (open) => act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(EditorStoreProvider, { store: store, children: _jsx(ToastProvider, { children: _jsxs(PersistenceProvider, { controller: controller, children: [_jsx(IssuesPanel, {}), _jsx(PublishDialog, { open: open, onOpenChange: () => undefined, policy: policy })] }) }) }) })));
133
+ return { store, publish, view };
134
+ }
135
+ const publishButton = () => [...document.querySelectorAll('button')].find((button) => button.textContent === 'Publish');
136
+ it('lists an issue and selects its node when it is clicked', async () => {
137
+ const { store, view } = setup(broken(), 'warn');
138
+ await view(false);
139
+ await act(async () => void store.validateNow());
140
+ const target = container.querySelector('.bd-issue-target');
141
+ expect(target).not.toBeNull();
142
+ await act(async () => target.click());
143
+ expect(store.getState().selectedIds).toEqual(['widget0001']);
144
+ });
145
+ it('groups issues by severity, with severity and component icons', async () => {
146
+ const { store, view } = setup(broken(), 'warn');
147
+ await view(false);
148
+ await act(async () => void store.validateNow());
149
+ const sections = [...container.querySelectorAll('.bd-issues-severity')];
150
+ expect(sections.length).toBeGreaterThan(0);
151
+ const order = sections.map((section) => section.getAttribute('data-severity'));
152
+ expect(order).toEqual(['error', 'warning', 'info'].filter((sev) => order.includes(sev)));
153
+ for (const section of sections) {
154
+ expect(section.querySelector('.bd-issues-heading svg')).not.toBeNull();
155
+ expect(section.querySelector('.bd-issue-severity[role=img]')).not.toBeNull();
156
+ expect(section.querySelector('.bd-issue-owner')?.textContent).not.toBe('');
157
+ }
158
+ });
159
+ it('shows the publish counts as icon badges with a spoken text', async () => {
160
+ const { view } = setup(broken(), 'warn');
161
+ await view(true);
162
+ const badges = [...document.querySelectorAll('.bd-publish-badge')];
163
+ expect(badges.map((badge) => badge.getAttribute('data-severity'))).toEqual([
164
+ 'error',
165
+ 'warning',
166
+ 'info',
167
+ ]);
168
+ for (const badge of badges)
169
+ expect(badge.querySelector('svg')).not.toBeNull();
170
+ expect(badges[0]?.textContent).toMatch(/[0-9] errors/);
171
+ });
172
+ it('refuses to publish while errors exist under the block policy', async () => {
173
+ const { publish, view } = setup(broken(), 'block');
174
+ await view(true);
175
+ expect(document.body.textContent).toContain('Publishing is blocked');
176
+ expect(publishButton().disabled).toBe(true);
177
+ expect(publish).not.toHaveBeenCalled();
178
+ });
179
+ it('warns but publishes under the warn policy, after saving', async () => {
180
+ const { store, publish, view } = setup(broken(), 'warn');
181
+ await view(true);
182
+ expect(document.body.textContent).toContain('You can still publish');
183
+ expect(document.body.textContent).toContain('replaces the live page');
184
+ await act(async () => {
185
+ store.dispatch({
186
+ type: 'node.setAttr',
187
+ payload: { id: 'widget0001', key: 'name', value: 'A' },
188
+ });
189
+ });
190
+ await act(async () => publishButton().click());
191
+ expect(publish).toHaveBeenCalledWith(expect.anything(), { baseRevision: 2 });
192
+ expect(document.body.textContent).toContain('Published.');
193
+ });
194
+ it('refuses a damaged document under any policy', async () => {
195
+ const { publish, view } = setup(corrupt(), 'warn');
196
+ await view(true);
197
+ expect(document.body.textContent).toContain('damaged');
198
+ expect(publishButton().disabled).toBe(true);
199
+ expect(publish).not.toHaveBeenCalled();
200
+ });
201
+ it('publishes a clean document', async () => {
202
+ const { publish, view } = setup(clean(), 'block');
203
+ await view(true);
204
+ await act(async () => publishButton().click());
205
+ expect(publish).toHaveBeenCalledOnce();
206
+ expect(document.body.textContent).toContain('Published.');
207
+ });
208
+ it('shows why a publication failed', async () => {
209
+ const { view } = setup(clean(), 'block', { ok: false, kind: 'conflict', currentRevision: 9 });
210
+ await view(true);
211
+ await act(async () => publishButton().click());
212
+ expect(document.body.textContent).toContain('changed elsewhere');
213
+ });
214
+ });
215
+ describe('PersistenceController.publish', () => {
216
+ function controllerFor(save, publish) {
217
+ const store = createEditorStore({
218
+ doc: clean(),
219
+ registry,
220
+ generateId: createSeededIdGenerator(5),
221
+ validationDelayMs: null,
222
+ });
223
+ const controller = createPersistence({
224
+ store,
225
+ adapter: { save, publish },
226
+ ref: { collection: 'pages', id: '1' },
227
+ revision: 1,
228
+ });
229
+ controller.start();
230
+ act(() => {
231
+ store.dispatch({
232
+ type: 'node.setAttr',
233
+ payload: { id: 'widget0001', key: 'name', value: 'A' },
234
+ });
235
+ });
236
+ return controller;
237
+ }
238
+ it('does not publish what it could not save', async () => {
239
+ const publish = vi.fn();
240
+ const controller = controllerFor(async () => ({ ok: false, kind: 'invalid', diagnostics: [] }), publish);
241
+ expect(await controller.publish()).toEqual({ ok: false, kind: 'unsaved' });
242
+ expect(publish).not.toHaveBeenCalled();
243
+ });
244
+ it('turns a rejection into an outcome and keeps the revision on success', async () => {
245
+ const failing = controllerFor(async () => ({ ok: true, revision: 2, updatedAt: 't' }), async () => {
246
+ throw new Error('offline');
247
+ });
248
+ expect(await failing.publish()).toEqual({ ok: false, kind: 'network', message: 'offline' });
249
+ const working = controllerFor(async () => ({ ok: true, revision: 2, updatedAt: 't' }), async () => ({ ok: true, revision: 4, updatedAt: 'u' }));
250
+ expect(await working.publish()).toMatchObject({ ok: true, revision: 4 });
251
+ expect(working.state.getState().revision).toBe(4);
252
+ });
253
+ it('moves to the conflict state when the backend says so', async () => {
254
+ const controller = controllerFor(async () => ({ ok: true, revision: 2, updatedAt: 't' }), async () => ({ ok: false, kind: 'conflict', currentRevision: 8 }));
255
+ expect(await controller.publish()).toMatchObject({ ok: false, kind: 'conflict' });
256
+ expect(controller.state.getState()).toMatchObject({ status: 'conflict', conflictRevision: 8 });
257
+ });
258
+ });
@@ -0,0 +1,18 @@
1
+ import type { DocumentAdapter, DocumentRef } from '../persistence/index.ts';
2
+ /** The choice that leaves the canvas on the adapter's own default entry. */
3
+ export declare const DEFAULT_SAMPLE = "__default__";
4
+ export interface SamplePickerProps {
5
+ readonly adapter: Pick<DocumentAdapter, 'listSamples'>;
6
+ readonly docRef: DocumentRef;
7
+ /** Tells the canvas which entry to render with (`CanvasHost.setContextRef`). */
8
+ readonly onChange: (contextRef: string | null) => void;
9
+ /** Where the choice is remembered; `localStorage` unless a test or host gives another. */
10
+ readonly storage?: Pick<Storage, 'getItem' | 'setItem'> | undefined;
11
+ }
12
+ /**
13
+ * Chooses which entry a template is shown with (docs/editor.md#sample-data): the samples the adapter
14
+ * lists, the choice sent to the canvas as its context and remembered per document. Renders nothing
15
+ * when the adapter lists no samples (a page, not a template).
16
+ */
17
+ export declare function SamplePicker({ adapter, docRef, onChange, storage }: SamplePickerProps): import("react").JSX.Element | null;
18
+ //# sourceMappingURL=sample-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-picker.d.ts","sourceRoot":"","sources":["../../src/toolbar/sample-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG5E,4EAA4E;AAC5E,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,0FAA0F;IAC1F,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACrE;AAmBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,iBAAiB,sCAiDrF"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { useT } from '../messages/index.js';
4
+ import { Select } from '../ui/index.js';
5
+ /** The choice that leaves the canvas on the adapter's own default entry. */
6
+ export const DEFAULT_SAMPLE = '__default__';
7
+ const keyOf = (ref) => `buildr:sample:${ref.collection}:${ref.id}`;
8
+ const read = (storage, key) => {
9
+ try {
10
+ return (storage ?? globalThis.localStorage).getItem(key);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ };
16
+ const write = (storage, key, value) => {
17
+ try {
18
+ (storage ?? globalThis.localStorage).setItem(key, value);
19
+ }
20
+ catch {
21
+ // Private windows and blocked storage: the choice just is not remembered.
22
+ }
23
+ };
24
+ /**
25
+ * Chooses which entry a template is shown with (docs/editor.md#sample-data): the samples the adapter
26
+ * lists, the choice sent to the canvas as its context and remembered per document. Renders nothing
27
+ * when the adapter lists no samples (a page, not a template).
28
+ */
29
+ export function SamplePicker({ adapter, docRef, onChange, storage }) {
30
+ const t = useT();
31
+ const [samples, setSamples] = useState([]);
32
+ const [value, setValue] = useState(DEFAULT_SAMPLE);
33
+ const collection = docRef.collection;
34
+ const id = docRef.id;
35
+ // `onChange` is deliberately not a dependency: the host passes a fresh closure every render.
36
+ // biome-ignore lint/correctness/useExhaustiveDependencies: see above
37
+ useEffect(() => {
38
+ let cancelled = false;
39
+ const ref = { collection, id };
40
+ void (async () => {
41
+ let list = [];
42
+ try {
43
+ list = (await adapter.listSamples?.(ref)) ?? [];
44
+ }
45
+ catch {
46
+ list = [];
47
+ }
48
+ if (cancelled)
49
+ return;
50
+ setSamples(list);
51
+ const saved = read(storage, keyOf(ref));
52
+ // A remembered entry that no longer exists is forgotten, not sent to the canvas.
53
+ if (saved !== null && list.some((sample) => sample.id === saved)) {
54
+ setValue(saved);
55
+ onChange(saved);
56
+ }
57
+ })();
58
+ return () => {
59
+ cancelled = true;
60
+ };
61
+ }, [adapter, collection, id, storage]);
62
+ if (samples.length === 0)
63
+ return null;
64
+ return (_jsx(Select, { label: t('sample.label'), value: value, onValueChange: (next) => {
65
+ setValue(next);
66
+ write(storage, keyOf({ collection, id }), next);
67
+ onChange(next === DEFAULT_SAMPLE ? null : next);
68
+ }, options: [
69
+ { value: DEFAULT_SAMPLE, label: t('sample.default') },
70
+ ...samples.map((sample) => ({ value: sample.id, label: sample.label })),
71
+ ] }));
72
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sample-picker.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-picker.test.d.ts","sourceRoot":"","sources":["../../src/toolbar/sample-picker.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment jsdom
3
+ import { act } from 'react';
4
+ import { createRoot } from 'react-dom/client';
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
+ import { MessagesProvider } from '../messages/index.js';
7
+ import { SamplePicker } from './sample-picker.js';
8
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
9
+ const ref = { collection: 'templates', id: '1' };
10
+ const samples = [
11
+ { id: 'p1', label: 'First post' },
12
+ { id: 'p2', label: 'Second post' },
13
+ ];
14
+ describe('SamplePicker', () => {
15
+ let container;
16
+ let root;
17
+ beforeEach(() => {
18
+ container = document.createElement('div');
19
+ document.body.append(container);
20
+ root = createRoot(container);
21
+ Element.prototype.scrollIntoView ??= () => { };
22
+ Element.prototype.hasPointerCapture ??= () => false;
23
+ Element.prototype.setPointerCapture ??= () => { };
24
+ Element.prototype.releasePointerCapture ??= () => { };
25
+ });
26
+ afterEach(() => {
27
+ act(() => root.unmount());
28
+ document.body.innerHTML = '';
29
+ });
30
+ const store = (initial = {}) => {
31
+ const data = { ...initial };
32
+ return {
33
+ data,
34
+ getItem: (key) => data[key] ?? null,
35
+ setItem: (key, value) => {
36
+ data[key] = value;
37
+ },
38
+ };
39
+ };
40
+ const mount = async (listSamples, onChange, storage = store()) => {
41
+ await act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(SamplePicker, { adapter: { listSamples }, docRef: ref, onChange: onChange, storage: storage }) })));
42
+ };
43
+ it('renders nothing when there are no samples', async () => {
44
+ await mount(undefined, () => undefined);
45
+ expect(container.innerHTML).toBe('');
46
+ await mount(async () => [], () => undefined);
47
+ expect(container.innerHTML).toBe('');
48
+ });
49
+ it('sends the remembered entry to the canvas', async () => {
50
+ const onChange = vi.fn();
51
+ await mount(async () => samples, onChange, store({ 'buildr:sample:templates:1': 'p2' }));
52
+ expect(onChange).toHaveBeenCalledWith('p2');
53
+ expect(container.textContent).toContain('Second post');
54
+ });
55
+ it('forgets a remembered entry that is gone, and survives broken storage', async () => {
56
+ const onChange = vi.fn();
57
+ await mount(async () => samples, onChange, store({ 'buildr:sample:templates:1': 'gone' }));
58
+ expect(onChange).not.toHaveBeenCalled();
59
+ const blocked = () => {
60
+ throw new Error('blocked');
61
+ };
62
+ await mount(async () => samples, onChange, { getItem: blocked, setItem: blocked });
63
+ expect(container.textContent).toContain('Default entry');
64
+ });
65
+ it('switching the entry tells the canvas and remembers it', async () => {
66
+ const onChange = vi.fn();
67
+ const storage = store();
68
+ await mount(async () => samples, onChange, storage);
69
+ await act(async () => container.querySelector('button[role=combobox]').click());
70
+ const option = [...document.querySelectorAll('[role=option]')].find((o) => o.textContent?.includes('First post'));
71
+ await act(async () => {
72
+ option.dispatchEvent(new PointerEvent('pointerup', { bubbles: true }));
73
+ option.click();
74
+ });
75
+ expect(onChange).toHaveBeenLastCalledWith('p1');
76
+ expect(storage.data['buildr:sample:templates:1']).toBe('p1');
77
+ });
78
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The save status as an icon and a short text (the same messages as `SaveStatus`). When the row is
3
+ * tight the text is visually hidden; it stays the status region's content.
4
+ */
5
+ export declare function SaveIndicator({ compact }: {
6
+ readonly compact?: boolean;
7
+ }): import("react").JSX.Element;
8
+ //# sourceMappingURL=save-indicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-indicator.d.ts","sourceRoot":"","sources":["../../src/toolbar/save-indicator.tsx"],"names":[],"mappings":"AAaA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,OAAe,EAAE,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,+BA6BhF"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useT } from '../messages/index.js';
3
+ import { usePersistence, usePersistenceState } from '../persistence/index.js';
4
+ import { useEditorState } from '../store/index.js';
5
+ import { Button, Icon } from '../ui/index.js';
6
+ const STATUS_ICONS = {
7
+ clean: 'check',
8
+ dirty: 'circle',
9
+ saving: 'loader-circle',
10
+ error: 'triangle-alert',
11
+ conflict: 'triangle-alert',
12
+ };
13
+ /**
14
+ * The save status as an icon and a short text (the same messages as `SaveStatus`). When the row is
15
+ * tight the text is visually hidden; it stays the status region's content.
16
+ */
17
+ export function SaveIndicator({ compact = false }) {
18
+ const t = useT();
19
+ const controller = usePersistence();
20
+ const status = usePersistenceState((state) => state.status);
21
+ const error = usePersistenceState((state) => state.error);
22
+ const readOnly = useEditorState((state) => state.readOnly);
23
+ const text = readOnly
24
+ ? t('save.readOnly')
25
+ : status === 'error' && error?.kind === 'invalid'
26
+ ? t('save.invalid')
27
+ : t(`save.${status}`);
28
+ const icon = readOnly ? 'lock' : (STATUS_ICONS[status] ?? 'circle');
29
+ return (_jsxs("span", { className: "bd-save-status", "data-status": readOnly ? 'readOnly' : status, "data-compact": compact, role: "status", title: text, children: [_jsx(Icon, { name: icon }), _jsx("span", { className: compact ? 'bd-visually-hidden' : undefined, children: text }), !readOnly && (status === 'dirty' || status === 'error') && (_jsx(Button, { variant: "ghost", onClick: () => void controller.saveNow(), children: t('save.now') }))] }));
30
+ }
@@ -0,0 +1,22 @@
1
+ export type ThemePreference = 'light' | 'dark' | 'system';
2
+ /** Where the author's choice is remembered (per browser, not per document). */
3
+ export declare const THEME_STORAGE_KEY = "buildr:theme";
4
+ export interface ThemeState {
5
+ /** What the switch shows: the author's choice, `system` until they make one. */
6
+ readonly preference: ThemePreference;
7
+ /** The value for the root's `data-theme`: `system` leaves the attribute off. */
8
+ readonly attribute: ThemePreference;
9
+ /** The host fixed the theme (`config.theme`); the switch is hidden and the host's value wins. */
10
+ readonly forced: boolean;
11
+ readonly setPreference: (next: ThemePreference) => void;
12
+ }
13
+ /**
14
+ * The editor's theme (docs/editor.md#toolbar-pb-083): the host's `config.theme` wins when it is
15
+ * `light` or `dark`; otherwise the author's remembered choice applies, and follows the system
16
+ * until they make one.
17
+ */
18
+ export declare function useThemePreference(hostTheme: ThemePreference): ThemeState;
19
+ export declare const ThemeProvider: import("react").Provider<ThemeState | undefined>;
20
+ /** The theme state of the enclosing editor; `undefined` outside one (the switch is then left out). */
21
+ export declare function useTheme(): ThemeState | undefined;
22
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/toolbar/theme.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;CACzD;AAsBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,UAAU,CAgBzE;AAID,eAAO,MAAM,aAAa,kDAAwB,CAAC;AAEnD,sGAAsG;AACtG,wBAAgB,QAAQ,IAAI,UAAU,GAAG,SAAS,CAEjD"}
@@ -0,0 +1,46 @@
1
+ import { createContext, useCallback, useContext, useMemo, useState } from 'react';
2
+ /** Where the author's choice is remembered (per browser, not per document). */
3
+ export const THEME_STORAGE_KEY = 'buildr:theme';
4
+ const isPreference = (value) => value === 'light' || value === 'dark' || value === 'system';
5
+ const read = () => {
6
+ try {
7
+ const saved = globalThis.localStorage.getItem(THEME_STORAGE_KEY);
8
+ return isPreference(saved) ? saved : 'system';
9
+ }
10
+ catch {
11
+ return 'system';
12
+ }
13
+ };
14
+ const write = (value) => {
15
+ try {
16
+ globalThis.localStorage.setItem(THEME_STORAGE_KEY, value);
17
+ }
18
+ catch {
19
+ // Private windows and blocked storage: the choice just is not remembered.
20
+ }
21
+ };
22
+ /**
23
+ * The editor's theme (docs/editor.md#toolbar-pb-083): the host's `config.theme` wins when it is
24
+ * `light` or `dark`; otherwise the author's remembered choice applies, and follows the system
25
+ * until they make one.
26
+ */
27
+ export function useThemePreference(hostTheme) {
28
+ const forced = hostTheme !== 'system';
29
+ const [stored, setStored] = useState(read);
30
+ const setPreference = useCallback((next) => {
31
+ setStored(next);
32
+ write(next);
33
+ }, []);
34
+ return useMemo(() => ({
35
+ preference: forced ? hostTheme : stored,
36
+ attribute: forced ? hostTheme : stored,
37
+ forced,
38
+ setPreference,
39
+ }), [forced, hostTheme, stored, setPreference]);
40
+ }
41
+ const ThemeContext = createContext(undefined);
42
+ export const ThemeProvider = ThemeContext.Provider;
43
+ /** The theme state of the enclosing editor; `undefined` outside one (the switch is then left out). */
44
+ export function useTheme() {
45
+ return useContext(ThemeContext);
46
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=theme.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.test.d.ts","sourceRoot":"","sources":["../../src/toolbar/theme.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment jsdom
3
+ import { act } from 'react';
4
+ import { createRoot } from 'react-dom/client';
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
+ import { THEME_STORAGE_KEY, useThemePreference } from './theme.js';
7
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
8
+ describe('useThemePreference', () => {
9
+ let state;
10
+ const Probe = ({ host }) => {
11
+ state = useThemePreference(host);
12
+ return null;
13
+ };
14
+ const mount = async (host) => {
15
+ const root = createRoot(document.createElement('div'));
16
+ await act(async () => root.render(_jsx(Probe, { host: host })));
17
+ return root;
18
+ };
19
+ beforeEach(() => localStorage.clear());
20
+ afterEach(() => vi.restoreAllMocks());
21
+ it('follows the system until the author chooses, then remembers the choice', async () => {
22
+ const root = await mount('system');
23
+ expect(state).toMatchObject({ preference: 'system', attribute: 'system', forced: false });
24
+ await act(async () => state.setPreference('dark'));
25
+ expect(state.attribute).toBe('dark');
26
+ expect(localStorage.getItem(THEME_STORAGE_KEY)).toBe('dark');
27
+ await act(async () => root.unmount());
28
+ const again = await mount('system');
29
+ expect(state.preference).toBe('dark');
30
+ await act(async () => again.unmount());
31
+ });
32
+ it('lets an explicit host theme win over the remembered choice', async () => {
33
+ localStorage.setItem(THEME_STORAGE_KEY, 'dark');
34
+ const root = await mount('light');
35
+ expect(state).toMatchObject({ attribute: 'light', forced: true });
36
+ await act(async () => root.unmount());
37
+ });
38
+ it('ignores an unknown stored value and survives blocked storage', async () => {
39
+ localStorage.setItem(THEME_STORAGE_KEY, 'purple');
40
+ const root = await mount('system');
41
+ expect(state.preference).toBe('system');
42
+ vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => {
43
+ throw new Error('blocked');
44
+ });
45
+ await act(async () => state.setPreference('light'));
46
+ expect(state.attribute).toBe('light');
47
+ await act(async () => root.unmount());
48
+ });
49
+ });
@@ -0,0 +1,13 @@
1
+ import type { BreakpointConfig } from '../app/config.ts';
2
+ import { type Zoom } from './zoom-menu.tsx';
3
+ export interface ToolbarCentreProps {
4
+ readonly breakpoints: readonly BreakpointConfig[];
5
+ readonly breakpoint: string;
6
+ readonly onBreakpointChange: (id: string) => void;
7
+ /** The canvas zoom and how to change it (`host.setZoom`); the zoom menu is left out without a handler. */
8
+ readonly zoom?: Zoom | undefined;
9
+ readonly onZoomChange?: ((zoom: Zoom) => void) | undefined;
10
+ }
11
+ /** The screen-size control and the zoom menu. */
12
+ export declare function ToolbarCentre(props: ToolbarCentreProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=toolbar-centre.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbar-centre.d.ts","sourceRoot":"","sources":["../../src/toolbar/toolbar-centre.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,0GAA0G;IAC1G,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC5D;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,+BAatD"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BreakpointControl } from './breakpoint-control.js';
3
+ import { ZoomMenu } from './zoom-menu.js';
4
+ /** The screen-size control and the zoom menu. */
5
+ export function ToolbarCentre(props) {
6
+ return (_jsxs("div", { className: "bd-toolbar-zone", "data-zone": "centre", children: [_jsx(BreakpointControl, { breakpoints: props.breakpoints, breakpoint: props.breakpoint, onChange: props.onBreakpointChange }), props.onZoomChange !== undefined && (_jsx(ZoomMenu, { zoom: props.zoom ?? 'fit', onChange: props.onZoomChange }))] }));
7
+ }
@@ -0,0 +1,12 @@
1
+ export interface ToolbarLeftProps {
2
+ readonly title: string;
3
+ /** Saves a new page name; without it (the backend cannot rename) the title is plain text. */
4
+ readonly onRename?: ((title: string) => Promise<void>) | undefined;
5
+ /** Draft or published; the pill is left out without it. */
6
+ readonly status?: 'draft' | 'published' | undefined;
7
+ /** The page in the CMS's admin; the link is left out without it, or when it moved to the more menu. */
8
+ readonly cmsUrl?: string | undefined;
9
+ }
10
+ /** The product mark, back to the CMS as an icon button, the page name and its draft or published pill. */
11
+ export declare function ToolbarLeft({ title, onRename, status, cmsUrl }: ToolbarLeftProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=toolbar-left.d.ts.map