@jxsuite/studio 6.1.1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -44,7 +44,16 @@
44
44
  * @docs studio/design/style-inspector
45
45
  */
46
46
 
47
- import { getNestedStyle } from "@jxsuite/schema/guards";
47
+ import {
48
+ getNestedStyle,
49
+ isFunctionDef,
50
+ isJsonObject,
51
+ isNestedStyle,
52
+ isNodeObject,
53
+ isNonNullObject,
54
+ isNumber,
55
+ isString,
56
+ } from "@jxsuite/schema/guards";
48
57
  import { effect, effectScope, reactive } from "../reactivity";
49
58
  import {
50
59
  cancelStyleDebounce,
@@ -76,11 +85,13 @@ import {
76
85
  varDisplayName,
77
86
  } from "../utils/studio-utils";
78
87
  import { stringArg } from "../commands/command-args";
88
+ import type { CommandArgValues, PropertySchema } from "../commands/command-args";
79
89
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
80
90
  import { showPromptDialog } from "../ui/layers";
81
91
  import { parseMediaEntries, schemeOfQuery } from "../utils/canvas-media";
82
92
  import { getEffectiveMedia, getEffectiveStyle } from "../site-context";
83
93
  import { computeInheritedSources } from "../utils/inherited-style";
94
+ import { tagAncestorSources } from "../style/tag-inheritance";
84
95
  import { loadUsages, peekUsages, usageFiles } from "../services/references";
85
96
  import { mediaDisplayName } from "./shared";
86
97
  import {
@@ -92,7 +103,7 @@ import {
92
103
  import {
93
104
  attachTargetLine,
94
105
  openSelectorMenu,
95
- resetTargetLine as resetTargetSelector,
106
+ resetTargetLine,
96
107
  setTargetLine,
97
108
  } from "../surfaces/target-line";
98
109
  import { clickAnythingTo, openPageAction, staleSelectionMessage } from "./empty-state";
@@ -101,20 +112,24 @@ import {
101
112
  autoOpenSections,
102
113
  compressBorderSide,
103
114
  compressShorthand,
115
+ cssDefs,
104
116
  cssMeta,
105
117
  expandBorderSide,
106
118
  expandShorthand,
107
119
  getCssInitialMap,
108
120
  getFontVars,
121
+ isDeclarationValue,
109
122
  TYPO_PREVIEW_CHANNELS,
110
123
  getLonghands,
111
124
  } from "./style-utils";
125
+ import type { CssFontPreset, CssLonghand, CssMetaEntry } from "./style-utils";
112
126
  import { UNIT_RE } from "../ui/unit-selector";
113
127
  import { colorTokens, resolvedColor } from "../ui/color-selector";
114
128
  import { resolveTokenValue, toTokenRef, tokenRefName } from "../style/token-ref";
129
+ import { PROJECT_VARIABLES_VIEW } from "../style/project-styles";
115
130
  import { mountStylePanelSurface } from "../surfaces/style-panel";
116
131
  import { openMenu } from "../surfaces/menu";
117
- import type { MenuHandle } from "../surfaces/menu";
132
+ import type { MenuHandle, MenuRowProjection } from "../surfaces/menu";
118
133
  import { cloneValue } from "../tabs/doc-op-apply";
119
134
  import { effectiveSlotMode, slotModeSeed, switchSlotMode } from "../ui/dynamic-slot";
120
135
  import { slotCaps, VALUE_SOURCE_HINTS, VALUE_SOURCE_LABELS } from "../ui/value-source";
@@ -138,21 +153,18 @@ import type { JxPath } from "../state";
138
153
  import type { JsonValue } from "../types";
139
154
  import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
140
155
 
141
- interface CssLonghand {
142
- name: string;
143
- entry: Record<string, unknown>;
144
- }
145
-
146
- type CssPropertyEntry = Record<string, unknown>;
147
-
148
156
  /** The chip a row wears when its caller has nothing more specific to say. */
149
157
  const DEFAULT_PROVENANCE: FieldProvenance = { state: "default" };
150
158
 
151
- type StyleMutateFn = (
152
- t: Tab,
153
- prop: string,
154
- val?: string | Record<string, unknown> | undefined,
155
- ) => void;
159
+ /**
160
+ * One write to one compound coordinate. A value is a declaration, `undefined` to delete it, or —
161
+ * from Relative Styling's add-a-rule, and nowhere else — the empty block `{}` a new nested rule
162
+ * starts as.
163
+ */
164
+ type StyleMutateFn = (t: Tab, prop: string, val?: string | JxStyle | undefined) => void;
165
+
166
+ /** The `mutateUpdate*Style` writer for one coordinate, at the `string` type they declare. */
167
+ type StyleWriteFn = (t: Tab, prop: string, value: string | undefined) => void;
156
168
 
157
169
  /**
158
170
  * Check if a selector is a stylebook tag path (e.g., "table" or "table th"). Tag paths don't start
@@ -209,7 +221,7 @@ function resolveContextStyle(
209
221
  }
210
222
  const flat: JxStyle = {};
211
223
  for (const [p, v] of Object.entries(base)) {
212
- if (typeof v !== "object") {
224
+ if (isDeclarationValue(v)) {
213
225
  flat[p] = v;
214
226
  }
215
227
  }
@@ -232,38 +244,26 @@ function contextMutate(
232
244
  activeSelector: string | null,
233
245
  editMedia: string | null,
234
246
  ): StyleMutateFn {
247
+ let write: StyleWriteFn;
235
248
  if (activeSelector && isTagPath(activeSelector)) {
236
249
  const stylePath = activeSelector.split(" ");
237
- return editMedia
238
- ? (t, prop, val) =>
239
- mutateUpdateMediaNestedStylePath(
240
- t,
241
- sel,
242
- editMedia,
243
- stylePath,
244
- prop,
245
- val as string | undefined,
246
- )
247
- : (t, prop, val) =>
248
- mutateUpdateNestedStylePath(t, sel, stylePath, prop, val as string | undefined);
249
- }
250
- if (activeSelector) {
251
- return editMedia
252
- ? (t, prop, val) =>
253
- mutateUpdateMediaNestedStyle(
254
- t,
255
- sel,
256
- editMedia,
257
- activeSelector,
258
- prop,
259
- val as string | undefined,
260
- )
261
- : (t, prop, val) =>
262
- mutateUpdateNestedStyle(t, sel, activeSelector, prop, val as string | undefined);
263
- }
264
- return editMedia
265
- ? (t, prop, val) => mutateUpdateMediaStyle(t, sel, editMedia, prop, val as string | undefined)
266
- : (t, prop, val) => mutateUpdateStyle(t, sel, prop, val as string | undefined);
250
+ write = editMedia
251
+ ? (t, prop, val) => mutateUpdateMediaNestedStylePath(t, sel, editMedia, stylePath, prop, val)
252
+ : (t, prop, val) => mutateUpdateNestedStylePath(t, sel, stylePath, prop, val);
253
+ } else if (activeSelector) {
254
+ write = editMedia
255
+ ? (t, prop, val) => mutateUpdateMediaNestedStyle(t, sel, editMedia, activeSelector, prop, val)
256
+ : (t, prop, val) => mutateUpdateNestedStyle(t, sel, activeSelector, prop, val);
257
+ } else {
258
+ write = editMedia
259
+ ? (t, prop, val) => mutateUpdateMediaStyle(t, sel, editMedia, prop, val)
260
+ : (t, prop, val) => mutateUpdateStyle(t, sel, prop, val);
261
+ }
262
+ /* SAFETY: the one non-string value a commit carries is the empty block `{}` Relative Styling
263
+ seeds a new nested rule with (see StyleMutateFn). Every `mutateUpdate*Style` writer stores the
264
+ value it is given as-is, deleting only on `undefined` or `""`, so the block lands as the rule's
265
+ body; their `string` parameter is narrower than what they store. */
266
+ return (t, prop, val) => write(t, prop, val as string | undefined);
267
267
  }
268
268
 
269
269
  /**
@@ -293,7 +293,7 @@ function mixedStyleProps(
293
293
  return mixed;
294
294
  }
295
295
  const blocks = targets.map((path) => {
296
- const node = getNodeAtPath(tab.doc.document, path) as JxMutableNode | undefined;
296
+ const node = getNodeAtPath(tab.doc.document, path);
297
297
  return resolveContextStyle(node?.style ?? {}, activeSelector, editMedia);
298
298
  });
299
299
  const props = new Set<string>();
@@ -314,7 +314,7 @@ function mixedStyleProps(
314
314
 
315
315
  /** Forget the selector menu's element handle — the Inspector unmounted, or a test starts clean. */
316
316
  export function resetSelectorMenu(): void {
317
- resetTargetSelector();
317
+ resetTargetLine();
318
318
  }
319
319
 
320
320
  /**
@@ -340,7 +340,7 @@ export function resetAffectedDisclosure(): void {
340
340
  * §6.2 forbids, so it routes to the definition site through the same command the context bar's
341
341
  * "Manage contexts…" footer runs.
342
342
  */
343
- function runCommand(id: string, args?: Record<string, unknown>): void {
343
+ function runCommand(id: string, args?: CommandArgValues): void {
344
344
  void activeRegistry()?.run(id, args);
345
345
  }
346
346
 
@@ -523,16 +523,16 @@ interface InheritedInfo {
523
523
  * `state.` is optional because both spellings occur in documents and both mean the same entry — the
524
524
  * chip names the signal, not the accessor path it was reached by.
525
525
  */
526
- function templateSignalOf(value: unknown): string | null {
527
- if (typeof value !== "string") {
526
+ function templateSignalOf(value: JxStyle[string]): string | null {
527
+ if (!isString(value)) {
528
528
  return null;
529
529
  }
530
530
  return /\$\{\s*(?:state\.)?([A-Za-z_$][\w$]*)/.exec(value)?.[1] ?? null;
531
531
  }
532
532
 
533
533
  /** Whether a value is a `${}` template rather than a literal — the `bound` rung for a CSS value. */
534
- function isTemplateValue(value: unknown): boolean {
535
- return typeof value === "string" && value.includes("${");
534
+ function isTemplateValue(value: JxStyle[string]): boolean {
535
+ return isString(value) && value.includes("${");
536
536
  }
537
537
 
538
538
  /** What the Style tab can say about one property's origin. */
@@ -582,28 +582,27 @@ function provenanceOf(prop: string, ctx: ProvenanceCtx): FieldProvenance {
582
582
  if (value !== undefined) {
583
583
  if (isTemplateValue(value)) {
584
584
  const signal = templateSignalOf(value);
585
- return {
586
- state: "bound",
587
- ...(signal ? { donor: signal } : {}),
588
- ...(signal && ctx.signals.includes(signal)
589
- ? {
590
- onClick: () => {
591
- runCommand("view.setActivity", { tab: "data" });
592
- runCommand("data.expandRow", { name: signal });
593
- },
594
- }
595
- : {}),
596
- };
585
+ const bound: FieldProvenance = { state: "bound" };
586
+ if (signal) {
587
+ bound.donor = signal;
588
+ if (ctx.signals.includes(signal)) {
589
+ bound.onClick = () => {
590
+ runCommand("view.setActivity", { tab: "data" });
591
+ runCommand("data.expandRow", { name: signal });
592
+ };
593
+ }
594
+ }
595
+ return bound;
597
596
  }
598
597
  return { state: "set", onClick: () => ctx.clear(prop) };
599
598
  }
600
599
  const inherited = ctx.inherited[prop];
601
600
  if (inherited) {
602
- return {
603
- state: "inherited",
604
- donor: inherited.donor,
605
- ...(inherited.jump ? { onClick: inherited.jump } : {}),
606
- };
601
+ const prov: FieldProvenance = { state: "inherited", donor: inherited.donor };
602
+ if (inherited.jump) {
603
+ prov.onClick = inherited.jump;
604
+ }
605
+ return prov;
607
606
  }
608
607
  return { state: "default" };
609
608
  }
@@ -628,14 +627,14 @@ function shorthandProvenance(
628
627
  ctx: ProvenanceCtx,
629
628
  clearAll?: (() => void) | undefined,
630
629
  ): FieldProvenance {
631
- const props = [shortProp, ...(getLonghands(shortProp) as CssLonghand[]).map((l) => l.name)];
630
+ const props = [shortProp, ...getLonghands(shortProp).map((l) => l.name)];
632
631
  const { mixed } = ctx;
633
632
  if (mixed && props.some((p) => mixed.props.has(p))) {
634
- return {
635
- state: "mixed",
636
- donor: String(mixed.count),
637
- ...(clearAll ? { onClick: clearAll } : {}),
638
- };
633
+ const prov: FieldProvenance = { state: "mixed", donor: String(mixed.count) };
634
+ if (clearAll) {
635
+ prov.onClick = clearAll;
636
+ }
637
+ return prov;
639
638
  }
640
639
  for (const p of props) {
641
640
  const prov = provenanceOf(p, ctx);
@@ -683,13 +682,10 @@ function longhandProvenance(
683
682
  /**
684
683
  * A section's tally, counting a shorthand as set when any of its longhands is.
685
684
  *
686
- * @param {{ prop: string; entry: CssPropertyEntry }[]} entries
685
+ * @param {CssPropertyItem[]} entries
687
686
  * @param {ProvenanceCtx} ctx
688
687
  */
689
- function sectionProvenance(
690
- entries: { prop: string; entry: CssPropertyEntry }[],
691
- ctx: ProvenanceCtx,
692
- ): ProvenanceState[] {
688
+ function sectionProvenance(entries: CssPropertyItem[], ctx: ProvenanceCtx): ProvenanceState[] {
693
689
  return entries.map(({ prop, entry }) =>
694
690
  inferInputType(entry) === "shorthand"
695
691
  ? shorthandProvenance(prop, ctx).state
@@ -699,6 +695,24 @@ function sectionProvenance(
699
695
 
700
696
  // ─── The row register ────────────────────────────────────────────────────────
701
697
 
698
+ /** One css-meta property, with its entry, as a section lists it. */
699
+ interface CssPropertyItem {
700
+ prop: string;
701
+ entry: CssMetaEntry;
702
+ }
703
+
704
+ /** One projected row and the verbs registered for it. */
705
+ interface ProjectedRow {
706
+ row: StyleRowView;
707
+ actions: RowActions;
708
+ }
709
+
710
+ /** A button-group row's buttons, and the values only its overflow list offers. */
711
+ interface ButtonGroupView {
712
+ buttons: StyleButtonView[];
713
+ extra: string[];
714
+ }
715
+
702
716
  /** One choice a row's list offers. `divider` draws a rule above the entry. */
703
717
  interface StyleChoice {
704
718
  value: string;
@@ -732,7 +746,8 @@ interface RowActions {
732
746
  mode: SlotMode;
733
747
  caps: SlotMode[];
734
748
  fieldKey: string;
735
- value: unknown;
749
+ /** The field's literal, or `undefined` when it is empty. */
750
+ value: string | undefined;
736
751
  stateDefs: string[];
737
752
  onChange: (value?: JsonValue) => void;
738
753
  };
@@ -795,15 +810,11 @@ function isNumericValue(value: string): boolean {
795
810
  * manifest lacks is a red `tests/metadata.test.ts`, which is where a miss is caught before it ships
796
811
  * rather than degraded after.
797
812
  */
798
- function buttonGroup(
799
- entry: CssPropertyEntry,
800
- rowKey: string,
801
- value: string,
802
- ): { buttons: StyleButtonView[]; extra: string[] } {
803
- const values = (entry.$buttonValues || entry.enum || []) as string[];
804
- const iconMap = (entry.$icons || {}) as Record<string, string>;
805
- const buttonValues = entry.$buttonValues as string[] | undefined;
806
- const enumValues = entry.enum as string[] | undefined;
813
+ function buttonGroup(entry: CssMetaEntry, rowKey: string, value: string): ButtonGroupView {
814
+ const values = entry.$buttonValues || entry.enum || [];
815
+ const iconMap = entry.$icons || {};
816
+ const buttonValues = entry.$buttonValues;
817
+ const enumValues = entry.enum;
807
818
  const extra =
808
819
  buttonValues && enumValues && enumValues.length > buttonValues.length
809
820
  ? enumValues.filter((v) => !buttonValues.includes(v))
@@ -842,7 +853,7 @@ function keywordChoices(options: string[], value: string): StyleChoice[] {
842
853
  * words alone.
843
854
  */
844
855
  function keywordOptions(options: string[], prop: string, face: string): StyleOptionView[] {
845
- const channel = TYPO_PREVIEW_CHANNELS[prop];
856
+ const channel = TYPO_PREVIEW_CHANNELS.get(prop);
846
857
  return options.map((v) => {
847
858
  const option: StyleOptionView = { label: keywordLabel(v), value: v };
848
859
  if (channel) {
@@ -862,16 +873,16 @@ function keywordOptions(options: string[], prop: string, face: string): StyleOpt
862
873
  */
863
874
  function previewFace(ctx: EditorCtx): string {
864
875
  const raw = ctx.activeStyle.fontFamily ?? ctx.inheritedStyle.fontFamily;
865
- if (typeof raw !== "string" && typeof raw !== "number") {
876
+ if (!isString(raw) && !isNumber(raw)) {
866
877
  return "";
867
878
  }
868
- const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document?.style), raw);
879
+ const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document.style), raw);
869
880
  return resolved === undefined ? "" : String(resolved);
870
881
  }
871
882
 
872
883
  /** The Modern Font Stacks a `fontFamily` entry offers, as css-meta.json states them. */
873
- function fontPresets(entry: CssPropertyEntry): { title: string; value: string }[] {
874
- return Array.isArray(entry.presets) ? (entry.presets as { title: string; value: string }[]) : [];
884
+ function fontPresets(entry: CssMetaEntry): CssFontPreset[] {
885
+ return Array.isArray(entry.presets) ? entry.presets : [];
875
886
  }
876
887
 
877
888
  /**
@@ -886,7 +897,7 @@ function fontPresets(entry: CssPropertyEntry): { title: string; value: string }[
886
897
  * the pick will write is in the list; a preset row is bare, which is what tells the two groups
887
898
  * apart in a list that draws no divider.
888
899
  */
889
- function fontOptions(entry: CssPropertyEntry): StyleOptionView[] {
900
+ function fontOptions(entry: CssMetaEntry): StyleOptionView[] {
890
901
  const fontVars = getFontVars();
891
902
  const style = getEffectiveStyle(activeTab.value?.doc.document?.style);
892
903
  const options: StyleOptionView[] = fontVars.map((fv) => ({
@@ -913,7 +924,7 @@ function fontOptions(entry: CssPropertyEntry): StyleOptionView[] {
913
924
  * minted early would be left behind when they finished typing something else.
914
925
  */
915
926
  function commitFont(
916
- entry: CssPropertyEntry,
927
+ entry: CssMetaEntry,
917
928
  raw: string,
918
929
  mint: boolean,
919
930
  onCommit: (value: string) => void,
@@ -1008,7 +1019,7 @@ interface EditorCtx {
1008
1019
  /** One write, fanned across every selected element, inside the caller's transaction. */
1009
1020
  mutate: StyleMutateFn;
1010
1021
  /** The same write in a transaction of its own. */
1011
- commit: (prop: string, value?: string | Record<string, unknown> | undefined) => void;
1022
+ commit: (prop: string, value?: string | JxStyle | undefined) => void;
1012
1023
  /** The key prefix a row's identity is built from — the coordinate, spelled once. */
1013
1024
  coord: string;
1014
1025
  targets: readonly JxPath[];
@@ -1034,7 +1045,7 @@ function styleCaps(): SlotMode[] {
1034
1045
  /** One ordinary property row: the label, the chip, the ladder and whichever control it draws. */
1035
1046
  function fieldRow(
1036
1047
  ctx: EditorCtx,
1037
- entry: CssPropertyEntry,
1048
+ entry: CssMetaEntry,
1038
1049
  prop: string,
1039
1050
  value: string,
1040
1051
  opts: {
@@ -1045,7 +1056,7 @@ function fieldRow(
1045
1056
  onCommit: (value: string | undefined) => void;
1046
1057
  placeholder?: string;
1047
1058
  },
1048
- ): { row: StyleRowView; actions: RowActions } {
1059
+ ): ProjectedRow {
1049
1060
  const key = `${ctx.coord}|${prop}${opts.child ? "|child" : ""}`;
1050
1061
  const row = blankRow(key, prop, "field");
1051
1062
  const actions: RowActions = {};
@@ -1123,8 +1134,8 @@ function fieldRow(
1123
1134
  break;
1124
1135
  }
1125
1136
  case "number-unit": {
1126
- const units = (entry.$units ?? []) as string[];
1127
- const keywords = (entry.$keywords ?? []) as string[];
1137
+ const units = entry.$units ?? [];
1138
+ const keywords = entry.$keywords ?? [];
1128
1139
  const match = UNIT_RE.exec(value);
1129
1140
  const isKeyword = !match && value !== "" && keywords.includes(value);
1130
1141
  const currentUnit = isKeyword ? (units[0] ?? "") : (match?.[2] ?? units[0] ?? "");
@@ -1136,12 +1147,14 @@ function fieldRow(
1136
1147
  row.choicesHint = `Unit for ${row.label.toLowerCase()}`;
1137
1148
  actions.choices = [
1138
1149
  ...units.map((u) => ({ checked: u === currentUnit, label: u, value: u })),
1139
- ...keywords.map((kw, index) => ({
1140
- checked: kw === value,
1141
- label: kw,
1142
- value: kw,
1143
- ...(index === 0 && units.length > 0 ? { divider: true } : {}),
1144
- })),
1150
+ ...keywords.map((kw, index) => {
1151
+ const choice: StyleChoice = { checked: kw === value, label: kw, value: kw };
1152
+ // The rule between the units and the keywords, drawn only when there are units above.
1153
+ if (index === 0 && units.length > 0) {
1154
+ choice.divider = true;
1155
+ }
1156
+ return choice;
1157
+ }),
1145
1158
  ];
1146
1159
  actions.choose = (chosen) => {
1147
1160
  if (keywords.includes(chosen)) {
@@ -1172,16 +1185,16 @@ function fieldRow(
1172
1185
  row.widget = "number";
1173
1186
  row.min = entry.minimum === undefined ? "" : String(entry.minimum);
1174
1187
  row.max = entry.maximum === undefined ? "" : String(entry.maximum);
1175
- row.step = typeof entry.maximum === "number" && entry.maximum <= 1 ? "0.1" : "";
1188
+ row.step = entry.maximum !== undefined && entry.maximum <= 1 ? "0.1" : "";
1176
1189
  actions.commit = commitLiteral;
1177
1190
  break;
1178
1191
  }
1179
1192
  case "select":
1180
1193
  case "combobox": {
1181
1194
  const options = Array.isArray(entry.enum)
1182
- ? (entry.enum as string[])
1195
+ ? entry.enum
1183
1196
  : Array.isArray(entry.examples)
1184
- ? (entry.examples as string[])
1197
+ ? entry.examples
1185
1198
  : [];
1186
1199
  // A keyword row is the combobox contract exactly: the field IS the value, and the rows
1187
1200
  // Under it are the values worth offering. `allows-custom-value` is what makes an enum a
@@ -1238,17 +1251,13 @@ function unitDisplayValue(
1238
1251
 
1239
1252
  /** A unit field's placeholder is the inherited NUMBER — "500", not "500px". */
1240
1253
  function unitPlaceholder(placeholder: string): string {
1241
- return UNIT_RE.exec(placeholder)?.[1] ?? placeholder ?? "0";
1254
+ return UNIT_RE.exec(placeholder)?.[1] ?? placeholder;
1242
1255
  }
1243
1256
 
1244
1257
  /** A shorthand header row and, when it is expanded, the longhand children under it. */
1245
- function shorthandRows(
1246
- ctx: EditorCtx,
1247
- entry: CssPropertyEntry,
1248
- shortProp: string,
1249
- ): { row: StyleRowView; actions: RowActions }[] {
1250
- const longhands = getLonghands(shortProp) as CssLonghand[];
1251
- const style = ctx.activeStyle as Record<string, unknown>;
1258
+ function shorthandRows(ctx: EditorCtx, entry: CssMetaEntry, shortProp: string): ProjectedRow[] {
1259
+ const longhands = getLonghands(shortProp);
1260
+ const style = ctx.activeStyle;
1252
1261
  const shortVal = style[shortProp];
1253
1262
  const hasLonghands = longhands.some((l) => style[l.name] !== undefined);
1254
1263
  const isExpanded = ctx.tab.session.ui.styleShorthands[shortProp] ?? hasLonghands;
@@ -1284,7 +1293,7 @@ function shorthandRows(
1284
1293
  row.widget = "shorthand";
1285
1294
  row.hasLabel = true;
1286
1295
  row.label = propLabel(entry, shortProp);
1287
- row.value = typeof shortVal === "string" ? shortVal : "";
1296
+ row.value = isString(shortVal) ? shortVal : "";
1288
1297
  row.placeholder = shorthandPlaceholder(shortVal, longhands, style, inherited, shortProp);
1289
1298
  row.expanded = isExpanded;
1290
1299
  row.expandIcon = isExpanded ? "caret-down" : "caret-right";
@@ -1307,14 +1316,14 @@ function shorthandRows(
1307
1316
  }
1308
1317
  };
1309
1318
 
1310
- const out = [{ actions, row }];
1319
+ const out: ProjectedRow[] = [{ actions, row }];
1311
1320
  if (!isExpanded) {
1312
1321
  return out;
1313
1322
  }
1314
1323
 
1315
1324
  const isBorderSide = entry.$shorthandType === "border-side";
1316
1325
  const expanded =
1317
- typeof shortVal === "string" && shortVal
1326
+ isString(shortVal) && shortVal
1318
1327
  ? isBorderSide
1319
1328
  ? expandBorderSide(shortVal)
1320
1329
  : expandShorthand(shortVal, longhands.length)
@@ -1325,9 +1334,11 @@ function shorthandRows(
1325
1334
  const recompress = (idx: number, val: string) =>
1326
1335
  writeShorthand(
1327
1336
  compress(
1337
+ /* As text: the compressors join and compare strings, and a number a document holds reads
1338
+ exactly as the template literal they build would have printed it. */
1328
1339
  longhands.map((l, i) =>
1329
- i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
1330
- ) as string[],
1340
+ String(i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal))),
1341
+ ),
1331
1342
  ),
1332
1343
  );
1333
1344
 
@@ -1350,9 +1361,9 @@ function shorthandRows(
1350
1361
 
1351
1362
  /** The shorthand header's placeholder: the longhands it would compress, or what shows through. */
1352
1363
  function shorthandPlaceholder(
1353
- shortVal: unknown,
1364
+ shortVal: JxStyle[string],
1354
1365
  longhands: CssLonghand[],
1355
- style: Record<string, unknown>,
1366
+ style: JxStyle,
1356
1367
  inherited: Record<string, string | number>,
1357
1368
  shortProp: string,
1358
1369
  ): string {
@@ -1373,6 +1384,11 @@ function shorthandPlaceholder(
1373
1384
 
1374
1385
  // ─── The whole view ──────────────────────────────────────────────────────────
1375
1386
 
1387
+ /** What the Style tab says beside the Variables view, where there is no element to style. */
1388
+ export const VARIABLES_INSPECTOR_MESSAGE =
1389
+ "Variables are edited in the view itself. Switch the view to Elements and pick a tag to style " +
1390
+ "its default here.";
1391
+
1376
1392
  /** The three teaching states, and the one that offers a button. */
1377
1393
  function emptyView(message: string, withOpen: boolean): StylePanelView {
1378
1394
  return {
@@ -1392,9 +1408,17 @@ function buildView(canvasMode: () => string): StylePanelView {
1392
1408
  if (!tab) {
1393
1409
  return emptyView("Open a page to style what you click.", true);
1394
1410
  }
1411
+ /* The Styles workspace's Variables view has no canvas to click and edits its custom properties in
1412
+ the pane itself, so the canvas teaching line would ask for something impossible. Say where the
1413
+ Inspector's half of the workspace is instead. */
1414
+ if (canvasMode() === PROJECT_VARIABLES_VIEW) {
1415
+ return emptyView(VARIABLES_INSPECTOR_MESSAGE, false);
1416
+ }
1395
1417
  if (canvasMode() === "stylebook" && shell.stylebook.selection) {
1396
1418
  const node = tab.doc.document;
1397
- if (!node) {
1419
+ /* Checked, not trusted: a tab's document is whatever the file parsed to, asserted rather than
1420
+ verified where it is loaded (`files/files.ts`), and Stylebook reads its root style next. */
1421
+ if (!isNodeObject(node)) {
1398
1422
  return emptyView("Open a page to style what you click.", true);
1399
1423
  }
1400
1424
  // No separate `Styling: <h1>` header. It said the same thing the Target Line's scope chip says,
@@ -1408,7 +1432,7 @@ function buildView(canvasMode: () => string): StylePanelView {
1408
1432
  if (!selected) {
1409
1433
  return emptyView(clickAnythingTo("style it"), false);
1410
1434
  }
1411
- const node = getNodeAtPath(tab.doc.document, selected) as JxMutableNode | undefined;
1435
+ const node = getNodeAtPath(tab.doc.document, selected);
1412
1436
  if (!node) {
1413
1437
  return emptyView(staleSelectionMessage(), false);
1414
1438
  }
@@ -1431,17 +1455,16 @@ function buildEditor(
1431
1455
  opts: { effectiveStyle?: JxStyle | undefined; stylebookSelector?: string | null },
1432
1456
  ): StylePanelView {
1433
1457
  const { effectiveStyle, stylebookSelector = null } = opts;
1434
- const sel = primarySelection(tab.session.selection) as JxPath;
1458
+ /* `buildView` calls this with a primary selection it has checked, or in Stylebook, where the
1459
+ edit targets a TAG and the selection is only parked on the root. A Stylebook tab whose session
1460
+ was never parked (or was cleared since) therefore means the root too, rather than a throw. */
1461
+ const sel: JxPath = primarySelection(tab.session.selection) ?? [];
1435
1462
  /** The document's OWN style — what a commit writes into. */
1436
1463
  const ownRootStyle: JxStyle = node.style || {};
1437
1464
  const style = effectiveStyle ?? ownRootStyle;
1438
1465
  // Signals seeding the ${} template default when a style value escalates (no $ref in JxStyle).
1439
1466
  const templateSignals = Object.entries(tab.doc.document.state || {})
1440
- .filter(
1441
- ([, d]) =>
1442
- !(d as Record<string, unknown>)?.$handler &&
1443
- (d as Record<string, unknown>)?.$prototype !== "Function",
1444
- )
1467
+ .filter(([, d]) => !(isJsonObject(d) && d.$handler) && !isFunctionDef(d))
1445
1468
  .map(([defName]) => defName);
1446
1469
  const { sizeBreakpoints } = parseMediaEntries(getEffectiveMedia(tab.doc.document.$media));
1447
1470
  const mediaNames = sizeBreakpoints.map((bp) => bp.name);
@@ -1455,7 +1478,7 @@ function buildEditor(
1455
1478
  const forcedScheme = tab.session.ui.previewColorScheme;
1456
1479
  const schemeLayer =
1457
1480
  mediaTab === null && (forcedScheme === "light" || forcedScheme === "dark")
1458
- ? (Object.entries(getEffectiveMedia(tab.doc.document.$media) ?? {}).find(
1481
+ ? (Object.entries(getEffectiveMedia(tab.doc.document.$media)).find(
1459
1482
  ([, q]) => schemeOfQuery(String(q)) === forcedScheme,
1460
1483
  )?.[0] ?? null)
1461
1484
  : null;
@@ -1463,9 +1486,7 @@ function buildEditor(
1463
1486
  const editMedia = mediaTab && mediaNames.length > 0 ? mediaTab : schemeLayer;
1464
1487
 
1465
1488
  // ── The selector axis — the one this tab owns ──────────────────────────────
1466
- const contextStyle = editMedia
1467
- ? (style[`@${editMedia}`] as Record<string, unknown>) || {}
1468
- : style;
1489
+ const contextStyle = editMedia ? (getNestedStyle(style, `@${editMedia}`) ?? {}) : style;
1469
1490
  const declaredSelectors = new Set(Object.keys(contextStyle).filter((s) => isNestedSelector(s)));
1470
1491
  /* Element-aware, not the flat global list: `:popover-open` on a `<p>` is a rule that can never
1471
1492
  match, and a menu that offers unmatchable states is a menu people stop reading. What the
@@ -1500,8 +1521,7 @@ function buildEditor(
1500
1521
 
1501
1522
  // ── The Target Line (§6.2) ─────────────────────────────────────────────────
1502
1523
  const stylebookTag = stylebookTagOf(stylebookSelector);
1503
- const elementLabel =
1504
- stylebookTag ?? (typeof node.tagName === "string" ? node.tagName : "element");
1524
+ const elementLabel = stylebookTag ?? (isString(node.tagName) ? node.tagName : "element");
1505
1525
  setTargetLine({
1506
1526
  segments: targetSegments(elementLabel, mediaTab, mediaNames.length > 0, schemeLayer),
1507
1527
  selector: {
@@ -1584,7 +1604,7 @@ function buildEditor(
1584
1604
  contextMutate(target, activeSelector, editMedia)(t, prop, val);
1585
1605
  }
1586
1606
  };
1587
- const commitStyle = (prop: string, val?: string | Record<string, unknown> | undefined) =>
1607
+ const commitStyle = (prop: string, val?: string | JxStyle | undefined) =>
1588
1608
  transactDoc(activeTab.value, (t) => mutateTargets(t, prop, val));
1589
1609
 
1590
1610
  // ── Compute inherited style, and NAME THE DONOR ────────────────────────────
@@ -1595,9 +1615,9 @@ function buildEditor(
1595
1615
  if (schemeLayer) {
1596
1616
  const baseBlock = activeSelector ? (getNestedStyle(style, activeSelector) ?? {}) : style;
1597
1617
  for (const [p, v] of Object.entries(baseBlock)) {
1598
- if (typeof v !== "object") {
1618
+ if (isDeclarationValue(v)) {
1599
1619
  inheritedInfo[p] = {
1600
- value: (v as string | number) ?? "",
1620
+ value: v ?? "",
1601
1621
  donor: "Base",
1602
1622
  jump: () => updateUi(activeTab.value, "previewColorScheme", "auto"),
1603
1623
  };
@@ -1614,6 +1634,14 @@ function buildEditor(
1614
1634
  };
1615
1635
  }
1616
1636
  }
1637
+ // A Project Styles tag rule also inherits from the rules above it in this same file (`body`,
1638
+ // Then each ancestor tag in its path), which is what its specimen is drawn with. The context walk
1639
+ // Above outranks it: a value the tag itself sets at Base is nearer than anything it inherits.
1640
+ if (stylebookPath) {
1641
+ for (const [p, source] of Object.entries(tagAncestorSources(style, stylebookPath, editMedia))) {
1642
+ inheritedInfo[p] ??= { donor: source.donor, value: source.value };
1643
+ }
1644
+ }
1617
1645
  const inheritedStyle: Record<string, string | number> = {};
1618
1646
  for (const [p, info] of Object.entries(inheritedInfo)) {
1619
1647
  inheritedStyle[p] = info.value;
@@ -1625,8 +1653,10 @@ function buildEditor(
1625
1653
  inherited: inheritedInfo,
1626
1654
  signals: templateSignals,
1627
1655
  clear: (prop: string) => commitStyle(prop),
1628
- ...(mixedProps.size > 0 ? { mixed: { count: targets.length, props: mixedProps } } : {}),
1629
1656
  };
1657
+ if (mixedProps.size > 0) {
1658
+ provCtx.mixed = { count: targets.length, props: mixedProps };
1659
+ }
1630
1660
 
1631
1661
  // Auto-open sections that have properties. Written back only when it actually moves, so the
1632
1662
  // Effect this runs inside settles after one extra pass rather than chasing its own write.
@@ -1663,7 +1693,7 @@ function buildEditor(
1663
1693
  }
1664
1694
 
1665
1695
  /** Register a projected row's verbs, and hand back the row. */
1666
- function register(entry: { row: StyleRowView; actions: RowActions }): StyleRowView {
1696
+ function register(entry: ProjectedRow): StyleRowView {
1667
1697
  _rows.set(entry.row.key, entry.actions);
1668
1698
  return entry.row;
1669
1699
  }
@@ -1672,18 +1702,18 @@ function register(entry: { row: StyleRowView; actions: RowActions }): StyleRowVi
1672
1702
  function propertySections(ctx: EditorCtx): StyleSectionView[] {
1673
1703
  const { activeStyle, tab } = ctx;
1674
1704
  const isFiltering = ctx.filter.length > 0;
1675
- const sectionProps: Record<string, { prop: string; entry: CssPropertyEntry }[]> = {};
1705
+ const sectionProps: Record<string, CssPropertyItem[]> = {};
1676
1706
  for (const sec of cssMeta.$sections) {
1677
1707
  sectionProps[sec.key] = [];
1678
1708
  }
1679
- for (const [prop, entry] of Object.entries(cssMeta.$defs) as [string, CssPropertyEntry][]) {
1680
- if (typeof entry.$shorthand === "string") {
1709
+ for (const [prop, entry] of Object.entries(cssDefs)) {
1710
+ if (isString(entry.$shorthand)) {
1681
1711
  continue;
1682
1712
  }
1683
- sectionProps[(entry.$section as string) || "other"]!.push({ entry, prop });
1713
+ sectionProps[entry.$section || "other"]!.push({ entry, prop });
1684
1714
  }
1685
1715
  for (const sec of cssMeta.$sections) {
1686
- sectionProps[sec.key]!.sort((a, b) => (a.entry.$order as number) - (b.entry.$order as number));
1716
+ sectionProps[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
1687
1717
  }
1688
1718
 
1689
1719
  const out: StyleSectionView[] = [];
@@ -1698,7 +1728,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
1698
1728
  }
1699
1729
  return (
1700
1730
  inferInputType(entry) === "shorthand" &&
1701
- (getLonghands(prop) as CssLonghand[]).some((l) => activeStyle[l.name] !== undefined)
1731
+ getLonghands(prop).some((l) => activeStyle[l.name] !== undefined)
1702
1732
  );
1703
1733
  });
1704
1734
  const clearSection = () => {
@@ -1708,7 +1738,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
1708
1738
  ctx.mutate(t, prop);
1709
1739
  }
1710
1740
  if (inferInputType(entry) === "shorthand") {
1711
- for (const l of getLonghands(prop) as CssLonghand[]) {
1741
+ for (const l of getLonghands(prop)) {
1712
1742
  ctx.mutate(t, l.name);
1713
1743
  }
1714
1744
  }
@@ -1738,11 +1768,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
1738
1768
  }
1739
1769
 
1740
1770
  /** One section's rows: every property that is set, or whose `$show` condition passes. */
1741
- function sectionRows(
1742
- ctx: EditorCtx,
1743
- entries: { prop: string; entry: CssPropertyEntry }[],
1744
- grid: boolean,
1745
- ): StyleRowView[] {
1771
+ function sectionRows(ctx: EditorCtx, entries: CssPropertyItem[], grid: boolean): StyleRowView[] {
1746
1772
  const { activeStyle } = ctx;
1747
1773
  const rows: StyleRowView[] = [];
1748
1774
  for (const { prop, entry } of entries) {
@@ -1760,7 +1786,7 @@ function sectionRows(
1760
1786
  }
1761
1787
  }
1762
1788
  if (type === "shorthand") {
1763
- const longhands = getLonghands(prop) as CssLonghand[];
1789
+ const longhands = getLonghands(prop);
1764
1790
  const hasAny = hasVal || longhands.some((l) => activeStyle[l.name] !== undefined);
1765
1791
  if (!hasAny && !condMet) {
1766
1792
  continue;
@@ -1771,7 +1797,7 @@ function sectionRows(
1771
1797
  continue;
1772
1798
  }
1773
1799
  const inherited = ctx.inheritedStyle[prop];
1774
- const built = fieldRow(ctx, entry, prop, (val as string) ?? "", {
1800
+ const built = fieldRow(ctx, entry, prop, String(val ?? ""), {
1775
1801
  onCommit: (newVal) => ctx.commit(prop, newVal || undefined),
1776
1802
  placeholder: !hasVal && inherited !== undefined ? String(inherited) : "",
1777
1803
  provenance: provenanceOf(prop, ctx.provCtx),
@@ -1823,7 +1849,7 @@ function sectionShell(
1823
1849
  function nestedSection(ctx: EditorCtx): StyleSectionView[] {
1824
1850
  const nestedRules: string[] = [];
1825
1851
  for (const [prop, val] of Object.entries(ctx.activeStyle)) {
1826
- if (val !== null && typeof val === "object" && !Array.isArray(val) && !prop.startsWith("@")) {
1852
+ if (isNestedStyle(val) && !prop.startsWith("@")) {
1827
1853
  nestedRules.push(prop);
1828
1854
  }
1829
1855
  }
@@ -1880,9 +1906,9 @@ function nestedSection(ctx: EditorCtx): StyleSectionView[] {
1880
1906
  function customSection(ctx: EditorCtx): StyleSectionView[] {
1881
1907
  const otherProps: string[] = [];
1882
1908
  for (const prop of Object.keys(ctx.activeStyle)) {
1883
- if (!(cssMeta.$defs as Record<string, unknown>)[prop]) {
1884
- const val = ctx.activeStyle[prop];
1885
- if (val !== null && typeof val === "object") {
1909
+ if (!cssDefs[prop]) {
1910
+ // Arrays and blocks are skipped; a `null` a document holds is listed, as it always was.
1911
+ if (isNonNullObject(ctx.activeStyle[prop])) {
1886
1912
  continue;
1887
1913
  }
1888
1914
  otherProps.push(prop);
@@ -1901,7 +1927,7 @@ function customSection(ctx: EditorCtx): StyleSectionView[] {
1901
1927
  const cssInitialMap = getCssInitialMap();
1902
1928
  /** One target's OWN block at this coordinate — what a write that preserves values reads first. */
1903
1929
  const targetStyleOf = (t: Tab, target: JxPath): JxStyle => {
1904
- const targetNode = getNodeAtPath(t.doc.document, target) as JxMutableNode | undefined;
1930
+ const targetNode = getNodeAtPath(t.doc.document, target);
1905
1931
  return resolveContextStyle(targetNode?.style ?? {}, ctx.activeSelector, ctx.editMedia);
1906
1932
  };
1907
1933
  for (const prop of otherProps) {
@@ -1979,14 +2005,16 @@ function closeRowMenu(): void {
1979
2005
  menu?.close();
1980
2006
  }
1981
2007
 
1982
- /** Open a list under the control that asked for it. One menu at a time, the kit's. */
2008
+ /**
2009
+ * Open a list under the control that asked for it. One menu at a time, the kit's. `trigger` is null
2010
+ * when the surface handed over something that is not an element, which opens nothing.
2011
+ */
1983
2012
  function openRowMenu(
1984
- anchor: unknown,
2013
+ trigger: HTMLElement | null,
1985
2014
  label: string,
1986
2015
  choices: StyleChoice[],
1987
2016
  run: (value: string) => void,
1988
2017
  ): void {
1989
- const trigger = anchor instanceof HTMLElement ? anchor : null;
1990
2018
  closeRowMenu();
1991
2019
  if (!trigger || choices.length === 0) {
1992
2020
  return;
@@ -2000,16 +2028,19 @@ function openRowMenu(
2000
2028
  },
2001
2029
  opener: trigger,
2002
2030
  region: MENU_REGION,
2003
- rows: choices.map((choice) => ({
2004
- ...(choice.checked === undefined
2005
- ? {}
2006
- : { checked: (choice.checked ? "true" : "false") as "true" | "false" }),
2007
- destructive: false,
2008
- disabled: false,
2009
- dividerAbove: choice.divider === true,
2010
- id: choice.value,
2011
- title: choice.label,
2012
- })),
2031
+ rows: choices.map((choice) => {
2032
+ const row: MenuRowProjection = {
2033
+ destructive: false,
2034
+ disabled: false,
2035
+ dividerAbove: choice.divider === true,
2036
+ id: choice.value,
2037
+ title: choice.label,
2038
+ };
2039
+ if (choice.checked !== undefined) {
2040
+ row.checked = choice.checked ? "true" : "false";
2041
+ }
2042
+ return row;
2043
+ }),
2013
2044
  run: (value) => run(value),
2014
2045
  });
2015
2046
  }
@@ -2058,7 +2089,9 @@ const ACTIONS: StylePanelActions = {
2058
2089
  return;
2059
2090
  }
2060
2091
  const { choose } = actions;
2061
- openRowMenu(anchor, "Values", actions.choices, (value) => choose(value));
2092
+ openRowMenu(anchor instanceof HTMLElement ? anchor : null, "Values", actions.choices, (value) =>
2093
+ choose(value),
2094
+ );
2062
2095
  },
2063
2096
  pickSource: (key, anchor) => {
2064
2097
  const source = rowActions(key)?.source;
@@ -2066,7 +2099,7 @@ const ACTIONS: StylePanelActions = {
2066
2099
  return;
2067
2100
  }
2068
2101
  openRowMenu(
2069
- anchor,
2102
+ anchor instanceof HTMLElement ? anchor : null,
2070
2103
  "Value source",
2071
2104
  source.caps.map((mode) => ({
2072
2105
  checked: mode === source.mode,
@@ -2074,8 +2107,8 @@ const ACTIONS: StylePanelActions = {
2074
2107
  value: mode,
2075
2108
  })),
2076
2109
  (chosen) => {
2077
- const next = chosen as SlotMode;
2078
- if (next === source.mode) {
2110
+ const next = source.caps.find((mode) => mode === chosen);
2111
+ if (next === undefined || next === source.mode) {
2079
2112
  return;
2080
2113
  }
2081
2114
  source.onChange(
@@ -2083,7 +2116,7 @@ const ACTIONS: StylePanelActions = {
2083
2116
  source.fieldKey,
2084
2117
  source.mode,
2085
2118
  next,
2086
- cloneValue(source.value as JsonValue | undefined),
2119
+ cloneValue(source.value),
2087
2120
  slotModeSeed(next, { stateDefs: source.stateDefs }),
2088
2121
  ),
2089
2122
  );
@@ -2123,6 +2156,11 @@ let _standing: { host: HTMLElement; handle: StylePanelSurface; scope: EffectScop
2123
2156
  export interface StyleHostDeps {
2124
2157
  /** `stylebook` edits a tag catalogue entry; anything else edits the element selection. */
2125
2158
  getCanvasMode: () => string;
2159
+ /**
2160
+ * Whether the tab is the one showing. Read inside the projecting effect, so a hidden tab costs
2161
+ * nothing per selection and re-projects the moment it is opened. Absent means always showing.
2162
+ */
2163
+ isShowing?: () => boolean;
2126
2164
  }
2127
2165
 
2128
2166
  /** The default the tab falls back to when the dock names no mode. */
@@ -2175,9 +2213,16 @@ export function bindStyleHost(el: HTMLElement | null, ctx?: StyleHostDeps): void
2175
2213
  const handle = mountStylePanelSurface(el, first, ACTIONS, {
2176
2214
  target: (element) => attachTargetLine(element ?? undefined),
2177
2215
  });
2216
+ const isShowing = ctx?.isShowing ?? (() => true);
2178
2217
  const scope = effectScope();
2179
2218
  scope.run(() => {
2180
2219
  effect(() => {
2220
+ /* A hidden tab does not project. Its editor is thousands of nodes, and a new selection
2221
+ re-keys every row, so projecting behind the Content tab rebuilt the whole of it on every
2222
+ click — most of what selecting an element cost. */
2223
+ if (!isShowing()) {
2224
+ return;
2225
+ }
2181
2226
  const view = buildView(_canvasMode);
2182
2227
  rememberButtons(view);
2183
2228
  handle.update(view);
@@ -2236,35 +2281,37 @@ export function styleCommands(): AnyCommand[] {
2236
2281
  group: "8_style",
2237
2282
  requires: "an element selection",
2238
2283
  when: styleTabOpen,
2239
- run: (_commandCtx, args) => {
2240
- const { selector } = args as { selector?: unknown };
2241
- if (selector === null) {
2242
- const tab = activeTab.value;
2243
- if (tab) {
2244
- tab.session.ui.activeSelector = null;
2245
- }
2246
- return;
2247
- }
2248
- const value = stringArg("style.setSelector", args, "selector");
2249
- if (!isNestedSelector(value)) {
2250
- throw new RangeError(
2251
- `command "style.setSelector" argument "selector": "${value}" is not a nested ` +
2252
- `selector — it must start with ":", ".", "&" or "["`,
2253
- );
2254
- }
2255
- const tab = activeTab.value;
2256
- if (!tab) {
2257
- throw new RangeError(`command "style.setSelector" needs an open document`);
2258
- }
2259
- tab.session.ui.activeSelector = value;
2260
- },
2284
+ run: (_commandCtx, args) => setSelector(args),
2261
2285
  title: "Set Style Selector",
2262
2286
  },
2263
2287
  ];
2264
2288
  }
2265
2289
 
2290
+ /** `style.setSelector`: edit a nested selector, or the base context for `selector: null`. */
2291
+ function setSelector(args: CommandArgValues): void {
2292
+ if (args.selector === null) {
2293
+ const tab = activeTab.value;
2294
+ if (tab) {
2295
+ tab.session.ui.activeSelector = null;
2296
+ }
2297
+ return;
2298
+ }
2299
+ const value = stringArg("style.setSelector", args, "selector");
2300
+ if (!isNestedSelector(value)) {
2301
+ throw new RangeError(
2302
+ `command "style.setSelector" argument "selector": "${value}" is not a nested ` +
2303
+ `selector — it must start with ":", ".", "&" or "["`,
2304
+ );
2305
+ }
2306
+ const tab = activeTab.value;
2307
+ if (!tab) {
2308
+ throw new RangeError(`command "style.setSelector" needs an open document`);
2309
+ }
2310
+ tab.session.ui.activeSelector = value;
2311
+ }
2312
+
2266
2313
  /** The `selector` property's schema: a nested selector, or `null` for the base context. */
2267
- function pathlessSelectorProperty(): object {
2314
+ function pathlessSelectorProperty(): PropertySchema {
2268
2315
  return {
2269
2316
  description:
2270
2317
  'A nested selector such as ":hover", ".child" or "[open]". null edits the base context.',