@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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* - **Repeater · Switch · Observed Attributes · CSS Properties · CSS Parts → the Logic tab.** Wiring
|
|
10
10
|
* a `$switch` and wiring a click handler are the same task (`panels/events-panel.ts`).
|
|
11
|
-
* - **The Page section → the
|
|
11
|
+
* - **The Page section → the Inspector's Page tab.** `panels/head-panel.ts` owns the one layout
|
|
12
12
|
* picker; this panel drew a second one that could disagree with it.
|
|
13
13
|
* - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (§17.1). Nothing remains here: the
|
|
14
14
|
* only reason adding a breakpoint used to cost you your element selection.
|
|
@@ -43,8 +43,15 @@
|
|
|
43
43
|
|
|
44
44
|
import { getNodeAtPath } from "../store";
|
|
45
45
|
import { effect, effectScope, reactive } from "../reactivity";
|
|
46
|
-
import {
|
|
47
|
-
|
|
46
|
+
import {
|
|
47
|
+
displayTagName,
|
|
48
|
+
isJsonObject,
|
|
49
|
+
isNonNullObject,
|
|
50
|
+
isRef,
|
|
51
|
+
isString,
|
|
52
|
+
isTagExpression,
|
|
53
|
+
} from "@jxsuite/schema/guards";
|
|
54
|
+
import type { JsonValue } from "../types";
|
|
48
55
|
import {
|
|
49
56
|
mutateUpdateAttribute,
|
|
50
57
|
mutateUpdateDef,
|
|
@@ -63,7 +70,7 @@ import {
|
|
|
63
70
|
stringArg,
|
|
64
71
|
stringProperty,
|
|
65
72
|
} from "../commands/command-args";
|
|
66
|
-
import type {
|
|
73
|
+
import type { LayoutHit } from "../canvas/iframe-protocol";
|
|
67
74
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
68
75
|
import { activeRegistry } from "../commands/active-registry";
|
|
69
76
|
import { componentRegistry } from "../files/components";
|
|
@@ -108,6 +115,7 @@ import { clickAnythingTo, openPageAction, staleSelectionMessage } from "./empty-
|
|
|
108
115
|
import { mountMediaPicker, unmountMediaPicker } from "../ui/media-picker";
|
|
109
116
|
import { colorTokens, resolvedColor } from "../ui/color-selector";
|
|
110
117
|
import { mountExpressionEditor } from "../ui/expression-editor";
|
|
118
|
+
import type { ExpressionEditorOpts } from "../ui/expression-editor";
|
|
111
119
|
import {
|
|
112
120
|
loadUsages,
|
|
113
121
|
peekUsages,
|
|
@@ -115,6 +123,7 @@ import {
|
|
|
115
123
|
usageFiles,
|
|
116
124
|
usageHeadline,
|
|
117
125
|
} from "../services/references";
|
|
126
|
+
import type { UsageQuery } from "../services/references";
|
|
118
127
|
import { getPlatform } from "../platform";
|
|
119
128
|
import htmlMeta from "../../data/html-meta.json";
|
|
120
129
|
import { popoverIdsIn } from "@jxsuite/schema/overlays";
|
|
@@ -123,7 +132,6 @@ import { showPromptDialog } from "../ui/layers";
|
|
|
123
132
|
import { emptyContentView, mountContentSurface } from "../surfaces/properties-panel";
|
|
124
133
|
|
|
125
134
|
import type {
|
|
126
|
-
ContentOption,
|
|
127
135
|
ContentPanelActions,
|
|
128
136
|
ContentPanelSurface,
|
|
129
137
|
ContentPanelView,
|
|
@@ -132,21 +140,19 @@ import type {
|
|
|
132
140
|
} from "../surfaces/properties-panel";
|
|
133
141
|
import type {
|
|
134
142
|
JxAttributeValue,
|
|
135
|
-
|
|
143
|
+
JxDocumentValue,
|
|
136
144
|
JxMutableNode,
|
|
137
|
-
JxPrototypeDef,
|
|
138
145
|
JxStateDefinition,
|
|
139
|
-
JxStateObject,
|
|
140
146
|
} from "@jxsuite/schema/types";
|
|
141
|
-
import type { SignalOption } from "../ui/dynamic-slot";
|
|
142
147
|
import type { JxPath } from "../state";
|
|
143
148
|
import type { EffectScope } from "@vue/reactivity";
|
|
149
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
144
150
|
|
|
145
151
|
/** The picker's escape hatch: a popover declared in another file, typed by hand. */
|
|
146
152
|
const POPOVER_TARGET_OTHER = "jx:other";
|
|
147
153
|
|
|
148
154
|
/** The empty row a picker offers so a value can be taken away with the same control that set it. */
|
|
149
|
-
const CLEAR_OPTION:
|
|
155
|
+
const CLEAR_OPTION: SurfaceOption = { label: "—", value: "" };
|
|
150
156
|
|
|
151
157
|
interface HtmlMetaEntry {
|
|
152
158
|
$section: string;
|
|
@@ -157,7 +163,20 @@ interface HtmlMetaEntry {
|
|
|
157
163
|
$input?: string;
|
|
158
164
|
$shorthand?: boolean;
|
|
159
165
|
type?: string;
|
|
160
|
-
|
|
166
|
+
enum?: string[];
|
|
167
|
+
/** Every value in `data/html-meta.json` is a string, a number, a boolean or a list of names. */
|
|
168
|
+
[key: string]: string | number | boolean | string[] | undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Every attribute `data/html-meta.json` describes, by its `$defs` key. */
|
|
172
|
+
const HTML_META_DEFS: ReadonlyMap<string, HtmlMetaEntry> = new Map(Object.entries(htmlMeta.$defs));
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* The node at `path`, typed as what `getNodeAtPath` really returns: `undefined` once the path walks
|
|
176
|
+
* off the tree, which a stale selection (or a sibling's path in a multi-selection) does.
|
|
177
|
+
*/
|
|
178
|
+
function nodeAtPath(doc: JxMutableNode, path: JxPath): JxMutableNode | undefined {
|
|
179
|
+
return getNodeAtPath(doc, path);
|
|
161
180
|
}
|
|
162
181
|
|
|
163
182
|
// ─── The binding vocabulary, shared with the Logic tab ───────────────────────
|
|
@@ -171,7 +190,7 @@ interface HtmlMetaEntry {
|
|
|
171
190
|
* Exported because Content and Logic both offer them and there is one right answer: a `$switch`
|
|
172
191
|
* inside a `$map` can read `$map/item`, and so can the `alt` attribute two nodes below it.
|
|
173
192
|
*/
|
|
174
|
-
export function mapSignalsFor(path: JxPath):
|
|
193
|
+
export function mapSignalsFor(path: JxPath): SurfaceOption[] | null {
|
|
175
194
|
return path.includes("map")
|
|
176
195
|
? [
|
|
177
196
|
{ label: "$map/item", value: "$map/item" },
|
|
@@ -182,13 +201,9 @@ export function mapSignalsFor(path: JxPath): SignalOption[] | null {
|
|
|
182
201
|
|
|
183
202
|
/** State keys a value position may bind to — handlers and Functions are not values. */
|
|
184
203
|
export function bindableSignalNames(doc: JxMutableNode): string[] {
|
|
185
|
-
return Object.entries(doc.state || {})
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
!(d as Record<string, unknown>)?.$handler &&
|
|
189
|
-
(d as JxPrototypeDef)?.$prototype !== "Function",
|
|
190
|
-
)
|
|
191
|
-
.map(([defName]) => defName);
|
|
204
|
+
return Object.entries(doc.state || {}).flatMap(([defName, d]) =>
|
|
205
|
+
isJsonObject(d) && (d.$handler || d.$prototype === "Function") ? [] : [defName],
|
|
206
|
+
);
|
|
192
207
|
}
|
|
193
208
|
|
|
194
209
|
/**
|
|
@@ -198,23 +213,24 @@ export function bindableSignalNames(doc: JxMutableNode): string[] {
|
|
|
198
213
|
* @returns {string}
|
|
199
214
|
*/
|
|
200
215
|
export function defaultAsString(def: JxStateDefinition | undefined) {
|
|
201
|
-
if (!
|
|
216
|
+
if (!isJsonObject(def)) {
|
|
202
217
|
return "";
|
|
203
218
|
}
|
|
204
|
-
const dv =
|
|
219
|
+
const dv = def.default;
|
|
205
220
|
if (dv === undefined) {
|
|
206
221
|
return "";
|
|
207
222
|
}
|
|
208
|
-
|
|
223
|
+
// `null` prints as "null" either way, so only a structure needs JSON.
|
|
224
|
+
return isNonNullObject(dv) ? JSON.stringify(dv) : String(dv);
|
|
209
225
|
}
|
|
210
226
|
|
|
211
227
|
/** Who a bound value comes from, in the fewest words that are true — the chip's donor text. */
|
|
212
|
-
function bindingDonor(value:
|
|
228
|
+
function bindingDonor(value: JxDocumentValue | undefined): string {
|
|
213
229
|
if (isRef(value)) {
|
|
214
230
|
const ref = value.$ref;
|
|
215
231
|
return ref.startsWith("#/state/") ? ref.slice(8) : ref || "nothing yet";
|
|
216
232
|
}
|
|
217
|
-
return
|
|
233
|
+
return isString(value) ? "a template" : "a formula";
|
|
218
234
|
}
|
|
219
235
|
|
|
220
236
|
/**
|
|
@@ -227,12 +243,12 @@ function bindingDonor(value: unknown): string {
|
|
|
227
243
|
* `templateSignalOf`, because both spellings of a template (`${x}` and `${state.x}`) name the same
|
|
228
244
|
* entry.
|
|
229
245
|
*/
|
|
230
|
-
function boundSignalOf(value:
|
|
246
|
+
function boundSignalOf(value: JxDocumentValue | undefined): string | null {
|
|
231
247
|
if (isRef(value)) {
|
|
232
248
|
const ref = value.$ref;
|
|
233
249
|
return ref.startsWith("#/state/") ? (ref.slice(8).split("/")[0] ?? null) : null;
|
|
234
250
|
}
|
|
235
|
-
if (
|
|
251
|
+
if (!isString(value)) {
|
|
236
252
|
return null;
|
|
237
253
|
}
|
|
238
254
|
return /\$\{\s*(?:state\.)?([A-Za-z_$][\w$]*)/.exec(value)?.[1] ?? null;
|
|
@@ -257,18 +273,17 @@ function revealSignal(name: string): void {
|
|
|
257
273
|
* provenance functions differ in everything else, and the question "does this document define
|
|
258
274
|
* `title`?" has one answer that neither of them should have to be handed.
|
|
259
275
|
*/
|
|
260
|
-
function boundProvenance(value:
|
|
276
|
+
function boundProvenance(value: JxDocumentValue | undefined, title: string): FieldProvenance {
|
|
261
277
|
const signal = boundSignalOf(value);
|
|
262
278
|
const document = activeTab.value?.doc.document;
|
|
263
279
|
const known = signal && document ? bindableSignalNames(document).includes(signal) : false;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
};
|
|
280
|
+
const provenance: FieldProvenance = { donor: bindingDonor(value), state: "bound", title };
|
|
281
|
+
// Only when the document actually defines it: a chip that jumps to a row that is not there
|
|
282
|
+
// Would be a worse answer than a chip that does not jump.
|
|
283
|
+
if (known && signal) {
|
|
284
|
+
provenance.onClick = () => revealSignal(signal);
|
|
285
|
+
}
|
|
286
|
+
return provenance;
|
|
272
287
|
}
|
|
273
288
|
|
|
274
289
|
/**
|
|
@@ -294,7 +309,7 @@ export function isComponentDefinitionOpen(node: JxMutableNode): boolean {
|
|
|
294
309
|
*/
|
|
295
310
|
function componentPropProvenance(
|
|
296
311
|
prop: { name: string; default?: unknown; description?: string },
|
|
297
|
-
rawValue:
|
|
312
|
+
rawValue: JxDocumentValue | undefined,
|
|
298
313
|
hasVal: boolean,
|
|
299
314
|
actions: {
|
|
300
315
|
onClear: () => void;
|
|
@@ -313,12 +328,15 @@ function componentPropProvenance(
|
|
|
313
328
|
unset field means this component ships no default for that setting — which is `default`, the
|
|
314
329
|
state that draws nothing, not a badge pointing at itself. */
|
|
315
330
|
if (prop.default !== undefined && !actions.isDefinition) {
|
|
316
|
-
|
|
331
|
+
const inherited: FieldProvenance = {
|
|
317
332
|
donor: "the component default",
|
|
318
333
|
state: "inherited",
|
|
319
334
|
title: `Not set here — the component's default (${String(prop.default)}) applies`,
|
|
320
|
-
...(actions.openDefinition ? { onClick: actions.openDefinition } : {}),
|
|
321
335
|
};
|
|
336
|
+
if (actions.openDefinition) {
|
|
337
|
+
inherited.onClick = actions.openDefinition;
|
|
338
|
+
}
|
|
339
|
+
return inherited;
|
|
322
340
|
}
|
|
323
341
|
return { state: "default" };
|
|
324
342
|
}
|
|
@@ -326,7 +344,7 @@ function componentPropProvenance(
|
|
|
326
344
|
/** Which of §6.7's states an HTML-attribute row is in. Attributes have no third cascade layer. */
|
|
327
345
|
function attributeProvenance(
|
|
328
346
|
attr: string,
|
|
329
|
-
value:
|
|
347
|
+
value: JxAttributeValue | undefined,
|
|
330
348
|
hasVal: boolean,
|
|
331
349
|
onClear: () => void,
|
|
332
350
|
mixedCount = 0,
|
|
@@ -337,7 +355,7 @@ function attributeProvenance(
|
|
|
337
355
|
if (mixedCount > 0) {
|
|
338
356
|
return { donor: String(mixedCount), onClick: onClear, state: "mixed" };
|
|
339
357
|
}
|
|
340
|
-
if (hasVal && (isRef(value) || (
|
|
358
|
+
if (hasVal && (isRef(value) || (isString(value) && value.includes("${")))) {
|
|
341
359
|
return boundProvenance(value, `Bound — ${attr}`);
|
|
342
360
|
}
|
|
343
361
|
return hasVal ? { onClick: onClear, state: "set", title: `Clear ${attr}` } : { state: "default" };
|
|
@@ -353,12 +371,12 @@ function attributeProvenance(
|
|
|
353
371
|
export function mixedAcrossSelection(
|
|
354
372
|
doc: JxMutableNode,
|
|
355
373
|
targets: readonly JxPath[],
|
|
356
|
-
read: (node: JxMutableNode | undefined) =>
|
|
374
|
+
read: (node: JxMutableNode | undefined) => JxDocumentValue | undefined,
|
|
357
375
|
): number {
|
|
358
376
|
if (targets.length < 2) {
|
|
359
377
|
return 0;
|
|
360
378
|
}
|
|
361
|
-
const values = targets.map((path) => read(
|
|
379
|
+
const values = targets.map((path) => read(nodeAtPath(doc, path)));
|
|
362
380
|
return unifyValues(values).mixed ? targets.length : 0;
|
|
363
381
|
}
|
|
364
382
|
|
|
@@ -366,8 +384,8 @@ export function mixedAcrossSelection(
|
|
|
366
384
|
* True when an attribute value is a binding (a `$ref` object or a template string containing
|
|
367
385
|
* `${…}`), so the Link-target special-case must fall back to the raw widget to keep it editable.
|
|
368
386
|
*/
|
|
369
|
-
function isBoundAttrValue(value:
|
|
370
|
-
return isRef(value) || (
|
|
387
|
+
function isBoundAttrValue(value: JxAttributeValue | undefined): boolean {
|
|
388
|
+
return isRef(value) || (isString(value) && value.includes("${"));
|
|
371
389
|
}
|
|
372
390
|
|
|
373
391
|
// ─── Page-route enumeration (for the Link-target Internal picker) ─────────────
|
|
@@ -400,6 +418,16 @@ function routeForPagePath(relPath: string): string {
|
|
|
400
418
|
return isIndex || body.includes(":") ? `/${body}${isIndex ? "/" : ""}` : `/${body}/`;
|
|
401
419
|
}
|
|
402
420
|
|
|
421
|
+
/**
|
|
422
|
+
* What the route walk reads from a listing entry. `path` is optional because the cloud adapter
|
|
423
|
+
* hands back its response body unvalidated, so an entry without one is addressed under its parent.
|
|
424
|
+
*/
|
|
425
|
+
interface ListedEntry {
|
|
426
|
+
name: string;
|
|
427
|
+
path?: string;
|
|
428
|
+
type: string;
|
|
429
|
+
}
|
|
430
|
+
|
|
403
431
|
/**
|
|
404
432
|
* Recursively walk the pages/ tree and populate {@link pageRouteEntries} with derived routes.
|
|
405
433
|
*
|
|
@@ -415,7 +443,7 @@ async function loadPageRouteEntries() {
|
|
|
415
443
|
try {
|
|
416
444
|
const platform = getPlatform();
|
|
417
445
|
const walk = async (dir: string, rel: string): Promise<void> => {
|
|
418
|
-
let listing:
|
|
446
|
+
let listing: readonly ListedEntry[];
|
|
419
447
|
try {
|
|
420
448
|
listing = await platform.listDirectory(dir);
|
|
421
449
|
} catch {
|
|
@@ -519,7 +547,7 @@ interface LadderPlan {
|
|
|
519
547
|
mode: SlotMode;
|
|
520
548
|
offered: SlotMode[];
|
|
521
549
|
/** Every pointer the From data… rung offers, state entries and repeater signals alike. */
|
|
522
|
-
sources:
|
|
550
|
+
sources: SurfaceOption[];
|
|
523
551
|
/**
|
|
524
552
|
* The state entries alone, kept apart from {@link sources} because `slotModeSeed` reads them
|
|
525
553
|
* differently: a fresh Mixed text rung seeds `${state.<first>}` from a state entry and `${}` from
|
|
@@ -527,7 +555,7 @@ interface LadderPlan {
|
|
|
527
555
|
* template instead of naming the signal it had just left.
|
|
528
556
|
*/
|
|
529
557
|
stateDefs: string[];
|
|
530
|
-
extraSignals:
|
|
558
|
+
extraSignals: SurfaceOption[];
|
|
531
559
|
value: JsonValue | undefined;
|
|
532
560
|
onChange: (v?: JsonValue) => void;
|
|
533
561
|
literalDefault: JsonValue | undefined;
|
|
@@ -577,6 +605,12 @@ interface RowPlan {
|
|
|
577
605
|
control?: ((host: HTMLElement) => void) | undefined;
|
|
578
606
|
}
|
|
579
607
|
|
|
608
|
+
/** A row and the plan that reads its gestures back, before {@link withPlan} files the plan. */
|
|
609
|
+
interface PlannedRow {
|
|
610
|
+
row: ContentRowView;
|
|
611
|
+
plan: RowPlan;
|
|
612
|
+
}
|
|
613
|
+
|
|
580
614
|
/** A row view with every field filled in, before the caller narrows it. */
|
|
581
615
|
function blankRow(key: string, prop: string, label: string): ContentRowView {
|
|
582
616
|
return {
|
|
@@ -601,7 +635,6 @@ function blankRow(key: string, prop: string, label: string): ContentRowView {
|
|
|
601
635
|
prop,
|
|
602
636
|
removeLabel: "",
|
|
603
637
|
resolved: "",
|
|
604
|
-
shape: "field",
|
|
605
638
|
source: "fixed",
|
|
606
639
|
sourceLabel: "",
|
|
607
640
|
sourceLocked: false,
|
|
@@ -610,6 +643,7 @@ function blankRow(key: string, prop: string, label: string): ContentRowView {
|
|
|
610
643
|
title: "",
|
|
611
644
|
tokens: [],
|
|
612
645
|
value: "",
|
|
646
|
+
variant: "field",
|
|
613
647
|
};
|
|
614
648
|
}
|
|
615
649
|
|
|
@@ -898,7 +932,7 @@ function openSourceMenu(key: string, anchor: HTMLElement): void {
|
|
|
898
932
|
opener: anchor,
|
|
899
933
|
region: "value-source",
|
|
900
934
|
rows: offered.map((rung) => ({
|
|
901
|
-
checked:
|
|
935
|
+
checked: rung === mode ? ("true" as const) : ("false" as const),
|
|
902
936
|
destructive: false,
|
|
903
937
|
disabled: false,
|
|
904
938
|
dividerAbove: false,
|
|
@@ -906,8 +940,9 @@ function openSourceMenu(key: string, anchor: HTMLElement): void {
|
|
|
906
940
|
title: VALUE_SOURCE_LABELS[rung],
|
|
907
941
|
})),
|
|
908
942
|
run: (id) => {
|
|
909
|
-
|
|
910
|
-
|
|
943
|
+
// The rows ARE `offered`, so a picked id is always one of its rungs.
|
|
944
|
+
const next = offered.find((rung) => rung === id);
|
|
945
|
+
if (next === undefined || next === mode) {
|
|
911
946
|
return;
|
|
912
947
|
}
|
|
913
948
|
/* Leaving From data… seeds an empty Fixed value stash with the signal's declared default, so
|
|
@@ -978,10 +1013,10 @@ function applyChip(
|
|
|
978
1013
|
interface LadderOpts {
|
|
979
1014
|
fieldKey: string;
|
|
980
1015
|
caps: SlotCapsSource;
|
|
981
|
-
value:
|
|
1016
|
+
value: JxDocumentValue | undefined;
|
|
982
1017
|
onChange: (v?: JsonValue) => void;
|
|
983
1018
|
stateDefs: string[];
|
|
984
|
-
extraSignals?:
|
|
1019
|
+
extraSignals?: SurfaceOption[] | null;
|
|
985
1020
|
literalDefault?: JsonValue | undefined;
|
|
986
1021
|
seedFor?: ((mode: SlotMode) => JsonValue | undefined) | undefined;
|
|
987
1022
|
/** The operators this position's grammar admits, when it admits fewer than all of them. */
|
|
@@ -998,7 +1033,7 @@ interface LadderOpts {
|
|
|
998
1033
|
function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void {
|
|
999
1034
|
const caps = slotCaps(opts.caps);
|
|
1000
1035
|
const mode = effectiveSlotMode(opts.fieldKey, opts.value);
|
|
1001
|
-
const sources:
|
|
1036
|
+
const sources: SurfaceOption[] = [
|
|
1002
1037
|
...opts.stateDefs.map((name) => ({ label: name, value: `#/state/${name}` })),
|
|
1003
1038
|
...(opts.extraSignals ?? []),
|
|
1004
1039
|
];
|
|
@@ -1026,6 +1061,9 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
|
|
|
1026
1061
|
seedFor: opts.seedFor,
|
|
1027
1062
|
sources,
|
|
1028
1063
|
stateDefs: opts.stateDefs,
|
|
1064
|
+
/* SAFETY: a ladder position's value was read out of the JSON document (an attribute, a prop, a
|
|
1065
|
+
`tagName`), so it is JSON; `JxRef` and the expression shapes are interfaces, which TypeScript
|
|
1066
|
+
will not match against `JsonObject`'s index signature. */
|
|
1029
1067
|
value: cloneValue(opts.value as JsonValue | undefined),
|
|
1030
1068
|
};
|
|
1031
1069
|
if (mode === "ref") {
|
|
@@ -1046,7 +1084,7 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
|
|
|
1046
1084
|
row.kind = "text";
|
|
1047
1085
|
row.mono = true;
|
|
1048
1086
|
row.placeholder = "${state.…}";
|
|
1049
|
-
row.value = getFieldValue(templateDraft,
|
|
1087
|
+
row.value = getFieldValue(templateDraft, isString(opts.value) ? opts.value : "");
|
|
1050
1088
|
plan.commit = (raw) => opts.onChange(raw);
|
|
1051
1089
|
plan.debounceMs = LIVE_PREVIEW;
|
|
1052
1090
|
plan.draft = templateDraft;
|
|
@@ -1054,22 +1092,26 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
|
|
|
1054
1092
|
return;
|
|
1055
1093
|
}
|
|
1056
1094
|
if (mode === "expression") {
|
|
1057
|
-
const node = (opts.value
|
|
1095
|
+
const node = isJsonObject(opts.value) ? opts.value.$expression : undefined;
|
|
1058
1096
|
row.kind = "control";
|
|
1059
1097
|
plan.commit = undefined;
|
|
1060
1098
|
plan.draft = undefined;
|
|
1099
|
+
const editorOpts: ExpressionEditorOpts = {
|
|
1100
|
+
allowEventRef: false,
|
|
1101
|
+
preview: null,
|
|
1102
|
+
stateDefs: opts.stateDefs,
|
|
1103
|
+
stateEntries: null,
|
|
1104
|
+
};
|
|
1105
|
+
if (opts.operators) {
|
|
1106
|
+
editorOpts.operators = opts.operators;
|
|
1107
|
+
}
|
|
1061
1108
|
plan.control = (host) =>
|
|
1062
1109
|
mountExpressionEditor(
|
|
1063
1110
|
host,
|
|
1064
1111
|
node,
|
|
1112
|
+
// SAFETY: the expression editor hands back the JSON expression node it built from `node`.
|
|
1065
1113
|
(next) => opts.onChange({ $expression: next } as JsonValue),
|
|
1066
|
-
|
|
1067
|
-
allowEventRef: false,
|
|
1068
|
-
...(opts.operators ? { operators: opts.operators } : {}),
|
|
1069
|
-
preview: null,
|
|
1070
|
-
stateDefs: opts.stateDefs,
|
|
1071
|
-
stateEntries: null,
|
|
1072
|
-
},
|
|
1114
|
+
editorOpts,
|
|
1073
1115
|
);
|
|
1074
1116
|
}
|
|
1075
1117
|
}
|
|
@@ -1083,7 +1125,7 @@ function textRow(opts: {
|
|
|
1083
1125
|
value: string;
|
|
1084
1126
|
placeholder?: string;
|
|
1085
1127
|
commit: (raw: string) => void;
|
|
1086
|
-
}):
|
|
1128
|
+
}): PlannedRow {
|
|
1087
1129
|
const row = blankRow(opts.key, opts.prop, opts.label);
|
|
1088
1130
|
row.kind = "text";
|
|
1089
1131
|
row.value = getFieldValue(opts.draft, opts.value);
|
|
@@ -1130,7 +1172,7 @@ function projectPanel(): ContentPanelView {
|
|
|
1130
1172
|
// Layout chrome first: it is mutually exclusive with a document selection, and it is the one
|
|
1131
1173
|
// Target whose name has to say where it came FROM.
|
|
1132
1174
|
if (shell.layoutSelection) {
|
|
1133
|
-
return layoutView(shell.layoutSelection
|
|
1175
|
+
return layoutView(shell.layoutSelection);
|
|
1134
1176
|
}
|
|
1135
1177
|
|
|
1136
1178
|
const selected = primarySelection(tab.session.selection);
|
|
@@ -1138,7 +1180,7 @@ function projectPanel(): ContentPanelView {
|
|
|
1138
1180
|
return emptyView(clickAnythingTo("edit its content"), "", []);
|
|
1139
1181
|
}
|
|
1140
1182
|
const path: JxPath = selected;
|
|
1141
|
-
const node =
|
|
1183
|
+
const node = nodeAtPath(tab.doc.document, path);
|
|
1142
1184
|
if (!node) {
|
|
1143
1185
|
return emptyView(staleSelectionMessage(), "", []);
|
|
1144
1186
|
}
|
|
@@ -1161,7 +1203,7 @@ function projectPanel(): ContentPanelView {
|
|
|
1161
1203
|
}
|
|
1162
1204
|
|
|
1163
1205
|
/** The Layout-element card — what the inspector says when you click page chrome. */
|
|
1164
|
-
function layoutView(selection:
|
|
1206
|
+
function layoutView(selection: LayoutHit): ContentPanelView {
|
|
1165
1207
|
const displayPath = selection.layoutFile || "layout";
|
|
1166
1208
|
return {
|
|
1167
1209
|
...emptyContentView(),
|
|
@@ -1192,26 +1234,26 @@ function sectionsFor(node: JxMutableNode, path: JxPath): ContentSectionView[] {
|
|
|
1192
1234
|
const bindableSignals = bindableSignalNames(doc);
|
|
1193
1235
|
|
|
1194
1236
|
// ── Which attributes this tag has, by section ──
|
|
1195
|
-
const applicableAttrs =
|
|
1196
|
-
for (const [attr, entry] of
|
|
1237
|
+
const applicableAttrs = new Map<string, HtmlMetaEntry>();
|
|
1238
|
+
for (const [attr, entry] of HTML_META_DEFS) {
|
|
1197
1239
|
if (!entry.$elements || entry.$elements.includes(displayTagName(tagName))) {
|
|
1198
1240
|
// The $attr field aliases a $defs key to a different attribute name, so the same attribute
|
|
1199
1241
|
// (e.g. "name") can carry per-element metadata.
|
|
1200
|
-
applicableAttrs
|
|
1242
|
+
applicableAttrs.set(entry.$attr ?? attr, entry);
|
|
1201
1243
|
}
|
|
1202
1244
|
}
|
|
1203
1245
|
const attrSections: Record<string, { name: string; entry: HtmlMetaEntry }[]> = {};
|
|
1204
1246
|
for (const sec of htmlMeta.$sections) {
|
|
1205
1247
|
attrSections[sec.key] = [];
|
|
1206
1248
|
}
|
|
1207
|
-
for (const [attr, entry] of
|
|
1249
|
+
for (const [attr, entry] of applicableAttrs) {
|
|
1208
1250
|
attrSections[entry.$section]?.push({ entry, name: attr });
|
|
1209
1251
|
}
|
|
1210
1252
|
for (const sec of htmlMeta.$sections) {
|
|
1211
1253
|
attrSections[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
|
|
1212
1254
|
}
|
|
1213
1255
|
|
|
1214
|
-
const knownAttrNames = new Set(
|
|
1256
|
+
const knownAttrNames = new Set(applicableAttrs.keys());
|
|
1215
1257
|
if (isCustomInstance) {
|
|
1216
1258
|
const comp = componentRegistry.find((c) => c.tagName === node.tagName);
|
|
1217
1259
|
for (const p of comp?.props ?? []) {
|
|
@@ -1222,7 +1264,7 @@ function sectionsFor(node: JxMutableNode, path: JxPath): ContentSectionView[] {
|
|
|
1222
1264
|
|
|
1223
1265
|
const autoOpen = new Set<string>();
|
|
1224
1266
|
for (const attr of Object.keys(attrs)) {
|
|
1225
|
-
const entry = applicableAttrs
|
|
1267
|
+
const entry = applicableAttrs.get(attr);
|
|
1226
1268
|
if (entry) {
|
|
1227
1269
|
autoOpen.add(entry.$section);
|
|
1228
1270
|
}
|
|
@@ -1328,7 +1370,7 @@ function elementRows(
|
|
|
1328
1370
|
node: JxMutableNode,
|
|
1329
1371
|
path: JxPath,
|
|
1330
1372
|
tagName: string,
|
|
1331
|
-
mapSignals:
|
|
1373
|
+
mapSignals: SurfaceOption[] | null,
|
|
1332
1374
|
bindableSignals: string[],
|
|
1333
1375
|
): ContentRowView[] {
|
|
1334
1376
|
const chosenTag = isTagExpression(node.tagName) ? node.tagName.$expression : null;
|
|
@@ -1385,7 +1427,7 @@ function elementRows(
|
|
|
1385
1427
|
? { $expression: { initial: tagName, operator: "?:", target: null, value: tagName } }
|
|
1386
1428
|
: undefined,
|
|
1387
1429
|
stateDefs: bindableSignals,
|
|
1388
|
-
value: node.tagName
|
|
1430
|
+
value: node.tagName,
|
|
1389
1431
|
});
|
|
1390
1432
|
void chosenTag;
|
|
1391
1433
|
rows.push(withPlan(tag.row, tag.plan));
|
|
@@ -1420,10 +1462,7 @@ function elementRows(
|
|
|
1420
1462
|
const textDraft = draft(draftKey(path, "textContent"));
|
|
1421
1463
|
const text = blankRow("prop|textContent", "textContent", "Text Content");
|
|
1422
1464
|
text.kind = "textarea";
|
|
1423
|
-
text.value = getFieldValue(
|
|
1424
|
-
textDraft,
|
|
1425
|
-
typeof node.textContent === "string" ? node.textContent : "",
|
|
1426
|
-
);
|
|
1465
|
+
text.value = getFieldValue(textDraft, isString(node.textContent) ? node.textContent : "");
|
|
1427
1466
|
const plan: RowPlan = {
|
|
1428
1467
|
commit: writeProperty("textContent"),
|
|
1429
1468
|
debounceMs: LIVE_PREVIEW,
|
|
@@ -1475,7 +1514,7 @@ function elementRows(
|
|
|
1475
1514
|
function componentPropRows(
|
|
1476
1515
|
node: JxMutableNode,
|
|
1477
1516
|
path: JxPath,
|
|
1478
|
-
mapSignals:
|
|
1517
|
+
mapSignals: SurfaceOption[] | null,
|
|
1479
1518
|
definitionOfThis: boolean,
|
|
1480
1519
|
): ContentRowView[] {
|
|
1481
1520
|
const tab = activeTab.value!;
|
|
@@ -1491,9 +1530,14 @@ function componentPropRows(
|
|
|
1491
1530
|
const isNpm = comp.source === "npm";
|
|
1492
1531
|
/* In the definition the "value" of a setting is its DECLARED DEFAULT — the state entry's
|
|
1493
1532
|
`default` — not a per-instance override, so the row reads and writes there instead. */
|
|
1494
|
-
const stateEntries =
|
|
1495
|
-
const currentVals: Record<string,
|
|
1496
|
-
? Object.fromEntries(
|
|
1533
|
+
const stateEntries = tab.doc.document.state ?? {};
|
|
1534
|
+
const currentVals: Readonly<Record<string, JxDocumentValue | undefined>> = definitionOfThis
|
|
1535
|
+
? Object.fromEntries(
|
|
1536
|
+
comp.props.map((prop) => {
|
|
1537
|
+
const entry = stateEntries[prop.name];
|
|
1538
|
+
return [prop.name, isJsonObject(entry) ? entry.default : undefined];
|
|
1539
|
+
}),
|
|
1540
|
+
)
|
|
1497
1541
|
: isNpm
|
|
1498
1542
|
? node.attributes || {}
|
|
1499
1543
|
: node.$props || {};
|
|
@@ -1507,6 +1551,8 @@ function componentPropRows(
|
|
|
1507
1551
|
t,
|
|
1508
1552
|
path,
|
|
1509
1553
|
name,
|
|
1554
|
+
/* SAFETY: `componentProp` offers the literal, ref and template rungs only, so what
|
|
1555
|
+
reaches here is a control's string or `true`, a `{ $ref }`, or a template string. */
|
|
1510
1556
|
v === "" ? undefined : (v as JxAttributeValue | undefined),
|
|
1511
1557
|
),
|
|
1512
1558
|
)
|
|
@@ -1537,7 +1583,9 @@ function componentPropRows(
|
|
|
1537
1583
|
if (isMediaFormat(prop.format)) {
|
|
1538
1584
|
row.kind = "control";
|
|
1539
1585
|
plan.control = (host) =>
|
|
1540
|
-
mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v)
|
|
1586
|
+
mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v), {
|
|
1587
|
+
images: prop.format === "image",
|
|
1588
|
+
});
|
|
1541
1589
|
} else if (prop.format === "color") {
|
|
1542
1590
|
row.kind = "color";
|
|
1543
1591
|
row.tokens = colorTokens();
|
|
@@ -1566,6 +1614,8 @@ function componentPropRows(
|
|
|
1566
1614
|
row.value = staticVal;
|
|
1567
1615
|
row.options = [
|
|
1568
1616
|
CLEAR_OPTION,
|
|
1617
|
+
/* SAFETY: `parseCemType` returns kind "combobox" only with `options` read from the capture
|
|
1618
|
+
group of `'([^']*)'`, which takes part in every match, so each option is a string. */
|
|
1569
1619
|
...(parsed.options as string[]).map((o) => ({ label: camelToLabel(o), value: o })),
|
|
1570
1620
|
];
|
|
1571
1621
|
plan.commit = (raw) => onChange(raw || undefined);
|
|
@@ -1599,7 +1649,7 @@ function componentPropRows(
|
|
|
1599
1649
|
// "→ the component definition" would open the document already in front of you.
|
|
1600
1650
|
isDefinition: definitionOfThis,
|
|
1601
1651
|
onClear: () => updateFn(prop.name),
|
|
1602
|
-
|
|
1652
|
+
openDefinition,
|
|
1603
1653
|
}),
|
|
1604
1654
|
);
|
|
1605
1655
|
rows.push(withPlan(row, plan));
|
|
@@ -1633,14 +1683,14 @@ interface AttrCtx {
|
|
|
1633
1683
|
doc: JxMutableNode;
|
|
1634
1684
|
targets: JxPath[];
|
|
1635
1685
|
tagName: string;
|
|
1636
|
-
mapSignals:
|
|
1686
|
+
mapSignals: SurfaceOption[] | null;
|
|
1637
1687
|
bindableSignals: string[];
|
|
1638
1688
|
}
|
|
1639
1689
|
|
|
1640
1690
|
function attributeRow(
|
|
1641
1691
|
attr: string,
|
|
1642
1692
|
entry: HtmlMetaEntry,
|
|
1643
|
-
value:
|
|
1693
|
+
value: JxAttributeValue | undefined,
|
|
1644
1694
|
ctx: AttrCtx,
|
|
1645
1695
|
): ContentRowView {
|
|
1646
1696
|
const { doc, node, path, tagName, targets } = ctx;
|
|
@@ -1652,6 +1702,8 @@ function attributeRow(
|
|
|
1652
1702
|
const commitAttr = (v?: JsonValue) =>
|
|
1653
1703
|
transactDoc(activeTab.value!, (t) => {
|
|
1654
1704
|
for (const target of targets) {
|
|
1705
|
+
/* SAFETY: `attribute` offers the literal, ref and template rungs only, so what reaches here
|
|
1706
|
+
is a control's string, a `{ $ref }`, or a template string. */
|
|
1655
1707
|
mutateUpdateAttribute(t, target, attr, v as JxAttributeValue | undefined);
|
|
1656
1708
|
}
|
|
1657
1709
|
});
|
|
@@ -1680,14 +1732,8 @@ function attributeRow(
|
|
|
1680
1732
|
if (attr === "target") {
|
|
1681
1733
|
const row = blankRow(key, attr, label);
|
|
1682
1734
|
row.kind = "select";
|
|
1683
|
-
row.value =
|
|
1684
|
-
row.options = [
|
|
1685
|
-
CLEAR_OPTION,
|
|
1686
|
-
...(Array.isArray(entry.enum) ? (entry.enum as string[]) : []).map((o) => ({
|
|
1687
|
-
label: o,
|
|
1688
|
-
value: o,
|
|
1689
|
-
})),
|
|
1690
|
-
];
|
|
1735
|
+
row.value = isString(node.attributes?.target) ? node.attributes.target : "";
|
|
1736
|
+
row.options = [CLEAR_OPTION, ...(entry.enum ?? []).map((o) => ({ label: o, value: o }))];
|
|
1691
1737
|
const plan: RowPlan = { commit: (raw) => commitAttr(raw || undefined), debounceMs: 0 };
|
|
1692
1738
|
applyChip(row, plan, attr, chip());
|
|
1693
1739
|
return withPlan(row, plan);
|
|
@@ -1699,10 +1745,10 @@ function attributeRow(
|
|
|
1699
1745
|
if (entry.$input === "popover-target" && !isBoundAttrValue(value)) {
|
|
1700
1746
|
const row = blankRow(key, attr, label);
|
|
1701
1747
|
row.kind = "select";
|
|
1702
|
-
row.value =
|
|
1748
|
+
row.value = isString(value) ? value : "";
|
|
1703
1749
|
row.options = [
|
|
1704
1750
|
CLEAR_OPTION,
|
|
1705
|
-
...popoverIdsIn(
|
|
1751
|
+
...popoverIdsIn(activeTab.value?.doc.document ?? {}, {
|
|
1706
1752
|
popoverTags: POPOVER_TAGS,
|
|
1707
1753
|
}).map((id) => ({ label: id, value: id })),
|
|
1708
1754
|
{ label: "Type an id…", value: POPOVER_TARGET_OTHER },
|
|
@@ -1740,17 +1786,13 @@ function attributeRow(
|
|
|
1740
1786
|
row.kind = "control";
|
|
1741
1787
|
const staticVal = isRef(value) ? "" : String(value || "");
|
|
1742
1788
|
plan.control = (host) =>
|
|
1743
|
-
mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined)
|
|
1789
|
+
mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined), {
|
|
1790
|
+
images: entry.format === "image",
|
|
1791
|
+
});
|
|
1744
1792
|
} else if (type === "select") {
|
|
1745
1793
|
row.kind = "select";
|
|
1746
1794
|
row.value = isRef(value) ? "" : String(value || "");
|
|
1747
|
-
row.options = [
|
|
1748
|
-
CLEAR_OPTION,
|
|
1749
|
-
...(Array.isArray(entry.enum) ? (entry.enum as string[]) : []).map((o) => ({
|
|
1750
|
-
label: o,
|
|
1751
|
-
value: o,
|
|
1752
|
-
})),
|
|
1753
|
-
];
|
|
1795
|
+
row.options = [CLEAR_OPTION, ...(entry.enum ?? []).map((o) => ({ label: o, value: o }))];
|
|
1754
1796
|
plan.commit = (raw) => commitAttr(raw || undefined);
|
|
1755
1797
|
plan.debounceMs = 0;
|
|
1756
1798
|
} else {
|
|
@@ -1772,6 +1814,15 @@ function attributeRow(
|
|
|
1772
1814
|
return withPlan(row, plan);
|
|
1773
1815
|
}
|
|
1774
1816
|
|
|
1817
|
+
/** The Link row's kinds, in the order its picker lists them. */
|
|
1818
|
+
const LINK_KIND_OPTIONS = [
|
|
1819
|
+
{ label: "Internal Page", value: "internal" },
|
|
1820
|
+
{ label: "External URL", value: "external" },
|
|
1821
|
+
{ label: "Anchor", value: "anchor" },
|
|
1822
|
+
{ label: "Email", value: "mailto" },
|
|
1823
|
+
{ label: "Phone", value: "tel" },
|
|
1824
|
+
] as const satisfies readonly { label: string; value: LinkKind }[];
|
|
1825
|
+
|
|
1775
1826
|
/**
|
|
1776
1827
|
* The Link target: a kind and a value over one `href`.
|
|
1777
1828
|
*
|
|
@@ -1780,7 +1831,7 @@ function attributeRow(
|
|
|
1780
1831
|
* `mailto:a@b.com`. Internal targets offer the routes enumerated from the `pages/` tree.
|
|
1781
1832
|
*/
|
|
1782
1833
|
function linkRow(key: string, label: string, node: JxMutableNode, path: JxPath): ContentRowView {
|
|
1783
|
-
const raw =
|
|
1834
|
+
const raw = isString(node.attributes?.href) ? node.attributes.href : "";
|
|
1784
1835
|
const { kind, value } = classifyHref(raw);
|
|
1785
1836
|
const commit = (nextKind: LinkKind, nextValue: string) => {
|
|
1786
1837
|
const composed = composeHref(nextKind, nextValue);
|
|
@@ -1792,16 +1843,16 @@ function linkRow(key: string, label: string, node: JxMutableNode, path: JxPath):
|
|
|
1792
1843
|
const row = blankRow(key, "href", label);
|
|
1793
1844
|
row.kind = "link";
|
|
1794
1845
|
row.linkKind = kind;
|
|
1795
|
-
row.kindOptions =
|
|
1796
|
-
{ label: "Internal Page", value: "internal" },
|
|
1797
|
-
{ label: "External URL", value: "external" },
|
|
1798
|
-
{ label: "Anchor", value: "anchor" },
|
|
1799
|
-
{ label: "Email", value: "mailto" },
|
|
1800
|
-
{ label: "Phone", value: "tel" },
|
|
1801
|
-
];
|
|
1846
|
+
row.kindOptions = LINK_KIND_OPTIONS.map((option) => ({ ...option }));
|
|
1802
1847
|
const plan: RowPlan = {
|
|
1803
1848
|
commit: (next) => commit(kind, next),
|
|
1804
|
-
commitKind: (nextKind) =>
|
|
1849
|
+
commitKind: (nextKind) => {
|
|
1850
|
+
// The picker's options ARE `LINK_KIND_OPTIONS`, so a picked kind is always one of them.
|
|
1851
|
+
const picked = LINK_KIND_OPTIONS.find((option) => option.value === nextKind);
|
|
1852
|
+
if (picked) {
|
|
1853
|
+
commit(picked.value, value);
|
|
1854
|
+
}
|
|
1855
|
+
},
|
|
1805
1856
|
debounceMs: INPUT_DEBOUNCE,
|
|
1806
1857
|
};
|
|
1807
1858
|
|
|
@@ -1854,7 +1905,7 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
|
|
|
1854
1905
|
const nameKey = draft(`kvname:${path.join("/")}:${attr}`);
|
|
1855
1906
|
const valueKey = draft(`kvval:${path.join("/")}:${attr}`);
|
|
1856
1907
|
const row = blankRow(key, attr, `${attr} value`);
|
|
1857
|
-
row.
|
|
1908
|
+
row.variant = "kv";
|
|
1858
1909
|
row.name = getFieldValue(nameKey, attr);
|
|
1859
1910
|
row.value = getFieldValue(valueKey, String(val));
|
|
1860
1911
|
row.removeLabel = `Remove ${attr}`;
|
|
@@ -1890,6 +1941,15 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
|
|
|
1890
1941
|
|
|
1891
1942
|
// ─── Usage (§9.1.1) ──────────────────────────────────────────────────────────
|
|
1892
1943
|
|
|
1944
|
+
/** The usage question for a component: its tag, and its definition file when the library knows it. */
|
|
1945
|
+
function usageQueryFor(tagName: string, componentPath: string | null): UsageQuery {
|
|
1946
|
+
const query: UsageQuery = { tagName };
|
|
1947
|
+
if (componentPath) {
|
|
1948
|
+
query.path = componentPath;
|
|
1949
|
+
}
|
|
1950
|
+
return query;
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1893
1953
|
/**
|
|
1894
1954
|
* The component instance's usage line — "Used on 7 pages →", expanding to the files.
|
|
1895
1955
|
*
|
|
@@ -1901,7 +1961,7 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
|
|
|
1901
1961
|
* check" and "nothing uses this" are the two answers a user must never confuse.
|
|
1902
1962
|
*/
|
|
1903
1963
|
function usagesSection(tagName: string, componentPath: string | null): ContentSectionView | null {
|
|
1904
|
-
const query =
|
|
1964
|
+
const query = usageQueryFor(tagName, componentPath);
|
|
1905
1965
|
const state = peekUsages(query);
|
|
1906
1966
|
// ONE gate, and it is the peek itself: a host with no `findReferences` answers "unsupported"
|
|
1907
1967
|
// Synchronously, and the section does not exist.
|
|
@@ -1936,7 +1996,7 @@ function usagesSection(tagName: string, componentPath: string | null): ContentSe
|
|
|
1936
1996
|
} else {
|
|
1937
1997
|
for (const file of files) {
|
|
1938
1998
|
const row = blankRow(`usage|${file.path}`, file.path, file.path);
|
|
1939
|
-
row.
|
|
1999
|
+
row.variant = "file";
|
|
1940
2000
|
row.text = file.path;
|
|
1941
2001
|
row.detail = String(file.count);
|
|
1942
2002
|
row.title = file.refs.map((r) => `${r.refType} ${r.ref} ×${r.count}`).join(", ");
|
|
@@ -1957,7 +2017,7 @@ function usagesSection(tagName: string, componentPath: string | null): ContentSe
|
|
|
1957
2017
|
|
|
1958
2018
|
function noteRow(key: string, text: string): ContentRowView {
|
|
1959
2019
|
const row = blankRow(key, key, "");
|
|
1960
|
-
row.
|
|
2020
|
+
row.variant = "note";
|
|
1961
2021
|
row.text = text;
|
|
1962
2022
|
plans.set(key, { debounceMs: 0 });
|
|
1963
2023
|
return row;
|
|
@@ -1965,7 +2025,7 @@ function noteRow(key: string, text: string): ContentRowView {
|
|
|
1965
2025
|
|
|
1966
2026
|
function actionRow(key: string, prop: string, text: string, run: () => void): ContentRowView {
|
|
1967
2027
|
const row = blankRow(key, prop, text);
|
|
1968
|
-
row.
|
|
2028
|
+
row.variant = "action";
|
|
1969
2029
|
row.text = text;
|
|
1970
2030
|
return withPlan(row, { action: run, debounceMs: 0 });
|
|
1971
2031
|
}
|
|
@@ -2030,9 +2090,7 @@ export function inspectorCommands(): AnyCommand[] {
|
|
|
2030
2090
|
}
|
|
2031
2091
|
const componentPath = componentRegistry.find((c) => c.tagName === tagName)?.path ?? null;
|
|
2032
2092
|
setInspectorSection(USAGES_SECTION, true);
|
|
2033
|
-
void loadUsages(
|
|
2034
|
-
renderPropertiesPanel(),
|
|
2035
|
-
);
|
|
2093
|
+
void loadUsages(usageQueryFor(tagName, componentPath)).then(() => renderPropertiesPanel());
|
|
2036
2094
|
},
|
|
2037
2095
|
title: "Find Usages",
|
|
2038
2096
|
},
|
|
@@ -2053,8 +2111,8 @@ function componentSelectionTag(): string | null {
|
|
|
2053
2111
|
if (!tab || !selection) {
|
|
2054
2112
|
return null;
|
|
2055
2113
|
}
|
|
2056
|
-
const node =
|
|
2057
|
-
const tagName =
|
|
2114
|
+
const node = nodeAtPath(tab.doc.document, selection);
|
|
2115
|
+
const tagName = isString(node?.tagName) ? node.tagName : "";
|
|
2058
2116
|
return tagName.includes("-") ? tagName : null;
|
|
2059
2117
|
}
|
|
2060
2118
|
|