@jxsuite/studio 2.0.1 → 2.1.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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +21080 -32585
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +7 -0
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +221 -245
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -53
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +30 -1
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +7 -1
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
  363. package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
  364. package/dist/chunks/files-j8a1t06k.js +0 -50
  365. package/dist/chunks/files-j8a1t06k.js.map +0 -9
  366. package/dist/chunks/git-panel-xtq5z81x.js +0 -28
  367. package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
  368. package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
  369. package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
  370. package/dist/chunks/settings-modal-17ttr96g.js +0 -29
  371. package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-0xgs7xrs.js +0 -429
  381. package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
  382. package/dist/chunks/studio-4d8hzcz5.js +0 -3427
  383. package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
  384. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  385. package/dist/chunks/studio-9smfzqhc.js +0 -19
  386. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  387. package/dist/chunks/studio-jm0z592w.js.map +0 -115
  388. package/dist/chunks/studio-m2t4mdg5.js +0 -1854
  389. package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
  390. package/dist/chunks/studio-n4p11dfy.js +0 -853
  391. package/dist/chunks/studio-n4p11dfy.js.map +0 -12
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-sjh1wt1a.js +0 -3744
  394. package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
  395. package/dist/chunks/studio-v7jkjqng.js.map +0 -46
  396. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  397. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  398. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  399. package/dist/chunks/studio-yfcstdzy.js +0 -399
  400. package/dist/chunks/studio-yfcstdzy.js.map +0 -12
  401. package/dist/chunks/studio-zp7jncs8.js +0 -469
  402. package/dist/chunks/studio-zp7jncs8.js.map +0 -14
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -2,11 +2,93 @@
2
2
  // ─── Data Explorer ──────────────────────────────────────────────────────────
3
3
 
4
4
  import { html, nothing } from "lit-html";
5
- import { classMap } from "lit-html/directives/class-map.js";
6
5
  import type { TemplateResult } from "lit-html";
6
+ import { activeTab } from "../workspace/workspace";
7
+ import { renderOnly } from "../store";
8
+ import { booleanArg, stringArg, stringProperty } from "../commands/command-args";
9
+ import { registerPanel } from "./panel-registry";
10
+ import type { AnyCommand, CommandRegistry } from "../commands/registry";
7
11
 
8
- /** Expanded data entries set — persists across renders. */
9
- const expandedDataKeys = new Set();
12
+ /**
13
+ * The focused tab's expansion record, created on first write.
14
+ *
15
+ * `ui.dataRows` rather than a module Set: expansion is a property of the document you are reading,
16
+ * and a module-global one followed you to the next tab and showed rows open that that document does
17
+ * not define.
18
+ */
19
+ function rowsUi(): Record<string, boolean> | null {
20
+ const ui = activeTab.value?.session.ui;
21
+ if (!ui) {
22
+ return null;
23
+ }
24
+ return (ui.dataRows ??= {});
25
+ }
26
+
27
+ /*
28
+ * ── The truncation markers, which are now BUTTONS ────────────────────────────
29
+ *
30
+ * The tree caps arrays at 20, objects at 30 and depth at 5, and printed "… 5 more" as inert text.
31
+ * That is the panel telling you it has the answer and will not show it — the exact case a user
32
+ * opens this panel for is the fetch that returned something unexpected at item 40. Plan §11.2:
33
+ * "truncation markers gain real expand actions."
34
+ *
35
+ * Raising a limit is remembered per marker rather than globally, so opening one long array does not
36
+ * re-render every other one at full length, and it never lowers: a step is a step.
37
+ */
38
+ const MORE_STEP = 50;
39
+
40
+ /** The focused tab's raised-limit record, created on first write. */
41
+ function limitsUi(): Record<string, number> | null {
42
+ const ui = activeTab.value?.session.ui;
43
+ if (!ui) {
44
+ return null;
45
+ }
46
+ return (ui.dataLimits ??= {});
47
+ }
48
+
49
+ /** The cap for one marker: the default, plus whatever the reader has asked for. */
50
+ function capFor(path: string, kind: "items" | "keys" | "depth", base: number): number {
51
+ return base + (limitsUi()?.[`${path}\u0000${kind}`] ?? 0);
52
+ }
53
+
54
+ /** Raise one marker's limit by a step. Exported for the tests. */
55
+ export function raiseDataLimit(path: string, kind: "items" | "keys" | "depth"): void {
56
+ const limits = limitsUi();
57
+ if (!limits) {
58
+ return;
59
+ }
60
+ const key = `${path}\u0000${kind}`;
61
+ limits[key] = (limits[key] ?? 0) + MORE_STEP;
62
+ }
63
+
64
+ /**
65
+ * One truncation marker: a button that shows more of what is already in hand.
66
+ *
67
+ * It repaints through `renderOnly("leftPanel")` rather than a callback, because this renderer is
68
+ * called from three places and threading a repaint through all of them to reach one `<button>`
69
+ * would put a required callback on a pure formatter.
70
+ */
71
+ function moreTemplate(
72
+ path: string,
73
+ kind: "items" | "keys" | "depth",
74
+ indent: string,
75
+ label: string,
76
+ after?: () => string,
77
+ ) {
78
+ return html`<button
79
+ type="button"
80
+ class="data-leaf data-ellipsis data-more"
81
+ style="padding-left:${indent}"
82
+ title=${after?.() ?? `Show ${MORE_STEP} more`}
83
+ @click=${(e: Event) => {
84
+ e.stopPropagation();
85
+ raiseDataLimit(path, kind);
86
+ renderOnly("leftPanel");
87
+ }}
88
+ >
89
+ ${label}
90
+ </button>`;
91
+ }
10
92
 
11
93
  /** Unwrap a Vue ref (has .value and .__v_isRef) to get the underlying value. */
12
94
  export function unwrapSignal(value: unknown) {
@@ -34,101 +116,13 @@ export function dataTypeLabel(value: unknown) {
34
116
  return typeof v;
35
117
  }
36
118
 
37
- /**
38
- * Render the data explorer tab showing live resolved values.
39
- *
40
- * @param {Record<string, unknown>} state - S.document.state (the $defs definitions)
41
- * @param {Record<string, unknown> | null} liveScope - Cached live scope from runtime rendering
42
- * @param {{
43
- * renderCanvas: () => void;
44
- * refreshData: () => void;
45
- * renderLeftPanel: () => void;
46
- * defCategory: (def: unknown) => string;
47
- * defBadgeLabel: (def: unknown) => string;
48
- * }} callbacks
49
- * @returns {import("lit-html").TemplateResult}
50
- */
51
- export function renderDataExplorerTemplate(
52
- state: Record<string, unknown>,
53
- liveScope: Record<string, unknown> | null,
54
- callbacks: {
55
- renderCanvas: () => void;
56
- /** Re-render the canvas AND let automatic `Request` entries fetch (the Refresh button). */
57
- refreshData: () => void;
58
- renderLeftPanel: () => void;
59
- defCategory: (def: unknown) => string;
60
- defBadgeLabel: (def: unknown) => string;
61
- },
62
- ) {
63
- const { refreshData, renderLeftPanel, defCategory, defBadgeLabel } = callbacks;
64
-
65
- const defs = state || {};
66
- const entries = Object.entries(defs);
67
- const scope = liveScope || {};
68
-
69
- return html`
70
- <div class="data-explorer-toolbar">
71
- <sp-action-button
72
- quiet
73
- size="s"
74
- class="data-refresh-btn"
75
- @click=${() => {
76
- // Edit/design suppress automatic `Request` fetches (a full render re-resolves every state
77
- // Entry, so authoring would refetch constantly). Re-firing them on demand is exactly what
78
- // This button is for, which is why it goes through refreshData rather than renderCanvas.
79
- refreshData();
80
- setTimeout(() => renderLeftPanel(), 200);
81
- }}
82
- >
83
- <sp-icon-refresh slot="icon"></sp-icon-refresh>
84
- Refresh
85
- </sp-action-button>
86
- </div>
87
- ${
88
- entries.length === 0
89
- ? html`<div class="empty-state">No state defined</div>`
90
- : entries.map(([name, def]) => {
91
- const value = scope[name];
92
- const unwrapped = unwrapSignal(value);
93
- const isExpanded = expandedDataKeys.has(name);
94
- return html`
95
- <div class="data-row">
96
- <div
97
- class=${classMap({
98
- "data-row-header": true,
99
- expanded: isExpanded,
100
- })}
101
- @click=${() => {
102
- if (expandedDataKeys.has(name)) {
103
- expandedDataKeys.delete(name);
104
- } else {
105
- expandedDataKeys.add(name);
106
- }
107
- renderLeftPanel();
108
- }}
109
- >
110
- <span class="signal-badge ${defCategory(def)}">${defBadgeLabel(def)}</span>
111
- <span class="data-name">${name}</span>
112
- <span
113
- class=${classMap({
114
- "data-pending": unwrapped === null,
115
- "data-type": true,
116
- })}
117
- >${dataTypeLabel(value)}</span
118
- >
119
- </div>
120
- ${
121
- isExpanded
122
- ? html`<div class="data-tree">${renderDataTreeTemplate(unwrapped, 0)}</div>`
123
- : nothing
124
- }
125
- </div>
126
- `;
127
- })
128
- }
129
- `;
130
- }
131
-
119
+ /* THE VALUE LIST IS GONE, AND ITS ROWS ARE THE DEFINITION ROWS — `panels/signals-panel.ts`.
120
+ It listed every state entry with its badge and what it resolved to, one rail tab away from a
121
+ panel listing every state entry with its badge and how it is defined: the same names twice, and
122
+ you read one to understand the other. Plan §11.2 asks for "definitions + live values in one row",
123
+ so the definition row now carries the resolved type and expands to the value tree, and what is
124
+ left here is the tree renderer, the type label and the row-expansion record the merged rows read.
125
+ `renderDataTreeTemplate` is unchanged — it was never the redundant half. */
132
126
  /**
133
127
  * Recursively render a JSON value as a tree view (Lit template).
134
128
  *
@@ -138,11 +132,12 @@ export function renderDataTreeTemplate(
138
132
  value: unknown,
139
133
  depth: number,
140
134
  maxDepth = 5,
135
+ path = "",
141
136
  ): TemplateResult {
142
137
  const indent = `${(depth + 1) * 12}px`;
143
138
 
144
- if (depth > maxDepth) {
145
- return html`<div class="data-leaf data-ellipsis" style="padding-left:${indent}">…</div>`;
139
+ if (depth > capFor(path, "depth", maxDepth)) {
140
+ return moreTemplate(path, "depth", indent, "…", () => `Show ${MORE_STEP} more levels`);
146
141
  }
147
142
 
148
143
  if (value === null || value === undefined) {
@@ -162,7 +157,7 @@ export function renderDataTreeTemplate(
162
157
  }
163
158
 
164
159
  if (Array.isArray(value)) {
165
- const cap = 20;
160
+ const cap = capFor(path, "items", 20);
166
161
  const items: TemplateResult[] = value.slice(0, cap).map((item, i) => {
167
162
  if (item === null || item === undefined || typeof item !== "object") {
168
163
  const valText =
@@ -182,14 +177,12 @@ export function renderDataTreeTemplate(
182
177
  <span class="data-key">[${i}] </span
183
178
  ><span class="data-value data-object-label">${label}</span>
184
179
  </div>
185
- ${renderDataTreeTemplate(item, depth + 1, maxDepth)}
180
+ ${renderDataTreeTemplate(item, depth + 1, maxDepth, `${path}/${i}`)}
186
181
  `;
187
182
  });
188
183
  return html`${items}${
189
184
  value.length > cap
190
- ? html`<div class="data-leaf data-ellipsis" style="padding-left:${indent}">
191
- … ${value.length - cap} more
192
- </div>`
185
+ ? moreTemplate(path, "items", indent, `… ${value.length - cap} more`)
193
186
  : nothing
194
187
  }`;
195
188
  }
@@ -197,7 +190,7 @@ export function renderDataTreeTemplate(
197
190
  // Object
198
191
  const obj = value as Record<string, unknown>;
199
192
  const keys = Object.keys(obj);
200
- const cap = 30;
193
+ const cap = capFor(path, "keys", 30);
201
194
  const items: TemplateResult[] = keys.slice(0, cap).map((key) => {
202
195
  const v = obj[key];
203
196
  if (v === null || v === undefined || typeof v !== "object") {
@@ -214,14 +207,163 @@ export function renderDataTreeTemplate(
214
207
  <span class="data-key">${key}: </span
215
208
  ><span class="data-value data-object-label">${label}</span>
216
209
  </div>
217
- ${renderDataTreeTemplate(v, depth + 1, maxDepth)}
210
+ ${renderDataTreeTemplate(v, depth + 1, maxDepth, `${path}/${key}`)}
218
211
  `;
219
212
  });
220
213
  return html`${items}${
221
- keys.length > cap
222
- ? html`<div class="data-leaf data-ellipsis" style="padding-left:${indent}">
223
- … ${keys.length - cap} more
224
- </div>`
225
- : nothing
214
+ keys.length > cap ? moreTemplate(path, "keys", indent, `… ${keys.length - cap} more`) : nothing
226
215
  }`;
227
216
  }
217
+
218
+ // ─── Commands ─────────────────────────────────────────────────────────────────
219
+
220
+ /** Expand (or collapse) one data row's value tree. Idempotent — expanding twice is expanding once. */
221
+ export function setDataRowExpanded(name: string, expanded: boolean): void {
222
+ const rows = rowsUi();
223
+ if (!rows) {
224
+ return;
225
+ }
226
+ if (expanded) {
227
+ rows[name] = true;
228
+ } else {
229
+ delete rows[name];
230
+ }
231
+ }
232
+
233
+ /** Whether a data row is currently expanded. Exported for the tests and the command's idempotence. */
234
+ export function isDataRowExpanded(name: string): boolean {
235
+ return rowsUi()?.[name] === true;
236
+ }
237
+
238
+ /** The expanded rows, in no particular order — `formula.openWorkspace` asks when it has no target. */
239
+ export function expandedDataRows(): string[] {
240
+ return Object.keys(rowsUi() ?? {});
241
+ }
242
+
243
+ /** Drop every expansion AND every raised limit on the focused tab — a fresh document, and tests. */
244
+ export function resetDataRowExpansion(): void {
245
+ const ui = activeTab.value?.session.ui;
246
+ if (ui) {
247
+ ui.dataRows = {};
248
+ ui.dataLimits = {};
249
+ }
250
+ }
251
+
252
+ /** The state entry names the open document defines — what a row can be named by. */
253
+ function definedDataNames(): string[] {
254
+ return Object.keys(activeTab.value?.doc.document?.state ?? {});
255
+ }
256
+
257
+ /** What the data verb needs that this module does not own. */
258
+ export interface DataExplorerCommandDeps {
259
+ /** Repaint the Navigator so the expanded row's tree appears — `left-panel.ts`'s `render`. */
260
+ renderLeftPanel: () => void;
261
+ }
262
+
263
+ /**
264
+ * The Data panel's row verb.
265
+ *
266
+ * `expandRow` reads as a delta but is not one: it names the state it ends in, which is why it
267
+ * survives `__jxAutomation`'s `/\.toggle[A-Z]/` refusal and why running it twice photographs the
268
+ * same picture. The collapse direction is `{ expanded: false }` on the same record rather than a
269
+ * second id.
270
+ *
271
+ * REFUSES a name the open document does not define. The predecessor matched the row by its rendered
272
+ * label through an XPath, so a document without that entry silently pressed nothing and the shot
273
+ * recorded a collapsed panel as if it were the feature.
274
+ *
275
+ * @param {DataExplorerCommandDeps} deps
276
+ * @returns {AnyCommand[]}
277
+ */
278
+ export function dataExplorerCommands(deps: DataExplorerCommandDeps): AnyCommand[] {
279
+ return [
280
+ {
281
+ args: {
282
+ additionalProperties: false,
283
+ properties: {
284
+ expanded: {
285
+ default: true,
286
+ description: "True to expand the row's value tree, false to collapse it.",
287
+ type: "boolean",
288
+ },
289
+ name: stringProperty("The state entry's name, as the document defines it."),
290
+ },
291
+ required: ["name"],
292
+ type: "object",
293
+ },
294
+ category: "Document",
295
+ id: "data.expandRow",
296
+ level: "document",
297
+ menus: ["palette"],
298
+ group: "5_data",
299
+ requires: "an open document that defines data",
300
+ when: (ctx) => ctx.document.open,
301
+ run: (_commandCtx, args) => {
302
+ const name = stringArg("data.expandRow", args, "name");
303
+ const defined = definedDataNames();
304
+ if (!defined.includes(name)) {
305
+ throw new RangeError(
306
+ `command "data.expandRow" argument "name": "${name}" is not defined by this ` +
307
+ `document — it defines: ${defined.length > 0 ? defined.join(", ") : "nothing"}`,
308
+ );
309
+ }
310
+ const { expanded } = args as { expanded?: unknown };
311
+ // `expanded` defaults to true but is never COERCED: `{ expanded: "no" }` would otherwise
312
+ // Read as a collapse, which is the class of silent wrong answer this whole record exists
313
+ // To stop.
314
+ setDataRowExpanded(
315
+ name,
316
+ expanded === undefined || booleanArg("data.expandRow", args, "expanded"),
317
+ );
318
+ deps.renderLeftPanel();
319
+ },
320
+ title: "Expand Data Row",
321
+ },
322
+ ];
323
+ }
324
+
325
+ /**
326
+ * Register the Data panel's row verb.
327
+ *
328
+ * @param {CommandRegistry} registry
329
+ * @param {DataExplorerCommandDeps} deps
330
+ */
331
+ export function registerDataExplorerCommands(
332
+ registry: CommandRegistry,
333
+ deps: DataExplorerCommandDeps,
334
+ ): void {
335
+ registry.registerAll(dataExplorerCommands(deps));
336
+ }
337
+
338
+ /**
339
+ * Contribute the Data panel — the DEFINITIONS and the values they resolve to, in one place.
340
+ *
341
+ * `level: "document"`, because both belong to the open document.
342
+ *
343
+ * **This is where the State editor lives now.** Plan §11.2 always said so ("State panel + inline
344
+ * editor → Navigator › Data"), but the two halves shipped apart: the rail button was taken away to
345
+ * keep the DOCUMENT group at four, the merge was deferred, and the editor was left reachable only
346
+ * by typing its name into the palette. So the one surface for declaring a state variable — or a
347
+ * component property, which is a state entry with a default — became unfindable, which is a
348
+ * capability lost rather than a control moved.
349
+ *
350
+ * Defining and watching are the same task interrupted: you add an entry, then look at what it
351
+ * resolved to. Two panels made that two panels.
352
+ */
353
+ export function registerDataPanel(): void {
354
+ registerPanel({
355
+ id: "data",
356
+ title: "Data",
357
+ level: "document",
358
+ dock: "navigator",
359
+ icon: "sp-icon-data",
360
+ requiresDocument: "Open a page to give it data — values it can read, compute or fetch.",
361
+ render: (ctx) =>
362
+ // `ctx.doc!` — `requiresDocument` means the registry renders the empty state instead of
363
+ // Calling this, the same assertion `head-panel.ts` makes for the same reason.
364
+ ctx.deps.renderSignalsTemplate(ctx.doc!, {
365
+ refreshData: ctx.deps.refreshData,
366
+ renderLeftPanel: ctx.rerender,
367
+ }),
368
+ });
369
+ }
@@ -56,7 +56,7 @@ export async function startPush(connection: string | undefined, onDone: () => vo
56
56
  if (pushDialog) {
57
57
  return;
58
58
  }
59
- const handle = openModal(html``);
59
+ const handle = openModal(html``, { label: "Push Schema", onDismiss: closePushDialog });
60
60
  pushDialog = { connection, handle, onDone, phase: "loading", plan: null, result: null };
61
61
  renderPushDialog();
62
62
  const plan = await pushSchema({
@@ -148,7 +148,9 @@ function renderPushDialog(): void {
148
148
  size="s"
149
149
  emphasized
150
150
  class="push-apply"
151
- @click=${() => void applyPush()}
151
+ @click=${() => {
152
+ void applyPush();
153
+ }}
152
154
  >Apply</sp-action-button
153
155
  >`
154
156
  : nothing
@@ -224,14 +226,18 @@ function renderSectionActions(sectionKey: string, ctx: SectionActionsContext): T
224
226
  <sp-action-button
225
227
  size="s"
226
228
  class="data-action-push"
227
- @click=${() => void startPush(pushTarget, rerender)}
229
+ @click=${() => {
230
+ void startPush(pushTarget, rerender);
231
+ }}
228
232
  >
229
233
  Push Schema
230
234
  </sp-action-button>
231
235
  <sp-action-button
232
236
  size="s"
233
237
  class="data-action-grid"
234
- @click=${() => void openGridSourcePicker()}
238
+ @click=${() => {
239
+ void openGridSourcePicker();
240
+ }}
235
241
  >
236
242
  Open Data Grid
237
243
  </sp-action-button>
package/src/panels/dnd.ts CHANGED
@@ -10,6 +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
14
  import { disableNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview";
14
15
  import {
15
16
  attachInstruction,
@@ -26,19 +27,18 @@ import {
26
27
  renderOnly,
27
28
  } from "../store";
28
29
  import { mutateInsertNode, mutateMoveNode, transact, transactDoc } from "../tabs/transact";
30
+ import { primarySelection } from "../tabs/selection";
29
31
  import { activeTab } from "../workspace/workspace";
30
32
  import { view } from "../view";
31
- import {
32
- buildComponentInstance,
33
- componentRegistry,
34
- computeRelativePath,
35
- } from "../files/components";
33
+ import { buildComponentInstance, componentRegistry } from "../files/components";
34
+ import { enableElement } from "../files/elements";
35
+ import type { ElementsEntry } from "../files/elements";
36
36
  import { renderComponentPreview } from "./component-preview";
37
37
  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 { JxMutableNode } from "@jxsuite/schema/types";
41
+ import type { JxElement, JxMutableNode } from "@jxsuite/schema/types";
42
42
  import type { ComponentEntry } from "../files/components.js";
43
43
 
44
44
  interface DragCanDragArgs {
@@ -180,9 +180,10 @@ export function registerLayersDnD() {
180
180
 
181
181
  if (wasExpanded) {
182
182
  const tab = activeTab.value;
183
- const newPath = tab?.session.selection;
183
+ const newPath = primarySelection(tab?.session.selection);
184
184
  if (newPath) {
185
- const collapsed = (view._layersCollapsed ||= new Set());
185
+ view._layersCollapsed ||= new Set();
186
+ const collapsed = view._layersCollapsed;
186
187
  collapsed.add(newPath.join("/"));
187
188
  }
188
189
  }
@@ -349,9 +350,10 @@ export function clearLayerDropGap(container: HTMLElement) {
349
350
  for (const r of rows) {
350
351
  (r as HTMLElement).style.transform = "";
351
352
  // Also clear `display:none` left by hideDescendantRows. The `.layer-row` div has no `style`
352
- // Lit binding and rows aren't keyed, so lit reuses these DOM nodes positionally on the
353
- // Post-drop re-render — a stale `display:none` would otherwise hide whichever row lands on the
354
- // Reused node (e.g. a sibling of the moved subtree).
353
+ // Lit binding, so an imperative style set during the drag survives the post-drop re-render on
354
+ // Whichever row keeps that key — and a move is exactly the edit that hands a key to a different
355
+ // Node. (The rows ARE keyed, by `pathKey`; the earlier form of this note said they were not,
356
+ // Which made the wrong thing sound load-bearing. What is load-bearing is the missing binding.)
355
357
  (r as HTMLElement).style.display = "";
356
358
  }
357
359
  }
@@ -448,49 +450,24 @@ export function applyDropInstruction(
448
450
  }
449
451
  }
450
452
 
451
- // Auto-import to $elements if the dropped block is a custom component
453
+ /* Auto-import to `$elements` if the dropped block is a custom component.
454
+ Through the ONE service (`files/elements.ts`), which is the whole point of it: this call site
455
+ had its own duplicate rule and matched a local component by `ref.endsWith(basename)`, so
456
+ dropping `./components/card.json` into a page that already imported `./vendor/card.json`
457
+ counted as already imported and produced an element the page could not resolve. */
452
458
  const fragment = srcData.fragment as JxMutableNode | undefined;
453
459
  const tag = fragment?.tagName;
454
- if (tag && tag.includes("-")) {
460
+ if (displayTagName(tag).includes("-")) {
455
461
  const comp = componentRegistry.find((c: ComponentEntry) => c.tagName === tag);
456
- if (comp) {
457
- const elements = tab.doc.document?.$elements || [];
458
- if (comp.source === "npm") {
459
- const specifier = comp.modulePath ? `${comp.package}/${comp.modulePath}` : comp.package;
460
- if (!specifier) {
461
- return;
462
- }
463
- const alreadyImported = elements.some(
464
- (e: JxMutableNode | string | { $ref: string }) => e === specifier || e === comp.package,
465
- );
466
- if (!alreadyImported) {
467
- transact(tab, (d: JxMutableNode) => {
468
- if (!d.$elements) {
469
- d.$elements = [];
470
- }
471
- d.$elements.push(specifier);
472
- });
473
- }
474
- } else {
475
- const alreadyImported = elements.some((e: JxMutableNode | string | { $ref: string }) => {
476
- const ref = typeof e === "object" && e !== null ? e.$ref : undefined;
477
- const compPath = comp.path;
478
- return (
479
- ref &&
480
- compPath &&
481
- (ref === `./${compPath}` || ref.endsWith(compPath.split("/").pop() as string))
482
- );
483
- });
484
- if (!alreadyImported && comp.path) {
485
- const relPath = computeRelativePath(tab?.documentPath ?? null, comp.path);
486
- transact(tab, (d: JxMutableNode) => {
487
- if (!d.$elements) {
488
- d.$elements = [];
489
- }
490
- d.$elements.push({ $ref: relPath });
491
- });
492
- }
493
- }
462
+ const before = (tab.doc.document?.$elements ?? []) as ElementsEntry[];
463
+ const after = comp ? enableElement(before, comp, tab.documentPath ?? null) : before;
464
+ // Only when the list actually GREW. A component the registry cannot name — an npm entry with
465
+ // No package, a local one with no path — returns the list unchanged, and writing that back
466
+ // Would put an empty `$elements: []` on a document that had none.
467
+ if (after.length !== before.length) {
468
+ transact(tab, (d: JxMutableNode) => {
469
+ d.$elements = after as (string | JxElement)[];
470
+ });
494
471
  }
495
472
  }
496
473
  }