@jxsuite/studio 6.1.2 → 8.0.1
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 +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/{color-area-0fj8a4ga.js → color-area-6rbra5dy.js} +2 -2
- package/dist/chunks/{color-field-xch8kx2g.js → color-field-gy56c94g.js} +3 -3
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/{color-slider-jxd8v350.js → color-slider-sqqdyf6c.js} +2 -2
- package/dist/chunks/{combobox-p0efwjke.js → combobox-72h32ejk.js} +3 -3
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/{grid-view-d2wq9ezg.js → grid-view-qg1b5eqx.js} +25 -25
- package/dist/chunks/{icons-pnfz478q.js → icons-63bjtbs7.js} +2 -2
- package/dist/chunks/{iframe-entry-jdcktez8.js → iframe-entry-2zggzajv.js} +4 -4
- package/dist/chunks/{iframe-entry-zap785cw.js → iframe-entry-76j8vwwx.js} +4 -4
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/{iframe-entry-x0ygf2yr.js → iframe-entry-pkgmcgp0.js} +4 -4
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-zpjmzqfk.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-m54mnwp6.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/{listbox-e74qjyq6.js → listbox-c421cf8c.js} +2 -2
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/{menu-n6yzswmy.js → menu-bdpzbfvs.js} +2 -2
- package/dist/chunks/{monaco-binding-7gx83x3r.js → monaco-binding-vq1hgnn0.js} +3 -3
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/{split-n2gfpm5m.js → split-c9zfdgxf.js} +2 -2
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/{studio-2j1cb95x.js → studio-6m380wp7.js} +4 -4
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-v0jzqdjm.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/{studio-d81xfh1g.js → studio-8tr6cfrc.js} +4 -4
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/{studio-dgz8d0c1.js → studio-bbe4c90a.js} +4 -4
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-90pq9km1.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-0q988f9w.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/{studio-5ve6bbep.js → studio-k7evxqh4.js} +4 -4
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-485046te.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-1fxkaaea.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-tq0rtfwj.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-a3g98wjr.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/studio-r5qy30vx.js +5 -0
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/{toast-host-ke5z4ng7.js → toast-host-1yg5ar8d.js} +3 -3
- package/dist/chunks/{tooltip-5v8ngwj2.js → tooltip-yypz28gq.js} +3 -3
- package/dist/chunks/{tree-mdq3v5cw.js → tree-9xa4hm7n.js} +2 -2
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/{ws-client-nze0k6mv.js → ws-client-bv552sfx.js} +3 -3
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +103 -104
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +12 -11
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +263 -49
- package/src/browse/library-model.ts +181 -133
- package/src/browse/library-pane.ts +738 -446
- package/src/browse/library-preview.ts +149 -19
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +16 -1
- package/src/canvas/canvas-live-render.ts +222 -30
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-render.ts +113 -107
- package/src/canvas/canvas-utils.ts +57 -12
- package/src/canvas/iframe-drop.ts +107 -0
- package/src/canvas/iframe-entry.ts +24 -12
- package/src/canvas/iframe-host.ts +134 -62
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-patch.ts +8 -7
- package/src/canvas/iframe-protocol.ts +24 -5
- package/src/canvas/iframe-render.ts +48 -1
- package/src/canvas/iframe-subtree.ts +5 -2
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/stage-scrollbar.ts +5 -1
- package/src/canvas/surface-registry.ts +6 -0
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +10 -8
- package/src/commands/context.ts +35 -10
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +9 -0
- package/src/commands/levels.ts +11 -5
- package/src/commands/live-context.ts +2 -0
- package/src/commands/registry.ts +10 -1
- package/src/content/collection-match.ts +6 -5
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/entry-commands.ts +51 -60
- package/src/content/entry-editor.ts +111 -18
- package/src/content/entry-fields.ts +13 -1
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +17 -3
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/convert-to-component.ts +67 -43
- package/src/editor/file-drop-action.ts +9 -1
- package/src/editor/inline-edit-apply.ts +44 -0
- package/src/editor/inline-edit.ts +10 -0
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +13 -4
- package/src/editor/shortcuts.ts +44 -22
- package/src/editor/slash-menu.ts +51 -8
- package/src/files/components.ts +74 -10
- package/src/files/file-ops.ts +15 -5
- package/src/files/files.ts +164 -150
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +95 -1
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +13 -3
- package/src/format/format-host.ts +15 -0
- package/src/github/github-auth.ts +2 -2
- package/src/github/github-publish.ts +4 -3
- package/src/grid/grid-controller.ts +5 -1
- package/src/grid/grid-open.ts +0 -27
- package/src/grid/grid-panel.ts +54 -2
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +3 -25
- package/src/grid/grid-view.ts +31 -6
- package/src/grid/sources/content-source.ts +75 -7
- package/src/grid/tabulator-tables.d.ts +6 -0
- package/src/hosting/document.ts +2 -2
- package/src/i18n/i18n-commands.ts +2 -1
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +47 -19
- package/src/packages/pull-package-sync.ts +1 -1
- package/src/panels/activity-panel.ts +21 -5
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/block-action-bar.ts +11 -11
- package/src/panels/canvas-dnd-bridge.ts +5 -2
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +1 -1
- package/src/panels/data-grid.ts +4 -0
- package/src/panels/dnd.ts +17 -30
- package/src/panels/elements-panel.ts +9 -2
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/formula-workspace.ts +2 -3
- package/src/panels/frontmatter-fields.ts +9 -9
- package/src/panels/git-diff-open.ts +9 -5
- package/src/panels/head-panel.ts +369 -103
- package/src/panels/i18n-panel.ts +11 -10
- package/src/panels/imports-panel.ts +2 -0
- package/src/panels/jump-bar.ts +27 -2
- package/src/panels/layers-panel.ts +36 -30
- package/src/panels/left-panel.ts +22 -8
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +111 -29
- package/src/panels/pane-grid.ts +6 -6
- package/src/panels/panel-registry.ts +14 -9
- package/src/panels/properties-panel.ts +7 -3
- package/src/panels/right-panel.ts +199 -43
- package/src/panels/seo-modal.ts +41 -108
- package/src/panels/settings-menu.ts +52 -50
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +3 -4
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/style-panel.ts +37 -3
- package/src/panels/stylebook-doc.ts +142 -10
- package/src/panels/stylebook-layers-panel.ts +39 -80
- package/src/panels/stylebook-panel.ts +47 -10
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-strip.ts +109 -25
- package/src/platform.ts +1 -1
- package/src/platforms/cloud.ts +28 -1
- package/src/platforms/default-platform.ts +4 -4
- package/src/platforms/devserver.ts +51 -25
- package/src/publish/deploy-checklist.ts +12 -7
- package/src/publish/pages-service.ts +38 -14
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +83 -18
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/services/automation.ts +16 -20
- package/src/services/cf-settings.ts +4 -4
- package/src/services/connection.ts +2 -2
- package/src/services/directory-picker.ts +2 -2
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +21 -2
- package/src/services/settings/definitions.ts +25 -14
- package/src/settings/contributed-section.ts +49 -10
- package/src/settings/css-vars-editor.ts +93 -27
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-sections.ts +20 -2
- package/src/settings/general-settings.ts +91 -21
- package/src/settings/preferences-dialog.ts +8 -1
- package/src/settings/project-sections.ts +27 -10
- package/src/settings/schema-field-ui.ts +3 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +182 -162
- package/src/shell.ts +467 -431
- package/src/site-context.ts +64 -10
- package/src/state.ts +28 -9
- package/src/studio.ts +194 -41
- package/src/style/project-styles.ts +34 -0
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/ai-chat.ts +2 -2
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +5 -5
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +134 -99
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +21 -0
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +46 -19
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +94 -59
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +15 -1
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +18 -0
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +24 -0
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +3 -1
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +38 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +5 -5
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +0 -21
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +8 -0
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +18 -75
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +2 -0
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +18 -2
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +77 -4
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +1 -1
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +9 -2
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +85 -24
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +23 -0
- package/src/surfaces/statusbar.ts +39 -15
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/welcome.ts +1 -1
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/tab.ts +47 -7
- package/src/types.ts +21 -26
- package/src/ui/form-controls.ts +47 -8
- package/src/ui/layers.ts +13 -0
- package/src/ui/media-picker.ts +284 -40
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +259 -27
- package/src/ui/virtual-window.ts +26 -1
- package/src/utils/base64.ts +3 -3
- package/src/utils/edit-display.ts +322 -67
- package/src/utils/local-day.ts +18 -0
- package/src/workspace/pane-derive.ts +4 -4
- package/src/workspace/session.ts +28 -7
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +125 -11
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-f2gkpy8d.js +0 -4
- package/dist/chunks/adapter-4912g339.js +0 -4
- package/dist/chunks/cf-account-picker-wccaenh6.js +0 -4
- package/dist/chunks/cf-settings-br6105tr.js +0 -4
- package/dist/chunks/color-28ksk2qm.js +0 -4
- package/dist/chunks/components-db68vsn7.js +0 -4
- package/dist/chunks/content-source-1449qesq.js +0 -4
- package/dist/chunks/convert-to-repeater-5h457egj.js +0 -4
- package/dist/chunks/editor-x9jn86a7.js +0 -4
- package/dist/chunks/entry-commands-may24cpt.js +0 -4
- package/dist/chunks/extension-sections-pvr14vxr.js +0 -4
- package/dist/chunks/file-ops-x9v54pcj.js +0 -4
- package/dist/chunks/files-j3knqf0s.js +0 -4
- package/dist/chunks/format-host-tyre2trb.js +0 -4
- package/dist/chunks/fs-events-64ma9htc.js +0 -4
- package/dist/chunks/git-panel-84ps5dex.js +0 -4
- package/dist/chunks/iframe-entry-fvbk89gm.js +0 -5
- package/dist/chunks/iframe-host-ck6vejt5.js +0 -4
- package/dist/chunks/index-b8xw3vy9.js +0 -4
- package/dist/chunks/jsonMode-w15cmrcm.js +0 -13
- package/dist/chunks/jx-validate-at3zn8wa.js +0 -4
- package/dist/chunks/layers-h4xp1pss.js +0 -4
- package/dist/chunks/layers-panel-m5hw1d7g.js +0 -4
- package/dist/chunks/lit-html-8t8t3dnr.js +0 -4
- package/dist/chunks/media-picker-2cweexc5.js +0 -4
- package/dist/chunks/menu-ynw13y0s.js +0 -4
- package/dist/chunks/monaco-buffer-qzxn567r.js +0 -4
- package/dist/chunks/monaco-setup-gxf6656g.js +0 -4
- package/dist/chunks/notify-cj5zbrs2.js +0 -4
- package/dist/chunks/parse-b7ddhr8m.js +0 -4
- package/dist/chunks/platform-3dfws9js.js +0 -4
- package/dist/chunks/popover-jt2gxmzs.js +0 -4
- package/dist/chunks/publish-panel-1gvxbj21.js +0 -4
- package/dist/chunks/quick-search-0dajrwqg.js +0 -4
- package/dist/chunks/references-49qgt404.js +0 -4
- package/dist/chunks/right-panel-jm1bwe53.js +0 -4
- package/dist/chunks/section-registry-6kwc4fky.js +0 -4
- package/dist/chunks/studio-0rt52vpq.js +0 -5
- package/dist/chunks/studio-18vgbhs5.js +0 -5
- package/dist/chunks/studio-24mccdrj.js +0 -5
- package/dist/chunks/studio-2eh507zk.js +0 -9
- package/dist/chunks/studio-2hcbccfv.js +0 -5
- package/dist/chunks/studio-2jbs3rxv.js +0 -5
- package/dist/chunks/studio-4h8k4dw9.js +0 -5
- package/dist/chunks/studio-5f6n18kx.js +0 -5
- package/dist/chunks/studio-5gthpky6.js +0 -5
- package/dist/chunks/studio-6ep3js6b.js +0 -9
- package/dist/chunks/studio-6wkmf3wz.js +0 -9
- package/dist/chunks/studio-841rf3cg.js +0 -5
- package/dist/chunks/studio-8gmwgheg.js +0 -5
- package/dist/chunks/studio-8qm0ep50.js +0 -5
- package/dist/chunks/studio-924p1tm1.js +0 -6
- package/dist/chunks/studio-a3shpz9y.js +0 -5
- package/dist/chunks/studio-amsbaaar.js +0 -6
- package/dist/chunks/studio-at5spjbc.js +0 -7
- package/dist/chunks/studio-b2xv945e.js +0 -5
- package/dist/chunks/studio-bn5nkafw.js +0 -5
- package/dist/chunks/studio-bw6q5xjf.js +0 -9
- package/dist/chunks/studio-c7q0t9x1.js +0 -5
- package/dist/chunks/studio-camnhc96.js +0 -6
- package/dist/chunks/studio-cffqvnzd.js +0 -5
- package/dist/chunks/studio-efvfrsf8.js +0 -5
- package/dist/chunks/studio-er30bpcx.js +0 -5
- package/dist/chunks/studio-ezscgr64.js +0 -5
- package/dist/chunks/studio-ffrrncvz.js +0 -5
- package/dist/chunks/studio-fpphgn8y.js +0 -10
- package/dist/chunks/studio-j1kvhdjk.js +0 -4
- package/dist/chunks/studio-j430n16g.js +0 -7
- package/dist/chunks/studio-jjkg84nj.js +0 -5
- package/dist/chunks/studio-m0q32ars.js +0 -4
- package/dist/chunks/studio-m6bdst11.js +0 -5
- package/dist/chunks/studio-nv2cptd4.js +0 -64
- package/dist/chunks/studio-nwfrc98n.js +0 -5
- package/dist/chunks/studio-p1wgvp7r.js +0 -5
- package/dist/chunks/studio-pag2wncm.js +0 -5
- package/dist/chunks/studio-qvanvzfd.js +0 -5
- package/dist/chunks/studio-qwa64kt7.js +0 -5
- package/dist/chunks/studio-rk1zc4x3.js +0 -928
- package/dist/chunks/studio-se2r3ptc.js +0 -5
- package/dist/chunks/studio-sg2a0dh0.js +0 -5
- package/dist/chunks/studio-tjzjhe68.js +0 -5
- package/dist/chunks/studio-v2w7q8r1.js +0 -7
- package/dist/chunks/studio-v5vjq1h0.js +0 -4
- package/dist/chunks/studio-v8aga3vp.js +0 -14
- package/dist/chunks/studio-vfcdrfmv.js +0 -5
- package/dist/chunks/studio-vmfkgdjf.js +0 -5
- package/dist/chunks/studio-wt1816jj.js +0 -5
- package/dist/chunks/studio-wz73q5kq.js +0 -4
- package/dist/chunks/studio-y04qtxvp.js +0 -7
- package/dist/chunks/studio-y21g8zzg.js +0 -5
- package/dist/chunks/studio-y64hrt8p.js +0 -12
- package/dist/chunks/studio-ynn90f58.js +0 -16
- package/dist/chunks/studio-yxz682sx.js +0 -5
- package/dist/chunks/studio-zp7snvkq.js +0 -5
- package/dist/chunks/studio-zq4z6tm6.js +0 -5
- package/dist/chunks/toast-c9fn075p.js +0 -4
- package/dist/chunks/tsMode-sf49ee9x.js +0 -14
- package/dist/chunks/workspace-jtfahpee.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -711
- package/src/panels/git-panel.ts +0 -1108
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -222
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -264
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `$site` and `$page` a page or a collection entry is drawn with on the canvas.
|
|
3
|
+
*
|
|
4
|
+
* A built page reads `${$page.locale}`, `${$page.url}` and `${$site.name}` from the state the build
|
|
5
|
+
* injects (site-architecture.md §10, §13.4). The canvas injected none of it, so every one of those
|
|
6
|
+
* bindings was undefined there: a component handed `$page.locale` as its locale threw a
|
|
7
|
+
* `RangeError` and was not rendered, and Preview of a multilingual page drew no list at all. The
|
|
8
|
+
* injection is `@jxsuite/site/context`'s, the one the build calls, because a host that improvised
|
|
9
|
+
* its own subset would differ from the build in whichever field it forgot.
|
|
10
|
+
*
|
|
11
|
+
* The route is the document's own: a page's URL pattern from its file, with the route parameters
|
|
12
|
+
* chosen for the preview; an entry's URL from its collection's template page in the entry's own
|
|
13
|
+
* language (studio.md §22.5), with the entry filling the page's parameter.
|
|
14
|
+
*
|
|
15
|
+
* @docs studio/interface/canvas
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { injectContext } from "@jxsuite/site/context";
|
|
19
|
+
import { documentUrlPattern } from "@jxsuite/site/routes";
|
|
20
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
21
|
+
import { resolveI18n } from "@jxsuite/schema/locale";
|
|
22
|
+
import { collectionForFile } from "../content/collection-match";
|
|
23
|
+
import { collectionPage, entryLocale, entryUrl } from "../content/collection-pages";
|
|
24
|
+
import type { SiteRoute } from "@jxsuite/site/context";
|
|
25
|
+
import type {
|
|
26
|
+
JxDocument,
|
|
27
|
+
JxDocumentValue,
|
|
28
|
+
JxStateDefinition,
|
|
29
|
+
ProjectConfig,
|
|
30
|
+
} from "@jxsuite/schema/types";
|
|
31
|
+
|
|
32
|
+
/** The two injected state entries. */
|
|
33
|
+
export interface PageContext {
|
|
34
|
+
$site: JxStateDefinition;
|
|
35
|
+
$page: JxStateDefinition;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** What {@link pageContextFor} reads off the document being drawn. */
|
|
39
|
+
export interface PageContextSource {
|
|
40
|
+
/** The project-relative path of the page or entry. */
|
|
41
|
+
documentPath: string;
|
|
42
|
+
/** Whether it is a collection entry rather than a page. */
|
|
43
|
+
isEntry: boolean;
|
|
44
|
+
/** The document's own `title` and `$lang`, which win over the route's. */
|
|
45
|
+
title?: JxDocumentValue | undefined;
|
|
46
|
+
lang?: JxDocumentValue | undefined;
|
|
47
|
+
/** An entry's fields (Markdown frontmatter), which may fill its URL and title. */
|
|
48
|
+
fields?: Readonly<Record<string, JxDocumentValue | undefined>> | null;
|
|
49
|
+
/** The route parameters chosen for a dynamic page's preview. */
|
|
50
|
+
params?: Readonly<Record<string, string>>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The parameters `url` fills in `pattern`, by position: `/blog/:slug` and `/blog/a` → `{slug: a}`. */
|
|
54
|
+
export function routeParams(pattern: string, url: string): NonNullable<SiteRoute["_pathParams"]> {
|
|
55
|
+
const values = url.split("/");
|
|
56
|
+
const out: NonNullable<SiteRoute["_pathParams"]> = {};
|
|
57
|
+
for (const [i, name] of pattern.split("/").entries()) {
|
|
58
|
+
const value = values[i];
|
|
59
|
+
if (name.startsWith(":") && value !== undefined) {
|
|
60
|
+
out[name.slice(1)] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The route a document is served at, as the build would serve it. */
|
|
67
|
+
async function routeOf(source: PageContextSource): Promise<SiteRoute> {
|
|
68
|
+
const { documentPath, fields, isEntry, params } = source;
|
|
69
|
+
if (!isEntry) {
|
|
70
|
+
return {
|
|
71
|
+
_pathParams: { ...params },
|
|
72
|
+
sourcePath: documentPath,
|
|
73
|
+
urlPattern: documentUrlPattern(documentPath),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const match = collectionForFile(documentPath);
|
|
77
|
+
const page = match ? await collectionPage(match.name, entryLocale(documentPath)) : null;
|
|
78
|
+
const url = entryUrl(page, documentPath, fields);
|
|
79
|
+
if (!page || url === null) {
|
|
80
|
+
return { _pathParams: {}, sourcePath: documentPath, urlPattern: page?.pattern ?? "/" };
|
|
81
|
+
}
|
|
82
|
+
return { _pathParams: routeParams(page.pattern, url), sourcePath: page.path, urlPattern: url };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The `$site` and `$page` for one document, injected exactly as the build injects them, or `null`
|
|
87
|
+
* when there is no project configuration to inject from.
|
|
88
|
+
*/
|
|
89
|
+
export async function pageContextFor(
|
|
90
|
+
source: PageContextSource,
|
|
91
|
+
projectConfig: ProjectConfig | null | undefined,
|
|
92
|
+
): Promise<PageContext | null> {
|
|
93
|
+
if (!projectConfig) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const route = await routeOf(source);
|
|
97
|
+
const fieldTitle = source.fields?.title;
|
|
98
|
+
const title = isString(source.title) ? source.title : isString(fieldTitle) ? fieldTitle : null;
|
|
99
|
+
// A scratch document: the injection writes project state, `$media`, imports and `$elements` onto
|
|
100
|
+
// The document it is handed, and the canvas composes those its own way. Only the two context
|
|
101
|
+
// Entries are taken from it.
|
|
102
|
+
const doc: JxDocument = { state: {} };
|
|
103
|
+
if (title !== null) {
|
|
104
|
+
doc.title = title;
|
|
105
|
+
}
|
|
106
|
+
if (isString(source.lang)) {
|
|
107
|
+
doc.$lang = source.lang;
|
|
108
|
+
}
|
|
109
|
+
const scratch = injectContext(doc, projectConfig, route, null, resolveI18n(projectConfig).i18n);
|
|
110
|
+
const { $page, $site } = scratch.state ?? {};
|
|
111
|
+
return $page === undefined || $site === undefined ? null : { $page, $site };
|
|
112
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
3
|
* Canvas render — extracted from studio.js (Phase 4o). Multi-mode canvas rendering orchestrator:
|
|
4
|
-
* dispatches to
|
|
4
|
+
* dispatches to source/edit/design/preview rendering paths.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { render, nothing } from "lit-html";
|
|
@@ -49,14 +49,20 @@ import { parseSourceForPath } from "../files/file-ops";
|
|
|
49
49
|
import { serializeDocument } from "../files/serialize-document";
|
|
50
50
|
import { parseJsonDocument, serializeJson } from "@jxsuite/schema/json-layout";
|
|
51
51
|
import { detachGridPanel, gridPanelMounted, renderGridMode } from "../grid/grid-panel";
|
|
52
|
-
import { detachLibraryPane, libraryPaneMounted, renderLibraryMode } from "../browse/library-pane";
|
|
53
52
|
import { detachEntryPane, entryPaneMounted, renderEntryMode } from "../content/entry-editor";
|
|
54
53
|
import { detachMediaPane, mediaPaneMounted, renderMediaMode } from "../media/media-pane";
|
|
55
54
|
import {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
} from "../
|
|
55
|
+
detachVariablesView,
|
|
56
|
+
renderVariablesMode,
|
|
57
|
+
variablesViewMounted,
|
|
58
|
+
} from "../style/variables-view";
|
|
59
|
+
import { PROJECT_VARIABLES_VIEW } from "../style/project-styles";
|
|
60
|
+
import {
|
|
61
|
+
detachWorkspaceHome,
|
|
62
|
+
isWorkspaceHomeMode,
|
|
63
|
+
renderWorkspaceHome,
|
|
64
|
+
workspaceHomeMounted,
|
|
65
|
+
} from "../workspace/workspace-home";
|
|
60
66
|
import { formatByName, formatForPath } from "../format/format-host";
|
|
61
67
|
import {
|
|
62
68
|
BUFFER_COMMIT,
|
|
@@ -66,10 +72,16 @@ import {
|
|
|
66
72
|
commitBufferWrites,
|
|
67
73
|
} from "../services/monaco-buffer";
|
|
68
74
|
import { noteTyping } from "../tabs/typing";
|
|
75
|
+
import { normalizeDocument } from "../tabs/bare-repeaters";
|
|
69
76
|
import { diffModelUrisFor, modelUriFor, monacoLangForPath } from "../services/model-uri";
|
|
70
77
|
import { renderWelcome } from "../surfaces/welcome";
|
|
71
78
|
import { emptyState } from "../surfaces/empty-state";
|
|
72
|
-
import {
|
|
79
|
+
import {
|
|
80
|
+
attachWritingBanner,
|
|
81
|
+
detachWritingBanner,
|
|
82
|
+
renderWritingBanner,
|
|
83
|
+
} from "../content/writing-banner";
|
|
84
|
+
import { writesEntryOnCanvas } from "../content/content-collections";
|
|
73
85
|
import { mountCanvasStage } from "../surfaces/canvas-stage";
|
|
74
86
|
import type {
|
|
75
87
|
CanvasStageActions,
|
|
@@ -238,7 +250,7 @@ function hardClearCanvasWrap(canvasWrap: HTMLElement) {
|
|
|
238
250
|
* the two width handles apart: `data-side`, the one part the stage document draws twice).
|
|
239
251
|
*
|
|
240
252
|
* Per STAGE rather than per module, for the reason every other field on `CanvasSurface` is: two
|
|
241
|
-
* panes each have a Monaco host and a
|
|
253
|
+
* panes each have a Monaco host and a banner slot, and one slot would hand the second pane's stage
|
|
242
254
|
* the first pane's editor.
|
|
243
255
|
*/
|
|
244
256
|
const _stageHosts = new WeakMap<CanvasSurface, Map<string, HTMLElement>>();
|
|
@@ -282,8 +294,8 @@ function stageActions(surface: CanvasSurface): CanvasStageActions {
|
|
|
282
294
|
stageHosts(surface).set(detail ? `${part}:${detail}` : part, element);
|
|
283
295
|
if (part === "panzoom") {
|
|
284
296
|
surface.panzoomWrap = element;
|
|
285
|
-
} else if (part === "
|
|
286
|
-
|
|
297
|
+
} else if (part === "writing-banner") {
|
|
298
|
+
attachWritingBanner(surface.paneId, element);
|
|
287
299
|
} else if (part === "diff-toolbar") {
|
|
288
300
|
setDiffToolbarHost(surface.paneId, element);
|
|
289
301
|
}
|
|
@@ -319,10 +331,10 @@ function drawStage(
|
|
|
319
331
|
entries: CanvasPanelEntry[],
|
|
320
332
|
): Promise<CanvasStageHandle | null> {
|
|
321
333
|
_stageEntries.set(surface, entries);
|
|
322
|
-
/* There is no
|
|
323
|
-
releases it for EVERY mode that draws no
|
|
334
|
+
/* There is no banner-host release here, and there must not be one: `renderCanvasImpl` already
|
|
335
|
+
releases it for EVERY mode that draws no banner, one branch above this one. A second answer to
|
|
324
336
|
the same question is how the two drift — and this one would answer only for the frames that
|
|
325
|
-
reach a stage, leaving grid,
|
|
337
|
+
reach a stage, leaving grid, the homes, entry and media to the first. */
|
|
326
338
|
const standing = surface.stage;
|
|
327
339
|
const stage = standing ?? mountCanvasStage(surface.wrap, view, stageActions(surface));
|
|
328
340
|
surface.stage = stage;
|
|
@@ -364,9 +376,8 @@ function editorStageView(frame: "source" | "code"): CanvasStageView {
|
|
|
364
376
|
* Release this pane's stage document.
|
|
365
377
|
*
|
|
366
378
|
* Called on a real mode transition and on a full reset — the two moments the structure standing on
|
|
367
|
-
* the stage stops being the stage's. The
|
|
368
|
-
*
|
|
369
|
-
* never says so.
|
|
379
|
+
* the stage stops being the stage's. The host handed to another module goes WITH it: a Compare bar
|
|
380
|
+
* pointing at a detached node is a surface that draws into nothing and never says so.
|
|
370
381
|
*
|
|
371
382
|
* @param {CanvasSurface} surface
|
|
372
383
|
*/
|
|
@@ -378,7 +389,6 @@ function detachCanvasStage(surface: CanvasSurface): void {
|
|
|
378
389
|
surface.stage = null;
|
|
379
390
|
_stageHosts.delete(surface);
|
|
380
391
|
_stageEntries.delete(surface);
|
|
381
|
-
attachDocumentHeaderHost(surface.paneId, null);
|
|
382
392
|
setDiffToolbarHost(surface.paneId, null);
|
|
383
393
|
}
|
|
384
394
|
|
|
@@ -616,10 +626,11 @@ function resetCanvasView(surface: CanvasSurface) {
|
|
|
616
626
|
const canvasWrap = surface.wrap;
|
|
617
627
|
const { paneId } = surface;
|
|
618
628
|
detachGridPanel(paneId);
|
|
619
|
-
detachLibraryPane(paneId);
|
|
620
629
|
detachEntryPane(paneId);
|
|
630
|
+
detachWritingBanner(paneId);
|
|
621
631
|
detachMediaPane(paneId);
|
|
622
|
-
|
|
632
|
+
detachVariablesView(paneId);
|
|
633
|
+
detachWorkspaceHome(paneId);
|
|
623
634
|
disposeSourceCollab(surface);
|
|
624
635
|
disposeSourceEditor(surface);
|
|
625
636
|
disposeDiffEditor(surface);
|
|
@@ -841,6 +852,8 @@ async function mountSourceEditor(
|
|
|
841
852
|
}
|
|
842
853
|
tab.doc.document = document;
|
|
843
854
|
tab.doc.content.frontmatter = frontmatter;
|
|
855
|
+
// The buffer is the author's own spelling now, so it is what the next save keeps.
|
|
856
|
+
tab.doc.source = sourceEditor.getValue();
|
|
844
857
|
tab.doc.dirty = true;
|
|
845
858
|
writes.markSettled();
|
|
846
859
|
} catch {
|
|
@@ -854,7 +867,10 @@ async function mountSourceEditor(
|
|
|
854
867
|
const parsed = parseJsonDocument(sourceEditor.getValue());
|
|
855
868
|
/* SAFETY: a JSON source tab holds a Jx document, whose schema makes the top-level object
|
|
856
869
|
parseJsonDocument returns a node; text that does not parse throws into the catch. */
|
|
857
|
-
|
|
870
|
+
const document = parsed.document as JxMutableNode;
|
|
871
|
+
// The member form every edit assumes, and the record of the bare repeaters the text wrote.
|
|
872
|
+
tab.doc.bareRepeaters = normalizeDocument(document);
|
|
873
|
+
tab.doc.document = document;
|
|
858
874
|
tab.doc.layout = parsed.layout;
|
|
859
875
|
tab.doc.dirty = true;
|
|
860
876
|
writes.markSettled();
|
|
@@ -979,7 +995,6 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
979
995
|
// No active tab — reset every piece of canvas view state so reopening a file can never inherit
|
|
980
996
|
// A stale Lit part, a dead Monaco editor, or a mismatched prevCanvasMode (the toxic states that
|
|
981
997
|
// Previously left the canvas unrenderable until a full reload).
|
|
982
|
-
attachDocumentHeaderHost(surface.paneId, null);
|
|
983
998
|
resetCanvasView(surface);
|
|
984
999
|
/* A DERIVED pane with nothing to draw explains itself. It is not the welcome screen and it is
|
|
985
1000
|
not a blank stage: it is a standing rule that has not resolved — "Select an element inside a
|
|
@@ -1009,7 +1024,6 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1009
1024
|
follow has run and a stage that blanked on that would flicker on every retarget. */
|
|
1010
1025
|
const staleDerivation = derivationOfPane(surface.paneId);
|
|
1011
1026
|
if (staleDerivation?.status === "unavailable" && staleDerivation.reason) {
|
|
1012
|
-
attachDocumentHeaderHost(surface.paneId, null);
|
|
1013
1027
|
resetCanvasView(surface);
|
|
1014
1028
|
/* …and for a COMPANION, what it is still holding. `tab` here is the pane's OWN document for a
|
|
1015
1029
|
companion and the SOURCE pane's for a lens — the hop `tabOfPane` takes — so the kind decides
|
|
@@ -1035,28 +1049,19 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1035
1049
|
// Re-rendering the previous mode's panels in place.
|
|
1036
1050
|
const canvasMode = canvasModeOfPane(surface.paneId);
|
|
1037
1051
|
|
|
1038
|
-
/*
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
`hasDocumentHeader` is the other predicate, and it is a fact about the DOCUMENT. It used to
|
|
1046
|
-
carry two more clauses, suppressing the card while a function body or a formula was open on
|
|
1047
|
-
the grounds that those sub-editors took the whole stage. They open in the dock's Logic tab now
|
|
1048
|
-
(§16.3) and the page is still on screen behind it, so those clauses only DETACHED the visible
|
|
1049
|
-
card: it stopped re-rendering and quietly showed frontmatter from before the edit. */
|
|
1050
|
-
/* …and NOT in a lens. The Document Header is an editing surface — Title, Route, SEO, the raw
|
|
1051
|
-
frontmatter — over a document this pane does not own, and two cards editing one document's
|
|
1052
|
-
frontmatter side by side is two writers for one field. A lens is a view; the card belongs to
|
|
1053
|
-
the pane that owns the tab. */
|
|
1054
|
-
const wantsDocHeader =
|
|
1052
|
+
/* Edit draws the page and nothing above it (§4.2): a document's settings — title, URL, layout,
|
|
1053
|
+
frontmatter, description, Search appearance — are the Inspector's Page tab's (§6), in every
|
|
1054
|
+
mode, so the stage carries no card of its own and the page starts at the top of the pane.
|
|
1055
|
+
A collection entry written in Edit carries the writing-mode banner (§22.5): the canvas wraps it
|
|
1056
|
+
in its template's layout, and the banner says the layout is locked. Not in a lens: the
|
|
1057
|
+
banner's door belongs to the pane that owns the tab, and a lens is a view. */
|
|
1058
|
+
const wantsWritingBanner =
|
|
1055
1059
|
canvasMode === "edit" &&
|
|
1056
1060
|
derivationOfPane(surface.paneId)?.kind !== "lens" &&
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1061
|
+
Boolean(projectState?.isSiteProject) &&
|
|
1062
|
+
writesEntryOnCanvas(tab.documentPath);
|
|
1063
|
+
if (!wantsWritingBanner) {
|
|
1064
|
+
detachWritingBanner(surface.paneId);
|
|
1060
1065
|
}
|
|
1061
1066
|
|
|
1062
1067
|
/* Advance THIS stage's render generation so stale async renders from its previous pass bail out.
|
|
@@ -1165,12 +1170,6 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1165
1170
|
return;
|
|
1166
1171
|
}
|
|
1167
1172
|
|
|
1168
|
-
// Library fast-path, same shape: the Library pane owns its own reactivity (view state, scan,
|
|
1169
|
-
// Window), so a same-tab re-render while it is mounted needs nothing from the canvas pipeline.
|
|
1170
|
-
if (canvasMode === "manage" && libraryPaneMounted(surface.paneId, tab) && !modeChanged) {
|
|
1171
|
-
return;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
1173
|
// Entry fast-path, same shape: the entry form owns its own effect over the tab's frontmatter, so
|
|
1175
1174
|
// A field commit repaints the form and nothing reaches the canvas pipeline.
|
|
1176
1175
|
if (canvasMode === "entry" && entryPaneMounted(surface.paneId, tab) && !modeChanged) {
|
|
@@ -1183,9 +1182,21 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1183
1182
|
return;
|
|
1184
1183
|
}
|
|
1185
1184
|
|
|
1186
|
-
//
|
|
1187
|
-
|
|
1188
|
-
|
|
1185
|
+
// Variables fast-path, same shape: the view follows the document through its own effect.
|
|
1186
|
+
if (
|
|
1187
|
+
canvasMode === PROJECT_VARIABLES_VIEW &&
|
|
1188
|
+
variablesViewMounted(surface.paneId, tab) &&
|
|
1189
|
+
!modeChanged
|
|
1190
|
+
) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// Workspace-home fast-path, same shape: a home is a standing document with nothing to re-render.
|
|
1195
|
+
if (
|
|
1196
|
+
isWorkspaceHomeMode(canvasMode) &&
|
|
1197
|
+
workspaceHomeMounted(surface.paneId, tab) &&
|
|
1198
|
+
!modeChanged
|
|
1199
|
+
) {
|
|
1189
1200
|
return;
|
|
1190
1201
|
}
|
|
1191
1202
|
|
|
@@ -1202,7 +1213,8 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1202
1213
|
const curCustomized = shell.stylebook.customizedOnly;
|
|
1203
1214
|
const filterChanged =
|
|
1204
1215
|
curFilter !== surface.prevStylebookFilter ||
|
|
1205
|
-
curCustomized !== surface.prevStylebookCustomizedOnly
|
|
1216
|
+
curCustomized !== surface.prevStylebookCustomizedOnly ||
|
|
1217
|
+
activeMediaOfPane(surface.paneId) !== surface.prevStylebookMedia;
|
|
1206
1218
|
if (!filterChanged) {
|
|
1207
1219
|
const style = transposeStylebookStyle(getEffectiveStyle(tab.doc.document.style));
|
|
1208
1220
|
if (postStyleUpdateToStylebookHosts(style) > 0) {
|
|
@@ -1249,18 +1261,18 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1249
1261
|
// Destroy the grid panel if switching away from grid mode
|
|
1250
1262
|
detachGridPanel(surface.paneId);
|
|
1251
1263
|
|
|
1252
|
-
// The
|
|
1253
|
-
// Mode without releasing them is exactly the unbounded retention its LRU cap exists to remove.
|
|
1254
|
-
detachLibraryPane(surface.paneId);
|
|
1255
|
-
|
|
1256
|
-
// Same for the entry form, whose effect scope subscribes to the document's frontmatter
|
|
1264
|
+
// The entry form's effect scope subscribes to the document's frontmatter
|
|
1257
1265
|
detachEntryPane(surface.paneId);
|
|
1258
1266
|
|
|
1259
1267
|
// And for the media viewer, whose effect scope subscribes to the tab's path
|
|
1260
1268
|
detachMediaPane(surface.paneId);
|
|
1261
1269
|
|
|
1262
|
-
//
|
|
1263
|
-
|
|
1270
|
+
// And for the Variables view, whose effect scope subscribes to the document's style
|
|
1271
|
+
detachVariablesView(surface.paneId);
|
|
1272
|
+
|
|
1273
|
+
// And for a workspace home, whose surface holds a mounted document (the Content home's
|
|
1274
|
+
// IntersectionObserver and preview LRU among them)
|
|
1275
|
+
detachWorkspaceHome(surface.paneId);
|
|
1264
1276
|
|
|
1265
1277
|
// Dispose Monaco editor if switching away from source mode
|
|
1266
1278
|
disposeSourceCollab(surface);
|
|
@@ -1293,6 +1305,7 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1293
1305
|
if (canvasMode === "stylebook") {
|
|
1294
1306
|
surface.prevStylebookFilter = shell.stylebook.filter;
|
|
1295
1307
|
surface.prevStylebookCustomizedOnly = shell.stylebook.customizedOnly;
|
|
1308
|
+
surface.prevStylebookMedia = activeMediaOfPane(surface.paneId);
|
|
1296
1309
|
void renderStylebookMode(surface, {
|
|
1297
1310
|
applyTransform,
|
|
1298
1311
|
canvasPanelEntry,
|
|
@@ -1371,29 +1384,8 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1371
1384
|
return;
|
|
1372
1385
|
}
|
|
1373
1386
|
|
|
1374
|
-
/* Settings mode: the Project Settings document (§17.1). Same non-iframe-editor pattern as
|
|
1375
|
-
grid and stylebook — the panel owns its own reactivity from here — and the reason the seven
|
|
1376
|
-
settings screenshots now crop `pane.primary` instead of `overlay.dialog:settings` without one
|
|
1377
|
-
manifest step changing. */
|
|
1378
|
-
if (canvasMode === "settings") {
|
|
1379
|
-
canvasWrap.style.padding = "0";
|
|
1380
|
-
canvasWrap.style.display = "block";
|
|
1381
|
-
renderSettingsPane(surface);
|
|
1382
|
-
return;
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
/* Library mode: the project's own contents, over a GridSource, in one of five layouts
|
|
1386
|
-
(`browse/library-pane.ts`). `commands/context.ts` already mapped `manage` to the `library`
|
|
1387
|
-
editor kind — this is the surface that map was pointing at. */
|
|
1388
|
-
if (canvasMode === "manage") {
|
|
1389
|
-
canvasWrap.style.padding = "0";
|
|
1390
|
-
canvasWrap.style.display = "block";
|
|
1391
|
-
renderLibraryMode(surface, tab);
|
|
1392
|
-
return;
|
|
1393
|
-
}
|
|
1394
|
-
|
|
1395
1387
|
/* Entry mode: one content entry's fields, typed by its collection's schema
|
|
1396
|
-
(`content/entry-editor.ts`). Same non-iframe-editor pattern as the
|
|
1388
|
+
(`content/entry-editor.ts`). Same non-iframe-editor pattern as the grid and the homes — and
|
|
1397
1389
|
the reason `entry` is in `commands/context.ts`'s mode map, without which a form over a
|
|
1398
1390
|
frontmatter record would have resolved into the CANVAS key scope. */
|
|
1399
1391
|
if (canvasMode === "entry") {
|
|
@@ -1412,6 +1404,22 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1412
1404
|
return;
|
|
1413
1405
|
}
|
|
1414
1406
|
|
|
1407
|
+
/* The Styles workspace's Variables view: `project.json`'s CSS custom properties, edited in a
|
|
1408
|
+
form (`style/variables-view.ts`). Like a home, it writes nothing onto the stage: its own style
|
|
1409
|
+
block fills it (`surfaces/styles-variables.json`). */
|
|
1410
|
+
if (canvasMode === PROJECT_VARIABLES_VIEW) {
|
|
1411
|
+
renderVariablesMode(surface, tab);
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/* A workspace's home: the surface a workspace opens on when none of its own tabs is open
|
|
1416
|
+
(`workspace/workspace-home.ts`). Unlike the five above it writes nothing onto the stage: the
|
|
1417
|
+
home's own style block fills it (`surfaces/publish-workspace.json`, for one). */
|
|
1418
|
+
if (isWorkspaceHomeMode(canvasMode)) {
|
|
1419
|
+
renderWorkspaceHome(surface, tab);
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1415
1423
|
// Grid mode: spreadsheet editor over the tab's grid source (mirrors the Monaco/stylebook
|
|
1416
1424
|
// Non-iframe-editor pattern; the panel owns its own reactivity from here).
|
|
1417
1425
|
if (canvasMode === "grid") {
|
|
@@ -1653,28 +1661,23 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1653
1661
|
const rootTag = S.document.tagName;
|
|
1654
1662
|
const isComponentDoc = isString(rootTag) && rootTag.includes("-");
|
|
1655
1663
|
const { featureToggles: editToggles } = S.ui;
|
|
1656
|
-
/* The stage stacks when it carries the
|
|
1657
|
-
Set on every render rather than on the transition, because whether a document
|
|
1658
|
-
changes with the tab and not with the mode. `editors.ts` and
|
|
1659
|
-
claim the column this way — `#canvas-wrap` is a row by
|
|
1660
|
-
own axis. Stretched, because the band is as wide as the
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
as the band's edge; the scroller's own 32px of top padding is the breathing room. */
|
|
1669
|
-
canvasWrap.style.flexDirection = wantsDocHeader ? "column" : "";
|
|
1670
|
-
canvasWrap.style.alignItems = wantsDocHeader ? "stretch" : "";
|
|
1671
|
-
canvasWrap.style.gap = wantsDocHeader ? "0px" : "";
|
|
1664
|
+
/* The stage stacks when it carries the writing banner: the band first, the page's scroller
|
|
1665
|
+
below it. Set on every render rather than on the transition, because whether a document is
|
|
1666
|
+
a collection entry changes with the tab and not with the mode. `editors.ts` and
|
|
1667
|
+
`formula-workspace.ts` already claim the column this way — `#canvas-wrap` is a row by
|
|
1668
|
+
default and each surface states its own axis. Stretched, because the band is as wide as the
|
|
1669
|
+
PANE rather than the breakpoint's column. And FLUSH: the cell's own 24px gap
|
|
1670
|
+
(`pane-grid.json`) between two side-by-side surfaces would be dead space between the band and
|
|
1671
|
+
the scroller below it, whose own 32px of top padding is the breathing room. */
|
|
1672
|
+
const stacks = wantsWritingBanner;
|
|
1673
|
+
canvasWrap.style.flexDirection = stacks ? "column" : "";
|
|
1674
|
+
canvasWrap.style.alignItems = stacks ? "stretch" : "";
|
|
1675
|
+
canvasWrap.style.gap = stacks ? "0px" : "";
|
|
1672
1676
|
void drawStage(
|
|
1673
1677
|
surface,
|
|
1674
1678
|
{
|
|
1675
|
-
/* The
|
|
1676
|
-
|
|
1677
|
-
scrolls under it and the breakpoint does not size it. The two handles are not in the
|
|
1679
|
+
/* The banner LEADS the frame: a sibling of the scroller rather than a block of the column,
|
|
1680
|
+
so the page scrolls under it and the breakpoint does not size it. The two handles are not in the
|
|
1678
1681
|
column either: they are `jx-split`s standing beside it in the canvas's row, because the
|
|
1679
1682
|
canvas is the track a splitter has to measure and the column is the thing being
|
|
1680
1683
|
resized. */
|
|
@@ -1684,7 +1687,7 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1684
1687
|
handles: "shown",
|
|
1685
1688
|
hug: isComponentDoc,
|
|
1686
1689
|
innerPart: "edit-column",
|
|
1687
|
-
lead:
|
|
1690
|
+
lead: wantsWritingBanner ? "banner" : "none",
|
|
1688
1691
|
panels: [entry.item],
|
|
1689
1692
|
},
|
|
1690
1693
|
[entry],
|
|
@@ -1692,6 +1695,9 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1692
1695
|
if (!stage) {
|
|
1693
1696
|
return;
|
|
1694
1697
|
}
|
|
1698
|
+
if (wantsWritingBanner) {
|
|
1699
|
+
renderWritingBanner(surface.paneId, tab);
|
|
1700
|
+
}
|
|
1695
1701
|
const editColumn = stageHost(surface, "edit-column");
|
|
1696
1702
|
const scroller = stageHost(surface, "edit-canvas");
|
|
1697
1703
|
/* SAFETY: the edit stage view always draws its `edit-canvas` part, and this runs only once
|
|
@@ -1733,9 +1739,9 @@ function renderCanvasImpl(surface: CanvasSurface) {
|
|
|
1733
1739
|
canvasWrap.style.padding = "0";
|
|
1734
1740
|
canvasWrap.style.overflow = "hidden";
|
|
1735
1741
|
}
|
|
1736
|
-
/*
|
|
1737
|
-
alone (see `
|
|
1738
|
-
inline writes Edit makes to stack it. */
|
|
1742
|
+
/* Nothing leads Design's frame, so the stage cell stays the row it is by default: the writing
|
|
1743
|
+
banner is Edit's alone (see `wantsWritingBanner`), and the transition into this mode has
|
|
1744
|
+
already cleared the inline writes Edit makes to stack it. */
|
|
1739
1745
|
|
|
1740
1746
|
const {
|
|
1741
1747
|
sizeBreakpoints,
|
|
@@ -1995,11 +2001,11 @@ setSurfaceTeardown((surface) => {
|
|
|
1995
2001
|
clearDiffView(surface.paneId);
|
|
1996
2002
|
setDiffToolbarHost(surface.paneId, null);
|
|
1997
2003
|
detachGridPanel(surface.paneId);
|
|
1998
|
-
detachLibraryPane(surface.paneId);
|
|
1999
2004
|
detachEntryPane(surface.paneId);
|
|
2000
2005
|
detachMediaPane(surface.paneId);
|
|
2001
|
-
|
|
2002
|
-
|
|
2006
|
+
detachVariablesView(surface.paneId);
|
|
2007
|
+
detachWorkspaceHome(surface.paneId);
|
|
2008
|
+
detachWritingBanner(surface.paneId);
|
|
2003
2009
|
disposeSourceCollab(surface);
|
|
2004
2010
|
disposeSourceEditor(surface);
|
|
2005
2011
|
surface.centerObserver?.disconnect();
|
|
@@ -257,8 +257,10 @@ export function centerCanvas(surface: CanvasSurface) {
|
|
|
257
257
|
const wrapWidth = surface.wrap.clientWidth;
|
|
258
258
|
const contentWidth = surface.panzoomWrap.scrollWidth;
|
|
259
259
|
const zoom = zoomOf(surface);
|
|
260
|
-
const
|
|
261
|
-
|
|
260
|
+
const free = wrapWidth - contentWidth * zoom;
|
|
261
|
+
/* Content that fits is centred, however little room is left over: a 16px floor on a fitted page
|
|
262
|
+
pushed its right edge 16px past the pane. Content wider than the pane starts 16px in. */
|
|
263
|
+
surface.panX = free >= 0 ? free / 2 : 16;
|
|
262
264
|
surface.panY = 0;
|
|
263
265
|
}
|
|
264
266
|
|
|
@@ -483,6 +485,14 @@ export function requestEditZoom(
|
|
|
483
485
|
);
|
|
484
486
|
}
|
|
485
487
|
|
|
488
|
+
/** The screen pixels a stage reserves above its boards (`--boards-inset`), or 0 for none. */
|
|
489
|
+
export function boardsInset(panzoomWrap: HTMLElement): number {
|
|
490
|
+
// The inset is declared in px (`--boards-inset:40px`); unset reads as "", which is no inset.
|
|
491
|
+
const declared = getComputedStyle(panzoomWrap).getPropertyValue("--boards-inset").trim();
|
|
492
|
+
const inset = Number(declared.replace(/px$/, ""));
|
|
493
|
+
return Number.isFinite(inset) ? inset : 0;
|
|
494
|
+
}
|
|
495
|
+
|
|
486
496
|
/**
|
|
487
497
|
* Compute and apply a geometric fit. Pure arithmetic — it declares nothing.
|
|
488
498
|
*
|
|
@@ -495,7 +505,9 @@ function applyGeometricFit(surface: CanvasSurface, axis: "width" | "page", maxZo
|
|
|
495
505
|
return;
|
|
496
506
|
}
|
|
497
507
|
const wrapWidth = surface.wrap.clientWidth;
|
|
498
|
-
|
|
508
|
+
// The boards' own top clearance (`--boards-inset`, the Project Styles bar) is screen space the
|
|
509
|
+
// Artboards cannot use, so the page is fitted into what is left below it.
|
|
510
|
+
const wrapHeight = surface.wrap.clientHeight - boardsInset(surface.panzoomWrap);
|
|
499
511
|
const gap = 24;
|
|
500
512
|
const padding = 32;
|
|
501
513
|
let totalPanelWidth = 0;
|
|
@@ -763,11 +775,12 @@ export function resetZoom(surface: CanvasSurface = activeCanvasSurface()) {
|
|
|
763
775
|
* hands a rect back), so one arithmetic serves a rect measured from a parent DOM element and a rect
|
|
764
776
|
* measured inside a canvas iframe alike.
|
|
765
777
|
*
|
|
766
|
-
* **The viewport is the box that SCROLLS, not the stage.**
|
|
767
|
-
* above its scroller, inside the same stage cell, so there the stage is the
|
|
768
|
-
* its centre is half a
|
|
769
|
-
* what the author can actually see. {@link revealScroller} is that box wherever
|
|
770
|
-
* where there is none (Design, Stylebook, a comparison) the stage is still the
|
|
778
|
+
* **The viewport is the box that SCROLLS, not the stage.** Over a collection entry Edit stands the
|
|
779
|
+
* writing banner above its scroller, inside the same stage cell, so there the stage is the banner
|
|
780
|
+
* plus the page and its centre is half a banner too high: a reveal would land the node that far
|
|
781
|
+
* above the middle of what the author can actually see. {@link revealScroller} is that box wherever
|
|
782
|
+
* there is one, and where there is none (Design, Stylebook, a comparison) the stage is still the
|
|
783
|
+
* viewport.
|
|
771
784
|
*/
|
|
772
785
|
function centeringOffset(surface: CanvasSurface, rect: { top: number; height: number }): number {
|
|
773
786
|
const viewport = rectOf(revealScroller(surface) ?? surface.wrap);
|
|
@@ -840,6 +853,37 @@ export function panToParentRect(
|
|
|
840
853
|
revealBy(surface, centeringOffset(surface, rect), false);
|
|
841
854
|
}
|
|
842
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Bring a PARENT-VIEWPORT rect into view on a pan/zoom stage, moving as little as it must: not at
|
|
858
|
+
* all when the rect is already wholly in view, and never so far that the boards' top edge comes
|
|
859
|
+
* down past where it stands now.
|
|
860
|
+
*
|
|
861
|
+
* {@link panToParentRect} always centres, which is right for a jump to a diff change or a node the
|
|
862
|
+
* author asked to see. The stylebook's Outline is a list the author clicks DOWN, and centring its
|
|
863
|
+
* first rows meant the h1 at the very top of a fitted catalogue pulled every board half a pane
|
|
864
|
+
* down, leaving an empty band above them and no specimen that had moved into view.
|
|
865
|
+
*/
|
|
866
|
+
export function revealParentRect(
|
|
867
|
+
rect: { top: number; height: number },
|
|
868
|
+
surface: CanvasSurface = activeCanvasSurface(),
|
|
869
|
+
) {
|
|
870
|
+
const viewport = rectOf(surface.wrap);
|
|
871
|
+
if (rect.top >= viewport.top && rect.top + rect.height <= viewport.top + viewport.height) {
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
const offset = centeringOffset(surface, rect);
|
|
875
|
+
const ceiling = Math.max(surface.panY, 0) - surface.panY;
|
|
876
|
+
const step = Math.min(offset, ceiling);
|
|
877
|
+
if (step !== 0) {
|
|
878
|
+
/* A reveal is a pan somebody asked for, so the entry's centring stands down as a user's pan
|
|
879
|
+
makes it: a frame still growing to its height would otherwise re-centre the stage (top
|
|
880
|
+
aligned) under the card just brought on screen, which is what a reveal on a fresh stylebook
|
|
881
|
+
canvas did. */
|
|
882
|
+
surface.needsCenter = false;
|
|
883
|
+
animatePanBy(surface, step);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
843
887
|
/** Animate a stage's `panY` by `offsetY` with the shared 250ms ease-out. */
|
|
844
888
|
function animatePanBy(surface: CanvasSurface, offsetY: number) {
|
|
845
889
|
const startY = surface.panY;
|
|
@@ -874,6 +918,7 @@ export const CANVAS_MODES = [
|
|
|
874
918
|
"preview",
|
|
875
919
|
"source",
|
|
876
920
|
"stylebook",
|
|
921
|
+
"tokens",
|
|
877
922
|
"grid",
|
|
878
923
|
"git-diff",
|
|
879
924
|
] as const;
|
|
@@ -1144,7 +1189,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1144
1189
|
description:
|
|
1145
1190
|
"Switch the active document's editor mode. edit and design put its element tree on " +
|
|
1146
1191
|
"the canvas, where the document tools work; preview renders it as a visitor sees it; " +
|
|
1147
|
-
"source shows the JSON; stylebook, grid and git-diff open other editors. Use it to " +
|
|
1192
|
+
"source shows the JSON; stylebook, tokens, grid and git-diff open other editors. Use it to " +
|
|
1148
1193
|
"return a document to edit or design when the tree tools are refused.",
|
|
1149
1194
|
name: "set_canvas_mode",
|
|
1150
1195
|
/* `after.editor.kind` rather than the tab's own field: it is the gate's read (`treeEditable`
|
|
@@ -1411,9 +1456,9 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1411
1456
|
* preset owns it. What is left over is genuinely a rendering context, and it is the half of
|
|
1412
1457
|
* site-architecture.md §13.4 the canvas can show today: the artboard root's `lang` and `dir`.
|
|
1413
1458
|
* That is why this is a verb and not a label — an RTL locale mirrors the layout on screen.
|
|
1414
|
-
* (That section's other half, `$page.locale
|
|
1415
|
-
*
|
|
1416
|
-
*
|
|
1459
|
+
* (That section's other half, `$page.locale`, is injected into the canvas render from the
|
|
1460
|
+
* page's route, as the build injects it (studio.md §4.1). This verb leaves it alone: the
|
|
1461
|
+
* pane's language is a rendering context, not the page's (§20.2).)
|
|
1417
1462
|
*
|
|
1418
1463
|
* It lives in this file rather than in `i18n/i18n-commands.ts` because `contextTab`, `paneArg`
|
|
1419
1464
|
* and `repaint` are local closures here, and every rendering-context verb needs all three: the
|