@jxsuite/studio 6.1.1 → 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 (637) hide show
  1. package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
  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-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
  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-1q1sh2ax.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-h46vtzk8.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-rv11kfwa.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-8grwxtqk.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-pre0skq6.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-vrmcjf9g.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-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-kggey1jt.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-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
  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-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
  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 +97 -97
  140. package/package.json +6 -6
  141. package/src/about/about-modal.ts +4 -3
  142. package/src/account/action-flow.ts +45 -38
  143. package/src/account-status.ts +7 -2
  144. package/src/browse/library-layouts.ts +8 -5
  145. package/src/browse/library-model.ts +18 -6
  146. package/src/browse/library-pane.ts +37 -21
  147. package/src/browse/library-preview.ts +14 -9
  148. package/src/browse/library-source.ts +1 -1
  149. package/src/canvas/asset-refs.ts +24 -9
  150. package/src/canvas/asset-resolve.ts +19 -23
  151. package/src/canvas/canvas-helpers.ts +7 -6
  152. package/src/canvas/canvas-live-render.ts +44 -53
  153. package/src/canvas/canvas-patcher.ts +30 -30
  154. package/src/canvas/canvas-perf.ts +11 -5
  155. package/src/canvas/canvas-render.ts +62 -41
  156. package/src/canvas/canvas-surface.ts +5 -3
  157. package/src/canvas/canvas-utils.ts +90 -49
  158. package/src/canvas/dialog-path.ts +9 -4
  159. package/src/canvas/dialog-state.ts +1 -2
  160. package/src/canvas/diff-marks.ts +9 -16
  161. package/src/canvas/diff-toolbar.ts +8 -7
  162. package/src/canvas/edit-width-drag.ts +4 -1
  163. package/src/canvas/edit-width.ts +1 -3
  164. package/src/canvas/iframe-channel.ts +27 -13
  165. package/src/canvas/iframe-drop.ts +13 -12
  166. package/src/canvas/iframe-editable-root.ts +29 -16
  167. package/src/canvas/iframe-entry.ts +80 -63
  168. package/src/canvas/iframe-eval.ts +73 -49
  169. package/src/canvas/iframe-host.ts +135 -96
  170. package/src/canvas/iframe-inline-edit.ts +49 -30
  171. package/src/canvas/iframe-insert.ts +5 -4
  172. package/src/canvas/iframe-interaction.ts +30 -25
  173. package/src/canvas/iframe-overlay.ts +1 -1
  174. package/src/canvas/iframe-patch.ts +18 -15
  175. package/src/canvas/iframe-position.ts +12 -6
  176. package/src/canvas/iframe-protocol.ts +12 -16
  177. package/src/canvas/iframe-render.ts +36 -34
  178. package/src/canvas/iframe-slash.ts +24 -11
  179. package/src/canvas/iframe-subtree.ts +6 -2
  180. package/src/canvas/path-mapping.ts +19 -12
  181. package/src/canvas/popover-path.ts +7 -3
  182. package/src/canvas/popover-state.ts +1 -2
  183. package/src/canvas/serialize-scope.ts +13 -5
  184. package/src/canvas/stage-scrollbar.ts +2 -1
  185. package/src/canvas/surface-registry.ts +21 -3
  186. package/src/collab/collab-commands.ts +7 -2
  187. package/src/collab/collab-session.ts +84 -45
  188. package/src/collab/collab-state.ts +4 -3
  189. package/src/collab/monaco-binding.ts +16 -13
  190. package/src/collab/monaco-cursors.ts +5 -2
  191. package/src/commands/budget.ts +3 -3
  192. package/src/commands/command-args.ts +103 -71
  193. package/src/commands/context.ts +22 -20
  194. package/src/commands/keymap.ts +47 -43
  195. package/src/commands/levels.ts +3 -3
  196. package/src/commands/live-context.ts +7 -7
  197. package/src/commands/reference.ts +2 -1
  198. package/src/commands/registry.ts +12 -10
  199. package/src/commands/run-reported.ts +15 -10
  200. package/src/component-props.ts +46 -30
  201. package/src/content/collection-match.ts +5 -4
  202. package/src/content/draft-state.ts +4 -3
  203. package/src/content/entry-commands.ts +3 -2
  204. package/src/content/entry-editor.ts +29 -17
  205. package/src/content/entry-fields.ts +12 -7
  206. package/src/content/entry-model.ts +21 -12
  207. package/src/editor/canvas-context-menu.ts +1 -2
  208. package/src/editor/canvas-slash-bridge.ts +3 -6
  209. package/src/editor/content-slice.ts +16 -14
  210. package/src/editor/context-menu.ts +35 -22
  211. package/src/editor/convert-targets.ts +30 -35
  212. package/src/editor/convert-to-component.ts +11 -5
  213. package/src/editor/convert-to-repeater.ts +34 -22
  214. package/src/editor/editable-tags.ts +17 -2
  215. package/src/editor/file-drop-action.ts +21 -22
  216. package/src/editor/inline-edit-apply.ts +35 -17
  217. package/src/editor/inline-edit.ts +66 -50
  218. package/src/editor/inline-format.ts +59 -56
  219. package/src/editor/inline-link.ts +40 -15
  220. package/src/editor/insert-zone-action.ts +1 -1
  221. package/src/editor/merge-tags.ts +58 -19
  222. package/src/editor/repeater-scope.ts +39 -28
  223. package/src/editor/shortcuts.ts +32 -20
  224. package/src/editor/slash-menu.ts +1 -6
  225. package/src/files/asset-versions.ts +4 -4
  226. package/src/files/components.ts +15 -10
  227. package/src/files/elements.ts +5 -6
  228. package/src/files/file-ops.ts +77 -36
  229. package/src/files/files.ts +90 -95
  230. package/src/files/media-meta.ts +2 -1
  231. package/src/files/media-paths.ts +3 -0
  232. package/src/files/serialize-document.ts +2 -2
  233. package/src/format/constraints.ts +1 -1
  234. package/src/format/convert-file.ts +27 -13
  235. package/src/format/format-choices.ts +2 -1
  236. package/src/format/format-host.ts +76 -50
  237. package/src/github/github-auth-status.ts +27 -3
  238. package/src/github/github-auth.ts +19 -9
  239. package/src/github/github-publish.ts +24 -20
  240. package/src/grid/cell-editors.ts +46 -31
  241. package/src/grid/cell-popovers.ts +5 -3
  242. package/src/grid/edit-buffer.ts +10 -9
  243. package/src/grid/grid-controller.ts +20 -22
  244. package/src/grid/grid-layout.ts +21 -5
  245. package/src/grid/grid-open.ts +3 -6
  246. package/src/grid/grid-panel.ts +11 -4
  247. package/src/grid/grid-source.ts +8 -8
  248. package/src/grid/grid-view.ts +14 -17
  249. package/src/grid/redirects-grid.ts +14 -5
  250. package/src/grid/redirects.ts +16 -14
  251. package/src/grid/schema-columns.ts +25 -19
  252. package/src/grid/sources/connector-source.ts +47 -20
  253. package/src/grid/sources/content-source.ts +25 -24
  254. package/src/grid/sources/csv-file-source.ts +2 -2
  255. package/src/grid/tabulator-tables.d.ts +55 -34
  256. package/src/hosting/stage.ts +7 -7
  257. package/src/i18n/i18n-commands.ts +1 -2
  258. package/src/media/media-pane.ts +4 -1
  259. package/src/new-project/add-repo-modal.ts +20 -19
  260. package/src/new-project/import-tab.ts +10 -14
  261. package/src/new-project/location-fields.ts +2 -1
  262. package/src/new-project/new-project-modal.ts +12 -9
  263. package/src/packages/jxsuite-update.ts +4 -3
  264. package/src/packages/pull-package-sync.ts +26 -25
  265. package/src/page-params.ts +97 -68
  266. package/src/panels/activity-panel.ts +17 -9
  267. package/src/panels/ai-chat/attached-context.ts +13 -7
  268. package/src/panels/ai-chat/chat-view.ts +80 -73
  269. package/src/panels/ai-chat/composer.ts +30 -33
  270. package/src/panels/ai-chat/sessions-view.ts +1 -2
  271. package/src/panels/ai-panel.ts +23 -20
  272. package/src/panels/block-action-bar.ts +46 -35
  273. package/src/panels/bottom-dock.ts +5 -3
  274. package/src/panels/canvas-dnd-bridge.ts +31 -24
  275. package/src/panels/data-explorer.ts +62 -25
  276. package/src/panels/data-grid.ts +14 -11
  277. package/src/panels/dnd.ts +108 -118
  278. package/src/panels/editors.ts +52 -21
  279. package/src/panels/elements-panel.ts +10 -3
  280. package/src/panels/events-panel.ts +84 -69
  281. package/src/panels/formula-workspace.ts +76 -51
  282. package/src/panels/frontmatter-fields.ts +24 -19
  283. package/src/panels/frontmatter-panel.ts +44 -34
  284. package/src/panels/git-diff-open.ts +4 -4
  285. package/src/panels/git-panel.ts +49 -61
  286. package/src/panels/head-panel.ts +131 -111
  287. package/src/panels/i18n-panel.ts +10 -3
  288. package/src/panels/imports-panel.ts +23 -47
  289. package/src/panels/jump-bar.ts +48 -29
  290. package/src/panels/layers-panel.ts +97 -74
  291. package/src/panels/left-panel.ts +3 -3
  292. package/src/panels/pane-context.ts +31 -22
  293. package/src/panels/pane-grid.ts +49 -20
  294. package/src/panels/panel-registry.ts +22 -37
  295. package/src/panels/properties-panel.ts +175 -121
  296. package/src/panels/quick-search.ts +53 -31
  297. package/src/panels/right-panel.ts +3 -3
  298. package/src/panels/seo-modal.ts +13 -17
  299. package/src/panels/settings-menu.ts +15 -15
  300. package/src/panels/signals-panel.ts +153 -131
  301. package/src/panels/statement-editor.ts +230 -140
  302. package/src/panels/style-panel.ts +218 -205
  303. package/src/panels/style-utils.ts +114 -51
  304. package/src/panels/stylebook-doc.ts +57 -54
  305. package/src/panels/stylebook-layers-panel.ts +9 -9
  306. package/src/panels/stylebook-panel.ts +13 -17
  307. package/src/panels/tab-drop.ts +27 -11
  308. package/src/panels/tab-strip.ts +36 -26
  309. package/src/platform-errors.ts +57 -43
  310. package/src/platform.ts +58 -30
  311. package/src/platforms/cloud.ts +345 -175
  312. package/src/platforms/default-platform.ts +10 -4
  313. package/src/platforms/devserver.ts +129 -117
  314. package/src/platforms/read-batcher.ts +16 -8
  315. package/src/project-list.ts +2 -1
  316. package/src/publish/deploy-checklist.ts +8 -2
  317. package/src/publish/pages-service.ts +28 -13
  318. package/src/publish/publish-commands.ts +5 -4
  319. package/src/publish/publish-panel.ts +10 -6
  320. package/src/recent-projects.ts +15 -8
  321. package/src/resize-edges.ts +26 -36
  322. package/src/services/a11y-report.ts +26 -19
  323. package/src/services/agent-seed.ts +23 -11
  324. package/src/services/ai-ask.ts +9 -12
  325. package/src/services/ai-command-tools.ts +68 -62
  326. package/src/services/ai-import-tools.ts +80 -67
  327. package/src/services/ai-models.ts +17 -13
  328. package/src/services/ai-project-tools.ts +68 -32
  329. package/src/services/ai-session-store.ts +19 -10
  330. package/src/services/ai-system-prompt.ts +46 -20
  331. package/src/services/ai-tools.ts +71 -27
  332. package/src/services/ai-write-report.ts +20 -12
  333. package/src/services/ai-writes.ts +4 -4
  334. package/src/services/automation.ts +58 -31
  335. package/src/services/cem-export.ts +149 -58
  336. package/src/services/clock.ts +6 -1
  337. package/src/services/code-services.ts +37 -31
  338. package/src/services/context-manager.ts +14 -10
  339. package/src/services/context-resolver.ts +20 -8
  340. package/src/services/data-service.ts +19 -15
  341. package/src/services/directory-picker.ts +18 -12
  342. package/src/services/document-assistant.ts +39 -19
  343. package/src/services/gated-registry.ts +10 -6
  344. package/src/services/harness/chat-reducer.ts +23 -1
  345. package/src/services/import-client.ts +91 -38
  346. package/src/services/import-seed.ts +8 -2
  347. package/src/services/jx-validate.ts +28 -31
  348. package/src/services/live-preview.ts +0 -0
  349. package/src/services/live-surfaces.ts +6 -3
  350. package/src/services/model-uri.ts +10 -2
  351. package/src/services/module-preloads.ts +12 -8
  352. package/src/services/monaco-buffer.ts +43 -24
  353. package/src/services/monaco-lazy.ts +7 -8
  354. package/src/services/monaco-setup.ts +23 -16
  355. package/src/services/notify.ts +44 -17
  356. package/src/services/popover-report.ts +25 -10
  357. package/src/services/preview-eval.ts +20 -8
  358. package/src/services/profile.ts +13 -6
  359. package/src/services/project-path.ts +13 -10
  360. package/src/services/references.ts +0 -0
  361. package/src/services/render-critic.ts +8 -7
  362. package/src/services/settings/kernel.ts +13 -4
  363. package/src/services/settings/write-queue.ts +9 -9
  364. package/src/services/token-lint.ts +12 -10
  365. package/src/services/tool-executor.ts +17 -5
  366. package/src/services/tool-outcomes.ts +44 -24
  367. package/src/services/trusted-types.ts +24 -7
  368. package/src/settings/contexts-section.ts +11 -8
  369. package/src/settings/contributed-section.ts +79 -60
  370. package/src/settings/css-vars-editor.ts +37 -16
  371. package/src/settings/defs-editor.ts +38 -35
  372. package/src/settings/extension-rows.ts +16 -8
  373. package/src/settings/extension-sections.ts +23 -13
  374. package/src/settings/extensions-section.ts +4 -1
  375. package/src/settings/general-settings.ts +11 -8
  376. package/src/settings/locales-section.ts +20 -12
  377. package/src/settings/preferences-dialog.ts +9 -6
  378. package/src/settings/preferences-keymap.ts +7 -5
  379. package/src/settings/preferences-sections.ts +11 -5
  380. package/src/settings/project-sections.ts +1 -1
  381. package/src/settings/schema-field-ui.ts +9 -0
  382. package/src/settings/settings-document.ts +5 -5
  383. package/src/shell/tree.ts +6 -5
  384. package/src/shell.ts +104 -81
  385. package/src/site-context.ts +37 -22
  386. package/src/state.ts +41 -49
  387. package/src/store.ts +54 -34
  388. package/src/studio.ts +25 -75
  389. package/src/style/live-preview.ts +1 -1
  390. package/src/style/project-styles.ts +6 -7
  391. package/src/style/token-ref.ts +5 -4
  392. package/src/surfaces/about.ts +18 -19
  393. package/src/surfaces/add-repo.ts +17 -19
  394. package/src/surfaces/ai-chat.ts +31 -36
  395. package/src/surfaces/ai-credentials-form.ts +6 -16
  396. package/src/surfaces/ai-managed-connect.ts +3 -4
  397. package/src/surfaces/ai-model-picker.ts +3 -5
  398. package/src/surfaces/block-action-bar.ts +22 -11
  399. package/src/surfaces/boot-failure.ts +4 -5
  400. package/src/surfaces/bottom-dock.ts +9 -18
  401. package/src/surfaces/canvas-stage.ts +12 -11
  402. package/src/surfaces/cf-account-picker.ts +17 -18
  403. package/src/surfaces/commandbar.ts +14 -9
  404. package/src/surfaces/convert-repeater.ts +17 -19
  405. package/src/surfaces/data-actions.ts +9 -7
  406. package/src/surfaces/dialog.ts +26 -28
  407. package/src/surfaces/diff-toolbar.ts +9 -7
  408. package/src/surfaces/doc-header.ts +10 -19
  409. package/src/surfaces/empty-state.ts +7 -10
  410. package/src/surfaces/entry-editor.ts +14 -11
  411. package/src/surfaces/expression-editor.ts +11 -25
  412. package/src/surfaces/files-panel.ts +27 -14
  413. package/src/surfaces/formula-palette.ts +4 -5
  414. package/src/surfaces/git-panel.ts +7 -15
  415. package/src/surfaces/github-auth.ts +16 -20
  416. package/src/surfaces/github-publish.ts +17 -22
  417. package/src/surfaces/grid-cell.ts +30 -31
  418. package/src/surfaces/grid-open.ts +10 -14
  419. package/src/surfaces/grid-panel.ts +13 -9
  420. package/src/surfaces/grid-replace.ts +13 -13
  421. package/src/surfaces/grid-views.ts +15 -18
  422. package/src/surfaces/inspector-dock.ts +13 -12
  423. package/src/surfaces/jump-bar.ts +5 -6
  424. package/src/surfaces/jxsuite-update.ts +16 -22
  425. package/src/surfaces/library-pane.ts +19 -20
  426. package/src/surfaces/logic-panel.ts +17 -30
  427. package/src/surfaces/logic-workspace.ts +13 -15
  428. package/src/surfaces/media-browser.ts +11 -10
  429. package/src/surfaces/media-field.ts +4 -5
  430. package/src/surfaces/media-pane.ts +8 -7
  431. package/src/surfaces/menu.ts +29 -23
  432. package/src/surfaces/navigator-dock.ts +11 -12
  433. package/src/surfaces/new-project.ts +27 -26
  434. package/src/surfaces/pane-context.ts +20 -25
  435. package/src/surfaces/pane-grid.ts +15 -10
  436. package/src/surfaces/panel-activity.ts +5 -6
  437. package/src/surfaces/panel-data.ts +3 -4
  438. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  439. package/src/surfaces/panel-elements.ts +5 -7
  440. package/src/surfaces/panel-i18n.ts +5 -7
  441. package/src/surfaces/panel-imports.ts +6 -13
  442. package/src/surfaces/panel-outline.ts +25 -19
  443. package/src/surfaces/panel-page.ts +11 -18
  444. package/src/surfaces/panel-problems.ts +5 -7
  445. package/src/surfaces/panel-signals.ts +20 -34
  446. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  447. package/src/surfaces/preferences.ts +21 -11
  448. package/src/surfaces/progress-modal.ts +15 -9
  449. package/src/surfaces/properties-panel.json +1 -1
  450. package/src/surfaces/properties-panel.ts +20 -42
  451. package/src/surfaces/publish.ts +18 -18
  452. package/src/surfaces/push-plan.ts +7 -8
  453. package/src/surfaces/rail.ts +13 -13
  454. package/src/surfaces/reference-field.ts +11 -15
  455. package/src/surfaces/schema-builder.ts +16 -22
  456. package/src/surfaces/schema-form.ts +15 -25
  457. package/src/surfaces/secret-field.ts +9 -6
  458. package/src/surfaces/seo.ts +21 -15
  459. package/src/surfaces/settings-contexts.ts +9 -7
  460. package/src/surfaces/settings-contributed.ts +14 -10
  461. package/src/surfaces/settings-css-vars.ts +5 -12
  462. package/src/surfaces/settings-defs.json +2 -2
  463. package/src/surfaces/settings-defs.ts +17 -21
  464. package/src/surfaces/settings-deploy.ts +8 -15
  465. package/src/surfaces/settings-extensions.ts +5 -6
  466. package/src/surfaces/settings-head.ts +33 -39
  467. package/src/surfaces/settings-locales.ts +8 -20
  468. package/src/surfaces/settings-overview.ts +5 -6
  469. package/src/surfaces/settings-packages.ts +8 -7
  470. package/src/surfaces/settings-pane.ts +9 -18
  471. package/src/surfaces/settings-rawjson.ts +5 -6
  472. package/src/surfaces/shell.ts +1 -2
  473. package/src/surfaces/slash-menu.ts +19 -9
  474. package/src/surfaces/statements.ts +13 -18
  475. package/src/surfaces/statusbar.ts +17 -14
  476. package/src/surfaces/style-panel.ts +18 -31
  477. package/src/surfaces/stylebook-chrome.ts +3 -5
  478. package/src/surfaces/tab-strip.ts +14 -13
  479. package/src/surfaces/target-line.ts +6 -7
  480. package/src/surfaces/welcome.ts +5 -7
  481. package/src/tabs/patch-ops.ts +4 -3
  482. package/src/tabs/project-config.ts +32 -21
  483. package/src/tabs/selection.ts +36 -8
  484. package/src/tabs/tab.ts +52 -41
  485. package/src/tabs/transact.ts +98 -53
  486. package/src/types.ts +32 -17
  487. package/src/ui/ai-credentials-form.ts +10 -13
  488. package/src/ui/ai-model-picker.ts +3 -3
  489. package/src/ui/cf-account-picker.ts +7 -9
  490. package/src/ui/color-selector.ts +9 -5
  491. package/src/ui/dynamic-slot.ts +7 -8
  492. package/src/ui/expression-editor.ts +112 -105
  493. package/src/ui/form-controls.ts +57 -48
  494. package/src/ui/formula-catalog.ts +239 -230
  495. package/src/ui/formula-chips.ts +33 -18
  496. package/src/ui/layers.ts +44 -31
  497. package/src/ui/media-picker.ts +18 -9
  498. package/src/ui/popover-surface.ts +20 -12
  499. package/src/ui/progress-modal.ts +13 -8
  500. package/src/ui/regions.ts +7 -6
  501. package/src/ui/schema-form.ts +113 -70
  502. package/src/ui/surface.ts +71 -8
  503. package/src/ui/timing.ts +9 -0
  504. package/src/ui/value-source.ts +44 -31
  505. package/src/ui/virtual-window.ts +3 -2
  506. package/src/utils/base64.ts +3 -1
  507. package/src/utils/edit-display.ts +73 -73
  508. package/src/utils/element-selectors.ts +3 -2
  509. package/src/utils/google-fonts.ts +15 -14
  510. package/src/utils/inherited-style.ts +18 -20
  511. package/src/utils/link-target.ts +1 -1
  512. package/src/utils/preview-format.ts +25 -3
  513. package/src/utils/strip-events.ts +49 -22
  514. package/src/utils/studio-utils.ts +29 -14
  515. package/src/view.ts +2 -3
  516. package/src/workspace/pane-derive.ts +10 -12
  517. package/src/workspace/session.ts +53 -43
  518. package/src/workspace/workspace.ts +40 -36
  519. package/dist/chunks/adapter-f93pafd7.js +0 -4
  520. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  521. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  522. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  523. package/dist/chunks/color-field-embq5ctg.js +0 -4
  524. package/dist/chunks/color-fpezvnkt.js +0 -4
  525. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  526. package/dist/chunks/combobox-773hdzyj.js +0 -4
  527. package/dist/chunks/components-ax2f1fnn.js +0 -4
  528. package/dist/chunks/content-source-108aqtk1.js +0 -4
  529. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  530. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  531. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  532. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  533. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  534. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  535. package/dist/chunks/files-44vp8a2s.js +0 -4
  536. package/dist/chunks/format-host-7q1petb9.js +0 -4
  537. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  538. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  539. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  540. package/dist/chunks/icons-p44xhjf0.js +0 -4
  541. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  542. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  543. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  544. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  545. package/dist/chunks/index-wkyfjeqz.js +0 -4
  546. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  547. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  548. package/dist/chunks/layers-xd92fg8d.js +0 -4
  549. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  550. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  551. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  552. package/dist/chunks/menu-37d07z9m.js +0 -4
  553. package/dist/chunks/menu-5c55ea3d.js +0 -4
  554. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  555. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  556. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  557. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  558. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  559. package/dist/chunks/parse-897fvqah.js +0 -4
  560. package/dist/chunks/platform-v1qctbe6.js +0 -4
  561. package/dist/chunks/popover-8htra4er.js +0 -4
  562. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  563. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  564. package/dist/chunks/references-gmqp82fs.js +0 -4
  565. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  566. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  567. package/dist/chunks/select-n3v7gwas.js +0 -4
  568. package/dist/chunks/split-pff8f3ze.js +0 -4
  569. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  570. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  571. package/dist/chunks/studio-1b04pd0j.js +0 -64
  572. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  573. package/dist/chunks/studio-4tanh828.js +0 -5
  574. package/dist/chunks/studio-55h4mstj.js +0 -4
  575. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  576. package/dist/chunks/studio-60dqgb0c.js +0 -5
  577. package/dist/chunks/studio-61dp09qg.js +0 -9
  578. package/dist/chunks/studio-63epcrj2.js +0 -5
  579. package/dist/chunks/studio-74k29dy9.js +0 -5
  580. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  581. package/dist/chunks/studio-7zx31knw.js +0 -9
  582. package/dist/chunks/studio-8bxk97km.js +0 -5
  583. package/dist/chunks/studio-933e30n4.js +0 -5
  584. package/dist/chunks/studio-98wnwhbg.js +0 -5
  585. package/dist/chunks/studio-9mccjwjh.js +0 -14
  586. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  587. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  588. package/dist/chunks/studio-e81q1vb9.js +0 -5
  589. package/dist/chunks/studio-epgrmqqm.js +0 -5
  590. package/dist/chunks/studio-ery42sqr.js +0 -4
  591. package/dist/chunks/studio-g1shz58g.js +0 -5
  592. package/dist/chunks/studio-gf0fz03c.js +0 -5
  593. package/dist/chunks/studio-gjtpe62q.js +0 -6
  594. package/dist/chunks/studio-gkskhg7m.js +0 -5
  595. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  596. package/dist/chunks/studio-j03zga3y.js +0 -9
  597. package/dist/chunks/studio-jhpxeckz.js +0 -5
  598. package/dist/chunks/studio-k01r7ykp.js +0 -5
  599. package/dist/chunks/studio-kk7h30ne.js +0 -7
  600. package/dist/chunks/studio-kt1zqney.js +0 -5
  601. package/dist/chunks/studio-m3cwhvye.js +0 -5
  602. package/dist/chunks/studio-mcayt6hz.js +0 -5
  603. package/dist/chunks/studio-myjcghv3.js +0 -5
  604. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  605. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  606. package/dist/chunks/studio-nj5a01jy.js +0 -928
  607. package/dist/chunks/studio-pcgz8heb.js +0 -5
  608. package/dist/chunks/studio-qcsq0t15.js +0 -5
  609. package/dist/chunks/studio-qkstvve9.js +0 -5
  610. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  611. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  612. package/dist/chunks/studio-s8dmmz66.js +0 -5
  613. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  614. package/dist/chunks/studio-szsjbj0g.js +0 -5
  615. package/dist/chunks/studio-t1xzawhr.js +0 -16
  616. package/dist/chunks/studio-t6b6qe31.js +0 -5
  617. package/dist/chunks/studio-tdcprbqb.js +0 -5
  618. package/dist/chunks/studio-vyc0b4he.js +0 -10
  619. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  620. package/dist/chunks/studio-w3hskzqk.js +0 -5
  621. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  622. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  623. package/dist/chunks/studio-y6n42tgs.js +0 -5
  624. package/dist/chunks/studio-yb560vxr.js +0 -5
  625. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  626. package/dist/chunks/studio-yw05w8f0.js +0 -7
  627. package/dist/chunks/studio-z16sgavc.js +0 -5
  628. package/dist/chunks/studio-zyqn40w4.js +0 -5
  629. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  630. package/dist/chunks/tabs-jwthg40w.js +0 -4
  631. package/dist/chunks/textfield-spy3hc77.js +0 -4
  632. package/dist/chunks/toast-4d35zd64.js +0 -4
  633. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  634. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  635. package/dist/chunks/tree-h19v1jfz.js +0 -4
  636. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  637. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
package/src/panels/dnd.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  monitorForElements,
11
11
  } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
12
12
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
13
- import { displayTagName } from "@jxsuite/schema/guards";
13
+ import { displayTagName, isNumber } from "@jxsuite/schema/guards";
14
14
  import { disableNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview";
15
15
  import {
16
16
  attachInstruction,
@@ -38,8 +38,10 @@ import { defaultDef, unsafeTags } from "./shared";
38
38
  import { elementAtPoint } from "../utils/geometry";
39
39
  import type { JxPath } from "../state";
40
40
  import type { Tab } from "../tabs/tab";
41
- import type { JxElement, JxMutableNode } from "@jxsuite/schema/types";
41
+ import type { JxMutableNode } from "@jxsuite/schema/types";
42
42
  import type { ComponentEntry } from "../files/components.js";
43
+ import type { ElementDragPayload } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
44
+ import type { DropTargetRecord } from "@atlaskit/pragmatic-drag-and-drop/types";
43
45
 
44
46
  interface DragCanDragArgs {
45
47
  element: HTMLElement;
@@ -51,17 +53,10 @@ interface DragPreviewArgs {
51
53
  nativeSetDragImage: ((image: Element, x: number, y: number) => void) | null;
52
54
  }
53
55
 
54
- interface DragDropSourceArgs {
55
- source: { data: Record<string, unknown>; element: HTMLElement };
56
- }
57
-
58
- interface DragSelfArgs {
59
- self: { data: Record<string, unknown> };
60
- }
61
-
62
- interface DragMonitorDropArgs {
63
- source: { data: Record<string, unknown>; element: HTMLElement };
64
- location: { current: { dropTargets: { data: Record<string, unknown> }[] } };
56
+ /** Where a drop instruction inserts: the parent's path and the index among its children. */
57
+ interface DropSlot {
58
+ parent: JxPath;
59
+ index: number;
65
60
  }
66
61
 
67
62
  /**
@@ -122,23 +117,25 @@ export function registerLayersDnD() {
122
117
  view.dndCleanups = [];
123
118
  _layersFrame = requestAnimationFrame(() => {
124
119
  _layersFrame = null;
125
- const container = leftPanel?.querySelector(OUTLINE_ROOT) as HTMLElement | null;
120
+ const container = leftPanel?.querySelector<HTMLElement>(OUTLINE_ROOT);
126
121
  if (!container) {
127
122
  return;
128
123
  }
129
124
 
130
- for (const row of container.querySelectorAll("[data-dnd-row]") as NodeListOf<HTMLElement>) {
131
- const rowPath = (row.dataset.value as string)
125
+ for (const row of container.querySelectorAll<HTMLElement>("[data-dnd-row]")) {
126
+ /* SAFETY: every `[data-dnd-row]` row is a `jx-tree-item` from panel-outline.json, and the
127
+ element reflects its `value` (the row's path key) onto the host as `data-value`. */
128
+ const rowPath: JxPath = (row.dataset.value as string)
132
129
  .split("/")
133
- .map((s: string) => (/^\d+$/.test(s) ? Math.trunc(Number(s)) : s)) as JxPath;
134
- const rowDepth = Math.trunc(Number(row.dataset.dndDepth as string)) || 0;
130
+ .map((s: string) => (/^\d+$/.test(s) ? Math.trunc(Number(s)) : s));
131
+ const rowDepth = Math.trunc(Number(row.dataset.dndDepth)) || 0;
135
132
  const isVoid = Object.hasOwn(row.dataset, "dndVoid");
136
133
  const isExpanded = Object.hasOwn(row.dataset, "dndExpanded");
137
134
 
138
135
  const cleanup = combine(
139
136
  draggable({
140
137
  canDrag({ element: _el, input }: DragCanDragArgs) {
141
- const target = elementAtPoint(input.clientX, input.clientY) as HTMLElement;
138
+ const target = elementAtPoint(input.clientX, input.clientY);
142
139
  if (target?.closest(OUTLINE_ACTIONS)) {
143
140
  return false;
144
141
  }
@@ -169,9 +166,10 @@ export function registerLayersDnD() {
169
166
  }),
170
167
  dropTargetForElements({
171
168
  element: row,
172
- canDrop({ source }: DragDropSourceArgs) {
173
- const srcPath = source.data.path as JxPath | undefined;
174
- if (srcPath && isAncestor(srcPath, rowPath)) {
169
+ canDrop({ source }) {
170
+ // Only a tree-node drag carries a path array; a file-tree drag's `path` is a string.
171
+ const srcPath = source.data.path;
172
+ if (Array.isArray(srcPath) && isAncestor(srcPath, rowPath)) {
175
173
  return false;
176
174
  }
177
175
  return true;
@@ -193,12 +191,12 @@ export function registerLayersDnD() {
193
191
  input,
194
192
  mode: isExpanded ? "expanded" : "standard",
195
193
  },
196
- ) as Record<string | symbol, unknown>;
194
+ );
197
195
  },
198
- onDragEnter({ self }: DragSelfArgs) {
196
+ onDragEnter({ self }) {
199
197
  showLayerDropGap(row, self.data, container);
200
198
  },
201
- onDrag({ self }: DragSelfArgs) {
199
+ onDrag({ self }) {
202
200
  showLayerDropGap(row, self.data, container);
203
201
  },
204
202
  // No onDragLeave clear — the gap persists while the pointer crosses dead space
@@ -213,7 +211,7 @@ export function registerLayersDnD() {
213
211
 
214
212
  // Global monitor
215
213
  const monitorCleanup = monitorForElements({
216
- onDrop({ source, location }: DragMonitorDropArgs) {
214
+ onDrop({ source, location }) {
217
215
  clearLayerDropGap(container);
218
216
  const [target] = location.current.dropTargets;
219
217
  if (!target) {
@@ -224,7 +222,13 @@ export function registerLayersDnD() {
224
222
  return;
225
223
  }
226
224
  const srcData = source.data;
227
- const targetPath = target.data.path as JxPath;
225
+ /* Only an Outline row's data carries a path. The Logic tab's statement rows attach tree-item
226
+ instructions too, and the drags they accept (statements) are ones applyDropInstruction
227
+ ignores, so a drop there has nothing to apply. */
228
+ const targetPath = target.data.path;
229
+ if (!Array.isArray(targetPath)) {
230
+ return;
231
+ }
228
232
 
229
233
  // If the source had children, persist collapse at the new location
230
234
  const srcRow = srcData.type === "tree-node" && source.element;
@@ -243,7 +247,7 @@ export function registerLayersDnD() {
243
247
  }
244
248
  }
245
249
  },
246
- onDropTargetChange({ location }: DragMonitorDropArgs) {
250
+ onDropTargetChange({ location }) {
247
251
  // Clear the layer gap when the drag moves onto a non-tree target (e.g. a canvas
248
252
  // Element). When there is no target at all, keep the gap so it persists.
249
253
  const [inner] = location.current.dropTargets;
@@ -259,14 +263,12 @@ export function registerLayersDnD() {
259
263
  /** Register DnD on component rows — called from renderLeftPanel when tab=components */
260
264
  export function registerComponentsDnD() {
261
265
  requestAnimationFrame(() => {
262
- const container = leftPanel?.querySelector(".components-section") as HTMLElement | null;
266
+ const container = leftPanel?.querySelector<HTMLElement>(".components-section");
263
267
  if (!container) {
264
268
  return;
265
269
  }
266
270
 
267
- for (const row of container.querySelectorAll(
268
- "[data-component-tag]",
269
- ) as NodeListOf<HTMLElement>) {
271
+ for (const row of container.querySelectorAll<HTMLElement>("[data-component-tag]")) {
270
272
  const tagName = row.dataset.componentTag;
271
273
  if (!tagName) {
272
274
  continue;
@@ -303,11 +305,12 @@ export function registerComponentsDnD() {
303
305
  /** Register DnD on element (HTML block) rows */
304
306
  export function registerElementsDnD() {
305
307
  requestAnimationFrame(() => {
306
- const container = leftPanel?.querySelector('[part="content"]') as HTMLElement | null;
308
+ const container = leftPanel?.querySelector<HTMLElement>('[part="content"]');
307
309
  if (!container) {
308
310
  return;
309
311
  }
310
- for (const row of container.querySelectorAll("[data-block-tag]") as NodeListOf<HTMLElement>) {
312
+ for (const row of container.querySelectorAll<HTMLElement>("[data-block-tag]")) {
313
+ // SAFETY: the selector matched on `data-block-tag`, so the attribute is present and this is its text.
311
314
  const tag = row.dataset.blockTag as string;
312
315
  const preview = row.querySelector(".element-card-preview");
313
316
  if (preview && !preview.firstChild) {
@@ -338,22 +341,22 @@ export function registerElementsDnD() {
338
341
  */
339
342
  function hideDescendantRows(parentRow: HTMLElement, container: HTMLElement) {
340
343
  const prefix = `${parentRow.dataset.value}/`;
341
- const rows = container.querySelectorAll(OUTLINE_ROWS);
344
+ const rows = container.querySelectorAll<HTMLElement>(OUTLINE_ROWS);
342
345
  for (const r of rows) {
343
- if ((r as HTMLElement).dataset.value?.startsWith(prefix)) {
344
- (r as HTMLElement).style.display = "none";
346
+ if (r.dataset.value?.startsWith(prefix)) {
347
+ r.style.display = "none";
345
348
  }
346
349
  }
347
350
  }
348
351
 
349
352
  /**
350
353
  * @param {HTMLElement} rowEl
351
- * @param {Record<string, unknown>} data
354
+ * @param {DropTargetRecord["data"]} data The row's own drop-target data, carrying its instruction.
352
355
  * @param {HTMLElement} container
353
356
  */
354
357
  export function showLayerDropGap(
355
358
  rowEl: HTMLElement,
356
- data: Record<string, unknown>,
359
+ data: DropTargetRecord["data"],
357
360
  container: HTMLElement,
358
361
  ) {
359
362
  const instruction = extractInstruction(data);
@@ -379,18 +382,18 @@ export function showLayerDropGap(
379
382
  view._currentDropTargetRow = rowEl;
380
383
 
381
384
  // Shift rows to create gap
382
- const rows = [...container.querySelectorAll(OUTLINE_ROWS)];
385
+ const rows = [...container.querySelectorAll<HTMLElement>(OUTLINE_ROWS)];
383
386
  const targetIdx = rows.indexOf(rowEl);
384
387
  const gap = view.layerDragSourceHeight;
385
388
 
386
- for (let i = 0; i < rows.length; i++) {
387
- if ((rows[i] as HTMLElement).dataset.dragging !== undefined) {
389
+ for (const [i, row] of rows.entries()) {
390
+ if (row.dataset.dragging !== undefined) {
388
391
  continue;
389
392
  }
390
393
  if (instruction.type === "reorder-above") {
391
- (rows[i] as HTMLElement).style.transform = i >= targetIdx ? `translateY(${gap}px)` : "";
394
+ row.style.transform = i >= targetIdx ? `translateY(${gap}px)` : "";
392
395
  } else {
393
- (rows[i] as HTMLElement).style.transform = i > targetIdx ? `translateY(${gap}px)` : "";
396
+ row.style.transform = i > targetIdx ? `translateY(${gap}px)` : "";
394
397
  }
395
398
  }
396
399
  }
@@ -401,18 +404,53 @@ export function clearLayerDropGap(container: HTMLElement) {
401
404
  delete view._currentDropTargetRow.dataset.drop;
402
405
  view._currentDropTargetRow = null;
403
406
  }
404
- const rows = container.querySelectorAll(OUTLINE_ROWS);
407
+ const rows = container.querySelectorAll<HTMLElement>(OUTLINE_ROWS);
405
408
  for (const r of rows) {
406
- (r as HTMLElement).style.transform = "";
409
+ r.style.transform = "";
407
410
  // Also clear `display:none` left by hideDescendantRows. The row has no `style`
408
411
  // Lit binding, so an imperative style set during the drag survives the post-drop re-render on
409
412
  // Whichever row keeps that key — and a move is exactly the edit that hands a key to a different
410
413
  // Node. (The rows ARE keyed, by `pathKey`; the earlier form of this note said they were not,
411
414
  // Which made the wrong thing sound load-bearing. What is load-bearing is the missing binding.)
412
- (r as HTMLElement).style.display = "";
415
+ r.style.display = "";
413
416
  }
414
417
  }
415
418
 
419
+ /**
420
+ * Where a drop instruction lands relative to `targetPath`.
421
+ *
422
+ * `make-child` appends to the target itself. A reorder lands beside it, which needs a parent and a
423
+ * numeric index, so a reorder (or any other instruction) around a root-level path answers
424
+ * `undefined`: the drop cannot land there at all. `null` is an instruction that lands but inserts
425
+ * nothing, which this module does not apply.
426
+ *
427
+ * @param {JxMutableNode} doc
428
+ * @param {string} type
429
+ * @param {JxPath} targetPath
430
+ * @returns {DropSlot | null | undefined}
431
+ */
432
+ function dropSlot(
433
+ doc: JxMutableNode,
434
+ type: string,
435
+ targetPath: JxPath,
436
+ ): DropSlot | null | undefined {
437
+ if (type === "make-child") {
438
+ return { index: childList(getNodeAtPath(doc, targetPath)).length, parent: targetPath };
439
+ }
440
+ const parent = parentElementPath(targetPath);
441
+ const index = childIndex(targetPath);
442
+ if (!parent || !isNumber(index)) {
443
+ return undefined;
444
+ }
445
+ if (type === "reorder-above") {
446
+ return { index, parent };
447
+ }
448
+ if (type === "reorder-below") {
449
+ return { index: index + 1, parent };
450
+ }
451
+ return null;
452
+ }
453
+
416
454
  /**
417
455
  * Apply a DnD instruction to `tab`'s document. `tab` is the tab whose canvas the drop resolved in
418
456
  * (host-routed for iframe drops — never the active tab at message time, which may have changed
@@ -420,89 +458,39 @@ export function clearLayerDropGap(container: HTMLElement) {
420
458
  *
421
459
  * @param {Tab | null} tab
422
460
  * @param {{ type: string }} instruction
423
- * @param {Record<string, unknown>} srcData
461
+ * @param {ElementDragPayload["data"]} srcData The drag source's own data, as `getInitialData` made
462
+ * it.
424
463
  * @param {JxPath} targetPath
425
464
  */
426
465
  export function applyDropInstruction(
427
466
  tab: Tab | null,
428
467
  instruction: { type: string },
429
- srcData: Record<string, unknown>,
468
+ srcData: ElementDragPayload["data"],
430
469
  targetPath: JxPath,
431
470
  ) {
432
471
  if (!tab) {
433
472
  return;
434
473
  }
435
- const doc = tab.doc.document as JxMutableNode;
436
474
  if (srcData.type === "tree-node") {
475
+ /* SAFETY: both minters of a "tree-node" payload — an Outline row's `getInitialData` and the
476
+ block action bar's drag handle — set `path` to the dragged node's JxPath. */
437
477
  const fromPath = srcData.path as JxPath;
438
- const targetParent = parentElementPath(targetPath) as JxPath;
439
- const targetIdx = childIndex(targetPath) as number;
440
- // Reordering requires a parent and a numeric index; root-level paths can't be
441
- // Reordered around.
442
- if (instruction.type !== "make-child" && (!targetParent || typeof targetIdx !== "number")) {
443
- return;
444
- }
445
-
446
- switch (instruction.type) {
447
- case "reorder-above": {
448
- transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetParent, targetIdx));
449
- break;
450
- }
451
- case "reorder-below": {
452
- transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetParent, targetIdx + 1));
453
- break;
454
- }
455
- case "make-child": {
456
- const target = getNodeAtPath(doc, targetPath);
457
- const len = childList(target).length;
458
- transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetPath, len));
459
- break;
460
- }
461
- default: {
462
- break;
463
- }
478
+ const slot = dropSlot(tab.doc.document, instruction.type, targetPath);
479
+ if (slot) {
480
+ transactDoc(tab, (t) => mutateMoveNode(t, fromPath, slot.parent, slot.index));
464
481
  }
465
482
  } else if (srcData.type === "block") {
466
- const targetParent = parentElementPath(targetPath) as JxPath;
467
- const targetIdx = childIndex(targetPath) as number;
468
- if (instruction.type !== "make-child" && (!targetParent || typeof targetIdx !== "number")) {
483
+ const slot = dropSlot(tab.doc.document, instruction.type, targetPath);
484
+ if (slot === undefined) {
469
485
  return;
470
486
  }
471
-
472
- switch (instruction.type) {
473
- case "reorder-above": {
474
- transactDoc(tab, (t) =>
475
- mutateInsertNode(
476
- t,
477
- targetParent,
478
- targetIdx,
479
- structuredClone(srcData.fragment as JxMutableNode),
480
- ),
481
- );
482
- break;
483
- }
484
- case "reorder-below": {
485
- transactDoc(tab, (t) =>
486
- mutateInsertNode(
487
- t,
488
- targetParent,
489
- targetIdx + 1,
490
- structuredClone(srcData.fragment as JxMutableNode),
491
- ),
492
- );
493
- break;
494
- }
495
- case "make-child": {
496
- const target = getNodeAtPath(doc, targetPath);
497
- const len = childList(target).length;
498
- transactDoc(tab, (t) =>
499
- mutateInsertNode(t, targetPath, len, structuredClone(srcData.fragment as JxMutableNode)),
500
- );
501
- break;
502
- }
503
- default: {
504
- break;
505
- }
487
+ /* SAFETY: every minter of a "block" payload — the Insert palette's element and component cards
488
+ and the file drop (`file-drop-action.ts`) — sets `fragment` to the JxMutableNode it inserts. */
489
+ const fragment = srcData.fragment as JxMutableNode;
490
+ if (slot) {
491
+ transactDoc(tab, (t) =>
492
+ mutateInsertNode(t, slot.parent, slot.index, structuredClone(fragment)),
493
+ );
506
494
  }
507
495
 
508
496
  /* Auto-import to `$elements` if the dropped block is a custom component.
@@ -510,18 +498,20 @@ export function applyDropInstruction(
510
498
  had its own duplicate rule and matched a local component by `ref.endsWith(basename)`, so
511
499
  dropping `./components/card.json` into a page that already imported `./vendor/card.json`
512
500
  counted as already imported and produced an element the page could not resolve. */
513
- const fragment = srcData.fragment as JxMutableNode | undefined;
514
- const tag = fragment?.tagName;
501
+ const tag = fragment.tagName;
515
502
  if (displayTagName(tag).includes("-")) {
516
503
  const comp = componentRegistry.find((c: ComponentEntry) => c.tagName === tag);
517
- const before = (tab.doc.document?.$elements ?? []) as ElementsEntry[];
504
+ /* SAFETY: `$elements` holds module specifiers and `{ $ref }` imports; the document type and
505
+ files/elements.ts spell an inline entry as JxMutableNode and JxElement respectively, two
506
+ editor views of the same JSON object that enableElement only compares by `$ref`. */
507
+ const before = (tab.doc.document.$elements ?? []) as ElementsEntry[];
518
508
  const after = comp ? enableElement(before, comp, tab.documentPath ?? null) : before;
519
509
  // Only when the list actually GREW. A component the registry cannot name — an npm entry with
520
510
  // No package, a local one with no path — returns the list unchanged, and writing that back
521
511
  // Would put an empty `$elements: []` on a document that had none.
522
512
  if (after.length !== before.length) {
523
513
  transact(tab, (d: JxMutableNode) => {
524
- d.$elements = after as (string | JxElement)[];
514
+ d.$elements = after;
525
515
  });
526
516
  }
527
517
  }
@@ -33,9 +33,10 @@
33
33
  import type * as monaco from "monaco-editor";
34
34
  import { loadMonaco, mountStillWanted } from "../services/monaco-lazy";
35
35
  import { monacoTheme } from "../shell";
36
- import { isJsonObject } from "@jxsuite/schema/guards";
36
+ import { isJsonObject, isString } from "@jxsuite/schema/guards";
37
37
 
38
- import { getNodeAtPath, renderOnly, updateUi } from "../store";
38
+ import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
39
+ import { renderOnly, updateUi } from "../store";
39
40
  import { activeTab, tabIsLive } from "../workspace/workspace";
40
41
  import { mutateUpdateDef, mutateUpdateProperty, transactDoc } from "../tabs/transact";
41
42
  import { view } from "../view";
@@ -50,11 +51,12 @@ import {
50
51
  } from "../services/monaco-buffer";
51
52
  import { globalEntries, namedFormulaEntries } from "../ui/formula-catalog";
52
53
  import { notify } from "../services/notify";
54
+ import type { NotifyOptions } from "../services/notify";
53
55
 
54
56
  import type { BufferWrites } from "../services/monaco-buffer";
55
57
  import { noteTyping } from "../tabs/typing";
56
58
  import type { OxLintDiagnostic } from "../services/code-services";
57
- import type { JxPrototypeDef } from "@jxsuite/schema/types";
59
+ import type { JsonValue, JxDocumentValue } from "@jxsuite/schema/types";
58
60
  import type { JxPath } from "../state";
59
61
  import type { Tab } from "../tabs/tab";
60
62
 
@@ -78,8 +80,8 @@ type FunctionEditor = NonNullable<typeof view.functionEditor>;
78
80
  function getFunctionBody(tab: Tab | null | undefined, editing: EditingTarget | null | undefined) {
79
81
  const document = tab?.doc.document;
80
82
  // Read body off any object-shaped def (covers legacy entries without $prototype).
81
- const bodyOf = (def: unknown) =>
82
- isJsonObject(def) && typeof def.body === "string" ? def.body : "";
83
+ const bodyOf = (def: JxDocumentValue | undefined) =>
84
+ isJsonObject(def) && isString(def.body) ? def.body : "";
83
85
  if (editing?.type === "def") {
84
86
  return bodyOf(document?.state?.[editing.defName]);
85
87
  } else if (editing?.type === "event") {
@@ -89,6 +91,27 @@ function getFunctionBody(tab: Tab | null | undefined, editing: EditingTarget | n
89
91
  return "";
90
92
  }
91
93
 
94
+ /**
95
+ * Whether one entry of a "lint" answer is an oxlint diagnostic.
96
+ *
97
+ * The code service forwards oxlint's own `--format=json` output (`code-api.ts`), whose every
98
+ * diagnostic carries a string `message` and `severity` and, where it points somewhere, a `labels`
99
+ * array. Those are the members checked here; `setLintMarkers` reads the rest as optional.
100
+ */
101
+ function isLintDiagnostic(value: unknown): value is OxLintDiagnostic {
102
+ return (
103
+ isJsonObject(value) &&
104
+ isString(value.message) &&
105
+ isString(value.severity) &&
106
+ (value.labels === undefined || Array.isArray(value.labels))
107
+ );
108
+ }
109
+
110
+ /** The entries of a "lint" answer that are oxlint diagnostics, in the order they came. */
111
+ function lintDiagnostics(entries: readonly JsonValue[]): OxLintDiagnostic[] {
112
+ return entries.flatMap((entry) => (isLintDiagnostic(entry) ? [entry] : []));
113
+ }
114
+
92
115
  /**
93
116
  * The element the Logic tab draws for Monaco to fill.
94
117
  *
@@ -110,6 +133,10 @@ export const CODE_HOST_SELECTOR = '[part="code-host"]';
110
133
  */
111
134
  export function syncFunctionEditor(host: HTMLElement): void {
112
135
  const tab = activeTab.value;
136
+ /* SAFETY: `editingFunction` is written only by openLogicTarget, and every caller that opens the
137
+ function surface (formula.editDef, formula.editEvent, the Data panel, the Logic tab's Open)
138
+ passes `{ type: "def", defName }` or `{ type: "event", path, eventKey }`, exactly the two
139
+ EditingTarget members. */
113
140
  const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;
114
141
  const container = editing && tab ? host.querySelector<HTMLElement>(CODE_HOST_SELECTOR) : null;
115
142
  if (!container || !tab || !editing) {
@@ -120,7 +147,7 @@ export function syncFunctionEditor(host: HTMLElement): void {
120
147
  }
121
148
 
122
149
  const current = view.functionEditor;
123
- const attached = Boolean(current && container.contains(current.getDomNode() as Node | null));
150
+ const attached = Boolean(current && container.contains(current.getDomNode()));
124
151
  /* THE TAB IS HALF OF THE IDENTITY, and the half that used to be missing.
125
152
  `_editingTarget` is a JSON string built from the target alone, and the ordinary target
126
153
  `{"eventKey":"onclick","path":["children",0],"type":"event"}` is the SAME string for the first
@@ -261,7 +288,7 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
261
288
  let wrote = false;
262
289
  if (editing.type === "def") {
263
290
  wrote = transactDoc(tab, (t) => mutateUpdateDef(t, editing.defName, { body: newBody }));
264
- } else if (editing.type === "event") {
291
+ } else {
265
292
  const node = getNodeAtPath(tab.doc.document, editing.path);
266
293
  /* THE ELEMENT THE HANDLER HANGS OFF CAN GO WHILE THE EDITOR IS OPEN — a collaborator's
267
294
  delete arriving over the wire, or the author's own ⌘Z. `editing.path` then resolves to
@@ -275,6 +302,9 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
275
302
  return false;
276
303
  }
277
304
  const current = node[editing.eventKey] || {};
305
+ /* SAFETY: an `on*` key holds an event binding, which the schema makes an object (a `$ref`, a
306
+ function def or an expression def), so the spread copies that binding's fields; `|| {}`
307
+ covers a key with no binding yet. */
278
308
  wrote = transactDoc(tab, (t) =>
279
309
  mutateUpdateProperty(t, editing.path, editing.eventKey, {
280
310
  ...(current as object),
@@ -334,6 +364,8 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
334
364
  */
335
365
  export async function closeFunctionEditor(): Promise<void> {
336
366
  const tab = activeTab.value;
367
+ /* SAFETY: `editingFunction` is written only by openLogicTarget, whose callers pass one of the two
368
+ EditingTarget shapes (see syncFunctionEditor). */
337
369
  const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;
338
370
  if (!tab || !editing) {
339
371
  return;
@@ -350,13 +382,13 @@ export async function closeFunctionEditor(): Promise<void> {
350
382
  cancelBufferWrites(editor);
351
383
  const write = editor._commitBody ?? bodyWriter(tab, editing);
352
384
  if (!write(minResult?.code ?? currentCode)) {
385
+ const options: NotifyOptions = { key: "logic.close-refused", source: "Logic" };
386
+ if (tab.documentPath) {
387
+ options.path = tab.documentPath;
388
+ }
353
389
  notify.warn(
354
390
  "The handler could not be saved — source editing holds this document. Your code is still in the editor.",
355
- {
356
- key: "logic.close-refused",
357
- source: "Logic",
358
- ...(tab.documentPath ? { path: tab.documentPath } : {}),
359
- },
391
+ options,
360
392
  );
361
393
  return;
362
394
  }
@@ -487,7 +519,7 @@ async function mountFunctionEditor(
487
519
  tabIsLive(tab) &&
488
520
  bufferIsLive(editor)
489
521
  ) {
490
- setLintMarkers(editor, result.diagnostics as OxLintDiagnostic[]);
522
+ setLintMarkers(editor, lintDiagnostics(result.diagnostics));
491
523
  }
492
524
  });
493
525
 
@@ -527,7 +559,7 @@ async function mountFunctionEditor(
527
559
  return;
528
560
  }
529
561
  if (result?.diagnostics) {
530
- setLintMarkers(editor, result.diagnostics as OxLintDiagnostic[]);
562
+ setLintMarkers(editor, lintDiagnostics(result.diagnostics));
531
563
  }
532
564
  });
533
565
  });
@@ -546,7 +578,7 @@ export async function registerFunctionCompletions() {
546
578
  if (!activeTab.value) {
547
579
  return { suggestions: [] };
548
580
  }
549
- const defs = activeTab.value.doc.document?.state || {};
581
+ const defs = activeTab.value.doc.document.state || {};
550
582
  const word = model.getWordUntilPosition(position);
551
583
  const range = {
552
584
  endColumn: word.endColumn,
@@ -561,13 +593,12 @@ export async function registerFunctionCompletions() {
561
593
  const suggestions: monaco.languages.CompletionItem[] = Object.entries(defs).map(
562
594
  ([key, def]) => {
563
595
  let kind = monacoNs.languages.CompletionItemKind.Variable;
564
- if (
565
- (def as JxPrototypeDef)?.$prototype === "Function" ||
566
- (def as Record<string, unknown>)?.$handler ||
567
- formulaDocs.has(key)
568
- ) {
596
+ // A primitive or array entry carries neither field, which is what reading them off it gave.
597
+ const prototype = isJsonObject(def) ? def.$prototype : undefined;
598
+ const handler = isJsonObject(def) ? def.$handler : undefined;
599
+ if (prototype === "Function" || handler || formulaDocs.has(key)) {
569
600
  kind = monacoNs.languages.CompletionItemKind.Function;
570
- } else if ((def as JxPrototypeDef)?.$prototype) {
601
+ } else if (prototype) {
571
602
  kind = monacoNs.languages.CompletionItemKind.Property;
572
603
  }
573
604
  const item: monaco.languages.CompletionItem = {
@@ -20,6 +20,7 @@
20
20
  * @docs studio/design/elements
21
21
  */
22
22
 
23
+ import { isString } from "@jxsuite/schema/guards";
23
24
  import { nothing } from "lit-html";
24
25
  import { buildComponentInstance, componentRegistry } from "../files/components";
25
26
  import { childList, getNodeAtPath } from "../store";
@@ -44,7 +45,7 @@ import type { NavigatorPanelContext, NavigatorPanelDeps, PanelBody } from "./pan
44
45
 
45
46
  /** The palette's source of blocks, as `NavigatorPanelDeps.webdata` carries it. */
46
47
  interface ElementsWebdata {
47
- elements: Record<string, { tag: string }[]>;
48
+ elements?: Record<string, { tag: string }[]>;
48
49
  }
49
50
 
50
51
  /** The Components section's name — its accordion label AND its key in `view.elementsCollapsed`. */
@@ -99,12 +100,15 @@ function categoryViews(webdata: ElementsWebdata, filter: string): ElementCategor
99
100
  */
100
101
  function enabledNpmTags(): Set<string> {
101
102
  const tab = activeTab.value;
103
+ /* SAFETY: getEffectiveElements reads nothing off an object entry but `$ref` (its dedup key), and
104
+ this function keeps only the string entries, so typing the document's node entries as
105
+ JxElement is never observed. */
102
106
  const entries = getEffectiveElements(
103
107
  tab?.doc.document?.$elements as (string | JxElement)[] | undefined,
104
108
  );
105
109
  const tags = new Set<string>();
106
110
  for (const entry of entries) {
107
- if (typeof entry !== "string") {
111
+ if (!isString(entry)) {
108
112
  continue;
109
113
  }
110
114
  const named = componentRegistry.find(
@@ -143,7 +147,9 @@ function componentViews(filter: string): ComponentCardView[] {
143
147
  /** Everything the document draws, as one value. */
144
148
  function panelValues(source: NavigatorPanelDeps): ElementsValues {
145
149
  const filter = needle();
146
- const categories = categoryViews(source.webdata as unknown as ElementsWebdata, filter);
150
+ /* SAFETY: `webdata` is wired in studio.ts from the bundled data/webdata.json, whose `elements`
151
+ maps each category name to an array of `{ tag }` entries. */
152
+ const categories = categoryViews(source.webdata as ElementsWebdata, filter);
147
153
  const components = componentViews(filter);
148
154
  const bare = categories.length === 0 && components.length === 0;
149
155
  return {
@@ -206,6 +212,7 @@ const ACTIONS: ElementsActions = {
206
212
  },
207
213
  insertElement: (tag) => {
208
214
  if (panelDeps) {
215
+ // SAFETY: studio.ts wires `defaultDef` to shared.ts defaultDef, which returns a JxMutableNode.
209
216
  insertAtSelection(panelDeps.defaultDef(tag) as JxMutableNode);
210
217
  }
211
218
  },