@jxsuite/studio 6.1.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- 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-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- 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/dialog-c4x05vyx.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-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.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-c421cf8c.js +4 -0
- 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-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- 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/number-field-y62xq0ty.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/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- 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-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- 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-bbe4c90a.js +5 -0
- 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-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- 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-rv11kfwa.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-h46vtzk8.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-wszjyh0j.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-pre0skq6.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-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- 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/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- 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-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- 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 +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- 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/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- 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 +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- 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 +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- 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 +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- 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/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- 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/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- 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 +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- 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/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- 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 +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- 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/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- 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/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- 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 +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
|
@@ -1,701 +0,0 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
/**
|
|
3
|
-
* The Document Header card — the artefact's own header, drawn IN the stage.
|
|
4
|
-
*
|
|
5
|
-
* It replaces the old "Properties" bar, which was a fourth full-width band that **appeared and
|
|
6
|
-
* vanished as a side effect of the canvas mode** with no control to summon it, and which showed
|
|
7
|
-
* nothing at all unless `findContentTypeSchema` matched the document to a content collection — so
|
|
8
|
-
* it never appeared on the default home page, the one document every new author opens first.
|
|
9
|
-
*
|
|
10
|
-
* Two gates are gone, and each was a lie about what the card is for:
|
|
11
|
-
*
|
|
12
|
-
* - The **collection gate** (`if (!fieldSet?.collection)`) — a page's `title` is frontmatter whether
|
|
13
|
-
* or not a collection schema describes it;
|
|
14
|
-
* - The **document-mode gate** (`doc.mode === "content"`) — a JSON page carries `title` and `$head`
|
|
15
|
-
* directly on the root node, and it has a header for exactly the same reason.
|
|
16
|
-
*
|
|
17
|
-
* What it renders instead: **any** document with frontmatter or `$head`, in every named layout —
|
|
18
|
-
* Title, Route, the layout picker, the schema-and-frontmatter field list, the door to Search
|
|
19
|
-
* appearance and a "Raw head tags" disclosure. `hasDocumentHeader` is this module's whole
|
|
20
|
-
* predicate, and it is a fact about the DOCUMENT.
|
|
21
|
-
*
|
|
22
|
-
* **The canvas mode is the STAGE's question, and this module still takes none.** The stage draws a
|
|
23
|
-
* host for the card in Edit only (`wantsDocHeader` in `canvas/canvas-render.ts`): Design gives its
|
|
24
|
-
* artboards the whole pane, and the Navigator's Page panel carries the same fields in every mode,
|
|
25
|
-
* so nothing is out of reach in either. The old mode gate lived HERE, as a `getCanvasMode()` check
|
|
26
|
-
* the card ran to decide whether to exist; the decision now has one owner, the frame that draws the
|
|
27
|
-
* page, and this module draws into whatever host it is handed.
|
|
28
|
-
*
|
|
29
|
-
* **One reserved-key policy, one `collectFmFields` call.** The two field sets this card merges used
|
|
30
|
-
* to disagree: this module passed an empty reserved set and `head-panel.ts` passed `{title}`, so
|
|
31
|
-
* `title` could render twice with two different commit paths. `RESERVED_FM_KEYS` wins and is
|
|
32
|
-
* imported, not restated — see the note on its declaration.
|
|
33
|
-
*
|
|
34
|
-
* **The card has no host of its own.** `#frontmatter-panel` — the grid row, the `hidden` div, the
|
|
35
|
-
* `frontmatterPanelEl` ref and the 40vh cap that came with them — is deleted. The STAGE renders the
|
|
36
|
-
* host now ({@link attachDocumentHeaderHost}, called from the stage document's `onNodeCreated` in
|
|
37
|
-
* `canvas/canvas-render.ts`), so the card is docked above the page, as wide as the pane, rather
|
|
38
|
-
* than in a band the shell drew above every stage.
|
|
39
|
-
*
|
|
40
|
-
* **The card is a Jx document now** (`src/surfaces/doc-header.json`), and this module is the flow
|
|
41
|
-
* behind it: it decides which document a pane's card is drawn for, which rows that document has,
|
|
42
|
-
* what each row commits into and where a media or reference row gets its choices, then hands the
|
|
43
|
-
* surface a projection whose every field is already a string. Three things follow.
|
|
44
|
-
*
|
|
45
|
-
* **The focus-aware scheduler is gone, and nothing replaced it.** `panels/panel-scheduler.ts`
|
|
46
|
-
* existed to withhold a repaint while a text input in the card had focus, because a lit re-render
|
|
47
|
-
* rebuilt every control and truncated whatever was being typed into one. A document binds each
|
|
48
|
-
* value on its own runtime effect and skips a write equal to what the control already holds
|
|
49
|
-
* (specs/studio-ui-guidelines.md §9.3), so a projection that changed one field repaints one field
|
|
50
|
-
* and a projection that changed nothing repaints nothing. There is no window left to withhold.
|
|
51
|
-
*
|
|
52
|
-
* **ONE row vocabulary.** Title, the Layout picker and every schema-driven frontmatter field are
|
|
53
|
-
* the same row, told apart by which control they draw; what makes them different is what they
|
|
54
|
-
* WRITE, and that is this module's business rather than the document's. {@link RowCommit} is that
|
|
55
|
-
* table, rebuilt with each projection and reached by the row's `key` — which is why a row's key and
|
|
56
|
-
* its `data-prop` are two different strings: a collection whose schema declares a `layout` property
|
|
57
|
-
* would otherwise collide with the Layout picker.
|
|
58
|
-
*
|
|
59
|
-
* **Two widgets are borrowed as BEHAVIOUR rather than as markup.** The media browser
|
|
60
|
-
* (`ui/media-picker.ts`) renders into the popover layer rather than into the field, and the entry
|
|
61
|
-
* ids behind a `#/content/<type>` reference are a read (`ui/form-controls.ts`), so the card draws
|
|
62
|
-
* its own control for each and calls the owner for the part that is not markup. Neither module's
|
|
63
|
-
* lit template is interpolated here — a document and a lit template cannot share a container, and
|
|
64
|
-
* studio-ui-guidelines.md §9.4 forbids the mix outright.
|
|
65
|
-
*
|
|
66
|
-
* @docs studio/editing/frontmatter
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
import { projectState } from "../store";
|
|
70
|
-
import { workspace } from "../workspace/workspace";
|
|
71
|
-
import { tabOfPane } from "../canvas/canvas-surface";
|
|
72
|
-
import { paneRegion } from "../ui/regions";
|
|
73
|
-
import { effect, effectScope } from "../reactivity";
|
|
74
|
-
import { collectFmFields, projectFmField } from "./frontmatter-fields";
|
|
75
|
-
import { LIVE_PREVIEW } from "../ui/timing";
|
|
76
|
-
import { mutateUpdateFrontmatter, transact, transactDoc } from "../tabs/transact";
|
|
77
|
-
import { pageRoute } from "./tab-strip";
|
|
78
|
-
import {
|
|
79
|
-
RESERVED_FM_KEYS,
|
|
80
|
-
applyContentMutation,
|
|
81
|
-
buildHeadDoc,
|
|
82
|
-
entryLabel,
|
|
83
|
-
entryValue,
|
|
84
|
-
isPageDocument,
|
|
85
|
-
isManagedEntry,
|
|
86
|
-
layoutPickerEntries,
|
|
87
|
-
} from "./head-panel";
|
|
88
|
-
import { isGoogleFontEntry, isGoogleFontPreconnect } from "../utils/google-fonts";
|
|
89
|
-
import { activeRegistry } from "../commands/active-registry";
|
|
90
|
-
import { invalidateLayoutCache } from "../site-context";
|
|
91
|
-
import { mountDocHeaderSurface } from "../surfaces/doc-header";
|
|
92
|
-
|
|
93
|
-
import type { JxHeadEntry, JxMutableNode } from "@jxsuite/schema/types";
|
|
94
|
-
import type { Tab } from "../tabs/tab";
|
|
95
|
-
import type { FmSchemaEntry } from "./frontmatter-fields";
|
|
96
|
-
import type * as MediaPickerModule from "../ui/media-picker";
|
|
97
|
-
import type {
|
|
98
|
-
DocHeaderActions,
|
|
99
|
-
DocHeaderChoice,
|
|
100
|
-
DocHeaderRawEntry,
|
|
101
|
-
DocHeaderRow,
|
|
102
|
-
DocHeaderSurface,
|
|
103
|
-
DocHeaderView,
|
|
104
|
-
} from "../surfaces/doc-header";
|
|
105
|
-
|
|
106
|
-
/** What one row of the card writes. The document knows the control; this knows the document. */
|
|
107
|
-
interface RowCommit {
|
|
108
|
-
/** Remove the value this row shows. */
|
|
109
|
-
clear: () => void;
|
|
110
|
-
/** Commit what the control settled on — a string from every kind but the checkbox. */
|
|
111
|
-
commit: (raw: string | boolean) => void;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* One pane's card: the node the stage gave it, the mounted surface, its commit table and the
|
|
116
|
-
* actions the surface was handed.
|
|
117
|
-
*
|
|
118
|
-
* A single `_host` was the same singleton every other stage-content module had, and it produced a
|
|
119
|
-
* subtler failure than most: the stage hands the host over from a lit `ref`, so with two stages
|
|
120
|
-
* drawing a header the second `ref` to fire silently took the card away from the first, leaving one
|
|
121
|
-
* pane's Document Header frozen on the frontmatter of the moment it lost the handle.
|
|
122
|
-
*/
|
|
123
|
-
interface HeaderCard {
|
|
124
|
-
/** The pane this card is drawn for. Held rather than looked up: an action has to answer it. */
|
|
125
|
-
paneId: string;
|
|
126
|
-
el: HTMLElement;
|
|
127
|
-
/** `null` until the pane's document first has a header to draw. */
|
|
128
|
-
surface: DocHeaderSurface | null;
|
|
129
|
-
/** This pane's rows, by key. Rebuilt with each projection. */
|
|
130
|
-
commits: Map<string, RowCommit>;
|
|
131
|
-
/** Handed to the surface once, when it is mounted; every one of them reads `commits`. */
|
|
132
|
-
actions: DocHeaderActions;
|
|
133
|
-
/** Text edits waiting out {@link LIVE_PREVIEW}, one per row key. */
|
|
134
|
-
pending: Map<string, { commit: () => void; timer: ReturnType<typeof setTimeout> }>;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const _hosts = new Map<string, HeaderCard>();
|
|
138
|
-
let _scope: { stop: () => void; run: <T>(fn: () => T) => T | undefined } | null = null;
|
|
139
|
-
|
|
140
|
-
/** Per-document disclosure state, keyed by tab id — not stored on the document. */
|
|
141
|
-
const _rawOpen = new Set<string>();
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Whether each document's card is open, keyed by tab id, and fixed when the card is first drawn for
|
|
145
|
-
* that document.
|
|
146
|
-
*
|
|
147
|
-
* The card is a band across the top of the pane, and on a short pane it can take half the page, so
|
|
148
|
-
* the reader can fold it down to its bar. What they did LAST is the default for the next editor
|
|
149
|
-
* they open ({@link DOC_HEADER_EXPANDED_KEY}), but it is not a broadcast: an editor already open
|
|
150
|
-
* keeps the state it was drawn in, because a card that folded away under a document the reader was
|
|
151
|
-
* not looking at would be a change nobody asked for.
|
|
152
|
-
*/
|
|
153
|
-
const _expanded = new Map<string, boolean>();
|
|
154
|
-
|
|
155
|
-
/** The reader's last open-or-close of any card. Absent means open — the card's first-run state. */
|
|
156
|
-
export const DOC_HEADER_EXPANDED_KEY = "jx-studio-doc-header-expanded";
|
|
157
|
-
|
|
158
|
-
/** The persisted default, tolerating absent, corrupt and unavailable storage. */
|
|
159
|
-
function readExpandedDefault(): boolean {
|
|
160
|
-
try {
|
|
161
|
-
return localStorage.getItem(DOC_HEADER_EXPANDED_KEY) !== "false";
|
|
162
|
-
} catch {
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** Whether `tabId`'s card is open, seeding it from the persisted default the first time it is asked. */
|
|
168
|
-
function isExpanded(tabId: string): boolean {
|
|
169
|
-
let open = _expanded.get(tabId);
|
|
170
|
-
if (open === undefined) {
|
|
171
|
-
open = readExpandedDefault();
|
|
172
|
-
_expanded.set(tabId, open);
|
|
173
|
-
}
|
|
174
|
-
return open;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* The element the stage has made available for the card, or `null` while no stage hosts it.
|
|
179
|
-
*
|
|
180
|
-
* Called from a lit `ref` in `canvas/canvas-render.ts`, so the host's lifetime is the stage's: the
|
|
181
|
-
* canvas creates it when it draws a document that has a header and drops it otherwise.
|
|
182
|
-
*
|
|
183
|
-
* @param {HTMLElement | null} el
|
|
184
|
-
*/
|
|
185
|
-
export function attachDocumentHeaderHost(paneId: string, el: HTMLElement | null): void {
|
|
186
|
-
const held = _hosts.get(paneId);
|
|
187
|
-
if (held?.el === el) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (held) {
|
|
191
|
-
takeDown(held);
|
|
192
|
-
_hosts.delete(paneId);
|
|
193
|
-
}
|
|
194
|
-
if (!el) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
const card: HeaderCard = {
|
|
198
|
-
actions: {} as DocHeaderActions,
|
|
199
|
-
commits: new Map(),
|
|
200
|
-
el,
|
|
201
|
-
paneId,
|
|
202
|
-
pending: new Map(),
|
|
203
|
-
surface: null,
|
|
204
|
-
};
|
|
205
|
-
card.actions = makeActions(card);
|
|
206
|
-
_hosts.set(paneId, card);
|
|
207
|
-
paint(paneId, card);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/* There is no `documentHeaderHost` getter any more, and its absence is the point.
|
|
211
|
-
It existed for ONE caller: the stage's lit `ref`, which was told about a removal WITHOUT being
|
|
212
|
-
told which node had gone, so it had to read the host back and ask whether it was still connected
|
|
213
|
-
before deciding the report was about the host it held. `surfaces/canvas-stage.json` states the
|
|
214
|
-
card's slot as a view, so a frame that draws no card simply announces none and `renderCanvasImpl`
|
|
215
|
-
releases the slot in one place — there is nothing left to settle after the fact, and a getter
|
|
216
|
-
whose only reader is gone is a fact about the module nobody is entitled to. */
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Mount the Document Header card: subscribe to the tab / document / frontmatter reads it renders
|
|
220
|
-
* from, so a change repaints the card without repainting the canvas around it.
|
|
221
|
-
*
|
|
222
|
-
* The card takes no context. It used to take `getCanvasMode()` purely to decide whether to exist,
|
|
223
|
-
* and that predicate is the thing this change deletes.
|
|
224
|
-
*/
|
|
225
|
-
export function mount() {
|
|
226
|
-
_scope = effectScope();
|
|
227
|
-
_scope.run(() => {
|
|
228
|
-
effect(() => {
|
|
229
|
-
// Every pane's tab, not the focused one's: two stages can each be drawing a header, and a
|
|
230
|
-
// Card that only tracked `activeTab` stopped repainting the moment focus moved away from it.
|
|
231
|
-
for (const tab of paneTabs()) {
|
|
232
|
-
// Track everything the card reads: the document root (title / `$head` / `$layout` live
|
|
233
|
-
// There for a JSON page) plus the frontmatter object AND its entries — field commits mutate
|
|
234
|
-
// Keys in place while the source-mode round-trip swaps the whole object, and both must
|
|
235
|
-
// Re-fire this effect.
|
|
236
|
-
void tab.doc.mode;
|
|
237
|
-
void tab.documentPath;
|
|
238
|
-
void tab.doc.document;
|
|
239
|
-
void tab.doc.document?.title;
|
|
240
|
-
void tab.doc.document?.$head;
|
|
241
|
-
void tab.doc.document?.$layout;
|
|
242
|
-
const fm = tab.doc.content?.frontmatter;
|
|
243
|
-
if (fm) {
|
|
244
|
-
for (const key of Object.keys(fm)) {
|
|
245
|
-
void fm[key];
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
render();
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export function unmount() {
|
|
255
|
-
_scope?.stop();
|
|
256
|
-
_scope = null;
|
|
257
|
-
for (const card of _hosts.values()) {
|
|
258
|
-
takeDown(card);
|
|
259
|
-
}
|
|
260
|
-
_hosts.clear();
|
|
261
|
-
_rawOpen.clear();
|
|
262
|
-
_expanded.clear();
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/** Take one pane's card down: cancel its waiting edits and dispose the document it mounted. */
|
|
266
|
-
function takeDown(card: HeaderCard): void {
|
|
267
|
-
for (const { timer } of card.pending.values()) {
|
|
268
|
-
clearTimeout(timer);
|
|
269
|
-
}
|
|
270
|
-
card.pending.clear();
|
|
271
|
-
card.surface?.dispose();
|
|
272
|
-
card.surface = null;
|
|
273
|
-
card.commits.clear();
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/** Each pane's tab, deduplicated — the set of documents a header could be drawn for. */
|
|
277
|
-
function paneTabs(): Tab[] {
|
|
278
|
-
const tabs: Tab[] = [];
|
|
279
|
-
for (const pane of workspace.panes) {
|
|
280
|
-
const tab = tabOfPane(pane.id);
|
|
281
|
-
if (tab && !tabs.includes(tab)) {
|
|
282
|
-
tabs.push(tab);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return tabs;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Repaint every card.
|
|
290
|
-
*
|
|
291
|
-
* Coalescing is the runtime's now: a projection assigns to a standing scope and each binding
|
|
292
|
-
* re-runs only where the value it reads has changed, so calling this twice in one tick costs one
|
|
293
|
-
* comparison per binding rather than two renders.
|
|
294
|
-
*/
|
|
295
|
-
export function render() {
|
|
296
|
-
for (const [paneId, card] of _hosts) {
|
|
297
|
-
paint(paneId, card);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Whether a document has a header to show.
|
|
303
|
-
*
|
|
304
|
-
* The one remaining gate, and it is a fact about the document rather than about the view: a
|
|
305
|
-
* component definition with no frontmatter, no title and no `$head` has no header, and printing an
|
|
306
|
-
* empty card over its canvas would be chrome pretending to be content.
|
|
307
|
-
*
|
|
308
|
-
* @param {Tab} tab
|
|
309
|
-
* @returns {boolean}
|
|
310
|
-
*/
|
|
311
|
-
export function hasDocumentHeader(tab: Tab): boolean {
|
|
312
|
-
const fm = tab.doc.content?.frontmatter ?? {};
|
|
313
|
-
const doc = tab.doc.document;
|
|
314
|
-
if (Object.keys(fm).length > 0) {
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
317
|
-
if (typeof doc?.title === "string" || (doc?.$head?.length ?? 0) > 0) {
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
// A page always has one, even an empty one: Title and Route are the two facts it must state.
|
|
321
|
-
// THIS tab's page-ness. `isPageDocument()` was zero-argument and answered about the focused
|
|
322
|
-
// Pane's document, so a predicate whose every other line reads `tab` finished by asking about a
|
|
323
|
-
// Different one: a page in the side pane lost its header whenever a component was focused, and a
|
|
324
|
-
// Bare component in the side pane grew one whenever a page was.
|
|
325
|
-
return isPageDocument(tab);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Draw (or take down) one pane's card.
|
|
330
|
-
*
|
|
331
|
-
* The surface is only ever mounted ONCE per host and assigned to afterwards. Rebuilding it on a
|
|
332
|
-
* repaint would take a field out from under a reader mid-edit, which is the failure the scheduler
|
|
333
|
-
* this conversion deletes was built to prevent; `connected()` answers the one case assignment
|
|
334
|
-
* cannot, a stage that redrew and took the card's root away.
|
|
335
|
-
*/
|
|
336
|
-
function paint(paneId: string, card: HeaderCard): void {
|
|
337
|
-
const tab = tabOfPane(paneId);
|
|
338
|
-
if (!tab || !hasDocumentHeader(tab)) {
|
|
339
|
-
/* The stage decides whether the host exists; this only covers the window between a document
|
|
340
|
-
losing its header and the canvas noticing. */
|
|
341
|
-
takeDown(card);
|
|
342
|
-
card.el.replaceChildren();
|
|
343
|
-
card.el.hidden = true;
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
const view = viewFor(tab, paneId, card);
|
|
347
|
-
card.el.hidden = false;
|
|
348
|
-
if (card.surface?.connected()) {
|
|
349
|
-
card.surface.update(view);
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
card.surface?.dispose();
|
|
353
|
-
card.surface = mountDocHeaderSurface(card.el, view, card.actions);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// ─── The projection ──────────────────────────────────────────────────────────
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Everything the card says about one document, and the commit table behind it.
|
|
360
|
-
*
|
|
361
|
-
* `tab`, not `activeTab` — the card is drawn for the pane that mounted it. Both branches of the
|
|
362
|
-
* commit path resolved through FOCUS once, so with two panes the visible card's controls edited
|
|
363
|
-
* whichever document happened to be focused: click "Clear title" on the card in the left pane and
|
|
364
|
-
* the field disappeared from the right pane's document instead.
|
|
365
|
-
*
|
|
366
|
-
* @param {Tab} tab
|
|
367
|
-
* @returns {DocHeaderView}
|
|
368
|
-
*/
|
|
369
|
-
function viewFor(tab: Tab, paneId: string, card: HeaderCard): DocHeaderView {
|
|
370
|
-
const isContent = tab.doc.mode === "content";
|
|
371
|
-
const fm = (tab.doc.content?.frontmatter ?? {}) as Record<string, unknown>;
|
|
372
|
-
// ONE view of the document's head material, whichever realm it lives in: frontmatter keys for a
|
|
373
|
-
// Markdown page, root properties for a JSON one.
|
|
374
|
-
const headDoc = isContent ? buildHeadDoc(tab.doc.document, fm) : tab.doc.document;
|
|
375
|
-
const applyMutation = isContent
|
|
376
|
-
? (fn: (doc: JxMutableNode) => void) => applyContentMutation(tab, render, fn)
|
|
377
|
-
: (fn: (doc: JxMutableNode) => void) => {
|
|
378
|
-
transact(tab, fn);
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
const commits = new Map<string, RowCommit>();
|
|
382
|
-
const rows: DocHeaderRow[] = [titleRow(headDoc, applyMutation, commits)];
|
|
383
|
-
const layout = layoutRow(tab, headDoc, applyMutation, commits);
|
|
384
|
-
if (layout) {
|
|
385
|
-
rows.push(layout);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// ONE call. The old pair of surfaces made two, with two different reserved-key policies.
|
|
389
|
-
const { collection, fields, requiredFields } = collectFmFields(
|
|
390
|
-
tab,
|
|
391
|
-
projectState?.projectConfig,
|
|
392
|
-
RESERVED_FM_KEYS,
|
|
393
|
-
);
|
|
394
|
-
for (const f of fields) {
|
|
395
|
-
rows.push(fieldRow(tab, f.field, f.entry, f.value, requiredFields, commits));
|
|
396
|
-
}
|
|
397
|
-
card.commits = commits;
|
|
398
|
-
|
|
399
|
-
const route = tab.documentPath ? pageRoute(tab.documentPath) : null;
|
|
400
|
-
const raw = rawEntries(headDoc.$head ?? []);
|
|
401
|
-
return {
|
|
402
|
-
collection: collection ? collection.name : "Document",
|
|
403
|
-
expanded: isExpanded(tab.id),
|
|
404
|
-
hasRoute: route !== null,
|
|
405
|
-
rawEntries: raw,
|
|
406
|
-
rawOpen: _rawOpen.has(tab.id),
|
|
407
|
-
rawState: raw.length === 0 ? "empty" : "list",
|
|
408
|
-
region: paneRegion(paneId, "frontmatter"),
|
|
409
|
-
route: route ?? "",
|
|
410
|
-
rows,
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/** A blank row, so every kind carries every field the document's bindings read. */
|
|
415
|
-
function blankRow(key: string, prop: string, label: string): DocHeaderRow {
|
|
416
|
-
return {
|
|
417
|
-
checked: false,
|
|
418
|
-
clearLabel: `Clear ${prop}`,
|
|
419
|
-
hasNote: false,
|
|
420
|
-
hasThumb: false,
|
|
421
|
-
isSet: false,
|
|
422
|
-
key,
|
|
423
|
-
kind: "text",
|
|
424
|
-
label,
|
|
425
|
-
note: "",
|
|
426
|
-
options: [],
|
|
427
|
-
placeholder: "",
|
|
428
|
-
prop,
|
|
429
|
-
thumb: "",
|
|
430
|
-
value: "",
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/** The one head value you type while writing, in both realms. */
|
|
435
|
-
function titleRow(
|
|
436
|
-
headDoc: JxMutableNode,
|
|
437
|
-
applyMutation: (fn: (doc: JxMutableNode) => void) => void,
|
|
438
|
-
commits: Map<string, RowCommit>,
|
|
439
|
-
): DocHeaderRow {
|
|
440
|
-
const title = typeof headDoc.title === "string" ? headDoc.title : "";
|
|
441
|
-
commits.set("title", {
|
|
442
|
-
clear: () =>
|
|
443
|
-
applyMutation((d) => {
|
|
444
|
-
delete d.title;
|
|
445
|
-
}),
|
|
446
|
-
commit: (raw) =>
|
|
447
|
-
applyMutation((d) => {
|
|
448
|
-
const val = String(raw).trim();
|
|
449
|
-
if (val) {
|
|
450
|
-
d.title = val;
|
|
451
|
-
} else {
|
|
452
|
-
delete d.title;
|
|
453
|
-
}
|
|
454
|
-
}),
|
|
455
|
-
});
|
|
456
|
-
return {
|
|
457
|
-
...blankRow("title", "title", "Title"),
|
|
458
|
-
clearLabel: "Clear title",
|
|
459
|
-
isSet: Boolean(title),
|
|
460
|
-
placeholder: "Untitled",
|
|
461
|
-
value: title,
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* The layout picker, or `null` when this document takes none — a component has no layout, and a
|
|
467
|
-
* page whose layouts directory is still being listed has nothing to offer yet.
|
|
468
|
-
*
|
|
469
|
-
* The listing is `head-panel.ts`'s, asked for as data: the Page panel draws the same choices from
|
|
470
|
-
* the same cache, so creating a layout invalidates one thing rather than two.
|
|
471
|
-
*/
|
|
472
|
-
function layoutRow(
|
|
473
|
-
tab: Tab,
|
|
474
|
-
headDoc: JxMutableNode,
|
|
475
|
-
applyMutation: (fn: (doc: JxMutableNode) => void) => void,
|
|
476
|
-
commits: Map<string, RowCommit>,
|
|
477
|
-
): DocHeaderRow | null {
|
|
478
|
-
if (!isPageDocument(tab)) {
|
|
479
|
-
return null;
|
|
480
|
-
}
|
|
481
|
-
const entries = layoutPickerEntries();
|
|
482
|
-
if (entries === null) {
|
|
483
|
-
return null;
|
|
484
|
-
}
|
|
485
|
-
const current = headDoc.$layout;
|
|
486
|
-
const defaultPath = projectState?.projectConfig?.defaults?.layout;
|
|
487
|
-
const defaultLabel = defaultPath ? layoutName(defaultPath) : "";
|
|
488
|
-
const options: DocHeaderChoice[] = [
|
|
489
|
-
{ label: defaultLabel ? `Default (${defaultLabel})` : "Default", value: "__default__" },
|
|
490
|
-
{ label: "None", value: "__none__" },
|
|
491
|
-
...entries.map((l) => ({ label: l.name, value: l.path })),
|
|
492
|
-
];
|
|
493
|
-
commits.set("__layout", {
|
|
494
|
-
clear: () =>
|
|
495
|
-
applyMutation((d) => {
|
|
496
|
-
delete d.$layout;
|
|
497
|
-
}),
|
|
498
|
-
commit: (raw) => {
|
|
499
|
-
const val = String(raw);
|
|
500
|
-
applyMutation((d) => {
|
|
501
|
-
if (val === "__default__") {
|
|
502
|
-
delete d.$layout;
|
|
503
|
-
} else if (val === "__none__") {
|
|
504
|
-
d.$layout = false;
|
|
505
|
-
} else {
|
|
506
|
-
d.$layout = val;
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
invalidateLayoutCache();
|
|
510
|
-
},
|
|
511
|
-
});
|
|
512
|
-
return {
|
|
513
|
-
...blankRow("__layout", "layout", "Layout"),
|
|
514
|
-
isSet: current !== undefined,
|
|
515
|
-
kind: "select",
|
|
516
|
-
options,
|
|
517
|
-
value: current === false ? "__none__" : current || "__default__",
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/** `./layouts/blog-post.json` → `Blog Post`. */
|
|
522
|
-
function layoutName(path: string): string {
|
|
523
|
-
return path
|
|
524
|
-
.replace(/^\.\/layouts\//, "")
|
|
525
|
-
.replace(/\.json$/, "")
|
|
526
|
-
.replaceAll(/[-_]+/g, " ")
|
|
527
|
-
.replaceAll(/\b\w/g, (c: string) => c.toUpperCase());
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* One schema-driven frontmatter field, as the row that draws it and the write that commits it.
|
|
532
|
-
*
|
|
533
|
-
* **What the row LOOKS like is `panels/frontmatter-fields.ts`'s answer, not this module's.** The
|
|
534
|
-
* Navigator's Page panel draws the same field set from the same schemas, and the two surfaces
|
|
535
|
-
* deciding independently that a `$ref` is a picker, that `"uri-reference"` is a media format or
|
|
536
|
-
* that an array is a comma-separated line is exactly how they came to disagree about `title`. What
|
|
537
|
-
* stays here is what the card COMMITS INTO — this tab's frontmatter, through its transaction log.
|
|
538
|
-
*
|
|
539
|
-
* `tab` is a parameter because this used to commit to `activeTab.value` at each of seven widgets,
|
|
540
|
-
* which is right for the Navigator's Document panel and wrong for a card drawn once per pane: a
|
|
541
|
-
* collection field edited on the card in one pane wrote into whichever document had the keyboard.
|
|
542
|
-
*/
|
|
543
|
-
function fieldRow(
|
|
544
|
-
tab: Tab,
|
|
545
|
-
field: string,
|
|
546
|
-
entry: FmSchemaEntry,
|
|
547
|
-
value: unknown,
|
|
548
|
-
requiredFields: Set<string>,
|
|
549
|
-
commits: Map<string, RowCommit>,
|
|
550
|
-
): DocHeaderRow {
|
|
551
|
-
const key = `fm:${field}`;
|
|
552
|
-
const { parse, row } = projectFmField(field, entry, value, requiredFields, { rerender: render });
|
|
553
|
-
commits.set(key, {
|
|
554
|
-
clear: () => transactDoc(tab, (t) => mutateUpdateFrontmatter(t, field)),
|
|
555
|
-
commit: (raw) => transactDoc(tab, (t) => mutateUpdateFrontmatter(t, field, parse(raw))),
|
|
556
|
-
});
|
|
557
|
-
return { ...blankRow(key, field, row.label), ...row, clearLabel: `Clear ${field}` };
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
/**
|
|
561
|
-
* The `$head` entries no structured control owns, listed read-only.
|
|
562
|
-
*
|
|
563
|
-
* Read-only on purpose: the card discloses what is there so the author is never surprised by a tag
|
|
564
|
-
* they cannot see, and the Page panel remains the surface that adds and removes them.
|
|
565
|
-
*/
|
|
566
|
-
function rawEntries(head: JxHeadEntry[]): DocHeaderRawEntry[] {
|
|
567
|
-
return head
|
|
568
|
-
.filter(
|
|
569
|
-
(e: JxHeadEntry) => !isManagedEntry(e) && !isGoogleFontEntry(e) && !isGoogleFontPreconnect(e),
|
|
570
|
-
)
|
|
571
|
-
.map((entry, index) => ({
|
|
572
|
-
key: `raw:${index}`,
|
|
573
|
-
label: entryLabel(entry),
|
|
574
|
-
value: entryValue(entry),
|
|
575
|
-
}));
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// ─── The actions ─────────────────────────────────────────────────────────────
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* What the reader can do on one pane's card.
|
|
582
|
-
*
|
|
583
|
-
* Made once per host and handed to the surface at mount, so every one of them reads the CURRENT
|
|
584
|
-
* commit table rather than closing over the projection that was standing when the card was drawn.
|
|
585
|
-
*/
|
|
586
|
-
function makeActions(card: HeaderCard): DocHeaderActions {
|
|
587
|
-
const flush = (key: string): void => {
|
|
588
|
-
const waiting = card.pending.get(key);
|
|
589
|
-
if (waiting) {
|
|
590
|
-
clearTimeout(waiting.timer);
|
|
591
|
-
card.pending.delete(key);
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
const now = (key: string, raw: string | boolean): void => {
|
|
595
|
-
flush(key);
|
|
596
|
-
card.commits.get(key)?.commit(raw);
|
|
597
|
-
};
|
|
598
|
-
return {
|
|
599
|
-
browse: (key, anchor) => {
|
|
600
|
-
flush(key);
|
|
601
|
-
void mediaPicker().then((m) => {
|
|
602
|
-
if (anchor instanceof HTMLElement) {
|
|
603
|
-
m.showMediaPickerPopover(anchor, (val: string) => {
|
|
604
|
-
card.commits.get(key)?.commit(val);
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
});
|
|
608
|
-
},
|
|
609
|
-
clear: (key) => {
|
|
610
|
-
flush(key);
|
|
611
|
-
card.commits.get(key)?.clear();
|
|
612
|
-
},
|
|
613
|
-
commitText: (key, value) => now(key, value),
|
|
614
|
-
/* Debounced, so the canvas follows the typing without a document write per keystroke. The
|
|
615
|
-
control is NOT reset in the meantime: the projection this commit causes resolves to the text
|
|
616
|
-
already in the field, and a document binding skips a write equal to what the element holds. */
|
|
617
|
-
editText: (key, value) => {
|
|
618
|
-
flush(key);
|
|
619
|
-
const commit = () => {
|
|
620
|
-
card.pending.delete(key);
|
|
621
|
-
card.commits.get(key)?.commit(value);
|
|
622
|
-
};
|
|
623
|
-
card.pending.set(key, { commit, timer: setTimeout(commit, LIVE_PREVIEW) });
|
|
624
|
-
},
|
|
625
|
-
openSeo: () => {
|
|
626
|
-
// The COMMAND, not a local open() — the Page panel offers the same door and neither of them
|
|
627
|
-
// Owns it.
|
|
628
|
-
void activeRegistry()?.run("document.openSeo");
|
|
629
|
-
},
|
|
630
|
-
setBoolean: (key, checked) => now(key, checked),
|
|
631
|
-
setChoice: (key, value) => now(key, value),
|
|
632
|
-
setExpanded: (open) => {
|
|
633
|
-
// Per DOCUMENT, like the Raw head tags disclosure, and also the default for the next one:
|
|
634
|
-
// The reader's last open-or-close is the state every editor opened after it starts in.
|
|
635
|
-
const tab = tabOfPane(card.paneId);
|
|
636
|
-
// The platform also fires `toggle` when the card is DRAWN open, so a toggle that agrees with
|
|
637
|
-
// The state already held is the card's own projection coming back, not the reader. Taking it
|
|
638
|
-
// As a choice would let merely looking at an older, open document reset the default.
|
|
639
|
-
if (!tab || _expanded.get(tab.id) === open) {
|
|
640
|
-
return;
|
|
641
|
-
}
|
|
642
|
-
_expanded.set(tab.id, open);
|
|
643
|
-
try {
|
|
644
|
-
localStorage.setItem(DOC_HEADER_EXPANDED_KEY, String(open));
|
|
645
|
-
} catch {
|
|
646
|
-
// Storage full or unavailable — this card still folds, the next one just opens.
|
|
647
|
-
}
|
|
648
|
-
settle(card);
|
|
649
|
-
},
|
|
650
|
-
setNumber: (key, value) => now(key, value),
|
|
651
|
-
setRawOpen: (open) => {
|
|
652
|
-
// Per DOCUMENT rather than per pane: the same file open in two stages discloses the same
|
|
653
|
-
// Tags, and a flag on the pane would make the two cards disagree about one document.
|
|
654
|
-
const tab = tabOfPane(card.paneId);
|
|
655
|
-
if (!tab) {
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
if (open) {
|
|
659
|
-
_rawOpen.add(tab.id);
|
|
660
|
-
} else {
|
|
661
|
-
_rawOpen.delete(tab.id);
|
|
662
|
-
}
|
|
663
|
-
settle(card);
|
|
664
|
-
},
|
|
665
|
-
upload: (key) => {
|
|
666
|
-
flush(key);
|
|
667
|
-
void mediaPicker().then((m) => {
|
|
668
|
-
m.pickAndUpload((val: string) => {
|
|
669
|
-
card.commits.get(key)?.commit(val);
|
|
670
|
-
});
|
|
671
|
-
});
|
|
672
|
-
},
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Bring a card's scope up to what the reader just did to one of its disclosures.
|
|
678
|
-
*
|
|
679
|
-
* A disclosure's `open` is two-way: the platform moves the element, and the scope that fed it still
|
|
680
|
-
* holds the value it was drawn with. Left there, the next document whose state EQUALS that stale
|
|
681
|
-
* value would project no change, the binding would not run, and the disclosure would stay as the
|
|
682
|
-
* previous document left it.
|
|
683
|
-
*/
|
|
684
|
-
function settle(card: HeaderCard): void {
|
|
685
|
-
paint(card.paneId, card);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* The media picker's two behaviours, imported on the first press.
|
|
690
|
-
*
|
|
691
|
-
* ONE cached promise, deliberately: two dynamic imports of a module in flight at once is the shape
|
|
692
|
-
* that loses its coverage record (see the note in the repository's agent guide), and the file also
|
|
693
|
-
* pulls in the upload pipeline and the media metadata cache — neither of which a card that draws no
|
|
694
|
-
* media field should ever load.
|
|
695
|
-
*/
|
|
696
|
-
let _mediaPicker: Promise<typeof MediaPickerModule> | null = null;
|
|
697
|
-
|
|
698
|
-
function mediaPicker(): Promise<typeof MediaPickerModule> {
|
|
699
|
-
_mediaPicker ??= import("../ui/media-picker");
|
|
700
|
-
return _mediaPicker;
|
|
701
|
-
}
|