@jxsuite/studio 4.1.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/data/elements-meta.json +5 -15
- package/data/html-meta.json +51 -6
- package/dist/chunks/{2020-n6tfwnda.js → 2020-g79n01v9.js} +14 -14
- package/dist/chunks/action-group-sp6tna8v.js +118 -0
- package/dist/chunks/adapter-nj7tnjfn.js +13 -0
- package/dist/chunks/cf-account-picker-qwkm9zrf.js +495 -0
- package/dist/chunks/cf-settings-71bv5zn9.js +20 -0
- package/dist/chunks/color-area-v17df7b8.js +154 -0
- package/dist/chunks/color-field-anwybnkn.js +208 -0
- package/dist/chunks/color-slider-44ez96fc.js +79 -0
- package/dist/chunks/color-xgg3kfw7.js +35 -0
- package/dist/chunks/combobox-5e7jev23.js +236 -0
- package/dist/chunks/components-vj72gqtq.js +20 -0
- package/dist/chunks/content-source-5mex4x1h.js +46 -0
- package/dist/chunks/convert-to-repeater-n64h8znc.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-234hjnqw.js +42 -0
- package/dist/chunks/extension-sections-3hpcambp.js +651 -0
- package/dist/chunks/file-ops-8yhd83xr.js +47 -0
- package/dist/chunks/files-hnxqxtsg.js +72 -0
- package/dist/chunks/format-host-779sfp2n.js +40 -0
- package/dist/chunks/fs-events-b88z7g4h.js +18 -0
- package/dist/chunks/git-panel-xwj8fpab.js +49 -0
- package/dist/chunks/icons-yy10wk9r.js +402 -0
- package/dist/chunks/iframe-entry-15g3n6xv.js +114 -0
- package/dist/chunks/iframe-entry-b27vq81n.js +203 -0
- package/dist/chunks/iframe-entry-nbyxee1y.js +154 -0
- package/dist/chunks/iframe-host-syr0f9sb.js +115 -0
- package/dist/chunks/{index-wcnt3r9g.js → index-mdmyx6s2.js} +11 -11
- package/dist/chunks/index-n4j7qxyr.js +109 -0
- package/dist/chunks/{javascript-q8kpmfah.js → javascript-xvrfrpkb.js} +8 -9
- package/dist/chunks/{jsonMode-dkr040ga.js → jsonMode-tyx2kj6p.js} +526 -527
- package/dist/chunks/jx-validate-j0wxk72w.js +15 -0
- package/dist/chunks/layers-ff81wthn.js +30 -0
- package/dist/chunks/layers-panel-pnnghw12.js +40 -0
- package/dist/chunks/listbox-6v2ac08j.js +44 -0
- package/dist/chunks/lit-html-m244w9nh.js +17 -0
- package/dist/chunks/media-picker-cqhhxhhe.js +33 -0
- package/dist/chunks/menu-9p2w46gj.js +15 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -0
- package/dist/chunks/{monaco-binding-rj6xpx9y.js → monaco-binding-sw6en4dw.js} +12 -15
- package/dist/chunks/monaco-buffer-bhy3hb6m.js +24 -0
- package/dist/chunks/{monaco-setup-vx9bhp1d.js → monaco-setup-8r62fj6y.js} +27 -37
- package/dist/chunks/notify-628t0anh.js +21 -0
- package/dist/chunks/number-field-5cndyft8.js +72 -0
- package/dist/chunks/parse-0zx14y15.js +10 -0
- package/dist/chunks/platform-ts9cg1a4.js +15 -0
- package/dist/chunks/popover-47z3ytva.js +25 -0
- package/dist/chunks/publish-panel-5zt840sy.js +27 -0
- package/dist/chunks/quick-search-3748564r.js +45 -0
- package/dist/chunks/references-qvvxej7h.js +26 -0
- package/dist/chunks/right-panel-eccz92qt.js +45 -0
- package/dist/chunks/section-registry-5pq32t0q.js +25 -0
- package/dist/chunks/select-2r16ez41.js +49 -0
- package/dist/chunks/split-g7nm1rgb.js +191 -0
- package/dist/chunks/studio-0hqbpbd0.js +62 -0
- package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-b55y6ewx.js → studio-1knfqgy7.js} +58 -58
- package/dist/chunks/{studio-2b946z26.js → studio-1z1kcjv4.js} +3628 -6095
- package/dist/chunks/studio-3773086z.js +111 -0
- package/dist/chunks/{studio-4r1pv6zf.js → studio-38emantv.js} +22 -5
- package/dist/chunks/{studio-x813zp48.js → studio-3rz5md06.js} +30 -30
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/studio-5te5tqng.js +81 -0
- package/dist/chunks/studio-5wt9nvhd.js +4763 -0
- package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
- package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
- package/dist/chunks/studio-6xa21ej9.js +28 -0
- package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
- package/dist/chunks/{studio-gcye7qka.js → studio-7e11jpa9.js} +21 -21
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xnmgv66.js +13615 -0
- package/dist/chunks/studio-8scdew0e.js +258 -0
- package/dist/chunks/{studio-fbf92ckf.js → studio-93zafjcm.js} +275 -163
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-a79k90n9.js +1162 -0
- package/dist/chunks/studio-aj37eer3.js +422 -0
- package/dist/chunks/studio-b0k5tqgp.js +2432 -0
- package/dist/chunks/studio-b4s9eykd.js +2811 -0
- package/dist/chunks/{studio-f3wqjtk5.js → studio-d0300636.js} +5076 -18
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/studio-e1pgga3k.js +839 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/{studio-q43a5y9h.js → studio-g3jevyjt.js} +16 -16
- package/dist/chunks/studio-gb13095a.js +2806 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/{studio-dm19q43r.js → studio-hhvs4sdg.js} +10 -10
- package/dist/chunks/{studio-x4qkdat5.js → studio-js8nv53n.js} +1749 -2481
- package/dist/chunks/{studio-qjy2z9bv.js → studio-jxp12rnj.js} +32 -137
- package/dist/chunks/{studio-trxrabqf.js → studio-k75n7vhp.js} +527 -283
- package/dist/chunks/{studio-q9jd1a60.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/studio-kkqkcp3d.js +17668 -0
- package/dist/chunks/studio-mhhyamxf.js +763 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-nq5yf5mp.js} +22 -22
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/studio-nzzpvzx9.js +185 -0
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/{studio-3bqpr0zh.js → studio-pxbgypmg.js} +299 -110
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/{studio-6yw4y3my.js → studio-qhhm6hbt.js} +8 -8
- package/dist/chunks/studio-qk4bfsq2.js +362 -0
- package/dist/chunks/{studio-msd847zn.js → studio-qk90fgqm.js} +361 -90
- package/dist/chunks/{studio-jkftxyvz.js → studio-r6nvacqs.js} +5861 -2154
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/studio-sbjyc8bt.js +954 -0
- package/dist/chunks/{studio-1wagb550.js → studio-syg2tadj.js} +11 -11
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-tqgryxwg.js +1171 -0
- package/dist/chunks/studio-try13h8c.js +8448 -0
- package/dist/chunks/studio-vfq8qpjt.js +1219 -0
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-ahn3pdgx.js → studio-vw7mzp6z.js} +52 -38
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/studio-wqz6dggm.js +1356 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -0
- package/dist/chunks/studio-zdn2g6dt.js +148 -0
- package/dist/chunks/swatch-group-t0n6h2rn.js +139 -0
- package/dist/chunks/tabs-wbp1cdws.js +156 -0
- package/dist/chunks/textfield-abk6qyee.js +73 -0
- package/dist/chunks/toast-780pvfbv.js +27 -0
- package/dist/chunks/toast-host-3sqv46sn.js +116 -0
- package/dist/chunks/toolbar-xbh5bhtr.js +194 -0
- package/dist/chunks/tooltip-eptb614w.js +369 -0
- package/dist/chunks/tree-a73p0pqm.js +367 -0
- package/dist/chunks/{tsMode-76kr53q0.js → tsMode-jy4m86rv.js} +83 -85
- package/dist/chunks/workspace-t55jdjbx.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1873 -673
- package/dist/studio.js +52757 -36535
- package/dist/workers/editor.worker.js +1040 -1085
- package/dist/workers/json.worker.js +1946 -1991
- package/dist/workers/ts.worker.js +4960 -5005
- package/index.html +1 -0
- package/package.json +18 -52
- package/src/about/about-modal.ts +72 -123
- package/src/browse/library-commands.ts +20 -49
- package/src/browse/library-layouts.ts +87 -218
- package/src/browse/library-pane.ts +406 -438
- package/src/canvas/canvas-helpers.ts +0 -49
- package/src/canvas/canvas-live-render.ts +25 -2
- package/src/canvas/canvas-render.ts +666 -231
- package/src/canvas/canvas-surface.ts +0 -1
- package/src/canvas/canvas-utils.ts +333 -113
- package/src/canvas/dialog-path.ts +76 -0
- package/src/canvas/dialog-state.ts +67 -0
- package/src/canvas/diff-marks.ts +252 -0
- package/src/canvas/diff-toolbar.ts +349 -0
- package/src/canvas/diff-view.ts +123 -0
- package/src/canvas/edit-width-drag.ts +187 -0
- package/src/canvas/edit-width.ts +150 -0
- package/src/canvas/iframe-entry.ts +125 -8
- package/src/canvas/iframe-host.ts +271 -15
- package/src/canvas/iframe-interaction.ts +133 -13
- package/src/canvas/iframe-patch.ts +7 -1
- package/src/canvas/iframe-position.ts +5 -6
- package/src/canvas/iframe-protocol.ts +106 -5
- package/src/canvas/iframe-render.ts +373 -5
- package/src/canvas/iframe-slash.ts +2 -2
- package/src/canvas/iframe-subtree.ts +5 -8
- package/src/canvas/path-mapping.ts +25 -3
- package/src/canvas/popover-path.ts +106 -0
- package/src/canvas/popover-state.ts +155 -0
- package/src/canvas/surface-registry.ts +21 -10
- package/src/collab/presence-chips.ts +51 -73
- package/src/commands/app-commands.ts +10 -0
- package/src/commands/budget.ts +12 -0
- package/src/commands/command-args.ts +404 -6
- package/src/commands/defaults.ts +44 -14
- package/src/commands/live-context.ts +11 -5
- package/src/commands/reference.ts +12 -2
- package/src/commands/registry.ts +177 -10
- package/src/commands/run-reported.ts +120 -0
- package/src/content/entry-commands.ts +16 -23
- package/src/content/entry-editor.ts +144 -101
- package/src/editor/canvas-slash-bridge.ts +2 -2
- package/src/editor/context-menu.ts +49 -200
- package/src/editor/convert-to-component.ts +42 -82
- package/src/editor/convert-to-repeater.ts +132 -173
- package/src/editor/inline-edit.ts +11 -0
- package/src/editor/shortcuts.ts +76 -49
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/components.ts +39 -0
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +944 -660
- package/src/files/json-layout.ts +474 -0
- package/src/files/serialize-document.ts +8 -1
- package/src/format/convert-file.ts +16 -10
- package/src/format/format-host.ts +50 -1
- package/src/github/github-auth.ts +71 -29
- package/src/github/github-publish.ts +57 -65
- package/src/grid/cell-editors.ts +46 -4
- package/src/grid/cell-popovers.ts +65 -62
- package/src/grid/grid-open.ts +86 -64
- package/src/grid/grid-panel.ts +390 -469
- package/src/grid/redirects-grid.ts +40 -44
- package/src/hosting/layout.ts +2 -0
- package/src/i18n/i18n-commands.ts +137 -62
- package/src/media/media-pane.ts +83 -133
- package/src/new-project/add-repo-modal.ts +125 -176
- package/src/new-project/import-tab.ts +181 -252
- package/src/new-project/location-fields.ts +93 -160
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- package/src/packages/pull-package-sync.ts +5 -1
- package/src/panels/activity-panel.ts +137 -104
- package/src/panels/ai-chat/chat-markdown.ts +15 -13
- package/src/panels/ai-chat/chat-view.ts +307 -472
- package/src/panels/ai-chat/composer.ts +175 -163
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +213 -185
- package/src/panels/block-action-bar.ts +444 -645
- package/src/panels/bottom-dock.ts +112 -47
- package/src/panels/chat-panel.ts +19 -14
- package/src/panels/data-explorer.ts +141 -102
- package/src/panels/data-grid.ts +183 -150
- package/src/panels/dnd.ts +75 -20
- package/src/panels/editors.ts +26 -19
- package/src/panels/elements-panel.ts +243 -186
- package/src/panels/empty-state.ts +26 -42
- package/src/panels/events-panel.ts +950 -729
- package/src/panels/formula-workspace.ts +434 -207
- package/src/panels/frontmatter-fields.ts +185 -153
- package/src/panels/frontmatter-panel.ts +411 -187
- package/src/panels/git-diff-open.ts +148 -0
- package/src/panels/git-panel.ts +679 -605
- package/src/panels/head-panel.ts +617 -435
- package/src/panels/i18n-panel.ts +148 -135
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +175 -147
- package/src/panels/layers-panel.ts +785 -671
- package/src/panels/left-panel.ts +166 -94
- package/src/panels/navigator-panels.ts +1 -1
- package/src/panels/pane-context.ts +529 -677
- package/src/panels/pane-grid.ts +265 -241
- package/src/panels/panel-registry.ts +15 -4
- package/src/panels/problems-panel.ts +181 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +223 -184
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +114 -661
- package/src/panels/settings-pane.ts +102 -86
- package/src/panels/signals-panel.ts +1318 -1172
- package/src/panels/statement-editor.ts +556 -428
- package/src/panels/style-panel.ts +1367 -630
- package/src/panels/style-utils.ts +36 -32
- package/src/panels/stylebook-doc.ts +30 -73
- package/src/panels/stylebook-layers-panel.ts +202 -109
- package/src/panels/stylebook-panel.ts +124 -88
- package/src/panels/tab-strip.ts +386 -288
- package/src/platforms/cloud.ts +106 -16
- package/src/platforms/devserver.ts +13 -0
- package/src/publish/deploy-checklist.ts +124 -78
- package/src/publish/publish-commands.ts +4 -12
- package/src/publish/publish-panel.ts +134 -328
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +538 -0
- package/src/services/ai-project-tools.ts +8 -2
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +112 -24
- package/src/services/ai-tools.ts +36 -212
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/document-assistant.ts +59 -8
- package/src/services/idle.ts +16 -14
- package/src/services/live-surfaces.ts +237 -0
- package/src/services/model-uri.ts +75 -0
- package/src/services/notify.ts +63 -6
- package/src/services/popover-report.ts +325 -0
- package/src/services/surface-registry.ts +56 -0
- package/src/services/tool-executor.ts +6 -0
- package/src/settings/contexts-section.ts +301 -299
- package/src/settings/contributed-section.ts +361 -222
- package/src/settings/css-vars-editor.ts +320 -325
- package/src/settings/defs-editor.ts +572 -535
- package/src/settings/dependencies-editor.ts +79 -107
- package/src/settings/extension-commands.ts +379 -0
- package/src/settings/extension-rows.ts +113 -0
- package/src/settings/extensions-section.ts +287 -0
- package/src/settings/general-settings.ts +130 -181
- package/src/settings/head-editor.ts +10 -305
- package/src/settings/locales-section.ts +146 -196
- package/src/settings/preferences-accounts.ts +1 -1
- package/src/settings/preferences-dialog.ts +350 -330
- package/src/settings/project-sections.ts +108 -181
- package/src/settings/schema-field-ui.ts +11 -399
- package/src/settings/section-registry.ts +8 -1
- package/src/settings/settings-document.ts +31 -29
- package/src/shell/tree.ts +42 -87
- package/src/shell.ts +48 -36
- package/src/studio.ts +104 -69
- package/src/style/token-ref.ts +0 -39
- package/src/surfaces/about.json +263 -0
- package/src/surfaces/about.ts +163 -0
- package/src/surfaces/add-repo.json +486 -0
- package/src/surfaces/add-repo.ts +236 -0
- package/src/surfaces/ai-chat.json +2185 -0
- package/src/surfaces/ai-chat.ts +549 -0
- package/src/surfaces/ai-credentials-form.json +332 -0
- package/src/surfaces/ai-credentials-form.ts +151 -0
- package/src/surfaces/ai-managed-connect.json +108 -0
- package/src/surfaces/ai-managed-connect.ts +123 -0
- package/src/surfaces/ai-model-picker.json +114 -0
- package/src/surfaces/ai-model-picker.ts +139 -0
- package/src/surfaces/block-action-bar.json +640 -0
- package/src/surfaces/block-action-bar.ts +368 -0
- package/src/surfaces/bottom-dock.json +154 -0
- package/src/surfaces/bottom-dock.ts +125 -0
- package/src/surfaces/canvas-stage.json +444 -0
- package/src/surfaces/canvas-stage.ts +253 -0
- package/src/surfaces/cf-account-picker.json +300 -0
- package/src/surfaces/cf-account-picker.ts +214 -0
- package/src/surfaces/commandbar.json +985 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +417 -391
- package/src/surfaces/convert-repeater.json +309 -0
- package/src/surfaces/convert-repeater.ts +276 -0
- package/src/surfaces/data-actions.json +157 -0
- package/src/surfaces/data-actions.ts +115 -0
- package/src/surfaces/dialog.json +289 -0
- package/src/surfaces/dialog.ts +343 -0
- package/src/surfaces/diff-toolbar.json +266 -0
- package/src/surfaces/diff-toolbar.ts +139 -0
- package/src/surfaces/doc-header.json +739 -0
- package/src/surfaces/doc-header.ts +223 -0
- package/src/surfaces/empty-state.json +152 -0
- package/src/surfaces/empty-state.ts +173 -0
- package/src/surfaces/entry-editor.json +281 -0
- package/src/surfaces/entry-editor.ts +191 -0
- package/src/surfaces/expression-editor.json +977 -0
- package/src/surfaces/expression-editor.ts +266 -0
- package/src/surfaces/files-panel.json +592 -0
- package/src/surfaces/files-panel.ts +301 -0
- package/src/surfaces/formula-palette.json +364 -0
- package/src/surfaces/formula-palette.ts +340 -0
- package/src/surfaces/git-panel.json +1822 -0
- package/src/surfaces/git-panel.ts +272 -0
- package/src/surfaces/github-auth.json +112 -0
- package/src/surfaces/github-auth.ts +139 -0
- package/src/surfaces/github-publish.json +206 -0
- package/src/surfaces/github-publish.ts +169 -0
- package/src/surfaces/grid-cell.json +218 -0
- package/src/surfaces/grid-cell.ts +120 -0
- package/src/surfaces/grid-open.json +147 -0
- package/src/surfaces/grid-open.ts +87 -0
- package/src/surfaces/grid-panel.json +706 -0
- package/src/surfaces/grid-panel.ts +206 -0
- package/src/surfaces/grid-replace.json +179 -0
- package/src/surfaces/grid-replace.ts +89 -0
- package/src/surfaces/grid-views.json +446 -0
- package/src/surfaces/grid-views.ts +172 -0
- package/src/surfaces/inspector-dock.json +187 -0
- package/src/surfaces/inspector-dock.ts +161 -0
- package/src/surfaces/jump-bar.json +243 -0
- package/src/surfaces/jump-bar.ts +129 -0
- package/src/surfaces/jxsuite-update.json +146 -0
- package/src/surfaces/jxsuite-update.ts +149 -0
- package/src/surfaces/library-pane.json +1509 -0
- package/src/surfaces/library-pane.ts +363 -0
- package/src/surfaces/logic-panel.json +1949 -0
- package/src/surfaces/logic-panel.ts +369 -0
- package/src/surfaces/logic-workspace.json +685 -0
- package/src/surfaces/logic-workspace.ts +238 -0
- package/src/surfaces/media-browser.json +303 -0
- package/src/surfaces/media-browser.ts +145 -0
- package/src/surfaces/media-field.json +163 -0
- package/src/surfaces/media-field.ts +116 -0
- package/src/surfaces/media-pane.json +513 -0
- package/src/surfaces/media-pane.ts +197 -0
- package/src/surfaces/menu.json +232 -0
- package/src/surfaces/menu.ts +375 -0
- package/src/surfaces/navigator-dock.json +113 -0
- package/src/surfaces/navigator-dock.ts +130 -0
- package/src/surfaces/new-project.json +1654 -0
- package/src/surfaces/new-project.ts +411 -0
- package/src/surfaces/palette.json +535 -0
- package/src/surfaces/pane-context.json +1497 -0
- package/src/surfaces/pane-context.ts +513 -0
- package/src/surfaces/pane-grid.json +188 -0
- package/src/surfaces/pane-grid.ts +250 -0
- package/src/surfaces/panel-activity.json +563 -0
- package/src/surfaces/panel-activity.ts +187 -0
- package/src/surfaces/panel-data.json +141 -0
- package/src/surfaces/panel-data.ts +156 -0
- package/src/surfaces/panel-deploy-checklist.json +283 -0
- package/src/surfaces/panel-deploy-checklist.ts +175 -0
- package/src/surfaces/panel-elements.json +367 -0
- package/src/surfaces/panel-elements.ts +175 -0
- package/src/surfaces/panel-i18n.json +569 -0
- package/src/surfaces/panel-i18n.ts +212 -0
- package/src/surfaces/panel-imports.json +780 -0
- package/src/surfaces/panel-imports.ts +209 -0
- package/src/surfaces/panel-outline.json +734 -0
- package/src/surfaces/panel-outline.ts +326 -0
- package/src/surfaces/panel-page.json +1017 -0
- package/src/surfaces/panel-page.ts +240 -0
- package/src/surfaces/panel-problems.json +497 -0
- package/src/surfaces/panel-problems.ts +157 -0
- package/src/surfaces/panel-signals.json +1973 -0
- package/src/surfaces/panel-signals.ts +436 -0
- package/src/surfaces/panel-stylebook-layers.json +317 -0
- package/src/surfaces/panel-stylebook-layers.ts +155 -0
- package/src/surfaces/preferences.json +850 -0
- package/src/surfaces/preferences.ts +332 -0
- package/src/surfaces/progress-modal.json +110 -0
- package/src/surfaces/progress-modal.ts +150 -0
- package/src/surfaces/properties-panel.json +1578 -0
- package/src/surfaces/properties-panel.ts +337 -0
- package/src/surfaces/publish.json +945 -0
- package/src/surfaces/publish.ts +392 -0
- package/src/surfaces/push-plan.json +110 -0
- package/src/surfaces/push-plan.ts +87 -0
- package/src/surfaces/rail.json +255 -0
- package/src/surfaces/rail.ts +206 -0
- package/src/surfaces/reference-field.json +191 -0
- package/src/surfaces/reference-field.ts +168 -0
- package/src/surfaces/schema-builder.json +1011 -0
- package/src/surfaces/schema-builder.ts +181 -0
- package/src/surfaces/schema-form.json +1013 -0
- package/src/surfaces/schema-form.ts +287 -0
- package/src/surfaces/secret-field.json +60 -0
- package/src/surfaces/secret-field.ts +146 -0
- package/src/surfaces/seo.json +932 -0
- package/src/surfaces/seo.ts +334 -0
- package/src/surfaces/settings-contexts.json +538 -0
- package/src/surfaces/settings-contexts.ts +196 -0
- package/src/surfaces/settings-contributed.json +489 -0
- package/src/surfaces/settings-contributed.ts +199 -0
- package/src/surfaces/settings-css-vars.json +820 -0
- package/src/surfaces/settings-css-vars.ts +199 -0
- package/src/surfaces/settings-defs.json +1363 -0
- package/src/surfaces/settings-defs.ts +232 -0
- package/src/surfaces/settings-deploy.json +108 -0
- package/src/surfaces/settings-deploy.ts +135 -0
- package/src/surfaces/settings-extensions.json +486 -0
- package/src/surfaces/settings-extensions.ts +201 -0
- package/src/surfaces/settings-head.json +779 -0
- package/src/surfaces/settings-head.ts +397 -0
- package/src/surfaces/settings-locales.json +420 -0
- package/src/surfaces/settings-locales.ts +137 -0
- package/src/surfaces/settings-overview.json +423 -0
- package/src/surfaces/settings-overview.ts +218 -0
- package/src/surfaces/settings-packages.json +549 -0
- package/src/surfaces/settings-packages.ts +158 -0
- package/src/surfaces/settings-pane.json +147 -0
- package/src/surfaces/settings-pane.ts +150 -0
- package/src/surfaces/settings-rawjson.json +104 -0
- package/src/surfaces/settings-rawjson.ts +107 -0
- package/src/surfaces/shell.json +99 -0
- package/src/surfaces/shell.ts +30 -0
- package/src/surfaces/slash-menu.json +180 -0
- package/src/surfaces/slash-menu.ts +272 -0
- package/src/surfaces/statements.json +607 -0
- package/src/surfaces/statements.ts +238 -0
- package/src/surfaces/statusbar.json +94 -0
- package/src/{panels → surfaces}/statusbar.ts +164 -90
- package/src/surfaces/style-panel.json +1643 -0
- package/src/surfaces/style-panel.ts +338 -0
- package/src/surfaces/stylebook-chrome.json +122 -0
- package/src/surfaces/stylebook-chrome.ts +122 -0
- package/src/surfaces/tab-strip.json +448 -0
- package/src/surfaces/tab-strip.ts +200 -0
- package/src/surfaces/target-line.json +419 -0
- package/src/surfaces/target-line.ts +349 -0
- package/src/surfaces/toasts.json +189 -0
- package/src/surfaces/welcome.json +571 -0
- package/src/surfaces/welcome.ts +338 -0
- package/src/tabs/project-config.ts +111 -21
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +22 -0
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +54 -36
- package/src/ui/ai-model-picker.ts +75 -47
- package/src/ui/cf-account-picker.ts +76 -141
- package/src/ui/color-selector.ts +80 -301
- package/src/ui/dynamic-slot.ts +43 -283
- package/src/ui/expression-editor.ts +797 -576
- package/src/ui/field-input.ts +8 -181
- package/src/ui/form-controls.ts +838 -366
- package/src/ui/formula-chips.ts +80 -85
- package/src/ui/kit.ts +33 -0
- package/src/ui/layers.ts +296 -593
- package/src/ui/media-picker.ts +203 -284
- package/src/ui/panel-resize.ts +251 -64
- package/src/ui/popover-surface.ts +153 -0
- package/src/ui/progress-modal.ts +22 -60
- package/src/ui/regions.ts +13 -7
- package/src/ui/schema-form.ts +906 -440
- package/src/ui/surface.ts +122 -0
- package/src/ui/unit-selector.ts +15 -131
- package/src/ui/value-source.ts +14 -0
- package/src/ui/virtual-window.ts +88 -9
- package/src/utils/canvas-media.ts +72 -0
- package/src/utils/edit-display.ts +7 -2
- package/src/utils/element-selectors.ts +69 -0
- package/src/utils/link-target.ts +2 -2
- package/src/utils/studio-utils.ts +0 -10
- package/src/view.ts +15 -0
- package/src/workspace/pane-derive.ts +36 -14
- package/src/workspace/workspace.ts +75 -6
- package/styles/canvas.css +72 -467
- package/styles/forced-colors.css +48 -82
- package/styles/forced-colors.json +41 -0
- package/styles/inspector.css +2 -1301
- package/styles/overlays.css +96 -2823
- package/styles/panels.css +6 -1423
- package/styles/shell-frame.css +272 -0
- package/styles/shell-frame.json +227 -0
- package/styles/shell.css +0 -1568
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-etqjwyf9.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-account-picker-en86v7x7.js +0 -163
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-48xg86wj.js +0 -49
- package/dist/chunks/convert-to-repeater-43tfn7cs.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-e63f1xc0.js +0 -46
- package/dist/chunks/extension-sections-txv08xxg.js +0 -311
- package/dist/chunks/file-ops-wbh4hhsx.js +0 -48
- package/dist/chunks/files-3kfkwhk4.js +0 -93
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-9t2drp0g.js +0 -1025
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-w16q81tf.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-532whr1y.js +0 -59
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8er6gbxy.js +0 -19
- package/dist/chunks/layers-panel-07hm7g5j.js +0 -67
- package/dist/chunks/layers-q75tj2mf.js +0 -45
- package/dist/chunks/lit-html-j055mkh8.js +0 -22
- package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
- package/dist/chunks/notify-yjm79n4s.js +0 -30
- package/dist/chunks/parse-24d0gay3.js +0 -19
- package/dist/chunks/platform-ba1j1gbh.js +0 -16
- package/dist/chunks/publish-panel-v9st96ja.js +0 -29
- package/dist/chunks/quick-search-zccjp6gv.js +0 -66
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-vm3b6kwy.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-qgvhnxf4.js +0 -18
- package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
- package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
- package/dist/chunks/sp-tooltip.dev-4sastdnw.js +0 -15
- package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
- package/dist/chunks/studio-0a5qrh01.js +0 -3
- package/dist/chunks/studio-0bq6eh7v.js +0 -12
- package/dist/chunks/studio-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1ngbejft.js +0 -181
- package/dist/chunks/studio-4b5z1x43.js +0 -424
- package/dist/chunks/studio-4n2b5gzb.js +0 -357
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5fx3g9jg.js +0 -4325
- package/dist/chunks/studio-5myknm0a.js +0 -1903
- package/dist/chunks/studio-7afd21nw.js +0 -67
- package/dist/chunks/studio-7nte2hj4.js +0 -613
- package/dist/chunks/studio-8jpzqk5s.js +0 -128
- package/dist/chunks/studio-8q517dfr.js +0 -24
- package/dist/chunks/studio-950k0dx6.js +0 -6939
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bgxt93ga.js +0 -62
- package/dist/chunks/studio-cmb03bg5.js +0 -13890
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-ef49pnzx.js +0 -387
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ew0djmhg.js +0 -341
- package/dist/chunks/studio-gfgb8pe6.js +0 -1652
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-jc994dnr.js +0 -1066
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mtfnaqs9.js +0 -659
- package/dist/chunks/studio-n6j9t10q.js +0 -318
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-qcy05dp8.js +0 -1743
- package/dist/chunks/studio-qq6jym04.js +0 -53
- package/dist/chunks/studio-rdx8jcxy.js +0 -83
- package/dist/chunks/studio-rn9ta2mz.js +0 -111
- package/dist/chunks/studio-t7qb9db8.js +0 -665
- package/dist/chunks/studio-tmc5emrw.js +0 -8
- package/dist/chunks/studio-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/studio-zqazsct2.js +0 -1823
- package/dist/chunks/workspace-fjx52ryv.js +0 -89
- package/src/panels/activity-bar.ts +0 -251
- package/src/panels/panel-scheduler.ts +0 -219
- package/src/panels/style-inputs.ts +0 -237
- package/src/panels/target-line.ts +0 -274
- package/src/panels/welcome-screen.ts +0 -346
- package/src/ui/button-group.ts +0 -102
- package/src/ui/choice-field.ts +0 -72
- package/src/ui/field-row.ts +0 -249
- package/src/ui/formula-palette.ts +0 -213
- package/src/ui/icons.ts +0 -52
- package/src/ui/jx-theme.ts +0 -130
- package/src/ui/spectrum.ts +0 -340
- package/src/ui/value-selector.ts +0 -174
- package/src/ui/widgets.ts +0 -172
- /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
- /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
- /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
- /package/dist/chunks/{tsMode-ef187txx.css → tsMode-hnxxb73h.css} +0 -0
package/src/editor/shortcuts.ts
CHANGED
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
import { childIndex, childList, getNodeAtPath, parentElementPath, projectState } from "../store";
|
|
34
34
|
import { activeTab, workspace } from "../workspace/workspace";
|
|
35
35
|
import {
|
|
36
|
-
STAGE_CLASS,
|
|
37
36
|
allCanvasSurfaces,
|
|
38
37
|
canvasModeOfPane,
|
|
39
38
|
surfaceForPane,
|
|
40
39
|
tabOfPane,
|
|
41
40
|
} from "../canvas/canvas-surface";
|
|
42
41
|
import type { CanvasSurface } from "../canvas/canvas-surface";
|
|
42
|
+
import { STAGE_SELECTOR } from "../surfaces/pane-grid";
|
|
43
43
|
import { primarySelection } from "../tabs/selection";
|
|
44
44
|
import {
|
|
45
45
|
mutateDuplicateNodes,
|
|
@@ -58,7 +58,8 @@ import {
|
|
|
58
58
|
import { openQuickSearch } from "../panels/quick-search";
|
|
59
59
|
import { inspectorTab } from "../panels/right-panel";
|
|
60
60
|
import { requestClose } from "../panels/tab-strip";
|
|
61
|
-
import {
|
|
61
|
+
import { layerHost } from "../ui/layers";
|
|
62
|
+
import { openDialogSurface } from "../surfaces/dialog";
|
|
62
63
|
import { rectOf } from "../utils/geometry";
|
|
63
64
|
import {
|
|
64
65
|
DOCK_IDS,
|
|
@@ -76,8 +77,7 @@ import { clipboardCommands, pasteNode } from "./context-menu";
|
|
|
76
77
|
import { hasElementSelection, hasSelection, inCanvas, keyScopeStack } from "../commands/context";
|
|
77
78
|
import { defaultCommands } from "../commands/defaults";
|
|
78
79
|
import { setActiveRegistry } from "../commands/active-registry";
|
|
79
|
-
import {
|
|
80
|
-
import { html } from "lit-html";
|
|
80
|
+
import { runReported } from "../commands/run-reported";
|
|
81
81
|
import type { CommandContext } from "../commands/context";
|
|
82
82
|
import type { DockId as CommandDockId } from "../commands/defaults";
|
|
83
83
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
@@ -388,11 +388,12 @@ function toggleShellDock(registry: CommandRegistry, dock: CommandDockId): void {
|
|
|
388
388
|
*
|
|
389
389
|
* `view.setAssistant` and `view.setRightTab` are `shell.ts`'s, composed into the app's registry by
|
|
390
390
|
* the bootstrap — a reduced registry (a test, a future second window kind) may not carry them, and
|
|
391
|
-
* a missing id must be inert rather than an exception thrown out of a keydown handler.
|
|
391
|
+
* a missing id must be inert rather than an exception thrown out of a keydown handler. A present
|
|
392
|
+
* one that refuses its arguments is not inert: `commands/run-reported.ts` files it in Problems.
|
|
392
393
|
*/
|
|
393
394
|
function runIfPresent(registry: CommandRegistry, id: string, args: Record<string, unknown>): void {
|
|
394
395
|
if (registry.get(id) && registry.isEnabled(id)) {
|
|
395
|
-
void registry
|
|
396
|
+
void runReported(registry, id, args, "Keyboard");
|
|
396
397
|
}
|
|
397
398
|
}
|
|
398
399
|
|
|
@@ -464,9 +465,19 @@ export function nextRegion(
|
|
|
464
465
|
return null;
|
|
465
466
|
}
|
|
466
467
|
|
|
467
|
-
/**
|
|
468
|
+
/**
|
|
469
|
+
* The first element inside a region that can take the caret.
|
|
470
|
+
*
|
|
471
|
+
* It also listed `sp-action-button`, `sp-tab`, `sp-textfield` and `sp-picker`, and those four were
|
|
472
|
+
* load-bearing while Spectrum drew the chrome: a Spectrum control keeps its real control in a
|
|
473
|
+
* SHADOW ROOT, so `querySelector` inside a region host reached the custom element and nothing else.
|
|
474
|
+
* The kit has no shadow root anywhere (`ui.md` §3.2 — no element declares `$shadow`), so each of
|
|
475
|
+
* its controls puts a native `<button>`, `<input>` or `<select>` in the region's own tree, and the
|
|
476
|
+
* native entries already in this list find them. Naming the kit tags beside them would match the
|
|
477
|
+
* WRAPPER, one node earlier in document order than the thing that takes focus.
|
|
478
|
+
*/
|
|
468
479
|
const REGION_FOCUSABLE =
|
|
469
|
-
'a[href], button, input, textarea, select,
|
|
480
|
+
'a[href], button, input, textarea, select, [tabindex]:not([tabindex="-1"])';
|
|
470
481
|
|
|
471
482
|
/**
|
|
472
483
|
* Move focus into a region and record that it moved.
|
|
@@ -569,6 +580,51 @@ const OPEN_PROJECT_REPORT: Record<Exclude<ProjectOpenOutcome, "cancelled">, stri
|
|
|
569
580
|
opened: "Opened the project in this window.",
|
|
570
581
|
};
|
|
571
582
|
|
|
583
|
+
/**
|
|
584
|
+
* The three-way question itself: New Window, This Window, or neither.
|
|
585
|
+
*
|
|
586
|
+
* It was a hand-written `sp-dialog-wrapper` passed to `showDialog`, and it was never bespoke — a
|
|
587
|
+
* headline, a sentence and confirm / secondary / cancel is exactly what `surfaces/dialog.json`
|
|
588
|
+
* draws for Save-or-Discard, so the wrapper was a second answer to a settled question
|
|
589
|
+
* (studio-ui-guidelines.md §12.5). What is genuinely this flow's is only WHAT the three answers
|
|
590
|
+
* mean, which is the mapping below; the modality, the focus restoration, Escape and the backdrop
|
|
591
|
+
* are the platform's `<dialog>`, through the kit.
|
|
592
|
+
*
|
|
593
|
+
* `onClosed` resolves `cancel` the way the wrapper's `@close` did, and the settle guard is what
|
|
594
|
+
* makes the pair safe: pressing Cancel fires both the answer and, as the dialog closes,
|
|
595
|
+
* `onClosed`.
|
|
596
|
+
*
|
|
597
|
+
* @param {string} openName The project already open in this window, named in the sentence.
|
|
598
|
+
* @returns {Promise<ProjectOpenTarget | "cancel">}
|
|
599
|
+
*/
|
|
600
|
+
function askWhereToOpen(openName: string): Promise<ProjectOpenTarget | "cancel"> {
|
|
601
|
+
return new Promise((resolve) => {
|
|
602
|
+
let settled = false;
|
|
603
|
+
const done = (value: ProjectOpenTarget | "cancel") => {
|
|
604
|
+
if (settled) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
settled = true;
|
|
608
|
+
handle.close();
|
|
609
|
+
resolve(value);
|
|
610
|
+
};
|
|
611
|
+
const handle = openDialogSurface({
|
|
612
|
+
cancelLabel: "Cancel",
|
|
613
|
+
confirmLabel: "New Window",
|
|
614
|
+
headline: "Open Project",
|
|
615
|
+
layer: layerHost("dialog"),
|
|
616
|
+
message: `${openName} is open in this window. Where should the project you pick open?`,
|
|
617
|
+
onCancel: () => done("cancel"),
|
|
618
|
+
onClosed: () => done("cancel"),
|
|
619
|
+
onConfirm: () => done("newWindow"),
|
|
620
|
+
onSecondary: () => done("thisWindow"),
|
|
621
|
+
region: "project/open-target",
|
|
622
|
+
secondaryLabel: "This Window",
|
|
623
|
+
size: "sm",
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
|
|
572
628
|
/**
|
|
573
629
|
* Ask where the project should open, then say what happened.
|
|
574
630
|
*
|
|
@@ -592,25 +648,7 @@ export async function openProjectFlow(hooks: StudioCommandHooks): Promise<void>
|
|
|
592
648
|
return;
|
|
593
649
|
}
|
|
594
650
|
const openName = projectState.name;
|
|
595
|
-
const choice = await
|
|
596
|
-
(done) => html`
|
|
597
|
-
<sp-dialog-wrapper
|
|
598
|
-
open
|
|
599
|
-
underlay
|
|
600
|
-
headline="Open Project"
|
|
601
|
-
confirm-label="New Window"
|
|
602
|
-
secondary-label="This Window"
|
|
603
|
-
cancel-label="Cancel"
|
|
604
|
-
size="s"
|
|
605
|
-
@confirm=${() => done("newWindow")}
|
|
606
|
-
@secondary=${() => done("thisWindow")}
|
|
607
|
-
@cancel=${() => done("cancel")}
|
|
608
|
-
@close=${() => done("cancel")}
|
|
609
|
-
>
|
|
610
|
-
<p>${openName} is open in this window. Where should the project you pick open?</p>
|
|
611
|
-
</sp-dialog-wrapper>
|
|
612
|
-
`,
|
|
613
|
-
);
|
|
651
|
+
const choice = await askWhereToOpen(openName);
|
|
614
652
|
if (choice === "cancel") {
|
|
615
653
|
return;
|
|
616
654
|
}
|
|
@@ -864,34 +902,21 @@ export function registerStudioCommands(
|
|
|
864
902
|
*
|
|
865
903
|
* `preventDefault()` iff a command claimed the chord. A command that is VISIBLE but disabled — ⌘Z
|
|
866
904
|
* with nothing to undo, Delete on the document element — still counts as claiming it: the registry
|
|
867
|
-
*
|
|
868
|
-
* because the chord is spoken for and letting the browser act on it instead would
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
872
|
-
*
|
|
905
|
+
* consults `isEnabled` itself and returns the id without running, and swallowing the key is the
|
|
906
|
+
* honest outcome, because the chord is spoken for and letting the browser act on it instead would
|
|
907
|
+
* be a surprise. Nothing is caught here, because nothing leaves: `handleKeyEvent` runs the hit
|
|
908
|
+
* through `commands/run-reported.ts`, so a record that refuses its arguments, a gate that closed
|
|
909
|
+
* between the check and the run, or a `run` body that throws is a Problems row under "Keyboard"
|
|
910
|
+
* rather than an exception out of the keydown listener.
|
|
873
911
|
*/
|
|
874
912
|
function dispatchKey(registry: CommandRegistry, event: KeyboardEvent): string | undefined {
|
|
875
|
-
const commandId =
|
|
913
|
+
const commandId = registry.handleKeyEvent(event, keyScopeStack(registry.context()));
|
|
876
914
|
if (commandId) {
|
|
877
915
|
event.preventDefault();
|
|
878
916
|
}
|
|
879
917
|
return commandId;
|
|
880
918
|
}
|
|
881
919
|
|
|
882
|
-
/** The id of the command that claimed the chord, whether it ran or refused. */
|
|
883
|
-
function claimChord(registry: CommandRegistry, event: KeyboardEvent): string | undefined {
|
|
884
|
-
const stack = keyScopeStack(registry.context());
|
|
885
|
-
try {
|
|
886
|
-
return registry.handleKeyEvent(event, stack);
|
|
887
|
-
} catch (error) {
|
|
888
|
-
if (error instanceof CommandUnavailableError) {
|
|
889
|
-
return error.commandId;
|
|
890
|
-
}
|
|
891
|
-
throw error;
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
920
|
// ─── Pointer and wheel gestures ───────────────────────────────────────────────
|
|
896
921
|
|
|
897
922
|
/**
|
|
@@ -928,7 +953,7 @@ export function initShortcuts(registry: CommandRegistry, stageContext: StageCont
|
|
|
928
953
|
document.addEventListener(
|
|
929
954
|
"wheel",
|
|
930
955
|
(e: WheelEvent) => {
|
|
931
|
-
if ((e.ctrlKey || e.metaKey) && !(e.target as Element | null)?.closest(
|
|
956
|
+
if ((e.ctrlKey || e.metaKey) && !(e.target as Element | null)?.closest(STAGE_SELECTOR)) {
|
|
932
957
|
e.preventDefault();
|
|
933
958
|
}
|
|
934
959
|
},
|
|
@@ -1005,7 +1030,9 @@ export function installStageGestures(surface: CanvasSurface): () => void {
|
|
|
1005
1030
|
requestEditZoom(editZoom * (1 + -e.deltaY * 0.005), surface);
|
|
1006
1031
|
return;
|
|
1007
1032
|
}
|
|
1008
|
-
|
|
1033
|
+
/* The stage's own scroller, by the `part` the stage document draws it with — the same
|
|
1034
|
+
attribute every other consumer of the canvas's chrome now addresses it by. */
|
|
1035
|
+
const sc = canvasWrap.querySelector<HTMLElement>('[part="edit-canvas"]');
|
|
1009
1036
|
if (sc) {
|
|
1010
1037
|
e.preventDefault();
|
|
1011
1038
|
sc.scrollTop += e.deltaY;
|
package/src/editor/slash-menu.ts
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* The slash menu — the shared element-insertion list, and the flow behind it.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* One implementation used by inline editing in both realms (Edit/Content and Design mode), by the
|
|
6
|
+
* block action bar's convert menu, and by the canvas `+`. `surfaces/slash-menu.json` is the panel —
|
|
7
|
+
* its markup, its ARIA and every value in its style — and this module is the decisions: what is on
|
|
8
|
+
* offer, what the filter matches, which row is active, and what a pick does.
|
|
9
|
+
*
|
|
10
|
+
* **Why this is not `surfaces/menu.json`.** Every other Studio menu is that surface, and §12.5 says
|
|
11
|
+
* a second list of actions is a defect — but a `jx-menu` owns DOM focus by contract: showing one
|
|
12
|
+
* moves the caret onto its first row. This panel exists to filter a caret that is somewhere else,
|
|
13
|
+
* inside the canvas's `contenteditable` and usually inside the canvas IFRAME, and every character
|
|
14
|
+
* typed after the `/` has to keep landing there. A panel that takes the keyboard ends the
|
|
15
|
+
* interaction it exists to serve. So the panel is a listbox that marks its active row and never
|
|
16
|
+
* takes focus, and the keys are taken where they actually land — a document-level capturing
|
|
17
|
+
* listener for this realm, and {@link handleSlashMenuKey} called straight across the bridge for the
|
|
18
|
+
* other one. That listener is not a focus trap and cannot become one: it forwards four keys to the
|
|
19
|
+
* same driver the bridge uses, and everything else keeps going to the caret.
|
|
20
|
+
*
|
|
21
|
+
* Light dismissal, the top layer and Escape-on-the-topmost-popover are the platform's, through the
|
|
22
|
+
* `jx-popover` the document is rooted in; the `mousedown` capture listener that used to hand-roll
|
|
23
|
+
* the first of those went with the Spectrum markup.
|
|
24
|
+
*
|
|
25
|
+
* @docs studio/editing/slash-commands
|
|
9
26
|
*/
|
|
10
27
|
|
|
11
|
-
import {
|
|
12
|
-
import { ref } from "lit-html/directives/ref.js";
|
|
13
|
-
import { getLayerSlot } from "../ui/layers";
|
|
28
|
+
import { openSlashMenuSurface } from "../surfaces/slash-menu";
|
|
14
29
|
import { rectOf } from "../utils/geometry";
|
|
30
|
+
import type { SlashMenuRow, SlashMenuSurface, SlashMenuView } from "../surfaces/slash-menu";
|
|
15
31
|
|
|
16
32
|
interface SlashCommand {
|
|
17
33
|
label: string;
|
|
@@ -61,16 +77,12 @@ let activeIdx = 0;
|
|
|
61
77
|
|
|
62
78
|
/** What the current open() asked for, so a repaint driven by the keyboard reproduces it. */
|
|
63
79
|
let showFilter = false;
|
|
80
|
+
/** What the panel's own filter field holds. Empty for an anchored menu, which has no field. */
|
|
81
|
+
let filterText = "";
|
|
64
82
|
let filteredItems: SlashCommand[] = [];
|
|
65
83
|
let open = false;
|
|
66
84
|
let _anchorRect: SlashMenuAnchorRect | null = null;
|
|
67
|
-
let
|
|
68
|
-
let _popoverEl: HTMLElement | null = null;
|
|
69
|
-
|
|
70
|
-
/** @returns {HTMLElement} */
|
|
71
|
-
function getHost() {
|
|
72
|
-
return getLayerSlot("popover", "slash-menu");
|
|
73
|
-
}
|
|
85
|
+
let _surface: SlashMenuSurface | null = null;
|
|
74
86
|
|
|
75
87
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
76
88
|
|
|
@@ -87,7 +99,7 @@ export function isSlashMenuOpen() {
|
|
|
87
99
|
* @param {SlashMenuCallbacks} cbs
|
|
88
100
|
*/
|
|
89
101
|
export function showSlashMenu(anchorEl: HTMLElement, filter: string, cbs: SlashMenuCallbacks) {
|
|
90
|
-
showAt(rectOf(anchorEl), filter, cbs);
|
|
102
|
+
showAt(rectOf(anchorEl), filter, cbs, anchorEl);
|
|
91
103
|
}
|
|
92
104
|
|
|
93
105
|
/**
|
|
@@ -107,17 +119,55 @@ export function showSlashMenuAtRect(
|
|
|
107
119
|
showAt(rect, filter, cbs);
|
|
108
120
|
}
|
|
109
121
|
|
|
122
|
+
/** Everything on offer right now: what the caller named, or the standard set. */
|
|
123
|
+
function source(): SlashCommand[] {
|
|
124
|
+
return callbacks?.commands || SLASH_COMMANDS;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** The offers a filter leaves standing. An empty filter leaves all of them. */
|
|
128
|
+
function matching(filter: string, from: SlashCommand[]): SlashCommand[] {
|
|
129
|
+
return filter
|
|
130
|
+
? from.filter(
|
|
131
|
+
(c) => c.label.toLowerCase().includes(filter) || c.tag.toLowerCase().includes(filter),
|
|
132
|
+
)
|
|
133
|
+
: from;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** What the panel should be showing, from the state above. */
|
|
137
|
+
function view(): SlashMenuView {
|
|
138
|
+
const rect = _anchorRect;
|
|
139
|
+
return {
|
|
140
|
+
activeIndex: activeIdx,
|
|
141
|
+
filter: filterText,
|
|
142
|
+
rows: filteredItems.map((cmd): SlashMenuRow => ({
|
|
143
|
+
description: cmd.description,
|
|
144
|
+
key: cmd.tag,
|
|
145
|
+
label: cmd.label,
|
|
146
|
+
})),
|
|
147
|
+
showFilter,
|
|
148
|
+
// The gap between the anchor and the panel is the `--jx-popover-offset` token the element
|
|
149
|
+
// Already applies, so this is the anchor's own edge rather than an edge plus a guess.
|
|
150
|
+
x: rect ? rect.left : 0,
|
|
151
|
+
y: rect ? rect.bottom : 0,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Push the current state to the open panel. A no-op when there is none. */
|
|
156
|
+
function paint(): void {
|
|
157
|
+
_surface?.update(view());
|
|
158
|
+
}
|
|
159
|
+
|
|
110
160
|
/** Shared body of the two show entry points. */
|
|
111
|
-
function showAt(
|
|
161
|
+
function showAt(
|
|
162
|
+
rect: SlashMenuAnchorRect,
|
|
163
|
+
filter: string,
|
|
164
|
+
cbs: SlashMenuCallbacks,
|
|
165
|
+
anchor?: Element | null,
|
|
166
|
+
) {
|
|
112
167
|
callbacks = cbs;
|
|
113
168
|
_anchorRect = rect;
|
|
114
169
|
|
|
115
|
-
|
|
116
|
-
filteredItems = filter
|
|
117
|
-
? source.filter(
|
|
118
|
-
(c) => c.label.toLowerCase().includes(filter) || c.tag.toLowerCase().includes(filter),
|
|
119
|
-
)
|
|
120
|
-
: source;
|
|
170
|
+
filteredItems = matching(filter, cbs.commands || SLASH_COMMANDS);
|
|
121
171
|
|
|
122
172
|
if (filteredItems.length === 0 && !cbs.showFilter) {
|
|
123
173
|
dismissSlashMenu();
|
|
@@ -125,120 +175,86 @@ function showAt(rect: SlashMenuAnchorRect, filter: string, cbs: SlashMenuCallbac
|
|
|
125
175
|
}
|
|
126
176
|
|
|
127
177
|
activeIdx = 0;
|
|
128
|
-
|
|
129
178
|
showFilter = cbs.showFilter || false;
|
|
130
|
-
render();
|
|
131
179
|
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
requestAnimationFrame(() => {
|
|
136
|
-
document.addEventListener("mousedown", onOutsideClick, true);
|
|
137
|
-
});
|
|
180
|
+
if (_surface) {
|
|
181
|
+
paint();
|
|
182
|
+
return;
|
|
138
183
|
}
|
|
139
184
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
185
|
+
open = true;
|
|
186
|
+
filterText = "";
|
|
187
|
+
document.addEventListener("keydown", onKeydown, true); // Capture phase
|
|
188
|
+
_surface = openSlashMenuSurface(
|
|
189
|
+
view(),
|
|
190
|
+
{
|
|
191
|
+
activateRow: (index) => {
|
|
192
|
+
const cmd = filteredItems[index];
|
|
193
|
+
if (cmd) {
|
|
194
|
+
select(cmd);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
dismissed: onPlatformDismiss,
|
|
198
|
+
hover: (index) => {
|
|
199
|
+
activeIdx = index;
|
|
200
|
+
paint();
|
|
201
|
+
},
|
|
202
|
+
input: onFilterInput,
|
|
203
|
+
},
|
|
204
|
+
anchor ?? null,
|
|
205
|
+
);
|
|
206
|
+
if (showFilter) {
|
|
207
|
+
const surface = _surface;
|
|
208
|
+
void surface.ready.then(() => {
|
|
209
|
+
if (_surface === surface) {
|
|
210
|
+
surface.focusFilter();
|
|
144
211
|
}
|
|
145
212
|
});
|
|
146
213
|
}
|
|
147
214
|
}
|
|
148
215
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Forget everything about the open menu and hand back whoever asked for it.
|
|
218
|
+
*
|
|
219
|
+
* Split out because there are two ways one closes — this module closing it, and the PLATFORM
|
|
220
|
+
* closing it (a click outside, Escape on the topmost popover) — and both have to leave exactly the
|
|
221
|
+
* same state behind.
|
|
222
|
+
*/
|
|
223
|
+
function teardown(): SlashMenuCallbacks | null {
|
|
153
224
|
const cbs = callbacks;
|
|
154
225
|
open = false;
|
|
155
226
|
callbacks = null;
|
|
156
227
|
_anchorRect = null;
|
|
157
|
-
_filterEl = null;
|
|
158
|
-
_popoverEl = null;
|
|
159
228
|
filteredItems = [];
|
|
229
|
+
filterText = "";
|
|
230
|
+
activeIdx = 0;
|
|
160
231
|
document.removeEventListener("keydown", onKeydown, true);
|
|
161
|
-
|
|
162
|
-
|
|
232
|
+
return cbs;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function dismissSlashMenu() {
|
|
236
|
+
if (!open) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const surface = _surface;
|
|
240
|
+
_surface = null;
|
|
241
|
+
const cbs = teardown();
|
|
242
|
+
surface?.close();
|
|
163
243
|
// After teardown so a re-entrant show from the callback sees a closed menu. select() relies on
|
|
164
244
|
// This ordering too: dismiss (→ onDismiss) fires BEFORE onSelect.
|
|
165
245
|
cbs?.onDismiss?.();
|
|
166
246
|
}
|
|
167
247
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
menu is, and a keyboard repaint cannot disagree with the open() that created it. */
|
|
172
|
-
function render() {
|
|
173
|
-
const rect = _anchorRect;
|
|
174
|
-
if (!rect) {
|
|
248
|
+
/** The platform closed the panel — a click outside, or Escape reaching the topmost popover. */
|
|
249
|
+
function onPlatformDismiss(): void {
|
|
250
|
+
if (!open) {
|
|
175
251
|
return;
|
|
176
252
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
html`
|
|
180
|
-
<sp-popover
|
|
181
|
-
open
|
|
182
|
-
data-jx-region="overlay.menu:slash-menu"
|
|
183
|
-
${ref((el) => {
|
|
184
|
-
_popoverEl = (el as HTMLElement | undefined) || null;
|
|
185
|
-
})}
|
|
186
|
-
style="position:fixed;left:${rect.left}px;top:${
|
|
187
|
-
rect.bottom + 4
|
|
188
|
-
}px;z-index:9999;max-height:320px;overflow-y:auto"
|
|
189
|
-
>
|
|
190
|
-
${
|
|
191
|
-
showFilter
|
|
192
|
-
? html`<input
|
|
193
|
-
class="slash-filter"
|
|
194
|
-
type="text"
|
|
195
|
-
placeholder="Filter…"
|
|
196
|
-
autocomplete="off"
|
|
197
|
-
style="display:block;width:100%;box-sizing:border-box;padding:6px 10px;border:none;border-bottom:1px solid var(--border, #444);outline:none;font-size:13px;background:transparent;color:inherit"
|
|
198
|
-
${ref((el) => {
|
|
199
|
-
_filterEl = (el as HTMLInputElement | undefined) || null;
|
|
200
|
-
})}
|
|
201
|
-
@input=${onFilterInput}
|
|
202
|
-
/>`
|
|
203
|
-
: nothing
|
|
204
|
-
}
|
|
205
|
-
<sp-menu style="min-width:220px">
|
|
206
|
-
${
|
|
207
|
-
filteredItems.length > 0
|
|
208
|
-
? filteredItems.map(
|
|
209
|
-
(cmd, i) => html`
|
|
210
|
-
<sp-menu-item
|
|
211
|
-
?focused=${i === activeIdx}
|
|
212
|
-
@click=${(e: Event) => {
|
|
213
|
-
e.preventDefault();
|
|
214
|
-
e.stopPropagation();
|
|
215
|
-
select(cmd);
|
|
216
|
-
}}
|
|
217
|
-
>
|
|
218
|
-
${cmd.label}
|
|
219
|
-
${
|
|
220
|
-
cmd.description
|
|
221
|
-
? html`<span slot="description">${cmd.description}</span>`
|
|
222
|
-
: nothing
|
|
223
|
-
}
|
|
224
|
-
</sp-menu-item>
|
|
225
|
-
`,
|
|
226
|
-
)
|
|
227
|
-
: html`<sp-menu-item disabled>No matches</sp-menu-item>`
|
|
228
|
-
}
|
|
229
|
-
</sp-menu>
|
|
230
|
-
</sp-popover>
|
|
231
|
-
`,
|
|
232
|
-
getHost(),
|
|
233
|
-
);
|
|
253
|
+
_surface = null;
|
|
254
|
+
teardown()?.onDismiss?.();
|
|
234
255
|
}
|
|
235
256
|
|
|
236
|
-
|
|
237
|
-
function onOutsideClick(e: MouseEvent) {
|
|
238
|
-
if (_popoverEl && !_popoverEl.contains(e.target as Node)) {
|
|
239
|
-
dismissSlashMenu();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
257
|
+
// ─── Internal ─────────────────────────────────────────────────────────────────
|
|
242
258
|
|
|
243
259
|
/** @param {SlashCommand} cmd */
|
|
244
260
|
function select(cmd: SlashCommand) {
|
|
@@ -247,41 +263,12 @@ function select(cmd: SlashCommand) {
|
|
|
247
263
|
cbs?.onSelect(cmd);
|
|
248
264
|
}
|
|
249
265
|
|
|
250
|
-
/** @param {
|
|
251
|
-
function onFilterInput(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const source = callbacks?.commands || SLASH_COMMANDS;
|
|
256
|
-
filteredItems = filter
|
|
257
|
-
? source.filter(
|
|
258
|
-
(c) => c.label.toLowerCase().includes(filter) || c.tag.toLowerCase().includes(filter),
|
|
259
|
-
)
|
|
260
|
-
: source;
|
|
261
|
-
|
|
266
|
+
/** @param {string} value */
|
|
267
|
+
function onFilterInput(value: string) {
|
|
268
|
+
filterText = value;
|
|
269
|
+
filteredItems = matching(value.toLowerCase(), source());
|
|
262
270
|
activeIdx = 0;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// Re-focus input after re-render
|
|
266
|
-
requestAnimationFrame(() => {
|
|
267
|
-
if (_filterEl && _filterEl !== document.activeElement) {
|
|
268
|
-
_filterEl.focus();
|
|
269
|
-
_filterEl.selectionStart = _filterEl.value.length;
|
|
270
|
-
_filterEl.selectionEnd = _filterEl.value.length;
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Scroll the active row into view after a repaint.
|
|
277
|
-
*
|
|
278
|
-
* The only imperative half of the keyboard model, and it stays imperative on purpose: where a row
|
|
279
|
-
* sits in a scroller is a measurement, not something a template can express. Everything else —
|
|
280
|
-
* WHICH row is active — is now a binding, because it has to be.
|
|
281
|
-
*/
|
|
282
|
-
function revealActive(): void {
|
|
283
|
-
const rows = getHost().querySelectorAll("sp-menu-item:not([disabled])");
|
|
284
|
-
rows[activeIdx]?.scrollIntoView({ block: "nearest" });
|
|
271
|
+
paint();
|
|
285
272
|
}
|
|
286
273
|
|
|
287
274
|
/**
|
|
@@ -289,29 +276,35 @@ function revealActive(): void {
|
|
|
289
276
|
* was pressed in the iframe realm — a synthetic keydown redispatch on this document would lose the
|
|
290
277
|
* capture-first + stopPropagation semantics the menu relies on to shield other handlers).
|
|
291
278
|
*
|
|
279
|
+
* The offers are read from the array behind the panel rather than from its rows: the rows are a
|
|
280
|
+
* rendering, and a key that arrives while the document is still reconciling would otherwise be
|
|
281
|
+
* counting a list that has not caught up.
|
|
282
|
+
*
|
|
283
|
+
* Nothing here scrolls the new row into view, and that is the kit's rather than an omission: the
|
|
284
|
+
* panel writes ONE id, the listbox's `active`, and `mountListbox` is what turns that into a row's
|
|
285
|
+
* `selected` and brings it back on screen. Measurement belongs to the element that can see the
|
|
286
|
+
* box.
|
|
287
|
+
*
|
|
292
288
|
* @param {string} key — "ArrowDown" | "ArrowUp" | "Enter" | "Escape"
|
|
293
289
|
*/
|
|
294
290
|
export function handleSlashMenuKey(key: string): void {
|
|
295
291
|
if (!open) {
|
|
296
292
|
return;
|
|
297
293
|
}
|
|
298
|
-
|
|
299
|
-
const items = getHost().querySelectorAll("sp-menu-item:not([disabled])") as NodeListOf<Element>;
|
|
294
|
+
const count = filteredItems.length;
|
|
300
295
|
|
|
301
296
|
if (key === "ArrowDown") {
|
|
302
|
-
if (
|
|
297
|
+
if (count === 0) {
|
|
303
298
|
return;
|
|
304
299
|
}
|
|
305
|
-
activeIdx = (activeIdx + 1) %
|
|
306
|
-
|
|
307
|
-
revealActive();
|
|
300
|
+
activeIdx = (activeIdx + 1) % count;
|
|
301
|
+
paint();
|
|
308
302
|
} else if (key === "ArrowUp") {
|
|
309
|
-
if (
|
|
303
|
+
if (count === 0) {
|
|
310
304
|
return;
|
|
311
305
|
}
|
|
312
|
-
activeIdx = (activeIdx - 1 +
|
|
313
|
-
|
|
314
|
-
revealActive();
|
|
306
|
+
activeIdx = (activeIdx - 1 + count) % count;
|
|
307
|
+
paint();
|
|
315
308
|
} else if (key === "Enter") {
|
|
316
309
|
const cmd = filteredItems[activeIdx];
|
|
317
310
|
if (cmd) {
|
package/src/files/components.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { getPlatform } from "../platform";
|
|
4
4
|
import { projectState } from "../store";
|
|
5
5
|
import type { ComponentMeta } from "../types";
|
|
6
|
+
import { componentMetaFrom } from "@jxsuite/schema/component-meta";
|
|
6
7
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
7
8
|
|
|
8
9
|
/** A discovered component: project components carry a file path; package components may not. */
|
|
@@ -26,6 +27,44 @@ export async function loadComponentRegistry() {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Bring the registry up to date with a document that was just saved.
|
|
32
|
+
*
|
|
33
|
+
* The registry is the snapshot the platform's scan took when the project opened, and a saved
|
|
34
|
+
* component definition used to leave it behind: give a prop `format: "image"` in the definition and
|
|
35
|
+
* every instance's Component Settings kept drawing the text box the snapshot knew, until the
|
|
36
|
+
* project was reopened. The saved document is the same input the scan reads, through the same
|
|
37
|
+
* extractor (`componentMetaFrom`, shared by all three backends), so the entry is rebuilt from it
|
|
38
|
+
* here rather than by a rescan of every JSON file in the project. A definition that stopped being a
|
|
39
|
+
* component (its `tagName` lost its hyphen) leaves the registry by the same rule the scan applies.
|
|
40
|
+
*
|
|
41
|
+
* @param {string | null} path - The saved document's project-relative path; `null` for an unsaved
|
|
42
|
+
* draft, which no scan would have seen either.
|
|
43
|
+
* @param {unknown} doc - The saved document.
|
|
44
|
+
* @returns {boolean} Whether the registry changed, so a caller knows to repaint what reads it.
|
|
45
|
+
*/
|
|
46
|
+
export function noteComponentSaved(path: string | null, doc: unknown): boolean {
|
|
47
|
+
if (!path) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const index = componentRegistry.findIndex((c) => c.path === path);
|
|
51
|
+
const meta = componentMetaFrom(doc, path);
|
|
52
|
+
if (!meta) {
|
|
53
|
+
if (index === -1) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
componentRegistry.splice(index, 1);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const entry = meta as ComponentEntry;
|
|
60
|
+
if (index === -1) {
|
|
61
|
+
componentRegistry.push(entry);
|
|
62
|
+
} else {
|
|
63
|
+
componentRegistry[index] = entry;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
29
68
|
/**
|
|
30
69
|
* Build a fresh instance definition for a component: $props from prop defaults, plus the
|
|
31
70
|
* component's slot fallback children cloned in as starting content so editors can edit from the
|