@jxsuite/studio 6.1.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/color-area-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/listbox-c421cf8c.js +4 -0
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/menu-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/studio-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/studio-bbe4c90a.js +5 -0
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/ws-client-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
|
@@ -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,11 +85,13 @@ 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";
|
|
82
92
|
import { getEffectiveMedia, getEffectiveStyle } from "../site-context";
|
|
83
93
|
import { computeInheritedSources } from "../utils/inherited-style";
|
|
94
|
+
import { tagAncestorSources } from "../style/tag-inheritance";
|
|
84
95
|
import { loadUsages, peekUsages, usageFiles } from "../services/references";
|
|
85
96
|
import { mediaDisplayName } from "./shared";
|
|
86
97
|
import {
|
|
@@ -92,7 +103,7 @@ import {
|
|
|
92
103
|
import {
|
|
93
104
|
attachTargetLine,
|
|
94
105
|
openSelectorMenu,
|
|
95
|
-
resetTargetLine
|
|
106
|
+
resetTargetLine,
|
|
96
107
|
setTargetLine,
|
|
97
108
|
} from "../surfaces/target-line";
|
|
98
109
|
import { clickAnythingTo, openPageAction, staleSelectionMessage } from "./empty-state";
|
|
@@ -101,20 +112,24 @@ import {
|
|
|
101
112
|
autoOpenSections,
|
|
102
113
|
compressBorderSide,
|
|
103
114
|
compressShorthand,
|
|
115
|
+
cssDefs,
|
|
104
116
|
cssMeta,
|
|
105
117
|
expandBorderSide,
|
|
106
118
|
expandShorthand,
|
|
107
119
|
getCssInitialMap,
|
|
108
120
|
getFontVars,
|
|
121
|
+
isDeclarationValue,
|
|
109
122
|
TYPO_PREVIEW_CHANNELS,
|
|
110
123
|
getLonghands,
|
|
111
124
|
} from "./style-utils";
|
|
125
|
+
import type { CssFontPreset, CssLonghand, CssMetaEntry } from "./style-utils";
|
|
112
126
|
import { UNIT_RE } from "../ui/unit-selector";
|
|
113
127
|
import { colorTokens, resolvedColor } from "../ui/color-selector";
|
|
114
128
|
import { resolveTokenValue, toTokenRef, tokenRefName } from "../style/token-ref";
|
|
129
|
+
import { PROJECT_VARIABLES_VIEW } from "../style/project-styles";
|
|
115
130
|
import { mountStylePanelSurface } from "../surfaces/style-panel";
|
|
116
131
|
import { openMenu } from "../surfaces/menu";
|
|
117
|
-
import type { MenuHandle } from "../surfaces/menu";
|
|
132
|
+
import type { MenuHandle, MenuRowProjection } from "../surfaces/menu";
|
|
118
133
|
import { cloneValue } from "../tabs/doc-op-apply";
|
|
119
134
|
import { effectiveSlotMode, slotModeSeed, switchSlotMode } from "../ui/dynamic-slot";
|
|
120
135
|
import { slotCaps, VALUE_SOURCE_HINTS, VALUE_SOURCE_LABELS } from "../ui/value-source";
|
|
@@ -138,21 +153,18 @@ import type { JxPath } from "../state";
|
|
|
138
153
|
import type { JsonValue } from "../types";
|
|
139
154
|
import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
|
|
140
155
|
|
|
141
|
-
interface CssLonghand {
|
|
142
|
-
name: string;
|
|
143
|
-
entry: Record<string, unknown>;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
type CssPropertyEntry = Record<string, unknown>;
|
|
147
|
-
|
|
148
156
|
/** The chip a row wears when its caller has nothing more specific to say. */
|
|
149
157
|
const DEFAULT_PROVENANCE: FieldProvenance = { state: "default" };
|
|
150
158
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
/**
|
|
160
|
+
* One write to one compound coordinate. A value is a declaration, `undefined` to delete it, or —
|
|
161
|
+
* from Relative Styling's add-a-rule, and nowhere else — the empty block `{}` a new nested rule
|
|
162
|
+
* starts as.
|
|
163
|
+
*/
|
|
164
|
+
type StyleMutateFn = (t: Tab, prop: string, val?: string | JxStyle | undefined) => void;
|
|
165
|
+
|
|
166
|
+
/** The `mutateUpdate*Style` writer for one coordinate, at the `string` type they declare. */
|
|
167
|
+
type StyleWriteFn = (t: Tab, prop: string, value: string | undefined) => void;
|
|
156
168
|
|
|
157
169
|
/**
|
|
158
170
|
* Check if a selector is a stylebook tag path (e.g., "table" or "table th"). Tag paths don't start
|
|
@@ -209,7 +221,7 @@ function resolveContextStyle(
|
|
|
209
221
|
}
|
|
210
222
|
const flat: JxStyle = {};
|
|
211
223
|
for (const [p, v] of Object.entries(base)) {
|
|
212
|
-
if (
|
|
224
|
+
if (isDeclarationValue(v)) {
|
|
213
225
|
flat[p] = v;
|
|
214
226
|
}
|
|
215
227
|
}
|
|
@@ -232,38 +244,26 @@ function contextMutate(
|
|
|
232
244
|
activeSelector: string | null,
|
|
233
245
|
editMedia: string | null,
|
|
234
246
|
): StyleMutateFn {
|
|
247
|
+
let write: StyleWriteFn;
|
|
235
248
|
if (activeSelector && isTagPath(activeSelector)) {
|
|
236
249
|
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);
|
|
250
|
+
write = editMedia
|
|
251
|
+
? (t, prop, val) => mutateUpdateMediaNestedStylePath(t, sel, editMedia, stylePath, prop, val)
|
|
252
|
+
: (t, prop, val) => mutateUpdateNestedStylePath(t, sel, stylePath, prop, val);
|
|
253
|
+
} else if (activeSelector) {
|
|
254
|
+
write = editMedia
|
|
255
|
+
? (t, prop, val) => mutateUpdateMediaNestedStyle(t, sel, editMedia, activeSelector, prop, val)
|
|
256
|
+
: (t, prop, val) => mutateUpdateNestedStyle(t, sel, activeSelector, prop, val);
|
|
257
|
+
} else {
|
|
258
|
+
write = editMedia
|
|
259
|
+
? (t, prop, val) => mutateUpdateMediaStyle(t, sel, editMedia, prop, val)
|
|
260
|
+
: (t, prop, val) => mutateUpdateStyle(t, sel, prop, val);
|
|
261
|
+
}
|
|
262
|
+
/* SAFETY: the one non-string value a commit carries is the empty block `{}` Relative Styling
|
|
263
|
+
seeds a new nested rule with (see StyleMutateFn). Every `mutateUpdate*Style` writer stores the
|
|
264
|
+
value it is given as-is, deleting only on `undefined` or `""`, so the block lands as the rule's
|
|
265
|
+
body; their `string` parameter is narrower than what they store. */
|
|
266
|
+
return (t, prop, val) => write(t, prop, val as string | undefined);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
/**
|
|
@@ -293,7 +293,7 @@ function mixedStyleProps(
|
|
|
293
293
|
return mixed;
|
|
294
294
|
}
|
|
295
295
|
const blocks = targets.map((path) => {
|
|
296
|
-
const node = getNodeAtPath(tab.doc.document, path)
|
|
296
|
+
const node = getNodeAtPath(tab.doc.document, path);
|
|
297
297
|
return resolveContextStyle(node?.style ?? {}, activeSelector, editMedia);
|
|
298
298
|
});
|
|
299
299
|
const props = new Set<string>();
|
|
@@ -314,7 +314,7 @@ function mixedStyleProps(
|
|
|
314
314
|
|
|
315
315
|
/** Forget the selector menu's element handle — the Inspector unmounted, or a test starts clean. */
|
|
316
316
|
export function resetSelectorMenu(): void {
|
|
317
|
-
|
|
317
|
+
resetTargetLine();
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
/**
|
|
@@ -340,7 +340,7 @@ export function resetAffectedDisclosure(): void {
|
|
|
340
340
|
* §6.2 forbids, so it routes to the definition site through the same command the context bar's
|
|
341
341
|
* "Manage contexts…" footer runs.
|
|
342
342
|
*/
|
|
343
|
-
function runCommand(id: string, args?:
|
|
343
|
+
function runCommand(id: string, args?: CommandArgValues): void {
|
|
344
344
|
void activeRegistry()?.run(id, args);
|
|
345
345
|
}
|
|
346
346
|
|
|
@@ -523,16 +523,16 @@ interface InheritedInfo {
|
|
|
523
523
|
* `state.` is optional because both spellings occur in documents and both mean the same entry — the
|
|
524
524
|
* chip names the signal, not the accessor path it was reached by.
|
|
525
525
|
*/
|
|
526
|
-
function templateSignalOf(value:
|
|
527
|
-
if (
|
|
526
|
+
function templateSignalOf(value: JxStyle[string]): string | null {
|
|
527
|
+
if (!isString(value)) {
|
|
528
528
|
return null;
|
|
529
529
|
}
|
|
530
530
|
return /\$\{\s*(?:state\.)?([A-Za-z_$][\w$]*)/.exec(value)?.[1] ?? null;
|
|
531
531
|
}
|
|
532
532
|
|
|
533
533
|
/** Whether a value is a `${}` template rather than a literal — the `bound` rung for a CSS value. */
|
|
534
|
-
function isTemplateValue(value:
|
|
535
|
-
return
|
|
534
|
+
function isTemplateValue(value: JxStyle[string]): boolean {
|
|
535
|
+
return isString(value) && value.includes("${");
|
|
536
536
|
}
|
|
537
537
|
|
|
538
538
|
/** What the Style tab can say about one property's origin. */
|
|
@@ -582,28 +582,27 @@ function provenanceOf(prop: string, ctx: ProvenanceCtx): FieldProvenance {
|
|
|
582
582
|
if (value !== undefined) {
|
|
583
583
|
if (isTemplateValue(value)) {
|
|
584
584
|
const signal = templateSignalOf(value);
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
};
|
|
585
|
+
const bound: FieldProvenance = { state: "bound" };
|
|
586
|
+
if (signal) {
|
|
587
|
+
bound.donor = signal;
|
|
588
|
+
if (ctx.signals.includes(signal)) {
|
|
589
|
+
bound.onClick = () => {
|
|
590
|
+
runCommand("view.setActivity", { tab: "data" });
|
|
591
|
+
runCommand("data.expandRow", { name: signal });
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return bound;
|
|
597
596
|
}
|
|
598
597
|
return { state: "set", onClick: () => ctx.clear(prop) };
|
|
599
598
|
}
|
|
600
599
|
const inherited = ctx.inherited[prop];
|
|
601
600
|
if (inherited) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
601
|
+
const prov: FieldProvenance = { state: "inherited", donor: inherited.donor };
|
|
602
|
+
if (inherited.jump) {
|
|
603
|
+
prov.onClick = inherited.jump;
|
|
604
|
+
}
|
|
605
|
+
return prov;
|
|
607
606
|
}
|
|
608
607
|
return { state: "default" };
|
|
609
608
|
}
|
|
@@ -628,14 +627,14 @@ function shorthandProvenance(
|
|
|
628
627
|
ctx: ProvenanceCtx,
|
|
629
628
|
clearAll?: (() => void) | undefined,
|
|
630
629
|
): FieldProvenance {
|
|
631
|
-
const props = [shortProp, ...
|
|
630
|
+
const props = [shortProp, ...getLonghands(shortProp).map((l) => l.name)];
|
|
632
631
|
const { mixed } = ctx;
|
|
633
632
|
if (mixed && props.some((p) => mixed.props.has(p))) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
633
|
+
const prov: FieldProvenance = { state: "mixed", donor: String(mixed.count) };
|
|
634
|
+
if (clearAll) {
|
|
635
|
+
prov.onClick = clearAll;
|
|
636
|
+
}
|
|
637
|
+
return prov;
|
|
639
638
|
}
|
|
640
639
|
for (const p of props) {
|
|
641
640
|
const prov = provenanceOf(p, ctx);
|
|
@@ -683,13 +682,10 @@ function longhandProvenance(
|
|
|
683
682
|
/**
|
|
684
683
|
* A section's tally, counting a shorthand as set when any of its longhands is.
|
|
685
684
|
*
|
|
686
|
-
* @param {
|
|
685
|
+
* @param {CssPropertyItem[]} entries
|
|
687
686
|
* @param {ProvenanceCtx} ctx
|
|
688
687
|
*/
|
|
689
|
-
function sectionProvenance(
|
|
690
|
-
entries: { prop: string; entry: CssPropertyEntry }[],
|
|
691
|
-
ctx: ProvenanceCtx,
|
|
692
|
-
): ProvenanceState[] {
|
|
688
|
+
function sectionProvenance(entries: CssPropertyItem[], ctx: ProvenanceCtx): ProvenanceState[] {
|
|
693
689
|
return entries.map(({ prop, entry }) =>
|
|
694
690
|
inferInputType(entry) === "shorthand"
|
|
695
691
|
? shorthandProvenance(prop, ctx).state
|
|
@@ -699,6 +695,24 @@ function sectionProvenance(
|
|
|
699
695
|
|
|
700
696
|
// ─── The row register ────────────────────────────────────────────────────────
|
|
701
697
|
|
|
698
|
+
/** One css-meta property, with its entry, as a section lists it. */
|
|
699
|
+
interface CssPropertyItem {
|
|
700
|
+
prop: string;
|
|
701
|
+
entry: CssMetaEntry;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/** One projected row and the verbs registered for it. */
|
|
705
|
+
interface ProjectedRow {
|
|
706
|
+
row: StyleRowView;
|
|
707
|
+
actions: RowActions;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/** A button-group row's buttons, and the values only its overflow list offers. */
|
|
711
|
+
interface ButtonGroupView {
|
|
712
|
+
buttons: StyleButtonView[];
|
|
713
|
+
extra: string[];
|
|
714
|
+
}
|
|
715
|
+
|
|
702
716
|
/** One choice a row's list offers. `divider` draws a rule above the entry. */
|
|
703
717
|
interface StyleChoice {
|
|
704
718
|
value: string;
|
|
@@ -732,7 +746,8 @@ interface RowActions {
|
|
|
732
746
|
mode: SlotMode;
|
|
733
747
|
caps: SlotMode[];
|
|
734
748
|
fieldKey: string;
|
|
735
|
-
|
|
749
|
+
/** The field's literal, or `undefined` when it is empty. */
|
|
750
|
+
value: string | undefined;
|
|
736
751
|
stateDefs: string[];
|
|
737
752
|
onChange: (value?: JsonValue) => void;
|
|
738
753
|
};
|
|
@@ -795,15 +810,11 @@ function isNumericValue(value: string): boolean {
|
|
|
795
810
|
* manifest lacks is a red `tests/metadata.test.ts`, which is where a miss is caught before it ships
|
|
796
811
|
* rather than degraded after.
|
|
797
812
|
*/
|
|
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;
|
|
813
|
+
function buttonGroup(entry: CssMetaEntry, rowKey: string, value: string): ButtonGroupView {
|
|
814
|
+
const values = entry.$buttonValues || entry.enum || [];
|
|
815
|
+
const iconMap = entry.$icons || {};
|
|
816
|
+
const buttonValues = entry.$buttonValues;
|
|
817
|
+
const enumValues = entry.enum;
|
|
807
818
|
const extra =
|
|
808
819
|
buttonValues && enumValues && enumValues.length > buttonValues.length
|
|
809
820
|
? enumValues.filter((v) => !buttonValues.includes(v))
|
|
@@ -842,7 +853,7 @@ function keywordChoices(options: string[], value: string): StyleChoice[] {
|
|
|
842
853
|
* words alone.
|
|
843
854
|
*/
|
|
844
855
|
function keywordOptions(options: string[], prop: string, face: string): StyleOptionView[] {
|
|
845
|
-
const channel = TYPO_PREVIEW_CHANNELS
|
|
856
|
+
const channel = TYPO_PREVIEW_CHANNELS.get(prop);
|
|
846
857
|
return options.map((v) => {
|
|
847
858
|
const option: StyleOptionView = { label: keywordLabel(v), value: v };
|
|
848
859
|
if (channel) {
|
|
@@ -862,16 +873,16 @@ function keywordOptions(options: string[], prop: string, face: string): StyleOpt
|
|
|
862
873
|
*/
|
|
863
874
|
function previewFace(ctx: EditorCtx): string {
|
|
864
875
|
const raw = ctx.activeStyle.fontFamily ?? ctx.inheritedStyle.fontFamily;
|
|
865
|
-
if (
|
|
876
|
+
if (!isString(raw) && !isNumber(raw)) {
|
|
866
877
|
return "";
|
|
867
878
|
}
|
|
868
|
-
const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document
|
|
879
|
+
const resolved = resolveTokenValue(getEffectiveStyle(ctx.tab.doc.document.style), raw);
|
|
869
880
|
return resolved === undefined ? "" : String(resolved);
|
|
870
881
|
}
|
|
871
882
|
|
|
872
883
|
/** The Modern Font Stacks a `fontFamily` entry offers, as css-meta.json states them. */
|
|
873
|
-
function fontPresets(entry:
|
|
874
|
-
return Array.isArray(entry.presets) ?
|
|
884
|
+
function fontPresets(entry: CssMetaEntry): CssFontPreset[] {
|
|
885
|
+
return Array.isArray(entry.presets) ? entry.presets : [];
|
|
875
886
|
}
|
|
876
887
|
|
|
877
888
|
/**
|
|
@@ -886,7 +897,7 @@ function fontPresets(entry: CssPropertyEntry): { title: string; value: string }[
|
|
|
886
897
|
* the pick will write is in the list; a preset row is bare, which is what tells the two groups
|
|
887
898
|
* apart in a list that draws no divider.
|
|
888
899
|
*/
|
|
889
|
-
function fontOptions(entry:
|
|
900
|
+
function fontOptions(entry: CssMetaEntry): StyleOptionView[] {
|
|
890
901
|
const fontVars = getFontVars();
|
|
891
902
|
const style = getEffectiveStyle(activeTab.value?.doc.document?.style);
|
|
892
903
|
const options: StyleOptionView[] = fontVars.map((fv) => ({
|
|
@@ -913,7 +924,7 @@ function fontOptions(entry: CssPropertyEntry): StyleOptionView[] {
|
|
|
913
924
|
* minted early would be left behind when they finished typing something else.
|
|
914
925
|
*/
|
|
915
926
|
function commitFont(
|
|
916
|
-
entry:
|
|
927
|
+
entry: CssMetaEntry,
|
|
917
928
|
raw: string,
|
|
918
929
|
mint: boolean,
|
|
919
930
|
onCommit: (value: string) => void,
|
|
@@ -1008,7 +1019,7 @@ interface EditorCtx {
|
|
|
1008
1019
|
/** One write, fanned across every selected element, inside the caller's transaction. */
|
|
1009
1020
|
mutate: StyleMutateFn;
|
|
1010
1021
|
/** The same write in a transaction of its own. */
|
|
1011
|
-
commit: (prop: string, value?: string |
|
|
1022
|
+
commit: (prop: string, value?: string | JxStyle | undefined) => void;
|
|
1012
1023
|
/** The key prefix a row's identity is built from — the coordinate, spelled once. */
|
|
1013
1024
|
coord: string;
|
|
1014
1025
|
targets: readonly JxPath[];
|
|
@@ -1034,7 +1045,7 @@ function styleCaps(): SlotMode[] {
|
|
|
1034
1045
|
/** One ordinary property row: the label, the chip, the ladder and whichever control it draws. */
|
|
1035
1046
|
function fieldRow(
|
|
1036
1047
|
ctx: EditorCtx,
|
|
1037
|
-
entry:
|
|
1048
|
+
entry: CssMetaEntry,
|
|
1038
1049
|
prop: string,
|
|
1039
1050
|
value: string,
|
|
1040
1051
|
opts: {
|
|
@@ -1045,7 +1056,7 @@ function fieldRow(
|
|
|
1045
1056
|
onCommit: (value: string | undefined) => void;
|
|
1046
1057
|
placeholder?: string;
|
|
1047
1058
|
},
|
|
1048
|
-
):
|
|
1059
|
+
): ProjectedRow {
|
|
1049
1060
|
const key = `${ctx.coord}|${prop}${opts.child ? "|child" : ""}`;
|
|
1050
1061
|
const row = blankRow(key, prop, "field");
|
|
1051
1062
|
const actions: RowActions = {};
|
|
@@ -1123,8 +1134,8 @@ function fieldRow(
|
|
|
1123
1134
|
break;
|
|
1124
1135
|
}
|
|
1125
1136
|
case "number-unit": {
|
|
1126
|
-
const units =
|
|
1127
|
-
const keywords =
|
|
1137
|
+
const units = entry.$units ?? [];
|
|
1138
|
+
const keywords = entry.$keywords ?? [];
|
|
1128
1139
|
const match = UNIT_RE.exec(value);
|
|
1129
1140
|
const isKeyword = !match && value !== "" && keywords.includes(value);
|
|
1130
1141
|
const currentUnit = isKeyword ? (units[0] ?? "") : (match?.[2] ?? units[0] ?? "");
|
|
@@ -1136,12 +1147,14 @@ function fieldRow(
|
|
|
1136
1147
|
row.choicesHint = `Unit for ${row.label.toLowerCase()}`;
|
|
1137
1148
|
actions.choices = [
|
|
1138
1149
|
...units.map((u) => ({ checked: u === currentUnit, label: u, value: u })),
|
|
1139
|
-
...keywords.map((kw, index) =>
|
|
1140
|
-
checked: kw === value,
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1150
|
+
...keywords.map((kw, index) => {
|
|
1151
|
+
const choice: StyleChoice = { checked: kw === value, label: kw, value: kw };
|
|
1152
|
+
// The rule between the units and the keywords, drawn only when there are units above.
|
|
1153
|
+
if (index === 0 && units.length > 0) {
|
|
1154
|
+
choice.divider = true;
|
|
1155
|
+
}
|
|
1156
|
+
return choice;
|
|
1157
|
+
}),
|
|
1145
1158
|
];
|
|
1146
1159
|
actions.choose = (chosen) => {
|
|
1147
1160
|
if (keywords.includes(chosen)) {
|
|
@@ -1172,16 +1185,16 @@ function fieldRow(
|
|
|
1172
1185
|
row.widget = "number";
|
|
1173
1186
|
row.min = entry.minimum === undefined ? "" : String(entry.minimum);
|
|
1174
1187
|
row.max = entry.maximum === undefined ? "" : String(entry.maximum);
|
|
1175
|
-
row.step =
|
|
1188
|
+
row.step = entry.maximum !== undefined && entry.maximum <= 1 ? "0.1" : "";
|
|
1176
1189
|
actions.commit = commitLiteral;
|
|
1177
1190
|
break;
|
|
1178
1191
|
}
|
|
1179
1192
|
case "select":
|
|
1180
1193
|
case "combobox": {
|
|
1181
1194
|
const options = Array.isArray(entry.enum)
|
|
1182
|
-
?
|
|
1195
|
+
? entry.enum
|
|
1183
1196
|
: Array.isArray(entry.examples)
|
|
1184
|
-
?
|
|
1197
|
+
? entry.examples
|
|
1185
1198
|
: [];
|
|
1186
1199
|
// A keyword row is the combobox contract exactly: the field IS the value, and the rows
|
|
1187
1200
|
// Under it are the values worth offering. `allows-custom-value` is what makes an enum a
|
|
@@ -1238,17 +1251,13 @@ function unitDisplayValue(
|
|
|
1238
1251
|
|
|
1239
1252
|
/** A unit field's placeholder is the inherited NUMBER — "500", not "500px". */
|
|
1240
1253
|
function unitPlaceholder(placeholder: string): string {
|
|
1241
|
-
return UNIT_RE.exec(placeholder)?.[1] ?? placeholder
|
|
1254
|
+
return UNIT_RE.exec(placeholder)?.[1] ?? placeholder;
|
|
1242
1255
|
}
|
|
1243
1256
|
|
|
1244
1257
|
/** 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>;
|
|
1258
|
+
function shorthandRows(ctx: EditorCtx, entry: CssMetaEntry, shortProp: string): ProjectedRow[] {
|
|
1259
|
+
const longhands = getLonghands(shortProp);
|
|
1260
|
+
const style = ctx.activeStyle;
|
|
1252
1261
|
const shortVal = style[shortProp];
|
|
1253
1262
|
const hasLonghands = longhands.some((l) => style[l.name] !== undefined);
|
|
1254
1263
|
const isExpanded = ctx.tab.session.ui.styleShorthands[shortProp] ?? hasLonghands;
|
|
@@ -1284,7 +1293,7 @@ function shorthandRows(
|
|
|
1284
1293
|
row.widget = "shorthand";
|
|
1285
1294
|
row.hasLabel = true;
|
|
1286
1295
|
row.label = propLabel(entry, shortProp);
|
|
1287
|
-
row.value =
|
|
1296
|
+
row.value = isString(shortVal) ? shortVal : "";
|
|
1288
1297
|
row.placeholder = shorthandPlaceholder(shortVal, longhands, style, inherited, shortProp);
|
|
1289
1298
|
row.expanded = isExpanded;
|
|
1290
1299
|
row.expandIcon = isExpanded ? "caret-down" : "caret-right";
|
|
@@ -1307,14 +1316,14 @@ function shorthandRows(
|
|
|
1307
1316
|
}
|
|
1308
1317
|
};
|
|
1309
1318
|
|
|
1310
|
-
const out = [{ actions, row }];
|
|
1319
|
+
const out: ProjectedRow[] = [{ actions, row }];
|
|
1311
1320
|
if (!isExpanded) {
|
|
1312
1321
|
return out;
|
|
1313
1322
|
}
|
|
1314
1323
|
|
|
1315
1324
|
const isBorderSide = entry.$shorthandType === "border-side";
|
|
1316
1325
|
const expanded =
|
|
1317
|
-
|
|
1326
|
+
isString(shortVal) && shortVal
|
|
1318
1327
|
? isBorderSide
|
|
1319
1328
|
? expandBorderSide(shortVal)
|
|
1320
1329
|
: expandShorthand(shortVal, longhands.length)
|
|
@@ -1325,9 +1334,11 @@ function shorthandRows(
|
|
|
1325
1334
|
const recompress = (idx: number, val: string) =>
|
|
1326
1335
|
writeShorthand(
|
|
1327
1336
|
compress(
|
|
1337
|
+
/* As text: the compressors join and compare strings, and a number a document holds reads
|
|
1338
|
+
exactly as the template literal they build would have printed it. */
|
|
1328
1339
|
longhands.map((l, i) =>
|
|
1329
|
-
i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
|
|
1330
|
-
)
|
|
1340
|
+
String(i === idx ? val : (style[l.name] ?? (expanded ? expanded[i] : emptyVal))),
|
|
1341
|
+
),
|
|
1331
1342
|
),
|
|
1332
1343
|
);
|
|
1333
1344
|
|
|
@@ -1350,9 +1361,9 @@ function shorthandRows(
|
|
|
1350
1361
|
|
|
1351
1362
|
/** The shorthand header's placeholder: the longhands it would compress, or what shows through. */
|
|
1352
1363
|
function shorthandPlaceholder(
|
|
1353
|
-
shortVal:
|
|
1364
|
+
shortVal: JxStyle[string],
|
|
1354
1365
|
longhands: CssLonghand[],
|
|
1355
|
-
style:
|
|
1366
|
+
style: JxStyle,
|
|
1356
1367
|
inherited: Record<string, string | number>,
|
|
1357
1368
|
shortProp: string,
|
|
1358
1369
|
): string {
|
|
@@ -1373,6 +1384,11 @@ function shorthandPlaceholder(
|
|
|
1373
1384
|
|
|
1374
1385
|
// ─── The whole view ──────────────────────────────────────────────────────────
|
|
1375
1386
|
|
|
1387
|
+
/** What the Style tab says beside the Variables view, where there is no element to style. */
|
|
1388
|
+
export const VARIABLES_INSPECTOR_MESSAGE =
|
|
1389
|
+
"Variables are edited in the view itself. Switch the view to Elements and pick a tag to style " +
|
|
1390
|
+
"its default here.";
|
|
1391
|
+
|
|
1376
1392
|
/** The three teaching states, and the one that offers a button. */
|
|
1377
1393
|
function emptyView(message: string, withOpen: boolean): StylePanelView {
|
|
1378
1394
|
return {
|
|
@@ -1392,9 +1408,17 @@ function buildView(canvasMode: () => string): StylePanelView {
|
|
|
1392
1408
|
if (!tab) {
|
|
1393
1409
|
return emptyView("Open a page to style what you click.", true);
|
|
1394
1410
|
}
|
|
1411
|
+
/* The Styles workspace's Variables view has no canvas to click and edits its custom properties in
|
|
1412
|
+
the pane itself, so the canvas teaching line would ask for something impossible. Say where the
|
|
1413
|
+
Inspector's half of the workspace is instead. */
|
|
1414
|
+
if (canvasMode() === PROJECT_VARIABLES_VIEW) {
|
|
1415
|
+
return emptyView(VARIABLES_INSPECTOR_MESSAGE, false);
|
|
1416
|
+
}
|
|
1395
1417
|
if (canvasMode() === "stylebook" && shell.stylebook.selection) {
|
|
1396
1418
|
const node = tab.doc.document;
|
|
1397
|
-
|
|
1419
|
+
/* Checked, not trusted: a tab's document is whatever the file parsed to, asserted rather than
|
|
1420
|
+
verified where it is loaded (`files/files.ts`), and Stylebook reads its root style next. */
|
|
1421
|
+
if (!isNodeObject(node)) {
|
|
1398
1422
|
return emptyView("Open a page to style what you click.", true);
|
|
1399
1423
|
}
|
|
1400
1424
|
// No separate `Styling: <h1>` header. It said the same thing the Target Line's scope chip says,
|
|
@@ -1408,7 +1432,7 @@ function buildView(canvasMode: () => string): StylePanelView {
|
|
|
1408
1432
|
if (!selected) {
|
|
1409
1433
|
return emptyView(clickAnythingTo("style it"), false);
|
|
1410
1434
|
}
|
|
1411
|
-
const node = getNodeAtPath(tab.doc.document, selected)
|
|
1435
|
+
const node = getNodeAtPath(tab.doc.document, selected);
|
|
1412
1436
|
if (!node) {
|
|
1413
1437
|
return emptyView(staleSelectionMessage(), false);
|
|
1414
1438
|
}
|
|
@@ -1431,17 +1455,16 @@ function buildEditor(
|
|
|
1431
1455
|
opts: { effectiveStyle?: JxStyle | undefined; stylebookSelector?: string | null },
|
|
1432
1456
|
): StylePanelView {
|
|
1433
1457
|
const { effectiveStyle, stylebookSelector = null } = opts;
|
|
1434
|
-
|
|
1458
|
+
/* `buildView` calls this with a primary selection it has checked, or in Stylebook, where the
|
|
1459
|
+
edit targets a TAG and the selection is only parked on the root. A Stylebook tab whose session
|
|
1460
|
+
was never parked (or was cleared since) therefore means the root too, rather than a throw. */
|
|
1461
|
+
const sel: JxPath = primarySelection(tab.session.selection) ?? [];
|
|
1435
1462
|
/** The document's OWN style — what a commit writes into. */
|
|
1436
1463
|
const ownRootStyle: JxStyle = node.style || {};
|
|
1437
1464
|
const style = effectiveStyle ?? ownRootStyle;
|
|
1438
1465
|
// Signals seeding the ${} template default when a style value escalates (no $ref in JxStyle).
|
|
1439
1466
|
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
|
-
)
|
|
1467
|
+
.filter(([, d]) => !(isJsonObject(d) && d.$handler) && !isFunctionDef(d))
|
|
1445
1468
|
.map(([defName]) => defName);
|
|
1446
1469
|
const { sizeBreakpoints } = parseMediaEntries(getEffectiveMedia(tab.doc.document.$media));
|
|
1447
1470
|
const mediaNames = sizeBreakpoints.map((bp) => bp.name);
|
|
@@ -1455,7 +1478,7 @@ function buildEditor(
|
|
|
1455
1478
|
const forcedScheme = tab.session.ui.previewColorScheme;
|
|
1456
1479
|
const schemeLayer =
|
|
1457
1480
|
mediaTab === null && (forcedScheme === "light" || forcedScheme === "dark")
|
|
1458
|
-
? (Object.entries(getEffectiveMedia(tab.doc.document.$media)
|
|
1481
|
+
? (Object.entries(getEffectiveMedia(tab.doc.document.$media)).find(
|
|
1459
1482
|
([, q]) => schemeOfQuery(String(q)) === forcedScheme,
|
|
1460
1483
|
)?.[0] ?? null)
|
|
1461
1484
|
: null;
|
|
@@ -1463,9 +1486,7 @@ function buildEditor(
|
|
|
1463
1486
|
const editMedia = mediaTab && mediaNames.length > 0 ? mediaTab : schemeLayer;
|
|
1464
1487
|
|
|
1465
1488
|
// ── The selector axis — the one this tab owns ──────────────────────────────
|
|
1466
|
-
const contextStyle = editMedia
|
|
1467
|
-
? (style[`@${editMedia}`] as Record<string, unknown>) || {}
|
|
1468
|
-
: style;
|
|
1489
|
+
const contextStyle = editMedia ? (getNestedStyle(style, `@${editMedia}`) ?? {}) : style;
|
|
1469
1490
|
const declaredSelectors = new Set(Object.keys(contextStyle).filter((s) => isNestedSelector(s)));
|
|
1470
1491
|
/* Element-aware, not the flat global list: `:popover-open` on a `<p>` is a rule that can never
|
|
1471
1492
|
match, and a menu that offers unmatchable states is a menu people stop reading. What the
|
|
@@ -1500,8 +1521,7 @@ function buildEditor(
|
|
|
1500
1521
|
|
|
1501
1522
|
// ── The Target Line (§6.2) ─────────────────────────────────────────────────
|
|
1502
1523
|
const stylebookTag = stylebookTagOf(stylebookSelector);
|
|
1503
|
-
const elementLabel =
|
|
1504
|
-
stylebookTag ?? (typeof node.tagName === "string" ? node.tagName : "element");
|
|
1524
|
+
const elementLabel = stylebookTag ?? (isString(node.tagName) ? node.tagName : "element");
|
|
1505
1525
|
setTargetLine({
|
|
1506
1526
|
segments: targetSegments(elementLabel, mediaTab, mediaNames.length > 0, schemeLayer),
|
|
1507
1527
|
selector: {
|
|
@@ -1584,7 +1604,7 @@ function buildEditor(
|
|
|
1584
1604
|
contextMutate(target, activeSelector, editMedia)(t, prop, val);
|
|
1585
1605
|
}
|
|
1586
1606
|
};
|
|
1587
|
-
const commitStyle = (prop: string, val?: string |
|
|
1607
|
+
const commitStyle = (prop: string, val?: string | JxStyle | undefined) =>
|
|
1588
1608
|
transactDoc(activeTab.value, (t) => mutateTargets(t, prop, val));
|
|
1589
1609
|
|
|
1590
1610
|
// ── Compute inherited style, and NAME THE DONOR ────────────────────────────
|
|
@@ -1595,9 +1615,9 @@ function buildEditor(
|
|
|
1595
1615
|
if (schemeLayer) {
|
|
1596
1616
|
const baseBlock = activeSelector ? (getNestedStyle(style, activeSelector) ?? {}) : style;
|
|
1597
1617
|
for (const [p, v] of Object.entries(baseBlock)) {
|
|
1598
|
-
if (
|
|
1618
|
+
if (isDeclarationValue(v)) {
|
|
1599
1619
|
inheritedInfo[p] = {
|
|
1600
|
-
value:
|
|
1620
|
+
value: v ?? "",
|
|
1601
1621
|
donor: "Base",
|
|
1602
1622
|
jump: () => updateUi(activeTab.value, "previewColorScheme", "auto"),
|
|
1603
1623
|
};
|
|
@@ -1614,6 +1634,14 @@ function buildEditor(
|
|
|
1614
1634
|
};
|
|
1615
1635
|
}
|
|
1616
1636
|
}
|
|
1637
|
+
// A Project Styles tag rule also inherits from the rules above it in this same file (`body`,
|
|
1638
|
+
// Then each ancestor tag in its path), which is what its specimen is drawn with. The context walk
|
|
1639
|
+
// Above outranks it: a value the tag itself sets at Base is nearer than anything it inherits.
|
|
1640
|
+
if (stylebookPath) {
|
|
1641
|
+
for (const [p, source] of Object.entries(tagAncestorSources(style, stylebookPath, editMedia))) {
|
|
1642
|
+
inheritedInfo[p] ??= { donor: source.donor, value: source.value };
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1617
1645
|
const inheritedStyle: Record<string, string | number> = {};
|
|
1618
1646
|
for (const [p, info] of Object.entries(inheritedInfo)) {
|
|
1619
1647
|
inheritedStyle[p] = info.value;
|
|
@@ -1625,8 +1653,10 @@ function buildEditor(
|
|
|
1625
1653
|
inherited: inheritedInfo,
|
|
1626
1654
|
signals: templateSignals,
|
|
1627
1655
|
clear: (prop: string) => commitStyle(prop),
|
|
1628
|
-
...(mixedProps.size > 0 ? { mixed: { count: targets.length, props: mixedProps } } : {}),
|
|
1629
1656
|
};
|
|
1657
|
+
if (mixedProps.size > 0) {
|
|
1658
|
+
provCtx.mixed = { count: targets.length, props: mixedProps };
|
|
1659
|
+
}
|
|
1630
1660
|
|
|
1631
1661
|
// Auto-open sections that have properties. Written back only when it actually moves, so the
|
|
1632
1662
|
// Effect this runs inside settles after one extra pass rather than chasing its own write.
|
|
@@ -1663,7 +1693,7 @@ function buildEditor(
|
|
|
1663
1693
|
}
|
|
1664
1694
|
|
|
1665
1695
|
/** Register a projected row's verbs, and hand back the row. */
|
|
1666
|
-
function register(entry:
|
|
1696
|
+
function register(entry: ProjectedRow): StyleRowView {
|
|
1667
1697
|
_rows.set(entry.row.key, entry.actions);
|
|
1668
1698
|
return entry.row;
|
|
1669
1699
|
}
|
|
@@ -1672,18 +1702,18 @@ function register(entry: { row: StyleRowView; actions: RowActions }): StyleRowVi
|
|
|
1672
1702
|
function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
1673
1703
|
const { activeStyle, tab } = ctx;
|
|
1674
1704
|
const isFiltering = ctx.filter.length > 0;
|
|
1675
|
-
const sectionProps: Record<string,
|
|
1705
|
+
const sectionProps: Record<string, CssPropertyItem[]> = {};
|
|
1676
1706
|
for (const sec of cssMeta.$sections) {
|
|
1677
1707
|
sectionProps[sec.key] = [];
|
|
1678
1708
|
}
|
|
1679
|
-
for (const [prop, entry] of Object.entries(
|
|
1680
|
-
if (
|
|
1709
|
+
for (const [prop, entry] of Object.entries(cssDefs)) {
|
|
1710
|
+
if (isString(entry.$shorthand)) {
|
|
1681
1711
|
continue;
|
|
1682
1712
|
}
|
|
1683
|
-
sectionProps[
|
|
1713
|
+
sectionProps[entry.$section || "other"]!.push({ entry, prop });
|
|
1684
1714
|
}
|
|
1685
1715
|
for (const sec of cssMeta.$sections) {
|
|
1686
|
-
sectionProps[sec.key]!.sort((a, b) =>
|
|
1716
|
+
sectionProps[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
|
|
1687
1717
|
}
|
|
1688
1718
|
|
|
1689
1719
|
const out: StyleSectionView[] = [];
|
|
@@ -1698,7 +1728,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1698
1728
|
}
|
|
1699
1729
|
return (
|
|
1700
1730
|
inferInputType(entry) === "shorthand" &&
|
|
1701
|
-
|
|
1731
|
+
getLonghands(prop).some((l) => activeStyle[l.name] !== undefined)
|
|
1702
1732
|
);
|
|
1703
1733
|
});
|
|
1704
1734
|
const clearSection = () => {
|
|
@@ -1708,7 +1738,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1708
1738
|
ctx.mutate(t, prop);
|
|
1709
1739
|
}
|
|
1710
1740
|
if (inferInputType(entry) === "shorthand") {
|
|
1711
|
-
for (const l of getLonghands(prop)
|
|
1741
|
+
for (const l of getLonghands(prop)) {
|
|
1712
1742
|
ctx.mutate(t, l.name);
|
|
1713
1743
|
}
|
|
1714
1744
|
}
|
|
@@ -1738,11 +1768,7 @@ function propertySections(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1738
1768
|
}
|
|
1739
1769
|
|
|
1740
1770
|
/** 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[] {
|
|
1771
|
+
function sectionRows(ctx: EditorCtx, entries: CssPropertyItem[], grid: boolean): StyleRowView[] {
|
|
1746
1772
|
const { activeStyle } = ctx;
|
|
1747
1773
|
const rows: StyleRowView[] = [];
|
|
1748
1774
|
for (const { prop, entry } of entries) {
|
|
@@ -1760,7 +1786,7 @@ function sectionRows(
|
|
|
1760
1786
|
}
|
|
1761
1787
|
}
|
|
1762
1788
|
if (type === "shorthand") {
|
|
1763
|
-
const longhands = getLonghands(prop)
|
|
1789
|
+
const longhands = getLonghands(prop);
|
|
1764
1790
|
const hasAny = hasVal || longhands.some((l) => activeStyle[l.name] !== undefined);
|
|
1765
1791
|
if (!hasAny && !condMet) {
|
|
1766
1792
|
continue;
|
|
@@ -1771,7 +1797,7 @@ function sectionRows(
|
|
|
1771
1797
|
continue;
|
|
1772
1798
|
}
|
|
1773
1799
|
const inherited = ctx.inheritedStyle[prop];
|
|
1774
|
-
const built = fieldRow(ctx, entry, prop, (val
|
|
1800
|
+
const built = fieldRow(ctx, entry, prop, String(val ?? ""), {
|
|
1775
1801
|
onCommit: (newVal) => ctx.commit(prop, newVal || undefined),
|
|
1776
1802
|
placeholder: !hasVal && inherited !== undefined ? String(inherited) : "",
|
|
1777
1803
|
provenance: provenanceOf(prop, ctx.provCtx),
|
|
@@ -1823,7 +1849,7 @@ function sectionShell(
|
|
|
1823
1849
|
function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1824
1850
|
const nestedRules: string[] = [];
|
|
1825
1851
|
for (const [prop, val] of Object.entries(ctx.activeStyle)) {
|
|
1826
|
-
if (
|
|
1852
|
+
if (isNestedStyle(val) && !prop.startsWith("@")) {
|
|
1827
1853
|
nestedRules.push(prop);
|
|
1828
1854
|
}
|
|
1829
1855
|
}
|
|
@@ -1880,9 +1906,9 @@ function nestedSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1880
1906
|
function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
1881
1907
|
const otherProps: string[] = [];
|
|
1882
1908
|
for (const prop of Object.keys(ctx.activeStyle)) {
|
|
1883
|
-
if (!
|
|
1884
|
-
|
|
1885
|
-
if (
|
|
1909
|
+
if (!cssDefs[prop]) {
|
|
1910
|
+
// Arrays and blocks are skipped; a `null` a document holds is listed, as it always was.
|
|
1911
|
+
if (isNonNullObject(ctx.activeStyle[prop])) {
|
|
1886
1912
|
continue;
|
|
1887
1913
|
}
|
|
1888
1914
|
otherProps.push(prop);
|
|
@@ -1901,7 +1927,7 @@ function customSection(ctx: EditorCtx): StyleSectionView[] {
|
|
|
1901
1927
|
const cssInitialMap = getCssInitialMap();
|
|
1902
1928
|
/** One target's OWN block at this coordinate — what a write that preserves values reads first. */
|
|
1903
1929
|
const targetStyleOf = (t: Tab, target: JxPath): JxStyle => {
|
|
1904
|
-
const targetNode = getNodeAtPath(t.doc.document, target)
|
|
1930
|
+
const targetNode = getNodeAtPath(t.doc.document, target);
|
|
1905
1931
|
return resolveContextStyle(targetNode?.style ?? {}, ctx.activeSelector, ctx.editMedia);
|
|
1906
1932
|
};
|
|
1907
1933
|
for (const prop of otherProps) {
|
|
@@ -1979,14 +2005,16 @@ function closeRowMenu(): void {
|
|
|
1979
2005
|
menu?.close();
|
|
1980
2006
|
}
|
|
1981
2007
|
|
|
1982
|
-
/**
|
|
2008
|
+
/**
|
|
2009
|
+
* Open a list under the control that asked for it. One menu at a time, the kit's. `trigger` is null
|
|
2010
|
+
* when the surface handed over something that is not an element, which opens nothing.
|
|
2011
|
+
*/
|
|
1983
2012
|
function openRowMenu(
|
|
1984
|
-
|
|
2013
|
+
trigger: HTMLElement | null,
|
|
1985
2014
|
label: string,
|
|
1986
2015
|
choices: StyleChoice[],
|
|
1987
2016
|
run: (value: string) => void,
|
|
1988
2017
|
): void {
|
|
1989
|
-
const trigger = anchor instanceof HTMLElement ? anchor : null;
|
|
1990
2018
|
closeRowMenu();
|
|
1991
2019
|
if (!trigger || choices.length === 0) {
|
|
1992
2020
|
return;
|
|
@@ -2000,16 +2028,19 @@ function openRowMenu(
|
|
|
2000
2028
|
},
|
|
2001
2029
|
opener: trigger,
|
|
2002
2030
|
region: MENU_REGION,
|
|
2003
|
-
rows: choices.map((choice) =>
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
:
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2031
|
+
rows: choices.map((choice) => {
|
|
2032
|
+
const row: MenuRowProjection = {
|
|
2033
|
+
destructive: false,
|
|
2034
|
+
disabled: false,
|
|
2035
|
+
dividerAbove: choice.divider === true,
|
|
2036
|
+
id: choice.value,
|
|
2037
|
+
title: choice.label,
|
|
2038
|
+
};
|
|
2039
|
+
if (choice.checked !== undefined) {
|
|
2040
|
+
row.checked = choice.checked ? "true" : "false";
|
|
2041
|
+
}
|
|
2042
|
+
return row;
|
|
2043
|
+
}),
|
|
2013
2044
|
run: (value) => run(value),
|
|
2014
2045
|
});
|
|
2015
2046
|
}
|
|
@@ -2058,7 +2089,9 @@ const ACTIONS: StylePanelActions = {
|
|
|
2058
2089
|
return;
|
|
2059
2090
|
}
|
|
2060
2091
|
const { choose } = actions;
|
|
2061
|
-
openRowMenu(anchor, "Values", actions.choices, (value) =>
|
|
2092
|
+
openRowMenu(anchor instanceof HTMLElement ? anchor : null, "Values", actions.choices, (value) =>
|
|
2093
|
+
choose(value),
|
|
2094
|
+
);
|
|
2062
2095
|
},
|
|
2063
2096
|
pickSource: (key, anchor) => {
|
|
2064
2097
|
const source = rowActions(key)?.source;
|
|
@@ -2066,7 +2099,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2066
2099
|
return;
|
|
2067
2100
|
}
|
|
2068
2101
|
openRowMenu(
|
|
2069
|
-
anchor,
|
|
2102
|
+
anchor instanceof HTMLElement ? anchor : null,
|
|
2070
2103
|
"Value source",
|
|
2071
2104
|
source.caps.map((mode) => ({
|
|
2072
2105
|
checked: mode === source.mode,
|
|
@@ -2074,8 +2107,8 @@ const ACTIONS: StylePanelActions = {
|
|
|
2074
2107
|
value: mode,
|
|
2075
2108
|
})),
|
|
2076
2109
|
(chosen) => {
|
|
2077
|
-
const next =
|
|
2078
|
-
if (next === source.mode) {
|
|
2110
|
+
const next = source.caps.find((mode) => mode === chosen);
|
|
2111
|
+
if (next === undefined || next === source.mode) {
|
|
2079
2112
|
return;
|
|
2080
2113
|
}
|
|
2081
2114
|
source.onChange(
|
|
@@ -2083,7 +2116,7 @@ const ACTIONS: StylePanelActions = {
|
|
|
2083
2116
|
source.fieldKey,
|
|
2084
2117
|
source.mode,
|
|
2085
2118
|
next,
|
|
2086
|
-
cloneValue(source.value
|
|
2119
|
+
cloneValue(source.value),
|
|
2087
2120
|
slotModeSeed(next, { stateDefs: source.stateDefs }),
|
|
2088
2121
|
),
|
|
2089
2122
|
);
|
|
@@ -2123,6 +2156,11 @@ let _standing: { host: HTMLElement; handle: StylePanelSurface; scope: EffectScop
|
|
|
2123
2156
|
export interface StyleHostDeps {
|
|
2124
2157
|
/** `stylebook` edits a tag catalogue entry; anything else edits the element selection. */
|
|
2125
2158
|
getCanvasMode: () => string;
|
|
2159
|
+
/**
|
|
2160
|
+
* Whether the tab is the one showing. Read inside the projecting effect, so a hidden tab costs
|
|
2161
|
+
* nothing per selection and re-projects the moment it is opened. Absent means always showing.
|
|
2162
|
+
*/
|
|
2163
|
+
isShowing?: () => boolean;
|
|
2126
2164
|
}
|
|
2127
2165
|
|
|
2128
2166
|
/** The default the tab falls back to when the dock names no mode. */
|
|
@@ -2175,9 +2213,16 @@ export function bindStyleHost(el: HTMLElement | null, ctx?: StyleHostDeps): void
|
|
|
2175
2213
|
const handle = mountStylePanelSurface(el, first, ACTIONS, {
|
|
2176
2214
|
target: (element) => attachTargetLine(element ?? undefined),
|
|
2177
2215
|
});
|
|
2216
|
+
const isShowing = ctx?.isShowing ?? (() => true);
|
|
2178
2217
|
const scope = effectScope();
|
|
2179
2218
|
scope.run(() => {
|
|
2180
2219
|
effect(() => {
|
|
2220
|
+
/* A hidden tab does not project. Its editor is thousands of nodes, and a new selection
|
|
2221
|
+
re-keys every row, so projecting behind the Content tab rebuilt the whole of it on every
|
|
2222
|
+
click — most of what selecting an element cost. */
|
|
2223
|
+
if (!isShowing()) {
|
|
2224
|
+
return;
|
|
2225
|
+
}
|
|
2181
2226
|
const view = buildView(_canvasMode);
|
|
2182
2227
|
rememberButtons(view);
|
|
2183
2228
|
handle.update(view);
|
|
@@ -2236,35 +2281,37 @@ export function styleCommands(): AnyCommand[] {
|
|
|
2236
2281
|
group: "8_style",
|
|
2237
2282
|
requires: "an element selection",
|
|
2238
2283
|
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
|
-
},
|
|
2284
|
+
run: (_commandCtx, args) => setSelector(args),
|
|
2261
2285
|
title: "Set Style Selector",
|
|
2262
2286
|
},
|
|
2263
2287
|
];
|
|
2264
2288
|
}
|
|
2265
2289
|
|
|
2290
|
+
/** `style.setSelector`: edit a nested selector, or the base context for `selector: null`. */
|
|
2291
|
+
function setSelector(args: CommandArgValues): void {
|
|
2292
|
+
if (args.selector === null) {
|
|
2293
|
+
const tab = activeTab.value;
|
|
2294
|
+
if (tab) {
|
|
2295
|
+
tab.session.ui.activeSelector = null;
|
|
2296
|
+
}
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
const value = stringArg("style.setSelector", args, "selector");
|
|
2300
|
+
if (!isNestedSelector(value)) {
|
|
2301
|
+
throw new RangeError(
|
|
2302
|
+
`command "style.setSelector" argument "selector": "${value}" is not a nested ` +
|
|
2303
|
+
`selector — it must start with ":", ".", "&" or "["`,
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
const tab = activeTab.value;
|
|
2307
|
+
if (!tab) {
|
|
2308
|
+
throw new RangeError(`command "style.setSelector" needs an open document`);
|
|
2309
|
+
}
|
|
2310
|
+
tab.session.ui.activeSelector = value;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2266
2313
|
/** The `selector` property's schema: a nested selector, or `null` for the base context. */
|
|
2267
|
-
function pathlessSelectorProperty():
|
|
2314
|
+
function pathlessSelectorProperty(): PropertySchema {
|
|
2268
2315
|
return {
|
|
2269
2316
|
description:
|
|
2270
2317
|
'A nested selector such as ":hover", ".child" or "[open]". null edits the base context.',
|