@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
@@ -34,8 +34,8 @@
34
34
  * does, because the document is appended into the `.panel-content` lit renders `nothing` into).
35
35
  *
36
36
  * **Off the rail.** `railDeclarations()` does not apply `when`, so a rail button here would spend
37
- * the last `rail/project` slot in every monolingual project and shift every document panel's ⌘1–8
38
- * chord by one. `i18n.showParity` is how this panel is reached.
37
+ * the last `rail/project` slot in every monolingual project. `i18n.showParity` is how this panel is
38
+ * reached.
39
39
  *
40
40
  * @docs studio/interface/languages
41
41
  */
@@ -190,7 +190,7 @@ async function takeScan(root: string, rerender: () => void): Promise<void> {
190
190
  */
191
191
  async function readDeclaredKeys(files: readonly LibraryFile[]): Promise<Map<string, string>> {
192
192
  const platform = getPlatform();
193
- const pages = files.filter((file) => file.category !== "Media" && file.path.startsWith("pages/"));
193
+ const pages = files.filter((file) => !file.media && file.path.startsWith("pages/"));
194
194
  /* Issued together, not one after another. Each read is a round trip on a remote backend, and a
195
195
  sequential loop paid one per page; issued in one tick, the cloud adapter coalesces them into a
196
196
  single batch request (specs/desktop.md §10.1). `Promise.all` keeps the input order, so the map
@@ -236,8 +236,8 @@ function timeOf(modified: string | undefined): number | null {
236
236
  * it is the source the other columns are measured against, and hiding it would leave the grid with
237
237
  * a column of `missing` cells whose sources are on disk.
238
238
  *
239
- * Assets are skipped. `categoryFor` already decides what is media by extension, so an image beside
240
- * a page is not a row here for the same reason it is not a page anywhere else.
239
+ * Assets are skipped. The scan already marks what is media by its extension, so an image beside a
240
+ * page is not a row here for the same reason it is not a page anywhere else.
241
241
  */
242
242
  export function parityRows(
243
243
  files: readonly LibraryFile[],
@@ -255,7 +255,7 @@ export function parityRows(
255
255
  /* Every key the paths alone produce, so a declared one can be matched against a real file rather
256
256
  than against a spelling. */
257
257
  const derivedKeys = new Set(
258
- files.flatMap((f) => (f.category === "Media" ? [] : [translationKeyOfPath(f.path, i18n)])),
258
+ files.flatMap((f) => (f.media ? [] : [translationKeyOfPath(f.path, i18n)])),
259
259
  );
260
260
  const keyOf = (file: LibraryFile): string => {
261
261
  const own = declared.get(file.path);
@@ -278,7 +278,7 @@ export function parityRows(
278
278
  return `pages/${own}${ext}`;
279
279
  };
280
280
  for (const file of files) {
281
- if (file.category === "Media") {
281
+ if (file.media) {
282
282
  continue;
283
283
  }
284
284
  const key = keyOf(file);
@@ -542,8 +542,10 @@ let rerender: () => void = () => {};
542
542
 
543
543
  /** What the document's three controls do. Every one of them is a decision this module owns. */
544
544
  const ACTIONS: I18nActions = {
545
+ /* On Locales, not wherever Project Settings was last left: the empty state's one sentence is
546
+ "declare your languages", and the dialog remembers its section for the session (§17.1). */
545
547
  openSettings: () => {
546
- runByName(SETTINGS_COMMAND);
548
+ runByName(SETTINGS_COMMAND, { section: "locales" });
547
549
  },
548
550
  rescan: () => {
549
551
  refreshParityScan();
@@ -606,8 +608,7 @@ export function registerI18nPanel(): void {
606
608
  // Button, and `check-icons.ts` fails on a resolver row no rail panel declares.
607
609
  icon: "globe",
608
610
  // OFF THE RAIL. `railDeclarations()` does not apply `when`, so a rail button would spend the
609
- // Last rail/project slot in every monolingual project — and would shift every document panel's
610
- // ⌘1-8 chord by one. `i18n.showParity` is how it is reached.
611
+ // Last rail/project slot in every monolingual project. `i18n.showParity` is how it is reached.
611
612
  rail: false,
612
613
  when: (ctx) => ctx.project.isMultilingual,
613
614
  // The body is a document, so lit draws nothing and the mount happens against the painted
@@ -442,6 +442,8 @@ export function registerPackagesPanel(): void {
442
442
  level: "document",
443
443
  dock: "navigator",
444
444
  icon: "cube",
445
+ // A developer panel (§5.1): on the rail only with **Show developer panels** on.
446
+ rail: "developer",
445
447
  requiresDocument: "Open a page to choose which components it can use.",
446
448
  render: () => nothing,
447
449
  afterRender: (ctx, host) => {
@@ -75,6 +75,8 @@ import { runReported } from "../commands/run-reported";
75
75
  import { openMenu } from "../surfaces/menu";
76
76
  import { rectOf } from "../utils/geometry";
77
77
  import { mountJumpBarSurface } from "../surfaces/jump-bar";
78
+ import { workspaceHomeLabel } from "../workspace/workspace-ids";
79
+ import { gridTabLabel } from "../grid/grid-source";
78
80
  import type { CommandRegistry } from "../commands/registry";
79
81
  import type { FormulaEditDef, FunctionEditDef } from "../types";
80
82
  import type { JxPath } from "../state";
@@ -152,6 +154,30 @@ export function documentLabel(path: string | null): string {
152
154
  return root && path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
153
155
  }
154
156
 
157
+ /**
158
+ * What the file segment says about a tab: its path, or, for a VIRTUAL tab, the view's own name.
159
+ *
160
+ * A pathless tab is one of two different things. A workspace home (`workspace://content`) or a grid
161
+ * (`grid://…`) has no file because it is a view, not a document, and it never will have one;
162
+ * calling it "Untitled · Not saved to disk yet" invited the author to save a page that does not
163
+ * exist. Those tabs are named exactly as their strip chip names them (`panels/tab-strip.ts`), so
164
+ * the address and the tab agree. Only a genuinely new document is "Untitled".
165
+ */
166
+ export function fileSegmentText(tab: Tab): Pick<JumpSegment, "label" | "title"> {
167
+ if (tab.documentPath) {
168
+ return { label: documentLabel(tab.documentPath), title: tab.documentPath };
169
+ }
170
+ const home = workspaceHomeLabel(tab.id);
171
+ if (home) {
172
+ return { label: home, title: `The ${home} workspace's home, a view rather than a file` };
173
+ }
174
+ const grid = gridTabLabel(tab.id);
175
+ if (grid) {
176
+ return { label: grid, title: `${grid}, a view of many files rather than one` };
177
+ }
178
+ return { label: documentLabel(null), title: "Not saved to disk yet" };
179
+ }
180
+
155
181
  // ─── The selection trail (moved here from statusbar.ts) ──────────────────────
156
182
 
157
183
  /** One crumb of the ancestor trail: what to call the node, and the path that selects it. */
@@ -284,8 +310,7 @@ export function jumpSegments(
284
310
  choices: [],
285
311
  command: derived ? "pane.pin" : "palette.openFiles",
286
312
  kind: "file",
287
- label: documentLabel(tab.documentPath),
288
- title: tab.documentPath ?? "Not saved to disk yet",
313
+ ...fileSegmentText(tab),
289
314
  },
290
315
  ];
291
316
 
@@ -3,14 +3,16 @@
3
3
  * Layers panel — the Outline: the document tree, with collapse, selection, drag-and-drop
4
4
  * reordering, and per-row actions that are RENDERINGS of the command registry.
5
5
  *
6
- * **One panel, two bodies, and both of them are documents now.** The tree is
7
- * `surfaces/panel-outline.json`; the Project Styles catalogue is
6
+ * **One panel, two bodies, and both of them are documents.** The tree is
7
+ * `surfaces/panel-outline.json`; the element catalogue a document's Elements view lists is
8
8
  * `surfaces/panel-stylebook-layers.json` (`panels/stylebook-layers-panel.ts`). This module renders
9
- * neither. It owns the record — only the record can know which body the pane is asking for — and
9
+ * neither. It owns the record (only the record can know which body the pane is asking for) and
10
10
  * everything that is a DECISION: which rows exist and in what order, what a row is called, what the
11
11
  * window onto them is, which verbs the registry places on which row, and the whole of the keyboard
12
12
  * model. The surface reads values. The two bodies are appended into the same `.panel-content`, so
13
- * each mode takes the other's document down on the way in; that symmetry is the whole of the seam.
13
+ * each mode takes the other's document down on the way in. The Variables view has no body here:
14
+ * `project.json`'s custom properties are listed by the Styles workspace's own Navigator panel
15
+ * (`panels/styles-panel.ts`, §7.1).
14
16
  *
15
17
  * Four things this file is deliberate about.
16
18
  *
@@ -27,7 +29,7 @@
27
29
  * **A row says something.** On a real page the tree was a wall of rows all reading "div": only
28
30
  * text-bearing nodes got a preview and containers got the tag they already wear as a coloured
29
31
  * badge. {@link outlineLabel} derives an identity instead — a title, an `$id`, a class, a landmark
30
- * name, the first text inside — and returns "" rather than repeat the badge.
32
+ * name, the text it owns (never a descendant row's) — and returns "" rather than repeat the badge.
31
33
  *
32
34
  * **It is a tree, and it is reachable.** `role="tree"` / `role="treeitem"` with a roving tabindex
33
35
  * and the arrow-key model ARIA specifies: ↑↓ walk the visible rows, → expands then descends, ←
@@ -87,6 +89,7 @@ import {
87
89
  mountStylebookLayersPanel,
88
90
  } from "./stylebook-layers-panel";
89
91
  import { selectStylebookTag, stylebookMeta } from "./stylebook-panel";
92
+ import { PROJECT_STYLES_VIEW } from "../style/project-styles";
90
93
  import { isInlineElement } from "../editor/inline-edit";
91
94
  import { showContextMenu } from "../editor/context-menu";
92
95
  import { revealPathInCanvas } from "../canvas/popover-state";
@@ -147,31 +150,32 @@ function truncate(text: string): string {
147
150
  }
148
151
 
149
152
  /**
150
- * The first text anywhere under `node`, or "".
153
+ * The text `node` OWNS, or "": its string children, and the text of its inline children.
151
154
  *
152
- * Bounded at three levels and short-circuited on the first hit: a container's identity is usually
153
- * its heading or its first line, and walking a whole subtree per row would cost the render what the
154
- * five-buttons-per-row build already cost it.
155
+ * Inline children (`strong`, `a`, …) never get a row of their own ({@link buildOutlineRows} skips
156
+ * them), so their words belong to the row that holds them. A block child's text does not: it is
157
+ * that child's row's to show. Borrowing it — what the bounded "first text under" walk did — made a
158
+ * `section > div > div > h2` read the heading four times over, one row above the other.
155
159
  */
156
- function firstText(node: JxMutableNode, depth = 0): string {
157
- if (isString(node.textContent) && node.textContent.trim()) {
160
+ function ownText(node: JxMutableNode): string {
161
+ if (isString(node.textContent)) {
158
162
  return node.textContent.trim();
159
163
  }
160
- if (depth >= 3 || !Array.isArray(node.children)) {
164
+ if (!Array.isArray(node.children)) {
161
165
  return "";
162
166
  }
167
+ let text = "";
163
168
  for (const child of node.children) {
164
- if (isString(child) && child.trim()) {
165
- return child.trim();
169
+ if (isString(child)) {
170
+ text += child;
171
+ } else if (isNonNullObject(child) && isInlineElement(child, node)) {
172
+ text += ownText(child);
166
173
  }
167
- if (isNonNullObject(child)) {
168
- const found = firstText(child, depth + 1);
169
- if (found) {
170
- return found;
171
- }
174
+ if (text.length > LABEL_MAX * 2) {
175
+ break;
172
176
  }
173
177
  }
174
- return "";
178
+ return text.trim();
175
179
  }
176
180
 
177
181
  /** The node's first class name, when it has a plain (unbound) `class` attribute. */
@@ -212,9 +216,9 @@ export function outlineLabel(node: JxMutableNode): string {
212
216
  if (landmark) {
213
217
  return landmark;
214
218
  }
215
- const inner = firstText(node);
216
- if (inner) {
217
- return `“${truncate(inner)}”`;
219
+ const own = ownText(node);
220
+ if (own) {
221
+ return `“${truncate(own)}”`;
218
222
  }
219
223
  const count = Array.isArray(node.children) ? node.children.length : 0;
220
224
  return count > 0 ? `${count} item${count === 1 ? "" : "s"}` : "";
@@ -1142,9 +1146,9 @@ export function outlineValues(): OutlineValues {
1142
1146
  /**
1143
1147
  * The surface standing in the Navigator, and the node it was mounted into.
1144
1148
  *
1145
- * One slot rather than a per-host map, for the reason `panels/stylebook-layers-panel.ts` gives:
1146
- * there is one Navigator, so a mount into a DIFFERENT node is the old one being replaced, and
1147
- * holding both would leave the first one's effects running against a scope nobody writes any more.
1149
+ * One slot rather than a per-host map, for the reason `panels/elements-panel.ts` gives: there is
1150
+ * one Navigator, so a mount into a DIFFERENT node is the old one being replaced, and holding both
1151
+ * would leave the first one's effects running against a scope nobody writes any more.
1148
1152
  */
1149
1153
  let standing: { host: HTMLElement; handle: OutlineSurfaceHandle } | null = null;
1150
1154
  /** Re-register drag-and-drop once the rows the projection asked for are actually in the DOM. */
@@ -1353,7 +1357,7 @@ export function mountOutlinePanel(
1353
1357
  /**
1354
1358
  * Take the tree down.
1355
1359
  *
1356
- * Called by the record when the pane starts showing Project Styles. Without it the document
1360
+ * Called by the record when the pane starts showing an Elements view. Without it the document
1357
1361
  * survives its own irrelevance: both bodies are appended into the same `.panel-content`, so the one
1358
1362
  * nobody took down sits under the one that replaced it for the rest of the session.
1359
1363
  */
@@ -1388,18 +1392,20 @@ export function registerLayersPanel(): void {
1388
1392
  requiresDocument: "Open a page to see the elements it is built from.",
1389
1393
  /*
1390
1394
  * One panel, two bodies, and neither of them is lit's. The body is a document either way, so
1391
- * there is nothing for lit to draw here — a document CLEARS nothing and is APPENDED, and lit's
1395
+ * there is nothing for lit to draw here: a document CLEARS nothing and is APPENDED, and lit's
1392
1396
  * own comment markers inside `.panel-content` are what it finds its (empty) content by.
1393
1397
  */
1394
1398
  render: (): PanelBody => nothing,
1395
1399
  /*
1396
- * `afterRender` runs on every repaint, and both mounts are idempotent — the standing surface is
1400
+ * `afterRender` runs on every repaint, and both mounts are idempotent: the standing surface is
1397
1401
  * updated where it is still there and re-mounted only where something has taken it out. The
1398
1402
  * detach on each side is not symmetry for its own sake: the two documents are appended into the
1399
1403
  * same node, so a body nobody took down would sit under the one that replaced it.
1400
1404
  */
1401
1405
  afterRender: (ctx, host) => {
1402
- if (ctx.deps.getCanvasMode() === "stylebook") {
1406
+ /* A document's Elements view lists the element catalogue; every other view draws the tree,
1407
+ Variables and Code included. */
1408
+ if (ctx.deps.getCanvasMode() === PROJECT_STYLES_VIEW) {
1403
1409
  detachOutline();
1404
1410
  mountStylebookLayersPanel({ selectStylebookTag, stylebookMeta }, host);
1405
1411
  return;
@@ -76,7 +76,24 @@ export function mount(deps: NavigatorPanelDeps) {
76
76
  { panels: [panelView()] },
77
77
  {
78
78
  onContent: (panelId, host) => {
79
+ const switched = _content !== null && _content.panelId !== panelId;
79
80
  _content = { host, panelId };
81
+ /* `#left-panel` is the ONE scroller every panel draws in (the dock's root is `display:
82
+ contents`), so its offset outlived the panel it belonged to: scrolled down to the Site
83
+ panel's Components, a click on Outline opened the Outline that far down. A different
84
+ panel is a different list, and it opens at its top. A repaint of the same panel keeps
85
+ its place, because the box is keyed on the panel and is not announced again.
86
+ In the next FRAME, not here: this runs while the dock is still building the new panel,
87
+ and a scroll write lays out the half-built document to clamp the offset (a forced
88
+ recalculation on every Navigator panel switch in the perf trace). The frame lays it out
89
+ anyway, and resets the offset before anything is painted. */
90
+ if (switched) {
91
+ requestAnimationFrame(() => {
92
+ if (_content?.host === host) {
93
+ requireShellRef(leftPanel, "left-panel").scrollTop = 0;
94
+ }
95
+ });
96
+ }
80
97
  /* A MICROTASK, not this call. `onNodeCreated` fires the moment the element is CONSTRUCTED
81
98
  and the runtime applies its attributes on the next line, so a panel's `afterRender` run
82
99
  from here would be handed a content box with no `part` on it — and several panels find
@@ -93,20 +110,17 @@ export function mount(deps: NavigatorPanelDeps) {
93
110
  _scope = effectScope();
94
111
  _scope.run(() => {
95
112
  effect(() => {
96
- // Shell state is tracked with no tab open — which panel is showing, and the project-level
97
- // State the project-level panels draw from. A document-less rail tab still repaints.
113
+ // Shell state is tracked with no tab open: which panel is showing. A document-less rail tab
114
+ // Still repaints.
98
115
  void shell.leftTab;
99
- void shell.settingsTab;
100
- void shell.git.status;
101
- void shell.git.loading;
102
- void shell.git.error;
103
- void shell.git.subTab;
104
- void shell.git.logEntries;
105
116
  const tab = activeTab.value;
106
117
  if (tab) {
107
118
  // Track properties the Navigator's panels read
108
119
  void tab.doc.document;
109
120
  void tab.doc.mode;
121
+ // The editor too: the Outline draws the element catalogue beside a document's Elements
122
+ // View, and the tree beside every other.
123
+ void tab.session.ui.canvasMode;
110
124
  // The whole SET, joined — a bare property read would not re-trigger when the selection
111
125
  // Changes WITHIN the array, and §6.7's helpers always replace it but nothing enforces that.
112
126
  void tab.session.selection.map((path) => path.join("/")).join("|");
@@ -7,8 +7,10 @@
7
7
  * Nothing here decides what a panel is called, what level it is, or what it draws — that would be
8
8
  * the second definition site the registry exists to prevent.
9
9
  *
10
- * **Registration order is rail order** within a level group: PROJECT (Files ⌘1 · Search ⌘2 · Source
11
- * Control ⌘3) above the divider, DOCUMENT (Outline ⌘4 · Page ⌘5 · Data ⌘6 · Packages ⌘7) below it.
10
+ * **Registration order is rail order** within a level group: PROJECT (Site, then Files with the
11
+ * developer panels on) above the divider, DOCUMENT (Outline · Data, then Packages with the
12
+ * developer panels on) below it (§5.1). Search, Languages and Insert are registered rail-less:
13
+ * reachable by `view.setActivity` and the palette, with no button.
12
14
  *
13
15
  * **Every rail button opens the Navigator.** Problems used to hold the fourth PROJECT slot while
14
16
  * its body was drawn in the Bottom dock, and paying for that took a per-dock branch in three
@@ -17,21 +19,22 @@
17
19
  * The count reaches the user from the status bar the moment there is one.
18
20
  *
19
21
  * **Search is declared and hidden.** It is a surface a later phase builds (the palette's project
20
- * index), and it holds a slot in the rail's four-tab budget (`studio-ui-guidelines.md` §12.2). A
22
+ * index), and it is off the rail like every other panel the Design rail does not list (§5.1). A
21
23
  * `when: () => false` record is the honest way to say "this exists in the design and not yet in the
22
- * app": the id is reserved, the budget already counts it, and the day it ships the only edit is
23
- * deleting one predicate — as opposed to a stub button that lies to whoever clicks it.
24
+ * app": the id is reserved, and the day it ships the only edit is deleting one predicate — as
25
+ * opposed to a stub button that lies to whoever clicks it.
24
26
  */
25
27
 
26
28
  import { registerFilesPanel } from "../files/files";
27
29
  import { registerDataPanel } from "./data-explorer";
28
30
  import { registerInsertPanel } from "./elements-panel";
29
- import { registerGitPanel } from "./git-panel";
30
31
  import { registerI18nPanel } from "./i18n-panel";
31
- import { registerPagePanel } from "./head-panel";
32
32
  import { registerPackagesPanel } from "./imports-panel";
33
33
  import { registerBottomPanels } from "./bottom-dock";
34
34
  import { registerLayersPanel } from "./layers-panel";
35
+ import { registerSitePanel } from "./site-panel";
36
+ import { registerCollectionsPanel } from "./collections-panel";
37
+ import { registerStylesPanel } from "./styles-panel";
35
38
  import { getPanel, listPanels, railPanelSet, registerPanel, resetPanels } from "./panel-registry";
36
39
  import type { PanelRecord } from "./panel-registry";
37
40
 
@@ -45,14 +48,21 @@ const NOT_YET_BUILT = () => false;
45
48
  * per window in the app, but a test suite mounts it per case.
46
49
  */
47
50
  export function registerNavigatorPanels(): void {
48
- // Keyed on Files rather than on `listPanels("navigator")`, because the Bottom dock composes
51
+ // Keyed on Site rather than on `listPanels("navigator")`, because the Bottom dock composes
49
52
  // Itself independently (`bottomPanelSet()` calls `registerBottomPanels()` directly) and either
50
53
  // Order has to leave this function still registering the Navigator's own eight.
51
- if (getPanel("files")) {
54
+ if (getPanel("site")) {
52
55
  return;
53
56
  }
54
57
 
55
58
  // ── PROJECT group ───────────────────────────────────────────────────────────
59
+ registerSitePanel();
60
+ /* The Content workspace's Navigator (§22.5): off the rail, because Content draws none, and opened
61
+ by that workspace's frame. */
62
+ registerCollectionsPanel();
63
+ /* The Styles workspace's Navigator (§7.1): variables, element defaults and color schemes, off the
64
+ rail for the same reason. */
65
+ registerStylesPanel();
56
66
  registerFilesPanel();
57
67
  registerPanel({
58
68
  id: "search",
@@ -60,10 +70,13 @@ export function registerNavigatorPanels(): void {
60
70
  level: "project",
61
71
  dock: "navigator",
62
72
  icon: "magnifying-glass",
73
+ rail: false,
63
74
  when: NOT_YET_BUILT,
64
75
  render: () => nothingYet(),
65
76
  });
66
- registerGitPanel();
77
+ /* No Source Control panel: its change list, commit and branch picker are the Publish workspace's
78
+ Review changes and Branches (§5.5, §22.8), and a Navigator beside that workspace would be a
79
+ second list of the same things. */
67
80
  /* Off the rail, and registered in the PROJECT group anyway: registration order is roster order,
68
81
  so this is what puts Languages beside the panels it belongs with in the palette and in
69
82
  `panel.focus.*`. Its `when` is `project.isMultilingual` — a project written in one language
@@ -72,7 +85,6 @@ export function registerNavigatorPanels(): void {
72
85
 
73
86
  // ── DOCUMENT group ──────────────────────────────────────────────────────────
74
87
  registerLayersPanel();
75
- registerPagePanel();
76
88
  registerDataPanel();
77
89
  registerPackagesPanel();
78
90