@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
@@ -3,13 +3,25 @@
3
3
  * Edit-mode display transforms — extracted from studio.js (Phase 4i). Pure stateless functions that
4
4
  * convert document trees for visual editing (template expressions, $map, $switch, empty
5
5
  * placeholders).
6
+ *
7
+ * @docs studio/interface/modes
6
8
  */
7
9
 
8
- import type { JxMutableNode } from "@jxsuite/schema/types";
9
- import { displayTagName } from "@jxsuite/schema/guards";
10
+ import type { JxDocumentValue, JxMutableNode } from "@jxsuite/schema/types";
11
+ import {
12
+ displayTagName,
13
+ isNodeObject,
14
+ isNonNullObject,
15
+ isNumber,
16
+ isRef,
17
+ isString,
18
+ } from "@jxsuite/schema/guards";
19
+ import { isDocumentContainer } from "./strip-events";
20
+ import type { RebuiltNode } from "./strip-events";
10
21
 
11
22
  const mediaTags = new Set(["img", "video", "source", "iframe", "audio"]);
12
- const TRANSPARENT_PX =
23
+ /** A 1×1 transparent GIF: what an unresolvable `src` binding shows in edit mode. */
24
+ export const TRANSPARENT_PX =
13
25
  "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
14
26
  // A neutral, visible gray placeholder for image-like bindings in edit mode (e.g. a component `image`
15
27
  // Prop bound to ${...}). The component renders <img src={prop}> internally, so a transparent pixel
@@ -54,6 +66,37 @@ function isImageUrlKey(key: string): boolean {
54
66
  return IMAGE_KEY_RE.test(key);
55
67
  }
56
68
 
69
+ /** A template that reads the repeater row (`item`, `index`, `$map`), which edit mode cannot supply. */
70
+ const ROW_BINDING_RE = /(?<![\w$.])(?:item|index|\$map)\b/u;
71
+
72
+ /** Whether a value is a template or `$ref` that reads the repeater row. */
73
+ export function isRowBound(value: JxDocumentValue | undefined): boolean {
74
+ if (isString(value)) {
75
+ return value.includes("${") && ROW_BINDING_RE.test(value);
76
+ }
77
+ return isNodeObject(value) && isString(value.$ref) && /^(?:#\/)?\$map\//u.test(value.$ref);
78
+ }
79
+
80
+ /**
81
+ * What a row-bound value shows in the perimeter: link targets are inert, image-like keys the
82
+ * placeholder image, anything else its readable binding text.
83
+ *
84
+ * @param {string} key
85
+ * @param {JxDocumentValue | undefined} value
86
+ */
87
+ function rowBoundDisplay(key: string, value: JxDocumentValue | undefined): string {
88
+ if (key === "href" || key === "action") {
89
+ return "";
90
+ }
91
+ if (isImageUrlKey(key)) {
92
+ return PLACEHOLDER_IMG;
93
+ }
94
+ if (isString(value)) {
95
+ return templateToEditDisplay(value);
96
+ }
97
+ return isNodeObject(value) && isString(value.$ref) ? refDisplayLabel(value.$ref) : "";
98
+ }
99
+
57
100
  const textTags = new Set([
58
101
  "p",
59
102
  "h1",
@@ -115,6 +158,31 @@ export const EMPTY_PLACEHOLDER_CLASSES = [
115
158
  "empty-container-placeholder",
116
159
  ] as const;
117
160
 
161
+ /** The style keys that give an element a size of its own: its box, not its content, sets it. */
162
+ const SIZING_KEYS = ["width", "height", "inlineSize", "blockSize"] as const;
163
+
164
+ /**
165
+ * Whether the node's own style fixes its width or height — a dot, a bar, a spacer.
166
+ *
167
+ * Such an element is drawn as a SHAPE, and an empty one is not missing anything: the jxsuite.com
168
+ * home's 6px status dot is an empty `<span>` sized in its style, and the text placeholder turned it
169
+ * into a column of letters one glyph wide over the hero. A placeholder that changes the box the
170
+ * author sized (the container one sets a `min-height` and a border) misdraws the page it is meant
171
+ * to explain, so a sized element gets none. Only the top-level declaration counts: a size set under
172
+ * a media query or a state is a variant of a box whose base the content still sizes.
173
+ */
174
+ function fixesItsOwnSize(node: JxMutableNode): boolean {
175
+ const { style } = node;
176
+ if (!isNonNullObject(style)) {
177
+ return false;
178
+ }
179
+ return SIZING_KEYS.some((key) => {
180
+ const value = style[key];
181
+ const text = isNumber(value) ? String(value) : isString(value) ? value.trim() : "";
182
+ return text !== "" && text !== "auto";
183
+ });
184
+ }
185
+
118
186
  /**
119
187
  * The empty-placeholder class prepareForEditMode would add for this node, or null. Used by the
120
188
  * canvas patcher to keep placeholder classes in sync when patching text without a full render.
@@ -133,6 +201,9 @@ export function computeEmptyPlaceholderClass(node: JxMutableNode): string | null
133
201
  if (Array.isArray(node.children) && node.children.length > 0) {
134
202
  return null;
135
203
  }
204
+ if (fixesItsOwnSize(node)) {
205
+ return null;
206
+ }
136
207
  if (textTags.has(displayTagName(node.tagName))) {
137
208
  return "empty-text-placeholder";
138
209
  }
@@ -161,6 +232,7 @@ export function templateToEditDisplay(str: string) {
161
232
  export function restoreTemplateExpressions(el: HTMLElement) {
162
233
  const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
163
234
  while (walker.nextNode()) {
235
+ // SAFETY: the walker was created with NodeFilter.SHOW_TEXT, so every node it stops on is Text.
164
236
  const node = walker.currentNode as Text;
165
237
  if (node.data.includes("\u276A")) {
166
238
  node.data = node.data.replaceAll(/\u276A\s*(.*?)\s*\u276B/g, "${$1}");
@@ -175,52 +247,253 @@ export function restoreTemplateExpressions(el: HTMLElement) {
175
247
  * edit-only device — it is never compiled or rendered in preview.
176
248
  *
177
249
  * @param {JxMutableNode} arrayObj
178
- * @returns {Record<string, unknown>}
250
+ * @returns {JxMutableNode}
179
251
  */
180
- function arrayToPerimeter(arrayObj: JxMutableNode): Record<string, unknown> {
252
+ function arrayToPerimeter(arrayObj: JxMutableNode, row: SampleRow): JxMutableNode {
181
253
  const template = arrayObj.map;
182
254
  return {
183
- children:
184
- template && typeof template === "object"
185
- ? [prepareForEditMode(template as JxMutableNode)]
186
- : [],
255
+ children: isNonNullObject(template)
256
+ ? [prepareNode(template, sampleRowOf(arrayObj.items, row))]
257
+ : [],
187
258
  className: "repeater-perimeter",
188
259
  tagName: "div",
189
260
  };
190
261
  }
191
262
 
263
+ // ─── Live component props ────────────────────────────────────────────────────
264
+
265
+ /**
266
+ * The row a repeater's template is drawn with in edit mode, as a JavaScript expression the runtime
267
+ * evaluates in the template's own scope, or null outside a repeater or where the repeater's items
268
+ * cannot be read.
269
+ *
270
+ * It is the repeater's FIRST item. A perimeter draws one instance of the template, and a component
271
+ * inside it used to be handed each bound prop's display text (`❪ item.data.date ❫`) as its value.
272
+ * Text survives that; a component that formats the prop does not: `Intl/formatDate` and a locale
273
+ * tag reject it with a `RangeError` (spec.md §16.4), and the instance was not rendered at all. The
274
+ * first item is real data of exactly the shape the template was written for, and it is the row
275
+ * Preview draws first.
276
+ */
277
+ export type SampleRow = string | null;
278
+
279
+ /** A JSON value as a JavaScript literal: JSON is a subset of ECMAScript since ES2019. */
280
+ function jsLiteral(value: JxDocumentValue): string {
281
+ return JSON.stringify(value);
282
+ }
283
+
284
+ /**
285
+ * A pointer the runtime resolves, as a JavaScript accessor over the template parameters, or null
286
+ * for a scheme a template cannot reach (`window#/`, `$defs`, an external file).
287
+ */
288
+ function refAccessor(ref: string): string | null {
289
+ const pointer = ref.startsWith("#/") ? ref.slice(2) : ref;
290
+ const [head, ...rest] = pointer.split("/");
291
+ const base = head === "state" || head === "$map" ? head : null;
292
+ if (base === null) {
293
+ return null;
294
+ }
295
+ // JSON Pointer unescaping (RFC 6901): `~1` is `/`, `~0` is `~`, in that order.
296
+ const keys = rest.map((seg) => seg.replaceAll("~1", "/").replaceAll("~0", "~"));
297
+ return base + keys.map((key) => `?.[${jsLiteral(key)}]`).join("");
298
+ }
299
+
300
+ /** Evaluate `expr` where `item`, `index` and `$map` are the sample `row`, or as-is with no row. */
301
+ function inRow(expr: string, row: SampleRow): string {
302
+ if (row === null) {
303
+ return `(${expr})`;
304
+ }
305
+ return `((r) => ((item, index, $map) => (${expr}))(r, 0, { index: 0, item: r }))(${row})`;
306
+ }
307
+
308
+ /** The first item of a repeater's `items`, read inside the enclosing sample `row` (if any). */
309
+ function sampleRowOf(items: JxDocumentValue | undefined, row: SampleRow): SampleRow {
310
+ if (Array.isArray(items)) {
311
+ return `${jsLiteral(items)}[0]`;
312
+ }
313
+ if (isRef(items)) {
314
+ const accessor = refAccessor(items.$ref);
315
+ return accessor === null ? null : `${inRow(accessor, row)}?.[0]`;
316
+ }
317
+ const parts = isString(items) ? templateExpressions(items) : [];
318
+ if (isString(items) && parts.length === 1 && isWholeTemplate(items, parts[0]!)) {
319
+ return `${inRow(parts[0]!.expr, row)}?.[0]`;
320
+ }
321
+ return null;
322
+ }
323
+
324
+ /** One `${…}` of a template: where it starts and ends in the string, and its expression. */
325
+ interface TemplatePart {
326
+ start: number;
327
+ end: number;
328
+ expr: string;
329
+ }
330
+
331
+ /** Whether `part` is the whole of `template`: one expression end to end, so it keeps its type. */
332
+ function isWholeTemplate(template: string, part: TemplatePart): boolean {
333
+ return part.start === 0 && part.end === template.length - 1;
334
+ }
335
+
336
+ /**
337
+ * Each `${…}` of a template, located by brace depth rather than by pattern: an expression may hold
338
+ * an object literal or a nested template, which a `[^}]+` pattern cuts short.
339
+ */
340
+ function templateExpressions(str: string): TemplatePart[] {
341
+ const found: TemplatePart[] = [];
342
+ let at = str.indexOf("${");
343
+ while (at !== -1) {
344
+ let depth = 0;
345
+ let end = -1;
346
+ for (let i = at + 1; i < str.length; i += 1) {
347
+ if (str[i] === "{") {
348
+ depth += 1;
349
+ } else if (str[i] === "}") {
350
+ depth -= 1;
351
+ if (depth === 0) {
352
+ end = i;
353
+ break;
354
+ }
355
+ }
356
+ }
357
+ if (end === -1) {
358
+ break;
359
+ }
360
+ found.push({ end, expr: str.slice(at + 2, end), start: at });
361
+ at = str.indexOf("${", end + 1);
362
+ }
363
+ return found;
364
+ }
365
+
366
+ /**
367
+ * A bound component prop as edit mode passes it: the binding itself, evaluated LIVE by the runtime
368
+ * (against the page's own state and `$page`, and inside a repeater against its sample row) and
369
+ * guarded, so a binding with nothing to read yet (a collection still loading, an empty one) reads
370
+ * as the empty string, a component prop's usual default, rather than throwing out of the binding's
371
+ * effect.
372
+ *
373
+ * Display text is what edit mode shows for a binding the PAGE draws, because the author edits that
374
+ * text in place. A component's prop is not drawn by the page: the component decides what it means,
375
+ * and a date, a locale, a count or a colour cannot be a label.
376
+ */
377
+ export function liveEditProp(template: string, row: SampleRow = null): string {
378
+ const parts = templateExpressions(template);
379
+ if (parts.length === 0) {
380
+ return template;
381
+ }
382
+ let out = "";
383
+ let last = 0;
384
+ for (const { start, end, expr } of parts) {
385
+ out += template.slice(last, start);
386
+ out += `\${(() => { try { return ${inRow(expr, row)}; } catch { return ""; } })()}`;
387
+ last = end + 1;
388
+ }
389
+ return out + template.slice(last);
390
+ }
391
+
392
+ /**
393
+ * A `$ref`-bound component prop in edit mode: a scope pointer resolves live as it is, and a row
394
+ * pointer (`$map/item/…`) is read from the sample row, or dropped where there is none so the
395
+ * component keeps its own default.
396
+ */
397
+ function liveEditRefProp(ref: string, row: SampleRow): JxDocumentValue | undefined {
398
+ const pointer = ref.startsWith("#/") ? ref.slice(2) : ref;
399
+ if (pointer !== "$map" && !pointer.startsWith("$map/")) {
400
+ return { $ref: ref };
401
+ }
402
+ const accessor = refAccessor(ref);
403
+ return row === null || accessor === null ? undefined : liveEditProp(`\${${accessor}}`, row);
404
+ }
405
+
406
+ /**
407
+ * The sample row of the repeater template at `path` in `doc` (what {@link prepareForEditMode} draws
408
+ * a perimeter's instance with), so a subtree re-rendered on its own (`iframe-subtree.ts`) is
409
+ * prepared exactly as the full render prepared it.
410
+ */
411
+ export function sampleRowAt(doc: JxDocumentValue, path: readonly (string | number)[]): SampleRow {
412
+ let node: JxDocumentValue | undefined = doc;
413
+ let row: SampleRow = null;
414
+ for (const seg of path) {
415
+ if (Array.isArray(node)) {
416
+ node = isNumber(seg) ? node[seg] : undefined;
417
+ continue;
418
+ }
419
+ if (!isNodeObject(node)) {
420
+ return row;
421
+ }
422
+ if (seg === "map" && node.$prototype === "Array") {
423
+ row = sampleRowOf(node.items, row);
424
+ }
425
+ node = isString(seg) ? node[seg] : undefined;
426
+ }
427
+ return row;
428
+ }
429
+
430
+ /**
431
+ * The text a `$ref` binding shows in edit mode: its pointer, with the `#/state/` prefix dropped.
432
+ *
433
+ * @param {string} ref
434
+ */
435
+ function refDisplayLabel(ref: string): string {
436
+ const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
437
+ return `{${label}}`;
438
+ }
439
+
192
440
  /**
193
441
  * Prepare a document for edit-mode rendering. Replaces template strings with readable literal text,
194
442
  * $prototype:Array with placeholders, and $ref bindings with display labels. Preserves state so the
195
- * runtime can still initialise scope.
443
+ * runtime can still initialise scope. Arrays are prepared member by member, and primitives and a
444
+ * cleared (`undefined`) key return unchanged, so the walker can recurse through any document
445
+ * value.
196
446
  *
197
447
  * @param {JxMutableNode} node
198
448
  * @returns {JxMutableNode}
199
449
  */
200
- export function prepareForEditMode(node: JxMutableNode): JxMutableNode {
201
- if (!node || typeof node !== "object") {
202
- return node;
203
- }
450
+ export function prepareForEditMode(node: JxMutableNode, row?: SampleRow): JxMutableNode;
451
+ export function prepareForEditMode(node: JxDocumentValue, row?: SampleRow): JxDocumentValue;
452
+ export function prepareForEditMode(
453
+ node: JxDocumentValue | undefined,
454
+ row?: SampleRow,
455
+ ): JxDocumentValue | undefined;
456
+ export function prepareForEditMode(
457
+ node: JxDocumentValue | undefined,
458
+ row: SampleRow = null,
459
+ ): JxDocumentValue | undefined {
460
+ return prepareNode(node, row);
461
+ }
462
+
463
+ /** {@link prepareForEditMode} for one value, inside the sample `row` of its enclosing repeater. */
464
+ function prepareNode(node: JxMutableNode, row: SampleRow): JxMutableNode;
465
+ function prepareNode(node: JxDocumentValue, row: SampleRow): JxDocumentValue;
466
+ function prepareNode(
467
+ node: JxDocumentValue | undefined,
468
+ row: SampleRow,
469
+ ): JxDocumentValue | undefined;
470
+ function prepareNode(
471
+ node: JxDocumentValue | undefined,
472
+ row: SampleRow,
473
+ ): JxDocumentValue | undefined {
204
474
  if (Array.isArray(node)) {
205
475
  // Arrays of nodes round-trip element-wise; the array itself is not a node.
206
- return (node as JxMutableNode[]).map((n) => prepareForEditMode(n)) as unknown as JxMutableNode;
476
+ return node.map((n) => prepareNode(n, row));
477
+ }
478
+ if (!isNodeObject(node)) {
479
+ return node;
207
480
  }
208
481
 
209
482
  // A mapped-array node itself → its edit-mode perimeter (e.g. when the patcher re-renders an
210
483
  // Array node directly). Members inside a children array funnel here via the children branch.
211
- if ((node as Record<string, unknown>).$prototype === "Array") {
212
- return arrayToPerimeter(node) as unknown as JxMutableNode;
484
+ if (node.$prototype === "Array") {
485
+ return arrayToPerimeter(node, row);
213
486
  }
214
487
 
215
- const /** @type {Record<string, unknown>} */ obj = node as Record<string, unknown>;
488
+ const obj = node;
216
489
 
217
- const out: Record<string, unknown> = {};
490
+ const out: RebuiltNode = {};
218
491
  let needsMediaPlaceholder = false;
219
- const isMediaElement = mediaTags.has((obj.tagName as string) || "");
492
+ const isMediaElement = isString(obj.tagName) && mediaTags.has(obj.tagName);
220
493
 
221
494
  // Check if this media element lacks a resolvable src (top-level or in attributes)
222
495
  if (isMediaElement) {
223
- const attrs = obj.attributes as Record<string, unknown> | undefined;
496
+ const attrs = obj.attributes;
224
497
  const topSrc = obj.src;
225
498
  const attrSrc = attrs?.src;
226
499
  const topPoster = obj.poster;
@@ -235,24 +508,28 @@ export function prepareForEditMode(node: JxMutableNode): JxMutableNode {
235
508
  for (const [k, v] of Object.entries(obj)) {
236
509
  if (k === "state" || k === "$media" || k === "$elements") {
237
510
  out[k] = v; // Preserve as-is for runtime resolution
238
- } else if (k === "$props" && v && typeof v === "object") {
239
- // Process $props values: convert template strings to display format
240
- const propsOut: Record<string, unknown> = {};
511
+ } else if (k === "$props" && isDocumentContainer(v)) {
512
+ /* A component's inputs render LIVE. They are its configuration, not text the author edits in
513
+ place (a template-valued prop is refused by inline prop editing), and showing their binding
514
+ text instead fed it to the component as a value: a header's `variant` became the literal
515
+ `❪ state.headerVariant ❫` and matched none of its styles. A prop that reads the repeater
516
+ row is drawn with the repeater's sample row (see liveEditProp), guarded, so a date or a
517
+ locale the component formats is real data rather than a label; a row-bound link target is
518
+ inert and a row-bound image-like key the placeholder image. */
519
+ const propsOut: RebuiltNode = {};
241
520
  for (const [pk, pv] of Object.entries(v)) {
242
- if (typeof pv === "string" && pv.includes("${")) {
243
- // Image-like prop → neutral placeholder (the component renders it as an <img src>); link
244
- // Targets → inert ""; everything else → the readable ❪ expr ❫ binding text.
245
- if (isImageUrlKey(pk)) {
246
- propsOut[pk] = PLACEHOLDER_IMG;
247
- } else if (pk === "href" || pk === "action") {
248
- propsOut[pk] = "";
249
- } else {
250
- propsOut[pk] = templateToEditDisplay(pv);
521
+ if (!isRowBound(pv)) {
522
+ propsOut[pk] = pv;
523
+ } else if (isString(pv)) {
524
+ propsOut[pk] =
525
+ isImageUrlKey(pk) || pk === "href" || pk === "action"
526
+ ? rowBoundDisplay(pk, pv)
527
+ : liveEditProp(pv, row);
528
+ } else if (isRef(pv)) {
529
+ const live = liveEditRefProp(pv.$ref, row);
530
+ if (live !== undefined) {
531
+ propsOut[pk] = live;
251
532
  }
252
- } else if (pv && typeof pv === "object" && (pv as Record<string, unknown>).$ref) {
253
- const ref = (pv as Record<string, unknown>).$ref as string;
254
- const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
255
- propsOut[pk] = `{${label}}`;
256
533
  } else {
257
534
  propsOut[pk] = pv;
258
535
  }
@@ -262,25 +539,21 @@ export function prepareForEditMode(node: JxMutableNode): JxMutableNode {
262
539
  if (Array.isArray(v)) {
263
540
  // Each member recurses; array pseudo-elements become a single repeater-perimeter element
264
541
  // (via the top-level array case) so they stay a 1:1 DOM node among their siblings.
265
- out.children = v.map((c) => prepareForEditMode(c as JxMutableNode));
266
- } else if (
267
- v &&
268
- typeof v === "object" &&
269
- (v as Record<string, unknown>).$prototype === "Array"
270
- ) {
542
+ out.children = v.map((c) => prepareNode(c, row));
543
+ } else if (isNodeObject(v) && v.$prototype === "Array") {
271
544
  // Legacy whole-children repeater → a single perimeter as the sole child.
272
- out.children = [prepareForEditMode(v as JxMutableNode)];
545
+ out.children = [prepareNode(v, row)];
273
546
  } else {
274
- out.children = prepareForEditMode(v as JxMutableNode);
547
+ out.children = prepareNode(v, row);
275
548
  }
276
- } else if (k === "cases" && obj.$switch && v && typeof v === "object") {
549
+ } else if (k === "cases" && obj.$switch && isDocumentContainer(v)) {
277
550
  // Replace $switch cases with a placeholder showing the first case or a label
278
- const caseKeys = Object.keys(v);
279
- if (caseKeys.length > 0) {
280
- const firstCase = (v as Record<string, unknown>)[caseKeys[0]!];
551
+ const [firstEntry] = Object.entries(v);
552
+ if (firstEntry) {
553
+ const [, firstCase] = firstEntry;
281
554
  out.children =
282
- firstCase && typeof firstCase === "object" && !(firstCase as Record<string, unknown>).$ref
283
- ? [prepareForEditMode(firstCase as JxMutableNode)]
555
+ isDocumentContainer(firstCase) && !(isNodeObject(firstCase) && firstCase.$ref)
556
+ ? [prepareNode(firstCase, row)]
284
557
  : [
285
558
  {
286
559
  style: {
@@ -294,43 +567,37 @@ export function prepareForEditMode(node: JxMutableNode): JxMutableNode {
294
567
  padding: "6px 10px",
295
568
  },
296
569
  tagName: "div",
297
- textContent: `[$switch: ${caseKeys.join(" | ")}]`,
570
+ textContent: `[$switch: ${Object.keys(v).join(" | ")}]`,
298
571
  },
299
572
  ];
300
573
  }
301
- } else if (k === "attributes" && isMediaElement && v && typeof v === "object") {
302
- // Process attributes for media elements: replace src/poster with transparent pixel
303
- const attrs = v as Record<string, unknown>;
304
- const processed: Record<string, unknown> = {};
305
- for (const [ak, av] of Object.entries(attrs)) {
306
- if (ak === "src" || ak === "poster") {
307
- if (typeof av === "string" && av !== "" && !av.includes("${")) {
308
- processed[ak] = av;
309
- } else {
310
- needsMediaPlaceholder = true;
311
- processed[ak] = TRANSPARENT_PX;
312
- }
313
- } else if (typeof av === "string" && av.includes("${")) {
314
- const isUrlAttr = ak === "href" || ak === "action";
315
- processed[ak] = isUrlAttr ? "" : templateToEditDisplay(av);
316
- } else if (av && typeof av === "object" && (av as Record<string, unknown>).$ref) {
317
- const ref = (av as Record<string, unknown>).$ref as string;
318
- const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
319
- processed[ak] = `{${label}}`;
574
+ } else if (k === "attributes" && isMediaElement && isDocumentContainer(v)) {
575
+ // A media element's src/poster: live, unless it reads the repeater row or names nothing.
576
+ const processed: RebuiltNode = {};
577
+ for (const [ak, av] of Object.entries(v)) {
578
+ if ((ak === "src" || ak === "poster") && (av === "" || av == null || isRowBound(av))) {
579
+ needsMediaPlaceholder = true;
580
+ processed[ak] = TRANSPARENT_PX;
320
581
  } else {
321
- processed[ak] = av;
582
+ processed[ak] = isRowBound(av) ? rowBoundDisplay(ak, av) : av;
322
583
  }
323
584
  }
324
585
  out.attributes = processed;
586
+ } else if (k === "attributes" && isDocumentContainer(v)) {
587
+ const processed: RebuiltNode = {};
588
+ for (const [ak, av] of Object.entries(v)) {
589
+ processed[ak] = isRowBound(av) ? rowBoundDisplay(ak, av) : av;
590
+ }
591
+ out.attributes = processed;
325
592
  } else if (k === "style") {
326
- /* Drop template-valued style declarations. State is not live in edit mode, so the value
327
- cannot be resolved; omitting the property lets the cascade answer, which is exactly what
328
- the `""` this used to write meant while declarations went inline. As a RULE, `color: ` is
329
- a malformed declaration instead of a no-op. Mirrored by iframe-patch's editModeStyle. */
330
- if (v && typeof v === "object") {
331
- const s: Record<string, unknown> = {};
593
+ /* Live, like every binding but text: state IS live on the canvas. Only a declaration that
594
+ reads the repeater row is omitted — the perimeter has no row — and omitted rather than
595
+ blanked, because `color: ` is a malformed declaration in a rule where the cascade answers
596
+ an absent one. Mirrored by iframe-patch's editModeStyle. */
597
+ if (isDocumentContainer(v)) {
598
+ const s: RebuiltNode = {};
332
599
  for (const [sk, sv] of Object.entries(v)) {
333
- if (typeof sv !== "string" || !sv.includes("${")) {
600
+ if (!isRowBound(sv)) {
334
601
  s[sk] = sv;
335
602
  }
336
603
  }
@@ -338,53 +605,41 @@ export function prepareForEditMode(node: JxMutableNode): JxMutableNode {
338
605
  } else {
339
606
  out.style = v;
340
607
  }
341
- } else if (typeof v === "string" && v.includes("${")) {
342
- // Template string in a display property → show raw expression
343
- const isMediaSrc =
344
- (k === "src" || k === "poster") && mediaTags.has((obj.tagName as string) || "");
345
- if (isMediaSrc) {
346
- needsMediaPlaceholder = true;
347
- out[k] = TRANSPARENT_PX;
348
- } else {
349
- const isUrlAttr = k === "src" || k === "href" || k === "poster" || k === "action";
350
- out[k] = isUrlAttr ? "" : templateToEditDisplay(v);
351
- }
352
- } else if (v && typeof v === "object" && (v as Record<string, unknown>).$ref) {
353
- // $ref binding → show ref path as literal text
354
- const ref = (v as Record<string, unknown>).$ref as string;
355
- const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
356
- const isMediaSrc =
357
- (k === "src" || k === "poster") && mediaTags.has((obj.tagName as string) || "");
358
- if (isMediaSrc) {
608
+ } else if (k === "$switch" && isString(v) && v.includes("${")) {
609
+ /* Not a render input any more: `cases` is replaced by the first case above, so a live
610
+ expression would hand the runtime a switch with nothing to choose from. */
611
+ out[k] = templateToEditDisplay(v);
612
+ } else if (k === "textContent" && isString(v) && v.includes("${")) {
613
+ // The author's text: shown as its binding, so editing it in place edits the template.
614
+ out[k] = templateToEditDisplay(v);
615
+ } else if (k === "textContent" && isNodeObject(v) && v.$ref) {
616
+ out[k] = refDisplayLabel(v.$ref);
617
+ } else if (isMediaElement && (k === "src" || k === "poster")) {
618
+ if (v === "" || v == null || isRowBound(v)) {
359
619
  needsMediaPlaceholder = true;
360
620
  out[k] = TRANSPARENT_PX;
361
621
  } else {
362
- out[k] = `{${label}}`;
622
+ out[k] = v;
363
623
  }
624
+ } else if (isRowBound(v)) {
625
+ out[k] = rowBoundDisplay(k, v);
626
+ } else if (isString(v) || (isNodeObject(v) && v.$ref)) {
627
+ // Any other bound or literal property renders as the page will.
628
+ out[k] = v;
364
629
  } else {
365
- // Empty src/poster on media elements → use transparent pixel placeholder
366
- if (
367
- (k === "src" || k === "poster") &&
368
- v === "" &&
369
- mediaTags.has((obj.tagName as string) || "")
370
- ) {
371
- needsMediaPlaceholder = true;
372
- out[k] = TRANSPARENT_PX;
373
- } else {
374
- out[k] = prepareForEditMode(v as JxMutableNode);
375
- }
630
+ out[k] = prepareNode(v, row);
376
631
  }
377
632
  }
378
633
 
379
634
  // Mark empty elements with placeholder classes for design-mode visibility
380
- const placeholderClass = computeEmptyPlaceholderClass(out as JxMutableNode);
635
+ const placeholderClass = computeEmptyPlaceholderClass(out);
381
636
  if (placeholderClass) {
382
637
  out.className = out.className ? `${out.className} ${placeholderClass}` : placeholderClass;
383
638
  }
384
639
 
385
640
  // Media elements with missing/dynamic src get a placeholder class
386
641
  if (needsMediaPlaceholder) {
387
- const cls = (out.className as string) || "";
642
+ const cls = isString(out.className) ? out.className : "";
388
643
  if (!cls.includes("empty-media-placeholder")) {
389
644
  out.className = cls ? `${cls} empty-media-placeholder` : "empty-media-placeholder";
390
645
  }
@@ -14,7 +14,7 @@
14
14
  */
15
15
 
16
16
  import { COMMON_SELECTORS } from "../store";
17
- import { displayTagName } from "@jxsuite/schema/guards";
17
+ import { displayTagName, isNonNullObject } from "@jxsuite/schema/guards";
18
18
  import { isPopover } from "@jxsuite/schema/overlays";
19
19
  import type { JxMutableNode } from "@jxsuite/schema/types";
20
20
 
@@ -62,7 +62,8 @@ function extraSelectorsFor(node: JxMutableNode): string[] {
62
62
  * @returns The offerable selectors.
63
63
  */
64
64
  export function selectorsForNode(node: JxMutableNode | null | undefined): string[] {
65
- if (!node || typeof node !== "object") {
65
+ // The style panel reads the node with getNodeAtPath, which can answer a bare string text child.
66
+ if (!isNonNullObject(node)) {
66
67
  return [...COMMON_SELECTORS];
67
68
  }
68
69
  return [...new Set([...COMMON_SELECTORS, ...extraSelectorsFor(node)])];