@jxsuite/studio 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/data/elements-meta.json +5 -15
- package/data/html-meta.json +51 -6
- package/dist/chunks/{2020-xp8vnwma.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-fyf63pmy.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-2w1f35qs.js +18 -0
- package/dist/chunks/content-source-3wqeas45.js +46 -0
- package/dist/chunks/convert-to-repeater-d0cgnb6d.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-d6g50j7s.js +42 -0
- package/dist/chunks/extension-sections-fy7q4fe9.js +651 -0
- package/dist/chunks/file-ops-3btj6st0.js +47 -0
- package/dist/chunks/files-ef8fgs3w.js +72 -0
- package/dist/chunks/format-host-3c33nwr8.js +40 -0
- package/dist/chunks/fs-events-13tj6sex.js +18 -0
- package/dist/chunks/git-panel-4wp2rn9b.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-jgesd924.js +115 -0
- package/dist/chunks/{index-nj44jpzj.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-1nq5evsh.js +29 -0
- package/dist/chunks/layers-panel-ar2gh90g.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-2qbetq73.js +33 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -0
- package/dist/chunks/menu-rf7n72mf.js +14 -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-rws7k4br.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-98f7sr3g.js +27 -0
- package/dist/chunks/quick-search-srzz83k2.js +45 -0
- package/dist/chunks/references-n553f0e1.js +26 -0
- package/dist/chunks/right-panel-rrgx2dn3.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-18avnhjp.js +2430 -0
- package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-hbtp0eh1.js → studio-25hkdrkw.js} +356 -85
- package/dist/chunks/studio-26d7myd1.js +258 -0
- package/dist/chunks/{studio-p8j86wag.js → studio-38emantv.js} +22 -5
- package/dist/chunks/studio-3gxv60tn.js +422 -0
- package/dist/chunks/{studio-8swrjbny.js → studio-3hxkd92t.js} +275 -163
- package/dist/chunks/studio-4m0haseg.js +185 -0
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/{studio-gv8vvshc.js → studio-5523bpzt.js} +11 -11
- package/dist/chunks/{studio-5q69gfag.js → studio-57mf66w2.js} +1753 -2484
- package/dist/chunks/studio-5jy81t3s.js +17463 -0
- package/dist/chunks/studio-5rt7sqa0.js +1168 -0
- package/dist/chunks/studio-5te5tqng.js +81 -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-eenfkt4e.js → studio-79y5sz51.js} +52 -38
- package/dist/chunks/{studio-4q0wznzf.js → studio-7e11jpa9.js} +461 -145
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xptrg0j.js +954 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-81390n6f.js} +22 -22
- package/dist/chunks/{studio-q43a5y9h.js → studio-8jn5yhyn.js} +16 -16
- package/dist/chunks/studio-8qtrpzr3.js +839 -0
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-9xxz1q69.js +1356 -0
- package/dist/chunks/studio-akbww0j5.js +13615 -0
- package/dist/chunks/studio-arfpe389.js +195 -0
- package/dist/chunks/{studio-2zkz8evn.js → studio-az3zd49t.js} +473 -281
- package/dist/chunks/studio-cpvb2ed1.js +1171 -0
- package/dist/chunks/{studio-9r6j5ev1.js → studio-d0300636.js} +5078 -19
- package/dist/chunks/{studio-bgxt93ga.js → studio-d055c37e.js} +13 -13
- package/dist/chunks/studio-d1ja2x9r.js +362 -0
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/{studio-4pqqxbrt.js → studio-em9nw8eh.js} +301 -112
- package/dist/chunks/studio-erdatzvp.js +1190 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/studio-fabxk6r9.js +2811 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/studio-hhvs4sdg.js +195 -0
- package/dist/chunks/{studio-68n67094.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/studio-pm6hgy7r.js +4763 -0
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/studio-qahxvnan.js +111 -0
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-kjjsjak4.js → studio-rkstz940.js} +3661 -6136
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rpyah2ew.js +2805 -0
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/{studio-yxrkyv8a.js → studio-s6z853aq.js} +12108 -11766
- package/dist/chunks/{studio-sf7zjgv1.js → studio-sgdc5pfc.js} +8 -8
- package/dist/chunks/studio-tb3ev01j.js +763 -0
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-htsf0w6m.js → studio-vz68yn9e.js} +31 -154
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/{studio-eesa1myv.js → studio-x3rty6tr.js} +58 -58
- package/dist/chunks/studio-xsykpvsh.js +8448 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -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-wrew8zk4.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1812 -698
- package/dist/manifest.json +7 -0
- package/dist/studio.js +52900 -36573
- 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/favicon.ico +0 -0
- package/index.html +2 -0
- package/package.json +22 -55
- package/src/about/about-modal.ts +73 -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 +310 -117
- 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 +369 -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 +165 -8
- 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 +65 -26
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +949 -664
- package/src/files/json-layout.ts +474 -0
- package/src/files/media-paths.ts +13 -42
- package/src/files/media-usage.ts +41 -131
- 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/document.ts +2 -0
- package/src/hosting/layout.ts +10 -0
- package/src/i18n/i18n-commands.ts +127 -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 +201 -250
- package/src/new-project/location-fields.ts +101 -165
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- 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 -153
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +210 -185
- package/src/panels/block-action-bar.ts +437 -643
- 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 +153 -133
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +174 -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 +177 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +217 -172
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +109 -646
- 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 +385 -287
- package/src/platforms/cloud.ts +347 -86
- 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 +165 -299
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +468 -0
- package/src/services/ai-import-tools.ts +50 -12
- package/src/services/ai-models.ts +108 -1
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +110 -18
- package/src/services/ai-tools.ts +28 -143
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/context-manager.ts +12 -1
- package/src/services/document-assistant.ts +50 -2
- 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 +17 -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 +193 -12
- package/src/settings/preferences-dialog.ts +384 -307
- 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 +90 -67
- 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 +984 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +414 -389
- 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 +163 -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 +71 -15
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +49 -3
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +116 -49
- package/src/ui/ai-model-picker.ts +102 -47
- package/src/ui/cf-account-picker.ts +135 -0
- 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 +293 -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 +15 -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 -1532
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-723bv0df.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-t88vb2dr.js +0 -49
- package/dist/chunks/convert-to-repeater-dhw1nrz9.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-6z6bhxg0.js +0 -46
- package/dist/chunks/extension-sections-3ydgjbdy.js +0 -311
- package/dist/chunks/file-ops-rskmhxyq.js +0 -48
- package/dist/chunks/files-0cratsr0.js +0 -92
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-ggawf1hy.js +0 -1024
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-tgcmfs4p.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-0yywyk76.js +0 -58
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8q2g05x1.js +0 -19
- package/dist/chunks/layers-panel-z3tqe5cd.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-54jvhskq.js +0 -28
- package/dist/chunks/quick-search-cgfmjwq5.js +0 -65
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-cqp8bc4v.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-yztmtrs1.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-xcvpnqr0.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-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1hbqnt19.js +0 -1823
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5rywrkxz.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-9c4k4vhv.js +0 -357
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahjfdy6e.js +0 -387
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bw5dz6km.js +0 -608
- package/dist/chunks/studio-cb12yz9w.js +0 -15055
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ex8zyp98.js +0 -1813
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-kyk2v92a.js +0 -659
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mmv72a27.js +0 -4344
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-pdfjntbk.js +0 -6939
- package/dist/chunks/studio-qq6jym04.js +0 -53
- package/dist/chunks/studio-r1r7afxx.js +0 -1066
- 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-txwkm6p9.js +0 -12
- package/dist/chunks/studio-v38hmvx1.js +0 -390
- package/dist/chunks/studio-vadzgkrz.js +0 -318
- package/dist/chunks/studio-wx5609xd.js +0 -341
- package/dist/chunks/studio-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/workspace-xpres40v.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,
|
|
@@ -77,7 +78,6 @@ import { hasElementSelection, hasSelection, inCanvas, keyScopeStack } from "../c
|
|
|
77
78
|
import { defaultCommands } from "../commands/defaults";
|
|
78
79
|
import { setActiveRegistry } from "../commands/active-registry";
|
|
79
80
|
import { CommandUnavailableError } from "../commands/registry";
|
|
80
|
-
import { html } from "lit-html";
|
|
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";
|
|
@@ -464,9 +464,19 @@ export function nextRegion(
|
|
|
464
464
|
return null;
|
|
465
465
|
}
|
|
466
466
|
|
|
467
|
-
/**
|
|
467
|
+
/**
|
|
468
|
+
* The first element inside a region that can take the caret.
|
|
469
|
+
*
|
|
470
|
+
* It also listed `sp-action-button`, `sp-tab`, `sp-textfield` and `sp-picker`, and those four were
|
|
471
|
+
* load-bearing while Spectrum drew the chrome: a Spectrum control keeps its real control in a
|
|
472
|
+
* SHADOW ROOT, so `querySelector` inside a region host reached the custom element and nothing else.
|
|
473
|
+
* The kit has no shadow root anywhere (`ui.md` §3.2 — no element declares `$shadow`), so each of
|
|
474
|
+
* its controls puts a native `<button>`, `<input>` or `<select>` in the region's own tree, and the
|
|
475
|
+
* native entries already in this list find them. Naming the kit tags beside them would match the
|
|
476
|
+
* WRAPPER, one node earlier in document order than the thing that takes focus.
|
|
477
|
+
*/
|
|
468
478
|
const REGION_FOCUSABLE =
|
|
469
|
-
'a[href], button, input, textarea, select,
|
|
479
|
+
'a[href], button, input, textarea, select, [tabindex]:not([tabindex="-1"])';
|
|
470
480
|
|
|
471
481
|
/**
|
|
472
482
|
* Move focus into a region and record that it moved.
|
|
@@ -569,6 +579,51 @@ const OPEN_PROJECT_REPORT: Record<Exclude<ProjectOpenOutcome, "cancelled">, stri
|
|
|
569
579
|
opened: "Opened the project in this window.",
|
|
570
580
|
};
|
|
571
581
|
|
|
582
|
+
/**
|
|
583
|
+
* The three-way question itself: New Window, This Window, or neither.
|
|
584
|
+
*
|
|
585
|
+
* It was a hand-written `sp-dialog-wrapper` passed to `showDialog`, and it was never bespoke — a
|
|
586
|
+
* headline, a sentence and confirm / secondary / cancel is exactly what `surfaces/dialog.json`
|
|
587
|
+
* draws for Save-or-Discard, so the wrapper was a second answer to a settled question
|
|
588
|
+
* (studio-ui-guidelines.md §12.5). What is genuinely this flow's is only WHAT the three answers
|
|
589
|
+
* mean, which is the mapping below; the modality, the focus restoration, Escape and the backdrop
|
|
590
|
+
* are the platform's `<dialog>`, through the kit.
|
|
591
|
+
*
|
|
592
|
+
* `onClosed` resolves `cancel` the way the wrapper's `@close` did, and the settle guard is what
|
|
593
|
+
* makes the pair safe: pressing Cancel fires both the answer and, as the dialog closes,
|
|
594
|
+
* `onClosed`.
|
|
595
|
+
*
|
|
596
|
+
* @param {string} openName The project already open in this window, named in the sentence.
|
|
597
|
+
* @returns {Promise<ProjectOpenTarget | "cancel">}
|
|
598
|
+
*/
|
|
599
|
+
function askWhereToOpen(openName: string): Promise<ProjectOpenTarget | "cancel"> {
|
|
600
|
+
return new Promise((resolve) => {
|
|
601
|
+
let settled = false;
|
|
602
|
+
const done = (value: ProjectOpenTarget | "cancel") => {
|
|
603
|
+
if (settled) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
settled = true;
|
|
607
|
+
handle.close();
|
|
608
|
+
resolve(value);
|
|
609
|
+
};
|
|
610
|
+
const handle = openDialogSurface({
|
|
611
|
+
cancelLabel: "Cancel",
|
|
612
|
+
confirmLabel: "New Window",
|
|
613
|
+
headline: "Open Project",
|
|
614
|
+
layer: layerHost("dialog"),
|
|
615
|
+
message: `${openName} is open in this window. Where should the project you pick open?`,
|
|
616
|
+
onCancel: () => done("cancel"),
|
|
617
|
+
onClosed: () => done("cancel"),
|
|
618
|
+
onConfirm: () => done("newWindow"),
|
|
619
|
+
onSecondary: () => done("thisWindow"),
|
|
620
|
+
region: "project/open-target",
|
|
621
|
+
secondaryLabel: "This Window",
|
|
622
|
+
size: "sm",
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
|
|
572
627
|
/**
|
|
573
628
|
* Ask where the project should open, then say what happened.
|
|
574
629
|
*
|
|
@@ -592,25 +647,7 @@ export async function openProjectFlow(hooks: StudioCommandHooks): Promise<void>
|
|
|
592
647
|
return;
|
|
593
648
|
}
|
|
594
649
|
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
|
-
);
|
|
650
|
+
const choice = await askWhereToOpen(openName);
|
|
614
651
|
if (choice === "cancel") {
|
|
615
652
|
return;
|
|
616
653
|
}
|
|
@@ -928,7 +965,7 @@ export function initShortcuts(registry: CommandRegistry, stageContext: StageCont
|
|
|
928
965
|
document.addEventListener(
|
|
929
966
|
"wheel",
|
|
930
967
|
(e: WheelEvent) => {
|
|
931
|
-
if ((e.ctrlKey || e.metaKey) && !(e.target as Element | null)?.closest(
|
|
968
|
+
if ((e.ctrlKey || e.metaKey) && !(e.target as Element | null)?.closest(STAGE_SELECTOR)) {
|
|
932
969
|
e.preventDefault();
|
|
933
970
|
}
|
|
934
971
|
},
|
|
@@ -1005,7 +1042,9 @@ export function installStageGestures(surface: CanvasSurface): () => void {
|
|
|
1005
1042
|
requestEditZoom(editZoom * (1 + -e.deltaY * 0.005), surface);
|
|
1006
1043
|
return;
|
|
1007
1044
|
}
|
|
1008
|
-
|
|
1045
|
+
/* The stage's own scroller, by the `part` the stage document draws it with — the same
|
|
1046
|
+
attribute every other consumer of the canvas's chrome now addresses it by. */
|
|
1047
|
+
const sc = canvasWrap.querySelector<HTMLElement>('[part="edit-canvas"]');
|
|
1009
1048
|
if (sc) {
|
|
1010
1049
|
e.preventDefault();
|
|
1011
1050
|
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) {
|