@jxsuite/studio 6.1.1 → 6.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +97 -97
  140. package/package.json +6 -6
  141. package/src/about/about-modal.ts +4 -3
  142. package/src/account/action-flow.ts +45 -38
  143. package/src/account-status.ts +7 -2
  144. package/src/browse/library-layouts.ts +8 -5
  145. package/src/browse/library-model.ts +18 -6
  146. package/src/browse/library-pane.ts +37 -21
  147. package/src/browse/library-preview.ts +14 -9
  148. package/src/browse/library-source.ts +1 -1
  149. package/src/canvas/asset-refs.ts +24 -9
  150. package/src/canvas/asset-resolve.ts +19 -23
  151. package/src/canvas/canvas-helpers.ts +7 -6
  152. package/src/canvas/canvas-live-render.ts +44 -53
  153. package/src/canvas/canvas-patcher.ts +30 -30
  154. package/src/canvas/canvas-perf.ts +11 -5
  155. package/src/canvas/canvas-render.ts +62 -41
  156. package/src/canvas/canvas-surface.ts +5 -3
  157. package/src/canvas/canvas-utils.ts +90 -49
  158. package/src/canvas/dialog-path.ts +9 -4
  159. package/src/canvas/dialog-state.ts +1 -2
  160. package/src/canvas/diff-marks.ts +9 -16
  161. package/src/canvas/diff-toolbar.ts +8 -7
  162. package/src/canvas/edit-width-drag.ts +4 -1
  163. package/src/canvas/edit-width.ts +1 -3
  164. package/src/canvas/iframe-channel.ts +27 -13
  165. package/src/canvas/iframe-drop.ts +13 -12
  166. package/src/canvas/iframe-editable-root.ts +29 -16
  167. package/src/canvas/iframe-entry.ts +80 -63
  168. package/src/canvas/iframe-eval.ts +73 -49
  169. package/src/canvas/iframe-host.ts +135 -96
  170. package/src/canvas/iframe-inline-edit.ts +49 -30
  171. package/src/canvas/iframe-insert.ts +5 -4
  172. package/src/canvas/iframe-interaction.ts +30 -25
  173. package/src/canvas/iframe-overlay.ts +1 -1
  174. package/src/canvas/iframe-patch.ts +18 -15
  175. package/src/canvas/iframe-position.ts +12 -6
  176. package/src/canvas/iframe-protocol.ts +12 -16
  177. package/src/canvas/iframe-render.ts +36 -34
  178. package/src/canvas/iframe-slash.ts +24 -11
  179. package/src/canvas/iframe-subtree.ts +6 -2
  180. package/src/canvas/path-mapping.ts +19 -12
  181. package/src/canvas/popover-path.ts +7 -3
  182. package/src/canvas/popover-state.ts +1 -2
  183. package/src/canvas/serialize-scope.ts +13 -5
  184. package/src/canvas/stage-scrollbar.ts +2 -1
  185. package/src/canvas/surface-registry.ts +21 -3
  186. package/src/collab/collab-commands.ts +7 -2
  187. package/src/collab/collab-session.ts +84 -45
  188. package/src/collab/collab-state.ts +4 -3
  189. package/src/collab/monaco-binding.ts +16 -13
  190. package/src/collab/monaco-cursors.ts +5 -2
  191. package/src/commands/budget.ts +3 -3
  192. package/src/commands/command-args.ts +103 -71
  193. package/src/commands/context.ts +22 -20
  194. package/src/commands/keymap.ts +47 -43
  195. package/src/commands/levels.ts +3 -3
  196. package/src/commands/live-context.ts +7 -7
  197. package/src/commands/reference.ts +2 -1
  198. package/src/commands/registry.ts +12 -10
  199. package/src/commands/run-reported.ts +15 -10
  200. package/src/component-props.ts +46 -30
  201. package/src/content/collection-match.ts +5 -4
  202. package/src/content/draft-state.ts +4 -3
  203. package/src/content/entry-commands.ts +3 -2
  204. package/src/content/entry-editor.ts +29 -17
  205. package/src/content/entry-fields.ts +12 -7
  206. package/src/content/entry-model.ts +21 -12
  207. package/src/editor/canvas-context-menu.ts +1 -2
  208. package/src/editor/canvas-slash-bridge.ts +3 -6
  209. package/src/editor/content-slice.ts +16 -14
  210. package/src/editor/context-menu.ts +35 -22
  211. package/src/editor/convert-targets.ts +30 -35
  212. package/src/editor/convert-to-component.ts +11 -5
  213. package/src/editor/convert-to-repeater.ts +34 -22
  214. package/src/editor/editable-tags.ts +17 -2
  215. package/src/editor/file-drop-action.ts +21 -22
  216. package/src/editor/inline-edit-apply.ts +35 -17
  217. package/src/editor/inline-edit.ts +66 -50
  218. package/src/editor/inline-format.ts +59 -56
  219. package/src/editor/inline-link.ts +40 -15
  220. package/src/editor/insert-zone-action.ts +1 -1
  221. package/src/editor/merge-tags.ts +58 -19
  222. package/src/editor/repeater-scope.ts +39 -28
  223. package/src/editor/shortcuts.ts +32 -20
  224. package/src/editor/slash-menu.ts +1 -6
  225. package/src/files/asset-versions.ts +4 -4
  226. package/src/files/components.ts +15 -10
  227. package/src/files/elements.ts +5 -6
  228. package/src/files/file-ops.ts +77 -36
  229. package/src/files/files.ts +90 -95
  230. package/src/files/media-meta.ts +2 -1
  231. package/src/files/media-paths.ts +3 -0
  232. package/src/files/serialize-document.ts +2 -2
  233. package/src/format/constraints.ts +1 -1
  234. package/src/format/convert-file.ts +27 -13
  235. package/src/format/format-choices.ts +2 -1
  236. package/src/format/format-host.ts +76 -50
  237. package/src/github/github-auth-status.ts +27 -3
  238. package/src/github/github-auth.ts +19 -9
  239. package/src/github/github-publish.ts +24 -20
  240. package/src/grid/cell-editors.ts +46 -31
  241. package/src/grid/cell-popovers.ts +5 -3
  242. package/src/grid/edit-buffer.ts +10 -9
  243. package/src/grid/grid-controller.ts +20 -22
  244. package/src/grid/grid-layout.ts +21 -5
  245. package/src/grid/grid-open.ts +3 -6
  246. package/src/grid/grid-panel.ts +11 -4
  247. package/src/grid/grid-source.ts +8 -8
  248. package/src/grid/grid-view.ts +14 -17
  249. package/src/grid/redirects-grid.ts +14 -5
  250. package/src/grid/redirects.ts +16 -14
  251. package/src/grid/schema-columns.ts +25 -19
  252. package/src/grid/sources/connector-source.ts +47 -20
  253. package/src/grid/sources/content-source.ts +25 -24
  254. package/src/grid/sources/csv-file-source.ts +2 -2
  255. package/src/grid/tabulator-tables.d.ts +55 -34
  256. package/src/hosting/stage.ts +7 -7
  257. package/src/i18n/i18n-commands.ts +1 -2
  258. package/src/media/media-pane.ts +4 -1
  259. package/src/new-project/add-repo-modal.ts +20 -19
  260. package/src/new-project/import-tab.ts +10 -14
  261. package/src/new-project/location-fields.ts +2 -1
  262. package/src/new-project/new-project-modal.ts +12 -9
  263. package/src/packages/jxsuite-update.ts +4 -3
  264. package/src/packages/pull-package-sync.ts +26 -25
  265. package/src/page-params.ts +97 -68
  266. package/src/panels/activity-panel.ts +17 -9
  267. package/src/panels/ai-chat/attached-context.ts +13 -7
  268. package/src/panels/ai-chat/chat-view.ts +80 -73
  269. package/src/panels/ai-chat/composer.ts +30 -33
  270. package/src/panels/ai-chat/sessions-view.ts +1 -2
  271. package/src/panels/ai-panel.ts +23 -20
  272. package/src/panels/block-action-bar.ts +46 -35
  273. package/src/panels/bottom-dock.ts +5 -3
  274. package/src/panels/canvas-dnd-bridge.ts +31 -24
  275. package/src/panels/data-explorer.ts +62 -25
  276. package/src/panels/data-grid.ts +14 -11
  277. package/src/panels/dnd.ts +108 -118
  278. package/src/panels/editors.ts +52 -21
  279. package/src/panels/elements-panel.ts +10 -3
  280. package/src/panels/events-panel.ts +84 -69
  281. package/src/panels/formula-workspace.ts +76 -51
  282. package/src/panels/frontmatter-fields.ts +24 -19
  283. package/src/panels/frontmatter-panel.ts +44 -34
  284. package/src/panels/git-diff-open.ts +4 -4
  285. package/src/panels/git-panel.ts +49 -61
  286. package/src/panels/head-panel.ts +131 -111
  287. package/src/panels/i18n-panel.ts +10 -3
  288. package/src/panels/imports-panel.ts +23 -47
  289. package/src/panels/jump-bar.ts +48 -29
  290. package/src/panels/layers-panel.ts +97 -74
  291. package/src/panels/left-panel.ts +3 -3
  292. package/src/panels/pane-context.ts +31 -22
  293. package/src/panels/pane-grid.ts +49 -20
  294. package/src/panels/panel-registry.ts +22 -37
  295. package/src/panels/properties-panel.ts +175 -121
  296. package/src/panels/quick-search.ts +53 -31
  297. package/src/panels/right-panel.ts +3 -3
  298. package/src/panels/seo-modal.ts +13 -17
  299. package/src/panels/settings-menu.ts +15 -15
  300. package/src/panels/signals-panel.ts +153 -131
  301. package/src/panels/statement-editor.ts +230 -140
  302. package/src/panels/style-panel.ts +218 -205
  303. package/src/panels/style-utils.ts +114 -51
  304. package/src/panels/stylebook-doc.ts +57 -54
  305. package/src/panels/stylebook-layers-panel.ts +9 -9
  306. package/src/panels/stylebook-panel.ts +13 -17
  307. package/src/panels/tab-drop.ts +27 -11
  308. package/src/panels/tab-strip.ts +36 -26
  309. package/src/platform-errors.ts +57 -43
  310. package/src/platform.ts +58 -30
  311. package/src/platforms/cloud.ts +345 -175
  312. package/src/platforms/default-platform.ts +10 -4
  313. package/src/platforms/devserver.ts +129 -117
  314. package/src/platforms/read-batcher.ts +16 -8
  315. package/src/project-list.ts +2 -1
  316. package/src/publish/deploy-checklist.ts +8 -2
  317. package/src/publish/pages-service.ts +28 -13
  318. package/src/publish/publish-commands.ts +5 -4
  319. package/src/publish/publish-panel.ts +10 -6
  320. package/src/recent-projects.ts +15 -8
  321. package/src/resize-edges.ts +26 -36
  322. package/src/services/a11y-report.ts +26 -19
  323. package/src/services/agent-seed.ts +23 -11
  324. package/src/services/ai-ask.ts +9 -12
  325. package/src/services/ai-command-tools.ts +68 -62
  326. package/src/services/ai-import-tools.ts +80 -67
  327. package/src/services/ai-models.ts +17 -13
  328. package/src/services/ai-project-tools.ts +68 -32
  329. package/src/services/ai-session-store.ts +19 -10
  330. package/src/services/ai-system-prompt.ts +46 -20
  331. package/src/services/ai-tools.ts +71 -27
  332. package/src/services/ai-write-report.ts +20 -12
  333. package/src/services/ai-writes.ts +4 -4
  334. package/src/services/automation.ts +58 -31
  335. package/src/services/cem-export.ts +149 -58
  336. package/src/services/clock.ts +6 -1
  337. package/src/services/code-services.ts +37 -31
  338. package/src/services/context-manager.ts +14 -10
  339. package/src/services/context-resolver.ts +20 -8
  340. package/src/services/data-service.ts +19 -15
  341. package/src/services/directory-picker.ts +18 -12
  342. package/src/services/document-assistant.ts +39 -19
  343. package/src/services/gated-registry.ts +10 -6
  344. package/src/services/harness/chat-reducer.ts +23 -1
  345. package/src/services/import-client.ts +91 -38
  346. package/src/services/import-seed.ts +8 -2
  347. package/src/services/jx-validate.ts +28 -31
  348. package/src/services/live-preview.ts +0 -0
  349. package/src/services/live-surfaces.ts +6 -3
  350. package/src/services/model-uri.ts +10 -2
  351. package/src/services/module-preloads.ts +12 -8
  352. package/src/services/monaco-buffer.ts +43 -24
  353. package/src/services/monaco-lazy.ts +7 -8
  354. package/src/services/monaco-setup.ts +23 -16
  355. package/src/services/notify.ts +44 -17
  356. package/src/services/popover-report.ts +25 -10
  357. package/src/services/preview-eval.ts +20 -8
  358. package/src/services/profile.ts +13 -6
  359. package/src/services/project-path.ts +13 -10
  360. package/src/services/references.ts +0 -0
  361. package/src/services/render-critic.ts +8 -7
  362. package/src/services/settings/kernel.ts +13 -4
  363. package/src/services/settings/write-queue.ts +9 -9
  364. package/src/services/token-lint.ts +12 -10
  365. package/src/services/tool-executor.ts +17 -5
  366. package/src/services/tool-outcomes.ts +44 -24
  367. package/src/services/trusted-types.ts +24 -7
  368. package/src/settings/contexts-section.ts +11 -8
  369. package/src/settings/contributed-section.ts +79 -60
  370. package/src/settings/css-vars-editor.ts +37 -16
  371. package/src/settings/defs-editor.ts +38 -35
  372. package/src/settings/extension-rows.ts +16 -8
  373. package/src/settings/extension-sections.ts +23 -13
  374. package/src/settings/extensions-section.ts +4 -1
  375. package/src/settings/general-settings.ts +11 -8
  376. package/src/settings/locales-section.ts +20 -12
  377. package/src/settings/preferences-dialog.ts +9 -6
  378. package/src/settings/preferences-keymap.ts +7 -5
  379. package/src/settings/preferences-sections.ts +11 -5
  380. package/src/settings/project-sections.ts +1 -1
  381. package/src/settings/schema-field-ui.ts +9 -0
  382. package/src/settings/settings-document.ts +5 -5
  383. package/src/shell/tree.ts +6 -5
  384. package/src/shell.ts +104 -81
  385. package/src/site-context.ts +37 -22
  386. package/src/state.ts +41 -49
  387. package/src/store.ts +54 -34
  388. package/src/studio.ts +25 -75
  389. package/src/style/live-preview.ts +1 -1
  390. package/src/style/project-styles.ts +6 -7
  391. package/src/style/token-ref.ts +5 -4
  392. package/src/surfaces/about.ts +18 -19
  393. package/src/surfaces/add-repo.ts +17 -19
  394. package/src/surfaces/ai-chat.ts +31 -36
  395. package/src/surfaces/ai-credentials-form.ts +6 -16
  396. package/src/surfaces/ai-managed-connect.ts +3 -4
  397. package/src/surfaces/ai-model-picker.ts +3 -5
  398. package/src/surfaces/block-action-bar.ts +22 -11
  399. package/src/surfaces/boot-failure.ts +4 -5
  400. package/src/surfaces/bottom-dock.ts +9 -18
  401. package/src/surfaces/canvas-stage.ts +12 -11
  402. package/src/surfaces/cf-account-picker.ts +17 -18
  403. package/src/surfaces/commandbar.ts +14 -9
  404. package/src/surfaces/convert-repeater.ts +17 -19
  405. package/src/surfaces/data-actions.ts +9 -7
  406. package/src/surfaces/dialog.ts +26 -28
  407. package/src/surfaces/diff-toolbar.ts +9 -7
  408. package/src/surfaces/doc-header.ts +10 -19
  409. package/src/surfaces/empty-state.ts +7 -10
  410. package/src/surfaces/entry-editor.ts +14 -11
  411. package/src/surfaces/expression-editor.ts +11 -25
  412. package/src/surfaces/files-panel.ts +27 -14
  413. package/src/surfaces/formula-palette.ts +4 -5
  414. package/src/surfaces/git-panel.ts +7 -15
  415. package/src/surfaces/github-auth.ts +16 -20
  416. package/src/surfaces/github-publish.ts +17 -22
  417. package/src/surfaces/grid-cell.ts +30 -31
  418. package/src/surfaces/grid-open.ts +10 -14
  419. package/src/surfaces/grid-panel.ts +13 -9
  420. package/src/surfaces/grid-replace.ts +13 -13
  421. package/src/surfaces/grid-views.ts +15 -18
  422. package/src/surfaces/inspector-dock.ts +13 -12
  423. package/src/surfaces/jump-bar.ts +5 -6
  424. package/src/surfaces/jxsuite-update.ts +16 -22
  425. package/src/surfaces/library-pane.ts +19 -20
  426. package/src/surfaces/logic-panel.ts +17 -30
  427. package/src/surfaces/logic-workspace.ts +13 -15
  428. package/src/surfaces/media-browser.ts +11 -10
  429. package/src/surfaces/media-field.ts +4 -5
  430. package/src/surfaces/media-pane.ts +8 -7
  431. package/src/surfaces/menu.ts +29 -23
  432. package/src/surfaces/navigator-dock.ts +11 -12
  433. package/src/surfaces/new-project.ts +27 -26
  434. package/src/surfaces/pane-context.ts +20 -25
  435. package/src/surfaces/pane-grid.ts +15 -10
  436. package/src/surfaces/panel-activity.ts +5 -6
  437. package/src/surfaces/panel-data.ts +3 -4
  438. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  439. package/src/surfaces/panel-elements.ts +5 -7
  440. package/src/surfaces/panel-i18n.ts +5 -7
  441. package/src/surfaces/panel-imports.ts +6 -13
  442. package/src/surfaces/panel-outline.ts +25 -19
  443. package/src/surfaces/panel-page.ts +11 -18
  444. package/src/surfaces/panel-problems.ts +5 -7
  445. package/src/surfaces/panel-signals.ts +20 -34
  446. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  447. package/src/surfaces/preferences.ts +21 -11
  448. package/src/surfaces/progress-modal.ts +15 -9
  449. package/src/surfaces/properties-panel.json +1 -1
  450. package/src/surfaces/properties-panel.ts +20 -42
  451. package/src/surfaces/publish.ts +18 -18
  452. package/src/surfaces/push-plan.ts +7 -8
  453. package/src/surfaces/rail.ts +13 -13
  454. package/src/surfaces/reference-field.ts +11 -15
  455. package/src/surfaces/schema-builder.ts +16 -22
  456. package/src/surfaces/schema-form.ts +15 -25
  457. package/src/surfaces/secret-field.ts +9 -6
  458. package/src/surfaces/seo.ts +21 -15
  459. package/src/surfaces/settings-contexts.ts +9 -7
  460. package/src/surfaces/settings-contributed.ts +14 -10
  461. package/src/surfaces/settings-css-vars.ts +5 -12
  462. package/src/surfaces/settings-defs.json +2 -2
  463. package/src/surfaces/settings-defs.ts +17 -21
  464. package/src/surfaces/settings-deploy.ts +8 -15
  465. package/src/surfaces/settings-extensions.ts +5 -6
  466. package/src/surfaces/settings-head.ts +33 -39
  467. package/src/surfaces/settings-locales.ts +8 -20
  468. package/src/surfaces/settings-overview.ts +5 -6
  469. package/src/surfaces/settings-packages.ts +8 -7
  470. package/src/surfaces/settings-pane.ts +9 -18
  471. package/src/surfaces/settings-rawjson.ts +5 -6
  472. package/src/surfaces/shell.ts +1 -2
  473. package/src/surfaces/slash-menu.ts +19 -9
  474. package/src/surfaces/statements.ts +13 -18
  475. package/src/surfaces/statusbar.ts +17 -14
  476. package/src/surfaces/style-panel.ts +18 -31
  477. package/src/surfaces/stylebook-chrome.ts +3 -5
  478. package/src/surfaces/tab-strip.ts +14 -13
  479. package/src/surfaces/target-line.ts +6 -7
  480. package/src/surfaces/welcome.ts +5 -7
  481. package/src/tabs/patch-ops.ts +4 -3
  482. package/src/tabs/project-config.ts +32 -21
  483. package/src/tabs/selection.ts +36 -8
  484. package/src/tabs/tab.ts +52 -41
  485. package/src/tabs/transact.ts +98 -53
  486. package/src/types.ts +32 -17
  487. package/src/ui/ai-credentials-form.ts +10 -13
  488. package/src/ui/ai-model-picker.ts +3 -3
  489. package/src/ui/cf-account-picker.ts +7 -9
  490. package/src/ui/color-selector.ts +9 -5
  491. package/src/ui/dynamic-slot.ts +7 -8
  492. package/src/ui/expression-editor.ts +112 -105
  493. package/src/ui/form-controls.ts +57 -48
  494. package/src/ui/formula-catalog.ts +239 -230
  495. package/src/ui/formula-chips.ts +33 -18
  496. package/src/ui/layers.ts +44 -31
  497. package/src/ui/media-picker.ts +18 -9
  498. package/src/ui/popover-surface.ts +20 -12
  499. package/src/ui/progress-modal.ts +13 -8
  500. package/src/ui/regions.ts +7 -6
  501. package/src/ui/schema-form.ts +113 -70
  502. package/src/ui/surface.ts +71 -8
  503. package/src/ui/timing.ts +9 -0
  504. package/src/ui/value-source.ts +44 -31
  505. package/src/ui/virtual-window.ts +3 -2
  506. package/src/utils/base64.ts +3 -1
  507. package/src/utils/edit-display.ts +73 -73
  508. package/src/utils/element-selectors.ts +3 -2
  509. package/src/utils/google-fonts.ts +15 -14
  510. package/src/utils/inherited-style.ts +18 -20
  511. package/src/utils/link-target.ts +1 -1
  512. package/src/utils/preview-format.ts +25 -3
  513. package/src/utils/strip-events.ts +49 -22
  514. package/src/utils/studio-utils.ts +29 -14
  515. package/src/view.ts +2 -3
  516. package/src/workspace/pane-derive.ts +10 -12
  517. package/src/workspace/session.ts +53 -43
  518. package/src/workspace/workspace.ts +40 -36
  519. package/dist/chunks/adapter-f93pafd7.js +0 -4
  520. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  521. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  522. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  523. package/dist/chunks/color-field-embq5ctg.js +0 -4
  524. package/dist/chunks/color-fpezvnkt.js +0 -4
  525. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  526. package/dist/chunks/combobox-773hdzyj.js +0 -4
  527. package/dist/chunks/components-ax2f1fnn.js +0 -4
  528. package/dist/chunks/content-source-108aqtk1.js +0 -4
  529. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  530. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  531. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  532. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  533. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  534. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  535. package/dist/chunks/files-44vp8a2s.js +0 -4
  536. package/dist/chunks/format-host-7q1petb9.js +0 -4
  537. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  538. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  539. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  540. package/dist/chunks/icons-p44xhjf0.js +0 -4
  541. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  542. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  543. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  544. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  545. package/dist/chunks/index-wkyfjeqz.js +0 -4
  546. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  547. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  548. package/dist/chunks/layers-xd92fg8d.js +0 -4
  549. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  550. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  551. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  552. package/dist/chunks/menu-37d07z9m.js +0 -4
  553. package/dist/chunks/menu-5c55ea3d.js +0 -4
  554. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  555. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  556. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  557. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  558. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  559. package/dist/chunks/parse-897fvqah.js +0 -4
  560. package/dist/chunks/platform-v1qctbe6.js +0 -4
  561. package/dist/chunks/popover-8htra4er.js +0 -4
  562. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  563. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  564. package/dist/chunks/references-gmqp82fs.js +0 -4
  565. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  566. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  567. package/dist/chunks/select-n3v7gwas.js +0 -4
  568. package/dist/chunks/split-pff8f3ze.js +0 -4
  569. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  570. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  571. package/dist/chunks/studio-1b04pd0j.js +0 -64
  572. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  573. package/dist/chunks/studio-4tanh828.js +0 -5
  574. package/dist/chunks/studio-55h4mstj.js +0 -4
  575. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  576. package/dist/chunks/studio-60dqgb0c.js +0 -5
  577. package/dist/chunks/studio-61dp09qg.js +0 -9
  578. package/dist/chunks/studio-63epcrj2.js +0 -5
  579. package/dist/chunks/studio-74k29dy9.js +0 -5
  580. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  581. package/dist/chunks/studio-7zx31knw.js +0 -9
  582. package/dist/chunks/studio-8bxk97km.js +0 -5
  583. package/dist/chunks/studio-933e30n4.js +0 -5
  584. package/dist/chunks/studio-98wnwhbg.js +0 -5
  585. package/dist/chunks/studio-9mccjwjh.js +0 -14
  586. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  587. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  588. package/dist/chunks/studio-e81q1vb9.js +0 -5
  589. package/dist/chunks/studio-epgrmqqm.js +0 -5
  590. package/dist/chunks/studio-ery42sqr.js +0 -4
  591. package/dist/chunks/studio-g1shz58g.js +0 -5
  592. package/dist/chunks/studio-gf0fz03c.js +0 -5
  593. package/dist/chunks/studio-gjtpe62q.js +0 -6
  594. package/dist/chunks/studio-gkskhg7m.js +0 -5
  595. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  596. package/dist/chunks/studio-j03zga3y.js +0 -9
  597. package/dist/chunks/studio-jhpxeckz.js +0 -5
  598. package/dist/chunks/studio-k01r7ykp.js +0 -5
  599. package/dist/chunks/studio-kk7h30ne.js +0 -7
  600. package/dist/chunks/studio-kt1zqney.js +0 -5
  601. package/dist/chunks/studio-m3cwhvye.js +0 -5
  602. package/dist/chunks/studio-mcayt6hz.js +0 -5
  603. package/dist/chunks/studio-myjcghv3.js +0 -5
  604. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  605. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  606. package/dist/chunks/studio-nj5a01jy.js +0 -928
  607. package/dist/chunks/studio-pcgz8heb.js +0 -5
  608. package/dist/chunks/studio-qcsq0t15.js +0 -5
  609. package/dist/chunks/studio-qkstvve9.js +0 -5
  610. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  611. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  612. package/dist/chunks/studio-s8dmmz66.js +0 -5
  613. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  614. package/dist/chunks/studio-szsjbj0g.js +0 -5
  615. package/dist/chunks/studio-t1xzawhr.js +0 -16
  616. package/dist/chunks/studio-t6b6qe31.js +0 -5
  617. package/dist/chunks/studio-tdcprbqb.js +0 -5
  618. package/dist/chunks/studio-vyc0b4he.js +0 -10
  619. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  620. package/dist/chunks/studio-w3hskzqk.js +0 -5
  621. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  622. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  623. package/dist/chunks/studio-y6n42tgs.js +0 -5
  624. package/dist/chunks/studio-yb560vxr.js +0 -5
  625. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  626. package/dist/chunks/studio-yw05w8f0.js +0 -7
  627. package/dist/chunks/studio-z16sgavc.js +0 -5
  628. package/dist/chunks/studio-zyqn40w4.js +0 -5
  629. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  630. package/dist/chunks/tabs-jwthg40w.js +0 -4
  631. package/dist/chunks/textfield-spy3hc77.js +0 -4
  632. package/dist/chunks/toast-4d35zd64.js +0 -4
  633. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  634. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  635. package/dist/chunks/tree-h19v1jfz.js +0 -4
  636. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  637. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
@@ -1,16 +1,88 @@
1
1
  /** Style utilities — pure CSS helper functions used by the style panel. */
2
2
 
3
- import type { JxMutableNode } from "@jxsuite/schema/types";
3
+ import { isNumber, isString } from "@jxsuite/schema/guards";
4
+ import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
4
5
 
5
6
  import { activeTab } from "../workspace/workspace";
6
7
  import { getEffectiveStyle } from "../site-context";
7
8
  import cssMeta from "../../data/css-meta.json";
8
9
 
10
+ /** One `$show` condition: the row is offered while `prop` holds one of `values`, or any value. */
11
+ export interface CssShowCondition {
12
+ prop: string;
13
+ values: string[];
14
+ }
15
+
16
+ /** One Modern Font Stacks preset a `fontFamily` entry offers. */
17
+ export interface CssFontPreset {
18
+ title: string;
19
+ value: string;
20
+ }
21
+
22
+ /** Every kind of value a css-meta entry holds under any of its keys. */
23
+ type CssMetaValue =
24
+ | string
25
+ | number
26
+ | boolean
27
+ | string[]
28
+ | CssShowCondition[]
29
+ | CssFontPreset[]
30
+ | Record<string, string>;
31
+
32
+ /**
33
+ * What `css-meta.json` says about one CSS property: which section files it, where in that section,
34
+ * and which control edits it. Every entry in the file carries `$order`; the rest is per property.
35
+ *
36
+ * The index signature is what keeps an entry assignable to the open records `inferInputType()` and
37
+ * `propLabel()` read it through; it admits only the value kinds the file actually holds.
38
+ */
39
+ export interface CssMetaEntry {
40
+ $order: number;
41
+ $section?: string;
42
+ $label?: string;
43
+ $input?: string;
44
+ $buttonValues?: string[];
45
+ $icons?: Record<string, string>;
46
+ $keywords?: string[];
47
+ $longhands?: string[];
48
+ /** `true` on a shorthand row; the shorthand's own name on each of its longhands. */
49
+ $shorthand?: string | boolean;
50
+ $shorthandType?: string;
51
+ $show?: CssShowCondition[];
52
+ $span?: number;
53
+ $units?: string[];
54
+ enum?: string[];
55
+ examples?: string[];
56
+ presets?: CssFontPreset[];
57
+ format?: string;
58
+ type?: string;
59
+ minimum?: number;
60
+ maximum?: number;
61
+ [key: string]: CssMetaValue | undefined;
62
+ }
63
+
64
+ /** A shorthand's longhand, with its own css-meta entry. */
65
+ export interface CssLonghand {
66
+ name: string;
67
+ entry: CssMetaEntry;
68
+ }
69
+
70
+ /**
71
+ * Css-meta's property table, by property name. The JSON module's inferred type is checked against
72
+ * {@link CssMetaEntry} here, once, so a key the file stops carrying is a type error at this line.
73
+ */
74
+ export const cssDefs: Readonly<Record<string, CssMetaEntry>> = cssMeta.$defs;
75
+
9
76
  let cssInitialMap = new Map<string, string>();
10
77
 
11
78
  /** Initialise cssInitialMap from webdata — call once during bootstrap. */
12
79
  export function initCssData(webdata: { cssProps: string[][] }) {
13
- cssInitialMap = new Map(webdata.cssProps as [string, string][]);
80
+ cssInitialMap = new Map<string, string>();
81
+ for (const [name, initial] of webdata.cssProps) {
82
+ if (name !== undefined && initial !== undefined) {
83
+ cssInitialMap.set(name, initial);
84
+ }
85
+ }
14
86
  }
15
87
 
16
88
  /** Get the CSS initial-value map (populated by initCssData). */
@@ -18,31 +90,30 @@ export function getCssInitialMap() {
18
90
  return cssInitialMap;
19
91
  }
20
92
 
93
+ /**
94
+ * A declaration's value rather than a nested block (`:hover`, `@--md`) or a block list.
95
+ *
96
+ * Exactly the `typeof value !== "object"` test the Style tab has always made, so a `null` a JSON
97
+ * document might hold still counts as a block, never as a value.
98
+ */
99
+ export function isDeclarationValue(value: JxStyle[string]): value is string | number | undefined {
100
+ return typeof value !== "object";
101
+ }
102
+
21
103
  // ─── Condition helpers ──────────────────────────────────────────────────────
22
104
 
23
- /** @param {{ prop: string; values: string[] }} cond @param {Record<string, unknown>} styles */
24
- export function conditionPasses(
25
- cond: { prop: string; values: string[] },
26
- styles: Record<string, unknown>,
27
- ) {
28
- const val = (styles[cond.prop] ?? "") as string;
105
+ /** Whether one `$show` condition holds against the style being edited. */
106
+ export function conditionPasses(cond: CssShowCondition, styles: JxStyle) {
107
+ const val = styles[cond.prop] ?? "";
29
108
  if (cond.values.length === 0) {
30
109
  return val !== "" && val !== "initial";
31
110
  }
32
- return cond.values.includes(val);
111
+ return isString(val) && cond.values.includes(val);
33
112
  }
34
113
 
35
- /**
36
- * @param {{ $show?: { prop: string; values: string[] }[] }} entry @param {Record<string, unknown>}
37
- * styles
38
- */
39
- export function allConditionsPass(
40
- entry: { $show?: { prop: string; values: string[] }[] },
41
- styles: Record<string, unknown>,
42
- ) {
43
- return (entry.$show ?? []).every((/** @type {{ prop: string; values: string[] }} */ c) =>
44
- conditionPasses(c, styles),
45
- );
114
+ /** Whether every `$show` condition of an entry holds; an entry with none always passes. */
115
+ export function allConditionsPass(entry: Pick<CssMetaEntry, "$show">, styles: JxStyle) {
116
+ return (entry.$show ?? []).every((c) => conditionPasses(c, styles));
46
117
  }
47
118
 
48
119
  // ─── Auto-open sections ─────────────────────────────────────────────────────
@@ -64,11 +135,10 @@ export function autoOpenSections(node: JxMutableNode, currentSections: Record<st
64
135
  const style = node.style || {};
65
136
  const result = { ...currentSections };
66
137
  for (const prop of Object.keys(style)) {
67
- if (typeof style[prop] === "object") {
138
+ if (!isDeclarationValue(style[prop])) {
68
139
  continue;
69
140
  }
70
- const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[prop];
71
- const section = (entry?.$section as string) ?? "other";
141
+ const section = cssDefs[prop]?.$section ?? "other";
72
142
  if (result[section] === undefined) {
73
143
  result[section] = true;
74
144
  }
@@ -78,31 +148,21 @@ export function autoOpenSections(node: JxMutableNode, currentSections: Record<st
78
148
 
79
149
  // ─── Shorthand expand/compress ──────────────────────────────────────────────
80
150
 
81
- /** Get longhands for a shorthand property from css-meta */
82
- export function getLonghands(shorthandProp: string) {
83
- const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[shorthandProp];
84
- if (entry?.$longhands) {
85
- return (entry.$longhands as string[])
86
- .map((name: string) => ({
87
- entry: (cssMeta.$defs as Record<string, Record<string, unknown>>)[name] || {
88
- $order: 0,
89
- },
90
- name,
91
- }))
92
- .toSorted(
93
- (
94
- /** @type {{ entry: Record<string, unknown> }} */ a,
95
- /** @type {{ entry: Record<string, unknown> }} */ b,
96
- ) => (a.entry.$order as number) - (b.entry.$order as number),
97
- );
151
+ /** Get longhands for a shorthand property from css-meta, in their `$order`. */
152
+ export function getLonghands(shorthandProp: string): CssLonghand[] {
153
+ const listed = cssDefs[shorthandProp]?.$longhands;
154
+ if (listed) {
155
+ return listed
156
+ .map((name) => ({ entry: cssDefs[name] || { $order: 0 }, name }))
157
+ .toSorted((a, b) => a.entry.$order - b.entry.$order);
98
158
  }
99
- const result = [];
100
- for (const [name, e] of Object.entries(cssMeta.$defs) as [string, Record<string, unknown>][]) {
159
+ const result: CssLonghand[] = [];
160
+ for (const [name, e] of Object.entries(cssDefs)) {
101
161
  if (e.$shorthand === shorthandProp) {
102
162
  result.push({ entry: e, name });
103
163
  }
104
164
  }
105
- result.sort((a, b) => (a.entry.$order as number) - (b.entry.$order as number));
165
+ result.sort((a, b) => a.entry.$order - b.entry.$order);
106
166
  return result;
107
167
  }
108
168
 
@@ -232,7 +292,7 @@ export function getFontVars() {
232
292
  const style = getEffectiveStyle(activeTab.value?.doc.document?.style);
233
293
  const vars = [];
234
294
  for (const [k, v] of Object.entries(style)) {
235
- if (k.startsWith("--font") && (typeof v === "string" || typeof v === "number")) {
295
+ if (k.startsWith("--font") && (isString(v) || isNumber(v))) {
236
296
  vars.push({ name: k, value: String(v) });
237
297
  }
238
298
  }
@@ -247,12 +307,15 @@ export function getFontVars() {
247
307
  * `face`, which is the channel every one of these rows ALSO carries, so a weight is shown in the
248
308
  * element's own typeface rather than in the panel's.
249
309
  */
250
- export const TYPO_PREVIEW_CHANNELS: Readonly<Record<string, string>> = {
251
- fontStyle: "slant",
252
- fontVariant: "variant",
253
- fontWeight: "weight",
254
- textDecoration: "decoration",
255
- textTransform: "transform",
256
- };
310
+ export const TYPO_PREVIEW_CHANNELS = new Map<string, TypoPreviewChannel>([
311
+ ["fontStyle", "slant"],
312
+ ["fontVariant", "variant"],
313
+ ["fontWeight", "weight"],
314
+ ["textDecoration", "decoration"],
315
+ ["textTransform", "transform"],
316
+ ]);
317
+
318
+ /** A `jx-option` drawing channel a typography row previews its value through (ui.md §5.3). */
319
+ export type TypoPreviewChannel = "decoration" | "slant" | "transform" | "variant" | "weight";
257
320
 
258
321
  export { default as cssMeta } from "../../data/css-meta.json";
@@ -21,6 +21,7 @@ import { isKeyframesAtRule } from "@jxsuite/runtime/css";
21
21
  import type { StylebookEntry } from "./stylebook-panel";
22
22
  import type { ComponentEntry } from "../files/components";
23
23
  import type { JxPath } from "../state";
24
+ import { isNonNullObject } from "@jxsuite/schema/guards";
24
25
  import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
25
26
 
26
27
  export interface StylebookDocResult {
@@ -44,8 +45,9 @@ function isTagPath(key: string): boolean {
44
45
  );
45
46
  }
46
47
 
47
- function isPlainObject(v: unknown): v is Record<string, unknown> {
48
- return v !== null && typeof v === "object" && !Array.isArray(v);
48
+ /** A nested style block (a rule or an at-rule body), as opposed to a scalar or a block list. */
49
+ function isStyleBlock(value: JxStyle[string]): value is JxStyle {
50
+ return isNonNullObject(value) && !Array.isArray(value);
49
51
  }
50
52
 
51
53
  /** The specimen-scoping selector prefix (see the module doc). */
@@ -58,12 +60,11 @@ const SPECIMEN_SCOPE = "& .element-card-preview";
58
60
  * `styleUpdate` fast path so an edit round-trips through the exact same transform.
59
61
  */
60
62
  export function transposeStylebookStyle(effectiveStyle: JxStyle): JxStyle {
61
- const style = effectiveStyle as Record<string, unknown>;
62
- const out: Record<string, unknown> = {};
63
+ const out: JxStyle = {};
63
64
 
64
65
  /** Drop the base-width marker, which is not a query and would resolve to `@media --`. */
65
- const withoutBaseWidth = (rule: Record<string, unknown>): Record<string, unknown> => {
66
- const cleaned: Record<string, unknown> = {};
66
+ const withoutBaseWidth = (rule: JxStyle): JxStyle => {
67
+ const cleaned: JxStyle = {};
67
68
  for (const [k, v] of Object.entries(rule)) {
68
69
  if (k !== "@--") {
69
70
  cleaned[k] = v;
@@ -72,8 +73,8 @@ export function transposeStylebookStyle(effectiveStyle: JxStyle): JxStyle {
72
73
  return cleaned;
73
74
  };
74
75
 
75
- for (const [k, v] of Object.entries(style)) {
76
- if (!isPlainObject(v)) {
76
+ for (const [k, v] of Object.entries(effectiveStyle)) {
77
+ if (!isStyleBlock(v)) {
77
78
  out[k] = v; // Flat scalars + -- custom props.
78
79
  continue;
79
80
  }
@@ -89,9 +90,9 @@ export function transposeStylebookStyle(effectiveStyle: JxStyle): JxStyle {
89
90
  }
90
91
  if (k.startsWith("@")) {
91
92
  // Media block: re-key tag rules inside; non-tag keys (scalars/pseudo) apply to the root.
92
- const bucket: Record<string, unknown> = {};
93
+ const bucket: JxStyle = {};
93
94
  for (const [mk, mv] of Object.entries(v)) {
94
- if (isPlainObject(mv) && isTagPath(mk)) {
95
+ if (isStyleBlock(mv) && isTagPath(mk)) {
95
96
  bucket[`${SPECIMEN_SCOPE} ${mk}`] = withoutBaseWidth(mv);
96
97
  } else {
97
98
  bucket[mk] = mv;
@@ -107,34 +108,30 @@ export function transposeStylebookStyle(effectiveStyle: JxStyle): JxStyle {
107
108
  out[k] = v;
108
109
  }
109
110
 
110
- return out as JxStyle;
111
+ return out;
111
112
  }
112
113
 
113
114
  /** Resolve a nested tag path ("table th") in a style object; null when absent. */
114
- function resolveNestedStyle(
115
- style: Record<string, unknown>,
116
- tagPath: string,
117
- ): Record<string, unknown> | null {
115
+ function resolveNestedStyle(style: JxStyle, tagPath: string): JxStyle | null {
118
116
  const parts = tagPath.split(" ");
119
- let obj: unknown = style;
117
+ let obj: JxStyle[string] = style;
120
118
  for (const part of parts) {
121
- if (!isPlainObject(obj)) {
119
+ if (!isStyleBlock(obj)) {
122
120
  return null;
123
121
  }
124
122
  obj = obj[part];
125
123
  }
126
- return isPlainObject(obj) ? obj : null;
124
+ return isStyleBlock(obj) ? obj : null;
127
125
  }
128
126
 
129
127
  /** Whether the effective style customizes `tagPath` (directly or under any `@media` block). */
130
128
  export function hasTagStyle(rootStyle: JxStyle, tagPath: string): boolean {
131
- const style = rootStyle as Record<string, unknown>;
132
- const direct = resolveNestedStyle(style, tagPath);
129
+ const direct = resolveNestedStyle(rootStyle, tagPath);
133
130
  if (direct && Object.keys(direct).length > 0) {
134
131
  return true;
135
132
  }
136
- for (const [key, val] of Object.entries(style)) {
137
- if (!key.startsWith("@") || !isPlainObject(val)) {
133
+ for (const [key, val] of Object.entries(rootStyle)) {
134
+ if (!key.startsWith("@") || !isStyleBlock(val)) {
138
135
  continue;
139
136
  }
140
137
  const nested = resolveNestedStyle(val, tagPath);
@@ -179,16 +176,21 @@ export function buildStylebookDoc(opts: BuildStylebookDocOpts): StylebookDocResu
179
176
  };
180
177
 
181
178
  const specimenNode = (entry: StylebookEntry): JxMutableNode => {
182
- const attributes: Record<string, string> = { ...entry.attributes };
179
+ const attributes = { ...entry.attributes };
183
180
  if (entry.style) {
184
181
  attributes.style = entry.style; // Inline CSS text — legacy `el.style.cssText` parity.
185
182
  }
186
- return {
187
- tagName: entry.tag,
188
- ...(entry.text ? { textContent: entry.text } : {}),
189
- ...(Object.keys(attributes).length > 0 ? { attributes } : {}),
190
- ...(entry.children ? { children: entry.children.map(specimenNode) } : {}),
191
- } as JxMutableNode;
183
+ const node: JxMutableNode = { tagName: entry.tag };
184
+ if (entry.text) {
185
+ node.textContent = entry.text;
186
+ }
187
+ if (Object.keys(attributes).length > 0) {
188
+ node.attributes = attributes;
189
+ }
190
+ if (entry.children) {
191
+ node.children = entry.children.map(specimenNode);
192
+ }
193
+ return node;
192
194
  };
193
195
 
194
196
  /** A card wrapping one specimen; registers card/preview/specimen paths under `tag`. */
@@ -217,19 +219,18 @@ export function buildStylebookDoc(opts: BuildStylebookDocOpts): StylebookDocResu
217
219
  { attributes: { class: "element-card-label" }, tagName: "div", textContent: label },
218
220
  ],
219
221
  tagName: "div",
220
- } as JxMutableNode;
222
+ };
221
223
  };
222
224
 
223
225
  const sections: JxMutableNode[] = [];
224
- const sectionNode = (label: string, cards: JxMutableNode[]): JxMutableNode =>
225
- ({
226
- attributes: { class: "sb-section" },
227
- children: [
228
- { attributes: { class: "sb-label" }, tagName: "div", textContent: label },
229
- { attributes: { class: "sb-body" }, children: cards, tagName: "div" },
230
- ],
231
- tagName: "div",
232
- }) as JxMutableNode;
226
+ const sectionNode = (label: string, cards: JxMutableNode[]): JxMutableNode => ({
227
+ attributes: { class: "sb-section" },
228
+ children: [
229
+ { attributes: { class: "sb-label" }, tagName: "div", textContent: label },
230
+ { attributes: { class: "sb-body" }, children: cards, tagName: "div" },
231
+ ],
232
+ tagName: "div",
233
+ });
233
234
 
234
235
  // Paths below mirror the assembled tree: root.children[si] = section; section.children[1] =
235
236
  // Sb-body; body.children[ci] = card. Sections are appended only when non-empty, so indices are
@@ -293,18 +294,18 @@ export function buildStylebookDoc(opts: BuildStylebookDocOpts): StylebookDocResu
293
294
  attributes[p.name] = String(p.default).replaceAll(/^'|'$/g, "");
294
295
  }
295
296
  }
296
- const specimen = {
297
- tagName: comp.tagName,
298
- ...(Object.keys(attributes).length > 0 ? { attributes } : {}),
299
- } as JxMutableNode;
297
+ const specimen: JxMutableNode = { tagName: comp.tagName };
298
+ if (Object.keys(attributes).length > 0) {
299
+ specimen.attributes = attributes;
300
+ }
300
301
  return cardNode(comp.tagName, `<${comp.tagName}>`, specimen, cardPath, null);
301
302
  }
302
303
  // Npm/format-class components can't be $ref-registered — placeholder box (legacy parity).
303
- const fallback = {
304
+ const fallback: JxMutableNode = {
304
305
  attributes: { class: "sb-fallback" },
305
306
  tagName: "div",
306
307
  textContent: `<${comp.tagName}>`,
307
- } as JxMutableNode;
308
+ };
308
309
  return cardNode(comp.tagName, `<${comp.tagName}>`, fallback, cardPath, null);
309
310
  });
310
311
  sections.push(sectionNode("Components", cards));
@@ -316,17 +317,19 @@ export function buildStylebookDoc(opts: BuildStylebookDocOpts): StylebookDocResu
316
317
  attributes: { class: "sb-empty" },
317
318
  tagName: "div",
318
319
  textContent: opts.customizedOnly ? "No customized elements" : "No matching elements",
319
- } as JxMutableNode);
320
+ });
320
321
  }
321
322
 
322
- const doc = {
323
- ...($elements.length > 0 ? { $elements } : {}),
324
- $media: opts.effectiveMedia,
325
- attributes: { class: "sb-root" },
326
- children: sections,
327
- style: transposeStylebookStyle(opts.effectiveStyle),
328
- tagName: "div",
329
- } as JxMutableNode;
323
+ // Assigned in this order so the posted document keeps its key order: `$elements` leads when present.
324
+ const doc: JxMutableNode = {};
325
+ if ($elements.length > 0) {
326
+ doc.$elements = $elements;
327
+ }
328
+ doc.$media = opts.effectiveMedia;
329
+ doc.attributes = { class: "sb-root" };
330
+ doc.children = sections;
331
+ doc.style = transposeStylebookStyle(opts.effectiveStyle);
332
+ doc.tagName = "div";
330
333
 
331
334
  return { doc, pathToTag, tagToCardPath };
332
335
  }
@@ -31,8 +31,8 @@ import type {
31
31
  StylebookRowView,
32
32
  StylebookVariableView,
33
33
  } from "../surfaces/panel-stylebook-layers";
34
+ import { isNonNullObject } from "@jxsuite/schema/guards";
34
35
  import type { JxStyle } from "@jxsuite/schema/types";
35
- import type { ComponentEntry } from "../files/components.js";
36
36
 
37
37
  /** What the panel is drawn from: the catalogue, and what selecting a row does. */
38
38
  export interface StylebookLayersCtx {
@@ -40,9 +40,9 @@ export interface StylebookLayersCtx {
40
40
  stylebookMeta: { $sections: { label: string; elements: StylebookEntry[] }[] };
41
41
  }
42
42
 
43
- /** The row's own padding at depth 0, and what each level of nesting adds. */
44
- const INDENT_BASE = 8;
45
- const INDENT_STEP = 16;
43
+ /** The row's own padding at depth 0, and what each level of nesting adds (the Outline's too). */
44
+ export const INDENT_BASE = 8;
45
+ export const INDENT_STEP = 16;
46
46
 
47
47
  /**
48
48
  * Whether the open file has already written a `& <tag>` block with something in it.
@@ -50,9 +50,9 @@ const INDENT_STEP = 16;
50
50
  * @param {JxStyle} rootStyle
51
51
  * @param {string} tag
52
52
  */
53
- function hasTagStyle(rootStyle: JxStyle, tag: string) {
53
+ function hasTagStyle(rootStyle: JxStyle, tag: string): boolean {
54
54
  const s = rootStyle[`& ${tag}`];
55
- return Boolean(s) && typeof s === "object" && Object.keys(s as object).length > 0;
55
+ return isNonNullObject(s) && Object.keys(s).length > 0;
56
56
  }
57
57
 
58
58
  /**
@@ -121,7 +121,7 @@ function variableRows(rootStyle: JxStyle): StylebookVariableView[] {
121
121
  */
122
122
  export function stylebookLayersValues(ctx: StylebookLayersCtx): StylebookLayersValues {
123
123
  const tab = activeTab.value;
124
- const rootStyle = (tab?.doc.document?.style || {}) as JxStyle;
124
+ const rootStyle: JxStyle = tab?.doc.document?.style || {};
125
125
  const { selection } = shell.stylebook;
126
126
  const leaf = selectedLeaf(selection);
127
127
 
@@ -131,7 +131,7 @@ export function stylebookLayersValues(ctx: StylebookLayersCtx): StylebookLayersV
131
131
  elementRows(entry, rootStyle, leaf, 0, "", rows);
132
132
  }
133
133
  }
134
- for (const comp of componentRegistry as ComponentEntry[]) {
134
+ for (const comp of componentRegistry) {
135
135
  rows.push({
136
136
  customized: false,
137
137
  indent: `${INDENT_BASE}px`,
@@ -174,7 +174,7 @@ function revealSelectedRow(host: HTMLElement): void {
174
174
  queueMicrotask(() => {
175
175
  host
176
176
  .querySelector('[part="row"][aria-current="true"]')
177
- ?.scrollIntoView?.({ behavior: "smooth", block: "nearest" });
177
+ ?.scrollIntoView({ behavior: "smooth", block: "nearest" });
178
178
  });
179
179
  }
180
180
 
@@ -36,7 +36,8 @@ import { PROJECT_STYLES_TITLE } from "../style/project-styles";
36
36
  import { mountStylebookCanvas, panToStylebookTag } from "../canvas/iframe-host";
37
37
  import stylebookMeta from "../../data/stylebook-meta.json";
38
38
  import type { CanvasPanelEntry } from "../canvas/canvas-utils";
39
- import type { CanvasStageView } from "../surfaces/canvas-stage";
39
+ import type { CanvasStageHandle, CanvasStageView } from "../surfaces/canvas-stage";
40
+ import type { TabUi } from "../tabs/tab";
40
41
 
41
42
  export interface StylebookEntry {
42
43
  tag: string;
@@ -61,7 +62,7 @@ interface StylebookCtx {
61
62
  surface: CanvasSurface,
62
63
  view: CanvasStageView,
63
64
  entries: CanvasPanelEntry[],
64
- ) => Promise<unknown>;
65
+ ) => Promise<CanvasStageHandle | null>;
65
66
  /** A node the stage drew for a part — here, the empty box the chrome bar stands in. */
66
67
  stageHost: (surface: CanvasSurface, part: string) => HTMLElement | null;
67
68
  applyTransform: (surface: CanvasSurface) => void;
@@ -151,7 +152,7 @@ export async function renderStylebookMode(
151
152
  so the field keeps its caret across the stage rebuild a keystroke in it causes. */
152
153
  const chromeBarNode = chromeBar(surface);
153
154
 
154
- (canvasWrap as HTMLElement).style.overflow = "hidden";
155
+ canvasWrap.style.overflow = "hidden";
155
156
 
156
157
  /** @type {{ name: string; displayName: string; width: number }[]} */
157
158
  const allPanelDefs = [];
@@ -173,7 +174,7 @@ export async function renderStylebookMode(
173
174
  /** @type {CanvasPanelEntry[]} */
174
175
  let panelEntries;
175
176
  if (!hasMedia) {
176
- const hasBaseWidth = effectiveMedia && effectiveMedia["--"];
177
+ const hasBaseWidth = effectiveMedia["--"];
177
178
  const label = hasBaseWidth ? `${mediaDisplayName("--")} (${baseWidth}px)` : null;
178
179
  panelEntries = [
179
180
  ctx.canvasPanelEntry(
@@ -224,22 +225,17 @@ export async function renderStylebookMode(
224
225
  const generated = buildStylebookDoc({
225
226
  components: componentRegistry,
226
227
  customizedOnly: Boolean(customizedOnly),
227
- effectiveMedia: effectiveMedia ?? {},
228
+ effectiveMedia,
228
229
  effectiveStyle: getEffectiveStyle(tab?.doc.document?.style),
229
230
  filter,
230
- meta: stylebookMeta as { $sections: { label: string; elements: StylebookEntry[] }[] },
231
+ meta: stylebookMeta,
231
232
  projectRoot: projectState?.projectRoot ?? null,
232
233
  });
233
234
 
234
235
  const { panels } = surface;
235
236
  for (const { panel } of panelEntries) {
236
237
  panels.push(panel);
237
- mountStylebookCanvas(
238
- surface.renderGeneration,
239
- generated,
240
- panel.canvas as HTMLElement,
241
- panel._width,
242
- );
238
+ mountStylebookCanvas(surface.renderGeneration, generated, panel.canvas, panel._width);
243
239
  }
244
240
  if (hasMedia) {
245
241
  ctx.updateActivePanelHeaders(surface);
@@ -260,16 +256,16 @@ export async function renderStylebookMode(
260
256
  */
261
257
  export function selectStylebookTag(tag: string, media?: string | null, { panCanvas = false } = {}) {
262
258
  shell.stylebook.selection = tag;
259
+ const ui: Partial<TabUi> = { activeSelector: tag, rightTab: "style" };
260
+ if (media !== undefined) {
261
+ ui.activeMedia = media;
262
+ }
263
263
  updateSession(activeTab.value, {
264
264
  // The ROOT path, not an empty selection: stylebook mode has always parked the selection on the
265
265
  // Document element while the Style tab edits a TAG, and widening the field to a list changed
266
266
  // Which literal spells that — `[[]]` is one selected path, the root — not what it means.
267
267
  selection: [[]],
268
- ui: {
269
- activeSelector: tag,
270
- rightTab: "style",
271
- ...(media !== undefined ? { activeMedia: media } : {}),
272
- },
268
+ ui,
273
269
  });
274
270
 
275
271
  if (tag && panCanvas) {