@jxsuite/studio 6.1.2 → 8.0.1

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 (522) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  4. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  5. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  6. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  7. package/dist/chunks/{color-area-0fj8a4ga.js → color-area-6rbra5dy.js} +2 -2
  8. package/dist/chunks/{color-field-xch8kx2g.js → color-field-gy56c94g.js} +3 -3
  9. package/dist/chunks/color-m7r1vk54.js +4 -0
  10. package/dist/chunks/{color-slider-jxd8v350.js → color-slider-sqqdyf6c.js} +2 -2
  11. package/dist/chunks/{combobox-p0efwjke.js → combobox-72h32ejk.js} +3 -3
  12. package/dist/chunks/components-r22xca09.js +4 -0
  13. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  14. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  15. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  16. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  17. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  18. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  19. package/dist/chunks/files-rcn56qvm.js +4 -0
  20. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  21. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  22. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  23. package/dist/chunks/{grid-view-d2wq9ezg.js → grid-view-qg1b5eqx.js} +25 -25
  24. package/dist/chunks/{icons-pnfz478q.js → icons-63bjtbs7.js} +2 -2
  25. package/dist/chunks/{iframe-entry-jdcktez8.js → iframe-entry-2zggzajv.js} +4 -4
  26. package/dist/chunks/{iframe-entry-zap785cw.js → iframe-entry-76j8vwwx.js} +4 -4
  27. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  28. package/dist/chunks/{iframe-entry-x0ygf2yr.js → iframe-entry-pkgmcgp0.js} +4 -4
  29. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  30. package/dist/chunks/{index-zpjmzqfk.js → index-32eqzv1k.js} +3 -3
  31. package/dist/chunks/index-f0jn7nnp.js +4 -0
  32. package/dist/chunks/{javascript-m54mnwp6.js → javascript-pjp734q4.js} +3 -3
  33. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  34. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  35. package/dist/chunks/layers-bgyr11tr.js +4 -0
  36. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  37. package/dist/chunks/{listbox-e74qjyq6.js → listbox-c421cf8c.js} +2 -2
  38. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  39. package/dist/chunks/media-library-sq468wts.js +4 -0
  40. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  41. package/dist/chunks/{menu-n6yzswmy.js → menu-bdpzbfvs.js} +2 -2
  42. package/dist/chunks/{monaco-binding-7gx83x3r.js → monaco-binding-vq1hgnn0.js} +3 -3
  43. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  44. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  45. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  46. package/dist/chunks/parse-v77xtwv7.js +4 -0
  47. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  48. package/dist/chunks/popover-b89sfej7.js +4 -0
  49. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  50. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  51. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  52. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  53. package/dist/chunks/references-9547rg5s.js +4 -0
  54. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  55. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  56. package/dist/chunks/{split-n2gfpm5m.js → split-c9zfdgxf.js} +2 -2
  57. package/dist/chunks/studio-03ct6yfv.js +9 -0
  58. package/dist/chunks/studio-07rcfje3.js +5 -0
  59. package/dist/chunks/studio-3e54qh39.js +7 -0
  60. package/dist/chunks/studio-3exxhz5g.js +5 -0
  61. package/dist/chunks/studio-3q40e3rj.js +5 -0
  62. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  63. package/dist/chunks/studio-3qqjeep5.js +6 -0
  64. package/dist/chunks/studio-43sd2mam.js +4 -0
  65. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  66. package/dist/chunks/studio-58xg6j2q.js +9 -0
  67. package/dist/chunks/studio-5g0rprdt.js +7 -0
  68. package/dist/chunks/{studio-2j1cb95x.js → studio-6m380wp7.js} +4 -4
  69. package/dist/chunks/studio-80jyh1xh.js +4 -0
  70. package/dist/chunks/studio-83mk4bgg.js +9 -0
  71. package/dist/chunks/{studio-v0jzqdjm.js → studio-881z1xrx.js} +4 -4
  72. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  73. package/dist/chunks/{studio-d81xfh1g.js → studio-8tr6cfrc.js} +4 -4
  74. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  75. package/dist/chunks/studio-9tmebf0s.js +5 -0
  76. package/dist/chunks/studio-a2bvaptz.js +5 -0
  77. package/dist/chunks/studio-b7y5mr30.js +5 -0
  78. package/dist/chunks/studio-bavb31r0.js +5 -0
  79. package/dist/chunks/{studio-dgz8d0c1.js → studio-bbe4c90a.js} +4 -4
  80. package/dist/chunks/studio-c05wdnt3.js +5 -0
  81. package/dist/chunks/studio-ccv2svc6.js +5 -0
  82. package/dist/chunks/studio-d5grtb9e.js +16 -0
  83. package/dist/chunks/studio-df0baea9.js +5 -0
  84. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  85. package/dist/chunks/studio-e1g64q43.js +5 -0
  86. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  87. package/dist/chunks/studio-ed3xx40h.js +7 -0
  88. package/dist/chunks/studio-f14e1zdj.js +5 -0
  89. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  90. package/dist/chunks/studio-fyh0jc96.js +5 -0
  91. package/dist/chunks/studio-gcxk20n7.js +5 -0
  92. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  93. package/dist/chunks/{studio-90pq9km1.js → studio-jcnsdaep.js} +4 -4
  94. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  95. package/dist/chunks/{studio-0q988f9w.js → studio-k3xxbagr.js} +3 -3
  96. package/dist/chunks/{studio-5ve6bbep.js → studio-k7evxqh4.js} +4 -4
  97. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  98. package/dist/chunks/studio-m8g16bgz.js +5 -0
  99. package/dist/chunks/studio-mn0476ag.js +5 -0
  100. package/dist/chunks/studio-mx1smyq0.js +5 -0
  101. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  102. package/dist/chunks/{studio-485046te.js → studio-nh6d342n.js} +7 -7
  103. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  104. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  105. package/dist/chunks/{studio-1fxkaaea.js → studio-pbxa5fpc.js} +4 -4
  106. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  107. package/dist/chunks/studio-ph84avkf.js +5 -0
  108. package/dist/chunks/{studio-tq0rtfwj.js → studio-q0mvbaq6.js} +4 -4
  109. package/dist/chunks/studio-q0tccd43.js +5 -0
  110. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  111. package/dist/chunks/{studio-a3g98wjr.js → studio-qgh13jtz.js} +4 -4
  112. package/dist/chunks/studio-qmn1xc24.js +5 -0
  113. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  114. package/dist/chunks/studio-r5qy30vx.js +5 -0
  115. package/dist/chunks/studio-rj9eamf8.js +5 -0
  116. package/dist/chunks/studio-rptgsk96.js +5 -0
  117. package/dist/chunks/studio-rthyg42z.js +928 -0
  118. package/dist/chunks/studio-s19tp1xr.js +5 -0
  119. package/dist/chunks/studio-s32578pn.js +5 -0
  120. package/dist/chunks/studio-svb7yyve.js +5 -0
  121. package/dist/chunks/studio-syreb644.js +5 -0
  122. package/dist/chunks/studio-tf9jryb1.js +10 -0
  123. package/dist/chunks/studio-tfkznv39.js +5 -0
  124. package/dist/chunks/studio-tft6r105.js +5 -0
  125. package/dist/chunks/studio-txf2kysx.js +5 -0
  126. package/dist/chunks/studio-v8867ddv.js +12 -0
  127. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  128. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  129. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  130. package/dist/chunks/studio-wc649wss.js +5 -0
  131. package/dist/chunks/studio-wys23mxz.js +5 -0
  132. package/dist/chunks/studio-x1x167jh.js +5 -0
  133. package/dist/chunks/studio-x9hsze61.js +5 -0
  134. package/dist/chunks/studio-y0n7yxea.js +9 -0
  135. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  136. package/dist/chunks/studio-z97c48fk.js +5 -0
  137. package/dist/chunks/studio-zat62m0c.js +5 -0
  138. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  139. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  140. package/dist/chunks/toast-1gv0h53h.js +4 -0
  141. package/dist/chunks/{toast-host-ke5z4ng7.js → toast-host-1yg5ar8d.js} +3 -3
  142. package/dist/chunks/{tooltip-5v8ngwj2.js → tooltip-yypz28gq.js} +3 -3
  143. package/dist/chunks/{tree-mdq3v5cw.js → tree-9xa4hm7n.js} +2 -2
  144. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  145. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  146. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  147. package/dist/chunks/{ws-client-nze0k6mv.js → ws-client-bv552sfx.js} +3 -3
  148. package/dist/iframe-entry.js +20 -16
  149. package/dist/manifest.json +77 -63
  150. package/dist/studio.js +103 -104
  151. package/dist/workers/ts.worker.js +3 -3
  152. package/package.json +12 -11
  153. package/src/browse/component-examples.ts +272 -0
  154. package/src/browse/library-commands.ts +64 -104
  155. package/src/browse/library-layouts.ts +263 -49
  156. package/src/browse/library-model.ts +181 -133
  157. package/src/browse/library-pane.ts +738 -446
  158. package/src/browse/library-preview.ts +149 -19
  159. package/src/browse/library-source.ts +308 -41
  160. package/src/browse/preview-root.ts +78 -0
  161. package/src/browse/preview-style.ts +155 -0
  162. package/src/canvas/asset-refs.ts +16 -1
  163. package/src/canvas/canvas-live-render.ts +222 -30
  164. package/src/canvas/canvas-origin.ts +37 -12
  165. package/src/canvas/canvas-page-context.ts +112 -0
  166. package/src/canvas/canvas-render.ts +113 -107
  167. package/src/canvas/canvas-utils.ts +57 -12
  168. package/src/canvas/iframe-drop.ts +107 -0
  169. package/src/canvas/iframe-entry.ts +24 -12
  170. package/src/canvas/iframe-host.ts +134 -62
  171. package/src/canvas/iframe-keys.ts +11 -0
  172. package/src/canvas/iframe-patch.ts +8 -7
  173. package/src/canvas/iframe-protocol.ts +24 -5
  174. package/src/canvas/iframe-render.ts +48 -1
  175. package/src/canvas/iframe-subtree.ts +5 -2
  176. package/src/canvas/npm-modules.ts +22 -0
  177. package/src/canvas/preview-navigate.ts +16 -0
  178. package/src/canvas/repeater-sources.ts +200 -0
  179. package/src/canvas/stage-scrollbar.ts +5 -1
  180. package/src/canvas/surface-registry.ts +6 -0
  181. package/src/commands/app-commands.ts +16 -6
  182. package/src/commands/budget.ts +10 -8
  183. package/src/commands/context.ts +35 -10
  184. package/src/commands/defaults.ts +69 -45
  185. package/src/commands/keymap.ts +9 -0
  186. package/src/commands/levels.ts +11 -5
  187. package/src/commands/live-context.ts +2 -0
  188. package/src/commands/registry.ts +10 -1
  189. package/src/content/collection-match.ts +6 -5
  190. package/src/content/collection-pages.ts +412 -0
  191. package/src/content/content-collections.ts +270 -0
  192. package/src/content/entry-commands.ts +51 -60
  193. package/src/content/entry-editor.ts +111 -18
  194. package/src/content/entry-fields.ts +13 -1
  195. package/src/content/entry-inspector.ts +225 -0
  196. package/src/content/entry-model.ts +17 -3
  197. package/src/content/entry-open.ts +80 -0
  198. package/src/content/entry-summaries.ts +440 -0
  199. package/src/content/file-record-ids.ts +80 -0
  200. package/src/content/file-records.ts +125 -0
  201. package/src/content/page-summaries.ts +129 -0
  202. package/src/content/record-entry.ts +201 -0
  203. package/src/content/writing-banner.ts +177 -0
  204. package/src/create/add-new-commands.ts +185 -0
  205. package/src/create/add-new-flow.ts +1116 -0
  206. package/src/create/add-new.ts +1014 -0
  207. package/src/create/element-name.ts +121 -0
  208. package/src/editor/convert-to-component.ts +67 -43
  209. package/src/editor/file-drop-action.ts +9 -1
  210. package/src/editor/inline-edit-apply.ts +44 -0
  211. package/src/editor/inline-edit.ts +10 -0
  212. package/src/editor/insert-component.ts +91 -0
  213. package/src/editor/insert-zone-action.ts +13 -4
  214. package/src/editor/shortcuts.ts +44 -22
  215. package/src/editor/slash-menu.ts +51 -8
  216. package/src/files/components.ts +74 -10
  217. package/src/files/file-ops.ts +15 -5
  218. package/src/files/files.ts +164 -150
  219. package/src/files/fs-events.ts +18 -7
  220. package/src/files/media-meta.ts +95 -1
  221. package/src/files/media-types.ts +55 -0
  222. package/src/files/media-upload.ts +209 -52
  223. package/src/files/new-file-name.ts +156 -0
  224. package/src/files/serialize-document.ts +13 -3
  225. package/src/format/format-host.ts +15 -0
  226. package/src/github/github-auth.ts +2 -2
  227. package/src/github/github-publish.ts +4 -3
  228. package/src/grid/grid-controller.ts +5 -1
  229. package/src/grid/grid-open.ts +0 -27
  230. package/src/grid/grid-panel.ts +54 -2
  231. package/src/grid/grid-reveal.ts +34 -0
  232. package/src/grid/grid-source.ts +3 -25
  233. package/src/grid/grid-view.ts +31 -6
  234. package/src/grid/sources/content-source.ts +75 -7
  235. package/src/grid/tabulator-tables.d.ts +6 -0
  236. package/src/hosting/document.ts +2 -2
  237. package/src/i18n/i18n-commands.ts +2 -1
  238. package/src/media/media-commands.ts +181 -0
  239. package/src/media/media-library-model.ts +232 -0
  240. package/src/media/media-library.ts +1283 -0
  241. package/src/media/media-pane.ts +47 -19
  242. package/src/packages/pull-package-sync.ts +1 -1
  243. package/src/panels/activity-panel.ts +21 -5
  244. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  245. package/src/panels/block-action-bar.ts +11 -11
  246. package/src/panels/canvas-dnd-bridge.ts +5 -2
  247. package/src/panels/chat-panel.ts +6 -6
  248. package/src/panels/collections-panel.ts +306 -0
  249. package/src/panels/component-preview.ts +35 -13
  250. package/src/panels/data-explorer.ts +1 -1
  251. package/src/panels/data-grid.ts +4 -0
  252. package/src/panels/dnd.ts +17 -30
  253. package/src/panels/elements-panel.ts +9 -2
  254. package/src/panels/empty-state.ts +2 -2
  255. package/src/panels/formula-workspace.ts +2 -3
  256. package/src/panels/frontmatter-fields.ts +9 -9
  257. package/src/panels/git-diff-open.ts +9 -5
  258. package/src/panels/head-panel.ts +369 -103
  259. package/src/panels/i18n-panel.ts +11 -10
  260. package/src/panels/imports-panel.ts +2 -0
  261. package/src/panels/jump-bar.ts +27 -2
  262. package/src/panels/layers-panel.ts +36 -30
  263. package/src/panels/left-panel.ts +22 -8
  264. package/src/panels/navigator-panels.ts +23 -11
  265. package/src/panels/pane-context.ts +111 -29
  266. package/src/panels/pane-grid.ts +6 -6
  267. package/src/panels/panel-registry.ts +14 -9
  268. package/src/panels/properties-panel.ts +7 -3
  269. package/src/panels/right-panel.ts +199 -43
  270. package/src/panels/seo-modal.ts +41 -108
  271. package/src/panels/settings-menu.ts +52 -50
  272. package/src/panels/settings-pane.ts +268 -162
  273. package/src/panels/signals-panel.ts +3 -4
  274. package/src/panels/site-model.ts +367 -0
  275. package/src/panels/site-panel.ts +638 -0
  276. package/src/panels/style-panel.ts +37 -3
  277. package/src/panels/stylebook-doc.ts +142 -10
  278. package/src/panels/stylebook-layers-panel.ts +39 -80
  279. package/src/panels/stylebook-panel.ts +47 -10
  280. package/src/panels/styles-panel.ts +327 -0
  281. package/src/panels/tab-strip.ts +109 -25
  282. package/src/platform.ts +1 -1
  283. package/src/platforms/cloud.ts +28 -1
  284. package/src/platforms/default-platform.ts +4 -4
  285. package/src/platforms/devserver.ts +51 -25
  286. package/src/publish/deploy-checklist.ts +12 -7
  287. package/src/publish/pages-service.ts +38 -14
  288. package/src/publish/publish-changes.ts +491 -0
  289. package/src/publish/publish-commands.ts +83 -18
  290. package/src/publish/publish-ids.ts +49 -0
  291. package/src/publish/publish-quick.ts +148 -0
  292. package/src/publish/publish-workspace.ts +926 -0
  293. package/src/publish/source-control.ts +907 -0
  294. package/src/services/automation.ts +16 -20
  295. package/src/services/cf-settings.ts +4 -4
  296. package/src/services/connection.ts +2 -2
  297. package/src/services/directory-picker.ts +2 -2
  298. package/src/services/references.ts +0 -0
  299. package/src/services/render-critic.ts +21 -2
  300. package/src/services/settings/definitions.ts +25 -14
  301. package/src/settings/contributed-section.ts +49 -10
  302. package/src/settings/css-vars-editor.ts +93 -27
  303. package/src/settings/developer-panels.ts +43 -0
  304. package/src/settings/extension-sections.ts +20 -2
  305. package/src/settings/general-settings.ts +91 -21
  306. package/src/settings/preferences-dialog.ts +8 -1
  307. package/src/settings/project-sections.ts +27 -10
  308. package/src/settings/schema-field-ui.ts +3 -1
  309. package/src/settings/section-registry.ts +116 -11
  310. package/src/settings/settings-dialog.ts +192 -0
  311. package/src/settings/settings-document.ts +182 -162
  312. package/src/shell.ts +467 -431
  313. package/src/site-context.ts +64 -10
  314. package/src/state.ts +28 -9
  315. package/src/studio.ts +194 -41
  316. package/src/style/project-styles.ts +34 -0
  317. package/src/style/stylebook-specimens.ts +89 -0
  318. package/src/style/stylebook-target.ts +26 -0
  319. package/src/style/tag-inheritance.ts +105 -0
  320. package/src/style/variables-focus.ts +61 -0
  321. package/src/style/variables-view.ts +235 -0
  322. package/src/surfaces/add-new.json +1482 -0
  323. package/src/surfaces/add-new.ts +325 -0
  324. package/src/surfaces/ai-chat.ts +2 -2
  325. package/src/surfaces/boot-failure.json +4 -3
  326. package/src/surfaces/bottom-dock.json +1 -1
  327. package/src/surfaces/canvas-stage.json +30 -19
  328. package/src/surfaces/canvas-stage.ts +5 -5
  329. package/src/surfaces/collections-panel.json +615 -0
  330. package/src/surfaces/collections-panel.ts +168 -0
  331. package/src/surfaces/commandbar.json +241 -96
  332. package/src/surfaces/commandbar.ts +134 -99
  333. package/src/surfaces/empty-state.json +1 -1
  334. package/src/surfaces/entry-editor.json +136 -0
  335. package/src/surfaces/entry-editor.ts +21 -0
  336. package/src/surfaces/entry-inspector.json +371 -0
  337. package/src/surfaces/entry-inspector.ts +143 -0
  338. package/src/surfaces/inspector-dock.json +162 -14
  339. package/src/surfaces/inspector-dock.ts +46 -19
  340. package/src/surfaces/library-pane.json +670 -437
  341. package/src/surfaces/library-pane.ts +94 -59
  342. package/src/surfaces/media-browser.json +62 -6
  343. package/src/surfaces/media-browser.ts +15 -1
  344. package/src/surfaces/media-field.json +1 -1
  345. package/src/surfaces/media-library.json +1586 -0
  346. package/src/surfaces/media-library.ts +282 -0
  347. package/src/surfaces/media-pick-dialog.json +71 -0
  348. package/src/surfaces/media-pick-dialog.ts +132 -0
  349. package/src/surfaces/menu.ts +18 -0
  350. package/src/surfaces/pane-context.json +144 -77
  351. package/src/surfaces/pane-context.ts +24 -0
  352. package/src/surfaces/panel-deploy-checklist.json +12 -6
  353. package/src/surfaces/panel-deploy-checklist.ts +3 -1
  354. package/src/surfaces/panel-page.json +72 -2
  355. package/src/surfaces/panel-page.ts +38 -7
  356. package/src/surfaces/panel-signals.json +1 -1
  357. package/src/surfaces/panel-signals.ts +5 -5
  358. package/src/surfaces/panel-stylebook-layers.json +71 -204
  359. package/src/surfaces/panel-stylebook-layers.ts +0 -21
  360. package/src/surfaces/preferences.json +120 -48
  361. package/src/surfaces/preferences.ts +8 -0
  362. package/src/surfaces/publish-quick.json +428 -0
  363. package/src/surfaces/publish-quick.ts +165 -0
  364. package/src/surfaces/publish-workspace.json +2892 -0
  365. package/src/surfaces/publish-workspace.ts +391 -0
  366. package/src/surfaces/rail.json +1 -159
  367. package/src/surfaces/rail.ts +18 -75
  368. package/src/surfaces/schema-form.json +10 -2
  369. package/src/surfaces/schema-form.ts +2 -0
  370. package/src/surfaces/seo.json +1 -1
  371. package/src/surfaces/settings-contributed.json +5 -5
  372. package/src/surfaces/settings-contributed.ts +18 -2
  373. package/src/surfaces/settings-css-vars.json +44 -36
  374. package/src/surfaces/settings-css-vars.ts +77 -4
  375. package/src/surfaces/settings-deploy.json +2 -15
  376. package/src/surfaces/settings-deploy.ts +1 -1
  377. package/src/surfaces/settings-dialog.json +51 -0
  378. package/src/surfaces/settings-dialog.ts +169 -0
  379. package/src/surfaces/settings-overview.json +3 -3
  380. package/src/surfaces/settings-overview.ts +9 -2
  381. package/src/surfaces/settings-pane.json +269 -46
  382. package/src/surfaces/settings-pane.ts +85 -24
  383. package/src/surfaces/shell.json +2 -1
  384. package/src/surfaces/site-panel.json +1029 -0
  385. package/src/surfaces/site-panel.ts +233 -0
  386. package/src/surfaces/slash-menu.json +63 -21
  387. package/src/surfaces/slash-menu.ts +23 -0
  388. package/src/surfaces/statusbar.ts +39 -15
  389. package/src/surfaces/styles-panel.json +735 -0
  390. package/src/surfaces/styles-panel.ts +195 -0
  391. package/src/surfaces/styles-variables.json +149 -0
  392. package/src/surfaces/styles-variables.ts +145 -0
  393. package/src/surfaces/tab-strip.json +4 -4
  394. package/src/surfaces/welcome.ts +1 -1
  395. package/src/surfaces/writing-banner.json +94 -0
  396. package/src/surfaces/writing-banner.ts +80 -0
  397. package/src/tabs/bare-repeaters.ts +101 -0
  398. package/src/tabs/tab.ts +47 -7
  399. package/src/types.ts +21 -26
  400. package/src/ui/form-controls.ts +47 -8
  401. package/src/ui/layers.ts +13 -0
  402. package/src/ui/media-picker.ts +284 -40
  403. package/src/ui/regions.ts +7 -6
  404. package/src/ui/schema-form.ts +259 -27
  405. package/src/ui/virtual-window.ts +26 -1
  406. package/src/utils/base64.ts +3 -3
  407. package/src/utils/edit-display.ts +322 -67
  408. package/src/utils/local-day.ts +18 -0
  409. package/src/workspace/pane-derive.ts +4 -4
  410. package/src/workspace/session.ts +28 -7
  411. package/src/workspace/tab-workspace.ts +137 -0
  412. package/src/workspace/workspace-back.ts +189 -0
  413. package/src/workspace/workspace-home.ts +133 -0
  414. package/src/workspace/workspace-ids.ts +129 -0
  415. package/src/workspace/workspace-switch.ts +372 -0
  416. package/src/workspace/workspace.ts +125 -11
  417. package/styles/shell-frame.css +30 -7
  418. package/styles/shell-frame.json +15 -3
  419. package/dist/chunks/2020-f2gkpy8d.js +0 -4
  420. package/dist/chunks/adapter-4912g339.js +0 -4
  421. package/dist/chunks/cf-account-picker-wccaenh6.js +0 -4
  422. package/dist/chunks/cf-settings-br6105tr.js +0 -4
  423. package/dist/chunks/color-28ksk2qm.js +0 -4
  424. package/dist/chunks/components-db68vsn7.js +0 -4
  425. package/dist/chunks/content-source-1449qesq.js +0 -4
  426. package/dist/chunks/convert-to-repeater-5h457egj.js +0 -4
  427. package/dist/chunks/editor-x9jn86a7.js +0 -4
  428. package/dist/chunks/entry-commands-may24cpt.js +0 -4
  429. package/dist/chunks/extension-sections-pvr14vxr.js +0 -4
  430. package/dist/chunks/file-ops-x9v54pcj.js +0 -4
  431. package/dist/chunks/files-j3knqf0s.js +0 -4
  432. package/dist/chunks/format-host-tyre2trb.js +0 -4
  433. package/dist/chunks/fs-events-64ma9htc.js +0 -4
  434. package/dist/chunks/git-panel-84ps5dex.js +0 -4
  435. package/dist/chunks/iframe-entry-fvbk89gm.js +0 -5
  436. package/dist/chunks/iframe-host-ck6vejt5.js +0 -4
  437. package/dist/chunks/index-b8xw3vy9.js +0 -4
  438. package/dist/chunks/jsonMode-w15cmrcm.js +0 -13
  439. package/dist/chunks/jx-validate-at3zn8wa.js +0 -4
  440. package/dist/chunks/layers-h4xp1pss.js +0 -4
  441. package/dist/chunks/layers-panel-m5hw1d7g.js +0 -4
  442. package/dist/chunks/lit-html-8t8t3dnr.js +0 -4
  443. package/dist/chunks/media-picker-2cweexc5.js +0 -4
  444. package/dist/chunks/menu-ynw13y0s.js +0 -4
  445. package/dist/chunks/monaco-buffer-qzxn567r.js +0 -4
  446. package/dist/chunks/monaco-setup-gxf6656g.js +0 -4
  447. package/dist/chunks/notify-cj5zbrs2.js +0 -4
  448. package/dist/chunks/parse-b7ddhr8m.js +0 -4
  449. package/dist/chunks/platform-3dfws9js.js +0 -4
  450. package/dist/chunks/popover-jt2gxmzs.js +0 -4
  451. package/dist/chunks/publish-panel-1gvxbj21.js +0 -4
  452. package/dist/chunks/quick-search-0dajrwqg.js +0 -4
  453. package/dist/chunks/references-49qgt404.js +0 -4
  454. package/dist/chunks/right-panel-jm1bwe53.js +0 -4
  455. package/dist/chunks/section-registry-6kwc4fky.js +0 -4
  456. package/dist/chunks/studio-0rt52vpq.js +0 -5
  457. package/dist/chunks/studio-18vgbhs5.js +0 -5
  458. package/dist/chunks/studio-24mccdrj.js +0 -5
  459. package/dist/chunks/studio-2eh507zk.js +0 -9
  460. package/dist/chunks/studio-2hcbccfv.js +0 -5
  461. package/dist/chunks/studio-2jbs3rxv.js +0 -5
  462. package/dist/chunks/studio-4h8k4dw9.js +0 -5
  463. package/dist/chunks/studio-5f6n18kx.js +0 -5
  464. package/dist/chunks/studio-5gthpky6.js +0 -5
  465. package/dist/chunks/studio-6ep3js6b.js +0 -9
  466. package/dist/chunks/studio-6wkmf3wz.js +0 -9
  467. package/dist/chunks/studio-841rf3cg.js +0 -5
  468. package/dist/chunks/studio-8gmwgheg.js +0 -5
  469. package/dist/chunks/studio-8qm0ep50.js +0 -5
  470. package/dist/chunks/studio-924p1tm1.js +0 -6
  471. package/dist/chunks/studio-a3shpz9y.js +0 -5
  472. package/dist/chunks/studio-amsbaaar.js +0 -6
  473. package/dist/chunks/studio-at5spjbc.js +0 -7
  474. package/dist/chunks/studio-b2xv945e.js +0 -5
  475. package/dist/chunks/studio-bn5nkafw.js +0 -5
  476. package/dist/chunks/studio-bw6q5xjf.js +0 -9
  477. package/dist/chunks/studio-c7q0t9x1.js +0 -5
  478. package/dist/chunks/studio-camnhc96.js +0 -6
  479. package/dist/chunks/studio-cffqvnzd.js +0 -5
  480. package/dist/chunks/studio-efvfrsf8.js +0 -5
  481. package/dist/chunks/studio-er30bpcx.js +0 -5
  482. package/dist/chunks/studio-ezscgr64.js +0 -5
  483. package/dist/chunks/studio-ffrrncvz.js +0 -5
  484. package/dist/chunks/studio-fpphgn8y.js +0 -10
  485. package/dist/chunks/studio-j1kvhdjk.js +0 -4
  486. package/dist/chunks/studio-j430n16g.js +0 -7
  487. package/dist/chunks/studio-jjkg84nj.js +0 -5
  488. package/dist/chunks/studio-m0q32ars.js +0 -4
  489. package/dist/chunks/studio-m6bdst11.js +0 -5
  490. package/dist/chunks/studio-nv2cptd4.js +0 -64
  491. package/dist/chunks/studio-nwfrc98n.js +0 -5
  492. package/dist/chunks/studio-p1wgvp7r.js +0 -5
  493. package/dist/chunks/studio-pag2wncm.js +0 -5
  494. package/dist/chunks/studio-qvanvzfd.js +0 -5
  495. package/dist/chunks/studio-qwa64kt7.js +0 -5
  496. package/dist/chunks/studio-rk1zc4x3.js +0 -928
  497. package/dist/chunks/studio-se2r3ptc.js +0 -5
  498. package/dist/chunks/studio-sg2a0dh0.js +0 -5
  499. package/dist/chunks/studio-tjzjhe68.js +0 -5
  500. package/dist/chunks/studio-v2w7q8r1.js +0 -7
  501. package/dist/chunks/studio-v5vjq1h0.js +0 -4
  502. package/dist/chunks/studio-v8aga3vp.js +0 -14
  503. package/dist/chunks/studio-vfcdrfmv.js +0 -5
  504. package/dist/chunks/studio-vmfkgdjf.js +0 -5
  505. package/dist/chunks/studio-wt1816jj.js +0 -5
  506. package/dist/chunks/studio-wz73q5kq.js +0 -4
  507. package/dist/chunks/studio-y04qtxvp.js +0 -7
  508. package/dist/chunks/studio-y21g8zzg.js +0 -5
  509. package/dist/chunks/studio-y64hrt8p.js +0 -12
  510. package/dist/chunks/studio-ynn90f58.js +0 -16
  511. package/dist/chunks/studio-yxz682sx.js +0 -5
  512. package/dist/chunks/studio-zp7snvkq.js +0 -5
  513. package/dist/chunks/studio-zq4z6tm6.js +0 -5
  514. package/dist/chunks/toast-c9fn075p.js +0 -4
  515. package/dist/chunks/tsMode-sf49ee9x.js +0 -14
  516. package/dist/chunks/workspace-jtfahpee.js +0 -4
  517. package/src/panels/frontmatter-panel.ts +0 -711
  518. package/src/panels/git-panel.ts +0 -1108
  519. package/src/surfaces/doc-header.json +0 -776
  520. package/src/surfaces/doc-header.ts +0 -222
  521. package/src/surfaces/git-panel.json +0 -1880
  522. package/src/surfaces/git-panel.ts +0 -264
@@ -45,6 +45,7 @@
45
45
  * the document it is warning you about.
46
46
  */
47
47
 
48
+ import { writesEntryOnCanvas } from "../content/content-collections";
48
49
  import { projectState, updateUi } from "../store";
49
50
  import { effect, effectScope } from "../reactivity";
50
51
  import { PRIMARY_PANE, focusPane, workspace } from "../workspace/workspace";
@@ -68,6 +69,8 @@ import { openMenu } from "../surfaces/menu";
68
69
  import { emptyPaneContextView, mountPaneContextSurface } from "../surfaces/pane-context";
69
70
  import { PANE_SELECTOR } from "../surfaces/pane-grid";
70
71
  import { diffShowsCode } from "../canvas/diff-view";
72
+ import { backTargetOf, goBack } from "../workspace/workspace-back";
73
+ import type { WorkspaceId } from "../workspace/workspace-ids";
71
74
  import { canRenderComparison } from "./git-diff-open";
72
75
  import { shell } from "../shell";
73
76
  import { paneRegion } from "../ui/regions";
@@ -89,7 +92,12 @@ import {
89
92
  import { editorKindOf, editorKindsOf, modeForEditorKind } from "../tabs/tab";
90
93
  import { collabState } from "../collab/collab-state";
91
94
  import { activeRegistry } from "../commands/active-registry";
92
- import { getEffectiveLayoutPath, getEffectiveLocales, getEffectiveMedia } from "../site-context";
95
+ import {
96
+ getEffectiveLayoutPath,
97
+ getEffectiveLocales,
98
+ getEffectiveMedia,
99
+ getEffectiveRenderLocale,
100
+ } from "../site-context";
93
101
  import { localeLabel, localeOfPath } from "@jxsuite/schema/locale";
94
102
  import { isSchemeQuery } from "../utils/canvas-media";
95
103
  import { dynamicRouteParams, loadParamValues, pagePathsDef } from "../page-params";
@@ -143,6 +151,14 @@ export interface PaneContextCtx {
143
151
  * Editor picker a control over the primary's document.
144
152
  */
145
153
  setCanvasMode: (tab: Tab, mode: string) => void;
154
+ /**
155
+ * Close a tab through the strip's guarded close (`panels/tab-strip.ts` `requestClose`): what the
156
+ * Back control does to a media viewer or a comparison. Absent (a test's partial bootstrap), the
157
+ * control runs `pane.backToHome` instead, whose bootstrap deps carry the same close.
158
+ */
159
+ closeTab?: (tabId: string) => void | Promise<void>;
160
+ /** Give the keyboard to the home a Back landed on (`WorkspaceBackDeps.focusHome`). */
161
+ focusHome?: (paneId: string, id: WorkspaceId) => void;
146
162
  parseMediaEntries: (media: Record<string, string> | null | undefined) => {
147
163
  sizeBreakpoints: {
148
164
  name: string;
@@ -219,10 +235,51 @@ export function attachPaneChromeHost(paneId: string, host: HTMLElement | null):
219
235
 
220
236
  /** Take one pane's document down and forget it. Idempotent. */
221
237
  function disposePane(paneId: string): void {
238
+ _bandWatches.get(paneId)?.observer.disconnect();
239
+ _bandWatches.delete(paneId);
222
240
  _surfaces.get(paneId)?.dispose();
223
241
  _surfaces.delete(paneId);
224
242
  }
225
243
 
244
+ /**
245
+ * Each pane's band, as the observer that keeps the stage offset in step with it watches it.
246
+ *
247
+ * The offset used to be MEASURED on every projection, synchronously, right after the update that
248
+ * may have changed the band. A projection runs inside whatever changed the pane (a tab activation,
249
+ * a workspace switch, a mode change) with the rest of that change still to be written, so the read
250
+ * paid a style recalculation of the whole half-written document every time: 12 to 18 ms per tab
251
+ * activation in the perf trace, the hottest forced recalculation once the tab strip stopped
252
+ * reading. A `ResizeObserver` reports the band's height after the frame's own layout, when it is
253
+ * free to read, and only when it actually changed.
254
+ */
255
+ const _bandWatches = new Map<string, { band: HTMLElement; observer: ResizeObserver }>();
256
+
257
+ /**
258
+ * Keep `paneId`'s stage offset following its band: measure it once now, and again whenever it
259
+ * resizes. Re-binds when the document has drawn a new band element; a no-op for the one it holds.
260
+ * Without `ResizeObserver` (a DOM with no layout engine) every call measures, as before.
261
+ */
262
+ function watchBand(paneId: string, host: HTMLElement, surface: PaneContextSurfaceHandle): void {
263
+ const band = surface.band();
264
+ const held = _bandWatches.get(paneId);
265
+ if (held && held.band === band) {
266
+ return;
267
+ }
268
+ held?.observer.disconnect();
269
+ _bandWatches.delete(paneId);
270
+ applyPaneContextOffset(topBandHeight(surface), host);
271
+ if (!band || typeof ResizeObserver === "undefined") {
272
+ return;
273
+ }
274
+ const observer = new ResizeObserver(() => {
275
+ if (_surfaces.get(paneId) === surface) {
276
+ applyPaneContextOffset(topBandHeight(surface), host);
277
+ }
278
+ });
279
+ observer.observe(band);
280
+ _bandWatches.set(paneId, { band, observer });
281
+ }
282
+
226
283
  /**
227
284
  * Mount the pane chrome. Idempotent.
228
285
  *
@@ -333,21 +390,6 @@ function topBandHeight(surface: PaneContextSurfaceHandle): number {
333
390
  return Math.max(surface.band()?.offsetHeight ?? 0, PANE_CONTEXT_HEIGHT);
334
391
  }
335
392
 
336
- /**
337
- * Whether this tab's editor has any of the bar's three axes to offer.
338
- *
339
- * Project Settings has none: it declares one editor kind, no canvas view, and no rendering context
340
- * — and the one control the bar WOULD contribute, "Manage contexts…", routes to a section of the
341
- * very document on screen. A bar of three inert controls above the definition site they point at is
342
- * chrome that says nothing, so the stage takes the whole pane.
343
- *
344
- * @param {Tab} tab
345
- * @returns {boolean}
346
- */
347
- function wantsContextBar(tab: Tab): boolean {
348
- return tab.session.ui.canvasMode !== "settings";
349
- }
350
-
351
393
  /** Project every attached pane's chrome. */
352
394
  export function render() {
353
395
  for (const [paneId, host] of _hosts) {
@@ -362,8 +404,7 @@ function renderPane(paneId: string, host: HTMLElement) {
362
404
  }
363
405
  try {
364
406
  const tab = tabOfPane(paneId);
365
- const show = tab !== null && wantsContextBar(tab);
366
- if (!show) {
407
+ if (tab === null) {
367
408
  disposePane(paneId);
368
409
  applyPaneContextOffset(0, host);
369
410
  return;
@@ -382,13 +423,15 @@ function renderPane(paneId: string, host: HTMLElement) {
382
423
  void surface.ready.then(() => {
383
424
  const live = _surfaces.get(paneId);
384
425
  if (live) {
385
- applyPaneContextOffset(topBandHeight(live), host);
426
+ watchBand(paneId, host, live);
386
427
  }
387
428
  });
388
429
  return;
389
430
  }
390
431
  surface.update(view);
391
- applyPaneContextOffset(topBandHeight(surface), host);
432
+ /* No read here: the band's observer writes the offset once the frame has laid the band out
433
+ ({@link watchBand}). Only a band element the update REPLACED is re-measured now. */
434
+ watchBand(paneId, host, surface);
392
435
  } catch (error) {
393
436
  console.error("pane-context render error:", error);
394
437
  }
@@ -663,10 +706,27 @@ function viewFor(tab: Tab, paneId: string, ctx: PaneContextCtx): PaneContextView
663
706
  view.summary = lensSummary(paneId);
664
707
  return view;
665
708
  }
709
+ /* The way out of a view in a workspace with no tab strip: named for where it leads. Never in a
710
+ lens, whose tab is the source pane's, and whose own exit is the derivation's. */
711
+ const back = backTargetOf(tab);
712
+ if (back) {
713
+ view.backState = "shown";
714
+ view.backLabel = back.label;
715
+ view.backHint = back.hint;
716
+ }
666
717
  Object.assign(view, editorAxis(tab));
667
718
  if (editorKindOf(tab) === "canvas") {
668
719
  Object.assign(view, viewAxis(tab));
669
720
  }
721
+ /* A workspace home (the Content, Media or Publish home) draws its workspace's own surface over a
722
+ stub document, so there is no rendering context to choose: "Context: Base" over the Publish
723
+ workspace was a control that could change nothing on screen. The ⟲ menu goes for the same
724
+ reason: every projection it offers is of the document, and a home has none to project. */
725
+ if (editorKindOf(tab) === "home") {
726
+ view.contextState = "hidden";
727
+ view.presetState = "hidden";
728
+ return view;
729
+ }
670
730
  Object.assign(view, contextAxis(tab, paneId, ctx));
671
731
  /* THIS tab's effective mode. `ctx.getCanvasMode()` answered for the focused pane, so a document
672
732
  opened as Code in either pane put an Export button in the OTHER pane's bar as well — over a
@@ -810,10 +870,8 @@ interface PaneLocale {
810
870
  * A single declared locale is the same as none for this control — there is nothing to switch TO,
811
871
  * and "groups a document declares nothing for are absent" is the rule the whole popover follows.
812
872
  *
813
- * The fallback chain is what makes the control honest about a file it has not been told about:
814
- * `previewLocale` is the author's explicit choice, the path is the file's own language
815
- * (`site-architecture.md` §13.3 puts a translation in its own directory), and the default locale is
816
- * what an unprefixed page renders as.
873
+ * The language itself is `getEffectiveRenderLocale`'s answer (`site-context.ts`), the rule every
874
+ * artboard draws by: the choice, else the file's own language, else the default locale.
817
875
  */
818
876
  function localeOf(tab: Tab | null): PaneLocale | null {
819
877
  const i18n = getEffectiveLocales();
@@ -821,8 +879,10 @@ function localeOf(tab: Tab | null): PaneLocale | null {
821
879
  return null;
822
880
  }
823
881
  const pathLocale = localeOfPath(tab.documentPath ?? "", i18n);
824
- const own = pathLocale ?? i18n.defaultLocale;
825
- const effective = tab.session.ui.previewLocale ?? own;
882
+ /* The artboard's own rule, so the segment and the canvas cannot name two languages; a stored
883
+ choice the project no longer declares is not reported, because it is not drawn. */
884
+ const own = getEffectiveRenderLocale(null, tab.documentPath) ?? i18n.defaultLocale;
885
+ const effective = getEffectiveRenderLocale(tab.session.ui.previewLocale, tab.documentPath) ?? own;
826
886
  return { effective, i18n, overridden: effective !== own, pathLocale };
827
887
  }
828
888
 
@@ -848,7 +908,12 @@ function contextAxis(tab: Tab, paneId: string, ctx: PaneContextCtx): Partial<Pan
848
908
  ]
849
909
  .filter((part) => part !== null)
850
910
  .join(" · ");
851
- const hasLayout = isPageDoc(tab) && Boolean(getEffectiveLayoutPath(tab.doc.document.$layout));
911
+ /* An entry written on the canvas is wrapped in its template's layout like a page (§22.5), so it
912
+ offers the same "show layout" choice. Whether a layout resolves for it is read asynchronously
913
+ by the canvas; the project default is the answer this bar can give synchronously. */
914
+ const hasLayout =
915
+ (isPageDoc(tab) && Boolean(getEffectiveLayoutPath(tab.doc.document.$layout))) ||
916
+ (Boolean(projectState?.isSiteProject) && writesEntryOnCanvas(tab.documentPath));
852
917
  const page = isPageDoc(tab);
853
918
  const params = page ? paramRows(tab) : [];
854
919
  const props = page ? [] : propRows(tab, paneId);
@@ -927,8 +992,9 @@ function sizeRows(
927
992
  * cannot and must not claim to translate the page. What it does change is real: the artboard's
928
993
  * `lang` and its `dir`, and an RTL locale mirrors the layout on the stage. A control that let an
929
994
  * author believe it had translated anything would be worse than no control — which is also why the
930
- * sentence stops there: the build's `$page.locale` is not injected into the canvas render today, so
931
- * a tooltip promising it would be describing the site rather than the pane.
995
+ * sentence stops there: the page's `$page.locale` comes from its route on the canvas as in the
996
+ * build (studio.md §4.1), so this control does not change it, and a tooltip promising otherwise
997
+ * would describe something the pane does not do.
932
998
  *
933
999
  * Labelled with each locale's AUTONYM, for the reason `localeLabel` gives: a reader looking for
934
1000
  * their own language scans for their own word for it.
@@ -1098,6 +1164,22 @@ function actionsFor(paneId: string, ctx: PaneContextCtx): PaneContextActions {
1098
1164
  }
1099
1165
  },
1100
1166
  exportFile: ctx.exportFile,
1167
+ /* The flow directly rather than `pane.backToHome`: the command's `when` keeps Escape away from
1168
+ a text field and the code editor, and the CONTROL must work in both (Back from Code is the
1169
+ Styles case). The pane is focused first, because the view going back is this pane's. */
1170
+ goBack: () => {
1171
+ focusPane(paneId);
1172
+ const { closeTab } = ctx;
1173
+ if (!closeTab) {
1174
+ runContextCommand(paneId, "pane.backToHome", {});
1175
+ return;
1176
+ }
1177
+ void goBack(paneId, {
1178
+ closeTab,
1179
+ setCanvasMode: ctx.setCanvasMode,
1180
+ ...(ctx.focusHome && { focusHome: ctx.focusHome }),
1181
+ });
1182
+ },
1101
1183
  manageContexts: () => {
1102
1184
  void activeRegistry()?.run("settings.open", { section: "contexts" });
1103
1185
  },
@@ -312,12 +312,12 @@ function attachDropZone(paneId: string, element: HTMLElement): () => void {
312
312
  * One of a cell's five boxes has been created. Fill the record in, and wire what belongs to it.
313
313
  *
314
314
  * The context bar is HANDED its host rather than resolving a region, the same way
315
- * `panels/frontmatter-panel.ts` is handed the stage. It cannot resolve one the way the tab strip
316
- * does: the strip's host carries `pane.<id>/tabs` and nothing inside it re-stamps that id, while
317
- * the context bar stamps `pane.<id>/context` on markup it renders INSIDE its box — so a region on
318
- * the wrapper as well would put the same id on two nested elements, and `resolveRegion` takes the
319
- * LAST match. Sixty shots crop `pane.primary/context`; a second, larger element carrying it is a
320
- * silently widened crop.
315
+ * `content/writing-banner.ts` is handed its host on the stage. It cannot resolve one the way the
316
+ * tab strip does: the strip's host carries `pane.<id>/tabs` and nothing inside it re-stamps that
317
+ * id, while the context bar stamps `pane.<id>/context` on markup it renders INSIDE its box — so a
318
+ * region on the wrapper as well would put the same id on two nested elements, and `resolveRegion`
319
+ * takes the LAST match. Sixty shots crop `pane.primary/context`; a second, larger element carrying
320
+ * it is a silently widened crop.
321
321
  */
322
322
  function cellPart(paneId: string, part: PaneCellPart, element: HTMLElement): void {
323
323
  const cell = cellState(paneId);
@@ -32,9 +32,9 @@ import { emptyContext } from "../commands/context";
32
32
  import { projectState } from "../store";
33
33
  import { shell } from "../shell";
34
34
  import { activeTab } from "../workspace/workspace";
35
+ import { developerPanelsShown } from "../settings/developer-panels";
35
36
  import type { Level } from "../commands/levels";
36
37
  import type { CommandContext } from "../commands/context";
37
- import type { GitDiffState } from "../types";
38
38
  import type { JxMutableNode, JxStateDefinition } from "@jxsuite/schema/types";
39
39
  import type { JxPath } from "../state";
40
40
  import type { Tab, TabUi } from "../tabs/tab";
@@ -85,8 +85,6 @@ export interface NavigatorPanelDeps {
85
85
  registerLayersDnD: () => void;
86
86
  registerElementsDnD: () => void;
87
87
  registerComponentsDnD: () => void;
88
- setGitDiffState: (state: GitDiffState | null) => void;
89
- cloneRepository?: () => void;
90
88
  }
91
89
 
92
90
  /**
@@ -158,8 +156,13 @@ export interface PanelRecord {
158
156
  * losing its rail slot and gaining its real home (Insert, reachable from the canvas and palette;
159
157
  * State, folded into Data — §5.1). Declaring it `false` also removes the panel's `rail/<level>`
160
158
  * placement, which is what keeps the rail inside its four-per-group budget.
159
+ *
160
+ * `"developer"` is a rail button only while **Show developer panels** is on (§5.1,
161
+ * `settings/developer-panels.ts`): Files and Packages, which a site author does not need on the
162
+ * Design rail and a developer wants one click away. It keeps its rail placement either way, so
163
+ * the budget counts the button the switch can add.
161
164
  */
162
- rail?: boolean;
165
+ rail?: boolean | "developer";
163
166
  /**
164
167
  * The sentence a document-level panel shows instead of its body when no document is open.
165
168
  *
@@ -208,6 +211,7 @@ export function panelContext(): CommandContext {
208
211
  ctx.project.isMultilingual =
209
212
  (resolveI18n(projectState?.projectConfig ?? {}).i18n?.locales.length ?? 0) > 1;
210
213
  ctx.git.dirtyCount = shell.git.status?.files.length ?? 0;
214
+ ctx.workspace.id = shell.workspace;
211
215
  ctx.document.open = activeTab.value !== null;
212
216
  return ctx;
213
217
  }
@@ -324,7 +328,8 @@ function railablePanels(): readonly PanelRecord[] {
324
328
  * @param {CommandContext} ctx
325
329
  */
326
330
  export function railGroups(ctx: CommandContext): RailGroup[] {
327
- const railable = railablePanels();
331
+ const developer = developerPanelsShown();
332
+ const railable = railablePanels().filter((panel) => panel.rail !== "developer" || developer);
328
333
  return RAIL_GROUP_LEVELS.flatMap(({ level, label }) => {
329
334
  const panels = railable.filter((panel) => panel.level === level && isPanelVisible(panel, ctx));
330
335
  return panels.length > 0 ? [{ level, label, panels }] : [];
@@ -334,10 +339,10 @@ export function railGroups(ctx: CommandContext): RailGroup[] {
334
339
  /**
335
340
  * The rail's panels flattened into rail order — PROJECT group, then DOCUMENT group.
336
341
  *
337
- * This is the order ⌘1–8 follow, and it is derived from the same two rows the rail draws rather
338
- * than from registration order, so a panel registered by its dock's module (Problems, from
339
- * `panels/bottom-dock.ts`) still lands in the slot its LEVEL gives it. `when` is not applied: a
340
- * chord roster that changed length with context would move every chord after the hidden panel.
342
+ * This is the order the `panel.focus.*` records follow, and it is derived from the same two rows
343
+ * the rail draws rather than from registration order, so a panel registered by its dock's module
344
+ * still lands in the slot its LEVEL gives it. `when` is not applied: a roster that changed length
345
+ * with context would reorder the palette under the reader.
341
346
  */
342
347
  export function railPanelSet(): PanelRecord[] {
343
348
  const railable = railablePanels();
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * - **Repeater · Switch · Observed Attributes · CSS Properties · CSS Parts → the Logic tab.** Wiring
10
10
  * a `$switch` and wiring a click handler are the same task (`panels/events-panel.ts`).
11
- * - **The Page section → the Document Header card.** `panels/head-panel.ts` owns the one layout
11
+ * - **The Page section → the Inspector's Page tab.** `panels/head-panel.ts` owns the one layout
12
12
  * picker; this panel drew a second one that could disagree with it.
13
13
  * - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (§17.1). Nothing remains here: the
14
14
  * only reason adding a breakpoint used to cost you your element selection.
@@ -1583,7 +1583,9 @@ function componentPropRows(
1583
1583
  if (isMediaFormat(prop.format)) {
1584
1584
  row.kind = "control";
1585
1585
  plan.control = (host) =>
1586
- mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v));
1586
+ mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v), {
1587
+ images: prop.format === "image",
1588
+ });
1587
1589
  } else if (prop.format === "color") {
1588
1590
  row.kind = "color";
1589
1591
  row.tokens = colorTokens();
@@ -1784,7 +1786,9 @@ function attributeRow(
1784
1786
  row.kind = "control";
1785
1787
  const staticVal = isRef(value) ? "" : String(value || "");
1786
1788
  plan.control = (host) =>
1787
- mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined));
1789
+ mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined), {
1790
+ images: entry.format === "image",
1791
+ });
1788
1792
  } else if (type === "select") {
1789
1793
  row.kind = "select";
1790
1794
  row.value = isRef(value) ? "" : String(value || "");