@jxsuite/studio 5.2.0 → 5.4.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/data/css-meta.json +28 -27
- package/dist/chunks/{cf-account-picker-h4dab9bq.js → cf-account-picker-3f08rry6.js} +21 -18
- package/dist/chunks/{cf-settings-adg74qsk.js → cf-settings-m79r7p5y.js} +4 -4
- package/dist/chunks/{components-5y78e05d.js → components-xm826zjw.js} +3 -3
- package/dist/chunks/{content-source-sgg1sv6n.js → content-source-jt7rbcbc.js} +22 -22
- package/dist/chunks/{convert-to-repeater-mf1cxgfn.js → convert-to-repeater-vg38bq99.js} +22 -22
- package/dist/chunks/{editor-3qhbg51x.js → editor-ddy019sn.js} +2 -2
- package/dist/chunks/entry-commands-64nb2a9a.js +42 -0
- package/dist/chunks/{extension-sections-c6zwzbre.js → extension-sections-r73an5s6.js} +31 -30
- package/dist/chunks/{file-ops-vrpq1jjk.js → file-ops-3xan8mnj.js} +21 -21
- package/dist/chunks/{files-msaf95y6.js → files-egsb0ry8.js} +30 -29
- package/dist/chunks/{format-host-f64fnesp.js → format-host-mym8qnd0.js} +3 -3
- package/dist/chunks/{fs-events-3y6y0nrm.js → fs-events-z2gg8qjt.js} +4 -4
- package/dist/chunks/{git-panel-bv5e22j0.js → git-panel-a05atk6q.js} +20 -20
- package/dist/chunks/{grid-view-1p6hsyjx.css → grid-view-3g1h2re8.css} +956 -139
- package/dist/chunks/{grid-view-paj67nr5.js → grid-view-qaqer9kr.js} +24 -24
- package/dist/chunks/{icons-yy10wk9r.js → icons-drxq9q10.js} +8 -2
- package/dist/chunks/{iframe-host-dh5np8vk.js → iframe-host-psetcv20.js} +11 -11
- package/dist/chunks/{index-n4j7qxyr.js → index-9yjae3hz.js} +4 -4
- package/dist/chunks/{javascript-4abzjcy9.css → javascript-bc9z461d.css} +688 -54
- package/dist/chunks/{javascript-xvrfrpkb.js → javascript-hr5sg57n.js} +2 -2
- package/dist/chunks/{jsonMode-vvmpmk34.css → jsonMode-qqd9nm1t.css} +1120 -303
- package/dist/chunks/{jsonMode-tyx2kj6p.js → jsonMode-zs88v0wr.js} +4 -4
- package/dist/chunks/{jx-validate-j0wxk72w.js → jx-validate-epp2z3s3.js} +2 -2
- package/dist/chunks/layers-panel-83a16ytx.js +41 -0
- package/dist/chunks/{layers-1vcfdbet.js → layers-s6mc01ry.js} +3 -3
- package/dist/chunks/{listbox-6v2ac08j.js → listbox-b7jxnhq1.js} +19 -3
- package/dist/chunks/{media-picker-p49nhqhs.js → media-picker-nhn6rv4w.js} +11 -11
- package/dist/chunks/{menu-qht48vnc.js → menu-8j4qxjrp.js} +4 -4
- package/dist/chunks/{monaco-binding-sw6en4dw.js → monaco-binding-e8d9wzyk.js} +3 -3
- package/dist/chunks/{monaco-buffer-pykwbm92.js → monaco-buffer-jaq1t9zj.js} +2 -2
- package/dist/chunks/{monaco-setup-8vbyqnhr.css → monaco-setup-ey9cjcm3.css} +954 -137
- package/dist/chunks/{monaco-setup-8r62fj6y.js → monaco-setup-gsjdysze.js} +7 -7
- package/dist/chunks/{platform-ts9cg1a4.js → platform-fnchmhy7.js} +5 -3
- package/dist/chunks/publish-panel-ak6hxfma.js +27 -0
- package/dist/chunks/quick-search-c63mkt3b.js +47 -0
- package/dist/chunks/{references-h69xp9zz.js → references-f7bdv3z5.js} +3 -3
- package/dist/chunks/right-panel-t5n8wttg.js +45 -0
- package/dist/chunks/{split-g7nm1rgb.js → split-4cz4b6ef.js} +14 -3
- package/dist/chunks/{studio-sar8g54p.js → studio-01269reb.js} +8 -8
- package/dist/chunks/{studio-rnyf3f8e.js → studio-0a4gncx0.js} +3 -3
- package/dist/chunks/{studio-e1f24eff.js → studio-0d4p4wxj.js} +6778 -2993
- package/dist/chunks/{studio-4wbb9ct0.js → studio-1tejxvba.js} +3006 -1855
- package/dist/chunks/{studio-p6pmwkvh.js → studio-3nprwbd9.js} +147 -28
- package/dist/chunks/{studio-4c041r8y.js → studio-40z39dme.js} +3 -3
- package/dist/chunks/{studio-68fydsrj.js → studio-482eeazk.js} +20 -20
- package/dist/chunks/{studio-y4f9fdge.js → studio-4998spet.js} +10 -9
- package/dist/chunks/{studio-nq5yf5mp.js → studio-557bmn0x.js} +2 -2
- package/dist/chunks/{studio-hdc2jt3z.js → studio-5w26wza5.js} +3 -3
- package/dist/chunks/{studio-6nzaktvy.js → studio-6pwn9j8c.js} +6 -3
- package/dist/chunks/{studio-wnsyffg1.js → studio-6vg0x5fz.js} +3 -2
- package/dist/chunks/{studio-vn5hske5.js → studio-7d3c1m59.js} +12 -5
- package/dist/chunks/{studio-28vs5k2y.js → studio-9vsvz7w7.js} +7 -7
- package/dist/chunks/{studio-t3adrr56.js → studio-9wm0xzpf.js} +19 -19
- package/dist/chunks/{studio-38emantv.js → studio-a5h5j33a.js} +19 -5
- package/dist/chunks/{studio-ympe0n7a.js → studio-ag3z6shb.js} +10 -4
- package/dist/chunks/studio-aj9drheq.js +177 -0
- package/dist/chunks/{studio-vt0tj32j.js → studio-apv9x70c.js} +189 -130
- package/dist/chunks/{studio-c04nzbby.js → studio-b9q3znz8.js} +2 -2
- package/dist/chunks/{studio-2mdbbc76.js → studio-bh47w0cy.js} +9 -10
- package/dist/chunks/{studio-ez11dmdh.js → studio-dgdm6vvt.js} +264 -52
- package/dist/chunks/{studio-5nz00bhh.js → studio-dwdcr2e8.js} +4 -4
- package/dist/chunks/{studio-nqgawfks.js → studio-fbcyz234.js} +146 -139
- package/dist/chunks/{studio-kcgff4r0.js → studio-fgmfksz8.js} +2 -2
- package/dist/chunks/{studio-x72j58vw.js → studio-fqpkpq1t.js} +7 -4
- package/dist/chunks/{studio-15f3kxqe.js → studio-fy320dfc.js} +62 -68
- package/dist/chunks/{studio-zjjde71a.js → studio-gjj4bbfx.js} +2 -2
- package/dist/chunks/{studio-66arbpc2.js → studio-jfhxy8h3.js} +16 -15
- package/dist/chunks/{studio-d0300636.js → studio-ks2zzth2.js} +17 -2
- package/dist/chunks/{studio-c07s5ckd.js → studio-kwewmhhq.js} +4 -4
- package/dist/chunks/{studio-01jeck2y.js → studio-m58xn8at.js} +26 -25
- package/dist/chunks/{studio-mpzwze9x.js → studio-mfkh1q8d.js} +17 -17
- package/dist/chunks/{studio-etvx9s2g.js → studio-mrh0a92f.js} +17 -17
- package/dist/chunks/{studio-qa7fzxan.js → studio-mt79tn56.js} +3 -3
- package/dist/chunks/{studio-hhskq2mr.js → studio-ne593z1j.js} +39 -32
- package/dist/chunks/{studio-h4nvnjvz.js → studio-ptfcxkz5.js} +418 -232
- package/dist/chunks/{studio-4xmjcrg3.js → studio-qxye31h7.js} +7 -7
- package/dist/chunks/{studio-a1pswps3.js → studio-rav5bpmp.js} +81 -59
- package/dist/chunks/{studio-ncn9e189.js → studio-rwmmbrth.js} +6 -6
- package/dist/chunks/{studio-en82c639.js → studio-sceg8ws0.js} +8 -8
- package/dist/chunks/{studio-wjpgxywa.js → studio-sjas5b3a.js} +19 -13
- package/dist/chunks/{studio-4r14yzyy.js → studio-vd67b66d.js} +3 -3
- package/dist/chunks/{studio-14d9tq4d.js → studio-w475cbf9.js} +10 -10
- package/dist/chunks/{studio-ctm7bhx5.js → studio-w7gpcvfj.js} +9 -9
- package/dist/chunks/{studio-9j6sfeba.js → studio-xrbfdxgk.js} +7 -7
- package/dist/chunks/{studio-x10fp4tp.js → studio-y49b6mjv.js} +35 -35
- package/dist/chunks/{studio-5t7ena5z.js → studio-ygvr9e4q.js} +10 -10
- package/dist/chunks/{studio-z2smx5ce.js → studio-yxmmjy2a.js} +9 -6
- package/dist/chunks/{tsMode-jy4m86rv.js → tsMode-ay4c78ne.js} +4 -4
- package/dist/chunks/{tsMode-hnxxb73h.css → tsMode-c72wyz27.css} +954 -137
- package/dist/chunks/{workspace-bnw54cha.js → workspace-b9k2frks.js} +5 -5
- package/dist/chunks/{ws-client-ny4zc51r.js → ws-client-erze4czt.js} +356 -20
- package/dist/codicon.ttf +0 -0
- package/dist/iframe-entry.js +20 -18
- package/dist/studio.css +956 -139
- package/dist/studio.js +1511 -851
- package/dist/workers/editor.worker.js +196 -107
- package/dist/workers/json.worker.js +196 -107
- package/dist/workers/ts.worker.js +196 -107
- package/package.json +18 -17
- package/src/about/about-modal.ts +4 -3
- package/src/browse/library-commands.ts +15 -13
- package/src/browse/library-pane.ts +2 -2
- package/src/canvas/canvas-render.ts +97 -83
- package/src/canvas/canvas-surface.ts +2 -2
- package/src/canvas/canvas-utils.ts +42 -32
- package/src/canvas/diff-toolbar.ts +21 -2
- package/src/canvas/diff-view.ts +30 -6
- package/src/canvas/iframe-entry.ts +2 -2
- package/src/canvas/iframe-host.ts +5 -5
- package/src/canvas/iframe-interaction.ts +7 -6
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-protocol.ts +6 -5
- package/src/canvas/iframe-render.ts +3 -3
- package/src/canvas/popover-state.ts +1 -1
- package/src/canvas/stage-scrollbar.ts +112 -0
- package/src/canvas/surface-registry.ts +9 -2
- package/src/collab/collab-commands.ts +8 -6
- package/src/collab/collab-session.ts +4 -4
- package/src/collab/collab-state.ts +4 -4
- package/src/collab/presence-chips.ts +3 -3
- package/src/commands/app-commands.ts +7 -7
- package/src/commands/budget.ts +17 -16
- package/src/commands/command-args.ts +10 -9
- package/src/commands/context.ts +20 -10
- package/src/commands/defaults.ts +30 -29
- package/src/commands/levels.ts +8 -6
- package/src/commands/live-context.ts +12 -10
- package/src/commands/reference.ts +5 -5
- package/src/commands/registry.ts +2 -2
- package/src/content/draft-state.ts +9 -8
- package/src/content/entry-commands.ts +16 -14
- package/src/content/entry-editor.ts +2 -2
- package/src/content/entry-fields.ts +1 -1
- package/src/editor/context-menu.ts +4 -4
- package/src/editor/convert-to-component.ts +6 -5
- package/src/editor/inline-edit.ts +3 -3
- package/src/editor/shortcuts.ts +88 -20
- package/src/editor/slash-menu.ts +11 -10
- package/src/files/elements.ts +4 -5
- package/src/files/file-ops.ts +1 -1
- package/src/files/files.ts +21 -17
- package/src/files/serialize-document.ts +1 -1
- package/src/format/convert-file.ts +5 -5
- package/src/github/github-auth-status.ts +107 -0
- package/src/github/github-auth.ts +18 -82
- package/src/github/github-publish.ts +7 -6
- package/src/grid/cell-editors.ts +8 -7
- package/src/grid/grid-layout.ts +1 -1
- package/src/grid/grid-open.ts +6 -5
- package/src/grid/grid-panel.ts +13 -12
- package/src/grid/redirects-grid.ts +14 -11
- package/src/grid/redirects.ts +10 -5
- package/src/grid/sources/content-source.ts +10 -9
- package/src/hosting/document.ts +28 -1
- package/src/hosting/stage.ts +15 -4
- package/src/i18n/i18n-commands.ts +9 -7
- package/src/new-project/location-fields.ts +16 -3
- package/src/new-project/new-project-modal.ts +23 -7
- package/src/page-params.ts +6 -6
- package/src/panels/activity-panel.ts +11 -10
- package/src/panels/ai-chat/chat-view.ts +27 -14
- package/src/panels/ai-chat/composer.ts +10 -3
- package/src/panels/ai-panel.ts +87 -29
- package/src/panels/block-action-bar.ts +59 -33
- package/src/panels/bottom-dock.ts +22 -22
- package/src/panels/chat-panel.ts +40 -5
- package/src/panels/data-explorer.ts +9 -9
- package/src/panels/data-grid.ts +1 -1
- package/src/panels/editors.ts +8 -8
- package/src/panels/elements-panel.ts +7 -8
- package/src/panels/empty-state.ts +1 -1
- package/src/panels/events-panel.ts +13 -12
- package/src/panels/formula-workspace.ts +8 -5
- package/src/panels/frontmatter-fields.ts +4 -1
- package/src/panels/frontmatter-panel.ts +18 -18
- package/src/panels/git-panel.ts +19 -13
- package/src/panels/head-panel.ts +9 -10
- package/src/panels/i18n-panel.ts +6 -4
- package/src/panels/imports-panel.ts +1 -1
- package/src/panels/jump-bar.ts +20 -18
- package/src/panels/layers-panel.ts +19 -17
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/navigator-panels.ts +8 -8
- package/src/panels/overlays.ts +1 -1
- package/src/panels/pane-context.ts +56 -28
- package/src/panels/pane-grid.ts +9 -8
- package/src/panels/panel-registry.ts +47 -19
- package/src/panels/problems-panel.ts +11 -12
- package/src/panels/properties-panel.ts +21 -20
- package/src/panels/provenance.ts +3 -3
- package/src/panels/quick-search.ts +15 -11
- package/src/panels/right-panel.ts +4 -3
- package/src/panels/seo-modal.ts +5 -4
- package/src/panels/settings-menu.ts +9 -9
- package/src/panels/settings-pane.ts +3 -3
- package/src/panels/signals-panel.ts +16 -9
- package/src/panels/statement-editor.ts +12 -9
- package/src/panels/style-panel.ts +45 -41
- package/src/panels/stylebook-panel.ts +0 -1
- package/src/panels/tab-strip.ts +26 -23
- package/src/platform-errors.ts +2 -2
- package/src/platform.ts +44 -4
- package/src/platforms/cloud.ts +11 -1
- package/src/platforms/default-platform.ts +141 -4
- package/src/platforms/devserver.ts +23 -3
- package/src/publish/deploy-checklist.ts +11 -10
- package/src/publish/publish-commands.ts +9 -8
- package/src/services/a11y-report.ts +1 -1
- package/src/services/ai-ask.ts +39 -16
- package/src/services/ai-command-tools.ts +28 -14
- package/src/services/ai-import-tools.ts +43 -29
- package/src/services/ai-project-tools.ts +20 -38
- package/src/services/ai-settings.ts +55 -2
- package/src/services/ai-tools.ts +69 -58
- package/src/services/ai-write-report.ts +4 -4
- package/src/services/ai-writes.ts +74 -55
- package/src/services/automation.ts +12 -12
- package/src/services/clock.ts +2 -1
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +69 -6
- package/src/services/directory-picker.ts +93 -27
- package/src/services/document-assistant.ts +86 -17
- package/src/services/gated-registry.ts +4 -3
- package/src/services/idle.ts +5 -4
- package/src/services/live-surfaces.ts +2 -1
- package/src/services/module-preloads.ts +67 -0
- package/src/services/notify.ts +9 -7
- package/src/services/popover-report.ts +3 -3
- package/src/services/preview-eval.ts +1 -1
- package/src/services/project-adoption.ts +34 -1
- package/src/services/project-path.ts +53 -0
- package/src/services/settings/kernel.ts +13 -2
- package/src/services/tool-executor.ts +135 -30
- package/src/services/tool-outcomes.ts +143 -0
- package/src/settings/contexts-section.ts +8 -8
- package/src/settings/contributed-section.ts +6 -6
- package/src/settings/css-vars-editor.ts +6 -5
- package/src/settings/extension-commands.ts +19 -18
- package/src/settings/extension-sections.ts +7 -7
- package/src/settings/extensions-section.ts +3 -3
- package/src/settings/general-settings.ts +21 -18
- package/src/settings/preferences-accounts.ts +3 -3
- package/src/settings/preferences-dialog.ts +9 -8
- package/src/settings/preferences-sections.ts +1 -1
- package/src/settings/project-sections.ts +2 -2
- package/src/settings/section-registry.ts +7 -6
- package/src/settings/settings-document.ts +41 -43
- package/src/shell/tree.ts +29 -0
- package/src/shell.ts +63 -55
- package/src/site-context.ts +1 -1
- package/src/store.ts +2 -2
- package/src/studio.ts +52 -28
- package/src/style/live-preview.ts +8 -8
- package/src/style/project-styles.ts +8 -9
- package/src/style/token-ref.ts +2 -2
- package/src/surfaces/about.json +6 -2
- package/src/surfaces/add-repo.json +2 -2
- package/src/surfaces/add-repo.ts +2 -2
- package/src/surfaces/ai-chat.json +14 -6
- package/src/surfaces/ai-chat.ts +4 -2
- package/src/surfaces/ai-credentials-form.json +53 -49
- package/src/surfaces/ai-credentials-form.ts +18 -4
- package/src/surfaces/ai-managed-connect.json +4 -4
- package/src/surfaces/block-action-bar.json +4 -4
- package/src/surfaces/block-action-bar.ts +3 -3
- package/src/surfaces/boot-failure.json +228 -0
- package/src/surfaces/boot-failure.ts +156 -0
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/canvas-stage.json +9 -40
- package/src/surfaces/canvas-stage.ts +9 -9
- package/src/surfaces/cf-account-picker.json +11 -8
- package/src/surfaces/commandbar.ts +11 -10
- package/src/surfaces/convert-repeater.ts +3 -2
- package/src/surfaces/dialog.json +7 -1
- package/src/surfaces/dialog.ts +2 -2
- package/src/surfaces/doc-header.json +6 -13
- package/src/surfaces/doc-header.ts +4 -5
- package/src/surfaces/entry-editor.json +1 -1
- package/src/surfaces/entry-editor.ts +2 -1
- package/src/surfaces/expression-editor.json +5 -5
- package/src/surfaces/files-panel.json +4 -3
- package/src/surfaces/files-panel.ts +1 -1
- package/src/surfaces/formula-palette.json +10 -9
- package/src/surfaces/formula-palette.ts +11 -7
- package/src/surfaces/git-panel.json +167 -109
- package/src/surfaces/git-panel.ts +2 -2
- package/src/surfaces/github-auth.json +2 -1
- package/src/surfaces/github-publish.ts +3 -3
- package/src/surfaces/grid-open.json +1 -1
- package/src/surfaces/grid-panel.json +2 -2
- package/src/surfaces/grid-views.json +1 -1
- package/src/surfaces/inspector-dock.json +2 -2
- package/src/surfaces/jump-bar.json +1 -1
- package/src/surfaces/jump-bar.ts +1 -1
- package/src/surfaces/library-pane.ts +2 -1
- package/src/surfaces/logic-panel.json +7 -7
- package/src/surfaces/logic-panel.ts +6 -4
- package/src/surfaces/logic-workspace.json +2 -2
- package/src/surfaces/logic-workspace.ts +2 -2
- package/src/surfaces/media-browser.ts +3 -3
- package/src/surfaces/media-pane.ts +2 -1
- package/src/surfaces/menu.ts +5 -5
- package/src/surfaces/new-project.json +1 -1
- package/src/surfaces/palette.json +8 -7
- package/src/surfaces/pane-context.json +86 -57
- package/src/surfaces/pane-context.ts +2 -1
- package/src/surfaces/pane-grid.json +3 -3
- package/src/surfaces/panel-activity.json +2 -1
- package/src/surfaces/panel-deploy-checklist.json +1 -1
- package/src/surfaces/panel-elements.ts +2 -1
- package/src/surfaces/panel-i18n.ts +2 -1
- package/src/surfaces/panel-outline.json +1 -1
- package/src/surfaces/panel-outline.ts +4 -3
- package/src/surfaces/panel-page.json +2 -2
- package/src/surfaces/panel-page.ts +4 -1
- package/src/surfaces/panel-problems.json +4 -3
- package/src/surfaces/panel-problems.ts +2 -2
- package/src/surfaces/panel-signals.json +23 -8
- package/src/surfaces/panel-signals.ts +5 -1
- package/src/surfaces/panel-stylebook-layers.json +1 -1
- package/src/surfaces/panel-stylebook-layers.ts +2 -2
- package/src/surfaces/preferences.json +21 -8
- package/src/surfaces/preferences.ts +9 -1
- package/src/surfaces/properties-panel.json +4 -4
- package/src/surfaces/properties-panel.ts +2 -2
- package/src/surfaces/publish.json +1 -1
- package/src/surfaces/publish.ts +2 -1
- package/src/surfaces/push-plan.json +4 -3
- package/src/surfaces/rail.json +2 -2
- package/src/surfaces/rail.ts +10 -4
- package/src/surfaces/reference-field.json +1 -1
- package/src/surfaces/schema-form.json +2 -2
- package/src/surfaces/schema-form.ts +1 -1
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +2 -2
- package/src/surfaces/settings-contributed.ts +2 -1
- package/src/surfaces/settings-css-vars.json +4 -4
- package/src/surfaces/settings-deploy.json +4 -4
- package/src/surfaces/settings-deploy.ts +2 -1
- package/src/surfaces/settings-extensions.json +6 -6
- package/src/surfaces/settings-extensions.ts +6 -2
- package/src/surfaces/settings-locales.json +4 -4
- package/src/surfaces/settings-overview.ts +2 -1
- package/src/surfaces/settings-pane.ts +3 -2
- package/src/surfaces/settings-rawjson.ts +1 -1
- package/src/surfaces/slash-menu.ts +4 -4
- package/src/surfaces/statements.json +3 -3
- package/src/surfaces/statusbar.ts +23 -23
- package/src/surfaces/style-panel.json +9 -5
- package/src/surfaces/style-panel.ts +3 -3
- package/src/surfaces/tab-strip.json +2 -2
- package/src/surfaces/target-line.json +1 -1
- package/src/surfaces/target-line.ts +12 -10
- package/src/surfaces/welcome.json +7 -2
- package/src/tabs/doc-op-apply.ts +5 -5
- package/src/tabs/patch-ops.ts +3 -3
- package/src/tabs/project-config.ts +10 -10
- package/src/tabs/selection.ts +1 -1
- package/src/tabs/tab.ts +13 -14
- package/src/tabs/transact.ts +18 -24
- package/src/types.ts +27 -3
- package/src/ui/ai-credentials-form.ts +74 -16
- package/src/ui/ai-managed-connect.ts +68 -19
- package/src/ui/color-selector.ts +1 -1
- package/src/ui/expression-editor.ts +3 -3
- package/src/ui/form-controls.ts +6 -5
- package/src/ui/formula-catalog.ts +4 -4
- package/src/ui/formula-chips.ts +2 -2
- package/src/ui/layers.ts +20 -18
- package/src/ui/panel-resize.ts +8 -28
- package/src/ui/popover-surface.ts +2 -2
- package/src/ui/progress-modal.ts +3 -3
- package/src/ui/regions.ts +14 -9
- package/src/ui/schema-form.ts +10 -9
- package/src/ui/timing.ts +9 -7
- package/src/ui/value-source.ts +4 -4
- package/src/ui/virtual-window.ts +58 -5
- package/src/utils/base64.ts +20 -1
- package/src/utils/canvas-media.ts +1 -1
- package/src/utils/studio-utils.ts +0 -31
- package/src/view.ts +4 -3
- package/src/workspace/pane-derive.ts +14 -13
- package/src/workspace/session.ts +7 -6
- package/src/workspace/workspace.ts +49 -39
- package/styles/canvas.css +1 -27
- package/styles/inspector.css +4 -3
- package/styles/overlays.css +1 -1
- package/styles/tokens.css +17 -1
- package/styles/tokens.json +6 -1
- package/dist/chunks/entry-commands-w9qsxa6q.js +0 -42
- package/dist/chunks/layers-panel-fksbdg4q.js +0 -40
- package/dist/chunks/publish-panel-vz23wwmg.js +0 -27
- package/dist/chunks/quick-search-e9rp74m8.js +0 -46
- package/dist/chunks/right-panel-j97t2yvy.js +0 -45
- package/dist/chunks/studio-727xh0e3.js +0 -76
- package/src/files/json-layout.ts +0 -474
- package/src/services/ai-turn-signal.ts +0 -70
package/src/panels/i18n-panel.ts
CHANGED
|
@@ -96,7 +96,8 @@ export interface ParityRow {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* The directories a translation can live in — the two layouts §13 defines, and
|
|
99
|
+
* The directories a translation can live in — the two layouts site-architecture.md §13 defines, and
|
|
100
|
+
* nothing else.
|
|
100
101
|
*
|
|
101
102
|
* Not `projectState.projectDirs`: `layouts/` and `components/` are shared by every locale and
|
|
102
103
|
* `public/` is not addressable per language, so scanning them would fill the grid with rows whose
|
|
@@ -239,9 +240,10 @@ export function parityRows(
|
|
|
239
240
|
const byKey = new Map<string, Map<string, LibraryFile>>();
|
|
240
241
|
/*
|
|
241
242
|
* A document's own `$translationKey` overrides the one its path implies, exactly as it does in
|
|
242
|
-
* the build (§13.5) — which is what makes a localized slug one row instead
|
|
243
|
-
* ones. Prefixed with the directory the derivation would have produced, so the
|
|
244
|
-
* a declared key is route-shaped (`about`) and this grid is file-shaped
|
|
243
|
+
* the build (site-architecture.md §13.5) — which is what makes a localized slug one row instead
|
|
244
|
+
* of two half-empty ones. Prefixed with the directory the derivation would have produced, so the
|
|
245
|
+
* two spellings meet: a declared key is route-shaped (`about`) and this grid is file-shaped
|
|
246
|
+
* (`pages/about.json`).
|
|
245
247
|
*/
|
|
246
248
|
/* Every key the paths alone produce, so a declared one can be matched against a real file rather
|
|
247
249
|
than against a spelling. */
|
|
@@ -65,7 +65,7 @@ export type { ElementsEntry } from "../files/elements";
|
|
|
65
65
|
/* `componentSpecifier` and `isComponentEnabled` are `files/elements.ts`'s `npmSpecifier` and
|
|
66
66
|
`hasElement`. They lived here and answered only for the two checkboxes in this file; the picker
|
|
67
67
|
below and the canvas drop each asked the question their own way and got different answers
|
|
68
|
-
(
|
|
68
|
+
(§9.1.3). One rule, four call sites. */
|
|
69
69
|
|
|
70
70
|
// ─── The panel's own state ───────────────────────────────────────────────────
|
|
71
71
|
|
package/src/panels/jump-bar.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* The jump bar — the pane's address, and every place you can go from it.
|
|
4
4
|
*
|
|
5
5
|
* **The two half-breadcrumbs this replaces.** Studio grew two trails, neither of which could say
|
|
6
6
|
* where you were:
|
|
7
7
|
*
|
|
8
|
-
* 1. `panels/pane-context.ts`'s `navTpl()` (the old `#tab-bar` breadcrumb,
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
8
|
+
* 1. `panels/pane-context.ts`'s `navTpl()` (the old `#tab-bar` breadcrumb, `tab-bar.ts:129-185`) — a
|
|
9
|
+
* `Back` button plus one span per `session.documentStack` frame. It appeared ONLY while you were
|
|
10
|
+
* inside a sub-document, printed the frame's file basename (which is the SAME basename for a
|
|
11
|
+
* `$map` template, so it read `index.json › index.json`), and knew nothing about the project
|
|
12
|
+
* above it or the selection below it. It is deleted, and so is the stack it walked: nothing ever
|
|
13
|
+
* pushed a frame, so it could only ever draw its empty branch.
|
|
14
14
|
* 2. `surfaces/statusbar.ts`'s selection field — a clickable ancestor trail, `selection.set` per
|
|
15
15
|
* crumb. It appeared ONLY while something was selected, and knew nothing about the document it
|
|
16
16
|
* was inside.
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
* project file selection ancestors
|
|
24
24
|
* ```
|
|
25
25
|
*
|
|
26
|
-
* **The status bar keeps only what an address cannot say.**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
26
|
+
* **The status bar keeps only what an address cannot say.** `studio.md` §16.2 gives the bar AMBIENT
|
|
27
|
+
* STATE, and an ancestor trail in a second place is exactly the duplication the shell redesign
|
|
28
|
+
* exists to remove — three breadcrumbs would be worse than the two we started with. So the trail
|
|
29
|
+
* moves here whole, and `statusbar/selection` keeps the two facts this bar cannot state: HOW MANY
|
|
30
|
+
* things are selected (a count is not a path) and which Stylebook rule the Style panel is editing
|
|
31
|
+
* (a selector is not a node).
|
|
32
32
|
*
|
|
33
33
|
* **Every interactive item is a command, resolved from the registry.** There is no click handler in
|
|
34
34
|
* this file that names behaviour: a segment names a command id and its args, and the registry
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
* (studio-ui-guidelines.md §6, §9.3). What stays here is the part that is a decision: which pane
|
|
48
48
|
* this bar is about, what its address is, which of its steps the registry can run, and what a
|
|
49
49
|
* chevron opens — and the chevron opens the KIT MENU, `surfaces/menu.ts`, because a list of
|
|
50
|
-
* commands is what that surface already is (§12.5).
|
|
50
|
+
* commands is what that surface already is (studio-ui-guidelines.md §12.5).
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
53
|
import { displayTagName } from "@jxsuite/schema/guards";
|
|
@@ -81,7 +81,8 @@ const JUMP_BAR_HEIGHT = 24;
|
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* What a segment addresses. The kind is stamped on the element so a test — and a shot — can name a
|
|
84
|
-
* step of the address without matching its rendered text, which is derived (
|
|
84
|
+
* step of the address without matching its rendered text, which is derived (the shot contract's R1,
|
|
85
|
+
* `scripts/screenshots/README.md`).
|
|
85
86
|
*/
|
|
86
87
|
export type JumpSegmentKind = "project" | "file" | "editor" | "node";
|
|
87
88
|
|
|
@@ -301,7 +302,7 @@ export function jumpSegments(
|
|
|
301
302
|
function editorSegment(sigil: string, def: FunctionEditDef | FormulaEditDef): JumpSegment {
|
|
302
303
|
return {
|
|
303
304
|
choices: [],
|
|
304
|
-
// No command, and none is missing: the Logic tab's own header carries the Close (
|
|
305
|
+
// No command, and none is missing: the Logic tab's own header carries the Close (§16.3), which
|
|
305
306
|
// Is where a reader looking at the editor already is. A second exit up here would be a button
|
|
306
307
|
// Beside the address that means "stop being at this address" — and the pane context bar drew
|
|
307
308
|
// Exactly that, a Back of its own, until this excision removed it.
|
|
@@ -350,7 +351,7 @@ function segmentTitle(registry: CommandRegistry, segment: JumpSegment, id: strin
|
|
|
350
351
|
*
|
|
351
352
|
* An unregistered or invisible command makes the step a READOUT rather than removing it, and more
|
|
352
353
|
* than one alternative is what earns a chevron: one is not a choice, and a control that cannot move
|
|
353
|
-
* is chrome (§2
|
|
354
|
+
* is chrome (studio-ui-guidelines.md §12.2).
|
|
354
355
|
*/
|
|
355
356
|
function projectStep(
|
|
356
357
|
registry: CommandRegistry | null,
|
|
@@ -411,7 +412,8 @@ export function dismissJumpMenu(): void {
|
|
|
411
412
|
* The rows are built from the segment's choices, and every row runs a command — the same command
|
|
412
413
|
* the segment itself names, with a different path. Nothing here decides what selecting means, and
|
|
413
414
|
* nothing here draws a panel: `surfaces/menu.ts` owns the roving caret, typeahead, Escape and light
|
|
414
|
-
* dismissal, because a list of commands is what that surface already is
|
|
415
|
+
* dismissal, because a list of commands is what that surface already is: a second one is the defect
|
|
416
|
+
* studio-ui-guidelines.md §12.5 names.
|
|
415
417
|
*/
|
|
416
418
|
function openChoices(segment: JumpSegment, anchor: HTMLElement | null): void {
|
|
417
419
|
const registry = activeRegistry();
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
*
|
|
17
17
|
* **Rows are `registry.forPlacement("outline/row")`.** Every row used to carry five hand-built
|
|
18
18
|
* action buttons, always visible, on every row. They collapse to the selected row plus the hovered
|
|
19
|
-
* one, which is Gutenberg's rule and the one
|
|
20
|
-
* selection-scoped verbs, the inspector owns values. The verbs, their names, their chords
|
|
21
|
-
* disabled reasons all come from the records in `block-action-bar.ts` — the surface
|
|
22
|
-
* does not decide. A row that is neither selected nor hovered is projected with an
|
|
23
|
-
* list, so the cluster costs nothing rather than being hidden by a rule: a `display:
|
|
24
|
-
* element is still an upgraded custom element, which is the whole cost the collapse
|
|
25
|
-
* remove.
|
|
19
|
+
* one, which is Gutenberg's rule and the one studio-ui-guidelines.md §12.1 codifies: the floating
|
|
20
|
+
* bar owns selection-scoped verbs, the inspector owns values. The verbs, their names, their chords
|
|
21
|
+
* and their disabled reasons all come from the records in `block-action-bar.ts` — the surface
|
|
22
|
+
* renders, it does not decide. A row that is neither selected nor hovered is projected with an
|
|
23
|
+
* EMPTY command list, so the cluster costs nothing rather than being hidden by a rule: a `display:
|
|
24
|
+
* none` kit element is still an upgraded custom element, which is the whole cost the collapse
|
|
25
|
+
* exists to remove.
|
|
26
26
|
*
|
|
27
27
|
* **A row says something.** On a real page the tree was a wall of rows all reading "div": only
|
|
28
28
|
* text-bearing nodes got a preview and containers got the tag they already wear as a coloured
|
|
@@ -504,7 +504,8 @@ function selectModelRow(index: number, gesture: { range?: boolean } = {}): void
|
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
/**
|
|
507
|
-
* Apply one row activation to the selection, honouring the two accumulate gestures
|
|
507
|
+
* Apply one row activation to the selection, honouring the two accumulate gestures
|
|
508
|
+
* (studio-ui-guidelines.md §8.1).
|
|
508
509
|
*
|
|
509
510
|
* - Plain: replace the selection with this path. **This is the only branch a keyboard walk or an
|
|
510
511
|
* unmodified click can reach, and it is byte-identical to what the Outline always did.**
|
|
@@ -1254,9 +1255,10 @@ export function mountOutlinePanel(
|
|
|
1254
1255
|
editInput,
|
|
1255
1256
|
editReady: (element) => {
|
|
1256
1257
|
/* On a microtask, because `onNodeCreated` fires as the node is BUILT and one tick before
|
|
1257
|
-
it is in the document — which is exactly why it is the seam
|
|
1258
|
-
hands over the element earlier than awaiting the
|
|
1259
|
-
when it is worth anything. An unconnected input
|
|
1258
|
+
it is in the document — which is exactly why it is the seam
|
|
1259
|
+
(studio-ui-guidelines.md §9.4): it hands over the element earlier than awaiting the
|
|
1260
|
+
mount would, and the host decides when it is worth anything. An unconnected input
|
|
1261
|
+
cannot take focus. */
|
|
1260
1262
|
queueMicrotask(() => {
|
|
1261
1263
|
const input = element as HTMLInputElement;
|
|
1262
1264
|
if (input.isConnected) {
|
|
@@ -1267,10 +1269,10 @@ export function mountOutlinePanel(
|
|
|
1267
1269
|
},
|
|
1268
1270
|
expand: expandOutlineRow,
|
|
1269
1271
|
emptyAction: () => {
|
|
1270
|
-
/* `"insert"`, not `"blocks"`. The panel was renamed
|
|
1271
|
-
for three phases, so the one action an empty page offers
|
|
1272
|
-
Navigator panel is registered as blocks". `setActivityTab`
|
|
1273
|
-
now, so this cannot recur. */
|
|
1272
|
+
/* `"insert"`, not `"blocks"`. The panel was renamed with the registry-driven rail (§5.1),
|
|
1273
|
+
and this call kept the old id for three phases, so the one action an empty page offers
|
|
1274
|
+
landed the Navigator on "No Navigator panel is registered as blocks". `setActivityTab`
|
|
1275
|
+
takes a `NavigatorPanelId` now, so this cannot recur. */
|
|
1274
1276
|
setActivityTab("insert");
|
|
1275
1277
|
},
|
|
1276
1278
|
hover: hoverRow,
|
|
@@ -1350,8 +1352,8 @@ export function detachOutline(): void {
|
|
|
1350
1352
|
* Contribute the Outline panel.
|
|
1351
1353
|
*
|
|
1352
1354
|
* `level: "document"` — it writes the open document's tree (reorder, rename, delete, duplicate).
|
|
1353
|
-
* "Outline" rather than "Layers" is §
|
|
1354
|
-
*
|
|
1355
|
+
* "Outline" rather than "Layers" is §5.1's name for it; the id stays `layers` because that is what
|
|
1356
|
+
* `view.setActivity` and 26 screenshot steps address it by, and an id is not a label.
|
|
1355
1357
|
*/
|
|
1356
1358
|
export function registerLayersPanel(): void {
|
|
1357
1359
|
registerPanel({
|
package/src/panels/left-panel.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* no-document copy table and the two post-render special cases are gone: this file resolves ONE
|
|
7
7
|
* record from the panel registry, hands the document its name and its level, renders its `render`
|
|
8
8
|
* into the content island, and calls its `afterRender`. Everything a panel is — its name, its
|
|
9
|
-
* level, its empty state, its drag registrations — is declared beside the state it writes (
|
|
10
|
-
*
|
|
9
|
+
* level, its empty state, its drag registrations — is declared beside the state it writes (one
|
|
10
|
+
* definition site per action, studio.md §13).
|
|
11
11
|
*
|
|
12
12
|
* **The box is `surfaces/navigator-dock.json` now, and the body is still lit.** A `PanelRecord`'s
|
|
13
13
|
* `render` returns a lit template, so the panel body cannot be a document; the dock draws the
|
|
@@ -108,7 +108,7 @@ export function mount(deps: NavigatorPanelDeps) {
|
|
|
108
108
|
void tab.doc.document;
|
|
109
109
|
void tab.doc.mode;
|
|
110
110
|
// The whole SET, joined — a bare property read would not re-trigger when the selection
|
|
111
|
-
// Changes WITHIN the array, and §6.
|
|
111
|
+
// Changes WITHIN the array, and §6.7's helpers always replace it but nothing enforces that.
|
|
112
112
|
void tab.session.selection.map((path) => path.join("/")).join("|");
|
|
113
113
|
}
|
|
114
114
|
render();
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
* advertisement, in the shell's own furniture, for a place to find things wrong with the product.
|
|
17
17
|
* The count reaches the user from the status bar the moment there is one.
|
|
18
18
|
*
|
|
19
|
-
* **Search is declared and hidden.** It is a surface a later phase builds (
|
|
20
|
-
* and it holds a
|
|
21
|
-
* to say "this exists in the design and not yet in the
|
|
22
|
-
* counts it, and the day it ships the only edit is
|
|
23
|
-
* button that lies to whoever clicks it.
|
|
19
|
+
* **Search is declared and hidden.** It is a surface a later phase builds (the palette's project
|
|
20
|
+
* index), and it holds a slot in the rail's four-tab budget (`studio-ui-guidelines.md` §12.2). A
|
|
21
|
+
* `when: () => false` record is the honest way to say "this exists in the design and not yet in the
|
|
22
|
+
* app": the id is reserved, the budget already counts it, and the day it ships the only edit is
|
|
23
|
+
* deleting one predicate — as opposed to a stub button that lies to whoever clicks it.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { registerFilesPanel } from "../files/files";
|
|
@@ -79,11 +79,11 @@ export function registerNavigatorPanels(): void {
|
|
|
79
79
|
// ── Off-rail: reachable by command and palette, no rail button ──────────────
|
|
80
80
|
registerInsertPanel();
|
|
81
81
|
|
|
82
|
-
// ── The Bottom dock's tabs (§3
|
|
82
|
+
// ── The Bottom dock's tabs (§16.3): Problems · Logic · Activity ──────────────
|
|
83
83
|
// Composed here, in the one place panel records are gathered, so the shell has ONE composition
|
|
84
84
|
// Site rather than one per dock. Importing the module is also what attaches the dock to the
|
|
85
|
-
// Shell's mount lifecycle — see its `registerShellSurface` call. Problems arrives with them and
|
|
86
|
-
//
|
|
85
|
+
// Shell's mount lifecycle — see its `registerShellSurface` call. Problems arrives with them and,
|
|
86
|
+
// Like every Bottom-dock tab, has no rail button (§16.3).
|
|
87
87
|
registerBottomPanels();
|
|
88
88
|
}
|
|
89
89
|
|
package/src/panels/overlays.ts
CHANGED
|
@@ -42,7 +42,7 @@ export function mount(ctx: OverlaysCtx) {
|
|
|
42
42
|
// Track selection, hover, mode, and the active panel (a hit in another breakpoint panel — or
|
|
43
43
|
// A header click — re-anchors the block action bar even when the selection path is unchanged).
|
|
44
44
|
// The whole SET, joined — a bare property read would not re-trigger when the selection
|
|
45
|
-
// Changes WITHIN the array, and §6.
|
|
45
|
+
// Changes WITHIN the array, and §6.7's helpers always replace it but nothing enforces that.
|
|
46
46
|
void tab.session.selection.map((path) => path.join("/")).join("|");
|
|
47
47
|
void tab.session.hover;
|
|
48
48
|
void tab.doc.mode;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
* The pane's own chrome —
|
|
3
|
+
* The pane's own chrome — the pane context bar and the floating zoom pod.
|
|
4
4
|
*
|
|
5
5
|
* This replaces `#tab-bar`, which was a 28px band styled identically to the tab strip above it,
|
|
6
6
|
* holding **five unrelated axes** with no labels on any of them: a document-stack breadcrumb
|
|
7
7
|
* (navigation), a zoom widget (viewport), route params and component test props (document data), a
|
|
8
|
-
* colour-scheme switch and feature toggles (rendering state), and Export (a mode action).
|
|
9
|
-
*
|
|
8
|
+
* colour-scheme switch and feature toggles (rendering state), and Export (a mode action). The pane
|
|
9
|
+
* context bar replaces them with three axes that each say what they are:
|
|
10
10
|
*
|
|
11
11
|
* - **Editor kind** — `Canvas ⌄`, offering only the kinds this document declares. A document with one
|
|
12
12
|
* kind renders the name as text rather than as a dropdown that cannot go anywhere.
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* Canvas. The two are drawn apart because they are two axes: preview is a flag over an edit or
|
|
16
16
|
* design base, so the radio marks the base throughout and the toggle says whether it is on.
|
|
17
17
|
* - **Rendering context** — `md ⌄ Light ⌄`, folding the size breakpoint, the colour scheme, the
|
|
18
|
-
* feature queries and the layout show/hide switch into one popover. Per §2
|
|
19
|
-
* control **only selects**; its footer is "Manage contexts…", which routes to
|
|
20
|
-
* — Project Settings › Contexts (`settings/contexts-section.ts`), the one
|
|
21
|
-
* colour scheme or a feature query is defined.
|
|
18
|
+
* feature queries and the layout show/hide switch into one popover. Per §6.2 ("The breakpoint and
|
|
19
|
+
* scheme axes") this control **only selects**; its footer is "Manage contexts…", which routes to
|
|
20
|
+
* the definition site — Project Settings › Contexts (`settings/contexts-section.ts`), the one
|
|
21
|
+
* place a breakpoint, a colour scheme or a feature query is defined.
|
|
22
22
|
* - **Resolving with** — the document DATA a render resolves against: a page's route params, a
|
|
23
23
|
* component's test props. Its own popover beside the context one, headed "resolving with", with
|
|
24
24
|
* the fields in a vertical stack. A SECOND popover rather than a fourth group in the first,
|
|
@@ -34,12 +34,13 @@
|
|
|
34
34
|
* **The bar is not a grid row.** It renders inside the pane's own cell (`#pane-chrome`, stacked
|
|
35
35
|
* over `#canvas-wrap`), because a per-pane surface cannot be a row of the application grid — the
|
|
36
36
|
* second pane would have no way to have one. The stage is offset by {@link PANE_CONTEXT_VAR} rather
|
|
37
|
-
* than by a track, and the zoom pod floats bottom-right over the canvas
|
|
37
|
+
* than by a track, and the zoom pod floats bottom-right over the canvas, as
|
|
38
|
+
* `docs/studio/interface/tabs.md` ("The pane context bar") describes it.
|
|
38
39
|
*
|
|
39
40
|
* **The read-only banner rides with the bar.** `collab/collab-state.ts` says whether a guest may
|
|
40
|
-
* write (§
|
|
41
|
-
* per-document chrome that sits directly above the editing surface. It is stacked under
|
|
42
|
-
* inside the document's `[part="band"]` and the offset is MEASURED from that band
|
|
41
|
+
* write (`collab.md` §4); the surface that owes them the sentence is this one, because it is the
|
|
42
|
+
* per-pane, per-document chrome that sits directly above the editing surface. It is stacked under
|
|
43
|
+
* the bar inside the document's `[part="band"]` and the offset is MEASURED from that band
|
|
43
44
|
* ({@link applyPaneContextOffset}), so a two-line banner pushes the stage down instead of covering
|
|
44
45
|
* the document it is warning you about.
|
|
45
46
|
*/
|
|
@@ -66,6 +67,9 @@ import {
|
|
|
66
67
|
import { openMenu } from "../surfaces/menu";
|
|
67
68
|
import { emptyPaneContextView, mountPaneContextSurface } from "../surfaces/pane-context";
|
|
68
69
|
import { PANE_SELECTOR } from "../surfaces/pane-grid";
|
|
70
|
+
import { diffShowsCode } from "../canvas/diff-view";
|
|
71
|
+
import { canRenderComparison } from "./git-diff-open";
|
|
72
|
+
import { shell } from "../shell";
|
|
69
73
|
import { paneRegion } from "../ui/regions";
|
|
70
74
|
import {
|
|
71
75
|
fitToScreen,
|
|
@@ -268,9 +272,9 @@ export function mount(host: HTMLElement, ctx: PaneContextCtx) {
|
|
|
268
272
|
void tab.session.ui.previewProps;
|
|
269
273
|
void tab.session.ui.showLayout;
|
|
270
274
|
void tab.session.ui.zoom;
|
|
271
|
-
// The read-only banner (§
|
|
272
|
-
//
|
|
273
|
-
//
|
|
275
|
+
// The read-only banner (`collab.md` §4) is part of this chrome, so its two facts are
|
|
276
|
+
// Tracked here too: a peer downgrading you mid-session must make the sentence appear, not
|
|
277
|
+
// Wait for the next zoom.
|
|
274
278
|
void collabState(tab).active;
|
|
275
279
|
void collabState(tab).readOnly;
|
|
276
280
|
}
|
|
@@ -322,7 +326,7 @@ export function applyPaneContextOffset(height: number, host?: HTMLElement | null
|
|
|
322
326
|
*
|
|
323
327
|
* The band is the DOCUMENT's, handed back by the mount rather than found by selector — a surface
|
|
324
328
|
* that re-queries its own markup is holding a node that the next render may already have replaced
|
|
325
|
-
* (guidelines §9.4).
|
|
329
|
+
* (`studio-ui-guidelines.md` §9.4).
|
|
326
330
|
*/
|
|
327
331
|
function topBandHeight(surface: PaneContextSurfaceHandle): number {
|
|
328
332
|
return Math.max(surface.band()?.offsetHeight ?? 0, PANE_CONTEXT_HEIGHT);
|
|
@@ -416,7 +420,7 @@ export function dismissPresetMenu(): void {
|
|
|
416
420
|
*
|
|
417
421
|
* **It is the kit menu, not a second one.** `surfaces/menu.ts` already owns roving focus,
|
|
418
422
|
* typeahead, light dismissal, the disabled row's `requires` sentence and the Escape that closes it
|
|
419
|
-
* (guidelines §12.5); this hands it rows.
|
|
423
|
+
* (`studio-ui-guidelines.md` §12.5); this hands it rows.
|
|
420
424
|
*/
|
|
421
425
|
function openPresetMenu(paneId: string, anchor: HTMLElement): void {
|
|
422
426
|
dismissPresetMenu();
|
|
@@ -617,13 +621,13 @@ export function presetRows(paneId: string): PresetRow[] {
|
|
|
617
621
|
* Everything one pane's chrome draws, as words and keyed rows.
|
|
618
622
|
*
|
|
619
623
|
* There is no takeover branch. Opening a function body or a formula reveals the dock's Logic tab
|
|
620
|
-
* (
|
|
621
|
-
* stage and the zoom pod still has something to zoom. Suppressing them while the dock was open
|
|
624
|
+
* (§16.3) and leaves the canvas standing underneath it, so the axes still describe the document on
|
|
625
|
+
* the stage and the zoom pod still has something to zoom. Suppressing them while the dock was open
|
|
622
626
|
* removed the controls for the very document the reader could still see.
|
|
623
627
|
*
|
|
624
|
-
* **There is no breadcrumb either.** The address is
|
|
625
|
-
* and the Logic tab's own header carries the Close. This bar drew a second Back and a
|
|
626
|
-
* beside both of them.
|
|
628
|
+
* **There is no breadcrumb either.** The address is the jump bar's job — `panels/jump-bar.ts`, one
|
|
629
|
+
* row above — and the Logic tab's own header carries the Close. This bar drew a second Back and a
|
|
630
|
+
* second trail beside both of them.
|
|
627
631
|
*/
|
|
628
632
|
function viewFor(tab: Tab, paneId: string, ctx: PaneContextCtx): PaneContextView {
|
|
629
633
|
/* A LENS suppresses the two axes that WRITE. Editor kind and Canvas view both land in
|
|
@@ -802,9 +806,9 @@ interface PaneLocale {
|
|
|
802
806
|
* and "groups a document declares nothing for are absent" is the rule the whole popover follows.
|
|
803
807
|
*
|
|
804
808
|
* The fallback chain is what makes the control honest about a file it has not been told about:
|
|
805
|
-
* `previewLocale` is the author's explicit choice, the path is the file's own language
|
|
806
|
-
* a translation in its own directory), and the default locale is
|
|
807
|
-
* as.
|
|
809
|
+
* `previewLocale` is the author's explicit choice, the path is the file's own language
|
|
810
|
+
* (`site-architecture.md` §13.3 puts a translation in its own directory), and the default locale is
|
|
811
|
+
* what an unprefixed page renders as.
|
|
808
812
|
*/
|
|
809
813
|
function localeOf(tab: Tab | null): PaneLocale | null {
|
|
810
814
|
const i18n = getEffectiveLocales();
|
|
@@ -949,7 +953,7 @@ function localeGroup(locale: PaneLocale | null): Partial<PaneContextView> {
|
|
|
949
953
|
};
|
|
950
954
|
}
|
|
951
955
|
|
|
952
|
-
// ───
|
|
956
|
+
// ─── The floating zoom pod ───────────────────────────────────────────────────
|
|
953
957
|
|
|
954
958
|
/** The fit entries the pod offers, in menu order. `1` is "actual size", a numeric fit. */
|
|
955
959
|
const FIT_CHOICES: readonly { value: string; fit: FitMode; label: string }[] = [
|
|
@@ -970,13 +974,28 @@ function fitChoiceValue(fit: FitMode): string {
|
|
|
970
974
|
/** The modes whose stage is the panzoom surface — the only ones with a fit to state. */
|
|
971
975
|
const STAGE_ZOOM_MODES = new Set(["design", "stylebook", "git-diff"]);
|
|
972
976
|
|
|
977
|
+
/**
|
|
978
|
+
* The path this pane is comparing, or "" before it has a comparison.
|
|
979
|
+
*
|
|
980
|
+
* Resolved exactly as `canvas-render.ts`'s git-diff branch resolves the comparison it draws: a Diff
|
|
981
|
+
* lens carries its own, and every other pane draws the Source Control panel's one app-level slot.
|
|
982
|
+
* Both halves are reactive, so the pod repaints when either one lands or retargets.
|
|
983
|
+
*/
|
|
984
|
+
function comparisonPathOf(paneId: string): string {
|
|
985
|
+
const derived = derivationOfPane(paneId);
|
|
986
|
+
const state =
|
|
987
|
+
derived?.kind === "lens" && derived.preset === "diff" ? derived.diff : shell.git.diffState;
|
|
988
|
+
return state?.filePath ?? "";
|
|
989
|
+
}
|
|
990
|
+
|
|
973
991
|
/**
|
|
974
992
|
* Zoom and fit, floating over the canvas bottom-right.
|
|
975
993
|
*
|
|
976
994
|
* Two surfaces, one control: `edit` drives the content-reflow `editZoom`, while design / Stylebook
|
|
977
995
|
* / git-diff render on the panzoom surface and drive `ui.zoom` — and only the panzoom surface has a
|
|
978
996
|
* fit, because a fit is a statement about an artboard. Preview is deliberately absent: its frame is
|
|
979
|
-
* a real viewport that scrolls its own document, so there is nothing to zoom.
|
|
997
|
+
* a real viewport that scrolls its own document, so there is nothing to zoom. So is a comparison's
|
|
998
|
+
* CODE half, for the same reason: see below.
|
|
980
999
|
*/
|
|
981
1000
|
function podFor(tab: Tab, paneId: string): Partial<PaneContextView> {
|
|
982
1001
|
/* THIS pane's mode. `ctx.getCanvasMode()` answers for the focused pane, so the unfocused pod
|
|
@@ -993,6 +1012,15 @@ function podFor(tab: Tab, paneId: string): Partial<PaneContextView> {
|
|
|
993
1012
|
if (!STAGE_ZOOM_MODES.has(mode)) {
|
|
994
1013
|
return { podState: "hidden" };
|
|
995
1014
|
}
|
|
1015
|
+
/* NO POD OVER A COMPARISON'S CODE HALF. That half is one Monaco diff editor filling the stage,
|
|
1016
|
+
with no panzoom surface under it, so `applyTransform` and `resetZoom` return early and + / − /
|
|
1017
|
+
100% / Fit moved nothing but their own label. And it sat on Monaco's own scrollbar and diff
|
|
1018
|
+
overview ruler at the stage's right edge, which no native measurement can see. The predicate is
|
|
1019
|
+
the one the renderer chose the half with, so the two cannot disagree; `diff-view.ts` is not
|
|
1020
|
+
reactive, so the Visual/Code switch repaints this chrome itself (`diff-toolbar.ts`). */
|
|
1021
|
+
if (mode === "git-diff" && diffShowsCode(paneId, canRenderComparison(comparisonPathOf(paneId)))) {
|
|
1022
|
+
return { podState: "hidden" };
|
|
1023
|
+
}
|
|
996
1024
|
const zoom = stageZoom(surface);
|
|
997
1025
|
return {
|
|
998
1026
|
fitOptions: FIT_CHOICES.map(({ label, value }) => ({ label, value })),
|
|
@@ -1011,7 +1039,7 @@ function podFor(tab: Tab, paneId: string): Partial<PaneContextView> {
|
|
|
1011
1039
|
* These four controls wrote `session.ui` directly through `updateUi`, which is why none of the
|
|
1012
1040
|
* three axes was a command: the popover WAS the capability, and the palette, the assistant and
|
|
1013
1041
|
* `__jxAutomation` had no name for it. Going through the registry makes the control and the verb
|
|
1014
|
-
* one thing (
|
|
1042
|
+
* one thing (one definition site per action, §13) and gets the breakpoint refusal for free.
|
|
1015
1043
|
*/
|
|
1016
1044
|
function runContextCommand(paneId: string, id: string, args: Record<string, unknown>): void {
|
|
1017
1045
|
// THIS pane, named. The bar is drawn once per pane and the side bar's controls write the side
|
|
@@ -1161,7 +1189,7 @@ export function isResolvingOpen(paneId: string): boolean {
|
|
|
1161
1189
|
* Open or close it.
|
|
1162
1190
|
*
|
|
1163
1191
|
* A named end state rather than a toggle, so `canvas.setResolvingOpen { open: false }` means the
|
|
1164
|
-
* same thing twice and a screenshot can photograph it (
|
|
1192
|
+
* same thing twice and a screenshot can photograph it (R1, `scripts/screenshots/README.md`).
|
|
1165
1193
|
*
|
|
1166
1194
|
* It writes the panel and does NOT re-project the bar. A popover moves into the top layer while it
|
|
1167
1195
|
* is open; nothing about the bar changes when it does, and the only thing the bar redraws for is
|
package/src/panels/pane-grid.ts
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The pane grid — `workspace.panes`, given a visual counterpart.
|
|
4
4
|
*
|
|
5
|
-
* `workspace.panes` has been a real data model since
|
|
6
|
-
* unsplit. Nothing drew it. `index.html` declared ONE each of
|
|
7
|
-
* `#pane-chrome` and `#canvas-wrap` as flat siblings in `#app`'s grid —
|
|
8
|
-
* to a PANE, laid out as rows and columns of the APPLICATION — so the
|
|
9
|
-
* and had somewhere to put exactly one. §18.3's stage handover was the
|
|
10
|
-
* by whichever pane had focus, releasing the loser's artboards on the
|
|
11
|
-
* that scaffolding was standing in for, and the handover is deleted
|
|
5
|
+
* `workspace.panes` has been a real data model since the shell redesign's chrome phase: an ordered
|
|
6
|
+
* list, a focused id, a split, an unsplit. Nothing drew it. `index.html` declared ONE each of
|
|
7
|
+
* `#tab-strip`, `#jump-bar`, `#pane-chrome` and `#canvas-wrap` as flat siblings in `#app`'s grid —
|
|
8
|
+
* four surfaces that belong to a PANE, laid out as rows and columns of the APPLICATION — so the
|
|
9
|
+
* shell could model two panes and had somewhere to put exactly one. §18.3's stage handover was the
|
|
10
|
+
* workaround: one stage, taken by whichever pane had focus, releasing the loser's artboards on the
|
|
11
|
+
* way past. This module is what that scaffolding was standing in for, and the handover is deleted
|
|
12
|
+
* with it.
|
|
12
13
|
*
|
|
13
14
|
* **The document owns the frame; this module owns the decisions.** `surfaces/pane-grid.json` is the
|
|
14
15
|
* cells, the five boxes inside each one, the splitter between two of them and every rule that lays
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
* `scale`, `min` and `max` closures that read `clientWidth` on every `pointermove` are gone, along
|
|
51
52
|
* with the window-resize staleness they were paying for.
|
|
52
53
|
*
|
|
53
|
-
* The
|
|
54
|
+
* The third rule of §18.1 — _a pane with nothing in it is a hole in the grid_ — is enforced in
|
|
54
55
|
* `workspace/workspace.ts`, where the tabs are. This module never repairs: repairing inside a
|
|
55
56
|
* reactive effect that writes `workspace.panes` is an effect that triggers itself.
|
|
56
57
|
*/
|
|
@@ -5,17 +5,18 @@
|
|
|
5
5
|
* A {@link PanelRecord} is to a surface what a `Command` is to an action: its name, the containment
|
|
6
6
|
* level of the state it WRITES, the dock that hosts it, the predicate that decides whether it
|
|
7
7
|
* exists at all, and the function that draws it. The rail, the panel header and the dock budget
|
|
8
|
-
* become RENDERINGS of these records —
|
|
8
|
+
* become RENDERINGS of these records — one definition site per action (§13), applied to regions
|
|
9
|
+
* rather than verbs.
|
|
9
10
|
*
|
|
10
11
|
* It mirrors the shipped `settings/settings-modal.ts` contribution point
|
|
11
12
|
* (`registerSettingsSection`) deliberately: a module-level `Map`, keyed by id, written by the
|
|
12
13
|
* module that OWNS the surface. The one thing it adds is the field that makes the rail derivable —
|
|
13
14
|
*
|
|
14
15
|
* **`level` is required, and it is the level of the state the panel WRITES, not the state it
|
|
15
|
-
* reads** (
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* reads** (§13.2). Insert reads the project's component registry and writes the document tree, so
|
|
17
|
+
* it is `document`. Files reads documents and writes project files, so it is `project`. That rule,
|
|
18
|
+
* and not intuition, is what settles every contested placement and what stops the rail
|
|
19
|
+
* re-accreting: the two rail groups are two rows of
|
|
19
20
|
* {@link
|
|
20
21
|
* import("../commands/levels").PANEL_PLACEMENT_MATRIX}, checked at registration exactly the
|
|
21
22
|
* way a command's `menus` are.
|
|
@@ -99,15 +100,16 @@ export interface NavigatorPanelDeps {
|
|
|
99
100
|
/**
|
|
100
101
|
* The focused document, as a document-level panel reads it. `null` when no tab is open.
|
|
101
102
|
*
|
|
102
|
-
* A `level: "project"` panel must not read this — that is
|
|
103
|
-
* the Source Control badge used to vanish when the last tab closed.
|
|
104
|
-
* enforce it (a closure's imports are not inspectable), so the contract
|
|
105
|
-
* by `tests/panel-registry.test.ts`, which renders every project-level
|
|
103
|
+
* A `level: "project"` panel must not read this — that is `studio-ui-guidelines.md` §12.1's closing
|
|
104
|
+
* rule, and the reason the Source Control badge used to vanish when the last tab closed.
|
|
105
|
+
* {@link registerPanel} cannot enforce it (a closure's imports are not inspectable), so the contract
|
|
106
|
+
* is stated here and asserted by `tests/panel-registry.test.ts`, which renders every project-level
|
|
107
|
+
* panel with `doc: null`.
|
|
106
108
|
*/
|
|
107
109
|
export interface NavigatorDocument {
|
|
108
110
|
document: JxMutableNode;
|
|
109
111
|
mode: string;
|
|
110
|
-
/** The whole selection SET the navigator/inspector panels render against (§6.
|
|
112
|
+
/** The whole selection SET the navigator/inspector panels render against (§6.7). */
|
|
111
113
|
selection: JxPath[];
|
|
112
114
|
canvas: Record<string, unknown> | null;
|
|
113
115
|
content?: { frontmatter?: Record<string, unknown> } | undefined;
|
|
@@ -131,8 +133,23 @@ export type PanelBody = TemplateResult | typeof nothing;
|
|
|
131
133
|
export interface PanelRecord {
|
|
132
134
|
/** Lowercase, stable, and the value `view.setActivity` accepts — renaming one is a shot break. */
|
|
133
135
|
id: string;
|
|
134
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* The human name, spelled once: the panel header, the rail button's accessible name and tooltip,
|
|
138
|
+
* the `Show …` command and the chrome-budget row. The rail prints it under the glyph too, unless
|
|
139
|
+
* {@link PanelRecord.railLabel} says otherwise.
|
|
140
|
+
*/
|
|
135
141
|
title: string;
|
|
142
|
+
/**
|
|
143
|
+
* The rail button's visible text, for a title too long to sit under the glyph.
|
|
144
|
+
*
|
|
145
|
+
* The stacked label box is 48px at `--jx-text-xs` (10px), and "Source Control" is 71px, so the
|
|
146
|
+
* kit's ellipsis drew it as "Source …". Absent: the rail prints `title`. It must be a LEADING
|
|
147
|
+
* part of `title`, because the button's accessible name stays the title and the words on screen
|
|
148
|
+
* must be inside it (WCAG 2.5.3 Label in Name; best practice is that they lead it).
|
|
149
|
+
* {@link registerPanel} throws otherwise. Not derived from the title's first word, which would
|
|
150
|
+
* turn "Project Styles" into "Project": a record that needs a short name says which one.
|
|
151
|
+
*/
|
|
152
|
+
railLabel?: string;
|
|
136
153
|
/** REQUIRED. The level of the state this panel WRITES. Checked against the panel matrix. */
|
|
137
154
|
level: Level;
|
|
138
155
|
dock: PanelDock;
|
|
@@ -146,9 +163,9 @@ export interface PanelRecord {
|
|
|
146
163
|
*
|
|
147
164
|
* Not a hiding mechanism — a rail-less panel is still reachable by `view.setActivity`, by the
|
|
148
165
|
* palette and by another surface linking to it. It is how a record survives the interval between
|
|
149
|
-
* losing its rail slot and gaining its real home (Insert
|
|
150
|
-
* into Data). Declaring it `false` also removes the panel's `rail/<level>`
|
|
151
|
-
* what keeps the rail inside its four-per-group budget.
|
|
166
|
+
* losing its rail slot and gaining its real home (Insert, reachable from the canvas and palette;
|
|
167
|
+
* State, folded into Data — §5.1). Declaring it `false` also removes the panel's `rail/<level>`
|
|
168
|
+
* placement, which is what keeps the rail inside its four-per-group budget.
|
|
152
169
|
*/
|
|
153
170
|
rail?: boolean;
|
|
154
171
|
/**
|
|
@@ -209,7 +226,8 @@ const PANEL_ID_PATTERN = /^[a-z][\w-]*$/;
|
|
|
209
226
|
const panelRegistry = new Map<string, PanelRecord>();
|
|
210
227
|
|
|
211
228
|
/**
|
|
212
|
-
* Define a panel. Throws on a duplicate id, a malformed id,
|
|
229
|
+
* Define a panel. Throws on a duplicate id, a malformed id, a matrix violation, or a `railLabel`
|
|
230
|
+
* that is not a leading part of the title.
|
|
213
231
|
*
|
|
214
232
|
* Failing at registration is the same bet `createCommandRegistry.register` makes: a misplaced
|
|
215
233
|
* surface is a design error, and a design error that only shows up as a wrong-looking rail is a
|
|
@@ -240,6 +258,16 @@ export function registerPanel(panel: PanelRecord): void {
|
|
|
240
258
|
const detail = violations.map((violation) => ` ✗ ${panel.id} ${violation.message}`).join("\n");
|
|
241
259
|
throw new Error(`Panel "${panel.id}" violates the level × placement matrix:\n${detail}`);
|
|
242
260
|
}
|
|
261
|
+
if (
|
|
262
|
+
panel.railLabel !== undefined &&
|
|
263
|
+
(panel.railLabel.trim() === "" || !panel.title.startsWith(panel.railLabel))
|
|
264
|
+
) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
`Panel "${panel.id}" declares railLabel "${panel.railLabel}", which is not a leading part ` +
|
|
267
|
+
`of its title "${panel.title}": the rail button's accessible name is the title, and the ` +
|
|
268
|
+
`words on screen must be inside it (WCAG 2.5.3, Label in Name).`,
|
|
269
|
+
);
|
|
270
|
+
}
|
|
243
271
|
panelRegistry.set(panel.id, panel);
|
|
244
272
|
}
|
|
245
273
|
|
|
@@ -287,10 +315,10 @@ const RAIL_GROUP_LEVELS: readonly { level: Level; label: string }[] = [
|
|
|
287
315
|
* Every panel that has a rail button, whatever dock draws its body.
|
|
288
316
|
*
|
|
289
317
|
* The rail is NOT the Navigator's tab strip. `panelPlacements()` has always awarded `rail/<level>`
|
|
290
|
-
* on `rail !== false` alone — the dock is a separate placement
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
318
|
+
* on `rail !== false` alone — the dock is a separate placement. Problems proved it for a release:
|
|
319
|
+
* its body is the Bottom dock's first tab, and it owned a rail slot and a badge until §16.3 took
|
|
320
|
+
* every Bottom-dock tab off the rail and put its count in the status bar. Filtering this by `dock
|
|
321
|
+
* === "navigator"` is what would put the same list in two hosts at once.
|
|
294
322
|
*/
|
|
295
323
|
function railablePanels(): readonly PanelRecord[] {
|
|
296
324
|
return listPanels().filter((panel) => panel.rail !== false);
|