@jxsuite/studio 6.1.0 → 6.1.2
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/dist/chunks/2020-f2gkpy8d.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-5g0ag7c0.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-pxg4ap1e.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-qbj760tx.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-anyrgzvb.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-v2bvmbjj.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-txjjzrsm.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-cpxkgjrj.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/studio-y64hrt8p.js +12 -0
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -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-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/tsMode-sf49ee9x.js +14 -0
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +98 -98
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +11 -11
- 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/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +66 -42
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +163 -64
- 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 +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +203 -118
- package/src/canvas/iframe-inline-edit.ts +69 -32
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +37 -26
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +15 -16
- package/src/canvas/iframe-render.ts +41 -36
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- 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/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -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/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/defaults.ts +4 -1
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +10 -8
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- 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 +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +87 -47
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +6 -1
- package/src/files/serialize-document.ts +2 -2
- 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 +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- 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 +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- 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 +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- 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 +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- 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 +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +55 -22
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +254 -216
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +174 -127
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- 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 +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- 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 +18 -12
- 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 +8 -7
- 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 +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +39 -77
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- 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.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- 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/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- 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/git-panel.ts +7 -15
- 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.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +25 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -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.ts +5 -6
- 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.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -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.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +126 -73
- package/src/surfaces/rail.ts +38 -12
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- 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.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- 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 +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/tabs/typing.ts +31 -0
- package/src/types.ts +32 -17
- 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 +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- 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 +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +103 -74
- 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/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 +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +47 -36
- package/dist/chunks/2020-nkxms0ay.js +0 -4
- package/dist/chunks/adapter-m948ab5f.js +0 -4
- package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
- package/dist/chunks/cf-settings-356xdtne.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-yk3t844e.js +0 -4
- package/dist/chunks/content-source-bawmyc09.js +0 -4
- package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-6sc8nacq.js +0 -4
- package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
- package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
- package/dist/chunks/file-ops-gye0qw56.js +0 -4
- package/dist/chunks/files-dmc2xvcq.js +0 -4
- package/dist/chunks/format-host-t76b53f8.js +0 -4
- package/dist/chunks/fs-events-cg4tpz06.js +0 -4
- package/dist/chunks/git-panel-yef7bshy.js +0 -4
- package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
- package/dist/chunks/icons-qbh8akb1.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-tmz30gfp.js +0 -4
- package/dist/chunks/index-nag78a9h.js +0 -4
- package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
- package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
- package/dist/chunks/layers-fvz99859.js +0 -4
- package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-9agdspkt.js +0 -4
- package/dist/chunks/media-picker-rhjvyy00.js +0 -4
- package/dist/chunks/menu-2e4y9j7b.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
- package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
- package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
- package/dist/chunks/notify-h3www560.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-hz34wcd7.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
- package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
- package/dist/chunks/references-2cgdxnb8.js +0 -4
- package/dist/chunks/right-panel-jf856w5w.js +0 -4
- package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0f55h9ye.js +0 -5
- package/dist/chunks/studio-0sqdhnew.js +0 -12
- package/dist/chunks/studio-19x1c75w.js +0 -5
- package/dist/chunks/studio-2sqcndak.js +0 -5
- package/dist/chunks/studio-3aey7dd3.js +0 -5
- package/dist/chunks/studio-3bpdkq2s.js +0 -5
- package/dist/chunks/studio-47y6fbpf.js +0 -5
- package/dist/chunks/studio-4m3826v2.js +0 -5
- package/dist/chunks/studio-4nx2dj1g.js +0 -4
- package/dist/chunks/studio-4xv5s47r.js +0 -9
- package/dist/chunks/studio-5g4t8v6w.js +0 -5
- package/dist/chunks/studio-5py436sf.js +0 -5
- package/dist/chunks/studio-77kt594t.js +0 -5
- package/dist/chunks/studio-8f87n763.js +0 -10
- package/dist/chunks/studio-8mb00b84.js +0 -5
- package/dist/chunks/studio-8p51gq2h.js +0 -6
- package/dist/chunks/studio-954ds834.js +0 -5
- package/dist/chunks/studio-9ft45c83.js +0 -9
- package/dist/chunks/studio-a2138x5k.js +0 -7
- package/dist/chunks/studio-a9yzstqj.js +0 -5
- package/dist/chunks/studio-acdksxx6.js +0 -5
- package/dist/chunks/studio-ar8jcf2y.js +0 -5
- package/dist/chunks/studio-bmn4mn9j.js +0 -7
- package/dist/chunks/studio-e7xxa0sj.js +0 -5
- package/dist/chunks/studio-ecaz25vk.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-fzdywr6p.js +0 -9
- package/dist/chunks/studio-g5fmf0c1.js +0 -5
- package/dist/chunks/studio-g7nse7zb.js +0 -5
- package/dist/chunks/studio-geq1ea6k.js +0 -14
- package/dist/chunks/studio-ghkb32r8.js +0 -5
- package/dist/chunks/studio-ghrhy2y7.js +0 -5
- package/dist/chunks/studio-grawhey1.js +0 -5
- package/dist/chunks/studio-h0xgswew.js +0 -5
- package/dist/chunks/studio-h9c4p2tx.js +0 -5
- package/dist/chunks/studio-jyzj5cxs.js +0 -5
- package/dist/chunks/studio-mgx8yhnz.js +0 -64
- package/dist/chunks/studio-mpb04y1d.js +0 -6
- package/dist/chunks/studio-n17mty64.js +0 -5
- package/dist/chunks/studio-nwh2eqsk.js +0 -6
- package/dist/chunks/studio-q1h883bt.js +0 -16
- package/dist/chunks/studio-q4tv82h7.js +0 -9
- package/dist/chunks/studio-qpqa7vk3.js +0 -5
- package/dist/chunks/studio-qqz8e5gk.js +0 -5
- package/dist/chunks/studio-qvasen3f.js +0 -5
- package/dist/chunks/studio-rggdb3hm.js +0 -5
- package/dist/chunks/studio-sghy936h.js +0 -4
- package/dist/chunks/studio-skprc6ef.js +0 -5
- package/dist/chunks/studio-tt2nactf.js +0 -5
- package/dist/chunks/studio-tyasmc39.js +0 -5
- package/dist/chunks/studio-vk9ezads.js +0 -5
- package/dist/chunks/studio-vzacdfsc.js +0 -4
- package/dist/chunks/studio-w4c0xmrw.js +0 -5
- package/dist/chunks/studio-wfjqhhbk.js +0 -5
- package/dist/chunks/studio-wgh5kxpj.js +0 -5
- package/dist/chunks/studio-xasj0796.js +0 -5
- package/dist/chunks/studio-y78s8r2n.js +0 -5
- package/dist/chunks/studio-z8w183sh.js +0 -5
- package/dist/chunks/studio-zscd9ty4.js +0 -928
- package/dist/chunks/studio-zxp13sss.js +0 -7
- package/dist/chunks/studio-zygnmm01.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-gr0m4dzr.js +0 -14
- package/dist/chunks/workspace-m15qtcqp.js +0 -4
- package/dist/chunks/ws-client-nf61frr1.js +0 -4
package/src/panels/dnd.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
monitorForElements,
|
|
11
11
|
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
12
12
|
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
|
13
|
-
import { displayTagName } from "@jxsuite/schema/guards";
|
|
13
|
+
import { displayTagName, isNumber } from "@jxsuite/schema/guards";
|
|
14
14
|
import { disableNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview";
|
|
15
15
|
import {
|
|
16
16
|
attachInstruction,
|
|
@@ -38,8 +38,10 @@ import { defaultDef, unsafeTags } from "./shared";
|
|
|
38
38
|
import { elementAtPoint } from "../utils/geometry";
|
|
39
39
|
import type { JxPath } from "../state";
|
|
40
40
|
import type { Tab } from "../tabs/tab";
|
|
41
|
-
import type {
|
|
41
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
42
42
|
import type { ComponentEntry } from "../files/components.js";
|
|
43
|
+
import type { ElementDragPayload } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
44
|
+
import type { DropTargetRecord } from "@atlaskit/pragmatic-drag-and-drop/types";
|
|
43
45
|
|
|
44
46
|
interface DragCanDragArgs {
|
|
45
47
|
element: HTMLElement;
|
|
@@ -51,17 +53,10 @@ interface DragPreviewArgs {
|
|
|
51
53
|
nativeSetDragImage: ((image: Element, x: number, y: number) => void) | null;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
interface DragSelfArgs {
|
|
59
|
-
self: { data: Record<string, unknown> };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
interface DragMonitorDropArgs {
|
|
63
|
-
source: { data: Record<string, unknown>; element: HTMLElement };
|
|
64
|
-
location: { current: { dropTargets: { data: Record<string, unknown> }[] } };
|
|
56
|
+
/** Where a drop instruction inserts: the parent's path and the index among its children. */
|
|
57
|
+
interface DropSlot {
|
|
58
|
+
parent: JxPath;
|
|
59
|
+
index: number;
|
|
65
60
|
}
|
|
66
61
|
|
|
67
62
|
/**
|
|
@@ -122,23 +117,25 @@ export function registerLayersDnD() {
|
|
|
122
117
|
view.dndCleanups = [];
|
|
123
118
|
_layersFrame = requestAnimationFrame(() => {
|
|
124
119
|
_layersFrame = null;
|
|
125
|
-
const container = leftPanel?.querySelector(OUTLINE_ROOT)
|
|
120
|
+
const container = leftPanel?.querySelector<HTMLElement>(OUTLINE_ROOT);
|
|
126
121
|
if (!container) {
|
|
127
122
|
return;
|
|
128
123
|
}
|
|
129
124
|
|
|
130
|
-
for (const row of container.querySelectorAll("[data-dnd-row]")
|
|
131
|
-
|
|
125
|
+
for (const row of container.querySelectorAll<HTMLElement>("[data-dnd-row]")) {
|
|
126
|
+
/* SAFETY: every `[data-dnd-row]` row is a `jx-tree-item` from panel-outline.json, and the
|
|
127
|
+
element reflects its `value` (the row's path key) onto the host as `data-value`. */
|
|
128
|
+
const rowPath: JxPath = (row.dataset.value as string)
|
|
132
129
|
.split("/")
|
|
133
|
-
.map((s: string) => (/^\d+$/.test(s) ? Math.trunc(Number(s)) : s))
|
|
134
|
-
const rowDepth = Math.trunc(Number(row.dataset.dndDepth
|
|
130
|
+
.map((s: string) => (/^\d+$/.test(s) ? Math.trunc(Number(s)) : s));
|
|
131
|
+
const rowDepth = Math.trunc(Number(row.dataset.dndDepth)) || 0;
|
|
135
132
|
const isVoid = Object.hasOwn(row.dataset, "dndVoid");
|
|
136
133
|
const isExpanded = Object.hasOwn(row.dataset, "dndExpanded");
|
|
137
134
|
|
|
138
135
|
const cleanup = combine(
|
|
139
136
|
draggable({
|
|
140
137
|
canDrag({ element: _el, input }: DragCanDragArgs) {
|
|
141
|
-
const target = elementAtPoint(input.clientX, input.clientY)
|
|
138
|
+
const target = elementAtPoint(input.clientX, input.clientY);
|
|
142
139
|
if (target?.closest(OUTLINE_ACTIONS)) {
|
|
143
140
|
return false;
|
|
144
141
|
}
|
|
@@ -169,9 +166,10 @@ export function registerLayersDnD() {
|
|
|
169
166
|
}),
|
|
170
167
|
dropTargetForElements({
|
|
171
168
|
element: row,
|
|
172
|
-
canDrop({ source }
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
canDrop({ source }) {
|
|
170
|
+
// Only a tree-node drag carries a path array; a file-tree drag's `path` is a string.
|
|
171
|
+
const srcPath = source.data.path;
|
|
172
|
+
if (Array.isArray(srcPath) && isAncestor(srcPath, rowPath)) {
|
|
175
173
|
return false;
|
|
176
174
|
}
|
|
177
175
|
return true;
|
|
@@ -193,12 +191,12 @@ export function registerLayersDnD() {
|
|
|
193
191
|
input,
|
|
194
192
|
mode: isExpanded ? "expanded" : "standard",
|
|
195
193
|
},
|
|
196
|
-
)
|
|
194
|
+
);
|
|
197
195
|
},
|
|
198
|
-
onDragEnter({ self }
|
|
196
|
+
onDragEnter({ self }) {
|
|
199
197
|
showLayerDropGap(row, self.data, container);
|
|
200
198
|
},
|
|
201
|
-
onDrag({ self }
|
|
199
|
+
onDrag({ self }) {
|
|
202
200
|
showLayerDropGap(row, self.data, container);
|
|
203
201
|
},
|
|
204
202
|
// No onDragLeave clear — the gap persists while the pointer crosses dead space
|
|
@@ -213,7 +211,7 @@ export function registerLayersDnD() {
|
|
|
213
211
|
|
|
214
212
|
// Global monitor
|
|
215
213
|
const monitorCleanup = monitorForElements({
|
|
216
|
-
onDrop({ source, location }
|
|
214
|
+
onDrop({ source, location }) {
|
|
217
215
|
clearLayerDropGap(container);
|
|
218
216
|
const [target] = location.current.dropTargets;
|
|
219
217
|
if (!target) {
|
|
@@ -224,7 +222,13 @@ export function registerLayersDnD() {
|
|
|
224
222
|
return;
|
|
225
223
|
}
|
|
226
224
|
const srcData = source.data;
|
|
227
|
-
|
|
225
|
+
/* Only an Outline row's data carries a path. The Logic tab's statement rows attach tree-item
|
|
226
|
+
instructions too, and the drags they accept (statements) are ones applyDropInstruction
|
|
227
|
+
ignores, so a drop there has nothing to apply. */
|
|
228
|
+
const targetPath = target.data.path;
|
|
229
|
+
if (!Array.isArray(targetPath)) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
228
232
|
|
|
229
233
|
// If the source had children, persist collapse at the new location
|
|
230
234
|
const srcRow = srcData.type === "tree-node" && source.element;
|
|
@@ -243,7 +247,7 @@ export function registerLayersDnD() {
|
|
|
243
247
|
}
|
|
244
248
|
}
|
|
245
249
|
},
|
|
246
|
-
onDropTargetChange({ location }
|
|
250
|
+
onDropTargetChange({ location }) {
|
|
247
251
|
// Clear the layer gap when the drag moves onto a non-tree target (e.g. a canvas
|
|
248
252
|
// Element). When there is no target at all, keep the gap so it persists.
|
|
249
253
|
const [inner] = location.current.dropTargets;
|
|
@@ -259,14 +263,12 @@ export function registerLayersDnD() {
|
|
|
259
263
|
/** Register DnD on component rows — called from renderLeftPanel when tab=components */
|
|
260
264
|
export function registerComponentsDnD() {
|
|
261
265
|
requestAnimationFrame(() => {
|
|
262
|
-
const container = leftPanel?.querySelector(".components-section")
|
|
266
|
+
const container = leftPanel?.querySelector<HTMLElement>(".components-section");
|
|
263
267
|
if (!container) {
|
|
264
268
|
return;
|
|
265
269
|
}
|
|
266
270
|
|
|
267
|
-
for (const row of container.querySelectorAll(
|
|
268
|
-
"[data-component-tag]",
|
|
269
|
-
) as NodeListOf<HTMLElement>) {
|
|
271
|
+
for (const row of container.querySelectorAll<HTMLElement>("[data-component-tag]")) {
|
|
270
272
|
const tagName = row.dataset.componentTag;
|
|
271
273
|
if (!tagName) {
|
|
272
274
|
continue;
|
|
@@ -303,11 +305,12 @@ export function registerComponentsDnD() {
|
|
|
303
305
|
/** Register DnD on element (HTML block) rows */
|
|
304
306
|
export function registerElementsDnD() {
|
|
305
307
|
requestAnimationFrame(() => {
|
|
306
|
-
const container = leftPanel?.querySelector('[part="content"]')
|
|
308
|
+
const container = leftPanel?.querySelector<HTMLElement>('[part="content"]');
|
|
307
309
|
if (!container) {
|
|
308
310
|
return;
|
|
309
311
|
}
|
|
310
|
-
for (const row of container.querySelectorAll("[data-block-tag]")
|
|
312
|
+
for (const row of container.querySelectorAll<HTMLElement>("[data-block-tag]")) {
|
|
313
|
+
// SAFETY: the selector matched on `data-block-tag`, so the attribute is present and this is its text.
|
|
311
314
|
const tag = row.dataset.blockTag as string;
|
|
312
315
|
const preview = row.querySelector(".element-card-preview");
|
|
313
316
|
if (preview && !preview.firstChild) {
|
|
@@ -338,22 +341,22 @@ export function registerElementsDnD() {
|
|
|
338
341
|
*/
|
|
339
342
|
function hideDescendantRows(parentRow: HTMLElement, container: HTMLElement) {
|
|
340
343
|
const prefix = `${parentRow.dataset.value}/`;
|
|
341
|
-
const rows = container.querySelectorAll(OUTLINE_ROWS);
|
|
344
|
+
const rows = container.querySelectorAll<HTMLElement>(OUTLINE_ROWS);
|
|
342
345
|
for (const r of rows) {
|
|
343
|
-
if (
|
|
344
|
-
|
|
346
|
+
if (r.dataset.value?.startsWith(prefix)) {
|
|
347
|
+
r.style.display = "none";
|
|
345
348
|
}
|
|
346
349
|
}
|
|
347
350
|
}
|
|
348
351
|
|
|
349
352
|
/**
|
|
350
353
|
* @param {HTMLElement} rowEl
|
|
351
|
-
* @param {
|
|
354
|
+
* @param {DropTargetRecord["data"]} data The row's own drop-target data, carrying its instruction.
|
|
352
355
|
* @param {HTMLElement} container
|
|
353
356
|
*/
|
|
354
357
|
export function showLayerDropGap(
|
|
355
358
|
rowEl: HTMLElement,
|
|
356
|
-
data:
|
|
359
|
+
data: DropTargetRecord["data"],
|
|
357
360
|
container: HTMLElement,
|
|
358
361
|
) {
|
|
359
362
|
const instruction = extractInstruction(data);
|
|
@@ -379,18 +382,18 @@ export function showLayerDropGap(
|
|
|
379
382
|
view._currentDropTargetRow = rowEl;
|
|
380
383
|
|
|
381
384
|
// Shift rows to create gap
|
|
382
|
-
const rows = [...container.querySelectorAll(OUTLINE_ROWS)];
|
|
385
|
+
const rows = [...container.querySelectorAll<HTMLElement>(OUTLINE_ROWS)];
|
|
383
386
|
const targetIdx = rows.indexOf(rowEl);
|
|
384
387
|
const gap = view.layerDragSourceHeight;
|
|
385
388
|
|
|
386
|
-
for (
|
|
387
|
-
if (
|
|
389
|
+
for (const [i, row] of rows.entries()) {
|
|
390
|
+
if (row.dataset.dragging !== undefined) {
|
|
388
391
|
continue;
|
|
389
392
|
}
|
|
390
393
|
if (instruction.type === "reorder-above") {
|
|
391
|
-
|
|
394
|
+
row.style.transform = i >= targetIdx ? `translateY(${gap}px)` : "";
|
|
392
395
|
} else {
|
|
393
|
-
|
|
396
|
+
row.style.transform = i > targetIdx ? `translateY(${gap}px)` : "";
|
|
394
397
|
}
|
|
395
398
|
}
|
|
396
399
|
}
|
|
@@ -401,18 +404,53 @@ export function clearLayerDropGap(container: HTMLElement) {
|
|
|
401
404
|
delete view._currentDropTargetRow.dataset.drop;
|
|
402
405
|
view._currentDropTargetRow = null;
|
|
403
406
|
}
|
|
404
|
-
const rows = container.querySelectorAll(OUTLINE_ROWS);
|
|
407
|
+
const rows = container.querySelectorAll<HTMLElement>(OUTLINE_ROWS);
|
|
405
408
|
for (const r of rows) {
|
|
406
|
-
|
|
409
|
+
r.style.transform = "";
|
|
407
410
|
// Also clear `display:none` left by hideDescendantRows. The row has no `style`
|
|
408
411
|
// Lit binding, so an imperative style set during the drag survives the post-drop re-render on
|
|
409
412
|
// Whichever row keeps that key — and a move is exactly the edit that hands a key to a different
|
|
410
413
|
// Node. (The rows ARE keyed, by `pathKey`; the earlier form of this note said they were not,
|
|
411
414
|
// Which made the wrong thing sound load-bearing. What is load-bearing is the missing binding.)
|
|
412
|
-
|
|
415
|
+
r.style.display = "";
|
|
413
416
|
}
|
|
414
417
|
}
|
|
415
418
|
|
|
419
|
+
/**
|
|
420
|
+
* Where a drop instruction lands relative to `targetPath`.
|
|
421
|
+
*
|
|
422
|
+
* `make-child` appends to the target itself. A reorder lands beside it, which needs a parent and a
|
|
423
|
+
* numeric index, so a reorder (or any other instruction) around a root-level path answers
|
|
424
|
+
* `undefined`: the drop cannot land there at all. `null` is an instruction that lands but inserts
|
|
425
|
+
* nothing, which this module does not apply.
|
|
426
|
+
*
|
|
427
|
+
* @param {JxMutableNode} doc
|
|
428
|
+
* @param {string} type
|
|
429
|
+
* @param {JxPath} targetPath
|
|
430
|
+
* @returns {DropSlot | null | undefined}
|
|
431
|
+
*/
|
|
432
|
+
function dropSlot(
|
|
433
|
+
doc: JxMutableNode,
|
|
434
|
+
type: string,
|
|
435
|
+
targetPath: JxPath,
|
|
436
|
+
): DropSlot | null | undefined {
|
|
437
|
+
if (type === "make-child") {
|
|
438
|
+
return { index: childList(getNodeAtPath(doc, targetPath)).length, parent: targetPath };
|
|
439
|
+
}
|
|
440
|
+
const parent = parentElementPath(targetPath);
|
|
441
|
+
const index = childIndex(targetPath);
|
|
442
|
+
if (!parent || !isNumber(index)) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
if (type === "reorder-above") {
|
|
446
|
+
return { index, parent };
|
|
447
|
+
}
|
|
448
|
+
if (type === "reorder-below") {
|
|
449
|
+
return { index: index + 1, parent };
|
|
450
|
+
}
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
|
|
416
454
|
/**
|
|
417
455
|
* Apply a DnD instruction to `tab`'s document. `tab` is the tab whose canvas the drop resolved in
|
|
418
456
|
* (host-routed for iframe drops — never the active tab at message time, which may have changed
|
|
@@ -420,89 +458,39 @@ export function clearLayerDropGap(container: HTMLElement) {
|
|
|
420
458
|
*
|
|
421
459
|
* @param {Tab | null} tab
|
|
422
460
|
* @param {{ type: string }} instruction
|
|
423
|
-
* @param {
|
|
461
|
+
* @param {ElementDragPayload["data"]} srcData The drag source's own data, as `getInitialData` made
|
|
462
|
+
* it.
|
|
424
463
|
* @param {JxPath} targetPath
|
|
425
464
|
*/
|
|
426
465
|
export function applyDropInstruction(
|
|
427
466
|
tab: Tab | null,
|
|
428
467
|
instruction: { type: string },
|
|
429
|
-
srcData:
|
|
468
|
+
srcData: ElementDragPayload["data"],
|
|
430
469
|
targetPath: JxPath,
|
|
431
470
|
) {
|
|
432
471
|
if (!tab) {
|
|
433
472
|
return;
|
|
434
473
|
}
|
|
435
|
-
const doc = tab.doc.document as JxMutableNode;
|
|
436
474
|
if (srcData.type === "tree-node") {
|
|
475
|
+
/* SAFETY: both minters of a "tree-node" payload — an Outline row's `getInitialData` and the
|
|
476
|
+
block action bar's drag handle — set `path` to the dragged node's JxPath. */
|
|
437
477
|
const fromPath = srcData.path as JxPath;
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
// Reordered around.
|
|
442
|
-
if (instruction.type !== "make-child" && (!targetParent || typeof targetIdx !== "number")) {
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
switch (instruction.type) {
|
|
447
|
-
case "reorder-above": {
|
|
448
|
-
transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetParent, targetIdx));
|
|
449
|
-
break;
|
|
450
|
-
}
|
|
451
|
-
case "reorder-below": {
|
|
452
|
-
transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetParent, targetIdx + 1));
|
|
453
|
-
break;
|
|
454
|
-
}
|
|
455
|
-
case "make-child": {
|
|
456
|
-
const target = getNodeAtPath(doc, targetPath);
|
|
457
|
-
const len = childList(target).length;
|
|
458
|
-
transactDoc(tab, (t) => mutateMoveNode(t, fromPath, targetPath, len));
|
|
459
|
-
break;
|
|
460
|
-
}
|
|
461
|
-
default: {
|
|
462
|
-
break;
|
|
463
|
-
}
|
|
478
|
+
const slot = dropSlot(tab.doc.document, instruction.type, targetPath);
|
|
479
|
+
if (slot) {
|
|
480
|
+
transactDoc(tab, (t) => mutateMoveNode(t, fromPath, slot.parent, slot.index));
|
|
464
481
|
}
|
|
465
482
|
} else if (srcData.type === "block") {
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
if (instruction.type !== "make-child" && (!targetParent || typeof targetIdx !== "number")) {
|
|
483
|
+
const slot = dropSlot(tab.doc.document, instruction.type, targetPath);
|
|
484
|
+
if (slot === undefined) {
|
|
469
485
|
return;
|
|
470
486
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
targetIdx,
|
|
479
|
-
structuredClone(srcData.fragment as JxMutableNode),
|
|
480
|
-
),
|
|
481
|
-
);
|
|
482
|
-
break;
|
|
483
|
-
}
|
|
484
|
-
case "reorder-below": {
|
|
485
|
-
transactDoc(tab, (t) =>
|
|
486
|
-
mutateInsertNode(
|
|
487
|
-
t,
|
|
488
|
-
targetParent,
|
|
489
|
-
targetIdx + 1,
|
|
490
|
-
structuredClone(srcData.fragment as JxMutableNode),
|
|
491
|
-
),
|
|
492
|
-
);
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
|
-
case "make-child": {
|
|
496
|
-
const target = getNodeAtPath(doc, targetPath);
|
|
497
|
-
const len = childList(target).length;
|
|
498
|
-
transactDoc(tab, (t) =>
|
|
499
|
-
mutateInsertNode(t, targetPath, len, structuredClone(srcData.fragment as JxMutableNode)),
|
|
500
|
-
);
|
|
501
|
-
break;
|
|
502
|
-
}
|
|
503
|
-
default: {
|
|
504
|
-
break;
|
|
505
|
-
}
|
|
487
|
+
/* SAFETY: every minter of a "block" payload — the Insert palette's element and component cards
|
|
488
|
+
and the file drop (`file-drop-action.ts`) — sets `fragment` to the JxMutableNode it inserts. */
|
|
489
|
+
const fragment = srcData.fragment as JxMutableNode;
|
|
490
|
+
if (slot) {
|
|
491
|
+
transactDoc(tab, (t) =>
|
|
492
|
+
mutateInsertNode(t, slot.parent, slot.index, structuredClone(fragment)),
|
|
493
|
+
);
|
|
506
494
|
}
|
|
507
495
|
|
|
508
496
|
/* Auto-import to `$elements` if the dropped block is a custom component.
|
|
@@ -510,18 +498,20 @@ export function applyDropInstruction(
|
|
|
510
498
|
had its own duplicate rule and matched a local component by `ref.endsWith(basename)`, so
|
|
511
499
|
dropping `./components/card.json` into a page that already imported `./vendor/card.json`
|
|
512
500
|
counted as already imported and produced an element the page could not resolve. */
|
|
513
|
-
const
|
|
514
|
-
const tag = fragment?.tagName;
|
|
501
|
+
const tag = fragment.tagName;
|
|
515
502
|
if (displayTagName(tag).includes("-")) {
|
|
516
503
|
const comp = componentRegistry.find((c: ComponentEntry) => c.tagName === tag);
|
|
517
|
-
|
|
504
|
+
/* SAFETY: `$elements` holds module specifiers and `{ $ref }` imports; the document type and
|
|
505
|
+
files/elements.ts spell an inline entry as JxMutableNode and JxElement respectively, two
|
|
506
|
+
editor views of the same JSON object that enableElement only compares by `$ref`. */
|
|
507
|
+
const before = (tab.doc.document.$elements ?? []) as ElementsEntry[];
|
|
518
508
|
const after = comp ? enableElement(before, comp, tab.documentPath ?? null) : before;
|
|
519
509
|
// Only when the list actually GREW. A component the registry cannot name — an npm entry with
|
|
520
510
|
// No package, a local one with no path — returns the list unchanged, and writing that back
|
|
521
511
|
// Would put an empty `$elements: []` on a document that had none.
|
|
522
512
|
if (after.length !== before.length) {
|
|
523
513
|
transact(tab, (d: JxMutableNode) => {
|
|
524
|
-
d.$elements = after
|
|
514
|
+
d.$elements = after;
|
|
525
515
|
});
|
|
526
516
|
}
|
|
527
517
|
}
|
package/src/panels/editors.ts
CHANGED
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
import type * as monaco from "monaco-editor";
|
|
34
34
|
import { loadMonaco, mountStillWanted } from "../services/monaco-lazy";
|
|
35
35
|
import { monacoTheme } from "../shell";
|
|
36
|
-
import { isJsonObject } from "@jxsuite/schema/guards";
|
|
36
|
+
import { isJsonObject, isString } from "@jxsuite/schema/guards";
|
|
37
37
|
|
|
38
|
-
import { getNodeAtPath
|
|
38
|
+
import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
39
|
+
import { renderOnly, updateUi } from "../store";
|
|
39
40
|
import { activeTab, tabIsLive } from "../workspace/workspace";
|
|
40
41
|
import { mutateUpdateDef, mutateUpdateProperty, transactDoc } from "../tabs/transact";
|
|
41
42
|
import { view } from "../view";
|
|
@@ -50,10 +51,12 @@ import {
|
|
|
50
51
|
} from "../services/monaco-buffer";
|
|
51
52
|
import { globalEntries, namedFormulaEntries } from "../ui/formula-catalog";
|
|
52
53
|
import { notify } from "../services/notify";
|
|
54
|
+
import type { NotifyOptions } from "../services/notify";
|
|
53
55
|
|
|
54
56
|
import type { BufferWrites } from "../services/monaco-buffer";
|
|
57
|
+
import { noteTyping } from "../tabs/typing";
|
|
55
58
|
import type { OxLintDiagnostic } from "../services/code-services";
|
|
56
|
-
import type {
|
|
59
|
+
import type { JsonValue, JxDocumentValue } from "@jxsuite/schema/types";
|
|
57
60
|
import type { JxPath } from "../state";
|
|
58
61
|
import type { Tab } from "../tabs/tab";
|
|
59
62
|
|
|
@@ -77,8 +80,8 @@ type FunctionEditor = NonNullable<typeof view.functionEditor>;
|
|
|
77
80
|
function getFunctionBody(tab: Tab | null | undefined, editing: EditingTarget | null | undefined) {
|
|
78
81
|
const document = tab?.doc.document;
|
|
79
82
|
// Read body off any object-shaped def (covers legacy entries without $prototype).
|
|
80
|
-
const bodyOf = (def:
|
|
81
|
-
isJsonObject(def) &&
|
|
83
|
+
const bodyOf = (def: JxDocumentValue | undefined) =>
|
|
84
|
+
isJsonObject(def) && isString(def.body) ? def.body : "";
|
|
82
85
|
if (editing?.type === "def") {
|
|
83
86
|
return bodyOf(document?.state?.[editing.defName]);
|
|
84
87
|
} else if (editing?.type === "event") {
|
|
@@ -88,6 +91,27 @@ function getFunctionBody(tab: Tab | null | undefined, editing: EditingTarget | n
|
|
|
88
91
|
return "";
|
|
89
92
|
}
|
|
90
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Whether one entry of a "lint" answer is an oxlint diagnostic.
|
|
96
|
+
*
|
|
97
|
+
* The code service forwards oxlint's own `--format=json` output (`code-api.ts`), whose every
|
|
98
|
+
* diagnostic carries a string `message` and `severity` and, where it points somewhere, a `labels`
|
|
99
|
+
* array. Those are the members checked here; `setLintMarkers` reads the rest as optional.
|
|
100
|
+
*/
|
|
101
|
+
function isLintDiagnostic(value: unknown): value is OxLintDiagnostic {
|
|
102
|
+
return (
|
|
103
|
+
isJsonObject(value) &&
|
|
104
|
+
isString(value.message) &&
|
|
105
|
+
isString(value.severity) &&
|
|
106
|
+
(value.labels === undefined || Array.isArray(value.labels))
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** The entries of a "lint" answer that are oxlint diagnostics, in the order they came. */
|
|
111
|
+
function lintDiagnostics(entries: readonly JsonValue[]): OxLintDiagnostic[] {
|
|
112
|
+
return entries.flatMap((entry) => (isLintDiagnostic(entry) ? [entry] : []));
|
|
113
|
+
}
|
|
114
|
+
|
|
91
115
|
/**
|
|
92
116
|
* The element the Logic tab draws for Monaco to fill.
|
|
93
117
|
*
|
|
@@ -109,6 +133,10 @@ export const CODE_HOST_SELECTOR = '[part="code-host"]';
|
|
|
109
133
|
*/
|
|
110
134
|
export function syncFunctionEditor(host: HTMLElement): void {
|
|
111
135
|
const tab = activeTab.value;
|
|
136
|
+
/* SAFETY: `editingFunction` is written only by openLogicTarget, and every caller that opens the
|
|
137
|
+
function surface (formula.editDef, formula.editEvent, the Data panel, the Logic tab's Open)
|
|
138
|
+
passes `{ type: "def", defName }` or `{ type: "event", path, eventKey }`, exactly the two
|
|
139
|
+
EditingTarget members. */
|
|
112
140
|
const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;
|
|
113
141
|
const container = editing && tab ? host.querySelector<HTMLElement>(CODE_HOST_SELECTOR) : null;
|
|
114
142
|
if (!container || !tab || !editing) {
|
|
@@ -119,7 +147,7 @@ export function syncFunctionEditor(host: HTMLElement): void {
|
|
|
119
147
|
}
|
|
120
148
|
|
|
121
149
|
const current = view.functionEditor;
|
|
122
|
-
const attached = Boolean(current && container.contains(current.getDomNode()
|
|
150
|
+
const attached = Boolean(current && container.contains(current.getDomNode()));
|
|
123
151
|
/* THE TAB IS HALF OF THE IDENTITY, and the half that used to be missing.
|
|
124
152
|
`_editingTarget` is a JSON string built from the target alone, and the ordinary target
|
|
125
153
|
`{"eventKey":"onclick","path":["children",0],"type":"event"}` is the SAME string for the first
|
|
@@ -260,7 +288,7 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
|
|
|
260
288
|
let wrote = false;
|
|
261
289
|
if (editing.type === "def") {
|
|
262
290
|
wrote = transactDoc(tab, (t) => mutateUpdateDef(t, editing.defName, { body: newBody }));
|
|
263
|
-
} else
|
|
291
|
+
} else {
|
|
264
292
|
const node = getNodeAtPath(tab.doc.document, editing.path);
|
|
265
293
|
/* THE ELEMENT THE HANDLER HANGS OFF CAN GO WHILE THE EDITOR IS OPEN — a collaborator's
|
|
266
294
|
delete arriving over the wire, or the author's own ⌘Z. `editing.path` then resolves to
|
|
@@ -274,6 +302,9 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
|
|
|
274
302
|
return false;
|
|
275
303
|
}
|
|
276
304
|
const current = node[editing.eventKey] || {};
|
|
305
|
+
/* SAFETY: an `on*` key holds an event binding, which the schema makes an object (a `$ref`, a
|
|
306
|
+
function def or an expression def), so the spread copies that binding's fields; `|| {}`
|
|
307
|
+
covers a key with no binding yet. */
|
|
277
308
|
wrote = transactDoc(tab, (t) =>
|
|
278
309
|
mutateUpdateProperty(t, editing.path, editing.eventKey, {
|
|
279
310
|
...(current as object),
|
|
@@ -333,6 +364,8 @@ function bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {
|
|
|
333
364
|
*/
|
|
334
365
|
export async function closeFunctionEditor(): Promise<void> {
|
|
335
366
|
const tab = activeTab.value;
|
|
367
|
+
/* SAFETY: `editingFunction` is written only by openLogicTarget, whose callers pass one of the two
|
|
368
|
+
EditingTarget shapes (see syncFunctionEditor). */
|
|
336
369
|
const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;
|
|
337
370
|
if (!tab || !editing) {
|
|
338
371
|
return;
|
|
@@ -349,13 +382,13 @@ export async function closeFunctionEditor(): Promise<void> {
|
|
|
349
382
|
cancelBufferWrites(editor);
|
|
350
383
|
const write = editor._commitBody ?? bodyWriter(tab, editing);
|
|
351
384
|
if (!write(minResult?.code ?? currentCode)) {
|
|
385
|
+
const options: NotifyOptions = { key: "logic.close-refused", source: "Logic" };
|
|
386
|
+
if (tab.documentPath) {
|
|
387
|
+
options.path = tab.documentPath;
|
|
388
|
+
}
|
|
352
389
|
notify.warn(
|
|
353
390
|
"The handler could not be saved — source editing holds this document. Your code is still in the editor.",
|
|
354
|
-
|
|
355
|
-
key: "logic.close-refused",
|
|
356
|
-
source: "Logic",
|
|
357
|
-
...(tab.documentPath ? { path: tab.documentPath } : {}),
|
|
358
|
-
},
|
|
391
|
+
options,
|
|
359
392
|
);
|
|
360
393
|
return;
|
|
361
394
|
}
|
|
@@ -486,7 +519,7 @@ async function mountFunctionEditor(
|
|
|
486
519
|
tabIsLive(tab) &&
|
|
487
520
|
bufferIsLive(editor)
|
|
488
521
|
) {
|
|
489
|
-
setLintMarkers(editor, result.diagnostics
|
|
522
|
+
setLintMarkers(editor, lintDiagnostics(result.diagnostics));
|
|
490
523
|
}
|
|
491
524
|
});
|
|
492
525
|
|
|
@@ -500,8 +533,9 @@ async function mountFunctionEditor(
|
|
|
500
533
|
// Stated as a fact rather than left to be read off the timer, because the timer is only ONE of
|
|
501
534
|
// The ways a buffer gets ahead and the other one is invisible to it. `markTyped` rather than
|
|
502
535
|
// `markAhead`: this text is the AUTHOR'S, so it is also the text a close would destroy, and
|
|
503
|
-
// Format-on-open's (below) is not.
|
|
536
|
+
// Format-on-open's (below) is not. Noted for Save too, so it is enabled ahead of the commit.
|
|
504
537
|
writes.markTyped();
|
|
538
|
+
noteTyping(tab.id);
|
|
505
539
|
|
|
506
540
|
writes.arm(BUFFER_COMMIT, 500, () => {
|
|
507
541
|
editor._commitBody?.(editor.getValue());
|
|
@@ -525,7 +559,7 @@ async function mountFunctionEditor(
|
|
|
525
559
|
return;
|
|
526
560
|
}
|
|
527
561
|
if (result?.diagnostics) {
|
|
528
|
-
setLintMarkers(editor, result.diagnostics
|
|
562
|
+
setLintMarkers(editor, lintDiagnostics(result.diagnostics));
|
|
529
563
|
}
|
|
530
564
|
});
|
|
531
565
|
});
|
|
@@ -544,7 +578,7 @@ export async function registerFunctionCompletions() {
|
|
|
544
578
|
if (!activeTab.value) {
|
|
545
579
|
return { suggestions: [] };
|
|
546
580
|
}
|
|
547
|
-
const defs = activeTab.value.doc.document
|
|
581
|
+
const defs = activeTab.value.doc.document.state || {};
|
|
548
582
|
const word = model.getWordUntilPosition(position);
|
|
549
583
|
const range = {
|
|
550
584
|
endColumn: word.endColumn,
|
|
@@ -559,13 +593,12 @@ export async function registerFunctionCompletions() {
|
|
|
559
593
|
const suggestions: monaco.languages.CompletionItem[] = Object.entries(defs).map(
|
|
560
594
|
([key, def]) => {
|
|
561
595
|
let kind = monacoNs.languages.CompletionItemKind.Variable;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
) {
|
|
596
|
+
// A primitive or array entry carries neither field, which is what reading them off it gave.
|
|
597
|
+
const prototype = isJsonObject(def) ? def.$prototype : undefined;
|
|
598
|
+
const handler = isJsonObject(def) ? def.$handler : undefined;
|
|
599
|
+
if (prototype === "Function" || handler || formulaDocs.has(key)) {
|
|
567
600
|
kind = monacoNs.languages.CompletionItemKind.Function;
|
|
568
|
-
} else if (
|
|
601
|
+
} else if (prototype) {
|
|
569
602
|
kind = monacoNs.languages.CompletionItemKind.Property;
|
|
570
603
|
}
|
|
571
604
|
const item: monaco.languages.CompletionItem = {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* @docs studio/design/elements
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
23
24
|
import { nothing } from "lit-html";
|
|
24
25
|
import { buildComponentInstance, componentRegistry } from "../files/components";
|
|
25
26
|
import { childList, getNodeAtPath } from "../store";
|
|
@@ -44,7 +45,7 @@ import type { NavigatorPanelContext, NavigatorPanelDeps, PanelBody } from "./pan
|
|
|
44
45
|
|
|
45
46
|
/** The palette's source of blocks, as `NavigatorPanelDeps.webdata` carries it. */
|
|
46
47
|
interface ElementsWebdata {
|
|
47
|
-
elements
|
|
48
|
+
elements?: Record<string, { tag: string }[]>;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/** The Components section's name — its accordion label AND its key in `view.elementsCollapsed`. */
|
|
@@ -99,12 +100,15 @@ function categoryViews(webdata: ElementsWebdata, filter: string): ElementCategor
|
|
|
99
100
|
*/
|
|
100
101
|
function enabledNpmTags(): Set<string> {
|
|
101
102
|
const tab = activeTab.value;
|
|
103
|
+
/* SAFETY: getEffectiveElements reads nothing off an object entry but `$ref` (its dedup key), and
|
|
104
|
+
this function keeps only the string entries, so typing the document's node entries as
|
|
105
|
+
JxElement is never observed. */
|
|
102
106
|
const entries = getEffectiveElements(
|
|
103
107
|
tab?.doc.document?.$elements as (string | JxElement)[] | undefined,
|
|
104
108
|
);
|
|
105
109
|
const tags = new Set<string>();
|
|
106
110
|
for (const entry of entries) {
|
|
107
|
-
if (
|
|
111
|
+
if (!isString(entry)) {
|
|
108
112
|
continue;
|
|
109
113
|
}
|
|
110
114
|
const named = componentRegistry.find(
|
|
@@ -143,7 +147,9 @@ function componentViews(filter: string): ComponentCardView[] {
|
|
|
143
147
|
/** Everything the document draws, as one value. */
|
|
144
148
|
function panelValues(source: NavigatorPanelDeps): ElementsValues {
|
|
145
149
|
const filter = needle();
|
|
146
|
-
|
|
150
|
+
/* SAFETY: `webdata` is wired in studio.ts from the bundled data/webdata.json, whose `elements`
|
|
151
|
+
maps each category name to an array of `{ tag }` entries. */
|
|
152
|
+
const categories = categoryViews(source.webdata as ElementsWebdata, filter);
|
|
147
153
|
const components = componentViews(filter);
|
|
148
154
|
const bare = categories.length === 0 && components.length === 0;
|
|
149
155
|
return {
|
|
@@ -206,6 +212,7 @@ const ACTIONS: ElementsActions = {
|
|
|
206
212
|
},
|
|
207
213
|
insertElement: (tag) => {
|
|
208
214
|
if (panelDeps) {
|
|
215
|
+
// SAFETY: studio.ts wires `defaultDef` to shared.ts defaultDef, which returns a JxMutableNode.
|
|
209
216
|
insertAtSelection(panelDeps.defaultDef(tag) as JxMutableNode);
|
|
210
217
|
}
|
|
211
218
|
},
|