@jxsuite/studio 6.1.1 → 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-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
- 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-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
- 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-1q1sh2ax.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-h46vtzk8.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-rv11kfwa.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-8grwxtqk.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-pre0skq6.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-vrmcjf9g.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-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-kggey1jt.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-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
- 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-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
- 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 +97 -97
- package/package.json +6 -6
- 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 +62 -41
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +90 -49
- 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 +135 -96
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-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 +12 -16
- package/src/canvas/iframe-render.ts +36 -34
- 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/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +7 -7
- 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 +32 -20
- 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 +3 -0
- 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 +52 -21
- 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 +218 -205
- 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 +129 -117
- 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 +25 -75
- 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 +19 -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.ts +13 -13
- 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/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 +73 -73
- 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 +40 -36
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-t6b6qe31.js +0 -5
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.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,9 +1472,7 @@ 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
|
|
@@ -1500,8 +1507,7 @@ function buildEditor(
|
|
|
1500
1507
|
|
|
1501
1508
|
// ── The Target Line (§6.2) ─────────────────────────────────────────────────
|
|
1502
1509
|
const stylebookTag = stylebookTagOf(stylebookSelector);
|
|
1503
|
-
const elementLabel =
|
|
1504
|
-
stylebookTag ?? (typeof node.tagName === "string" ? node.tagName : "element");
|
|
1510
|
+
const elementLabel = stylebookTag ?? (isString(node.tagName) ? node.tagName : "element");
|
|
1505
1511
|
setTargetLine({
|
|
1506
1512
|
segments: targetSegments(elementLabel, mediaTab, mediaNames.length > 0, schemeLayer),
|
|
1507
1513
|
selector: {
|
|
@@ -1584,7 +1590,7 @@ function buildEditor(
|
|
|
1584
1590
|
contextMutate(target, activeSelector, editMedia)(t, prop, val);
|
|
1585
1591
|
}
|
|
1586
1592
|
};
|
|
1587
|
-
const commitStyle = (prop: string, val?: string |
|
|
1593
|
+
const commitStyle = (prop: string, val?: string | JxStyle | undefined) =>
|
|
1588
1594
|
transactDoc(activeTab.value, (t) => mutateTargets(t, prop, val));
|
|
1589
1595
|
|
|
1590
1596
|
// ── Compute inherited style, and NAME THE DONOR ────────────────────────────
|
|
@@ -1595,9 +1601,9 @@ function buildEditor(
|
|
|
1595
1601
|
if (schemeLayer) {
|
|
1596
1602
|
const baseBlock = activeSelector ? (getNestedStyle(style, activeSelector) ?? {}) : style;
|
|
1597
1603
|
for (const [p, v] of Object.entries(baseBlock)) {
|
|
1598
|
-
if (
|
|
1604
|
+
if (isDeclarationValue(v)) {
|
|
1599
1605
|
inheritedInfo[p] = {
|
|
1600
|
-
value:
|
|
1606
|
+
value: v ?? "",
|
|
1601
1607
|
donor: "Base",
|
|
1602
1608
|
jump: () => updateUi(activeTab.value, "previewColorScheme", "auto"),
|
|
1603
1609
|
};
|
|
@@ -1625,8 +1631,10 @@ function buildEditor(
|
|
|
1625
1631
|
inherited: inheritedInfo,
|
|
1626
1632
|
signals: templateSignals,
|
|
1627
1633
|
clear: (prop: string) => commitStyle(prop),
|
|
1628
|
-
...(mixedProps.size > 0 ? { mixed: { count: targets.length, props: mixedProps } } : {}),
|
|
1629
1634
|
};
|
|
1635
|
+
if (mixedProps.size > 0) {
|
|
1636
|
+
provCtx.mixed = { count: targets.length, props: mixedProps };
|
|
1637
|
+
}
|
|
1630
1638
|
|
|
1631
1639
|
// Auto-open sections that have properties. Written back only when it actually moves, so the
|
|
1632
1640
|
// Effect this runs inside settles after one extra pass rather than chasing its own write.
|
|
@@ -1663,7 +1671,7 @@ function buildEditor(
|
|
|
1663
1671
|
}
|
|
1664
1672
|
|
|
1665
1673
|
/** Register a projected row's verbs, and hand back the row. */
|
|
1666
|
-
function register(entry:
|
|
1674
|
+
function register(entry: ProjectedRow): StyleRowView {
|
|
1667
1675
|
_rows.set(entry.row.key, entry.actions);
|
|
1668
1676
|
return entry.row;
|
|
1669
1677
|
}
|
|
@@ -1672,18 +1680,18 @@ function register(entry: { row: StyleRowView; actions: RowActions }): StyleRowVi
|
|
|
1672
1680
|
function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
1673
1681
|
const { activeStyle, tab } = ctx;
|
|
1674
1682
|
const isFiltering = ctx.filter.length > 0;
|
|
1675
|
-
const sectionProps: Record<string,
|
|
1683
|
+
const sectionProps: Record<string, CssPropertyItem[]> = {};
|
|
1676
1684
|
for (const sec of cssMeta.$sections) {
|
|
1677
1685
|
sectionProps[sec.key] = [];
|
|
1678
1686
|
}
|
|
1679
|
-
for (const [prop, entry] of Object.entries(
|
|
1680
|
-
if (
|
|
1687
|
+
for (const [prop, entry] of Object.entries(cssDefs)) {
|
|
1688
|
+
if (isString(entry.$shorthand)) {
|
|
1681
1689
|
continue;
|
|
1682
1690
|
}
|
|
1683
|
-
sectionProps[
|
|
1691
|
+
sectionProps[entry.$section || "other"]!.push({ entry, prop });
|
|
1684
1692
|
}
|
|
1685
1693
|
for (const sec of cssMeta.$sections) {
|
|
1686
|
-
sectionProps[sec.key]!.sort((a, b) =>
|
|
1694
|
+
sectionProps[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
|
|
1687
1695
|
}
|
|
1688
1696
|
|
|
1689
1697
|
const out: StyleSectionView[] = [];
|
|
@@ -1698,7 +1706,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1698
1706
|
}
|
|
1699
1707
|
return (
|
|
1700
1708
|
inferInputType(entry) === "shorthand" &&
|
|
1701
|
-
|
|
1709
|
+
getLonghands(prop).some((l) => activeStyle[l.name] !== undefined)
|
|
1702
1710
|
);
|
|
1703
1711
|
});
|
|
1704
1712
|
const clearSection = () => {
|
|
@@ -1708,7 +1716,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1708
1716
|
ctx.mutate(t, prop);
|
|
1709
1717
|
}
|
|
1710
1718
|
if (inferInputType(entry) === "shorthand") {
|
|
1711
|
-
for (const l of getLonghands(prop)
|
|
1719
|
+
for (const l of getLonghands(prop)) {
|
|
1712
1720
|
ctx.mutate(t, l.name);
|
|
1713
1721
|
}
|
|
1714
1722
|
}
|
|
@@ -1738,11 +1746,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1738
1746
|
}
|
|
1739
1747
|
|
|
1740
1748
|
/** One section's rows: every property that is set, or whose `$show` condition passes. */
|
|
1741
|
-
function sectionRows(
|
|
1742
|
-
ctx: EditorCtx,
|
|
1743
|
-
entries: { prop: string; entry: CssPropertyEntry }[],
|
|
1744
|
-
grid: boolean,
|
|
1745
|
-
): StyleRowView[] {
|
|
1749
|
+
function sectionRows(ctx: EditorCtx, entries: CssPropertyItem[], grid: boolean): StyleRowView[] {
|
|
1746
1750
|
const { activeStyle } = ctx;
|
|
1747
1751
|
const rows: StyleRowView[] = [];
|
|
1748
1752
|
for (const { prop, entry } of entries) {
|
|
@@ -1760,7 +1764,7 @@ function sectionRows(
|
|
|
1760
1764
|
}
|
|
1761
1765
|
}
|
|
1762
1766
|
if (type === "shorthand") {
|
|
1763
|
-
const longhands = getLonghands(prop)
|
|
1767
|
+
const longhands = getLonghands(prop);
|
|
1764
1768
|
const hasAny = hasVal || longhands.some((l) => activeStyle[l.name] !== undefined);
|
|
1765
1769
|
if (!hasAny && !condMet) {
|
|
1766
1770
|
continue;
|
|
@@ -1771,7 +1775,7 @@ function sectionRows(
|
|
|
1771
1775
|
continue;
|
|
1772
1776
|
}
|
|
1773
1777
|
const inherited = ctx.inheritedStyle[prop];
|
|
1774
|
-
const built = fieldRow(ctx, entry, prop, (val
|
|
1778
|
+
const built = fieldRow(ctx, entry, prop, String(val ?? ""), {
|
|
1775
1779
|
onCommit: (newVal) => ctx.commit(prop, newVal || undefined),
|
|
1776
1780
|
placeholder: !hasVal && inherited !== undefined ? String(inherited) : "",
|
|
1777
1781
|
provenance: provenanceOf(prop, ctx.provCtx),
|
|
@@ -1823,7 +1827,7 @@ function sectionShell(
|
|
|
1823
1827
|
function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1824
1828
|
const nestedRules: string[] = [];
|
|
1825
1829
|
for (const [prop, val] of Object.entries(ctx.activeStyle)) {
|
|
1826
|
-
if (
|
|
1830
|
+
if (isNestedStyle(val) && !prop.startsWith("@")) {
|
|
1827
1831
|
nestedRules.push(prop);
|
|
1828
1832
|
}
|
|
1829
1833
|
}
|
|
@@ -1880,9 +1884,9 @@ function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1880
1884
|
function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1881
1885
|
const otherProps: string[] = [];
|
|
1882
1886
|
for (const prop of Object.keys(ctx.activeStyle)) {
|
|
1883
|
-
if (!
|
|
1884
|
-
|
|
1885
|
-
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])) {
|
|
1886
1890
|
continue;
|
|
1887
1891
|
}
|
|
1888
1892
|
otherProps.push(prop);
|
|
@@ -1901,7 +1905,7 @@ function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1901
1905
|
const cssInitialMap = getCssInitialMap();
|
|
1902
1906
|
/** One target's OWN block at this coordinate — what a write that preserves values reads first. */
|
|
1903
1907
|
const targetStyleOf = (t: Tab, target: JxPath): JxStyle => {
|
|
1904
|
-
const targetNode = getNodeAtPath(t.doc.document, target)
|
|
1908
|
+
const targetNode = getNodeAtPath(t.doc.document, target);
|
|
1905
1909
|
return resolveContextStyle(targetNode?.style ?? {}, ctx.activeSelector, ctx.editMedia);
|
|
1906
1910
|
};
|
|
1907
1911
|
for (const prop of otherProps) {
|
|
@@ -1979,14 +1983,16 @@ function closeRowMenu(): void {
|
|
|
1979
1983
|
menu?.close();
|
|
1980
1984
|
}
|
|
1981
1985
|
|
|
1982
|
-
/**
|
|
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
|
+
*/
|
|
1983
1990
|
function openRowMenu(
|
|
1984
|
-
|
|
1991
|
+
trigger: HTMLElement | null,
|
|
1985
1992
|
label: string,
|
|
1986
1993
|
choices: StyleChoice[],
|
|
1987
1994
|
run: (value: string) => void,
|
|
1988
1995
|
): void {
|
|
1989
|
-
const trigger = anchor instanceof HTMLElement ? anchor : null;
|
|
1990
1996
|
closeRowMenu();
|
|
1991
1997
|
if (!trigger || choices.length === 0) {
|
|
1992
1998
|
return;
|
|
@@ -2000,16 +2006,19 @@ function openRowMenu(
|
|
|
2000
2006
|
},
|
|
2001
2007
|
opener: trigger,
|
|
2002
2008
|
region: MENU_REGION,
|
|
2003
|
-
rows: choices.map((choice) =>
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
:
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
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
|
+
}),
|
|
2013
2022
|
run: (value) => run(value),
|
|
2014
2023
|
});
|
|
2015
2024
|
}
|
|
@@ -2058,7 +2067,9 @@ const ACTIONS: StylePanelActions = {
|
|
|
2058
2067
|
return;
|
|
2059
2068
|
}
|
|
2060
2069
|
const { choose } = actions;
|
|
2061
|
-
openRowMenu(anchor, "Values", actions.choices, (value) =>
|
|
2070
|
+
openRowMenu(anchor instanceof HTMLElement ? anchor : null, "Values", actions.choices, (value) =>
|
|
2071
|
+
choose(value),
|
|
2072
|
+
);
|
|
2062
2073
|
},
|
|
2063
2074
|
pickSource: (key, anchor) => {
|
|
2064
2075
|
const source = rowActions(key)?.source;
|
|
@@ -2066,7 +2077,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2066
2077
|
return;
|
|
2067
2078
|
}
|
|
2068
2079
|
openRowMenu(
|
|
2069
|
-
anchor,
|
|
2080
|
+
anchor instanceof HTMLElement ? anchor : null,
|
|
2070
2081
|
"Value source",
|
|
2071
2082
|
source.caps.map((mode) => ({
|
|
2072
2083
|
checked: mode === source.mode,
|
|
@@ -2074,8 +2085,8 @@ const ACTIONS: StylePanelActions = {
|
|
|
2074
2085
|
value: mode,
|
|
2075
2086
|
})),
|
|
2076
2087
|
(chosen) => {
|
|
2077
|
-
const next =
|
|
2078
|
-
if (next === source.mode) {
|
|
2088
|
+
const next = source.caps.find((mode) => mode === chosen);
|
|
2089
|
+
if (next === undefined || next === source.mode) {
|
|
2079
2090
|
return;
|
|
2080
2091
|
}
|
|
2081
2092
|
source.onChange(
|
|
@@ -2083,7 +2094,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2083
2094
|
source.fieldKey,
|
|
2084
2095
|
source.mode,
|
|
2085
2096
|
next,
|
|
2086
|
-
cloneValue(source.value
|
|
2097
|
+
cloneValue(source.value),
|
|
2087
2098
|
slotModeSeed(next, { stateDefs: source.stateDefs }),
|
|
2088
2099
|
),
|
|
2089
2100
|
);
|
|
@@ -2236,35 +2247,37 @@ export function styleCommands(): AnyCommand[] {
|
|
|
2236
2247
|
group: "8_style",
|
|
2237
2248
|
requires: "an element selection",
|
|
2238
2249
|
when: styleTabOpen,
|
|
2239
|
-
run: (_commandCtx, args) =>
|
|
2240
|
-
const { selector } = args as { selector?: unknown };
|
|
2241
|
-
if (selector === null) {
|
|
2242
|
-
const tab = activeTab.value;
|
|
2243
|
-
if (tab) {
|
|
2244
|
-
tab.session.ui.activeSelector = null;
|
|
2245
|
-
}
|
|
2246
|
-
return;
|
|
2247
|
-
}
|
|
2248
|
-
const value = stringArg("style.setSelector", args, "selector");
|
|
2249
|
-
if (!isNestedSelector(value)) {
|
|
2250
|
-
throw new RangeError(
|
|
2251
|
-
`command "style.setSelector" argument "selector": "${value}" is not a nested ` +
|
|
2252
|
-
`selector — it must start with ":", ".", "&" or "["`,
|
|
2253
|
-
);
|
|
2254
|
-
}
|
|
2255
|
-
const tab = activeTab.value;
|
|
2256
|
-
if (!tab) {
|
|
2257
|
-
throw new RangeError(`command "style.setSelector" needs an open document`);
|
|
2258
|
-
}
|
|
2259
|
-
tab.session.ui.activeSelector = value;
|
|
2260
|
-
},
|
|
2250
|
+
run: (_commandCtx, args) => setSelector(args),
|
|
2261
2251
|
title: "Set Style Selector",
|
|
2262
2252
|
},
|
|
2263
2253
|
];
|
|
2264
2254
|
}
|
|
2265
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
|
+
|
|
2266
2279
|
/** The `selector` property's schema: a nested selector, or `null` for the base context. */
|
|
2267
|
-
function pathlessSelectorProperty():
|
|
2280
|
+
function pathlessSelectorProperty(): PropertySchema {
|
|
2268
2281
|
return {
|
|
2269
2282
|
description:
|
|
2270
2283
|
'A nested selector such as ":hover", ".child" or "[open]". null edits the base context.',
|