@jxsuite/studio 6.1.0 → 6.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (645) hide show
  1. package/dist/chunks/2020-f2gkpy8d.js +4 -0
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-5g0ag7c0.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-pxg4ap1e.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-qbj760tx.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-anyrgzvb.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-v2bvmbjj.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-txjjzrsm.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-cpxkgjrj.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/studio-y64hrt8p.js +12 -0
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/tsMode-sf49ee9x.js +14 -0
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +98 -98
  140. package/dist/workers/ts.worker.js +3 -3
  141. package/package.json +11 -11
  142. package/src/about/about-modal.ts +4 -3
  143. package/src/account/action-flow.ts +45 -38
  144. package/src/account-status.ts +7 -2
  145. package/src/browse/library-layouts.ts +8 -5
  146. package/src/browse/library-model.ts +18 -6
  147. package/src/browse/library-pane.ts +37 -21
  148. package/src/browse/library-preview.ts +14 -9
  149. package/src/browse/library-source.ts +1 -1
  150. package/src/canvas/asset-refs.ts +24 -9
  151. package/src/canvas/asset-resolve.ts +19 -23
  152. package/src/canvas/canvas-helpers.ts +7 -6
  153. package/src/canvas/canvas-live-render.ts +44 -53
  154. package/src/canvas/canvas-patcher.ts +30 -30
  155. package/src/canvas/canvas-perf.ts +11 -5
  156. package/src/canvas/canvas-render.ts +66 -42
  157. package/src/canvas/canvas-surface.ts +5 -3
  158. package/src/canvas/canvas-utils.ts +163 -64
  159. package/src/canvas/dialog-path.ts +9 -4
  160. package/src/canvas/dialog-state.ts +1 -2
  161. package/src/canvas/diff-marks.ts +9 -16
  162. package/src/canvas/diff-toolbar.ts +8 -7
  163. package/src/canvas/edit-width-drag.ts +4 -1
  164. package/src/canvas/edit-width.ts +1 -3
  165. package/src/canvas/iframe-channel.ts +27 -13
  166. package/src/canvas/iframe-drop.ts +13 -12
  167. package/src/canvas/iframe-editable-root.ts +29 -16
  168. package/src/canvas/iframe-entry.ts +80 -63
  169. package/src/canvas/iframe-eval.ts +73 -49
  170. package/src/canvas/iframe-host.ts +203 -118
  171. package/src/canvas/iframe-inline-edit.ts +69 -32
  172. package/src/canvas/iframe-insert.ts +5 -4
  173. package/src/canvas/iframe-interaction.ts +37 -26
  174. package/src/canvas/iframe-overlay.ts +1 -1
  175. package/src/canvas/iframe-patch.ts +18 -15
  176. package/src/canvas/iframe-position.ts +12 -6
  177. package/src/canvas/iframe-protocol.ts +15 -16
  178. package/src/canvas/iframe-render.ts +41 -36
  179. package/src/canvas/iframe-slash.ts +24 -11
  180. package/src/canvas/iframe-subtree.ts +6 -2
  181. package/src/canvas/path-mapping.ts +19 -12
  182. package/src/canvas/popover-path.ts +7 -3
  183. package/src/canvas/popover-state.ts +1 -2
  184. package/src/canvas/serialize-scope.ts +13 -5
  185. package/src/canvas/stage-scrollbar.ts +2 -1
  186. package/src/canvas/surface-registry.ts +21 -3
  187. package/src/collab/collab-commands.ts +7 -2
  188. package/src/collab/collab-session.ts +84 -45
  189. package/src/collab/collab-state.ts +4 -3
  190. package/src/collab/monaco-binding.ts +16 -13
  191. package/src/collab/monaco-cursors.ts +5 -2
  192. package/src/commands/budget.ts +3 -3
  193. package/src/commands/command-args.ts +103 -71
  194. package/src/commands/context.ts +22 -20
  195. package/src/commands/defaults.ts +4 -1
  196. package/src/commands/keymap.ts +47 -43
  197. package/src/commands/levels.ts +3 -3
  198. package/src/commands/live-context.ts +10 -8
  199. package/src/commands/reference.ts +2 -1
  200. package/src/commands/registry.ts +12 -10
  201. package/src/commands/run-reported.ts +15 -10
  202. package/src/component-props.ts +46 -30
  203. package/src/content/collection-match.ts +5 -4
  204. package/src/content/draft-state.ts +4 -3
  205. package/src/content/entry-commands.ts +3 -2
  206. package/src/content/entry-editor.ts +29 -17
  207. package/src/content/entry-fields.ts +12 -7
  208. package/src/content/entry-model.ts +21 -12
  209. package/src/editor/canvas-context-menu.ts +1 -2
  210. package/src/editor/canvas-slash-bridge.ts +3 -6
  211. package/src/editor/content-slice.ts +16 -14
  212. package/src/editor/context-menu.ts +35 -22
  213. package/src/editor/convert-targets.ts +30 -35
  214. package/src/editor/convert-to-component.ts +11 -5
  215. package/src/editor/convert-to-repeater.ts +34 -22
  216. package/src/editor/editable-tags.ts +17 -2
  217. package/src/editor/file-drop-action.ts +21 -22
  218. package/src/editor/inline-edit-apply.ts +35 -17
  219. package/src/editor/inline-edit.ts +66 -50
  220. package/src/editor/inline-format.ts +59 -56
  221. package/src/editor/inline-link.ts +40 -15
  222. package/src/editor/insert-zone-action.ts +1 -1
  223. package/src/editor/merge-tags.ts +58 -19
  224. package/src/editor/repeater-scope.ts +39 -28
  225. package/src/editor/shortcuts.ts +87 -47
  226. package/src/editor/slash-menu.ts +1 -6
  227. package/src/files/asset-versions.ts +4 -4
  228. package/src/files/components.ts +15 -10
  229. package/src/files/elements.ts +5 -6
  230. package/src/files/file-ops.ts +77 -36
  231. package/src/files/files.ts +90 -95
  232. package/src/files/media-meta.ts +2 -1
  233. package/src/files/media-paths.ts +6 -1
  234. package/src/files/serialize-document.ts +2 -2
  235. package/src/format/constraints.ts +1 -1
  236. package/src/format/convert-file.ts +27 -13
  237. package/src/format/format-choices.ts +2 -1
  238. package/src/format/format-host.ts +76 -50
  239. package/src/github/github-auth-status.ts +27 -3
  240. package/src/github/github-auth.ts +19 -9
  241. package/src/github/github-publish.ts +24 -20
  242. package/src/grid/cell-editors.ts +46 -31
  243. package/src/grid/cell-popovers.ts +5 -3
  244. package/src/grid/edit-buffer.ts +10 -9
  245. package/src/grid/grid-controller.ts +20 -22
  246. package/src/grid/grid-layout.ts +21 -5
  247. package/src/grid/grid-open.ts +3 -6
  248. package/src/grid/grid-panel.ts +11 -4
  249. package/src/grid/grid-source.ts +8 -8
  250. package/src/grid/grid-view.ts +14 -17
  251. package/src/grid/redirects-grid.ts +14 -5
  252. package/src/grid/redirects.ts +16 -14
  253. package/src/grid/schema-columns.ts +25 -19
  254. package/src/grid/sources/connector-source.ts +47 -20
  255. package/src/grid/sources/content-source.ts +25 -24
  256. package/src/grid/sources/csv-file-source.ts +2 -2
  257. package/src/grid/tabulator-tables.d.ts +55 -34
  258. package/src/hosting/stage.ts +7 -7
  259. package/src/i18n/i18n-commands.ts +1 -2
  260. package/src/media/media-pane.ts +4 -1
  261. package/src/new-project/add-repo-modal.ts +20 -19
  262. package/src/new-project/import-tab.ts +10 -14
  263. package/src/new-project/location-fields.ts +2 -1
  264. package/src/new-project/new-project-modal.ts +12 -9
  265. package/src/packages/jxsuite-update.ts +4 -3
  266. package/src/packages/pull-package-sync.ts +26 -25
  267. package/src/page-params.ts +97 -68
  268. package/src/panels/activity-panel.ts +17 -9
  269. package/src/panels/ai-chat/attached-context.ts +13 -7
  270. package/src/panels/ai-chat/chat-view.ts +80 -73
  271. package/src/panels/ai-chat/composer.ts +30 -33
  272. package/src/panels/ai-chat/sessions-view.ts +1 -2
  273. package/src/panels/ai-panel.ts +23 -20
  274. package/src/panels/block-action-bar.ts +46 -35
  275. package/src/panels/bottom-dock.ts +5 -3
  276. package/src/panels/canvas-dnd-bridge.ts +31 -24
  277. package/src/panels/data-explorer.ts +62 -25
  278. package/src/panels/data-grid.ts +14 -11
  279. package/src/panels/dnd.ts +108 -118
  280. package/src/panels/editors.ts +55 -22
  281. package/src/panels/elements-panel.ts +10 -3
  282. package/src/panels/events-panel.ts +84 -69
  283. package/src/panels/formula-workspace.ts +76 -51
  284. package/src/panels/frontmatter-fields.ts +24 -19
  285. package/src/panels/frontmatter-panel.ts +44 -34
  286. package/src/panels/git-diff-open.ts +4 -4
  287. package/src/panels/git-panel.ts +49 -61
  288. package/src/panels/head-panel.ts +131 -111
  289. package/src/panels/i18n-panel.ts +10 -3
  290. package/src/panels/imports-panel.ts +23 -47
  291. package/src/panels/jump-bar.ts +48 -29
  292. package/src/panels/layers-panel.ts +97 -74
  293. package/src/panels/left-panel.ts +3 -3
  294. package/src/panels/pane-context.ts +31 -22
  295. package/src/panels/pane-grid.ts +49 -20
  296. package/src/panels/panel-registry.ts +22 -37
  297. package/src/panels/properties-panel.ts +175 -121
  298. package/src/panels/quick-search.ts +53 -31
  299. package/src/panels/right-panel.ts +3 -3
  300. package/src/panels/seo-modal.ts +13 -17
  301. package/src/panels/settings-menu.ts +15 -15
  302. package/src/panels/signals-panel.ts +153 -131
  303. package/src/panels/statement-editor.ts +230 -140
  304. package/src/panels/style-panel.ts +254 -216
  305. package/src/panels/style-utils.ts +114 -51
  306. package/src/panels/stylebook-doc.ts +57 -54
  307. package/src/panels/stylebook-layers-panel.ts +9 -9
  308. package/src/panels/stylebook-panel.ts +13 -17
  309. package/src/panels/tab-drop.ts +27 -11
  310. package/src/panels/tab-strip.ts +36 -26
  311. package/src/platform-errors.ts +57 -43
  312. package/src/platform.ts +58 -30
  313. package/src/platforms/cloud.ts +345 -175
  314. package/src/platforms/default-platform.ts +10 -4
  315. package/src/platforms/devserver.ts +174 -127
  316. package/src/platforms/read-batcher.ts +16 -8
  317. package/src/project-list.ts +2 -1
  318. package/src/publish/deploy-checklist.ts +8 -2
  319. package/src/publish/pages-service.ts +28 -13
  320. package/src/publish/publish-commands.ts +5 -4
  321. package/src/publish/publish-panel.ts +10 -6
  322. package/src/recent-projects.ts +15 -8
  323. package/src/resize-edges.ts +26 -36
  324. package/src/services/a11y-report.ts +26 -19
  325. package/src/services/agent-seed.ts +23 -11
  326. package/src/services/ai-ask.ts +9 -12
  327. package/src/services/ai-command-tools.ts +68 -62
  328. package/src/services/ai-import-tools.ts +80 -67
  329. package/src/services/ai-models.ts +17 -13
  330. package/src/services/ai-project-tools.ts +68 -32
  331. package/src/services/ai-session-store.ts +19 -10
  332. package/src/services/ai-system-prompt.ts +46 -20
  333. package/src/services/ai-tools.ts +71 -27
  334. package/src/services/ai-write-report.ts +20 -12
  335. package/src/services/ai-writes.ts +4 -4
  336. package/src/services/automation.ts +58 -31
  337. package/src/services/cem-export.ts +149 -58
  338. package/src/services/clock.ts +6 -1
  339. package/src/services/code-services.ts +37 -31
  340. package/src/services/context-manager.ts +14 -10
  341. package/src/services/context-resolver.ts +20 -8
  342. package/src/services/data-service.ts +19 -15
  343. package/src/services/directory-picker.ts +18 -12
  344. package/src/services/document-assistant.ts +39 -19
  345. package/src/services/gated-registry.ts +10 -6
  346. package/src/services/harness/chat-reducer.ts +23 -1
  347. package/src/services/import-client.ts +91 -38
  348. package/src/services/import-seed.ts +8 -2
  349. package/src/services/jx-validate.ts +28 -31
  350. package/src/services/live-preview.ts +0 -0
  351. package/src/services/live-surfaces.ts +6 -3
  352. package/src/services/model-uri.ts +10 -2
  353. package/src/services/module-preloads.ts +12 -8
  354. package/src/services/monaco-buffer.ts +43 -24
  355. package/src/services/monaco-lazy.ts +7 -8
  356. package/src/services/monaco-setup.ts +23 -16
  357. package/src/services/notify.ts +44 -17
  358. package/src/services/popover-report.ts +25 -10
  359. package/src/services/preview-eval.ts +20 -8
  360. package/src/services/profile.ts +13 -6
  361. package/src/services/project-path.ts +13 -10
  362. package/src/services/references.ts +0 -0
  363. package/src/services/render-critic.ts +8 -7
  364. package/src/services/settings/kernel.ts +13 -4
  365. package/src/services/settings/write-queue.ts +9 -9
  366. package/src/services/token-lint.ts +12 -10
  367. package/src/services/tool-executor.ts +17 -5
  368. package/src/services/tool-outcomes.ts +44 -24
  369. package/src/services/trusted-types.ts +24 -7
  370. package/src/settings/contexts-section.ts +11 -8
  371. package/src/settings/contributed-section.ts +79 -60
  372. package/src/settings/css-vars-editor.ts +37 -16
  373. package/src/settings/defs-editor.ts +38 -35
  374. package/src/settings/extension-rows.ts +16 -8
  375. package/src/settings/extension-sections.ts +23 -13
  376. package/src/settings/extensions-section.ts +4 -1
  377. package/src/settings/general-settings.ts +11 -8
  378. package/src/settings/locales-section.ts +20 -12
  379. package/src/settings/preferences-dialog.ts +9 -6
  380. package/src/settings/preferences-keymap.ts +7 -5
  381. package/src/settings/preferences-sections.ts +11 -5
  382. package/src/settings/project-sections.ts +1 -1
  383. package/src/settings/schema-field-ui.ts +9 -0
  384. package/src/settings/settings-document.ts +5 -5
  385. package/src/shell/tree.ts +6 -5
  386. package/src/shell.ts +104 -81
  387. package/src/site-context.ts +37 -22
  388. package/src/state.ts +41 -49
  389. package/src/store.ts +54 -34
  390. package/src/studio.ts +39 -77
  391. package/src/style/live-preview.ts +1 -1
  392. package/src/style/project-styles.ts +6 -7
  393. package/src/style/token-ref.ts +5 -4
  394. package/src/surfaces/about.ts +18 -19
  395. package/src/surfaces/add-repo.ts +17 -19
  396. package/src/surfaces/ai-chat.ts +31 -36
  397. package/src/surfaces/ai-credentials-form.ts +6 -16
  398. package/src/surfaces/ai-managed-connect.ts +3 -4
  399. package/src/surfaces/ai-model-picker.ts +3 -5
  400. package/src/surfaces/block-action-bar.ts +22 -11
  401. package/src/surfaces/boot-failure.ts +4 -5
  402. package/src/surfaces/bottom-dock.ts +9 -18
  403. package/src/surfaces/canvas-stage.ts +12 -11
  404. package/src/surfaces/cf-account-picker.ts +17 -18
  405. package/src/surfaces/commandbar.ts +14 -9
  406. package/src/surfaces/convert-repeater.ts +17 -19
  407. package/src/surfaces/data-actions.ts +9 -7
  408. package/src/surfaces/dialog.ts +26 -28
  409. package/src/surfaces/diff-toolbar.ts +9 -7
  410. package/src/surfaces/doc-header.ts +10 -19
  411. package/src/surfaces/empty-state.ts +7 -10
  412. package/src/surfaces/entry-editor.ts +14 -11
  413. package/src/surfaces/expression-editor.ts +11 -25
  414. package/src/surfaces/files-panel.ts +27 -14
  415. package/src/surfaces/formula-palette.ts +4 -5
  416. package/src/surfaces/git-panel.ts +7 -15
  417. package/src/surfaces/github-auth.ts +16 -20
  418. package/src/surfaces/github-publish.ts +17 -22
  419. package/src/surfaces/grid-cell.ts +30 -31
  420. package/src/surfaces/grid-open.ts +10 -14
  421. package/src/surfaces/grid-panel.ts +13 -9
  422. package/src/surfaces/grid-replace.ts +13 -13
  423. package/src/surfaces/grid-views.ts +15 -18
  424. package/src/surfaces/inspector-dock.ts +13 -12
  425. package/src/surfaces/jump-bar.ts +5 -6
  426. package/src/surfaces/jxsuite-update.ts +16 -22
  427. package/src/surfaces/library-pane.ts +25 -20
  428. package/src/surfaces/logic-panel.ts +17 -30
  429. package/src/surfaces/logic-workspace.ts +13 -15
  430. package/src/surfaces/media-browser.ts +11 -10
  431. package/src/surfaces/media-field.ts +4 -5
  432. package/src/surfaces/media-pane.ts +8 -7
  433. package/src/surfaces/menu.ts +29 -23
  434. package/src/surfaces/navigator-dock.ts +11 -12
  435. package/src/surfaces/new-project.ts +27 -26
  436. package/src/surfaces/pane-context.ts +20 -25
  437. package/src/surfaces/pane-grid.ts +15 -10
  438. package/src/surfaces/panel-activity.ts +5 -6
  439. package/src/surfaces/panel-data.ts +3 -4
  440. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  441. package/src/surfaces/panel-elements.ts +5 -7
  442. package/src/surfaces/panel-i18n.ts +5 -7
  443. package/src/surfaces/panel-imports.ts +6 -13
  444. package/src/surfaces/panel-outline.ts +25 -19
  445. package/src/surfaces/panel-page.ts +11 -18
  446. package/src/surfaces/panel-problems.ts +5 -7
  447. package/src/surfaces/panel-signals.ts +20 -34
  448. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  449. package/src/surfaces/preferences.ts +21 -11
  450. package/src/surfaces/progress-modal.ts +15 -9
  451. package/src/surfaces/properties-panel.json +1 -1
  452. package/src/surfaces/properties-panel.ts +20 -42
  453. package/src/surfaces/publish.ts +18 -18
  454. package/src/surfaces/push-plan.ts +7 -8
  455. package/src/surfaces/rail.json +126 -73
  456. package/src/surfaces/rail.ts +38 -12
  457. package/src/surfaces/reference-field.ts +11 -15
  458. package/src/surfaces/schema-builder.ts +16 -22
  459. package/src/surfaces/schema-form.ts +15 -25
  460. package/src/surfaces/secret-field.ts +9 -6
  461. package/src/surfaces/seo.ts +21 -15
  462. package/src/surfaces/settings-contexts.ts +9 -7
  463. package/src/surfaces/settings-contributed.ts +14 -10
  464. package/src/surfaces/settings-css-vars.ts +5 -12
  465. package/src/surfaces/settings-defs.json +2 -2
  466. package/src/surfaces/settings-defs.ts +17 -21
  467. package/src/surfaces/settings-deploy.ts +8 -15
  468. package/src/surfaces/settings-extensions.ts +5 -6
  469. package/src/surfaces/settings-head.ts +33 -39
  470. package/src/surfaces/settings-locales.ts +8 -20
  471. package/src/surfaces/settings-overview.ts +5 -6
  472. package/src/surfaces/settings-packages.ts +8 -7
  473. package/src/surfaces/settings-pane.ts +9 -18
  474. package/src/surfaces/settings-rawjson.ts +5 -6
  475. package/src/surfaces/shell.ts +1 -2
  476. package/src/surfaces/slash-menu.ts +19 -9
  477. package/src/surfaces/statements.ts +13 -18
  478. package/src/surfaces/statusbar.ts +17 -14
  479. package/src/surfaces/style-panel.ts +18 -31
  480. package/src/surfaces/stylebook-chrome.ts +3 -5
  481. package/src/surfaces/tab-strip.ts +14 -13
  482. package/src/surfaces/target-line.ts +6 -7
  483. package/src/surfaces/welcome.ts +5 -7
  484. package/src/tabs/patch-ops.ts +4 -3
  485. package/src/tabs/project-config.ts +32 -21
  486. package/src/tabs/selection.ts +36 -8
  487. package/src/tabs/tab.ts +52 -41
  488. package/src/tabs/transact.ts +98 -53
  489. package/src/tabs/typing.ts +31 -0
  490. package/src/types.ts +32 -17
  491. package/src/ui/ai-credentials-form.ts +10 -13
  492. package/src/ui/ai-model-picker.ts +3 -3
  493. package/src/ui/cf-account-picker.ts +7 -9
  494. package/src/ui/color-selector.ts +9 -5
  495. package/src/ui/dynamic-slot.ts +7 -8
  496. package/src/ui/expression-editor.ts +112 -105
  497. package/src/ui/form-controls.ts +57 -48
  498. package/src/ui/formula-catalog.ts +239 -230
  499. package/src/ui/formula-chips.ts +33 -18
  500. package/src/ui/layers.ts +44 -31
  501. package/src/ui/media-picker.ts +18 -9
  502. package/src/ui/popover-surface.ts +20 -12
  503. package/src/ui/progress-modal.ts +13 -8
  504. package/src/ui/regions.ts +7 -6
  505. package/src/ui/schema-form.ts +113 -70
  506. package/src/ui/surface.ts +71 -8
  507. package/src/ui/timing.ts +9 -0
  508. package/src/ui/value-source.ts +44 -31
  509. package/src/ui/virtual-window.ts +3 -2
  510. package/src/utils/base64.ts +3 -1
  511. package/src/utils/edit-display.ts +103 -74
  512. package/src/utils/element-selectors.ts +3 -2
  513. package/src/utils/google-fonts.ts +15 -14
  514. package/src/utils/inherited-style.ts +18 -20
  515. package/src/utils/link-target.ts +1 -1
  516. package/src/utils/preview-format.ts +25 -3
  517. package/src/utils/strip-events.ts +49 -22
  518. package/src/utils/studio-utils.ts +29 -14
  519. package/src/view.ts +2 -3
  520. package/src/workspace/pane-derive.ts +10 -12
  521. package/src/workspace/session.ts +53 -43
  522. package/src/workspace/workspace.ts +47 -36
  523. package/dist/chunks/2020-nkxms0ay.js +0 -4
  524. package/dist/chunks/adapter-m948ab5f.js +0 -4
  525. package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
  526. package/dist/chunks/cf-settings-356xdtne.js +0 -4
  527. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  528. package/dist/chunks/color-field-embq5ctg.js +0 -4
  529. package/dist/chunks/color-fpezvnkt.js +0 -4
  530. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  531. package/dist/chunks/combobox-773hdzyj.js +0 -4
  532. package/dist/chunks/components-yk3t844e.js +0 -4
  533. package/dist/chunks/content-source-bawmyc09.js +0 -4
  534. package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
  535. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  536. package/dist/chunks/editor-6sc8nacq.js +0 -4
  537. package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
  538. package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
  539. package/dist/chunks/file-ops-gye0qw56.js +0 -4
  540. package/dist/chunks/files-dmc2xvcq.js +0 -4
  541. package/dist/chunks/format-host-t76b53f8.js +0 -4
  542. package/dist/chunks/fs-events-cg4tpz06.js +0 -4
  543. package/dist/chunks/git-panel-yef7bshy.js +0 -4
  544. package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
  545. package/dist/chunks/icons-qbh8akb1.js +0 -4
  546. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  547. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  548. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  549. package/dist/chunks/iframe-host-tmz30gfp.js +0 -4
  550. package/dist/chunks/index-nag78a9h.js +0 -4
  551. package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
  552. package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
  553. package/dist/chunks/layers-fvz99859.js +0 -4
  554. package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
  555. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  556. package/dist/chunks/lit-html-9agdspkt.js +0 -4
  557. package/dist/chunks/media-picker-rhjvyy00.js +0 -4
  558. package/dist/chunks/menu-2e4y9j7b.js +0 -4
  559. package/dist/chunks/menu-37d07z9m.js +0 -4
  560. package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
  561. package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
  562. package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
  563. package/dist/chunks/notify-h3www560.js +0 -4
  564. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  565. package/dist/chunks/parse-897fvqah.js +0 -4
  566. package/dist/chunks/platform-hz34wcd7.js +0 -4
  567. package/dist/chunks/popover-8htra4er.js +0 -4
  568. package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
  569. package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
  570. package/dist/chunks/references-2cgdxnb8.js +0 -4
  571. package/dist/chunks/right-panel-jf856w5w.js +0 -4
  572. package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
  573. package/dist/chunks/select-n3v7gwas.js +0 -4
  574. package/dist/chunks/split-pff8f3ze.js +0 -4
  575. package/dist/chunks/studio-0f55h9ye.js +0 -5
  576. package/dist/chunks/studio-0sqdhnew.js +0 -12
  577. package/dist/chunks/studio-19x1c75w.js +0 -5
  578. package/dist/chunks/studio-2sqcndak.js +0 -5
  579. package/dist/chunks/studio-3aey7dd3.js +0 -5
  580. package/dist/chunks/studio-3bpdkq2s.js +0 -5
  581. package/dist/chunks/studio-47y6fbpf.js +0 -5
  582. package/dist/chunks/studio-4m3826v2.js +0 -5
  583. package/dist/chunks/studio-4nx2dj1g.js +0 -4
  584. package/dist/chunks/studio-4xv5s47r.js +0 -9
  585. package/dist/chunks/studio-5g4t8v6w.js +0 -5
  586. package/dist/chunks/studio-5py436sf.js +0 -5
  587. package/dist/chunks/studio-77kt594t.js +0 -5
  588. package/dist/chunks/studio-8f87n763.js +0 -10
  589. package/dist/chunks/studio-8mb00b84.js +0 -5
  590. package/dist/chunks/studio-8p51gq2h.js +0 -6
  591. package/dist/chunks/studio-954ds834.js +0 -5
  592. package/dist/chunks/studio-9ft45c83.js +0 -9
  593. package/dist/chunks/studio-a2138x5k.js +0 -7
  594. package/dist/chunks/studio-a9yzstqj.js +0 -5
  595. package/dist/chunks/studio-acdksxx6.js +0 -5
  596. package/dist/chunks/studio-ar8jcf2y.js +0 -5
  597. package/dist/chunks/studio-bmn4mn9j.js +0 -7
  598. package/dist/chunks/studio-e7xxa0sj.js +0 -5
  599. package/dist/chunks/studio-ecaz25vk.js +0 -5
  600. package/dist/chunks/studio-ery42sqr.js +0 -4
  601. package/dist/chunks/studio-fzdywr6p.js +0 -9
  602. package/dist/chunks/studio-g5fmf0c1.js +0 -5
  603. package/dist/chunks/studio-g7nse7zb.js +0 -5
  604. package/dist/chunks/studio-geq1ea6k.js +0 -14
  605. package/dist/chunks/studio-ghkb32r8.js +0 -5
  606. package/dist/chunks/studio-ghrhy2y7.js +0 -5
  607. package/dist/chunks/studio-grawhey1.js +0 -5
  608. package/dist/chunks/studio-h0xgswew.js +0 -5
  609. package/dist/chunks/studio-h9c4p2tx.js +0 -5
  610. package/dist/chunks/studio-jyzj5cxs.js +0 -5
  611. package/dist/chunks/studio-mgx8yhnz.js +0 -64
  612. package/dist/chunks/studio-mpb04y1d.js +0 -6
  613. package/dist/chunks/studio-n17mty64.js +0 -5
  614. package/dist/chunks/studio-nwh2eqsk.js +0 -6
  615. package/dist/chunks/studio-q1h883bt.js +0 -16
  616. package/dist/chunks/studio-q4tv82h7.js +0 -9
  617. package/dist/chunks/studio-qpqa7vk3.js +0 -5
  618. package/dist/chunks/studio-qqz8e5gk.js +0 -5
  619. package/dist/chunks/studio-qvasen3f.js +0 -5
  620. package/dist/chunks/studio-rggdb3hm.js +0 -5
  621. package/dist/chunks/studio-sghy936h.js +0 -4
  622. package/dist/chunks/studio-skprc6ef.js +0 -5
  623. package/dist/chunks/studio-tt2nactf.js +0 -5
  624. package/dist/chunks/studio-tyasmc39.js +0 -5
  625. package/dist/chunks/studio-vk9ezads.js +0 -5
  626. package/dist/chunks/studio-vzacdfsc.js +0 -4
  627. package/dist/chunks/studio-w4c0xmrw.js +0 -5
  628. package/dist/chunks/studio-wfjqhhbk.js +0 -5
  629. package/dist/chunks/studio-wgh5kxpj.js +0 -5
  630. package/dist/chunks/studio-xasj0796.js +0 -5
  631. package/dist/chunks/studio-y78s8r2n.js +0 -5
  632. package/dist/chunks/studio-z8w183sh.js +0 -5
  633. package/dist/chunks/studio-zscd9ty4.js +0 -928
  634. package/dist/chunks/studio-zxp13sss.js +0 -7
  635. package/dist/chunks/studio-zygnmm01.js +0 -5
  636. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  637. package/dist/chunks/tabs-jwthg40w.js +0 -4
  638. package/dist/chunks/textfield-spy3hc77.js +0 -4
  639. package/dist/chunks/toast-4d35zd64.js +0 -4
  640. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  641. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  642. package/dist/chunks/tree-h19v1jfz.js +0 -4
  643. package/dist/chunks/tsMode-gr0m4dzr.js +0 -14
  644. package/dist/chunks/workspace-m15qtcqp.js +0 -4
  645. package/dist/chunks/ws-client-nf61frr1.js +0 -4
@@ -13,28 +13,42 @@
13
13
  * set. The lit drawing lives beside its one remaining caller in `ui/expression-editor.ts` and dies
14
14
  * with that conversion; nothing here has to be touched when it does.
15
15
  *
16
- * The preview is taken structurally (`{ values }`) rather than as a named type, because the two
17
- * callers hold two spellings of the same record — `EditorPreview` and `services/preview-eval.ts`'s
18
- * `ExpressionPreview` — and a chip only ever reads one field of it.
16
+ * The preview is taken structurally (`{ values }`) rather than as `services/preview-eval.ts`'s
17
+ * `ExpressionPreview`, because a chip only ever reads that one field of it.
19
18
  */
20
19
 
21
- import { isJsonObject, isRef } from "@jxsuite/schema/guards";
20
+ import { isJsonObject, isRef, isString } from "@jxsuite/schema/guards";
21
+ import type { JxDocumentValue } from "@jxsuite/schema/types";
22
22
 
23
23
  type NodePath = (string | number)[];
24
24
 
25
+ /**
26
+ * A value of an expression tree: anything a document holds, or a node an editor rebuilt from one.
27
+ *
28
+ * The rebuilt half is why this is not just `JxDocumentValue`. Replacing one operand spreads the
29
+ * node it sits in, and a member the source node lacked can come through as `undefined` (a blank
30
+ * node's `target`); it serializes away, and until then `"target" in node` still sees the key.
31
+ */
32
+ export type ExpressionValue = JxDocumentValue | ExpressionFields | ExpressionValue[];
33
+
34
+ /** An expression node's members by name — `operator`, `target`, `value`, `cases`, … */
35
+ export interface ExpressionFields {
36
+ [key: string]: ExpressionValue | undefined;
37
+ }
38
+
25
39
  /** What a chip needs to know about the live evaluation: display strings keyed by node path. */
26
40
  export interface ChipPreview {
27
41
  values: Map<string, string>;
28
42
  }
29
43
 
30
44
  interface ChainLink {
31
- node: Record<string, unknown>;
45
+ node: ExpressionFields;
32
46
  path: NodePath;
33
47
  }
34
48
 
35
49
  interface Chain {
36
50
  /** The innermost target operand (ref/literal), absent for target-less roots. */
37
- head: { value: unknown; path: NodePath } | null;
51
+ head: { value: ExpressionValue | undefined; path: NodePath } | null;
38
52
  /** Operator nodes, deepest target first → outermost operator last. */
39
53
  links: ChainLink[];
40
54
  }
@@ -60,8 +74,8 @@ export interface FormulaChip {
60
74
  group: boolean;
61
75
  }
62
76
 
63
- function isExprNode(value: unknown): value is Record<string, unknown> {
64
- return isJsonObject(value) && typeof value.operator === "string";
77
+ function isExprNode(value: ExpressionValue | undefined): value is ExpressionFields {
78
+ return isJsonObject(value) && isString(value.operator);
65
79
  }
66
80
 
67
81
  /** Human label for a pointer ref: strips the #/state/ and window#/ prefixes. */
@@ -76,14 +90,14 @@ function refLabel(ref: string): string {
76
90
  }
77
91
 
78
92
  /** Compact label for a non-node operand (ref or literal). */
79
- function operandLabel(value: unknown): string {
93
+ function operandLabel(value: ExpressionValue | undefined): string {
80
94
  if (isRef(value)) {
81
95
  return refLabel(value.$ref);
82
96
  }
83
97
  if (isExprNode(value)) {
84
98
  return `(${chipSummary(value)})`;
85
99
  }
86
- if (typeof value === "string") {
100
+ if (isString(value)) {
87
101
  return JSON.stringify(value);
88
102
  }
89
103
  return String(value);
@@ -95,10 +109,10 @@ function targetPath(basePath: NodePath, hops: number): NodePath {
95
109
  }
96
110
 
97
111
  /** Unroll a node's target chain into head operand + operator links (deepest first). */
98
- function unrollChain(node: Record<string, unknown>, basePath: NodePath): Chain {
112
+ function unrollChain(node: ExpressionFields, basePath: NodePath): Chain {
99
113
  // Collect the chain root-first, then materialize each link's path from its descent depth.
100
- const nodes: Record<string, unknown>[] = [];
101
- let current: Record<string, unknown> = node;
114
+ const nodes: ExpressionFields[] = [];
115
+ let current: ExpressionFields = node;
102
116
  for (;;) {
103
117
  nodes.push(current);
104
118
  const next = current.target;
@@ -109,8 +123,9 @@ function unrollChain(node: Record<string, unknown>, basePath: NodePath): Chain {
109
123
  }
110
124
  }
111
125
  const deepest = nodes.at(-1)!;
126
+ // Reading an absent key yields undefined, so `in` alone decides whether a head operand exists.
112
127
  const head: Chain["head"] =
113
- "target" in deepest || deepest.target !== undefined
128
+ "target" in deepest
114
129
  ? { path: targetPath(basePath, nodes.length), value: deepest.target }
115
130
  : null;
116
131
  const rootFirst = nodes.map((n, i) => ({ node: n, path: targetPath(basePath, i) }));
@@ -118,7 +133,7 @@ function unrollChain(node: Record<string, unknown>, basePath: NodePath): Chain {
118
133
  }
119
134
 
120
135
  /** Compact one-line text form of a node: head operand followed by the operator chain. */
121
- export function chipSummary(node: unknown): string {
136
+ export function chipSummary(node: ExpressionValue | undefined): string {
122
137
  if (!isExprNode(node)) {
123
138
  return operandLabel(node);
124
139
  }
@@ -155,7 +170,7 @@ function chip(
155
170
  /** Group chips for a link's non-target expression operands (value / initial / cases / default). */
156
171
  function groupChips(link: ChainLink, preview: ChipPreview | null | undefined): FormulaChip[] {
157
172
  const chips: FormulaChip[] = [];
158
- const add = (operand: unknown, path: NodePath) => {
173
+ const add = (operand: ExpressionValue | undefined, path: NodePath) => {
159
174
  if (isExprNode(operand)) {
160
175
  chips.push(chip(`(${chipSummary(operand)})`, path, preview, true));
161
176
  }
@@ -185,13 +200,13 @@ function groupChips(link: ChainLink, preview: ChipPreview | null | undefined): F
185
200
  * strip of no chips and no strip at all are the same thing on screen, and saying it here keeps both
186
201
  * drawings from having to decide.
187
202
  *
188
- * @param {unknown} node The expression node to read.
203
+ * @param {ExpressionValue | undefined} node The expression node to read.
189
204
  * @param {{ preview?: ChipPreview | null; path?: NodePath }} [opts] The live evaluation, and the
190
205
  * document position `node` sits at — every chip path is prefixed with it.
191
206
  * @returns {FormulaChip[]}
192
207
  */
193
208
  export function formulaChipStrip(
194
- node: unknown,
209
+ node: ExpressionValue | undefined,
195
210
  opts: { preview?: ChipPreview | null; path?: NodePath } = {},
196
211
  ): FormulaChip[] {
197
212
  if (!isExprNode(node)) {
package/src/ui/layers.ts CHANGED
@@ -12,7 +12,8 @@
12
12
  * array and owns exactly two things that array does not: the timer that retires a resting toast,
13
13
  * and the transition account {@link overlayIdleBlockers} publishes.
14
14
  */
15
- import { render as litRender, nothing } from "lit-html";
15
+ import { isFunction, isString } from "@jxsuite/schema/guards";
16
+ import { render, nothing } from "lit-html";
16
17
  import { overlayRegion, REGION_ATTR } from "./regions";
17
18
  import { openDialogSurface } from "../surfaces/dialog";
18
19
  import { mountSurface, registerSurface } from "./surface";
@@ -21,20 +22,20 @@ import { dismiss, toasts } from "../services/notify";
21
22
  import { activeRegistry } from "../commands/active-registry";
22
23
  import { runReported } from "../commands/run-reported";
23
24
  import { effect, effectScope, reactive } from "../reactivity";
24
- import type { DialogChoiceOption, DialogSurfaceOptions } from "../surfaces/dialog";
25
+ import type { DialogSurfaceOptions } from "../surfaces/dialog";
25
26
  import type { Notification, Severity } from "../services/notify";
26
27
  import type { EffectScope } from "@vue/reactivity";
27
- import type { SurfaceHandle } from "./surface";
28
- import type { JxDocument } from "@jxsuite/schema/types";
28
+ import type { SurfaceHandle, SurfaceOption } from "./surface";
29
29
  import type { TemplateResult } from "lit-html";
30
30
 
31
31
  /** The four fixed layer hosts, by name. Also the `kind` half of every overlay region id. */
32
32
  export type LayerKind = "popover" | "modal" | "dialog" | "toast";
33
33
 
34
- let _popoverLayer: HTMLElement;
35
- let _modalLayer: HTMLElement;
36
- let _dialogLayer: HTMLElement;
37
- let _toastLayer: HTMLElement;
34
+ /* Null until `initLayers()` runs, and still null afterwards for a page without that host element. */
35
+ let _popoverLayer: HTMLElement | null = null;
36
+ let _modalLayer: HTMLElement | null = null;
37
+ let _dialogLayer: HTMLElement | null = null;
38
+ let _toastLayer: HTMLElement | null = null;
38
39
 
39
40
  /**
40
41
  * The host a layer kind renders into, falling back to `<body>` before `initLayers()` has run.
@@ -52,14 +53,15 @@ export function layerHost(kind: LayerKind): HTMLElement {
52
53
  : kind === "toast"
53
54
  ? _toastLayer
54
55
  : _dialogLayer;
55
- return host || document.body;
56
+ return host ?? document.body;
56
57
  }
57
58
 
58
59
  export function initLayers() {
59
- _popoverLayer = document.querySelector("#layer-popover") as HTMLElement;
60
- _modalLayer = document.querySelector("#layer-modal") as HTMLElement;
61
- _dialogLayer = document.querySelector("#layer-dialog") as HTMLElement;
62
- _toastLayer = document.querySelector("#layer-toast") as HTMLElement;
60
+ // The four hosts are `<div>`s in the shell frame (`src/shell/tree.ts`).
61
+ _popoverLayer = document.querySelector<HTMLElement>("#layer-popover");
62
+ _modalLayer = document.querySelector<HTMLElement>("#layer-modal");
63
+ _dialogLayer = document.querySelector<HTMLElement>("#layer-dialog");
64
+ _toastLayer = document.querySelector<HTMLElement>("#layer-toast");
63
65
  mountToastHost();
64
66
  }
65
67
 
@@ -214,12 +216,12 @@ export function showSaveDiscardDialog(
214
216
  function messageOptions(
215
217
  message: string | TemplateResult,
216
218
  ): Pick<DialogSurfaceOptions, "message" | "island"> {
217
- if (typeof message === "string") {
219
+ if (isString(message)) {
218
220
  return { message };
219
221
  }
220
222
  return {
221
223
  island: (host) => {
222
- litRender(message, host);
224
+ render(message, host);
223
225
  },
224
226
  };
225
227
  }
@@ -344,8 +346,8 @@ export function showPromptDialog(
344
346
  * still refuses, because `confirm()` runs `check` unconditionally.
345
347
  */
346
348
  let touched = false;
347
- const placeholderNow = () => (typeof placeholder === "function" ? placeholder() : placeholder);
348
- const optionsNow = (): DialogChoiceOption[] =>
349
+ const placeholderNow = () => (isFunction(placeholder) ? placeholder() : placeholder);
350
+ const optionsNow = (): SurfaceOption[] =>
349
351
  choice ? choice.options().map((option) => ({ label: option.label, value: option.value })) : [];
350
352
 
351
353
  return new Promise((resolve) => {
@@ -362,15 +364,11 @@ export function showPromptDialog(
362
364
  error = next;
363
365
  handle.update({ error, invalid: error !== "" });
364
366
  };
365
- const handle = openDialogSurface({
367
+ const surfaceOptions: DialogSurfaceOptions = {
366
368
  cancelLabel,
367
369
  confirmLabel,
368
370
  headline,
369
371
  layer: layerHost("dialog"),
370
- ...(message === undefined ? {} : messageOptions(message)),
371
- ...(choice ? { choice: { chosen, label: choice.label, options: optionsNow() } } : {}),
372
- field: { mono, multiline, placeholder: placeholderNow(), rows, select, value },
373
- ...(size === undefined ? {} : { size }),
374
372
  onCancel: () => done(null),
375
373
  onClosed: () => done(null),
376
374
  onConfirm: () => {
@@ -408,7 +406,18 @@ export function showPromptDialog(
408
406
  placeholder: placeholderNow(),
409
407
  });
410
408
  },
411
- });
409
+ };
410
+ if (message !== undefined) {
411
+ Object.assign(surfaceOptions, messageOptions(message));
412
+ }
413
+ if (choice) {
414
+ surfaceOptions.choice = { chosen, label: choice.label, options: optionsNow() };
415
+ }
416
+ surfaceOptions.field = { mono, multiline, placeholder: placeholderNow(), rows, select, value };
417
+ if (size !== undefined) {
418
+ surfaceOptions.size = size;
419
+ }
420
+ const handle = openDialogSurface(surfaceOptions);
412
421
  });
413
422
  }
414
423
 
@@ -452,7 +461,7 @@ export function clearLayerSlot(layer: LayerKind, id: string) {
452
461
  const key = `${layer}:${id}`;
453
462
  const slot = _namedSlots.get(key);
454
463
  if (slot) {
455
- litRender(nothing, slot);
464
+ render(nothing, slot);
456
465
  slot.remove();
457
466
  _namedSlots.delete(key);
458
467
  }
@@ -491,7 +500,11 @@ const _toastEntering = new Set<string>();
491
500
  * means the answer has to be able to change.
492
501
  */
493
502
  function reducedMotion(): boolean {
494
- return globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
503
+ // A realm without `matchMedia` (a bare test runtime) has no preference to honour.
504
+ if (!("matchMedia" in globalThis)) {
505
+ return false;
506
+ }
507
+ return globalThis.matchMedia("(prefers-reduced-motion: reduce)").matches === true;
495
508
  }
496
509
 
497
510
  /**
@@ -515,7 +528,7 @@ function reducedMotion(): boolean {
515
528
  */
516
529
  export function toastsAreHeld(): boolean {
517
530
  try {
518
- return new URLSearchParams(globalThis.location?.search ?? "").get("automation") === "1";
531
+ return new URLSearchParams(globalThis.location.search).get("automation") === "1";
519
532
  } catch {
520
533
  // Intentionally ignored: no location (a bare test realm) means no automation.
521
534
  return false;
@@ -580,13 +593,13 @@ export interface ToastProjection {
580
593
  actionTitle: string;
581
594
  }
582
595
 
583
- interface ToastScope extends Record<string, unknown> {
596
+ interface ToastScope {
584
597
  toasts: ToastProjection[];
585
598
  runAction: (id: string) => void;
586
599
  dismissToast: (id: string) => void;
587
600
  }
588
601
 
589
- registerSurface("toasts", toastsDoc as unknown as JxDocument);
602
+ registerSurface("toasts", toastsDoc);
590
603
 
591
604
  let _toastState: ToastScope | null = null;
592
605
  let _toastMount: Promise<SurfaceHandle> | null = null;
@@ -610,7 +623,7 @@ function toastScope(): ToastScope {
610
623
  void runReported(registry, record.action, record.actionArgs, "Notifications");
611
624
  },
612
625
  toasts: [],
613
- }) as ToastScope;
626
+ });
614
627
  return _toastState;
615
628
  }
616
629
 
@@ -631,12 +644,12 @@ function projectToast(record: Notification): ToastProjection {
631
644
  actionDisabled: reason !== undefined,
632
645
  actionLabel: command?.title ?? "",
633
646
  actionTitle:
634
- command === null || command === undefined
647
+ command === null
635
648
  ? ""
636
649
  : reason === undefined
637
650
  ? command.title
638
651
  : `${command.title} — requires ${reason}`,
639
- hasAction: command !== null && command !== undefined,
652
+ hasAction: command !== null,
640
653
  icon: TOAST_ICON[record.severity],
641
654
  id: record.id,
642
655
  message: record.message,
@@ -48,7 +48,11 @@ import {
48
48
  } from "../files/media-meta";
49
49
  import { mediaSiteUrl, previewFileSrc } from "../files/media-paths";
50
50
  import { notedListing } from "../files/asset-versions";
51
- import type { MediaBrowserRow, MediaBrowserSurfaceHandle } from "../surfaces/media-browser";
51
+ import type {
52
+ MediaBrowserRow,
53
+ MediaBrowserSurfaceHandle,
54
+ MediaBrowserView,
55
+ } from "../surfaces/media-browser";
52
56
  import type { MediaFieldHandle, MediaFieldView } from "../surfaces/media-field";
53
57
 
54
58
  // ─── Media file cache ────────────────────────────────────────────────────────
@@ -139,7 +143,7 @@ let _browserFilter = "";
139
143
  let _browserOrigin = { x: 0, y: 0 };
140
144
 
141
145
  /** What the panel shows for the filter that stands now. */
142
- function browserView() {
146
+ function browserView(): MediaBrowserView {
143
147
  const query = _browserFilter.toLowerCase();
144
148
  const filtered = query
145
149
  ? mediaCache.filter(
@@ -164,9 +168,9 @@ function browserView() {
164
168
  emptyLabel: "No matches",
165
169
  filter: _browserFilter,
166
170
  moreLabel: `…${filtered.length - BROWSE_LIMIT} more`,
167
- moreState: (filtered.length > BROWSE_LIMIT ? "shown" : "hidden") as "hidden" | "shown",
171
+ moreState: filtered.length > BROWSE_LIMIT ? "shown" : "hidden",
168
172
  rows,
169
- rowsState: (rows.length > 0 ? "listed" : "empty") as "empty" | "listed",
173
+ rowsState: rows.length > 0 ? "listed" : "empty",
170
174
  x: _browserOrigin.x,
171
175
  y: _browserOrigin.y,
172
176
  };
@@ -293,12 +297,16 @@ export function pickAndUpload(onCommit: (val: string) => void) {
293
297
  const FIELD_DEBOUNCE_MS = 400;
294
298
 
295
299
  /** One mounted field, and the decisions that move under it between repaints. */
296
- interface FieldEntry {
297
- handle: MediaFieldHandle;
300
+ /** What a field's callbacks read at call time; a re-mount rewrites both in place. */
301
+ interface FieldBinding {
298
302
  prop: string;
299
303
  commit: (value: string) => void;
300
304
  }
301
305
 
306
+ interface FieldEntry extends FieldBinding {
307
+ handle: MediaFieldHandle;
308
+ }
309
+
302
310
  /**
303
311
  * The fields this module has mounted, by the host they were mounted into.
304
312
  *
@@ -347,8 +355,8 @@ export function mountMediaPicker(
347
355
  existing.handle.update(fieldView(prop, value));
348
356
  return;
349
357
  }
350
- const entry: FieldEntry = { commit: onCommit, handle: null as unknown as MediaFieldHandle, prop };
351
- entry.handle = mountMediaFieldSurface(host, fieldView(prop, value), {
358
+ const entry: FieldBinding = { commit: onCommit, prop };
359
+ const handle = mountMediaFieldSurface(host, fieldView(prop, value), {
352
360
  browse: (anchor: HTMLElement) => {
353
361
  void loadMediaCache();
354
362
  showMediaPickerPopover(anchor, (val: string) => entry.commit(val));
@@ -364,7 +372,8 @@ export function mountMediaPicker(
364
372
  void loadMediaCache();
365
373
  },
366
374
  });
367
- _fields.set(host, entry);
375
+ // The same object, so the callbacks above see a later re-mount's `prop` and `commit`.
376
+ _fields.set(host, Object.assign(entry, { handle }));
368
377
  }
369
378
 
370
379
  /**
@@ -30,8 +30,8 @@
30
30
  import { layerHost } from "./layers";
31
31
  import { overlayRegion, REGION_ATTR } from "./regions";
32
32
  import { mountSurface } from "./surface";
33
- import type { JxMountOptions } from "@jxsuite/runtime/types";
34
- import type { SurfaceHandle } from "./surface";
33
+ import type { JxHostScope, JxMountOptions, JxScope } from "@jxsuite/runtime/types";
34
+ import type { MountSurfaceOptions, SurfaceHandle } from "./surface";
35
35
 
36
36
  /** A popover panel element, as the platform's popover API sees it. */
37
37
  type PanelElement = HTMLElement & {
@@ -51,13 +51,14 @@ export interface PopoverSurfaceHandle {
51
51
  readonly close: () => void;
52
52
  }
53
53
 
54
- export interface OpenPopoverSurfaceOptions {
54
+ /** How a popover surface is opened. `S` is the scope's own type, held to `JxHostScope` on open. */
55
+ export interface OpenPopoverSurfaceOptions<S = JxScope> {
55
56
  /** The registered surface name — its document's root must be a `jx-popover`. */
56
57
  name: string;
57
58
  /** The panel's instance name; its region becomes `overlay.<kind>:<id>`. */
58
59
  slot: string;
59
60
  /** The reactive scope the document reads. */
60
- scope: Record<string, unknown>;
61
+ scope: S;
61
62
  /**
62
63
  * The control it was opened from. It becomes the popover's invoker, so a press on that control
63
64
  * does not light-dismiss the panel its own click is about to toggle, and focus goes back to it.
@@ -78,7 +79,9 @@ export interface OpenPopoverSurfaceOptions {
78
79
  * @param {OpenPopoverSurfaceOptions} options
79
80
  * @returns {PopoverSurfaceHandle}
80
81
  */
81
- export function openPopoverSurface(options: OpenPopoverSurfaceOptions): PopoverSurfaceHandle {
82
+ export function openPopoverSurface<S extends JxHostScope<S>>(
83
+ options: OpenPopoverSurfaceOptions<S>,
84
+ ): PopoverSurfaceHandle {
82
85
  const { anchor, name, scope, slot: slotId } = options;
83
86
  const host = document.createElement("div");
84
87
  host.style.pointerEvents = "auto";
@@ -88,6 +91,8 @@ export function openPopoverSurface(options: OpenPopoverSurfaceOptions): PopoverS
88
91
  let panel: PanelElement | null = null;
89
92
  let mounted: SurfaceHandle | null = null;
90
93
  let closed = false;
94
+ // A function rather than a property read, because the signal can abort across every `await` below.
95
+ const aborted = (): boolean => controller.signal.aborted;
91
96
 
92
97
  const finish = (fromPlatform: boolean): void => {
93
98
  if (closed) {
@@ -104,21 +109,24 @@ export function openPopoverSurface(options: OpenPopoverSurfaceOptions): PopoverS
104
109
  };
105
110
 
106
111
  const ready = (async () => {
107
- const surface = await mountSurface(name, scope, host, {
108
- signal: controller.signal,
109
- ...(options.onNodeCreated ? { onNodeCreated: options.onNodeCreated } : {}),
110
- });
111
- if (controller.signal.aborted) {
112
+ const mountOptions: MountSurfaceOptions = { signal: controller.signal };
113
+ if (options.onNodeCreated) {
114
+ mountOptions.onNodeCreated = options.onNodeCreated;
115
+ }
116
+ const surface = await mountSurface(name, scope, host, mountOptions);
117
+ if (aborted()) {
112
118
  return;
113
119
  }
114
120
  mounted = surface;
121
+ /* SAFETY: `name` must register a document whose root is a `jx-popover` (see
122
+ OpenPopoverSurfaceOptions.name), an HTMLElement carrying `open` and the popover methods. */
115
123
  panel = surface.root as PanelElement;
116
124
  /* On the PANEL as well as the slot: a popover is `position: fixed` in the top layer, so the
117
125
  slot around it has a zero-height box and the screenshots lane refuses it ("has an empty
118
126
  box"). Both carry the id; the measurement takes the last match, which is the panel. */
119
127
  panel.setAttribute(REGION_ATTR, overlayRegion("popover", slotId));
120
128
  panel.addEventListener("toggle", (event) => {
121
- if ((event as { newState?: string }).newState === "closed") {
129
+ if ("newState" in event && event.newState === "closed") {
122
130
  finish(true);
123
131
  }
124
132
  });
@@ -130,7 +138,7 @@ export function openPopoverSurface(options: OpenPopoverSurfaceOptions): PopoverS
130
138
  panel?.addEventListener("jx-ready", () => resolve(), { once: true });
131
139
  });
132
140
  }
133
- if (controller.signal.aborted) {
141
+ if (aborted()) {
134
142
  return;
135
143
  }
136
144
  panel.showPopover(anchor ? { source: anchor } : undefined);
@@ -29,7 +29,7 @@ import { beginActivity } from "../panels/activity-panel";
29
29
  import { setBottomTab } from "../shell";
30
30
  import { layerHost } from "./layers";
31
31
  import { openProgressSurface } from "../surfaces/progress-modal";
32
- import type { ActivityHandle } from "../panels/activity-panel";
32
+ import type { ActivityHandle, ActivityOptions } from "../panels/activity-panel";
33
33
 
34
34
  export interface ProgressModalHandle {
35
35
  /** Update the status line shown under the title. Also the Activity entry's status. */
@@ -68,12 +68,17 @@ export interface ProgressModalOptions {
68
68
  export function showProgressModal(opts: ProgressModalOptions): ProgressModalHandle {
69
69
  let closed = false;
70
70
 
71
- const activity = beginActivity({
72
- title: opts.title,
73
- ...(opts.status === undefined ? {} : { status: opts.status }),
74
- ...(opts.source === undefined ? {} : { source: opts.source }),
75
- ...(opts.cancel === undefined ? {} : { cancel: opts.cancel }),
76
- });
71
+ const activityOptions: ActivityOptions = { title: opts.title };
72
+ if (opts.status !== undefined) {
73
+ activityOptions.status = opts.status;
74
+ }
75
+ if (opts.source !== undefined) {
76
+ activityOptions.source = opts.source;
77
+ }
78
+ if (opts.cancel !== undefined) {
79
+ activityOptions.cancel = opts.cancel;
80
+ }
81
+ const activity = beginActivity(activityOptions);
77
82
 
78
83
  const close = () => {
79
84
  if (closed) {
@@ -118,7 +123,7 @@ export function showProgressModal(opts: ProgressModalOptions): ProgressModalHand
118
123
  // CAPTURED LOG as their message — `result.log ?? "bun install failed"` — so a multi-line one
119
124
  // Is split the way the old view split it: "<title> failed" as the headline, the whole text
120
125
  // As the detail. A Problems list whose first row is 400 lines of `bun` output is not a list.
121
- const text = (message ?? "").trim();
126
+ const text = message.trim();
122
127
  if (text === "" || text.includes("\n")) {
123
128
  activity.log(text);
124
129
  activity.fail(`${opts.title} failed`);
package/src/ui/regions.ts CHANGED
@@ -97,16 +97,17 @@ export function parseRegionId(id: string): ParsedRegionId | null {
97
97
  }
98
98
  }
99
99
  }
100
- if (!(REGION_SURFACES as readonly string[]).includes(surface)) {
100
+ const known = REGION_SURFACES.find((candidate) => candidate === surface);
101
+ if (known === undefined) {
101
102
  return null;
102
103
  }
103
104
  return instance === undefined
104
105
  ? part === undefined
105
- ? { surface: surface as RegionSurface }
106
- : { part, surface: surface as RegionSurface }
106
+ ? { surface: known }
107
+ : { part, surface: known }
107
108
  : part === undefined
108
- ? { instance, surface: surface as RegionSurface }
109
- : { instance, part, surface: surface as RegionSurface };
109
+ ? { instance, surface: known }
110
+ : { instance, part, surface: known };
110
111
  }
111
112
 
112
113
  /** Whether a string is a well-formed region id. */
@@ -267,7 +268,7 @@ export const REGION_FOR_FOCUS: Readonly<Record<FocusRegion, string>> = {
267
268
  status: "statusbar",
268
269
  };
269
270
 
270
- const FOCUS_FOR_SURFACE: Readonly<Record<string, FocusRegion>> = {
271
+ const FOCUS_FOR_SURFACE: Readonly<Partial<Record<RegionSurface, FocusRegion>>> = {
271
272
  "dock.bottom": "dock",
272
273
  inspector: "inspector",
273
274
  navigator: "navigator",