@jxsuite/studio 10.1.0 → 10.3.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/dist/chunks/{2020-mkb0qa6p.js → 2020-906vx2dq.js} +3 -3
- package/dist/chunks/adapter-hnvad61x.js +4 -0
- package/dist/chunks/add-new-flow-3tkn72ey.js +4 -0
- package/dist/chunks/cf-account-picker-xb8vvt2h.js +4 -0
- package/dist/chunks/cf-settings-mkbcz4z2.js +4 -0
- package/dist/chunks/components-w5zqwva1.js +4 -0
- package/dist/chunks/content-source-1vzxq1ba.js +4 -0
- package/dist/chunks/convert-to-repeater-gwzh9gar.js +4 -0
- package/dist/chunks/editor-wvf5e6j9.js +4 -0
- package/dist/chunks/entry-commands-mx2whrjx.js +4 -0
- package/dist/chunks/extension-sections-338ee35t.js +4 -0
- package/dist/chunks/file-ops-9bxvk59j.js +4 -0
- package/dist/chunks/files-t07yqqej.js +4 -0
- package/dist/chunks/format-host-5ja5gxyk.js +4 -0
- package/dist/chunks/fs-events-3424ezp3.js +4 -0
- package/dist/chunks/grid-open-1mpq9mzb.js +4 -0
- package/dist/chunks/{grid-view-r22jsqht.js → grid-view-w9nfy203.js} +15 -15
- package/dist/chunks/icons-gb967qc8.js +4 -0
- package/dist/chunks/iframe-host-wsg0bn73.js +4 -0
- package/dist/chunks/image-bake-4afr4y6a.js +4 -0
- package/dist/chunks/image-editor-x7t8jbjn.js +4 -0
- package/dist/chunks/index-f9qr7kzh.js +4 -0
- package/dist/chunks/{index-pxwwf00y.js → index-yjrfeks8.js} +3 -3
- package/dist/chunks/{javascript-pzqryby6.js → javascript-hy2mws8v.js} +3 -3
- package/dist/chunks/{jsonMode-tcnyxyap.js → jsonMode-vj30te2h.js} +6 -6
- package/dist/chunks/jx-validate-ttr5ewf0.js +4 -0
- package/dist/chunks/layers-m49nmwvx.js +4 -0
- package/dist/chunks/layers-panel-hvy2e549.js +4 -0
- package/dist/chunks/lit-html-k2mb9k0r.js +4 -0
- package/dist/chunks/media-library-ae67q4at.js +4 -0
- package/dist/chunks/media-open-yp9jm834.js +4 -0
- package/dist/chunks/media-picker-s41ngdfr.js +4 -0
- package/dist/chunks/{monaco-binding-bqpge64f.js → monaco-binding-a51py33c.js} +3 -3
- package/dist/chunks/monaco-buffer-pa0g6ax7.js +4 -0
- package/dist/chunks/{monaco-setup-1mkab762.js → monaco-setup-g9kterhx.js} +3 -3
- package/dist/chunks/notify-bwehrp7q.js +4 -0
- package/dist/chunks/parse-hee7ne9b.js +4 -0
- package/dist/chunks/platform-kv0k65cy.js +4 -0
- package/dist/chunks/publish-panel-gzfxcm0t.js +4 -0
- package/dist/chunks/publish-quick-w3nxd7q4.js +4 -0
- package/dist/chunks/publish-workspace-dppd82tc.js +4 -0
- package/dist/chunks/quick-search-tdxaam55.js +4 -0
- package/dist/chunks/references-vqyr5s9x.js +4 -0
- package/dist/chunks/right-panel-0yrw4cgz.js +4 -0
- package/dist/chunks/source-control-6fk72me2.js +4 -0
- package/dist/chunks/{studio-0g2sm01j.js → studio-0939t1q1.js} +4 -4
- package/dist/chunks/studio-0gvvqj3h.js +5 -0
- package/dist/chunks/studio-0khd8xtx.js +4 -0
- package/dist/chunks/{studio-rf8d6p9f.js → studio-0w3541dg.js} +6 -6
- package/dist/chunks/{studio-9b7177jq.js → studio-0x6f3nk9.js} +4 -4
- package/dist/chunks/studio-1410q5dw.js +5 -0
- package/dist/chunks/{studio-8qejv8yf.js → studio-15hwqgd8.js} +4 -4
- package/dist/chunks/studio-1ks5d9y4.js +5 -0
- package/dist/chunks/{studio-881z1xrx.js → studio-2ggfzrrd.js} +4 -4
- package/dist/chunks/{studio-jw0q5j6k.js → studio-321ym1tt.js} +4 -4
- package/dist/chunks/studio-3c10v2q1.js +5 -0
- package/dist/chunks/{studio-9rcbvksg.js → studio-3na1r48j.js} +8 -8
- package/dist/chunks/{studio-ggm7zf70.js → studio-3q7mhbgx.js} +5 -5
- package/dist/chunks/studio-3qr08sxq.js +4 -0
- package/dist/chunks/studio-3xk9zdgb.js +5 -0
- package/dist/chunks/studio-423tfdte.js +5 -0
- package/dist/chunks/{studio-brdp85q7.js → studio-45mj4jqe.js} +4 -4
- package/dist/chunks/studio-4f7thq0p.js +5 -0
- package/dist/chunks/{studio-w67vfgy5.js → studio-4fnb5648.js} +4 -4
- package/dist/chunks/studio-4zd6an2b.js +5 -0
- package/dist/chunks/studio-53wy9ek3.js +5 -0
- package/dist/chunks/studio-5n193zqd.js +5 -0
- package/dist/chunks/{studio-x2metr13.js → studio-5tet77de.js} +3 -3
- package/dist/chunks/studio-7rrdbvex.js +5 -0
- package/dist/chunks/studio-8kx6m0rg.js +5 -0
- package/dist/chunks/{studio-va0e63sk.js → studio-90zkgne5.js} +7 -7
- package/dist/chunks/studio-9c6cbq2c.js +4 -0
- package/dist/chunks/studio-9dq7rwc7.js +5 -0
- package/dist/chunks/studio-9qx1ywbv.js +9 -0
- package/dist/chunks/studio-a65kbs2e.js +9 -0
- package/dist/chunks/studio-aam8zt8z.js +5 -0
- package/dist/chunks/{studio-8jb31dcf.js → studio-abh9kfdh.js} +4 -4
- package/dist/chunks/studio-b4e0ftkt.js +5 -0
- package/dist/chunks/studio-b68k0z00.js +5 -0
- package/dist/chunks/{studio-dy2xtt7a.js → studio-bct64zmj.js} +4 -4
- package/dist/chunks/studio-bz0b5brj.js +6 -0
- package/dist/chunks/studio-cfnn70h1.js +5 -0
- package/dist/chunks/studio-daksw8kh.js +5 -0
- package/dist/chunks/{studio-mwnmzx7g.js → studio-e7vjyp04.js} +7 -7
- package/dist/chunks/studio-ea6r1zyr.js +5 -0
- package/dist/chunks/studio-egnjpyde.js +9 -0
- package/dist/chunks/studio-ejrypvmq.js +5 -0
- package/dist/chunks/studio-eqcddvc2.js +928 -0
- package/dist/chunks/studio-f8tyeyzt.js +5 -0
- package/dist/chunks/studio-fj6c905s.js +5 -0
- package/dist/chunks/{studio-hsr3k06v.js → studio-fkrr7kgg.js} +5 -5
- package/dist/chunks/studio-fspe7m9t.js +5 -0
- package/dist/chunks/{studio-4zqfw5ha.js → studio-g0hxtcga.js} +4 -4
- package/dist/chunks/studio-g9brbewz.js +5 -0
- package/dist/chunks/studio-ggx3j7nd.js +5 -0
- package/dist/chunks/{studio-jh6t5qz4.js → studio-hfxttkyr.js} +4 -4
- package/dist/chunks/studio-hh394phe.js +5 -0
- package/dist/chunks/{studio-07k0geap.js → studio-j0zf5x2x.js} +4 -4
- package/dist/chunks/studio-jeb7hth3.js +5 -0
- package/dist/chunks/studio-k0xzrse2.js +64 -0
- package/dist/chunks/studio-k1xqrgm5.js +5 -0
- package/dist/chunks/studio-k2evngrj.js +7 -0
- package/dist/chunks/studio-k3we3kqb.js +5 -0
- package/dist/chunks/{studio-nf0pqpbj.js → studio-n9qba0gx.js} +4 -4
- package/dist/chunks/studio-nf8esxxc.js +5 -0
- package/dist/chunks/studio-nn4f9m9c.js +5 -0
- package/dist/chunks/studio-nskxe9q1.js +6 -0
- package/dist/chunks/{studio-4nkm4404.js → studio-nvcn2ykc.js} +4 -4
- package/dist/chunks/studio-nwynxqtb.js +5 -0
- package/dist/chunks/{studio-f2j9et3h.js → studio-nzemfbkk.js} +8 -8
- package/dist/chunks/studio-p2a03pgm.js +5 -0
- package/dist/chunks/{studio-skynbac3.js → studio-pm17wdc4.js} +4 -4
- package/dist/chunks/{studio-9cp96v90.js → studio-q80fg1d6.js} +7 -7
- package/dist/chunks/studio-r050sez0.js +6 -0
- package/dist/chunks/{studio-sd07xva5.js → studio-s7t4vp1d.js} +5 -5
- package/dist/chunks/studio-s9fng7m8.js +7 -0
- package/dist/chunks/studio-sce30r7b.js +4 -0
- package/dist/chunks/{studio-zxm98z2m.js → studio-stahswgb.js} +6 -6
- package/dist/chunks/studio-swedpd82.js +5 -0
- package/dist/chunks/studio-thz5t120.js +5 -0
- package/dist/chunks/studio-tpxcryf2.js +5 -0
- package/dist/chunks/{studio-tpy3rdxn.js → studio-v5wktj6f.js} +4 -4
- package/dist/chunks/{studio-7vb997ff.js → studio-vpevkfxw.js} +4 -4
- package/dist/chunks/studio-waekn290.js +5 -0
- package/dist/chunks/studio-wfct4h6n.js +5 -0
- package/dist/chunks/studio-wgc54sxf.js +5 -0
- package/dist/chunks/studio-wqfaqw4m.js +5 -0
- package/dist/chunks/studio-wse1rs8t.js +7 -0
- package/dist/chunks/studio-x0gsfr1d.js +16 -0
- package/dist/chunks/studio-xpx91fby.js +6 -0
- package/dist/chunks/studio-y1b86ast.js +5 -0
- package/dist/chunks/studio-yrcrncev.js +5 -0
- package/dist/chunks/{studio-zacvfm31.js → studio-yzpskb0j.js} +4 -4
- package/dist/chunks/studio-zfdbmhp3.js +5 -0
- package/dist/chunks/{tsMode-6vwhy6ty.js → tsMode-jg1dtphj.js} +7 -7
- package/dist/chunks/workspace-9btkc8tk.js +4 -0
- package/dist/chunks/workspace-home-qcc4z5ag.js +4 -0
- package/dist/chunks/{ws-client-zcxkfgmf.js → ws-client-arz2qsy9.js} +3 -3
- package/dist/iframe-entry.js +13 -13
- package/dist/manifest.json +83 -77
- package/dist/studio.js +74 -75
- package/package.json +5 -5
- package/src/browse/library-model.ts +56 -23
- package/src/browse/library-pane.ts +44 -29
- package/src/browse/library-preview.ts +6 -2
- package/src/canvas/asset-refs.ts +13 -4
- package/src/canvas/asset-resolve.ts +54 -11
- package/src/canvas/canvas-render.ts +25 -0
- package/src/canvas/iframe-entry.ts +5 -1
- package/src/canvas/iframe-host.ts +16 -6
- package/src/canvas/iframe-protocol.ts +9 -1
- package/src/commands/context.ts +6 -0
- package/src/commands/live-context.ts +5 -2
- package/src/editor/shortcuts.ts +6 -0
- package/src/files/asset-versions.ts +108 -2
- package/src/files/file-ops.ts +11 -1
- package/src/files/files.ts +111 -48
- package/src/files/media-paths.ts +12 -4
- package/src/files/media-upload.ts +195 -21
- package/src/files/new-file-name.ts +39 -1
- package/src/media/image-bake.ts +164 -0
- package/src/media/image-editor.ts +846 -0
- package/src/media/image-format.ts +262 -0
- package/src/media/image-recipe.ts +651 -0
- package/src/media/media-commands.ts +65 -1
- package/src/media/media-library-model.ts +1 -1
- package/src/media/media-library.ts +175 -15
- package/src/media/media-open.ts +156 -3
- package/src/media/media-pane.ts +8 -4
- package/src/panels/data-grid.ts +0 -4
- package/src/panels/pane-context.ts +6 -1
- package/src/panels/settings-menu.ts +3 -3
- package/src/panels/settings-pane.ts +42 -56
- package/src/panels/tab-strip.ts +12 -3
- package/src/services/ai-import-tools.ts +6 -3
- package/src/services/ai-models.ts +65 -11
- package/src/services/ai-settings.ts +45 -5
- package/src/services/document-assistant.ts +5 -2
- package/src/services/settings/definitions.ts +19 -0
- package/src/settings/contributed-section.ts +16 -7
- package/src/settings/css-vars-editor.ts +4 -4
- package/src/settings/general-settings.ts +1 -4
- package/src/settings/preferences-accounts.ts +2 -2
- package/src/settings/preferences-dialog.ts +4 -2
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/section-registry.ts +5 -4
- package/src/settings/settings-document.ts +33 -24
- package/src/settings/settings-workspace.ts +205 -0
- package/src/shell.ts +31 -6
- package/src/studio.ts +13 -2
- package/src/surfaces/ai-credentials-form.json +59 -5
- package/src/surfaces/ai-credentials-form.ts +15 -2
- package/src/surfaces/commandbar.ts +7 -3
- package/src/surfaces/image-editor.json +1390 -0
- package/src/surfaces/image-editor.ts +272 -0
- package/src/surfaces/media-library.json +129 -1
- package/src/surfaces/media-library.ts +17 -2
- package/src/surfaces/settings-contributed.json +4 -4
- package/src/surfaces/settings-contributed.ts +2 -2
- package/src/surfaces/settings-pane.json +262 -180
- package/src/surfaces/settings-pane.ts +63 -14
- package/src/types.ts +2 -1
- package/src/ui/ai-credentials-form.ts +128 -11
- package/src/ui/regions.ts +5 -5
- package/src/workspace/tab-workspace.ts +5 -3
- package/src/workspace/workspace-home.ts +18 -4
- package/src/workspace/workspace-ids.ts +40 -7
- package/src/workspace/workspace-switch.ts +3 -1
- package/src/workspace/workspace.ts +22 -1
- package/dist/chunks/adapter-xcpsmecx.js +0 -4
- package/dist/chunks/add-new-flow-ptmhmzr9.js +0 -4
- package/dist/chunks/cf-account-picker-z1sgwpwd.js +0 -4
- package/dist/chunks/cf-settings-xqvhxxe9.js +0 -4
- package/dist/chunks/components-whsc81a7.js +0 -4
- package/dist/chunks/content-source-jwtxg78w.js +0 -4
- package/dist/chunks/convert-to-repeater-f92ey3kp.js +0 -4
- package/dist/chunks/editor-zdqdpq1x.js +0 -4
- package/dist/chunks/entry-commands-w8p2fbpt.js +0 -4
- package/dist/chunks/extension-sections-y2p1te2r.js +0 -4
- package/dist/chunks/file-ops-13ab4swj.js +0 -4
- package/dist/chunks/files-zbc8p6v1.js +0 -4
- package/dist/chunks/format-host-zjsbktbx.js +0 -4
- package/dist/chunks/fs-events-t6x0hch6.js +0 -4
- package/dist/chunks/grid-open-fyzdwpkh.js +0 -4
- package/dist/chunks/icons-853n6qt3.js +0 -4
- package/dist/chunks/iframe-host-kbyqc7pt.js +0 -4
- package/dist/chunks/index-6nvj89vb.js +0 -4
- package/dist/chunks/jx-validate-5sp8a4rm.js +0 -4
- package/dist/chunks/layers-panel-qrxj9vr2.js +0 -4
- package/dist/chunks/layers-tpzayggx.js +0 -4
- package/dist/chunks/lit-html-x6nrxsx3.js +0 -4
- package/dist/chunks/media-library-ywppnjrz.js +0 -4
- package/dist/chunks/media-picker-etxgc8qq.js +0 -4
- package/dist/chunks/monaco-buffer-qrnqhk0b.js +0 -4
- package/dist/chunks/notify-kcv38wwe.js +0 -4
- package/dist/chunks/parse-df2kkmhc.js +0 -4
- package/dist/chunks/platform-dtsysmyd.js +0 -4
- package/dist/chunks/publish-panel-evb1rcxt.js +0 -4
- package/dist/chunks/publish-quick-m9vkhahq.js +0 -4
- package/dist/chunks/publish-workspace-ktk9h536.js +0 -4
- package/dist/chunks/quick-search-2f47fxcw.js +0 -4
- package/dist/chunks/references-5w6ajjv7.js +0 -4
- package/dist/chunks/right-panel-kz0a6byf.js +0 -4
- package/dist/chunks/source-control-1phx90zk.js +0 -4
- package/dist/chunks/studio-0hr000ba.js +0 -5
- package/dist/chunks/studio-1wyp7dt5.js +0 -5
- package/dist/chunks/studio-20ap8dds.js +0 -5
- package/dist/chunks/studio-291gqh98.js +0 -5
- package/dist/chunks/studio-37twdaf7.js +0 -64
- package/dist/chunks/studio-4smcnv33.js +0 -5
- package/dist/chunks/studio-56egy6vf.js +0 -5
- package/dist/chunks/studio-5dmgmyw4.js +0 -5
- package/dist/chunks/studio-5e7p1vgd.js +0 -5
- package/dist/chunks/studio-5m0w815d.js +0 -5
- package/dist/chunks/studio-695k95bw.js +0 -5
- package/dist/chunks/studio-6vwvshw8.js +0 -6
- package/dist/chunks/studio-732mw0g8.js +0 -5
- package/dist/chunks/studio-76t560kn.js +0 -6
- package/dist/chunks/studio-7823f0g8.js +0 -5
- package/dist/chunks/studio-8486jn4r.js +0 -5
- package/dist/chunks/studio-848rk4p1.js +0 -5
- package/dist/chunks/studio-8x8616xd.js +0 -5
- package/dist/chunks/studio-a3s6frde.js +0 -4
- package/dist/chunks/studio-ahf3cspq.js +0 -4
- package/dist/chunks/studio-bkmv1h3e.js +0 -9
- package/dist/chunks/studio-cgb97rwv.js +0 -5
- package/dist/chunks/studio-ch8gt8vt.js +0 -5
- package/dist/chunks/studio-cqf1k4qk.js +0 -5
- package/dist/chunks/studio-cvz0e00f.js +0 -5
- package/dist/chunks/studio-dbgv4fv9.js +0 -16
- package/dist/chunks/studio-eesyjg7h.js +0 -9
- package/dist/chunks/studio-et6t8g4m.js +0 -4
- package/dist/chunks/studio-fep7hr66.js +0 -7
- package/dist/chunks/studio-fyf7j57j.js +0 -5
- package/dist/chunks/studio-g5prntab.js +0 -5
- package/dist/chunks/studio-ga77mf07.js +0 -5
- package/dist/chunks/studio-h7gy12h2.js +0 -5
- package/dist/chunks/studio-j933k8nr.js +0 -5
- package/dist/chunks/studio-jgbvqcgh.js +0 -5
- package/dist/chunks/studio-k4xc5g6h.js +0 -5
- package/dist/chunks/studio-p0nf2e1f.js +0 -6
- package/dist/chunks/studio-pd9dsqpq.js +0 -5
- package/dist/chunks/studio-pmzg17fj.js +0 -5
- package/dist/chunks/studio-pzfa2vmb.js +0 -5
- package/dist/chunks/studio-qyb5bebs.js +0 -9
- package/dist/chunks/studio-rt498t2v.js +0 -5
- package/dist/chunks/studio-s0fg2wav.js +0 -5
- package/dist/chunks/studio-t3j8htp7.js +0 -7
- package/dist/chunks/studio-thj81e98.js +0 -7
- package/dist/chunks/studio-tyw7tk0x.js +0 -5
- package/dist/chunks/studio-vcz63n42.js +0 -5
- package/dist/chunks/studio-vffwe9k7.js +0 -5
- package/dist/chunks/studio-vjhej0w5.js +0 -928
- package/dist/chunks/studio-vxjap704.js +0 -5
- package/dist/chunks/studio-xebavr9s.js +0 -5
- package/dist/chunks/studio-yg5n49za.js +0 -5
- package/dist/chunks/studio-yhz5b313.js +0 -5
- package/dist/chunks/studio-zsjpsw08.js +0 -5
- package/dist/chunks/workspace-d65bz1qk.js +0 -4
- package/dist/chunks/workspace-home-vbg9b3jh.js +0 -4
- package/src/settings/settings-dialog.ts +0 -192
- package/src/surfaces/settings-dialog.json +0 -51
- package/src/surfaces/settings-dialog.ts +0 -169
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The Image editor surface: one image asset, edited where it is opened (studio.md §9.5).
|
|
4
|
+
*
|
|
5
|
+
* This is the adapter. `media/image-editor.ts` keeps the recipe, its undo stack, the decoded source
|
|
6
|
+
* and the one write door, and hands this module a flat projection: pre-formatted geometry strings,
|
|
7
|
+
* the values the fields show, and the words the `$switch`es read. The document renders that and
|
|
8
|
+
* decides nothing.
|
|
9
|
+
*
|
|
10
|
+
* **One island.** A drag converts screen pixels into the image's own frame, which needs the frame's
|
|
11
|
+
* drawn size, so the frame element is captured as it is created (`onNodeCreated`,
|
|
12
|
+
* studio-ui-guidelines.md §9.4) and the flow asks for its rect. The handles are captured the same
|
|
13
|
+
* way, so moving the roving tab stop to the next handle focuses an element this module was handed
|
|
14
|
+
* rather than one it searched for.
|
|
15
|
+
*
|
|
16
|
+
* **The container is CLEARED, because this is a pane and not a panel** — the reason
|
|
17
|
+
* `surfaces/media-pane.ts` gives: the canvas stage is handed to whichever mode owns it whole.
|
|
18
|
+
*
|
|
19
|
+
* @docs studio/projects/media
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
23
|
+
import { reactive } from "../reactivity";
|
|
24
|
+
import { mountSurface, registerSurface } from "../ui/surface";
|
|
25
|
+
import { rectOf } from "../utils/geometry";
|
|
26
|
+
import imageEditorDoc from "./image-editor.json";
|
|
27
|
+
import type { SurfaceHandle } from "../ui/surface";
|
|
28
|
+
import type { JxScope } from "@jxsuite/runtime/types";
|
|
29
|
+
import type { JxElement } from "@jxsuite/schema/types";
|
|
30
|
+
|
|
31
|
+
registerSurface("image-editor", imageEditorDoc);
|
|
32
|
+
|
|
33
|
+
/** One crop handle as the document draws it. */
|
|
34
|
+
export interface ImageHandleRow {
|
|
35
|
+
id: string;
|
|
36
|
+
/** Where it sits on screen, as a reader hears it. */
|
|
37
|
+
label: string;
|
|
38
|
+
/** `"0"` for the one handle in the tab order, `"-1"` for the other seven. */
|
|
39
|
+
tabindex: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Everything the document draws, as one value. */
|
|
43
|
+
export interface ImageEditorView {
|
|
44
|
+
region: string;
|
|
45
|
+
/** `loading` while the bytes are read, `refused` with the reason, `ready` with a picture. */
|
|
46
|
+
status: "loading" | "ready" | "refused";
|
|
47
|
+
/** What the loading or refused box says. */
|
|
48
|
+
message: string;
|
|
49
|
+
name: string;
|
|
50
|
+
alt: string;
|
|
51
|
+
/** A same-origin `blob:` URL for the bytes the editor holds. */
|
|
52
|
+
src: string;
|
|
53
|
+
/** The oriented aspect, width over height, as a number string. */
|
|
54
|
+
ratio: string;
|
|
55
|
+
/** The oriented width in CSS pixels, so the preview is never upscaled. */
|
|
56
|
+
maxWidth: string;
|
|
57
|
+
imageWidth: string;
|
|
58
|
+
imageHeight: string;
|
|
59
|
+
imageTransform: string;
|
|
60
|
+
/** The tone pass, the same string the bake sets on its context; `none` when neutral. */
|
|
61
|
+
filter: string;
|
|
62
|
+
cropX: string;
|
|
63
|
+
cropY: string;
|
|
64
|
+
cropW: string;
|
|
65
|
+
cropH: string;
|
|
66
|
+
handles: ImageHandleRow[];
|
|
67
|
+
handleHelpId: string;
|
|
68
|
+
/** The ratio the crop is held to, and the picker's rows. */
|
|
69
|
+
aspect: string;
|
|
70
|
+
aspectOptions: { label: string; value: string }[];
|
|
71
|
+
/** The crop area's cursor: `move`, or `default` when there is nowhere for it to go. */
|
|
72
|
+
moveCursor: string;
|
|
73
|
+
facts: string;
|
|
74
|
+
width: string;
|
|
75
|
+
maxOutputWidth: string;
|
|
76
|
+
fitLabel: string;
|
|
77
|
+
fitHint: string;
|
|
78
|
+
quality: "shown" | "hidden";
|
|
79
|
+
qualityValue: string;
|
|
80
|
+
brightness: string;
|
|
81
|
+
contrast: string;
|
|
82
|
+
saturation: string;
|
|
83
|
+
warning: string;
|
|
84
|
+
/** Disabled flags, each named for the state that disables. */
|
|
85
|
+
busy: boolean;
|
|
86
|
+
undecoded: boolean;
|
|
87
|
+
cannotUndo: boolean;
|
|
88
|
+
cannotRedo: boolean;
|
|
89
|
+
cannotFit: boolean;
|
|
90
|
+
clean: boolean;
|
|
91
|
+
cannotSave: boolean;
|
|
92
|
+
saving: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** What a control can ask the editor to do. Every one is a decision the flow owns. */
|
|
96
|
+
export interface ImageEditorActions {
|
|
97
|
+
imageLoaded: (width: number, height: number) => void;
|
|
98
|
+
imageFailed: (src: string) => void;
|
|
99
|
+
rotate: (direction: number) => void;
|
|
100
|
+
flip: (axis: string) => void;
|
|
101
|
+
undo: () => void;
|
|
102
|
+
redo: () => void;
|
|
103
|
+
reset: () => void;
|
|
104
|
+
save: () => void;
|
|
105
|
+
fieldEdited: () => void;
|
|
106
|
+
fitForWeb: () => void;
|
|
107
|
+
setWidth: (value: string) => void;
|
|
108
|
+
setAspect: (value: string) => void;
|
|
109
|
+
setValue: (key: string, value: string) => void;
|
|
110
|
+
handleDown: (
|
|
111
|
+
handle: string,
|
|
112
|
+
pointerId: number,
|
|
113
|
+
clientX: number,
|
|
114
|
+
clientY: number,
|
|
115
|
+
target: Element,
|
|
116
|
+
) => void;
|
|
117
|
+
handleMove: (pointerId: number, clientX: number, clientY: number) => void;
|
|
118
|
+
handleUp: (pointerId: number) => void;
|
|
119
|
+
handleFocused: (handle: string) => void;
|
|
120
|
+
nudge: (handle: string, dx: number, dy: number, large: boolean) => void;
|
|
121
|
+
cycleHandle: (handle: string, step: number) => void;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ImageEditorSurfaceHandle {
|
|
125
|
+
ready: Promise<HTMLElement>;
|
|
126
|
+
/** Whether what was mounted is still inside the host; true while the mount is in flight. */
|
|
127
|
+
attached: () => boolean;
|
|
128
|
+
update: (view: ImageEditorView) => void;
|
|
129
|
+
/** The drawn frame's rect, or null before it exists. */
|
|
130
|
+
frameRect: () => DOMRect | null;
|
|
131
|
+
/** Move focus to one handle, when it has been drawn. */
|
|
132
|
+
focusHandle: (handle: string) => void;
|
|
133
|
+
/** Commit a number still being typed, so a save writes what is on screen. Keeps the focus. */
|
|
134
|
+
flushFields: () => void;
|
|
135
|
+
/** Put the view's values back in the number fields, whatever was typed into them. */
|
|
136
|
+
syncFields: (view: ImageEditorView) => void;
|
|
137
|
+
dispose: () => void;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
type ImageEditorScope = ImageEditorView & ImageEditorActions;
|
|
141
|
+
|
|
142
|
+
/** Each number field's `part`, which is also the name of the view value it shows. */
|
|
143
|
+
const FIELD_VALUES = {
|
|
144
|
+
brightness: "brightness",
|
|
145
|
+
contrast: "contrast",
|
|
146
|
+
quality: "qualityValue",
|
|
147
|
+
saturation: "saturation",
|
|
148
|
+
width: "width",
|
|
149
|
+
} as const;
|
|
150
|
+
|
|
151
|
+
function isFieldPart(part: string): part is keyof typeof FIELD_VALUES {
|
|
152
|
+
return Object.hasOwn(FIELD_VALUES, part);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The `part` a definition declares, or `""`. Read off the DEFINITION, because a node is announced
|
|
157
|
+
* as it is created, before its attributes are applied.
|
|
158
|
+
*/
|
|
159
|
+
function partOf(def: JxElement | string): string {
|
|
160
|
+
const part = isString(def) ? undefined : def.attributes?.["part"];
|
|
161
|
+
return isString(part) ? part : "";
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** The handle a mapped row stands for, read off its `$map` item. */
|
|
165
|
+
function mappedHandle(state: JxScope | undefined): string | null {
|
|
166
|
+
const map = state?.["$map"];
|
|
167
|
+
const item = isNonNullObject(map) && "item" in map ? map.item : undefined;
|
|
168
|
+
return isNonNullObject(item) && "id" in item && isString(item.id) ? item.id : null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Write a projection into the scope. Each key is assigned through the reactive proxy, which
|
|
173
|
+
* notifies only when a value moved, so a drag that changes four crop strings redraws those four.
|
|
174
|
+
*/
|
|
175
|
+
function project(scope: ImageEditorScope, view: ImageEditorView): void {
|
|
176
|
+
Object.assign(scope, view);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Mount the Image editor document into `host`, wired to `actions`.
|
|
181
|
+
*
|
|
182
|
+
* @param {HTMLElement} host - The pane's canvas stage
|
|
183
|
+
* @param {ImageEditorView} view - What to draw right now
|
|
184
|
+
* @param {ImageEditorActions} actions - What each control does
|
|
185
|
+
* @returns {ImageEditorSurfaceHandle}
|
|
186
|
+
*/
|
|
187
|
+
export function mountImageEditorSurface(
|
|
188
|
+
host: HTMLElement,
|
|
189
|
+
view: ImageEditorView,
|
|
190
|
+
actions: ImageEditorActions,
|
|
191
|
+
): ImageEditorSurfaceHandle {
|
|
192
|
+
host.replaceChildren();
|
|
193
|
+
const scope = reactive<ImageEditorScope>({ ...view, ...actions });
|
|
194
|
+
|
|
195
|
+
let frame: Element | null = null;
|
|
196
|
+
const handles = new Map<string, HTMLElement>();
|
|
197
|
+
const fields = new Map<keyof typeof FIELD_VALUES, HTMLElement>();
|
|
198
|
+
let mounted: SurfaceHandle | null = null;
|
|
199
|
+
let disposed = false;
|
|
200
|
+
const ready = mountSurface("image-editor", scope, host, {
|
|
201
|
+
onNodeCreated: (element, _path, def, state) => {
|
|
202
|
+
// `disposed` first: nodes are still created while a mount that was taken down runs out.
|
|
203
|
+
if (disposed || !(element instanceof HTMLElement)) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const part = partOf(def);
|
|
207
|
+
if (part === "frame") {
|
|
208
|
+
frame = element;
|
|
209
|
+
} else if (part === "handle") {
|
|
210
|
+
const id = mappedHandle(state);
|
|
211
|
+
if (id !== null) {
|
|
212
|
+
handles.set(id, element);
|
|
213
|
+
}
|
|
214
|
+
} else if (isFieldPart(part)) {
|
|
215
|
+
fields.set(part, element);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
}).then((surface) => {
|
|
219
|
+
if (disposed) {
|
|
220
|
+
surface.dispose();
|
|
221
|
+
} else {
|
|
222
|
+
mounted = surface;
|
|
223
|
+
}
|
|
224
|
+
/* SAFETY: `image-editor.json`'s root definition is a `div` element, so the runtime mounts an
|
|
225
|
+
HTMLElement; a `Text` root only comes from a document whose root is a bare string. */
|
|
226
|
+
return surface.root as HTMLElement;
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
attached: () => {
|
|
231
|
+
if (disposed) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
const root = mounted?.root;
|
|
235
|
+
return root === undefined ? true : host.contains(root);
|
|
236
|
+
},
|
|
237
|
+
dispose() {
|
|
238
|
+
disposed = true;
|
|
239
|
+
mounted?.dispose();
|
|
240
|
+
mounted = null;
|
|
241
|
+
frame = null;
|
|
242
|
+
handles.clear();
|
|
243
|
+
fields.clear();
|
|
244
|
+
},
|
|
245
|
+
focusHandle: (handle) => {
|
|
246
|
+
const element = handles.get(handle);
|
|
247
|
+
if (element?.isConnected) {
|
|
248
|
+
element.focus();
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
frameRect: () => (frame?.isConnected ? rectOf(frame) : null),
|
|
252
|
+
flushFields: () => {
|
|
253
|
+
/* A number input commits on blur, which fires its change event synchronously, and the
|
|
254
|
+
document's handler then takes the value. Focused straight back, so the author's place is
|
|
255
|
+
not lost to a keystroke that only meant "save". */
|
|
256
|
+
const active = document.activeElement;
|
|
257
|
+
if (active instanceof HTMLInputElement && host.contains(active)) {
|
|
258
|
+
active.blur();
|
|
259
|
+
active.focus();
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
ready,
|
|
263
|
+
syncFields: (next) => {
|
|
264
|
+
for (const [part, element] of fields) {
|
|
265
|
+
if (element.isConnected && "value" in element) {
|
|
266
|
+
element.value = next[FIELD_VALUES[part]];
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
update: (next) => project(scope, next),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
3
|
"$id": "StudioMediaLibrary",
|
|
4
|
-
"$description": "The Media workspace's library (`specs/studio.md` §22.6): the project's media as filters, a grid and the selected file's detail. ONE document in two modes. In `manage` it is the Media home tab, with Replace, Open in viewer and Delete under the detail; in `pick` it is the full-size picker inside a `jx-dialog` (`media-pick-dialog.json`), and the dialog's own footer answers Cancel or Use <file>. `media/media-library.ts` keeps every decision (which files a filter keeps, the sort, what a count may claim, where an arrow lands, what Replace writes) and hands this document strings and discriminants. **Unused is drawn with no number until the usage sweep has settled**, and Missing alt text and tags are not drawn at all: each needs a store that does not exist, and a filter that cannot be answered is not shipped as one that always answers nothing.",
|
|
4
|
+
"$description": "The Media workspace's library (`specs/studio.md` §22.6): the project's media as filters, a grid and the selected file's detail. ONE document in two modes. In `manage` it is the Media home tab, with Replace, Open in viewer, Rename, Duplicate and Delete under the detail; in `pick` it is the full-size picker inside a `jx-dialog` (`media-pick-dialog.json`), and the dialog's own footer answers Cancel or Use <file>. `media/media-library.ts` keeps every decision (which files a filter keeps, the sort, what a count may claim, where an arrow lands, what Replace writes) and hands this document strings and discriminants. **Unused is drawn with no number until the usage sweep has settled**, and Missing alt text and tags are not drawn at all: each needs a store that does not exist, and a filter that cannot be answered is not shipped as one that always answers nothing.",
|
|
5
5
|
"tagName": "div",
|
|
6
6
|
"attributes": {
|
|
7
7
|
"part": "media-library",
|
|
@@ -1578,6 +1578,134 @@
|
|
|
1578
1578
|
}
|
|
1579
1579
|
]
|
|
1580
1580
|
},
|
|
1581
|
+
{
|
|
1582
|
+
"tagName": "div",
|
|
1583
|
+
"attributes": {
|
|
1584
|
+
"part": "edit-slot",
|
|
1585
|
+
"role": "none"
|
|
1586
|
+
},
|
|
1587
|
+
"style": {
|
|
1588
|
+
"display": "contents"
|
|
1589
|
+
},
|
|
1590
|
+
"$switch": {
|
|
1591
|
+
"$ref": "#/state/editable"
|
|
1592
|
+
},
|
|
1593
|
+
"cases": {
|
|
1594
|
+
"yes": {
|
|
1595
|
+
"tagName": "jx-button",
|
|
1596
|
+
"attributes": {
|
|
1597
|
+
"part": "edit-image"
|
|
1598
|
+
},
|
|
1599
|
+
"$props": {
|
|
1600
|
+
"size": "sm",
|
|
1601
|
+
"variant": "secondary"
|
|
1602
|
+
},
|
|
1603
|
+
"onclick": {
|
|
1604
|
+
"$prototype": "Function",
|
|
1605
|
+
"body": [
|
|
1606
|
+
{
|
|
1607
|
+
"operator": "call",
|
|
1608
|
+
"target": {
|
|
1609
|
+
"$ref": "#/state/editImage"
|
|
1610
|
+
},
|
|
1611
|
+
"value": []
|
|
1612
|
+
}
|
|
1613
|
+
],
|
|
1614
|
+
"description": "Withheld, not disabled, for a file the editor cannot write: a refused format is not offered rather than offered and then refused (studio.md §9.5)."
|
|
1615
|
+
},
|
|
1616
|
+
"children": [
|
|
1617
|
+
{
|
|
1618
|
+
"tagName": "span",
|
|
1619
|
+
"textContent": "Edit image"
|
|
1620
|
+
}
|
|
1621
|
+
]
|
|
1622
|
+
},
|
|
1623
|
+
"no": {
|
|
1624
|
+
"tagName": "span",
|
|
1625
|
+
"attributes": {
|
|
1626
|
+
"hidden": true
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
},
|
|
1631
|
+
{
|
|
1632
|
+
"tagName": "jx-button",
|
|
1633
|
+
"attributes": {
|
|
1634
|
+
"part": "rename"
|
|
1635
|
+
},
|
|
1636
|
+
"$props": {
|
|
1637
|
+
"size": "sm",
|
|
1638
|
+
"variant": "secondary"
|
|
1639
|
+
},
|
|
1640
|
+
"onclick": {
|
|
1641
|
+
"$prototype": "Function",
|
|
1642
|
+
"body": [
|
|
1643
|
+
{
|
|
1644
|
+
"operator": "call",
|
|
1645
|
+
"target": {
|
|
1646
|
+
"$ref": "#/state/rename"
|
|
1647
|
+
},
|
|
1648
|
+
"value": []
|
|
1649
|
+
}
|
|
1650
|
+
]
|
|
1651
|
+
},
|
|
1652
|
+
"children": [
|
|
1653
|
+
{
|
|
1654
|
+
"tagName": "span",
|
|
1655
|
+
"textContent": "Rename"
|
|
1656
|
+
}
|
|
1657
|
+
]
|
|
1658
|
+
},
|
|
1659
|
+
{
|
|
1660
|
+
"tagName": "div",
|
|
1661
|
+
"attributes": {
|
|
1662
|
+
"part": "duplicate-slot",
|
|
1663
|
+
"role": "none"
|
|
1664
|
+
},
|
|
1665
|
+
"style": {
|
|
1666
|
+
"display": "contents"
|
|
1667
|
+
},
|
|
1668
|
+
"$switch": {
|
|
1669
|
+
"$ref": "#/state/duplicable"
|
|
1670
|
+
},
|
|
1671
|
+
"cases": {
|
|
1672
|
+
"yes": {
|
|
1673
|
+
"tagName": "jx-button",
|
|
1674
|
+
"attributes": {
|
|
1675
|
+
"part": "duplicate"
|
|
1676
|
+
},
|
|
1677
|
+
"$props": {
|
|
1678
|
+
"size": "sm",
|
|
1679
|
+
"variant": "secondary"
|
|
1680
|
+
},
|
|
1681
|
+
"onclick": {
|
|
1682
|
+
"$prototype": "Function",
|
|
1683
|
+
"body": [
|
|
1684
|
+
{
|
|
1685
|
+
"operator": "call",
|
|
1686
|
+
"target": {
|
|
1687
|
+
"$ref": "#/state/duplicate"
|
|
1688
|
+
},
|
|
1689
|
+
"value": []
|
|
1690
|
+
}
|
|
1691
|
+
],
|
|
1692
|
+
"description": "Withheld, not disabled, on a backend that cannot read a file's raw bytes: a copy read as text would be a broken file (studio.md §9.3)."
|
|
1693
|
+
},
|
|
1694
|
+
"children": [
|
|
1695
|
+
{
|
|
1696
|
+
"tagName": "span",
|
|
1697
|
+
"textContent": "Duplicate"
|
|
1698
|
+
}
|
|
1699
|
+
]
|
|
1700
|
+
},
|
|
1701
|
+
"no": {
|
|
1702
|
+
"tagName": "span",
|
|
1703
|
+
"attributes": {
|
|
1704
|
+
"hidden": true
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
},
|
|
1581
1709
|
{
|
|
1582
1710
|
"tagName": "jx-button",
|
|
1583
1711
|
"attributes": {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* This is the adapter. `media/media-library.ts` is the flow: which files a filter keeps, in what
|
|
6
6
|
* order, what each count may claim, which tile is selected, where an arrow lands and what Replace,
|
|
7
|
-
* Delete and an upload write. It hands this module one projection, and this
|
|
8
|
-
* document a scope and reports the nodes the flow needs to hold.
|
|
7
|
+
* Rename, Duplicate, Delete and an upload write. It hands this module one projection, and this
|
|
8
|
+
* module hands the document a scope and reports the nodes the flow needs to hold.
|
|
9
9
|
*
|
|
10
10
|
* **Four islands, all through `onNodeCreated`.** The flow needs four nodes the document creates:
|
|
11
11
|
* each tile (watched for viewport entry, so a thumbnail is requested only when it is looked at, and
|
|
@@ -97,6 +97,13 @@ export interface MediaLibraryView {
|
|
|
97
97
|
previewSpecimen: string;
|
|
98
98
|
/** The Replace input's `accept`: the selected file's own format only. */
|
|
99
99
|
replaceAccept: string;
|
|
100
|
+
/**
|
|
101
|
+
* Whether the selected file opens in the Image editor (studio.md §9.5): withheld on exactly the
|
|
102
|
+
* conditions `media.edit` gates on, so the palette and this pane cannot give two answers.
|
|
103
|
+
*/
|
|
104
|
+
editable: "yes" | "no";
|
|
105
|
+
/** Whether the host can copy the selected file: `media.duplicate` gates on the same capability. */
|
|
106
|
+
duplicable: "yes" | "no";
|
|
100
107
|
usageState: "hidden" | "shown";
|
|
101
108
|
usageHeadline: string;
|
|
102
109
|
usageFiles: MediaUsageRow[];
|
|
@@ -126,7 +133,13 @@ export interface MediaLibraryActions {
|
|
|
126
133
|
openDocument: (path: string) => void;
|
|
127
134
|
replace: (input: HTMLInputElement) => void;
|
|
128
135
|
remove: () => void;
|
|
136
|
+
/** Rename the selected file, through the Rename dialog. */
|
|
137
|
+
rename: () => void;
|
|
138
|
+
/** Copy the selected file to a new name beside it, and select the copy. */
|
|
139
|
+
duplicate: () => void;
|
|
129
140
|
openViewer: () => void;
|
|
141
|
+
/** Open the selected image in its Image editor. */
|
|
142
|
+
editImage: () => void;
|
|
130
143
|
reset: () => void;
|
|
131
144
|
/** A tile node was created for `file`. */
|
|
132
145
|
tileHost: (element: HTMLElement, file: string) => void;
|
|
@@ -174,6 +187,8 @@ export function emptyMediaLibraryView(): MediaLibraryView {
|
|
|
174
187
|
query: "",
|
|
175
188
|
region: "",
|
|
176
189
|
replaceAccept: "",
|
|
190
|
+
editable: "no",
|
|
191
|
+
duplicable: "no",
|
|
177
192
|
selectedFile: "",
|
|
178
193
|
sort: "",
|
|
179
194
|
sortOptions: [],
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"marginBottom": "12px"
|
|
25
25
|
},
|
|
26
26
|
"& [part=\"columns\"]": {
|
|
27
|
-
"$description": "The 1px gap over the border colour is the divider between the two columns: two panels on `--bg
|
|
27
|
+
"$description": "The 1px gap over the border colour is the divider between the two columns: two panels on the page's own `--bg` with `--border` showing through the gap, so nothing draws a rule of its own. The panels are `--bg`, not `--bg-panel`, because the section is drawn on the Settings home, whose background is `--bg`: a second shade under one section of the form reads as a box nobody asked for.",
|
|
28
28
|
"display": "flex",
|
|
29
29
|
"height": "100%",
|
|
30
30
|
"gap": "1px",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"padding": "12px",
|
|
38
38
|
"width": "200px",
|
|
39
39
|
"minWidth": "200px",
|
|
40
|
-
"background": "var(--bg
|
|
40
|
+
"background": "var(--bg)",
|
|
41
41
|
"overflowY": "auto"
|
|
42
42
|
},
|
|
43
43
|
"& [part=\"entry\"], & [part=\"new-open\"]": {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"display": "flex",
|
|
63
63
|
"alignItems": "center",
|
|
64
64
|
"justifyContent": "center",
|
|
65
|
-
"background": "var(--bg
|
|
65
|
+
"background": "var(--bg)",
|
|
66
66
|
"color": "var(--fg-dim)",
|
|
67
67
|
"fontSize": "13px"
|
|
68
68
|
},
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"$description": "`min-width: 0` is the one line `.settings-editor-panel` did not have and needed: a flex child's floor is its content, and the schema form inside this one is a whole form rather than the short cards Data Shapes puts here — so a long pointer or a wide row pushed the column past the right edge of the pane instead of scrolling inside it.",
|
|
71
71
|
"flex": "1",
|
|
72
72
|
"padding": "16px",
|
|
73
|
-
"background": "var(--bg
|
|
73
|
+
"background": "var(--bg)",
|
|
74
74
|
"overflowY": "auto",
|
|
75
75
|
"minWidth": "0"
|
|
76
76
|
},
|
|
@@ -41,7 +41,7 @@ export interface ContributedEntryView {
|
|
|
41
41
|
/** The key in the section's map on disk — the row's identity and its `data-entry`. */
|
|
42
42
|
key: string;
|
|
43
43
|
selected: boolean;
|
|
44
|
-
/** `
|
|
44
|
+
/** `pane.<id>/settings/entry:<key>`, so a shot can name the row without a selector. */
|
|
45
45
|
region: string;
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -61,7 +61,7 @@ export interface ContributedView {
|
|
|
61
61
|
editorState: "empty" | "editing";
|
|
62
62
|
/** What the rename field holds — the key on disk, or what the reader has just typed. */
|
|
63
63
|
entryName: string;
|
|
64
|
-
/** `
|
|
64
|
+
/** `pane.<id>/settings/editor`. */
|
|
65
65
|
editorRegion: string;
|
|
66
66
|
/** The new-entry button: "New content type", or "New entry" when the section names none. */
|
|
67
67
|
newLabel: string;
|