@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
@@ -0,0 +1,462 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * Regions — the shell's addressable surfaces, in one id space.
4
+ *
5
+ * `shell.ts` declares `FocusRegion = "rail" | "navigator" | "pane" | "inspector" | "dock" |
6
+ * "status"` and has done since the shell record landed. It is an enum with **no DOM counterpart**:
7
+ * nothing can be asked where the Navigator _is_, so nothing can move focus into it, cycle to the
8
+ * next one, or measure it. Three consumers want exactly that map — F6 region cycling, focus
9
+ * restoration after a toast or a Problems jump, and the screenshot pipeline, which today addresses
10
+ * the shell through sixteen CSS selectors, seven of which name nodes the shell redesign deletes.
11
+ *
12
+ * **The grammar** (UX-REDESIGN-PLAN §13.2) is `<surface>[.<instance>][/<part>]`:
13
+ *
14
+ * ```text
15
+ * navigator the Navigator dock
16
+ * navigator/panel:git the Source Control panel inside it
17
+ * navigator/panel:git/commit a leaf within that panel
18
+ * inspector/tab:style the Style tab's body
19
+ * inspector/field:href a field row (ui/field-row.ts already emits `data-prop`)
20
+ * pane.primary/tabs the primary pane's own tab strip
21
+ * overlay.dialog:settings a named overlay slot
22
+ * ```
23
+ *
24
+ * **Ids are DERIVED, not authored**, which is the property that makes them survive a rename. The
25
+ * panel host stamps `navigator/panel:${id}` once and every panel gets a region for free; the
26
+ * inspector stamps `inspector/tab:${key}` from its own tab records; `getLayerSlot()` stamps
27
+ * `overlay.<kind>:<id>` from the key it already builds. A panel rename then propagates to the
28
+ * region automatically, and a stale id fails the shot contract instead of photographing the wrong
29
+ * box. Only leaves — `navigator/panel:git/commit` — are hand-stamped, and those are counted.
30
+ *
31
+ * Resolution reads the live DOM rather than a registration table, for the same reason
32
+ * {@link import("./layers").isModalOpen} does: whatever is on screen is the answer, and there is no
33
+ * bookkeeping for a new surface to forget.
34
+ */
35
+
36
+ import type { FocusRegion } from "../shell";
37
+
38
+ /** The attribute every region carries. One attribute, one grammar, one resolver. */
39
+ export const REGION_ATTR = "data-jx-region";
40
+
41
+ /** The eight surfaces §13.2 declares. A region id always begins with one of these. */
42
+ export const REGION_SURFACES = [
43
+ "rail",
44
+ "navigator",
45
+ "inspector",
46
+ "pane",
47
+ "dock.bottom",
48
+ "statusbar",
49
+ "commandbar",
50
+ "overlay",
51
+ ] as const;
52
+
53
+ export type RegionSurface = (typeof REGION_SURFACES)[number];
54
+
55
+ /** A parsed region id. `instance` and `part` are absent for a bare surface. */
56
+ export interface ParsedRegionId {
57
+ surface: RegionSurface;
58
+ /** `primary` in `pane.primary`, `dialog` in `overlay.dialog:settings`. */
59
+ instance?: string;
60
+ /** Everything after the first `/` — `panel:git/commit` in `navigator/panel:git/commit`. */
61
+ part?: string;
62
+ }
63
+
64
+ /**
65
+ * `dock.bottom` is the one surface whose name contains the instance separator, so the split is
66
+ * longest-prefix rather than "up to the first dot".
67
+ */
68
+ const DOTTED_SURFACES = new Set<string>(["dock.bottom"]);
69
+
70
+ /**
71
+ * Parse a region id, or return `null` when it is not one.
72
+ *
73
+ * Rejecting is the point: the resolver never falls back to `querySelector(id)`, so a CSS selector
74
+ * that slips into a manifest resolves to nothing instead of quietly working.
75
+ */
76
+ export function parseRegionId(id: string): ParsedRegionId | null {
77
+ const slash = id.indexOf("/");
78
+ const head = slash === -1 ? id : id.slice(0, slash);
79
+ const part = slash === -1 ? undefined : id.slice(slash + 1);
80
+ if (part === "" || head === "") {
81
+ return null;
82
+ }
83
+
84
+ let surface = head;
85
+ let instance: string | undefined;
86
+ if (!DOTTED_SURFACES.has(head)) {
87
+ const dot = head.indexOf(".");
88
+ if (dot !== -1) {
89
+ surface = head.slice(0, dot);
90
+ instance = head.slice(dot + 1);
91
+ if (instance === "") {
92
+ return null;
93
+ }
94
+ }
95
+ }
96
+ if (!(REGION_SURFACES as readonly string[]).includes(surface)) {
97
+ return null;
98
+ }
99
+ return instance === undefined
100
+ ? part === undefined
101
+ ? { surface: surface as RegionSurface }
102
+ : { part, surface: surface as RegionSurface }
103
+ : part === undefined
104
+ ? { instance, surface: surface as RegionSurface }
105
+ : { instance, part, surface: surface as RegionSurface };
106
+ }
107
+
108
+ /** Whether a string is a well-formed region id. */
109
+ export function isRegionId(id: string): boolean {
110
+ return parseRegionId(id) !== null;
111
+ }
112
+
113
+ /**
114
+ * `pane` names the primary pane.
115
+ *
116
+ * The second pane arrives with the pane grid, and every id minted before it should keep meaning
117
+ * what it meant — so the alias is declared here once rather than at each call site.
118
+ */
119
+ function canonicalRegionId(id: string): string {
120
+ if (id === "pane") {
121
+ return "pane.primary";
122
+ }
123
+ return id.startsWith("pane/") ? `pane.primary/${id.slice(5)}` : id;
124
+ }
125
+
126
+ /** Where the search runs. Injectable so a test can resolve inside a detached tree. */
127
+ type RegionRoot = Pick<ParentNode, "querySelectorAll">;
128
+
129
+ function regionRoot(root?: RegionRoot): RegionRoot {
130
+ return root ?? document;
131
+ }
132
+
133
+ /**
134
+ * Ids answered by an attribute the app ALREADY emits, rather than by a `data-jx-region` stamp.
135
+ *
136
+ * `ui/field-row.ts` has emitted `data-prop=${prop}` on every inspector row since it landed, and the
137
+ * screenshot manifest has been addressing `#right-panel [data-prop='href']` through it for as long.
138
+ * Restamping several hundred rows with a second attribute saying the same thing would be pure
139
+ * duplication, so the grammar reads the existing one — `inspector/field:href` is the id, and the
140
+ * precedent is the reason that part of the grammar was specified the way it was.
141
+ */
142
+ const DERIVED_RESOLVERS: readonly {
143
+ pattern: RegExp;
144
+ locate: (match: RegExpMatchArray, root: RegionRoot) => HTMLElement[];
145
+ }[] = [
146
+ /*
147
+ * The Browse control of an Inspector field — ORDER MATTERS, it must precede the bare field rule,
148
+ * which would otherwise claim `image/browse` as a prop named "image/browse".
149
+ *
150
+ * `ui/media-picker.ts` used to STAMP this id on the button itself, and the id was a lie about
151
+ * where the button is: the same picker draws the Document Header card's Icon and og:image fields,
152
+ * and that card is rendered inside a PANE's stage. So `inspector/field:icon/browse` resolved to
153
+ * two elements the moment the grid split — one per pane, neither of them in the Inspector — and
154
+ * `resolveRegion` takes the LAST, which is the side pane's. `paneRegion` could never have reached
155
+ * it: an `inspector/…` id on an element outside the Inspector is not a pane-scoping problem, it
156
+ * is a wrong id.
157
+ *
158
+ * Deriving it fixes both halves at once. The id now MEANS "the Browse control of the Inspector's
159
+ * field `<prop>`", the search is scoped to the one Inspector, and the card's own pickers answer
160
+ * to nothing — correctly, because they are not in the Inspector. Nothing addresses them today;
161
+ * when something does, the id is `pane.<id>/field:<prop>/browse` and it is derived from the pane
162
+ * like every other stage-content id.
163
+ */
164
+ {
165
+ locate: ([, prop], root) => {
166
+ const row = resolveRegion(`inspector/field:${prop!}`, root);
167
+ const browse = row?.querySelector<HTMLElement>(".media-picker-browse");
168
+ return browse ? [browse] : [];
169
+ },
170
+ pattern: /^inspector\/field:(.+)\/browse$/,
171
+ },
172
+ {
173
+ locate: ([, prop], root) => {
174
+ const inspector = resolveRegion("inspector", root);
175
+ return inspector
176
+ ? [...inspector.querySelectorAll<HTMLElement>(`[data-prop="${CSS.escape(prop!)}"]`)]
177
+ : [];
178
+ },
179
+ pattern: /^inspector\/field:(.+)$/,
180
+ },
181
+ ];
182
+
183
+ /**
184
+ * Every element currently carrying `id`, in document order.
185
+ *
186
+ * Plural because overlays legitimately stack: two popovers open at once both used to match
187
+ * `sp-popover[open]`, and the shot cropped whichever the DOM happened to list first. An id that
188
+ * addresses several elements is answerable — `resolve` takes the last, which is the topmost.
189
+ */
190
+ export function resolveAllRegions(id: string, root?: RegionRoot): HTMLElement[] {
191
+ const canonical = canonicalRegionId(id);
192
+ if (!isRegionId(canonical)) {
193
+ return [];
194
+ }
195
+ const stamped = [
196
+ ...regionRoot(root).querySelectorAll<HTMLElement>(
197
+ `[${REGION_ATTR}="${CSS.escape(canonical)}"]`,
198
+ ),
199
+ ];
200
+ if (stamped.length > 0) {
201
+ return stamped;
202
+ }
203
+ for (const resolver of DERIVED_RESOLVERS) {
204
+ const match = canonical.match(resolver.pattern);
205
+ if (match) {
206
+ return resolver.locate(match, regionRoot(root));
207
+ }
208
+ }
209
+ return [];
210
+ }
211
+
212
+ /**
213
+ * The element a region id addresses right now, or `null`.
214
+ *
215
+ * The LAST match wins, because the only ids that repeat are overlay slots and the last one appended
216
+ * is the one on top.
217
+ */
218
+ export function resolveRegion(id: string, root?: RegionRoot): HTMLElement | null {
219
+ const all = resolveAllRegions(id, root);
220
+ return all.at(-1) ?? null;
221
+ }
222
+
223
+ /** Every region id present in the DOM, deduplicated and sorted — the map, enumerated. */
224
+ export function listRegions(root?: RegionRoot): string[] {
225
+ const ids = new Set<string>();
226
+ for (const el of regionRoot(root).querySelectorAll<HTMLElement>(`[${REGION_ATTR}]`)) {
227
+ const id = el.getAttribute(REGION_ATTR);
228
+ if (id && isRegionId(id)) {
229
+ ids.add(id);
230
+ }
231
+ }
232
+ return [...ids].toSorted();
233
+ }
234
+
235
+ /** The region id nearest ancestor-or-self of `el` declares, or `null`. */
236
+ export function regionIdOf(el: Element | null): string | null {
237
+ const host = el?.closest(`[${REGION_ATTR}]`);
238
+ const id = host?.getAttribute(REGION_ATTR) ?? null;
239
+ return id && isRegionId(id) ? id : null;
240
+ }
241
+
242
+ // ─── The FocusRegion ↔ region-id map ─────────────────────────────────────────
243
+
244
+ /**
245
+ * `shell.focusRegion`'s six values, as region ids.
246
+ *
247
+ * This is the map that made the enum inert: the shell could say which region had focus and nothing
248
+ * could act on it. With it, "focus the Navigator" is `resolveRegion(REGION_FOR_FOCUS.navigator)`,
249
+ * and F6 is a walk over `Object.keys`.
250
+ */
251
+ export const REGION_FOR_FOCUS: Readonly<Record<FocusRegion, string>> = {
252
+ dock: "dock.bottom",
253
+ inspector: "inspector",
254
+ navigator: "navigator",
255
+ pane: "pane.primary",
256
+ rail: "rail",
257
+ status: "statusbar",
258
+ };
259
+
260
+ const FOCUS_FOR_SURFACE: Readonly<Record<string, FocusRegion>> = {
261
+ "dock.bottom": "dock",
262
+ inspector: "inspector",
263
+ navigator: "navigator",
264
+ pane: "pane",
265
+ rail: "rail",
266
+ statusbar: "status",
267
+ };
268
+
269
+ /**
270
+ * Which `shell.focusRegion` an element sits in, or `null` when it is outside every region (an
271
+ * overlay, or a node nobody has stamped).
272
+ *
273
+ * The inverse direction matters as much as the forward one: focus moves for reasons the shell did
274
+ * not initiate — a click, a toast dismissal, restoring the caret after a dialog — and the record
275
+ * has to be able to catch up from the DOM.
276
+ */
277
+ export function focusRegionOf(el: Element | null): FocusRegion | null {
278
+ const id = regionIdOf(el);
279
+ if (!id) {
280
+ return null;
281
+ }
282
+ const parsed = parseRegionId(id);
283
+ return parsed ? (FOCUS_FOR_SURFACE[parsed.surface] ?? null) : null;
284
+ }
285
+
286
+ // ─── Stamping ─────────────────────────────────────────────────────────────────
287
+
288
+ /**
289
+ * The shell's fixed hosts, declared once.
290
+ *
291
+ * These live in `index.html` as bare `<div id>`s, so they cannot stamp themselves the way a panel
292
+ * or an overlay slot does. The table is the shell's own layout stated in region terms, and it is
293
+ * the only place a surface id is written down by hand.
294
+ *
295
+ * `#tab-strip` is addressed as `pane.primary/tabs` deliberately: the region names the PANE's strip,
296
+ * so the id survives the node. The assistant is the case that has now happened twice over:
297
+ * `inspector.assistant` was minted while the chat was a fifth grid column, survived the column
298
+ * being deleted, and survives the `#chat-panel` DIV being deleted too — it is stamped by
299
+ * `panels/chat-panel.ts` on whatever container hosts the assistant, which is now the Inspector's
300
+ * fourth tab body. That is the whole argument for naming the role rather than the div, and the
301
+ * reason this table lost a row without any shot losing its subject.
302
+ *
303
+ * `pane.primary/frontmatter` left the table for the same reason. It named `#frontmatter-panel`, a
304
+ * grid row; the Document Header card is now drawn INSIDE the stage, so
305
+ * `panels/frontmatter-panel.ts` stamps the id on the card's own `<section>` wherever the stage puts
306
+ * it. Two rows gone, no shot re-pointed.
307
+ *
308
+ * `pane.primary` and `pane.primary/tabs` are the third and fourth to leave, and the clearest case
309
+ * yet: they named `#canvas-wrap` and `#tab-strip`, two flat siblings of an APPLICATION grid that
310
+ * were only ever the primary pane's stage and strip. `panels/pane-grid.ts` builds a cell per pane
311
+ * and stamps {@link paneRegion} on each, so the id is derived from the pane rather than from a div
312
+ * that could only ever be one of them. Four rows gone, not one shot re-pointed.
313
+ */
314
+ export const SHELL_REGION_HOSTS: Readonly<Record<string, string>> = {
315
+ "#activity-bar": "rail",
316
+ // The fourth overlay layer. It is here rather than stamped by `ui/layers.ts` for the same reason
317
+ // Every other row is: it is a bare `<div id>` in index.html, so it cannot stamp itself, and the
318
+ // Id has to resolve whether or not a toast has ever been raised — a region that only exists once
319
+ // Something has gone wrong is a region a shot cannot address and focus cannot be moved into.
320
+ "#layer-toast": "overlay.toasts",
321
+ "#left-panel": "navigator",
322
+ "#right-panel": "inspector",
323
+ "#statusbar": "statusbar",
324
+ "#toolbar": "commandbar",
325
+ };
326
+
327
+ /**
328
+ * Stamp the shell hosts. Idempotent, and safe to call before the DOM exists (an absent host is
329
+ * simply not stamped — the desktop shell and the tests both boot partial trees).
330
+ */
331
+ export function stampShellRegions(root: ParentNode = document): void {
332
+ for (const [selector, id] of Object.entries(SHELL_REGION_HOSTS)) {
333
+ root.querySelector(selector)?.setAttribute(REGION_ATTR, id);
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Region id for a pane, or for a part inside one — derived from the pane's own id.
339
+ *
340
+ * The fourth member of the derived-region family, and the one that had to exist before a second
341
+ * pane could be drawn. Twelve surfaces used to emit the literal `pane.primary/…` because the shell
342
+ * had exactly one pane to be; the moment two cells are on screen, every one of those ids resolves
343
+ * to two elements and `resolveRegion` takes the LAST — so a shot cropping `pane.primary/library`
344
+ * would silently photograph the SIDE pane's library. For the primary this produces byte-identical
345
+ * strings, which is why the manifest needed no edit.
346
+ *
347
+ * @param {string} paneId
348
+ * @param {string} [part]
349
+ * @returns {string}
350
+ */
351
+ export function paneRegion(paneId: string, part?: string): string {
352
+ return part ? `pane.${paneId}/${part}` : `pane.${paneId}`;
353
+ }
354
+
355
+ /** Region id of a pane's tab strip. One spelling, derived like every other. */
356
+ export function paneStripRegion(paneId: string): string {
357
+ return paneRegion(paneId, "tabs");
358
+ }
359
+
360
+ /** Region id for a Navigator panel, derived from the panel's own id. */
361
+ export function navigatorPanelRegion(panelId: string): string {
362
+ return `navigator/panel:${panelId}`;
363
+ }
364
+
365
+ /** Region id for an Inspector tab, derived from the tab record's value. */
366
+ export function inspectorTabRegion(tabId: string): string {
367
+ return `inspector/tab:${tabId}`;
368
+ }
369
+
370
+ /**
371
+ * The statement editor has TWO hosts, so the id names the host and not the control.
372
+ *
373
+ * `panels/statement-editor.ts` hard-stamped `navigator/statements` on itself. It is drawn by the
374
+ * Navigator's State panel AND by the Inspector's Events tab, both openable at once, and
375
+ * {@link resolveRegion} takes the LAST match in document order — `#right-panel` follows
376
+ * `#left-panel` — so the id addressed the INSPECTOR's editor under a name that says Navigator, and
377
+ * the shot cropping it cropped a control in the wrong dock.
378
+ *
379
+ * These two constants are the fix, and their shape is the general rule: a shared control cannot
380
+ * know where it is, so its region id is a REQUIRED argument its host supplies (see
381
+ * {@link import("../panels/statement-editor").StatementEditorOpts}). A third host cannot be added
382
+ * without naming itself.
383
+ */
384
+ export const NAVIGATOR_STATEMENTS_REGION = "navigator/statements";
385
+
386
+ /**
387
+ * The Inspector's statement editor, named by the HANDLER it edits.
388
+ *
389
+ * A constant was only half the fix. `panels/events-panel.ts` draws this editor inside
390
+ * `eventEntries.map(...)` — one per structured handler on the selected node — so a node with
391
+ * `onClick` and `onInput` stamped `inspector/statements` on two elements and `resolveRegion` took
392
+ * the second. That is the same defect the Navigator/Inspector split was made to close, one level
393
+ * down: an id that is unique because of what happens to be on screen is not unique.
394
+ *
395
+ * The Navigator's stays a constant because its host has ONE slot (`expandedSignal`), and deriving
396
+ * an id there would be inventing a distinction the surface does not have.
397
+ *
398
+ * @param {string} eventKey The handler's property key — `onClick`, `onInput`.
399
+ * @returns {string}
400
+ */
401
+ export function inspectorStatementsRegion(eventKey: string): string {
402
+ return `inspector/statements:${eventKey}`;
403
+ }
404
+
405
+ /**
406
+ * Region id for a Bottom dock tab, derived from the panel's own id.
407
+ *
408
+ * The third member of the derived-region family, and the one that shows the grammar was worth
409
+ * specifying before the surface existed: `dock.bottom` has parsed since P3 (it is the only surface
410
+ * whose NAME contains the instance separator, which is why {@link DOTTED_SURFACES} exists) and
411
+ * resolved to nothing, because nothing hosted it. `panels/bottom-dock.ts` stamps this once, from
412
+ * the same id `view.setBottomTab` accepts, so the dock's four tabs are addressable without anyone
413
+ * authoring an id — and the host itself carries the bare `dock.bottom` only while it is open, so a
414
+ * closed dock resolves to nothing rather than to an invisible box.
415
+ */
416
+ export function bottomPanelRegion(panelId: string): string {
417
+ return `dock.bottom/panel:${panelId}`;
418
+ }
419
+
420
+ /**
421
+ * The overlay instance each layer host contributes: a modal IS a dialog, a popover IS a menu.
422
+ *
423
+ * `toast` is plural because the host is the STACK, not one notification: `overlay.toasts` addresses
424
+ * the whole live region, which is what a shot crops and what a focus move lands in. An individual
425
+ * toast is a row inside it and is addressed by nothing — it is not a surface a user navigates to.
426
+ */
427
+ export const OVERLAY_INSTANCE: Readonly<Record<"popover" | "modal" | "dialog" | "toast", string>> =
428
+ {
429
+ dialog: "dialog",
430
+ modal: "dialog",
431
+ popover: "menu",
432
+ toast: "toasts",
433
+ };
434
+
435
+ /**
436
+ * Region id for an overlay slot.
437
+ *
438
+ * With an `id` this is `overlay.dialog:settings` — derived from the key `getLayerSlot` already
439
+ * builds, so naming a slot names its region. Without one it is the bare instance, which resolves to
440
+ * the topmost open overlay of that kind.
441
+ */
442
+ export function overlayRegion(
443
+ layer: "popover" | "modal" | "dialog" | "toast",
444
+ id?: string,
445
+ ): string {
446
+ const instance = OVERLAY_INSTANCE[layer];
447
+ return id ? `overlay.${instance}:${id}` : `overlay.${instance}`;
448
+ }
449
+
450
+ /**
451
+ * `regions` — the namespace §13.3 names, gathered so a consumer imports one thing.
452
+ *
453
+ * `probe.regions` is a projection of this; nothing here knows the camera exists.
454
+ */
455
+ export const regions = {
456
+ focusRegionOf,
457
+ idOf: regionIdOf,
458
+ list: listRegions,
459
+ parse: parseRegionId,
460
+ resolve: resolveRegion,
461
+ resolveAll: resolveAllRegions,
462
+ } as const;