@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
|
@@ -44,7 +44,16 @@
|
|
|
44
44
|
* @docs studio/design/style-inspector
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
getNestedStyle,
|
|
49
|
+
isFunctionDef,
|
|
50
|
+
isJsonObject,
|
|
51
|
+
isNestedStyle,
|
|
52
|
+
isNodeObject,
|
|
53
|
+
isNonNullObject,
|
|
54
|
+
isNumber,
|
|
55
|
+
isString,
|
|
56
|
+
} from "@jxsuite/schema/guards";
|
|
48
57
|
import { effect, effectScope, reactive } from "../reactivity";
|
|
49
58
|
import {
|
|
50
59
|
cancelStyleDebounce,
|
|
@@ -76,6 +85,7 @@ import {
|
|
|
76
85
|
varDisplayName,
|
|
77
86
|
} from "../utils/studio-utils";
|
|
78
87
|
import { stringArg } from "../commands/command-args";
|
|
88
|
+
import type { CommandArgValues, PropertySchema } from "../commands/command-args";
|
|
79
89
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
80
90
|
import { showPromptDialog } from "../ui/layers";
|
|
81
91
|
import { parseMediaEntries, schemeOfQuery } from "../utils/canvas-media";
|
|
@@ -92,7 +102,7 @@ import {
|
|
|
92
102
|
import {
|
|
93
103
|
attachTargetLine,
|
|
94
104
|
openSelectorMenu,
|
|
95
|
-
resetTargetLine
|
|
105
|
+
resetTargetLine,
|
|
96
106
|
setTargetLine,
|
|
97
107
|
} from "../surfaces/target-line";
|
|
98
108
|
import { clickAnythingTo, openPageAction, staleSelectionMessage } from "./empty-state";
|
|
@@ -101,20 +111,23 @@ import {
|
|
|
101
111
|
autoOpenSections,
|
|
102
112
|
compressBorderSide,
|
|
103
113
|
compressShorthand,
|
|
114
|
+
cssDefs,
|
|
104
115
|
cssMeta,
|
|
105
116
|
expandBorderSide,
|
|
106
117
|
expandShorthand,
|
|
107
118
|
getCssInitialMap,
|
|
108
119
|
getFontVars,
|
|
120
|
+
isDeclarationValue,
|
|
109
121
|
TYPO_PREVIEW_CHANNELS,
|
|
110
122
|
getLonghands,
|
|
111
123
|
} from "./style-utils";
|
|
124
|
+
import type { CssFontPreset, CssLonghand, CssMetaEntry } from "./style-utils";
|
|
112
125
|
import { UNIT_RE } from "../ui/unit-selector";
|
|
113
126
|
import { colorTokens, resolvedColor } from "../ui/color-selector";
|
|
114
127
|
import { resolveTokenValue, toTokenRef, tokenRefName } from "../style/token-ref";
|
|
115
128
|
import { mountStylePanelSurface } from "../surfaces/style-panel";
|
|
116
129
|
import { openMenu } from "../surfaces/menu";
|
|
117
|
-
import type { MenuHandle } from "../surfaces/menu";
|
|
130
|
+
import type { MenuHandle, MenuRowProjection } from "../surfaces/menu";
|
|
118
131
|
import { cloneValue } from "../tabs/doc-op-apply";
|
|
119
132
|
import { effectiveSlotMode, slotModeSeed, switchSlotMode } from "../ui/dynamic-slot";
|
|
120
133
|
import { slotCaps, VALUE_SOURCE_HINTS, VALUE_SOURCE_LABELS } from "../ui/value-source";
|
|
@@ -138,21 +151,18 @@ import type { JxPath } from "../state";
|
|
|
138
151
|
import type { JsonValue } from "../types";
|
|
139
152
|
import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
|
|
140
153
|
|
|
141
|
-
interface CssLonghand {
|
|
142
|
-
name: string;
|
|
143
|
-
entry: Record<string, unknown>;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
type CssPropertyEntry = Record<string, unknown>;
|
|
147
|
-
|
|
148
154
|
/** The chip a row wears when its caller has nothing more specific to say. */
|
|
149
155
|
const DEFAULT_PROVENANCE: FieldProvenance = { state: "default" };
|
|
150
156
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
/**
|
|
158
|
+
* One write to one compound coordinate. A value is a declaration, `undefined` to delete it, or —
|
|
159
|
+
* from Relative Styling's add-a-rule, and nowhere else — the empty block `{}` a new nested rule
|
|
160
|
+
* starts as.
|
|
161
|
+
*/
|
|
162
|
+
type StyleMutateFn = (t: Tab, prop: string, val?: string | JxStyle | undefined) => void;
|
|
163
|
+
|
|
164
|
+
/** The `mutateUpdate*Style` writer for one coordinate, at the `string` type they declare. */
|
|
165
|
+
type StyleWriteFn = (t: Tab, prop: string, value: string | undefined) => void;
|
|
156
166
|
|
|
157
167
|
/**
|
|
158
168
|
* Check if a selector is a stylebook tag path (e.g., "table" or "table th"). Tag paths don't start
|
|
@@ -209,7 +219,7 @@ function resolveContextStyle(
|
|
|
209
219
|
}
|
|
210
220
|
const flat: JxStyle = {};
|
|
211
221
|
for (const [p, v] of Object.entries(base)) {
|
|
212
|
-
if (
|
|
222
|
+
if (isDeclarationValue(v)) {
|
|
213
223
|
flat[p] = v;
|
|
214
224
|
}
|
|
215
225
|
}
|
|
@@ -232,38 +242,26 @@ function contextMutate(
|
|
|
232
242
|
activeSelector: string | null,
|
|
233
243
|
editMedia: string | null,
|
|
234
244
|
): StyleMutateFn {
|
|
245
|
+
let write: StyleWriteFn;
|
|
235
246
|
if (activeSelector && isTagPath(activeSelector)) {
|
|
236
247
|
const stylePath = activeSelector.split(" ");
|
|
237
|
-
|
|
238
|
-
? (t, prop, val) =>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
: (t, prop, val) =>
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
t,
|
|
255
|
-
sel,
|
|
256
|
-
editMedia,
|
|
257
|
-
activeSelector,
|
|
258
|
-
prop,
|
|
259
|
-
val as string | undefined,
|
|
260
|
-
)
|
|
261
|
-
: (t, prop, val) =>
|
|
262
|
-
mutateUpdateNestedStyle(t, sel, activeSelector, prop, val as string | undefined);
|
|
263
|
-
}
|
|
264
|
-
return editMedia
|
|
265
|
-
? (t, prop, val) => mutateUpdateMediaStyle(t, sel, editMedia, prop, val as string | undefined)
|
|
266
|
-
: (t, prop, val) => mutateUpdateStyle(t, sel, prop, val as string | undefined);
|
|
248
|
+
write = editMedia
|
|
249
|
+
? (t, prop, val) => mutateUpdateMediaNestedStylePath(t, sel, editMedia, stylePath, prop, val)
|
|
250
|
+
: (t, prop, val) => mutateUpdateNestedStylePath(t, sel, stylePath, prop, val);
|
|
251
|
+
} else if (activeSelector) {
|
|
252
|
+
write = editMedia
|
|
253
|
+
? (t, prop, val) => mutateUpdateMediaNestedStyle(t, sel, editMedia, activeSelector, prop, val)
|
|
254
|
+
: (t, prop, val) => mutateUpdateNestedStyle(t, sel, activeSelector, prop, val);
|
|
255
|
+
} else {
|
|
256
|
+
write = editMedia
|
|
257
|
+
? (t, prop, val) => mutateUpdateMediaStyle(t, sel, editMedia, prop, val)
|
|
258
|
+
: (t, prop, val) => mutateUpdateStyle(t, sel, prop, val);
|
|
259
|
+
}
|
|
260
|
+
/* SAFETY: the one non-string value a commit carries is the empty block `{}` Relative Styling
|
|
261
|
+
seeds a new nested rule with (see StyleMutateFn). Every `mutateUpdate*Style` writer stores the
|
|
262
|
+
value it is given as-is, deleting only on `undefined` or `""`, so the block lands as the rule's
|
|
263
|
+
body; their `string` parameter is narrower than what they store. */
|
|
264
|
+
return (t, prop, val) => write(t, prop, val as string | undefined);
|
|
267
265
|
}
|
|
268
266
|
|
|
269
267
|
/**
|
|
@@ -293,7 +291,7 @@ function mixedStyleProps(
|
|
|
293
291
|
return mixed;
|
|
294
292
|
}
|
|
295
293
|
const blocks = targets.map((path) => {
|
|
296
|
-
const node = getNodeAtPath(tab.doc.document, path)
|
|
294
|
+
const node = getNodeAtPath(tab.doc.document, path);
|
|
297
295
|
return resolveContextStyle(node?.style ?? {}, activeSelector, editMedia);
|
|
298
296
|
});
|
|
299
297
|
const props = new Set<string>();
|
|
@@ -314,7 +312,7 @@ function mixedStyleProps(
|
|
|
314
312
|
|
|
315
313
|
/** Forget the selector menu's element handle — the Inspector unmounted, or a test starts clean. */
|
|
316
314
|
export function resetSelectorMenu(): void {
|
|
317
|
-
|
|
315
|
+
resetTargetLine();
|
|
318
316
|
}
|
|
319
317
|
|
|
320
318
|
/**
|
|
@@ -340,7 +338,7 @@ export function resetAffectedDisclosure(): void {
|
|
|
340
338
|
* §6.2 forbids, so it routes to the definition site through the same command the context bar's
|
|
341
339
|
* "Manage contexts…" footer runs.
|
|
342
340
|
*/
|
|
343
|
-
function runCommand(id: string, args?:
|
|
341
|
+
function runCommand(id: string, args?: CommandArgValues): void {
|
|
344
342
|
void activeRegistry()?.run(id, args);
|
|
345
343
|
}
|
|
346
344
|
|
|
@@ -523,16 +521,16 @@ interface InheritedInfo {
|
|
|
523
521
|
* `state.` is optional because both spellings occur in documents and both mean the same entry — the
|
|
524
522
|
* chip names the signal, not the accessor path it was reached by.
|
|
525
523
|
*/
|
|
526
|
-
function templateSignalOf(value:
|
|
527
|
-
if (
|
|
524
|
+
function templateSignalOf(value: JxStyle[string]): string | null {
|
|
525
|
+
if (!isString(value)) {
|
|
528
526
|
return null;
|
|
529
527
|
}
|
|
530
528
|
return /\$\{\s*(?:state\.)?([A-Za-z_$][\w$]*)/.exec(value)?.[1] ?? null;
|
|
531
529
|
}
|
|
532
530
|
|
|
533
531
|
/** Whether a value is a `${}` template rather than a literal — the `bound` rung for a CSS value. */
|
|
534
|
-
function isTemplateValue(value:
|
|
535
|
-
return
|
|
532
|
+
function isTemplateValue(value: JxStyle[string]): boolean {
|
|
533
|
+
return isString(value) && value.includes("${");
|
|
536
534
|
}
|
|
537
535
|
|
|
538
536
|
/** What the Style tab can say about one property's origin. */
|
|
@@ -582,28 +580,27 @@ function provenanceOf(prop: string, ctx: ProvenanceCtx): FieldProvenance {
|
|
|
582
580
|
if (value !== undefined) {
|
|
583
581
|
if (isTemplateValue(value)) {
|
|
584
582
|
const signal = templateSignalOf(value);
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
};
|
|
583
|
+
const bound: FieldProvenance = { state: "bound" };
|
|
584
|
+
if (signal) {
|
|
585
|
+
bound.donor = signal;
|
|
586
|
+
if (ctx.signals.includes(signal)) {
|
|
587
|
+
bound.onClick = () => {
|
|
588
|
+
runCommand("view.setActivity", { tab: "data" });
|
|
589
|
+
runCommand("data.expandRow", { name: signal });
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return bound;
|
|
597
594
|
}
|
|
598
595
|
return { state: "set", onClick: () => ctx.clear(prop) };
|
|
599
596
|
}
|
|
600
597
|
const inherited = ctx.inherited[prop];
|
|
601
598
|
if (inherited) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
599
|
+
const prov: FieldProvenance = { state: "inherited", donor: inherited.donor };
|
|
600
|
+
if (inherited.jump) {
|
|
601
|
+
prov.onClick = inherited.jump;
|
|
602
|
+
}
|
|
603
|
+
return prov;
|
|
607
604
|
}
|
|
608
605
|
return { state: "default" };
|
|
609
606
|
}
|
|
@@ -628,14 +625,14 @@ function shorthandProvenance(
|
|
|
628
625
|
ctx: ProvenanceCtx,
|
|
629
626
|
clearAll?: (() => void) | undefined,
|
|
630
627
|
): FieldProvenance {
|
|
631
|
-
const props = [shortProp, ...
|
|
628
|
+
const props = [shortProp, ...getLonghands(shortProp).map((l) => l.name)];
|
|
632
629
|
const { mixed } = ctx;
|
|
633
630
|
if (mixed && props.some((p) => mixed.props.has(p))) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
631
|
+
const prov: FieldProvenance = { state: "mixed", donor: String(mixed.count) };
|
|
632
|
+
if (clearAll) {
|
|
633
|
+
prov.onClick = clearAll;
|
|
634
|
+
}
|
|
635
|
+
return prov;
|
|
639
636
|
}
|
|
640
637
|
for (const p of props) {
|
|
641
638
|
const prov = provenanceOf(p, ctx);
|
|
@@ -683,13 +680,10 @@ function longhandProvenance(
|
|
|
683
680
|
/**
|
|
684
681
|
* A section's tally, counting a shorthand as set when any of its longhands is.
|
|
685
682
|
*
|
|
686
|
-
* @param {
|
|
683
|
+
* @param {CssPropertyItem[]} entries
|
|
687
684
|
* @param {ProvenanceCtx} ctx
|
|
688
685
|
*/
|
|
689
|
-
function sectionProvenance(
|
|
690
|
-
entries: { prop: string; entry: CssPropertyEntry }[],
|
|
691
|
-
ctx: ProvenanceCtx,
|
|
692
|
-
): ProvenanceState[] {
|
|
686
|
+
function sectionProvenance(entries: CssPropertyItem[], ctx: ProvenanceCtx): ProvenanceState[] {
|
|
693
687
|
return entries.map(({ prop, entry }) =>
|
|
694
688
|
inferInputType(entry) === "shorthand"
|
|
695
689
|
? shorthandProvenance(prop, ctx).state
|
|
@@ -699,6 +693,24 @@ function sectionProvenance(
|
|
|
699
693
|
|
|
700
694
|
// ─── The row register ────────────────────────────────────────────────────────
|
|
701
695
|
|
|
696
|
+
/** One css-meta property, with its entry, as a section lists it. */
|
|
697
|
+
interface CssPropertyItem {
|
|
698
|
+
prop: string;
|
|
699
|
+
entry: CssMetaEntry;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/** One projected row and the verbs registered for it. */
|
|
703
|
+
interface ProjectedRow {
|
|
704
|
+
row: StyleRowView;
|
|
705
|
+
actions: RowActions;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/** A button-group row's buttons, and the values only its overflow list offers. */
|
|
709
|
+
interface ButtonGroupView {
|
|
710
|
+
buttons: StyleButtonView[];
|
|
711
|
+
extra: string[];
|
|
712
|
+
}
|
|
713
|
+
|
|
702
714
|
/** One choice a row's list offers. `divider` draws a rule above the entry. */
|
|
703
715
|
interface StyleChoice {
|
|
704
716
|
value: string;
|
|
@@ -732,7 +744,8 @@ interface RowActions {
|
|
|
732
744
|
mode: SlotMode;
|
|
733
745
|
caps: SlotMode[];
|
|
734
746
|
fieldKey: string;
|
|
735
|
-
|
|
747
|
+
/** The field's literal, or `undefined` when it is empty. */
|
|
748
|
+
value: string | undefined;
|
|
736
749
|
stateDefs: string[];
|
|
737
750
|
onChange: (value?: JsonValue) => void;
|
|
738
751
|
};
|
|
@@ -795,15 +808,11 @@ function isNumericValue(value: string): boolean {
|
|
|
795
808
|
* manifest lacks is a red `tests/metadata.test.ts`, which is where a miss is caught before it ships
|
|
796
809
|
* rather than degraded after.
|
|
797
810
|
*/
|
|
798
|
-
function buttonGroup(
|
|
799
|
-
entry
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
const values = (entry.$buttonValues || entry.enum || []) as string[];
|
|
804
|
-
const iconMap = (entry.$icons || {}) as Record<string, string>;
|
|
805
|
-
const buttonValues = entry.$buttonValues as string[] | undefined;
|
|
806
|
-
const enumValues = entry.enum as string[] | undefined;
|
|
811
|
+
function buttonGroup(entry: CssMetaEntry, rowKey: string, value: string): ButtonGroupView {
|
|
812
|
+
const values = entry.$buttonValues || entry.enum || [];
|
|
813
|
+
const iconMap = entry.$icons || {};
|
|
814
|
+
const buttonValues = entry.$buttonValues;
|
|
815
|
+
const enumValues = entry.enum;
|
|
807
816
|
const extra =
|
|
808
817
|
buttonValues && enumValues && enumValues.length > buttonValues.length
|
|
809
818
|
? enumValues.filter((v) => !buttonValues.includes(v))
|
|
@@ -842,7 +851,7 @@ function keywordChoices(options: string[], value: string): StyleChoice[] {
|
|
|
842
851
|
* words alone.
|
|
843
852
|
*/
|
|
844
853
|
function keywordOptions(options: string[], prop: string, face: string): StyleOptionView[] {
|
|
845
|
-
const channel = TYPO_PREVIEW_CHANNELS
|
|
854
|
+
const channel = TYPO_PREVIEW_CHANNELS.get(prop);
|
|
846
855
|
return options.map((v) => {
|
|
847
856
|
const option: StyleOptionView = { label: keywordLabel(v), value: v };
|
|
848
857
|
if (channel) {
|
|
@@ -862,16 +871,16 @@ function keywordOptions(options: string[], prop: string, face: string): StyleOpt
|
|
|
862
871
|
*/
|
|
863
872
|
function previewFace(ctx: EditorCtx): string {
|
|
864
873
|
const raw = ctx.activeStyle.fontFamily ?? ctx.inheritedStyle.fontFamily;
|
|
865
|
-
if (
|
|
874
|
+
if (!isString(raw) && !isNumber(raw)) {
|
|
866
875
|
return "";
|
|
867
876
|
}
|
|
868
|
-
const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document
|
|
877
|
+
const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document.style), raw);
|
|
869
878
|
return resolved === undefined ? "" : String(resolved);
|
|
870
879
|
}
|
|
871
880
|
|
|
872
881
|
/** The Modern Font Stacks a `fontFamily` entry offers, as css-meta.json states them. */
|
|
873
|
-
function fontPresets(entry:
|
|
874
|
-
return Array.isArray(entry.presets) ?
|
|
882
|
+
function fontPresets(entry: CssMetaEntry): CssFontPreset[] {
|
|
883
|
+
return Array.isArray(entry.presets) ? entry.presets : [];
|
|
875
884
|
}
|
|
876
885
|
|
|
877
886
|
/**
|
|
@@ -886,7 +895,7 @@ function fontPresets(entry: CssPropertyEntry): { title: string; value: string }[
|
|
|
886
895
|
* the pick will write is in the list; a preset row is bare, which is what tells the two groups
|
|
887
896
|
* apart in a list that draws no divider.
|
|
888
897
|
*/
|
|
889
|
-
function fontOptions(entry:
|
|
898
|
+
function fontOptions(entry: CssMetaEntry): StyleOptionView[] {
|
|
890
899
|
const fontVars = getFontVars();
|
|
891
900
|
const style = getEffectiveStyle(activeTab.value?.doc.document?.style);
|
|
892
901
|
const options: StyleOptionView[] = fontVars.map((fv) => ({
|
|
@@ -913,7 +922,7 @@ function fontOptions(entry: CssPropertyEntry): StyleOptionView[] {
|
|
|
913
922
|
* minted early would be left behind when they finished typing something else.
|
|
914
923
|
*/
|
|
915
924
|
function commitFont(
|
|
916
|
-
entry:
|
|
925
|
+
entry: CssMetaEntry,
|
|
917
926
|
raw: string,
|
|
918
927
|
mint: boolean,
|
|
919
928
|
onCommit: (value: string) => void,
|
|
@@ -1008,7 +1017,7 @@ interface EditorCtx {
|
|
|
1008
1017
|
/** One write, fanned across every selected element, inside the caller's transaction. */
|
|
1009
1018
|
mutate: StyleMutateFn;
|
|
1010
1019
|
/** The same write in a transaction of its own. */
|
|
1011
|
-
commit: (prop: string, value?: string |
|
|
1020
|
+
commit: (prop: string, value?: string | JxStyle | undefined) => void;
|
|
1012
1021
|
/** The key prefix a row's identity is built from — the coordinate, spelled once. */
|
|
1013
1022
|
coord: string;
|
|
1014
1023
|
targets: readonly JxPath[];
|
|
@@ -1034,7 +1043,7 @@ function styleCaps(): SlotMode[] {
|
|
|
1034
1043
|
/** One ordinary property row: the label, the chip, the ladder and whichever control it draws. */
|
|
1035
1044
|
function fieldRow(
|
|
1036
1045
|
ctx: EditorCtx,
|
|
1037
|
-
entry:
|
|
1046
|
+
entry: CssMetaEntry,
|
|
1038
1047
|
prop: string,
|
|
1039
1048
|
value: string,
|
|
1040
1049
|
opts: {
|
|
@@ -1045,7 +1054,7 @@ function fieldRow(
|
|
|
1045
1054
|
onCommit: (value: string | undefined) => void;
|
|
1046
1055
|
placeholder?: string;
|
|
1047
1056
|
},
|
|
1048
|
-
):
|
|
1057
|
+
): ProjectedRow {
|
|
1049
1058
|
const key = `${ctx.coord}|${prop}${opts.child ? "|child" : ""}`;
|
|
1050
1059
|
const row = blankRow(key, prop, "field");
|
|
1051
1060
|
const actions: RowActions = {};
|
|
@@ -1123,8 +1132,8 @@ function fieldRow(
|
|
|
1123
1132
|
break;
|
|
1124
1133
|
}
|
|
1125
1134
|
case "number-unit": {
|
|
1126
|
-
const units =
|
|
1127
|
-
const keywords =
|
|
1135
|
+
const units = entry.$units ?? [];
|
|
1136
|
+
const keywords = entry.$keywords ?? [];
|
|
1128
1137
|
const match = UNIT_RE.exec(value);
|
|
1129
1138
|
const isKeyword = !match && value !== "" && keywords.includes(value);
|
|
1130
1139
|
const currentUnit = isKeyword ? (units[0] ?? "") : (match?.[2] ?? units[0] ?? "");
|
|
@@ -1136,12 +1145,14 @@ function fieldRow(
|
|
|
1136
1145
|
row.choicesHint = `Unit for ${row.label.toLowerCase()}`;
|
|
1137
1146
|
actions.choices = [
|
|
1138
1147
|
...units.map((u) => ({ checked: u === currentUnit, label: u, value: u })),
|
|
1139
|
-
...keywords.map((kw, index) =>
|
|
1140
|
-
checked: kw === value,
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1148
|
+
...keywords.map((kw, index) => {
|
|
1149
|
+
const choice: StyleChoice = { checked: kw === value, label: kw, value: kw };
|
|
1150
|
+
// The rule between the units and the keywords, drawn only when there are units above.
|
|
1151
|
+
if (index === 0 && units.length > 0) {
|
|
1152
|
+
choice.divider = true;
|
|
1153
|
+
}
|
|
1154
|
+
return choice;
|
|
1155
|
+
}),
|
|
1145
1156
|
];
|
|
1146
1157
|
actions.choose = (chosen) => {
|
|
1147
1158
|
if (keywords.includes(chosen)) {
|
|
@@ -1172,16 +1183,16 @@ function fieldRow(
|
|
|
1172
1183
|
row.widget = "number";
|
|
1173
1184
|
row.min = entry.minimum === undefined ? "" : String(entry.minimum);
|
|
1174
1185
|
row.max = entry.maximum === undefined ? "" : String(entry.maximum);
|
|
1175
|
-
row.step =
|
|
1186
|
+
row.step = entry.maximum !== undefined && entry.maximum <= 1 ? "0.1" : "";
|
|
1176
1187
|
actions.commit = commitLiteral;
|
|
1177
1188
|
break;
|
|
1178
1189
|
}
|
|
1179
1190
|
case "select":
|
|
1180
1191
|
case "combobox": {
|
|
1181
1192
|
const options = Array.isArray(entry.enum)
|
|
1182
|
-
?
|
|
1193
|
+
? entry.enum
|
|
1183
1194
|
: Array.isArray(entry.examples)
|
|
1184
|
-
?
|
|
1195
|
+
? entry.examples
|
|
1185
1196
|
: [];
|
|
1186
1197
|
// A keyword row is the combobox contract exactly: the field IS the value, and the rows
|
|
1187
1198
|
// Under it are the values worth offering. `allows-custom-value` is what makes an enum a
|
|
@@ -1238,17 +1249,13 @@ function unitDisplayValue(
|
|
|
1238
1249
|
|
|
1239
1250
|
/** A unit field's placeholder is the inherited NUMBER — "500", not "500px". */
|
|
1240
1251
|
function unitPlaceholder(placeholder: string): string {
|
|
1241
|
-
return UNIT_RE.exec(placeholder)?.[1] ?? placeholder
|
|
1252
|
+
return UNIT_RE.exec(placeholder)?.[1] ?? placeholder;
|
|
1242
1253
|
}
|
|
1243
1254
|
|
|
1244
1255
|
/** A shorthand header row and, when it is expanded, the longhand children under it. */
|
|
1245
|
-
function shorthandRows(
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
shortProp: string,
|
|
1249
|
-
): { row: StyleRowView; actions: RowActions }[] {
|
|
1250
|
-
const longhands = getLonghands(shortProp) as CssLonghand[];
|
|
1251
|
-
const style = ctx.activeStyle as Record<string, unknown>;
|
|
1256
|
+
function shorthandRows(ctx: EditorCtx, entry: CssMetaEntry, shortProp: string): ProjectedRow[] {
|
|
1257
|
+
const longhands = getLonghands(shortProp);
|
|
1258
|
+
const style = ctx.activeStyle;
|
|
1252
1259
|
const shortVal = style[shortProp];
|
|
1253
1260
|
const hasLonghands = longhands.some((l) => style[l.name] !== undefined);
|
|
1254
1261
|
const isExpanded = ctx.tab.session.ui.styleShorthands[shortProp] ?? hasLonghands;
|
|
@@ -1284,7 +1291,7 @@ function shorthandRows(
|
|
|
1284
1291
|
row.widget = "shorthand";
|
|
1285
1292
|
row.hasLabel = true;
|
|
1286
1293
|
row.label = propLabel(entry, shortProp);
|
|
1287
|
-
row.value =
|
|
1294
|
+
row.value = isString(shortVal) ? shortVal : "";
|
|
1288
1295
|
row.placeholder = shorthandPlaceholder(shortVal, longhands, style, inherited, shortProp);
|
|
1289
1296
|
row.expanded = isExpanded;
|
|
1290
1297
|
row.expandIcon = isExpanded ? "caret-down" : "caret-right";
|
|
@@ -1307,14 +1314,14 @@ function shorthandRows(
|
|
|
1307
1314
|
}
|
|
1308
1315
|
};
|
|
1309
1316
|
|
|
1310
|
-
const out = [{ actions, row }];
|
|
1317
|
+
const out: ProjectedRow[] = [{ actions, row }];
|
|
1311
1318
|
if (!isExpanded) {
|
|
1312
1319
|
return out;
|
|
1313
1320
|
}
|
|
1314
1321
|
|
|
1315
1322
|
const isBorderSide = entry.$shorthandType === "border-side";
|
|
1316
1323
|
const expanded =
|
|
1317
|
-
|
|
1324
|
+
isString(shortVal) && shortVal
|
|
1318
1325
|
? isBorderSide
|
|
1319
1326
|
? expandBorderSide(shortVal)
|
|
1320
1327
|
: expandShorthand(shortVal, longhands.length)
|
|
@@ -1325,9 +1332,11 @@ function shorthandRows(
|
|
|
1325
1332
|
const recompress = (idx: number, val: string) =>
|
|
1326
1333
|
writeShorthand(
|
|
1327
1334
|
compress(
|
|
1335
|
+
/* As text: the compressors join and compare strings, and a number a document holds reads
|
|
1336
|
+
exactly as the template literal they build would have printed it. */
|
|
1328
1337
|
longhands.map((l, i) =>
|
|
1329
|
-
i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
|
|
1330
|
-
)
|
|
1338
|
+
String(i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal))),
|
|
1339
|
+
),
|
|
1331
1340
|
),
|
|
1332
1341
|
);
|
|
1333
1342
|
|
|
@@ -1350,9 +1359,9 @@ function shorthandRows(
|
|
|
1350
1359
|
|
|
1351
1360
|
/** The shorthand header's placeholder: the longhands it would compress, or what shows through. */
|
|
1352
1361
|
function shorthandPlaceholder(
|
|
1353
|
-
shortVal:
|
|
1362
|
+
shortVal: JxStyle[string],
|
|
1354
1363
|
longhands: CssLonghand[],
|
|
1355
|
-
style:
|
|
1364
|
+
style: JxStyle,
|
|
1356
1365
|
inherited: Record<string, string | number>,
|
|
1357
1366
|
shortProp: string,
|
|
1358
1367
|
): string {
|
|
@@ -1394,7 +1403,9 @@ function buildView(canvasMode: () => string): StylePanelView {
|
|
|
1394
1403
|
}
|
|
1395
1404
|
if (canvasMode() === "stylebook" && shell.stylebook.selection) {
|
|
1396
1405
|
const node = tab.doc.document;
|
|
1397
|
-
|
|
1406
|
+
/* Checked, not trusted: a tab's document is whatever the file parsed to, asserted rather than
|
|
1407
|
+
verified where it is loaded (`files/files.ts`), and Stylebook reads its root style next. */
|
|
1408
|
+
if (!isNodeObject(node)) {
|
|
1398
1409
|
return emptyView("Open a page to style what you click.", true);
|
|
1399
1410
|
}
|
|
1400
1411
|
// No separate `Styling: <h1>` header. It said the same thing the Target Line's scope chip says,
|
|
@@ -1408,7 +1419,7 @@ function buildView(canvasMode: () => string): StylePanelView {
|
|
|
1408
1419
|
if (!selected) {
|
|
1409
1420
|
return emptyView(clickAnythingTo("style it"), false);
|
|
1410
1421
|
}
|
|
1411
|
-
const node = getNodeAtPath(tab.doc.document, selected)
|
|
1422
|
+
const node = getNodeAtPath(tab.doc.document, selected);
|
|
1412
1423
|
if (!node) {
|
|
1413
1424
|
return emptyView(staleSelectionMessage(), false);
|
|
1414
1425
|
}
|
|
@@ -1431,17 +1442,15 @@ function buildEditor(
|
|
|
1431
1442
|
opts: { effectiveStyle?: JxStyle | undefined; stylebookSelector?: string | null },
|
|
1432
1443
|
): StylePanelView {
|
|
1433
1444
|
const { effectiveStyle, stylebookSelector = null } = opts;
|
|
1445
|
+
/* SAFETY: `buildView` calls this with a primary selection it has checked, or in Stylebook, where
|
|
1446
|
+
`selectStylebookTag` parks the selection on the root path `[[]]` rather than emptying it. */
|
|
1434
1447
|
const sel = primarySelection(tab.session.selection) as JxPath;
|
|
1435
1448
|
/** The document's OWN style — what a commit writes into. */
|
|
1436
1449
|
const ownRootStyle: JxStyle = node.style || {};
|
|
1437
1450
|
const style = effectiveStyle ?? ownRootStyle;
|
|
1438
1451
|
// Signals seeding the ${} template default when a style value escalates (no $ref in JxStyle).
|
|
1439
1452
|
const templateSignals = Object.entries(tab.doc.document.state || {})
|
|
1440
|
-
.filter(
|
|
1441
|
-
([, d]) =>
|
|
1442
|
-
!(d as Record<string, unknown>)?.$handler &&
|
|
1443
|
-
(d as Record<string, unknown>)?.$prototype !== "Function",
|
|
1444
|
-
)
|
|
1453
|
+
.filter(([, d]) => !(isJsonObject(d) && d.$handler) && !isFunctionDef(d))
|
|
1445
1454
|
.map(([defName]) => defName);
|
|
1446
1455
|
const { sizeBreakpoints } = parseMediaEntries(getEffectiveMedia(tab.doc.document.$media));
|
|
1447
1456
|
const mediaNames = sizeBreakpoints.map((bp) => bp.name);
|
|
@@ -1455,7 +1464,7 @@ function buildEditor(
|
|
|
1455
1464
|
const forcedScheme = tab.session.ui.previewColorScheme;
|
|
1456
1465
|
const schemeLayer =
|
|
1457
1466
|
mediaTab === null && (forcedScheme === "light" || forcedScheme === "dark")
|
|
1458
|
-
? (Object.entries(getEffectiveMedia(tab.doc.document.$media)
|
|
1467
|
+
? (Object.entries(getEffectiveMedia(tab.doc.document.$media)).find(
|
|
1459
1468
|
([, q]) => schemeOfQuery(String(q)) === forcedScheme,
|
|
1460
1469
|
)?.[0] ?? null)
|
|
1461
1470
|
: null;
|
|
@@ -1463,38 +1472,58 @@ function buildEditor(
|
|
|
1463
1472
|
const editMedia = mediaTab && mediaNames.length > 0 ? mediaTab : schemeLayer;
|
|
1464
1473
|
|
|
1465
1474
|
// ── The selector axis — the one this tab owns ──────────────────────────────
|
|
1466
|
-
const contextStyle = editMedia
|
|
1467
|
-
? (style[`@${editMedia}`] as Record<string, unknown>) || {}
|
|
1468
|
-
: style;
|
|
1475
|
+
const contextStyle = editMedia ? (getNestedStyle(style, `@${editMedia}`) ?? {}) : style;
|
|
1469
1476
|
const declaredSelectors = new Set(Object.keys(contextStyle).filter((s) => isNestedSelector(s)));
|
|
1470
1477
|
/* Element-aware, not the flat global list: `:popover-open` on a `<p>` is a rule that can never
|
|
1471
1478
|
match, and a menu that offers unmatchable states is a menu people stop reading. What the
|
|
1472
1479
|
element already DECLARES and the active selector are unioned in after, so nothing an author has
|
|
1473
1480
|
written can drop out of it. */
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
+
/* In Project Styles the coordinate is a TAG PATH (`a`, `table th`) and its states nest under it
|
|
1482
|
+
(`a :hover`). The menu offered the ROOT's states instead, and picking one replaced the tag, so
|
|
1483
|
+
`:hover` styled the document element and a project had no way to write `a:hover` at all. Here
|
|
1484
|
+
the states are the tag's own, spelled as the path they write. */
|
|
1485
|
+
const stylebookPath =
|
|
1486
|
+
stylebookSelector && isTagPath(stylebookSelector) ? stylebookSelector : null;
|
|
1487
|
+
const stylebookLeaf = stylebookPath?.split(" ").at(-1) ?? null;
|
|
1488
|
+
const stylebookDeclared = stylebookPath
|
|
1489
|
+
? Object.keys(resolveNestedTagStyle(style, stylebookPath)).filter((k) => isNestedSelector(k))
|
|
1490
|
+
: [];
|
|
1491
|
+
const selectorOptions = stylebookPath
|
|
1492
|
+
? [
|
|
1493
|
+
...new Set([
|
|
1494
|
+
...[...selectorsForNode({ tagName: stylebookLeaf ?? "div" }), ...stylebookDeclared].map(
|
|
1495
|
+
(state) => `${stylebookPath} ${state}`,
|
|
1496
|
+
),
|
|
1497
|
+
...(activeSelector && activeSelector !== stylebookPath ? [activeSelector] : []),
|
|
1498
|
+
]),
|
|
1499
|
+
]
|
|
1500
|
+
: [
|
|
1501
|
+
...new Set([
|
|
1502
|
+
...selectorsForNode(node),
|
|
1503
|
+
...declaredSelectors,
|
|
1504
|
+
...(activeSelector ? [activeSelector] : []),
|
|
1505
|
+
]),
|
|
1506
|
+
];
|
|
1481
1507
|
|
|
1482
1508
|
// ── The Target Line (§6.2) ─────────────────────────────────────────────────
|
|
1483
1509
|
const stylebookTag = stylebookTagOf(stylebookSelector);
|
|
1484
|
-
const elementLabel =
|
|
1485
|
-
stylebookTag ?? (typeof node.tagName === "string" ? node.tagName : "element");
|
|
1510
|
+
const elementLabel = stylebookTag ?? (isString(node.tagName) ? node.tagName : "element");
|
|
1486
1511
|
setTargetLine({
|
|
1487
1512
|
segments: targetSegments(elementLabel, mediaTab, mediaNames.length > 0, schemeLayer),
|
|
1488
1513
|
selector: {
|
|
1489
|
-
|
|
1514
|
+
// The bare tag path IS the base rule in Project Styles, so it reads as the base entry.
|
|
1515
|
+
value: stylebookPath && activeSelector === stylebookPath ? null : activeSelector,
|
|
1490
1516
|
options: selectorOptions,
|
|
1491
|
-
declared:
|
|
1517
|
+
declared: stylebookPath
|
|
1518
|
+
? new Set(stylebookDeclared.map((state) => `${stylebookPath} ${state}`))
|
|
1519
|
+
: declaredSelectors,
|
|
1492
1520
|
onSelect: (value) => {
|
|
1493
1521
|
const current = activeTab.value;
|
|
1494
1522
|
if (!current) {
|
|
1495
1523
|
return;
|
|
1496
1524
|
}
|
|
1497
|
-
|
|
1525
|
+
// Clearing the state in Project Styles returns to the tag, never to the document root.
|
|
1526
|
+
current.session.ui.activeSelector = value ?? stylebookPath;
|
|
1498
1527
|
/* §6.2's own rule: a control that selects a rendering context has to change the rendering,
|
|
1499
1528
|
or it is a control over a label. `:hover` gets away with not doing this because you can
|
|
1500
1529
|
hover the element; `:popover-open` cannot, because a closed popover is not on the screen
|
|
@@ -1523,7 +1552,9 @@ function buildEditor(
|
|
|
1523
1552
|
isNestedSelector(v.trim()) ? "" : 'A selector must start with ":", ".", "&" or "[".',
|
|
1524
1553
|
}).then((value) => {
|
|
1525
1554
|
if (value && activeTab.value) {
|
|
1526
|
-
activeTab.value.session.ui.activeSelector =
|
|
1555
|
+
activeTab.value.session.ui.activeSelector = stylebookPath
|
|
1556
|
+
? `${stylebookPath} ${value.trim()}`
|
|
1557
|
+
: value.trim();
|
|
1527
1558
|
}
|
|
1528
1559
|
});
|
|
1529
1560
|
},
|
|
@@ -1559,7 +1590,7 @@ function buildEditor(
|
|
|
1559
1590
|
contextMutate(target, activeSelector, editMedia)(t, prop, val);
|
|
1560
1591
|
}
|
|
1561
1592
|
};
|
|
1562
|
-
const commitStyle = (prop: string, val?: string |
|
|
1593
|
+
const commitStyle = (prop: string, val?: string | JxStyle | undefined) =>
|
|
1563
1594
|
transactDoc(activeTab.value, (t) => mutateTargets(t, prop, val));
|
|
1564
1595
|
|
|
1565
1596
|
// ── Compute inherited style, and NAME THE DONOR ────────────────────────────
|
|
@@ -1570,9 +1601,9 @@ function buildEditor(
|
|
|
1570
1601
|
if (schemeLayer) {
|
|
1571
1602
|
const baseBlock = activeSelector ? (getNestedStyle(style, activeSelector) ?? {}) : style;
|
|
1572
1603
|
for (const [p, v] of Object.entries(baseBlock)) {
|
|
1573
|
-
if (
|
|
1604
|
+
if (isDeclarationValue(v)) {
|
|
1574
1605
|
inheritedInfo[p] = {
|
|
1575
|
-
value:
|
|
1606
|
+
value: v ?? "",
|
|
1576
1607
|
donor: "Base",
|
|
1577
1608
|
jump: () => updateUi(activeTab.value, "previewColorScheme", "auto"),
|
|
1578
1609
|
};
|
|
@@ -1600,8 +1631,10 @@ function buildEditor(
|
|
|
1600
1631
|
inherited: inheritedInfo,
|
|
1601
1632
|
signals: templateSignals,
|
|
1602
1633
|
clear: (prop: string) => commitStyle(prop),
|
|
1603
|
-
...(mixedProps.size > 0 ? { mixed: { count: targets.length, props: mixedProps } } : {}),
|
|
1604
1634
|
};
|
|
1635
|
+
if (mixedProps.size > 0) {
|
|
1636
|
+
provCtx.mixed = { count: targets.length, props: mixedProps };
|
|
1637
|
+
}
|
|
1605
1638
|
|
|
1606
1639
|
// Auto-open sections that have properties. Written back only when it actually moves, so the
|
|
1607
1640
|
// Effect this runs inside settles after one extra pass rather than chasing its own write.
|
|
@@ -1638,7 +1671,7 @@ function buildEditor(
|
|
|
1638
1671
|
}
|
|
1639
1672
|
|
|
1640
1673
|
/** Register a projected row's verbs, and hand back the row. */
|
|
1641
|
-
function register(entry:
|
|
1674
|
+
function register(entry: ProjectedRow): StyleRowView {
|
|
1642
1675
|
_rows.set(entry.row.key, entry.actions);
|
|
1643
1676
|
return entry.row;
|
|
1644
1677
|
}
|
|
@@ -1647,18 +1680,18 @@ function register(entry: { row: StyleRowView; actions: RowActions }): StyleRowVi
|
|
|
1647
1680
|
function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
1648
1681
|
const { activeStyle, tab } = ctx;
|
|
1649
1682
|
const isFiltering = ctx.filter.length > 0;
|
|
1650
|
-
const sectionProps: Record<string,
|
|
1683
|
+
const sectionProps: Record<string, CssPropertyItem[]> = {};
|
|
1651
1684
|
for (const sec of cssMeta.$sections) {
|
|
1652
1685
|
sectionProps[sec.key] = [];
|
|
1653
1686
|
}
|
|
1654
|
-
for (const [prop, entry] of Object.entries(
|
|
1655
|
-
if (
|
|
1687
|
+
for (const [prop, entry] of Object.entries(cssDefs)) {
|
|
1688
|
+
if (isString(entry.$shorthand)) {
|
|
1656
1689
|
continue;
|
|
1657
1690
|
}
|
|
1658
|
-
sectionProps[
|
|
1691
|
+
sectionProps[entry.$section || "other"]!.push({ entry, prop });
|
|
1659
1692
|
}
|
|
1660
1693
|
for (const sec of cssMeta.$sections) {
|
|
1661
|
-
sectionProps[sec.key]!.sort((a, b) =>
|
|
1694
|
+
sectionProps[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
|
|
1662
1695
|
}
|
|
1663
1696
|
|
|
1664
1697
|
const out: StyleSectionView[] = [];
|
|
@@ -1673,7 +1706,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1673
1706
|
}
|
|
1674
1707
|
return (
|
|
1675
1708
|
inferInputType(entry) === "shorthand" &&
|
|
1676
|
-
|
|
1709
|
+
getLonghands(prop).some((l) => activeStyle[l.name] !== undefined)
|
|
1677
1710
|
);
|
|
1678
1711
|
});
|
|
1679
1712
|
const clearSection = () => {
|
|
@@ -1683,7 +1716,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1683
1716
|
ctx.mutate(t, prop);
|
|
1684
1717
|
}
|
|
1685
1718
|
if (inferInputType(entry) === "shorthand") {
|
|
1686
|
-
for (const l of getLonghands(prop)
|
|
1719
|
+
for (const l of getLonghands(prop)) {
|
|
1687
1720
|
ctx.mutate(t, l.name);
|
|
1688
1721
|
}
|
|
1689
1722
|
}
|
|
@@ -1713,11 +1746,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1713
1746
|
}
|
|
1714
1747
|
|
|
1715
1748
|
/** One section's rows: every property that is set, or whose `$show` condition passes. */
|
|
1716
|
-
function sectionRows(
|
|
1717
|
-
ctx: EditorCtx,
|
|
1718
|
-
entries: { prop: string; entry: CssPropertyEntry }[],
|
|
1719
|
-
grid: boolean,
|
|
1720
|
-
): StyleRowView[] {
|
|
1749
|
+
function sectionRows(ctx: EditorCtx, entries: CssPropertyItem[], grid: boolean): StyleRowView[] {
|
|
1721
1750
|
const { activeStyle } = ctx;
|
|
1722
1751
|
const rows: StyleRowView[] = [];
|
|
1723
1752
|
for (const { prop, entry } of entries) {
|
|
@@ -1735,7 +1764,7 @@ function sectionRows(
|
|
|
1735
1764
|
}
|
|
1736
1765
|
}
|
|
1737
1766
|
if (type === "shorthand") {
|
|
1738
|
-
const longhands = getLonghands(prop)
|
|
1767
|
+
const longhands = getLonghands(prop);
|
|
1739
1768
|
const hasAny = hasVal || longhands.some((l) => activeStyle[l.name] !== undefined);
|
|
1740
1769
|
if (!hasAny && !condMet) {
|
|
1741
1770
|
continue;
|
|
@@ -1746,7 +1775,7 @@ function sectionRows(
|
|
|
1746
1775
|
continue;
|
|
1747
1776
|
}
|
|
1748
1777
|
const inherited = ctx.inheritedStyle[prop];
|
|
1749
|
-
const built = fieldRow(ctx, entry, prop, (val
|
|
1778
|
+
const built = fieldRow(ctx, entry, prop, String(val ?? ""), {
|
|
1750
1779
|
onCommit: (newVal) => ctx.commit(prop, newVal || undefined),
|
|
1751
1780
|
placeholder: !hasVal && inherited !== undefined ? String(inherited) : "",
|
|
1752
1781
|
provenance: provenanceOf(prop, ctx.provCtx),
|
|
@@ -1798,7 +1827,7 @@ function sectionShell(
|
|
|
1798
1827
|
function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1799
1828
|
const nestedRules: string[] = [];
|
|
1800
1829
|
for (const [prop, val] of Object.entries(ctx.activeStyle)) {
|
|
1801
|
-
if (
|
|
1830
|
+
if (isNestedStyle(val) && !prop.startsWith("@")) {
|
|
1802
1831
|
nestedRules.push(prop);
|
|
1803
1832
|
}
|
|
1804
1833
|
}
|
|
@@ -1855,9 +1884,9 @@ function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1855
1884
|
function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1856
1885
|
const otherProps: string[] = [];
|
|
1857
1886
|
for (const prop of Object.keys(ctx.activeStyle)) {
|
|
1858
|
-
if (!
|
|
1859
|
-
|
|
1860
|
-
if (
|
|
1887
|
+
if (!cssDefs[prop]) {
|
|
1888
|
+
// Arrays and blocks are skipped; a `null` a document holds is listed, as it always was.
|
|
1889
|
+
if (isNonNullObject(ctx.activeStyle[prop])) {
|
|
1861
1890
|
continue;
|
|
1862
1891
|
}
|
|
1863
1892
|
otherProps.push(prop);
|
|
@@ -1876,7 +1905,7 @@ function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1876
1905
|
const cssInitialMap = getCssInitialMap();
|
|
1877
1906
|
/** One target's OWN block at this coordinate — what a write that preserves values reads first. */
|
|
1878
1907
|
const targetStyleOf = (t: Tab, target: JxPath): JxStyle => {
|
|
1879
|
-
const targetNode = getNodeAtPath(t.doc.document, target)
|
|
1908
|
+
const targetNode = getNodeAtPath(t.doc.document, target);
|
|
1880
1909
|
return resolveContextStyle(targetNode?.style ?? {}, ctx.activeSelector, ctx.editMedia);
|
|
1881
1910
|
};
|
|
1882
1911
|
for (const prop of otherProps) {
|
|
@@ -1954,14 +1983,16 @@ function closeRowMenu(): void {
|
|
|
1954
1983
|
menu?.close();
|
|
1955
1984
|
}
|
|
1956
1985
|
|
|
1957
|
-
/**
|
|
1986
|
+
/**
|
|
1987
|
+
* Open a list under the control that asked for it. One menu at a time, the kit's. `trigger` is null
|
|
1988
|
+
* when the surface handed over something that is not an element, which opens nothing.
|
|
1989
|
+
*/
|
|
1958
1990
|
function openRowMenu(
|
|
1959
|
-
|
|
1991
|
+
trigger: HTMLElement | null,
|
|
1960
1992
|
label: string,
|
|
1961
1993
|
choices: StyleChoice[],
|
|
1962
1994
|
run: (value: string) => void,
|
|
1963
1995
|
): void {
|
|
1964
|
-
const trigger = anchor instanceof HTMLElement ? anchor : null;
|
|
1965
1996
|
closeRowMenu();
|
|
1966
1997
|
if (!trigger || choices.length === 0) {
|
|
1967
1998
|
return;
|
|
@@ -1975,16 +2006,19 @@ function openRowMenu(
|
|
|
1975
2006
|
},
|
|
1976
2007
|
opener: trigger,
|
|
1977
2008
|
region: MENU_REGION,
|
|
1978
|
-
rows: choices.map((choice) =>
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
:
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2009
|
+
rows: choices.map((choice) => {
|
|
2010
|
+
const row: MenuRowProjection = {
|
|
2011
|
+
destructive: false,
|
|
2012
|
+
disabled: false,
|
|
2013
|
+
dividerAbove: choice.divider === true,
|
|
2014
|
+
id: choice.value,
|
|
2015
|
+
title: choice.label,
|
|
2016
|
+
};
|
|
2017
|
+
if (choice.checked !== undefined) {
|
|
2018
|
+
row.checked = choice.checked ? "true" : "false";
|
|
2019
|
+
}
|
|
2020
|
+
return row;
|
|
2021
|
+
}),
|
|
1988
2022
|
run: (value) => run(value),
|
|
1989
2023
|
});
|
|
1990
2024
|
}
|
|
@@ -2033,7 +2067,9 @@ const ACTIONS: StylePanelActions = {
|
|
|
2033
2067
|
return;
|
|
2034
2068
|
}
|
|
2035
2069
|
const { choose } = actions;
|
|
2036
|
-
openRowMenu(anchor, "Values", actions.choices, (value) =>
|
|
2070
|
+
openRowMenu(anchor instanceof HTMLElement ? anchor : null, "Values", actions.choices, (value) =>
|
|
2071
|
+
choose(value),
|
|
2072
|
+
);
|
|
2037
2073
|
},
|
|
2038
2074
|
pickSource: (key, anchor) => {
|
|
2039
2075
|
const source = rowActions(key)?.source;
|
|
@@ -2041,7 +2077,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2041
2077
|
return;
|
|
2042
2078
|
}
|
|
2043
2079
|
openRowMenu(
|
|
2044
|
-
anchor,
|
|
2080
|
+
anchor instanceof HTMLElement ? anchor : null,
|
|
2045
2081
|
"Value source",
|
|
2046
2082
|
source.caps.map((mode) => ({
|
|
2047
2083
|
checked: mode === source.mode,
|
|
@@ -2049,8 +2085,8 @@ const ACTIONS: StylePanelActions = {
|
|
|
2049
2085
|
value: mode,
|
|
2050
2086
|
})),
|
|
2051
2087
|
(chosen) => {
|
|
2052
|
-
const next =
|
|
2053
|
-
if (next === source.mode) {
|
|
2088
|
+
const next = source.caps.find((mode) => mode === chosen);
|
|
2089
|
+
if (next === undefined || next === source.mode) {
|
|
2054
2090
|
return;
|
|
2055
2091
|
}
|
|
2056
2092
|
source.onChange(
|
|
@@ -2058,7 +2094,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2058
2094
|
source.fieldKey,
|
|
2059
2095
|
source.mode,
|
|
2060
2096
|
next,
|
|
2061
|
-
cloneValue(source.value
|
|
2097
|
+
cloneValue(source.value),
|
|
2062
2098
|
slotModeSeed(next, { stateDefs: source.stateDefs }),
|
|
2063
2099
|
),
|
|
2064
2100
|
);
|
|
@@ -2211,35 +2247,37 @@ export function styleCommands(): AnyCommand[] {
|
|
|
2211
2247
|
group: "8_style",
|
|
2212
2248
|
requires: "an element selection",
|
|
2213
2249
|
when: styleTabOpen,
|
|
2214
|
-
run: (_commandCtx, args) =>
|
|
2215
|
-
const { selector } = args as { selector?: unknown };
|
|
2216
|
-
if (selector === null) {
|
|
2217
|
-
const tab = activeTab.value;
|
|
2218
|
-
if (tab) {
|
|
2219
|
-
tab.session.ui.activeSelector = null;
|
|
2220
|
-
}
|
|
2221
|
-
return;
|
|
2222
|
-
}
|
|
2223
|
-
const value = stringArg("style.setSelector", args, "selector");
|
|
2224
|
-
if (!isNestedSelector(value)) {
|
|
2225
|
-
throw new RangeError(
|
|
2226
|
-
`command "style.setSelector" argument "selector": "${value}" is not a nested ` +
|
|
2227
|
-
`selector — it must start with ":", ".", "&" or "["`,
|
|
2228
|
-
);
|
|
2229
|
-
}
|
|
2230
|
-
const tab = activeTab.value;
|
|
2231
|
-
if (!tab) {
|
|
2232
|
-
throw new RangeError(`command "style.setSelector" needs an open document`);
|
|
2233
|
-
}
|
|
2234
|
-
tab.session.ui.activeSelector = value;
|
|
2235
|
-
},
|
|
2250
|
+
run: (_commandCtx, args) => setSelector(args),
|
|
2236
2251
|
title: "Set Style Selector",
|
|
2237
2252
|
},
|
|
2238
2253
|
];
|
|
2239
2254
|
}
|
|
2240
2255
|
|
|
2256
|
+
/** `style.setSelector`: edit a nested selector, or the base context for `selector: null`. */
|
|
2257
|
+
function setSelector(args: CommandArgValues): void {
|
|
2258
|
+
if (args.selector === null) {
|
|
2259
|
+
const tab = activeTab.value;
|
|
2260
|
+
if (tab) {
|
|
2261
|
+
tab.session.ui.activeSelector = null;
|
|
2262
|
+
}
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
const value = stringArg("style.setSelector", args, "selector");
|
|
2266
|
+
if (!isNestedSelector(value)) {
|
|
2267
|
+
throw new RangeError(
|
|
2268
|
+
`command "style.setSelector" argument "selector": "${value}" is not a nested ` +
|
|
2269
|
+
`selector — it must start with ":", ".", "&" or "["`,
|
|
2270
|
+
);
|
|
2271
|
+
}
|
|
2272
|
+
const tab = activeTab.value;
|
|
2273
|
+
if (!tab) {
|
|
2274
|
+
throw new RangeError(`command "style.setSelector" needs an open document`);
|
|
2275
|
+
}
|
|
2276
|
+
tab.session.ui.activeSelector = value;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2241
2279
|
/** The `selector` property's schema: a nested selector, or `null` for the base context. */
|
|
2242
|
-
function pathlessSelectorProperty():
|
|
2280
|
+
function pathlessSelectorProperty(): PropertySchema {
|
|
2243
2281
|
return {
|
|
2244
2282
|
description:
|
|
2245
2283
|
'A nested selector such as ":hover", ".child" or "[open]". null edits the base context.',
|