@jxsuite/studio 6.1.1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -8,14 +8,14 @@
8
8
  * writing. A previewed SERP result is not a field; it is a picture you study, and studying it in a
9
9
  * strip above the canvas meant the card grew taller than the thing it describes.
10
10
  *
11
- * So it opens as a modal, from two places — the Document Header card and the Navigator's Page
12
- * panel. Two doors because the two are different moments: one while writing the page, one while
13
- * working on its head material. Both run `document.openSeo`, so there is a third door in the
14
- * palette and no surface owns the capability (one definition site per action, §13).
11
+ * So it opens as a modal, from the Inspector's Page tab (and, once, from the Document Header card
12
+ * Edit used to dock above the page, studio.md §4.2). The tab's button runs `document.openSeo`, so
13
+ * there is a second door in the palette and no surface owns the capability (one definition site per
14
+ * action, §13).
15
15
  *
16
- * **The card keeps the fields; the modal keeps the picture.** Title still lives on the card,
17
- * because it is the one head value you type while writing. Everything the modal holds is either a
18
- * rendering of what the build will emit or a field you set once and leave.
16
+ * **The Page tab keeps the fields; the modal keeps the picture.** Title lives on the tab, because
17
+ * it is the one head value you type while writing. Everything the modal holds is either a rendering
18
+ * of what the build will emit or a field you set once and leave.
19
19
  *
20
20
  * **This module is the flow; `surfaces/seo.json` is the markup.** What lives here is every
21
21
  * judgement the picture rests on: which realm a commit is written into, what each previewed line
@@ -24,30 +24,28 @@
24
24
  * decision — it holds the parts, the ARIA and the styling, and it branches on flags this module
25
25
  * hands it.
26
26
  *
27
- * The mutation path is the card's, unchanged: a markdown page commits through
28
- * `applyContentMutation` and a JSON one through `transact`, both taking the tab so the modal edits
29
- * the document it was opened over rather than whichever pane has focus.
27
+ * The mutation path is the Page tab's: a markdown page commits through `applyContentMutation` and a
28
+ * JSON one through `transact`, both taking the tab so the modal edits the document it was opened
29
+ * over rather than whichever pane has focus.
30
30
  *
31
31
  * @docs studio/editing/frontmatter
32
32
  */
33
33
 
34
34
  import { activeRegistry } from "../commands/active-registry";
35
+ import { HEAD_EDIT_DEBOUNCE } from "../ui/timing";
35
36
  import { previewAssetSrc } from "../canvas/asset-refs";
36
- import { getPlatform } from "../platform";
37
37
  import { layerHost } from "../ui/layers";
38
- import { mediaSiteUrl } from "../files/media-paths";
39
- import { openMenu } from "../surfaces/menu";
40
38
  import { openSeoSurface } from "../surfaces/seo";
41
39
  import { provenanceTitle } from "./provenance";
42
- import { PUBLIC_DIR } from "@jxsuite/schema/asset-paths";
43
- import { scanLibrary } from "../browse/library-model";
44
40
  import { tabLabel } from "./tab-strip";
45
41
  import { transact } from "../tabs/transact";
46
42
  import { activeTab } from "../workspace/workspace";
47
- import { MEDIA_EXTENSIONS, uploadAccept, uploadAssets } from "../files/media-upload";
43
+ import { pickAndUpload, showMediaPickerPopover } from "../ui/media-picker";
48
44
  import {
49
45
  OG_FIELDS,
50
46
  PAGE_FIELDS,
47
+ pageDescription,
48
+ setPageDescription,
51
49
  applyContentMutation,
52
50
  buildHeadDoc,
53
51
  findLinkEntry,
@@ -225,6 +223,11 @@ function writeField(
225
223
  applyMutation((doc: JxMutableNode) => upsertLink(doc, "icon", trimmed));
226
224
  return;
227
225
  }
226
+ if (key === "description") {
227
+ // The page's one description, written where the build reads it.
228
+ applyMutation((doc: JxMutableNode) => setPageDescription(doc, trimmed));
229
+ return;
230
+ }
228
231
  const field = META_BY_KEY.get(key);
229
232
  if (!field) {
230
233
  return;
@@ -232,15 +235,6 @@ function writeField(
232
235
  applyMutation((doc: JxMutableNode) => upsertMeta(doc, field.attr, field.key, trimmed));
233
236
  }
234
237
 
235
- /**
236
- * How long a keystroke waits before it is written.
237
- *
238
- * Every commit is a document mutation, and the previews repaint from it, so a write per keystroke
239
- * would redraw the picture mid-word. A `change` — the control losing focus, or its clear button —
240
- * cancels the timer and commits immediately, which is why nothing is ever lost to the debounce.
241
- */
242
- const EDIT_DEBOUNCE_MS = 300;
243
-
244
238
  /** One timer per field key, so editing Description then Title does not cancel the first write. */
245
239
  const _pending = new Map<string, ReturnType<typeof setTimeout>>();
246
240
 
@@ -260,35 +254,6 @@ function cancelPending(key?: string): void {
260
254
  }
261
255
  }
262
256
 
263
- // ─── The project's media ──────────────────────────────────────────────────────
264
-
265
- /** The listing, once. Invalidated by an upload, which is the only thing that changes it here. */
266
- let _media: string[] | null = null;
267
-
268
- /**
269
- * Every media file under `public/`, as the site URLs a pick would write.
270
- *
271
- * `browse/library-model.ts`'s walker rather than a second one: it is the scanner the Library pane
272
- * already runs over the same tree, it records what it could not read instead of swallowing it, and
273
- * it skips the directories nobody wants walked. The site URL is the authored form — what production
274
- * serves — and `files/media-paths.ts` holds the one definition of that mapping.
275
- */
276
- async function mediaChoices(): Promise<string[]> {
277
- if (_media) {
278
- return _media;
279
- }
280
- const { files } = await scanLibrary([PUBLIC_DIR], getPlatform());
281
- _media = files
282
- .filter((file) => MEDIA_EXTENSIONS.has(file.ext))
283
- .map((file) => mediaSiteUrl(file.path));
284
- return _media;
285
- }
286
-
287
- /** Forget the listing: it was derived from a tree an upload has just changed. */
288
- function invalidateMediaChoices(): void {
289
- _media = null;
290
- }
291
-
292
257
  // ─── The modal ───────────────────────────────────────────────────────────────
293
258
 
294
259
  /** The open surface, or `null`. One at a time: it is about the focused document. */
@@ -300,20 +265,24 @@ let _tab: Tab | null = null;
300
265
  /** Where each chip that leads somewhere goes, rebuilt with the view it was drawn from. */
301
266
  let _donors = new Map<string, () => void>();
302
267
 
268
+ /** What the SEO body reads and writes for one tab: its merged head, and how an edit lands. */
269
+ interface SeoContext {
270
+ headDoc: JxMutableNode;
271
+ head: JxHeadEntry[];
272
+ applyMutation: (fn: (doc: JxMutableNode) => void) => void;
273
+ }
274
+
303
275
  /**
304
276
  * What the SEO body needs from a tab, resolved once.
305
277
  *
306
278
  * Both realms in one place: a markdown page keeps its head material in frontmatter and a JSON one
307
279
  * in root properties, and `buildHeadDoc` is the card's own view of that difference.
308
280
  */
309
- function seoContextFor(tab: Tab): {
310
- headDoc: JxMutableNode;
311
- head: JxHeadEntry[];
312
- applyMutation: (fn: (doc: JxMutableNode) => void) => void;
313
- } {
281
+ function seoContextFor(tab: Tab): SeoContext {
314
282
  const isContent = tab.doc.mode === "content";
315
- const fm = (tab.doc.content?.frontmatter ?? {}) as Record<string, unknown>;
316
- const headDoc = isContent ? buildHeadDoc(tab.doc.document, fm) : tab.doc.document;
283
+ const headDoc = isContent
284
+ ? buildHeadDoc(tab.doc.document, tab.doc.content.frontmatter)
285
+ : tab.doc.document;
317
286
  return {
318
287
  applyMutation: isContent
319
288
  ? (fn: (doc: JxMutableNode) => void) => applyContentMutation(tab, renderSeoModal, fn)
@@ -363,9 +332,12 @@ function buildView(tab: Tab, headDoc: JxMutableNode, head: JxHeadEntry[]): SeoVi
363
332
  note: "",
364
333
  rows: [
365
334
  ...PAGE_FIELDS.map((field) =>
366
- editRow(field.key, field.label, metaValue(head, field.key), {
367
- multiline: field.multiline,
368
- }),
335
+ editRow(
336
+ field.key,
337
+ field.label,
338
+ field.key === "description" ? pageDescription(headDoc) : metaValue(head, field.key),
339
+ { multiline: field.multiline },
340
+ ),
369
341
  ),
370
342
  editRow(ICON_KEY, "Icon", iconHref, { media: true }),
371
343
  ],
@@ -413,69 +385,26 @@ function commitField(key: string, value: string): void {
413
385
  renderSeoModal();
414
386
  }
415
387
 
416
- /** Open the OS file picker for a media row, and assign the first file it returns. */
388
+ /**
389
+ * Upload into a media row: the image field's own Upload (`ui/media-picker.ts`), which opens the
390
+ * picker, uploads through the one core, and hands the first file's ref back. A commit that lands
391
+ * after the modal closed writes nothing, because {@link commitField} is about the open modal.
392
+ */
417
393
  function uploadInto(key: string): void {
418
- /* The input is created per click and discarded after: a hidden one kept in the document would be
419
- a node the surface owns outside its own document, which is exactly what a surface may not
420
- have. */
421
- const input = document.createElement("input");
422
- input.type = "file";
423
- input.multiple = true;
424
- input.accept = uploadAccept();
425
- input.addEventListener("change", () => {
426
- if (!input.files?.length) {
427
- return;
428
- }
429
- void uploadAssets([...input.files]).then((uploaded) => {
430
- invalidateMediaChoices();
431
- const [first] = uploaded;
432
- if (first) {
433
- commitField(key, first.ref);
434
- }
435
- });
436
- });
437
- input.click();
394
+ pickAndUpload((ref: string) => commitField(key, ref));
438
395
  }
439
396
 
440
397
  /**
441
- * Offer the project's media for one row.
398
+ * Offer the project's images for one row: the media picker's own compact browser, with its **Browse
399
+ * all images…** row opening the Media workspace's surface in pick mode.
442
400
  *
443
- * A kit menu rather than the Spectrum popover `ui/media-picker.ts` draws, and it has to be: a modal
444
- * `<dialog>` is in the top layer, so an overlay painted into a layer div renders UNDERNEATH the
445
- * dialog that opened it and is inert besides (`specs/ui.md` §7). The menu is shown with the Browse
446
- * button as its `source`, which is what puts it in the dialog's own top-layer hierarchy.
401
+ * Not a list of this module's own. It kept one (a walk of `public/` alone, and a kit menu of site
402
+ * URLs) because the old picker painted into a layer div UNDER the modal; the browser is a top-layer
403
+ * `jx-popover` now, so it paints over the modal that opened it, and the field and this dialog
404
+ * answer "what media does this project have" from the same listing (studio.md §9.3).
447
405
  */
448
406
  function browseFor(key: string, anchor: HTMLElement): void {
449
- void mediaChoices().then((choices) => {
450
- openMenu({
451
- label: "Project media",
452
- opener: anchor,
453
- region: "seo-media",
454
- rows:
455
- choices.length > 0
456
- ? choices.map((path) => ({
457
- destructive: false,
458
- disabled: false,
459
- dividerAbove: false,
460
- id: path,
461
- run: () => commitField(key, path),
462
- /* The site URL rather than the file name, because it is the string the pick writes
463
- AND the only one of the two that is unique: two `hero.jpg`s in two directories are
464
- one row twice over in a list that shows names. */
465
- title: path,
466
- }))
467
- : [
468
- {
469
- destructive: false,
470
- disabled: true,
471
- dividerAbove: false,
472
- id: "seo.media.empty",
473
- requires: "a file under public/",
474
- title: "No media in this project",
475
- },
476
- ],
477
- });
478
- });
407
+ showMediaPickerPopover(anchor, (ref: string) => commitField(key, ref), { images: true });
479
408
  }
480
409
 
481
410
  /** Open it over `tab`. Idempotent — opening it again re-points it at the current document. */
@@ -495,7 +424,7 @@ export function openSeoModal(tab: Tab): void {
495
424
  setTimeout(() => {
496
425
  _pending.delete(key);
497
426
  commitField(key, value);
498
- }, EDIT_DEBOUNCE_MS),
427
+ }, HEAD_EDIT_DEBOUNCE),
499
428
  );
500
429
  },
501
430
  onOpenDonor: (key: string) => {
@@ -533,10 +462,10 @@ export function closeSeoModal(): void {
533
462
  /**
534
463
  * `document.openSeo` — the one capability behind both buttons.
535
464
  *
536
- * The Document Header card and the Page panel each render a control that runs this, so neither owns
537
- * it and the palette has it by name. A record rather than two click handlers, for the reason the
538
- * rendering-context axes became records: a surface that IS the capability is a capability the
539
- * palette, the assistant and `__jxAutomation` cannot reach.
465
+ * The Page tab renders a control that runs this, so it does not own it and the palette has it by
466
+ * name. A record rather than two click handlers, for the reason the rendering-context axes became
467
+ * records: a surface that IS the capability is a capability the palette, the assistant and
468
+ * `__jxAutomation` cannot reach.
540
469
  *
541
470
  * @returns {AnyCommand[]}
542
471
  */
@@ -1,35 +1,37 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * The rail foot's ⚙ Settings menu — a RENDERING of the `settings/menu` placement.
3
+ * The top bar's ⚙ Settings menu — a RENDERING of the `settings/menu` placement.
4
4
  *
5
5
  * The gear used to run one command. That was the right shape for a pinned slot and the wrong shape
6
- * for the question people bring to it: Studio has two settings families at two containment levels —
7
- * `app.preferences` (the application, ⌘,) and `settings.open` (this project, ⌘⇧,) — plus a third
8
- * editor over the same project document, `styles.open`. A slot can hold one of those and must lie
9
- * about the rest by omission. A menu can hold all three and say what each one is, because it prints
10
- * every row's own name, chord and gate beside it (`studio-ui-guidelines.md` §12.3). That is the
11
- * whole argument for the matrix row `settings/menu` admitting two levels, and for the divider this
12
- * file draws where the level changes.
6
+ * for the question people bring to it: Studio has two settings families at two containment levels,
7
+ * `app.preferences` (the application, ⌘,) and `settings.open` (this project, ⌘⇧,). A slot can hold
8
+ * one of those and must lie about the other by omission. A menu can hold both and say what each one
9
+ * is, because it prints every row's own name, chord and gate beside it (`studio-ui-guidelines.md`
10
+ * §12.3). That is the whole argument for the matrix row `settings/menu` admitting two levels, and
11
+ * for the divider this file draws where the level changes. Project Styles is not here: Styles is a
12
+ * workspace, and the top bar already names it.
13
13
  *
14
14
  * **Nothing here is a list of actions.** The rows are `registry.forPlacement("settings/menu")`, so
15
15
  * a record joins the menu by declaring the placement and leaves by not declaring it. The submenus
16
16
  * are the enumeration of each parent command's own `section` ARGUMENT, read from that argument's
17
17
  * own definition site — which is state the command already validates, not a second vocabulary
18
- * (`studio-ui-guidelines.md` §12.5).
18
+ * (`studio-ui-guidelines.md` §12.5). Project Settings' submenu is GROUPED as its dialog's nav is
19
+ * (General, Integrations, Advanced), with a divider where the group changes.
19
20
  *
20
21
  * **A parent row runs its own command AND owns a submenu.** The APG menu pattern does not describe
21
22
  * that and Spectrum's stock submenu forbade it outright; the kit's `jx-menu-item` makes it the rule
22
23
  * (`ui.md` §5.1), so the deviation `specs/studio-ui-guidelines.md` §8.4 records is now what the
23
24
  * element does rather than what this file hand-rolls around it. Nothing is unreachable by keyboard:
24
25
  * Enter runs the row, ArrowRight reaches every child, and every child is also in the settings
25
- * document's own inner nav.
26
+ * dialog's own nav.
26
27
  *
27
28
  * The menu is the `menu` surface (`surfaces/menu.json`, through `surfaces/menu.ts`). What is left
28
29
  * here is the projection — which records, which sections, what each row runs — and where the panel
29
- * hangs: off the gear's right edge, its bottom flush with the rail's, which is also the floor every
30
- * submenu keeps above the status bar. The section subscription lives for as long as the menu is up:
31
- * six of Project Settings' sections are contributed by extensions and register a tick after the
32
- * built-ins (`settings/extension-sections.ts`), so a menu opened in that window would otherwise be
30
+ * hangs: below the gear, right-aligned to it. The gear moved from the rail's foot to the top bar
31
+ * because the rail is drawn only in the Design workspace, and the settings are every workspace's.
32
+ * The section subscription lives for as long as the menu is up: six of Project Settings' sections
33
+ * are contributed by extensions and register a tick after the built-ins
34
+ * (`settings/extension-sections.ts`), so a menu opened in that window would otherwise be
33
35
  * permanently short. It deliberately does NOT call the sync itself: opening a menu must not do IO.
34
36
  *
35
37
  * @docs studio/interface/preferences
@@ -39,25 +41,25 @@
39
41
  import { activeRegistry } from "../commands/active-registry";
40
42
  import { runReported } from "../commands/run-reported";
41
43
  import { LEVELS } from "../commands/levels";
42
- import { onSettingsDocumentChanged, sortedSettingsSections } from "../settings/section-registry";
44
+ import { groupedSettingsSections, onSettingsDocumentChanged } from "../settings/section-registry";
43
45
  import { PREFERENCES_SECTIONS } from "../settings/preferences-sections";
44
46
  import { openMenu } from "../surfaces/menu";
45
- import { REGION_ATTR } from "../ui/regions";
46
47
  import { rectOf } from "../utils/geometry";
47
48
 
49
+ import type { CommandArgValues } from "../commands/command-args";
48
50
  import type { CommandRegistry } from "../commands/registry";
49
51
  import type { Level } from "../commands/levels";
50
52
  import type { MenuHandle, MenuRowProjection } from "../surfaces/menu";
53
+ import type { KeyedLabel } from "../ui/surface";
51
54
 
52
- /** The placement the rail's gear renders. One definition site for the string. */
53
- export const SETTINGS_MENU_PLACEMENT = "settings/menu" as const;
54
-
55
- /** One value a parent command's `section` argument accepts. */
56
- interface MenuSection {
57
- key: string;
58
- label: string;
55
+ /** One submenu row's source: the argument value, its label, and whether a new group starts here. */
56
+ interface SectionRow extends KeyedLabel {
57
+ dividerAbove: boolean;
59
58
  }
60
59
 
60
+ /** The placement the top bar's gear renders. One definition site for the string. */
61
+ export const SETTINGS_MENU_PLACEMENT = "settings/menu" as const;
62
+
61
63
  let _menu: MenuHandle | null = null;
62
64
  let _unsubscribe: (() => void) | null = null;
63
65
  let _rerender: (() => void) | null = null;
@@ -73,16 +75,32 @@ let _rerender: (() => void) | null = null;
73
75
  * `settings.open` refuses anything absent from `settingsSectionKeys()` — so a submenu row can never
74
76
  * name a value its own command would refuse.
75
77
  */
76
- const SECTION_SOURCES: Readonly<Record<string, () => readonly MenuSection[]>> = {
77
- "app.preferences": () =>
78
- PREFERENCES_SECTIONS.map((section) => ({ key: section.id, label: section.title })),
79
- "settings.open": () =>
80
- sortedSettingsSections().map((section) => ({ key: section.key, label: section.label })),
81
- };
78
+ const SECTION_SOURCES: ReadonlyMap<string, () => readonly SectionRow[]> = new Map([
79
+ [
80
+ "app.preferences",
81
+ () =>
82
+ PREFERENCES_SECTIONS.map((section) => ({
83
+ dividerAbove: false,
84
+ key: section.id,
85
+ label: section.title,
86
+ })),
87
+ ],
88
+ [
89
+ "settings.open",
90
+ () =>
91
+ groupedSettingsSections().flatMap((group, groupIndex) =>
92
+ group.sections.map((section, index) => ({
93
+ dividerAbove: groupIndex > 0 && index === 0,
94
+ key: section.key,
95
+ label: section.label,
96
+ })),
97
+ ),
98
+ ],
99
+ ]);
82
100
 
83
101
  /** The sections a row offers, or none. */
84
- function menuSectionsFor(id: string): readonly MenuSection[] {
85
- return SECTION_SOURCES[id]?.() ?? [];
102
+ function menuSectionsFor(id: string): readonly SectionRow[] {
103
+ return SECTION_SOURCES.get(id)?.() ?? [];
86
104
  }
87
105
 
88
106
  // ─── Running ──────────────────────────────────────────────────────────────────
@@ -95,7 +113,7 @@ function menuSectionsFor(id: string): readonly MenuSection[] {
95
113
  * click throws BEFORE `run`, synchronously. `commands/run-reported.ts` catches both and files the
96
114
  * sentence in Problems, under this menu's name.
97
115
  */
98
- function runRow(id: string, args?: Record<string, unknown>): void {
116
+ function runRow(id: string, args?: CommandArgValues): void {
99
117
  const registry = activeRegistry();
100
118
  if (!registry) {
101
119
  return;
@@ -134,7 +152,7 @@ function buildSettingsMenuRows(registry: CommandRegistry): MenuRowProjection[] {
134
152
  ? menuSectionsFor(id).map((section) => ({
135
153
  destructive: false,
136
154
  disabled: false,
137
- dividerAbove: false,
155
+ dividerAbove: section.dividerAbove,
138
156
  id: `${id}:${section.key}`,
139
157
  // Named by the argument value it passes, never by a reworded command title.
140
158
  run: () => runRow(id, { section: section.key }),
@@ -161,26 +179,9 @@ function buildSettingsMenuRows(registry: CommandRegistry): MenuRowProjection[] {
161
179
  });
162
180
  }
163
181
 
164
- // ─── Geometry ─────────────────────────────────────────────────────────────────
165
-
166
- /**
167
- * The lowest edge any menu in this stack may reach.
168
- *
169
- * The trigger's REGION, not the viewport. The gear sits in the rail, whose bottom is the status
170
- * bar's top — so clamping to the viewport would let a tall submenu run down over the status bar
171
- * while the root menu sits neatly above it. One floor for both levels is what keeps the stack
172
- * looking like one surface, and it is expressed through the shell's own addressing grammar rather
173
- * than a selector into markup — so a menu button in another region would align to that one without
174
- * this function learning about it.
175
- */
176
- function menuFloor(anchor: HTMLElement): number {
177
- const host = anchor.closest<HTMLElement>(`[${REGION_ATTR}]`);
178
- return host ? rectOf(host).bottom : window.innerHeight;
179
- }
180
-
181
182
  // ─── Public surface ───────────────────────────────────────────────────────────
182
183
 
183
- /** Whether the gear menu is on screen. The rail reads it for `aria-expanded`. */
184
+ /** Whether the gear menu is on screen. The top bar reads it for `aria-expanded`. */
184
185
  export function isSettingsMenuOpen(): boolean {
185
186
  return _menu !== null;
186
187
  }
@@ -197,7 +198,7 @@ export function dismissSettingsMenu(): void {
197
198
  * class stay lit BINDINGS rather than imperative attribute writes; a stale `aria-expanded` is a
198
199
  * defect this app has shipped before. Same seam as `showContextMenu(e, path, { rerender })`.
199
200
  *
200
- * @param anchor The control the menu hangs off — the rail's gear.
201
+ * @param anchor The control the menu hangs off — the top bar's gear.
201
202
  */
202
203
  export function openSettingsMenu(anchor: HTMLElement, opts: { rerender?: () => void } = {}): void {
203
204
  if (_menu) {
@@ -213,9 +214,7 @@ export function openSettingsMenu(anchor: HTMLElement, opts: { rerender?: () => v
213
214
  return;
214
215
  }
215
216
  _rerender = opts.rerender ?? null;
216
- const floor = (): number => menuFloor(anchor);
217
217
  const handle = openMenu({
218
- floor,
219
218
  label: "Settings",
220
219
  onClosed: (closedHandle) => {
221
220
  if (_menu !== closedHandle) {
@@ -230,13 +229,16 @@ export function openSettingsMenu(anchor: HTMLElement, opts: { rerender?: () => v
230
229
  rerender?.();
231
230
  },
232
231
  opener: anchor,
233
- /* Hanging off the trigger's right edge, with its BOTTOM flush with the bottom of the region the
234
- trigger lives in. Not "below the trigger": the gear is the last control in a full-height rail
235
- whose foot abuts the status bar, so a menu dropped below it would be off-screen, and one
236
- aligned to the button would float six pixels of `.rail-footer` padding clear of the status
237
- bar. Floored at 4, because Project Settings has ~16 sections once extensions have contributed
238
- and a menu taller than the area must keep its FIRST rows on screen. */
239
- place: (box) => ({ x: rectOf(anchor).right + 4, y: Math.max(4, floor() - box.height) }),
232
+ /* Below the gear, its RIGHT edge flush with the gear's. The gear sits at the right-hand end of
233
+ the top bar, just before the dock toggles, so a menu hanging from its left edge would run off
234
+ the window; right-aligning it is a function of the menu's own width, which is why this is a
235
+ `place` callback run once the panel has been laid out. Floored at 4 on the left, so a menu
236
+ wider than the space to the gear's left keeps its leading edge on screen. */
237
+ place: (box) => {
238
+ const gear = rectOf(anchor);
239
+ return { x: Math.max(4, gear.right - box.width), y: gear.bottom + 4 };
240
+ },
241
+ placement: "block-end span-inline-start",
240
242
  region: "settings",
241
243
  rows,
242
244
  });