@jxsuite/studio 2.0.1 → 2.1.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/canvas.html +21 -0
- package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
- package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
- package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
- package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
- package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
- package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
- package/dist/chunks/content-source-34gnkbnn.js +38 -0
- package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
- package/dist/chunks/extension-sections-6mqydz35.js +301 -0
- package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
- package/dist/chunks/files-8kn321h1.js +70 -0
- package/dist/chunks/files-8kn321h1.js.map +9 -0
- package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
- package/dist/chunks/git-panel-tjbr191d.js +51 -0
- package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
- package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
- package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
- package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
- package/dist/chunks/layers-panel-87pb25km.js +58 -0
- package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
- package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
- package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
- package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
- package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
- package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
- package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
- package/dist/chunks/right-panel-zpdxd98t.js +37 -0
- package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
- package/dist/chunks/section-registry-zmckaxf4.js +30 -0
- package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
- package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
- package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
- package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
- package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
- package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
- package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
- package/dist/chunks/studio-41exgzhq.js +6690 -0
- package/dist/chunks/studio-41exgzhq.js.map +38 -0
- package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
- package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
- package/dist/chunks/studio-50k77cca.js +1787 -0
- package/dist/chunks/studio-50k77cca.js.map +18 -0
- package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
- package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
- package/dist/chunks/studio-6f0am8f2.js +53 -0
- package/dist/chunks/studio-6f0am8f2.js.map +10 -0
- package/dist/chunks/studio-6nmjc5qk.js +7002 -0
- package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
- package/dist/chunks/studio-7afd21nw.js +67 -0
- package/dist/chunks/studio-7afd21nw.js.map +10 -0
- package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
- package/dist/chunks/studio-7bmdvzne.js.map +10 -0
- package/dist/chunks/studio-8jpzqk5s.js +128 -0
- package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
- package/dist/chunks/studio-94m77tgk.js +1482 -0
- package/dist/chunks/studio-94m77tgk.js.map +13 -0
- package/dist/chunks/studio-9je6w5sq.js +1000 -0
- package/dist/chunks/studio-9je6w5sq.js.map +16 -0
- package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
- package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
- package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
- package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
- package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
- package/dist/chunks/studio-bw5dz6km.js +608 -0
- package/dist/chunks/studio-bw5dz6km.js.map +21 -0
- package/dist/chunks/studio-c6s5getc.js +4232 -0
- package/dist/chunks/studio-c6s5getc.js.map +39 -0
- package/dist/chunks/studio-cjm7fdjf.js +451 -0
- package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
- package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
- package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
- package/dist/chunks/studio-dg7zyt5x.js +28 -0
- package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
- package/dist/chunks/studio-dzcyvvvz.js +166 -0
- package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
- package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
- package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
- package/dist/chunks/studio-f12h6177.js +411 -0
- package/dist/chunks/studio-f12h6177.js.map +13 -0
- package/dist/chunks/studio-hbp1s8m9.js +1817 -0
- package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
- package/dist/chunks/studio-k2sxjph5.js +15295 -0
- package/dist/chunks/studio-k2sxjph5.js.map +235 -0
- package/dist/chunks/studio-myje51t3.js +385 -0
- package/dist/chunks/studio-myje51t3.js.map +12 -0
- package/dist/chunks/studio-na6rwzhw.js +353 -0
- package/dist/chunks/studio-na6rwzhw.js.map +11 -0
- package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
- package/dist/chunks/studio-p471gg5n.js.map +14 -0
- package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
- package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
- package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
- package/dist/chunks/studio-sas7mt3k.js +75 -0
- package/dist/chunks/studio-sas7mt3k.js.map +10 -0
- package/dist/chunks/studio-t5wqwzdh.js +74 -0
- package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
- package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
- package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
- package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
- package/dist/chunks/studio-tr20m8g8.js.map +9 -0
- package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
- package/dist/chunks/studio-v96qfnww.js.map +54 -0
- package/dist/chunks/studio-vcetc91k.js +659 -0
- package/dist/chunks/studio-vcetc91k.js.map +10 -0
- package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
- package/dist/chunks/studio-vmymjefp.js.map +98 -0
- package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
- package/dist/chunks/studio-x9hmy5kr.js +390 -0
- package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
- package/dist/chunks/studio-xa0ce0n7.js +335 -0
- package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
- package/dist/chunks/studio-xm3dbxvn.js +378 -0
- package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
- package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
- package/dist/chunks/studio-zv37yrfa.js +1054 -0
- package/dist/chunks/studio-zv37yrfa.js.map +13 -0
- package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
- package/dist/chunks/ws-client-654ts66j.js.map +11 -0
- package/dist/iframe-entry.js +668 -230
- package/dist/studio.js +21080 -32585
- package/index.html +35 -4685
- package/package.json +17 -15
- package/src/about/about-modal.ts +42 -11
- package/src/browse/library-commands.ts +240 -0
- package/src/browse/library-layouts.ts +369 -0
- package/src/browse/library-model.ts +396 -0
- package/src/browse/library-pane.ts +1049 -0
- package/src/browse/library-preview.ts +252 -0
- package/src/browse/library-source.ts +150 -0
- package/src/canvas/canvas-helpers.ts +33 -9
- package/src/canvas/canvas-live-render.ts +45 -29
- package/src/canvas/canvas-patcher.ts +151 -31
- package/src/canvas/canvas-perf.ts +46 -7
- package/src/canvas/canvas-render.ts +1092 -220
- package/src/canvas/canvas-surface.ts +240 -0
- package/src/canvas/canvas-utils.ts +1166 -124
- package/src/canvas/iframe-drop.ts +2 -1
- package/src/canvas/iframe-entry.ts +241 -4
- package/src/canvas/iframe-host.ts +1226 -143
- package/src/canvas/iframe-inline-edit.ts +31 -0
- package/src/canvas/iframe-interaction.ts +76 -16
- package/src/canvas/iframe-keys.ts +107 -45
- package/src/canvas/iframe-overlay.ts +38 -1
- package/src/canvas/iframe-protocol.ts +137 -2
- package/src/canvas/iframe-render.ts +70 -2
- package/src/canvas/iframe-slash.ts +6 -0
- package/src/canvas/path-mapping.ts +56 -6
- package/src/canvas/surface-registry.ts +292 -0
- package/src/collab/collab-commands.ts +244 -0
- package/src/collab/collab-session.ts +198 -32
- package/src/collab/collab-state.ts +28 -2
- package/src/collab/presence-chips.ts +100 -9
- package/src/commands/active-registry.ts +42 -0
- package/src/commands/app-commands.ts +176 -0
- package/src/commands/budget.ts +158 -0
- package/src/commands/command-args.ts +253 -0
- package/src/commands/context.ts +387 -0
- package/src/commands/defaults.ts +580 -0
- package/src/commands/keymap.ts +571 -0
- package/src/commands/levels.ts +345 -0
- package/src/commands/live-context.ts +193 -0
- package/src/commands/reference.ts +227 -0
- package/src/commands/registry.ts +293 -0
- package/src/component-props.ts +3 -2
- package/src/content/draft-state.ts +106 -0
- package/src/content/entry-commands.ts +282 -0
- package/src/content/entry-editor.ts +327 -0
- package/src/content/entry-fields.ts +116 -0
- package/src/content/entry-model.ts +175 -0
- package/src/editor/canvas-context-menu.ts +17 -11
- package/src/editor/canvas-slash-bridge.ts +11 -4
- package/src/editor/context-menu.ts +804 -204
- package/src/editor/convert-to-component.ts +31 -10
- package/src/editor/convert-to-repeater.ts +3 -2
- package/src/editor/inline-edit-apply.ts +5 -5
- package/src/editor/inline-edit.ts +86 -50
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/shortcuts.ts +1043 -329
- package/src/editor/slash-menu.ts +1 -0
- package/src/files/elements.ts +166 -0
- package/src/files/file-ops.ts +178 -31
- package/src/files/files.ts +898 -268
- package/src/files/fs-events.ts +21 -0
- package/src/files/media-meta.ts +203 -0
- package/src/files/media-paths.ts +141 -0
- package/src/files/media-upload.ts +7 -3
- package/src/files/media-usage.ts +189 -0
- package/src/github/github-auth.ts +235 -33
- package/src/github/github-publish.ts +80 -21
- package/src/grid/grid-controller.ts +152 -12
- package/src/grid/grid-layout.ts +225 -20
- package/src/grid/grid-open.ts +120 -0
- package/src/grid/grid-panel.ts +554 -39
- package/src/grid/grid-source.ts +27 -1
- package/src/grid/redirects-grid.ts +599 -0
- package/src/grid/redirects.ts +398 -0
- package/src/grid/sources/content-source.ts +108 -2
- package/src/i18n/i18n-commands.ts +322 -0
- package/src/new-project/add-repo-modal.ts +8 -10
- package/src/new-project/import-tab.ts +7 -0
- package/src/new-project/location-fields.ts +9 -1
- package/src/new-project/new-project-modal.ts +221 -245
- package/src/packages/jxsuite-update.ts +97 -48
- package/src/packages/pull-package-sync.ts +18 -9
- package/src/page-params.ts +2 -1
- package/src/panels/activity-bar.ts +152 -91
- package/src/panels/activity-panel.ts +481 -0
- package/src/panels/ai-chat/chat-markdown.ts +8 -3
- package/src/panels/ai-chat/chat-view.ts +245 -18
- package/src/panels/ai-chat/composer.ts +31 -5
- package/src/panels/ai-chat/sessions-view.ts +17 -10
- package/src/panels/ai-panel.ts +279 -53
- package/src/panels/block-action-bar.ts +1115 -224
- package/src/panels/bottom-dock.ts +337 -0
- package/src/panels/canvas-dnd-bridge.ts +37 -8
- package/src/panels/chat-panel.ts +29 -12
- package/src/panels/data-explorer.ts +254 -112
- package/src/panels/data-grid.ts +10 -4
- package/src/panels/dnd.ts +28 -51
- package/src/panels/editors.ts +434 -107
- package/src/panels/elements-panel.ts +66 -2
- package/src/panels/empty-state.ts +112 -0
- package/src/panels/events-panel.ts +596 -82
- package/src/panels/formula-workspace.ts +408 -218
- package/src/panels/frontmatter-fields.ts +51 -10
- package/src/panels/frontmatter-panel.ts +357 -79
- package/src/panels/git-panel.ts +375 -164
- package/src/panels/head-panel.ts +791 -85
- package/src/panels/i18n-panel.ts +592 -0
- package/src/panels/imports-panel.ts +95 -85
- package/src/panels/jump-bar.ts +584 -0
- package/src/panels/layers-panel.ts +1106 -328
- package/src/panels/left-panel.ts +109 -204
- package/src/panels/navigator-panels.ts +131 -0
- package/src/panels/overlays.ts +7 -2
- package/src/panels/pane-context.ts +1477 -0
- package/src/panels/pane-grid.ts +406 -0
- package/src/panels/panel-registry.ts +340 -0
- package/src/panels/panel-scheduler.ts +75 -0
- package/src/panels/problems-panel.ts +234 -0
- package/src/panels/properties-panel.ts +946 -1139
- package/src/panels/provenance.ts +258 -0
- package/src/panels/quick-search.ts +791 -122
- package/src/panels/right-panel.ts +228 -102
- package/src/panels/seo-modal.ts +395 -0
- package/src/panels/settings-pane.ts +203 -0
- package/src/panels/signals-panel.ts +354 -137
- package/src/panels/statement-editor.ts +41 -25
- package/src/panels/statusbar.ts +342 -106
- package/src/panels/style-panel.ts +974 -463
- package/src/panels/style-utils.ts +3 -3
- package/src/panels/stylebook-doc.ts +4 -2
- package/src/panels/stylebook-layers-panel.ts +3 -2
- package/src/panels/stylebook-panel.ts +51 -26
- package/src/panels/tab-strip.ts +1058 -78
- package/src/panels/target-line.ts +274 -0
- package/src/panels/toolbar.ts +631 -484
- package/src/panels/welcome-screen.ts +301 -198
- package/src/platform-errors.ts +26 -3
- package/src/platform.ts +96 -2
- package/src/platforms/cloud.ts +71 -8
- package/src/platforms/devserver.ts +92 -29
- package/src/publish/deploy-checklist.ts +383 -0
- package/src/publish/pages-service.ts +10 -1
- package/src/publish/publish-commands.ts +218 -0
- package/src/publish/publish-panel.ts +110 -16
- package/src/recent-projects.ts +3 -2
- package/src/services/a11y-report.ts +505 -0
- package/src/services/ai-models.ts +30 -1
- package/src/services/ai-project-tools.ts +29 -10
- package/src/services/ai-system-prompt.ts +53 -14
- package/src/services/ai-tools.ts +39 -3
- package/src/services/ai-writes.ts +154 -0
- package/src/services/announce.ts +97 -0
- package/src/services/automation.ts +424 -175
- package/src/services/cem-export.ts +9 -4
- package/src/services/clock.ts +61 -0
- package/src/services/document-assistant.ts +36 -8
- package/src/services/idle.ts +179 -0
- package/src/services/import-client.ts +26 -0
- package/src/services/monaco-buffer.ts +627 -0
- package/src/services/monaco-lazy.ts +36 -0
- package/src/services/notify.ts +271 -0
- package/src/services/profile.ts +155 -0
- package/src/services/references.ts +0 -0
- package/src/services/token-lint.ts +3 -2
- package/src/services/tool-executor.ts +53 -7
- package/src/services/trusted-types.ts +123 -0
- package/src/settings/contexts-section.ts +427 -0
- package/src/settings/contributed-section.ts +149 -11
- package/src/settings/css-vars-editor.ts +306 -349
- package/src/settings/defs-editor.ts +93 -34
- package/src/settings/dependencies-editor.ts +7 -7
- package/src/settings/extension-sections.ts +37 -5
- package/src/settings/general-settings.ts +204 -121
- package/src/settings/locales-section.ts +347 -0
- package/src/settings/preferences-accounts.ts +140 -0
- package/src/settings/preferences-dialog.ts +620 -0
- package/src/settings/preferences-keymap.ts +270 -0
- package/src/settings/project-sections.ts +260 -0
- package/src/settings/section-registry.ts +169 -0
- package/src/settings/settings-document.ts +385 -0
- package/src/shell.ts +1549 -0
- package/src/site-context.ts +45 -20
- package/src/state.ts +14 -275
- package/src/store.ts +88 -43
- package/src/studio.ts +790 -346
- package/src/style/live-preview.ts +36 -0
- package/src/style/project-styles.ts +349 -0
- package/src/style/token-ref.ts +123 -0
- package/src/tabs/patch-ops.ts +16 -4
- package/src/tabs/project-config.ts +416 -0
- package/src/tabs/selection.ts +323 -0
- package/src/tabs/tab.ts +182 -47
- package/src/tabs/transact.ts +209 -28
- package/src/types.ts +68 -13
- package/src/ui/ai-credentials-form.ts +39 -35
- package/src/ui/ai-managed-connect.ts +7 -1
- package/src/ui/dynamic-slot.ts +224 -81
- package/src/ui/expression-editor.ts +71 -63
- package/src/ui/field-input.ts +4 -6
- package/src/ui/field-row.ts +215 -38
- package/src/ui/form-controls.ts +194 -7
- package/src/ui/layers.ts +492 -69
- package/src/ui/media-picker.ts +115 -25
- package/src/ui/panel-resize.ts +109 -91
- package/src/ui/progress-modal.ts +131 -50
- package/src/ui/regions.ts +462 -0
- package/src/ui/schema-form.ts +229 -45
- package/src/ui/spectrum.ts +24 -8
- package/src/ui/timing.ts +49 -0
- package/src/ui/value-selector.ts +20 -0
- package/src/ui/value-source.ts +348 -0
- package/src/ui/virtual-window.ts +400 -0
- package/src/utils/edit-display.ts +3 -2
- package/src/utils/inherited-style.ts +67 -37
- package/src/view.ts +64 -78
- package/src/workspace/pane-derive.ts +1258 -0
- package/src/workspace/session.ts +317 -0
- package/src/workspace/workspace.ts +1345 -23
- package/styles/canvas.css +653 -0
- package/styles/forced-colors.css +106 -0
- package/styles/inspector.css +1454 -0
- package/styles/overlays.css +2704 -0
- package/styles/panels.css +1701 -0
- package/styles/shell.css +1423 -0
- package/styles/tokens.css +151 -0
- package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
- package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
- package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
- package/dist/chunks/files-j8a1t06k.js +0 -50
- package/dist/chunks/files-j8a1t06k.js.map +0 -9
- package/dist/chunks/git-panel-xtq5z81x.js +0 -28
- package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
- package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
- package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
- package/dist/chunks/settings-modal-17ttr96g.js +0 -29
- package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
- package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
- package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
- package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
- package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
- package/dist/chunks/studio-0xgs7xrs.js +0 -429
- package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
- package/dist/chunks/studio-4d8hzcz5.js +0 -3427
- package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
- package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
- package/dist/chunks/studio-9smfzqhc.js +0 -19
- package/dist/chunks/studio-9smfzqhc.js.map +0 -10
- package/dist/chunks/studio-jm0z592w.js.map +0 -115
- package/dist/chunks/studio-m2t4mdg5.js +0 -1854
- package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
- package/dist/chunks/studio-n4p11dfy.js +0 -853
- package/dist/chunks/studio-n4p11dfy.js.map +0 -12
- package/dist/chunks/studio-qkvt37c0.js.map +0 -9
- package/dist/chunks/studio-sjh1wt1a.js +0 -3744
- package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
- package/dist/chunks/studio-v7jkjqng.js.map +0 -46
- package/dist/chunks/studio-xq0t7n5t.js +0 -140
- package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
- package/dist/chunks/studio-xze4zrs1.js.map +0 -10
- package/dist/chunks/studio-yfcstdzy.js +0 -399
- package/dist/chunks/studio-yfcstdzy.js.map +0 -12
- package/dist/chunks/studio-zp7jncs8.js +0 -469
- package/dist/chunks/studio-zp7jncs8.js.map +0 -14
- package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
- package/src/browse/browse-modal.ts +0 -69
- package/src/browse/browse.ts +0 -904
- package/src/canvas/canvas-diff.ts +0 -216
- package/src/canvas/nested-site-style.ts +0 -58
- package/src/new-project/design-fields.ts +0 -264
- package/src/new-project/templates.ts +0 -61
- package/src/panels/tab-bar.ts +0 -548
- package/src/settings/settings-modal.ts +0 -203
- /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
- /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
- /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
- /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
- /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
- /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
- /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
- /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushing a project-style edit to every live canvas — one definition site.
|
|
3
|
+
*
|
|
4
|
+
* Plan §9.4's promise is "tune a design token and watch the page change", and until now that was
|
|
5
|
+
* true of exactly one kind of canvas. `postSiteStyleToLiveHosts` skips stylebook hosts by
|
|
6
|
+
* construction ({@link file://../canvas/iframe-host.ts}: `host.ready && !host.stylebook`), because
|
|
7
|
+
* a specimen canvas does not render the site sheet — it renders a GENERATED document whose root
|
|
8
|
+
* carries the transposed effective style, and its live channel is `styleUpdate`, not
|
|
9
|
+
* `siteStyleUpdate`. So a token edited in the token editor reached every page canvas immediately
|
|
10
|
+
* and left the Project Styles canvas — the one the plan puts _beside_ the editor — showing the old
|
|
11
|
+
* palette until something forced a full re-render.
|
|
12
|
+
*
|
|
13
|
+
* Two hosts, two messages, one event. Every surface that writes `projectConfig.style` calls this
|
|
14
|
+
* instead of picking one of the two posts, which is the only arrangement in which the pair cannot
|
|
15
|
+
* drift apart again.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { postSiteStyleToLiveHosts, postStyleUpdateToStylebookHosts } from "../canvas/iframe-host";
|
|
19
|
+
import { transposeStylebookStyle } from "../panels/stylebook-doc";
|
|
20
|
+
import { getEffectiveStyle } from "../site-context";
|
|
21
|
+
import { activeTab } from "../workspace/workspace";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Re-apply the project's style to every live canvas, in place — no re-render.
|
|
25
|
+
*
|
|
26
|
+
* The stylebook post needs the EFFECTIVE style (site merged with the open document's), because a
|
|
27
|
+
* specimen canvas opened on a component shows that component's `& <tag>` defaults too; posting the
|
|
28
|
+
* site style alone would silently drop them until the next full render. That is the one thing here
|
|
29
|
+
* that reads the focused document, and it reads it to refresh a document-level canvas, not to
|
|
30
|
+
* source a project-level badge.
|
|
31
|
+
*/
|
|
32
|
+
export function pushProjectStylesToCanvas(): void {
|
|
33
|
+
postSiteStyleToLiveHosts();
|
|
34
|
+
const style = transposeStylebookStyle(getEffectiveStyle(activeTab.value?.doc.document?.style));
|
|
35
|
+
postStyleUpdateToStylebookHosts(style as Record<string, unknown>);
|
|
36
|
+
}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Styles — the model behind the project's design tokens and element defaults.
|
|
3
|
+
*
|
|
4
|
+
* ## The name and the wire value are different things
|
|
5
|
+
*
|
|
6
|
+
* The surface a user reaches is called **Project Styles** (plan §9.4). The canvas view it opens is
|
|
7
|
+
* the string `"stylebook"`, a member of `CANVAS_MODES` in
|
|
8
|
+
* {@link file://../canvas/iframe-protocol.ts} and therefore half of a `ParentToIframe` union: the
|
|
9
|
+
* studio bundle and `dist/iframe-entry.js` agree on it, and changing it means rebuilding both in
|
|
10
|
+
* lockstep. So it is not a name and may never be renamed to follow one.
|
|
11
|
+
* {@link PROJECT_STYLES_TITLE} is the name; {@link PROJECT_STYLES_VIEW} is the wire value; a
|
|
12
|
+
* surface that needs one must not reach for the other.
|
|
13
|
+
*
|
|
14
|
+
* ## One vocabulary for the `@` blocks
|
|
15
|
+
*
|
|
16
|
+
* A token's value can differ per rendering context, and on disk every such override lives in the
|
|
17
|
+
* same place — a `@<name>` block beside the token, keyed by a `$media` entry name. Breakpoints and
|
|
18
|
+
* colour schemes are two _kinds_ of that one thing, and this module models them as one
|
|
19
|
+
* {@link TokenContext} list so a surface cannot grow a second override path for the second kind (a
|
|
20
|
+
* per-scheme writer and a per-media writer that disagreed about pruning an emptied block is exactly
|
|
21
|
+
* what this replaces). Contexts are **defined** in Project Settings › Contexts and only selected or
|
|
22
|
+
* overridden here — §2 principle 5.
|
|
23
|
+
*
|
|
24
|
+
* On-disk format is unchanged by anything in this module: it reads and writes the same
|
|
25
|
+
* `style["--token"]` and `style["@--ctx"]["--token"]` shapes the compiler already consumes.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { parseMediaEntries, schemeOfQuery } from "../utils/canvas-media";
|
|
29
|
+
import { varDisplayName } from "../utils/studio-utils";
|
|
30
|
+
|
|
31
|
+
import type { JxStyle } from "@jxsuite/schema/types";
|
|
32
|
+
import type { CanvasMode } from "../canvas/iframe-protocol";
|
|
33
|
+
|
|
34
|
+
/** What the surface is called, everywhere a reader sees it. One definition site. */
|
|
35
|
+
export const PROJECT_STYLES_TITLE = "Project Styles";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The canvas view Project Styles opens — a WIRE value, not a name. See the module doc: it is a
|
|
39
|
+
* `CANVAS_MODES` member shared with the iframe bundle, and it stays `"stylebook"`.
|
|
40
|
+
*/
|
|
41
|
+
export const PROJECT_STYLES_VIEW: CanvasMode = "stylebook";
|
|
42
|
+
|
|
43
|
+
// ─── Token groups ────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
/** The four buckets the token editor lists, in display order. */
|
|
46
|
+
export type TokenGroupId = "color" | "font" | "size" | "other";
|
|
47
|
+
|
|
48
|
+
export interface TokenGroup {
|
|
49
|
+
id: TokenGroupId;
|
|
50
|
+
/** The group heading. */
|
|
51
|
+
title: string;
|
|
52
|
+
/** The prefix a token added in this group is named under. */
|
|
53
|
+
prefix: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The groups, in order. `other` is rendered only when something lands in it — a bucket named
|
|
58
|
+
* "Other" over an empty list teaches nothing (§2 principle 6).
|
|
59
|
+
*
|
|
60
|
+
* A group is a name and a prefix and nothing else. The example values an add row hints with are a
|
|
61
|
+
* property of the FORM, not of the model, and they live beside the form that shows them.
|
|
62
|
+
*/
|
|
63
|
+
export const TOKEN_GROUPS: readonly TokenGroup[] = [
|
|
64
|
+
{ id: "color", prefix: "--color-", title: "Colors" },
|
|
65
|
+
{ id: "font", prefix: "--font-", title: "Fonts" },
|
|
66
|
+
{ id: "size", prefix: "--size-", title: "Sizes & Spacing" },
|
|
67
|
+
{ id: "other", prefix: "--", title: "Other" },
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Which group a custom property belongs to, by prefix.
|
|
72
|
+
*
|
|
73
|
+
* @param {string} name
|
|
74
|
+
* @returns {TokenGroupId}
|
|
75
|
+
*/
|
|
76
|
+
export function groupIdOfToken(name: string): TokenGroupId {
|
|
77
|
+
if (name.startsWith("--color")) {
|
|
78
|
+
return "color";
|
|
79
|
+
}
|
|
80
|
+
if (name.startsWith("--font")) {
|
|
81
|
+
return "font";
|
|
82
|
+
}
|
|
83
|
+
if (name.startsWith("--size") || name.startsWith("--spacing") || name.startsWith("--radius")) {
|
|
84
|
+
return "size";
|
|
85
|
+
}
|
|
86
|
+
return "other";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The label a reader sees for a token: the friendly name it was added under, recovered from the
|
|
91
|
+
* variable name. `--color-primary-blue` → "Primary Blue".
|
|
92
|
+
*
|
|
93
|
+
* The `other` group keeps its raw name deliberately — a token there has no prefix to strip, so "Z
|
|
94
|
+
* Index Modal" would be a guess at a name its author never typed.
|
|
95
|
+
*
|
|
96
|
+
* @param {string} name
|
|
97
|
+
* @returns {string}
|
|
98
|
+
*/
|
|
99
|
+
export function tokenLabel(name: string): string {
|
|
100
|
+
const group = groupIdOfToken(name);
|
|
101
|
+
if (group === "other") {
|
|
102
|
+
return name;
|
|
103
|
+
}
|
|
104
|
+
/*
|
|
105
|
+
* `varDisplayName` falls back to stripping a bare `--` when the prefix does not match, which is
|
|
106
|
+
* what turns `--spacing-lg` (group `size`, prefix `--size-`) into "Spacing Lg". The predecessor
|
|
107
|
+
* chained three prefixes with `||` and never reached the second, because the first always
|
|
108
|
+
* returns a truthy string.
|
|
109
|
+
*/
|
|
110
|
+
const { prefix } = TOKEN_GROUPS.find((g) => g.id === group)!;
|
|
111
|
+
return varDisplayName(name, prefix);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ─── Tokens ──────────────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
/** One design token declared at the top level of a style block. */
|
|
117
|
+
export interface ProjectToken {
|
|
118
|
+
/** The custom property, e.g. `--color-primary`. */
|
|
119
|
+
name: string;
|
|
120
|
+
group: TokenGroupId;
|
|
121
|
+
/** What a reader sees — {@link tokenLabel}. */
|
|
122
|
+
label: string;
|
|
123
|
+
value: string | number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Every design token in a style block, in declaration order.
|
|
128
|
+
*
|
|
129
|
+
* Non-custom properties (`color: blue`) and object values are not tokens and are skipped — an
|
|
130
|
+
* object under a `--` key is malformed, and every `@ctx` block is an object by construction.
|
|
131
|
+
*
|
|
132
|
+
* @param {JxStyle | null | undefined} style
|
|
133
|
+
* @returns {ProjectToken[]}
|
|
134
|
+
*/
|
|
135
|
+
export function listTokens(style: JxStyle | null | undefined): ProjectToken[] {
|
|
136
|
+
if (!style) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
const out: ProjectToken[] = [];
|
|
140
|
+
for (const [name, value] of Object.entries(style)) {
|
|
141
|
+
if (!name.startsWith("--")) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
out.push({ group: groupIdOfToken(name), label: tokenLabel(name), name, value });
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Group tokens for display: every group in {@link TOKEN_GROUPS} order, each with its members.
|
|
154
|
+
*
|
|
155
|
+
* @param {JxStyle | null | undefined} style
|
|
156
|
+
* @returns {{ group: TokenGroup; tokens: ProjectToken[] }[]}
|
|
157
|
+
*/
|
|
158
|
+
export function groupTokens(
|
|
159
|
+
style: JxStyle | null | undefined,
|
|
160
|
+
): { group: TokenGroup; tokens: ProjectToken[] }[] {
|
|
161
|
+
const tokens = listTokens(style);
|
|
162
|
+
return TOKEN_GROUPS.map((group) => ({
|
|
163
|
+
group,
|
|
164
|
+
tokens: tokens.filter((t) => t.group === group.id),
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ─── Rendering contexts ──────────────────────────────────────────────────────
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* What a context IS, for a reader. `size` is a breakpoint, `scheme` is a colour scheme, `feature`
|
|
172
|
+
* is any other feature query. The distinction decides only how the row is labelled and whether it
|
|
173
|
+
* is offered unprompted — the on-disk block is the same shape for all three.
|
|
174
|
+
*/
|
|
175
|
+
export type TokenContextKind = "size" | "scheme" | "feature";
|
|
176
|
+
|
|
177
|
+
/** A declared `$media` entry, seen as a place a token can carry a different value. */
|
|
178
|
+
export interface TokenContext {
|
|
179
|
+
/** The `$media` entry name, e.g. `--sm` or `--dark`. */
|
|
180
|
+
name: string;
|
|
181
|
+
/** The style key its overrides live under, e.g. `@--sm`. */
|
|
182
|
+
key: string;
|
|
183
|
+
/** What the reader sees: "Dark" for a scheme, the raw `@--sm` for anything else. */
|
|
184
|
+
label: string;
|
|
185
|
+
kind: TokenContextKind;
|
|
186
|
+
/** Present only when `kind` is `"scheme"`. */
|
|
187
|
+
scheme?: "light" | "dark";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The contexts a token can be overridden in, derived from `$media`.
|
|
192
|
+
*
|
|
193
|
+
* Schemes come first because they are the pair a colour token is always asked about; breakpoints
|
|
194
|
+
* follow in the order {@link parseMediaEntries} sorts them (the same order the canvas shows its
|
|
195
|
+
* panels in), then any other feature query. `--` is the base canvas width, not a context.
|
|
196
|
+
*
|
|
197
|
+
* @param {Record<string, string> | null | undefined} media
|
|
198
|
+
* @returns {TokenContext[]}
|
|
199
|
+
*/
|
|
200
|
+
export function listTokenContexts(
|
|
201
|
+
media: Record<string, string> | null | undefined,
|
|
202
|
+
): TokenContext[] {
|
|
203
|
+
if (!media) {
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
const { featureQueries, sizeBreakpoints } = parseMediaEntries(media);
|
|
207
|
+
const schemes: TokenContext[] = [];
|
|
208
|
+
const features: TokenContext[] = [];
|
|
209
|
+
for (const { name, query } of featureQueries) {
|
|
210
|
+
const scheme = schemeOfQuery(query);
|
|
211
|
+
if (scheme) {
|
|
212
|
+
schemes.push({
|
|
213
|
+
key: `@${name}`,
|
|
214
|
+
kind: "scheme",
|
|
215
|
+
label: scheme === "dark" ? "Dark" : "Light",
|
|
216
|
+
name,
|
|
217
|
+
scheme,
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
features.push({ key: `@${name}`, kind: "feature", label: `@${name}`, name });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const sizes: TokenContext[] = sizeBreakpoints.map(({ name }) => ({
|
|
224
|
+
key: `@${name}`,
|
|
225
|
+
kind: "size",
|
|
226
|
+
label: `@${name}`,
|
|
227
|
+
name,
|
|
228
|
+
}));
|
|
229
|
+
return [...schemes, ...sizes, ...features];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ─── Overrides ───────────────────────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
/** A token's value in one context, alongside the context it came from. */
|
|
235
|
+
export interface TokenOverride {
|
|
236
|
+
context: TokenContext;
|
|
237
|
+
value: string | number;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The block a context's overrides live in, or undefined when the context carries none.
|
|
242
|
+
*
|
|
243
|
+
* @param {JxStyle} style
|
|
244
|
+
* @param {TokenContext} context
|
|
245
|
+
*/
|
|
246
|
+
function overrideBlock(style: JxStyle, context: TokenContext): Record<string, unknown> | undefined {
|
|
247
|
+
const block = style[context.key];
|
|
248
|
+
return block && typeof block === "object" ? (block as Record<string, unknown>) : undefined;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* A token's value in one context, or undefined when it inherits the base value.
|
|
253
|
+
*
|
|
254
|
+
* @param {JxStyle} style
|
|
255
|
+
* @param {TokenContext} context
|
|
256
|
+
* @param {string} token
|
|
257
|
+
* @returns {string | number | undefined}
|
|
258
|
+
*/
|
|
259
|
+
export function readTokenOverride(
|
|
260
|
+
style: JxStyle,
|
|
261
|
+
context: TokenContext,
|
|
262
|
+
token: string,
|
|
263
|
+
): string | number | undefined {
|
|
264
|
+
const value = overrideBlock(style, context)?.[token];
|
|
265
|
+
return typeof value === "string" || typeof value === "number" ? value : undefined;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Write or clear a token's override in one context, IN PLACE.
|
|
270
|
+
*
|
|
271
|
+
* An empty value clears it, and an emptied block is removed rather than left as `"@--dark": {}` — a
|
|
272
|
+
* block that exists but says nothing is a diff on every save and a rule the compiler emits for no
|
|
273
|
+
* reason. The block is recreated on demand, so a caller holding a stale render still writes to the
|
|
274
|
+
* right place.
|
|
275
|
+
*
|
|
276
|
+
* @param {JxStyle} style
|
|
277
|
+
* @param {TokenContext} context
|
|
278
|
+
* @param {string} token
|
|
279
|
+
* @param {string} value — empty clears
|
|
280
|
+
*/
|
|
281
|
+
export function writeTokenOverride(
|
|
282
|
+
style: JxStyle,
|
|
283
|
+
context: TokenContext,
|
|
284
|
+
token: string,
|
|
285
|
+
value: string,
|
|
286
|
+
): void {
|
|
287
|
+
if (value) {
|
|
288
|
+
const block = (style[context.key] ??= {}) as Record<string, unknown>;
|
|
289
|
+
block[token] = value;
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const block = overrideBlock(style, context);
|
|
293
|
+
if (!block) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
delete block[token];
|
|
297
|
+
if (Object.keys(block).length === 0) {
|
|
298
|
+
delete style[context.key];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Every context in which a token already carries an override, in {@link listTokenContexts} order.
|
|
304
|
+
*
|
|
305
|
+
* @param {JxStyle} style
|
|
306
|
+
* @param {readonly TokenContext[]} contexts
|
|
307
|
+
* @param {string} token
|
|
308
|
+
* @returns {TokenOverride[]}
|
|
309
|
+
*/
|
|
310
|
+
export function tokenOverrides(
|
|
311
|
+
style: JxStyle,
|
|
312
|
+
contexts: readonly TokenContext[],
|
|
313
|
+
token: string,
|
|
314
|
+
): TokenOverride[] {
|
|
315
|
+
const out: TokenOverride[] = [];
|
|
316
|
+
for (const context of contexts) {
|
|
317
|
+
const value = readTokenOverride(style, context, token);
|
|
318
|
+
if (value !== undefined) {
|
|
319
|
+
out.push({ context, value });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return out;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* The contexts a token can still be given an override in — the add affordance's menu.
|
|
327
|
+
*
|
|
328
|
+
* The predecessor had none: an override row appeared only for a token that already carried an
|
|
329
|
+
* `@media` block, so the only way to create the first one was to hand-edit `project.json`. This is
|
|
330
|
+
* the list of contexts that are declared and not yet used, minus the ones already shown unprompted
|
|
331
|
+
* (`alreadyShown`), so the menu never offers a row the reader is already looking at.
|
|
332
|
+
*
|
|
333
|
+
* @param {JxStyle} style
|
|
334
|
+
* @param {readonly TokenContext[]} contexts
|
|
335
|
+
* @param {string} token
|
|
336
|
+
* @param {readonly TokenContext[]} [alreadyShown]
|
|
337
|
+
* @returns {TokenContext[]}
|
|
338
|
+
*/
|
|
339
|
+
export function addableContexts(
|
|
340
|
+
style: JxStyle,
|
|
341
|
+
contexts: readonly TokenContext[],
|
|
342
|
+
token: string,
|
|
343
|
+
alreadyShown: readonly TokenContext[] = [],
|
|
344
|
+
): TokenContext[] {
|
|
345
|
+
const shown = new Set(alreadyShown.map((c) => c.name));
|
|
346
|
+
return contexts.filter(
|
|
347
|
+
(context) => !shown.has(context.name) && readTokenOverride(style, context, token) === undefined,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token references — reading `var(--token)` as a binding, and rendering it as a chip.
|
|
3
|
+
*
|
|
4
|
+
* A style value that is exactly `var(--something)` is not a value, it is a reference to one. Raw
|
|
5
|
+
* text says so only to a reader who already knows CSS: `var(--color-brand)` is eleven characters of
|
|
6
|
+
* syntax around a name, and the thing the author actually wants to know — _which_ token, and what
|
|
7
|
+
* it currently resolves to — is the part that is not shown. So a bound value renders as a **chip**
|
|
8
|
+
* (plan §9.4), in the same vocabulary as the provenance chips shipped in P5: the token's friendly
|
|
9
|
+
* name, and for a colour, its resolved swatch.
|
|
10
|
+
*
|
|
11
|
+
* The resolver follows a chain of references, because an alias token (`--color-accent:
|
|
12
|
+
* var(--color-brand)`) is the normal way a palette is built and a chip that stopped at the first
|
|
13
|
+
* hop would report `var(--color-brand)` as a colour.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { html } from "lit-html";
|
|
17
|
+
import { tokenLabel } from "./project-styles";
|
|
18
|
+
|
|
19
|
+
import type { JxStyle } from "@jxsuite/schema/types";
|
|
20
|
+
import type { TemplateResult } from "lit-html";
|
|
21
|
+
|
|
22
|
+
/** A value that is EXACTLY one `var()` reference — not `calc(var(--a) * 2)`, which is a value. */
|
|
23
|
+
const TOKEN_REF_RE = /^var\(\s*(--[\w-]+)\s*\)$/;
|
|
24
|
+
|
|
25
|
+
/** How many hops the resolver follows before it decides the chain is a cycle. */
|
|
26
|
+
const MAX_HOPS = 10;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The token a value references, or null when the value is not a bare reference.
|
|
30
|
+
*
|
|
31
|
+
* @param {unknown} value
|
|
32
|
+
* @returns {string | null}
|
|
33
|
+
*/
|
|
34
|
+
export function tokenRefName(value: unknown): string | null {
|
|
35
|
+
if (typeof value !== "string") {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return TOKEN_REF_RE.exec(value)?.[1] ?? null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The reference form of a token name — the value written into a style field that follows it.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} name
|
|
45
|
+
* @returns {string}
|
|
46
|
+
*/
|
|
47
|
+
export function toTokenRef(name: string): string {
|
|
48
|
+
return `var(${name})`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Follow a value's references to the concrete value at the end of the chain.
|
|
53
|
+
*
|
|
54
|
+
* Returns undefined when the chain leaves the style block (a token defined by a stylesheet the
|
|
55
|
+
* editor cannot see) or loops back on itself. A caller shows the raw text in both cases: an
|
|
56
|
+
* unresolvable reference is still a reference, and inventing a value for it would be worse than
|
|
57
|
+
* saying nothing.
|
|
58
|
+
*
|
|
59
|
+
* @param {JxStyle | null | undefined} style
|
|
60
|
+
* @param {string | number | null | undefined} value
|
|
61
|
+
* @returns {string | number | undefined}
|
|
62
|
+
*/
|
|
63
|
+
export function resolveTokenValue(
|
|
64
|
+
style: JxStyle | null | undefined,
|
|
65
|
+
value: string | number | null | undefined,
|
|
66
|
+
): string | number | undefined {
|
|
67
|
+
if (value === null || value === undefined) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
let current: string | number = value;
|
|
71
|
+
const seen = new Set<string>();
|
|
72
|
+
for (let hop = 0; hop < MAX_HOPS; hop += 1) {
|
|
73
|
+
const ref = tokenRefName(current);
|
|
74
|
+
if (!ref) {
|
|
75
|
+
return current;
|
|
76
|
+
}
|
|
77
|
+
if (seen.has(ref)) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
seen.add(ref);
|
|
81
|
+
const next = style?.[ref];
|
|
82
|
+
if (typeof next !== "string" && typeof next !== "number") {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
current = next;
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Render a bound value as a chip: the referenced token's name, and — for a colour — the swatch it
|
|
92
|
+
* resolves to. The `title` carries the full reference and its resolution, because the chip is
|
|
93
|
+
* deliberately short and a reader who needs the literal must still be able to get it.
|
|
94
|
+
*
|
|
95
|
+
* The chip is not a control. Following it somewhere would be a second navigation contract on a
|
|
96
|
+
* surface that already lists every token a scroll away, and a chip that looks clickable and is not
|
|
97
|
+
* is the defect §6.2 removed from the collapsed-section dot.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} name — the referenced token
|
|
100
|
+
* @param {string | number | undefined} resolved — {@link resolveTokenValue} of the reference
|
|
101
|
+
* @param {{ swatch?: boolean }} [opts] — `swatch` renders the resolved value as a colour chip
|
|
102
|
+
* @returns {TemplateResult}
|
|
103
|
+
*/
|
|
104
|
+
export function renderTokenChip(
|
|
105
|
+
name: string,
|
|
106
|
+
resolved: string | number | undefined,
|
|
107
|
+
opts: { swatch?: boolean } = {},
|
|
108
|
+
): TemplateResult {
|
|
109
|
+
const shown = resolved === undefined ? "unresolved" : String(resolved);
|
|
110
|
+
return html`
|
|
111
|
+
<span class="style-token-chip" title="${toTokenRef(name)} → ${shown}">
|
|
112
|
+
${
|
|
113
|
+
opts.swatch && resolved !== undefined
|
|
114
|
+
? html`<span
|
|
115
|
+
class="style-token-chip-swatch"
|
|
116
|
+
style="background:${String(resolved)}"
|
|
117
|
+
></span>`
|
|
118
|
+
: ""
|
|
119
|
+
}
|
|
120
|
+
<span class="style-token-chip-label">${tokenLabel(name)}</span>
|
|
121
|
+
</span>
|
|
122
|
+
`;
|
|
123
|
+
}
|
package/src/tabs/patch-ops.ts
CHANGED
|
@@ -74,16 +74,28 @@ export interface TransactionRecord {
|
|
|
74
74
|
export interface PatchConsumer {
|
|
75
75
|
/** Decide whether this batch can be applied surgically in the current canvas state. */
|
|
76
76
|
classify: (tab: Tab, ops: JxPatchOp[]) => { patchable: boolean; reason: string };
|
|
77
|
-
/**
|
|
78
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Mark a document root reference as surgically consumed, in every pane the patch will reach.
|
|
79
|
+
*
|
|
80
|
+
* `tab` is what decides those panes — one pane owns it, and a derived pane may be projecting that
|
|
81
|
+
* pane — and each pane's canvas doc-effect clears only its own mark. A single mark per reference
|
|
82
|
+
* was consumed by whichever pane's effect ran first, so the second full-rendered every patched
|
|
83
|
+
* edit while the skip counter reported one skip.
|
|
84
|
+
*/
|
|
85
|
+
markConsumed: (docRef: object, tab: Tab) => void;
|
|
79
86
|
/**
|
|
80
87
|
* Apply the batch to all ready canvas panels. Throws on any failure (caller escalates). `record`
|
|
81
88
|
* carries the value-carrying `docOps` the iframe consumer posts across the frame boundary; the
|
|
82
89
|
* legacy (parent-DOM) consumer ignores it and reads the post-mutation reactive doc instead.
|
|
83
90
|
*/
|
|
84
91
|
apply: (tab: Tab, ops: JxPatchOp[], record?: TransactionRecord) => void;
|
|
85
|
-
/**
|
|
86
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Schedule a full canvas render as the fallback path, recording the reason.
|
|
94
|
+
*
|
|
95
|
+
* `tab` names the document that failed to patch, and so the PANE whose stage must be rebuilt: a
|
|
96
|
+
* stage that is not showing this document is not out of date and must not be re-rendered.
|
|
97
|
+
*/
|
|
98
|
+
escalate: (reason: string, tab: Tab) => void;
|
|
87
99
|
}
|
|
88
100
|
|
|
89
101
|
let _consumer: PatchConsumer | null = null;
|