efficient-easel 0.101.1 → 0.103.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 +51 -0
- package/dist/LinkPicker-W2Rtxetz.d.ts +111 -0
- package/dist/autosave/index.d.ts +6 -3
- package/dist/autosave/index.js +1 -1
- package/dist/chrome/index.d.ts +3 -2
- package/dist/chrome/index.js +1 -25
- package/dist/chunk-26OOWIJJ.js +1 -0
- package/dist/chunk-2LK54I4E.js +1 -0
- package/dist/chunk-3M3A3DN2.js +4 -0
- package/dist/chunk-3QVB4AG2.js +3 -0
- package/dist/chunk-3WSPDAK2.js +1 -0
- package/dist/chunk-4ES5JGGX.js +1 -0
- package/dist/chunk-4MXFKJUY.js +1 -0
- package/dist/chunk-57DJOKXT.js +1 -0
- package/dist/chunk-5MZ3RNQQ.js +13 -0
- package/dist/chunk-5ZBY24K7.js +1 -0
- package/dist/chunk-66ICOE3I.js +8 -0
- package/dist/chunk-6DJHRLCU.js +25 -0
- package/dist/chunk-6FY3PZS3.js +1 -0
- package/dist/chunk-6TZTKAB5.js +1 -0
- package/dist/chunk-6UJ3Y6FC.js +1 -0
- package/dist/chunk-6W7WLPZH.js +1 -0
- package/dist/chunk-7F52SZOI.js +2 -0
- package/dist/chunk-7MU3RJ6S.js +1 -0
- package/dist/chunk-A7ZJII7O.js +1 -0
- package/dist/chunk-AJBJ74ME.js +1 -0
- package/dist/chunk-AKFJK65Z.js +1 -0
- package/dist/chunk-AKZWUV5Z.js +1 -0
- package/dist/chunk-BDTITTMW.js +1 -0
- package/dist/chunk-BSPCSC45.js +1 -0
- package/dist/chunk-BXZ6WLHC.js +22 -0
- package/dist/chunk-DUVRZ456.js +1 -0
- package/dist/chunk-F6CCTEIX.js +1 -0
- package/dist/chunk-FGNR22NY.js +1 -0
- package/dist/chunk-FUDHI5I4.js +1 -0
- package/dist/chunk-GENAF3P6.js +1 -0
- package/dist/chunk-GOTN2KY4.js +2 -0
- package/dist/chunk-GXN65JMA.js +1 -0
- package/dist/chunk-GXQCZJOP.js +1 -0
- package/dist/chunk-GZO72N3Q.js +0 -0
- package/dist/chunk-HDKTR5TZ.js +62 -0
- package/dist/chunk-HMX55DYT.js +1 -0
- package/dist/chunk-HQ4VVRIC.js +1 -0
- package/dist/chunk-HWW4XJOH.js +1 -0
- package/dist/chunk-I54UCYOU.js +1 -0
- package/dist/chunk-IQ5TA7AM.js +1 -0
- package/dist/chunk-IWAPPEL4.js +6 -0
- package/dist/chunk-IYT6NN2J.js +1 -0
- package/dist/chunk-KCBEE2MC.js +2 -0
- package/dist/chunk-KDYIMJTZ.js +1 -0
- package/dist/chunk-KQMML6JM.js +4 -0
- package/dist/chunk-LG436UTD.js +1 -0
- package/dist/chunk-MSBF7IW3.js +2 -0
- package/dist/chunk-NBJ2YY6Y.js +4 -0
- package/dist/chunk-OM67AJQC.js +1 -0
- package/dist/chunk-OORDMLL4.js +5 -0
- package/dist/chunk-OYX47SL7.js +1 -0
- package/dist/chunk-P67FP7PG.js +9 -0
- package/dist/chunk-PWZOS45R.js +2 -0
- package/dist/chunk-Q2HPBMG5.js +1 -0
- package/dist/chunk-Q3SQBNJB.js +1 -0
- package/dist/chunk-R2HLPNQF.js +1 -0
- package/dist/chunk-R5L2E7JX.js +1 -0
- package/dist/chunk-R5ZVNJLJ.js +2 -0
- package/dist/chunk-RLBXE4EU.js +1 -0
- package/dist/chunk-RW4XBUUW.js +1 -0
- package/dist/chunk-SERF2FAU.js +1 -0
- package/dist/chunk-TTJ54QGG.js +18 -0
- package/dist/chunk-VV5ADNBR.js +1 -0
- package/dist/chunk-YJXEHK6I.js +2 -0
- package/dist/chunk-Z3KBLIEH.js +10 -0
- package/dist/chunk-ZE7I3PLX.js +1 -0
- package/dist/chunk-ZWK3CBRU.js +1 -0
- package/dist/chunk-ZZ7VLIHQ.js +1 -0
- package/dist/drag/index.d.ts +3 -41
- package/dist/drag/index.js +1 -18
- package/dist/easel/index.js +1 -9
- package/dist/{words-BMzV04b1.d.ts → engine-DBxp_v6B.d.ts} +1 -58
- package/dist/fields/index.d.ts +2 -109
- package/dist/fields/index.js +1 -22
- package/dist/gold/index.d.ts +4 -2
- package/dist/host-DJ8Gzsx7.d.ts +552 -0
- package/dist/menu/index.js +1 -1
- package/dist/node-ops/index.js +1 -1
- package/dist/panelWidths-D9hTLR25.d.ts +66 -0
- package/dist/screen/components/AddBlockRow.d.ts +14 -0
- package/dist/screen/components/AddBlockRow.js +1 -0
- package/dist/screen/components/AddChildRow.d.ts +39 -0
- package/dist/screen/components/AddChildRow.js +1 -0
- package/dist/screen/components/AddSidePanel.d.ts +54 -0
- package/dist/screen/components/AddSidePanel.js +1 -0
- package/dist/screen/components/MediaSidePanel.d.ts +47 -0
- package/dist/screen/components/MediaSidePanel.js +1 -0
- package/dist/screen/components/NodeContextMenu.d.ts +364 -0
- package/dist/screen/components/NodeContextMenu.js +1 -0
- package/dist/screen/components/PageEditGuardNotices.d.ts +5 -0
- package/dist/screen/components/PageEditGuardNotices.js +1 -0
- package/dist/screen/components/PanelToggleIcon.d.ts +14 -0
- package/dist/screen/components/PanelToggleIcon.js +1 -0
- package/dist/screen/components/PreviewDeviceContext.d.ts +28 -0
- package/dist/screen/components/PreviewDeviceContext.js +1 -0
- package/dist/screen/components/PreviewPartsContext.d.ts +33 -0
- package/dist/screen/components/PreviewPartsContext.js +1 -0
- package/dist/screen/components/ScreenChrome.d.ts +5 -0
- package/dist/screen/components/ScreenChrome.js +1 -0
- package/dist/screen/components/ScreenDocumentContext.d.ts +20 -0
- package/dist/screen/components/ScreenDocumentContext.js +1 -0
- package/dist/screen/components/ScreenMount.d.ts +76 -0
- package/dist/screen/components/ScreenMount.js +1 -0
- package/dist/screen/components/ScreenStoreProvider.d.ts +63 -0
- package/dist/screen/components/ScreenStoreProvider.js +1 -0
- package/dist/screen/components/SectionScreenShell.d.ts +5 -0
- package/dist/screen/components/SectionScreenShell.js +16 -0
- package/dist/screen/components/SidePanelHead.d.ts +81 -0
- package/dist/screen/components/SidePanelHead.js +1 -0
- package/dist/screen/components/SlotChildActionsContext.d.ts +41 -0
- package/dist/screen/components/SlotChildActionsContext.js +1 -0
- package/dist/screen/components/UiIcon.d.ts +52 -0
- package/dist/screen/components/UiIcon.js +1 -0
- package/dist/screen/components/panel-widths.d.ts +37 -0
- package/dist/screen/components/panel-widths.js +1 -0
- package/dist/screen/components/usePartBridge.d.ts +66 -0
- package/dist/screen/components/usePartBridge.js +1 -0
- package/dist/screen/index.d.ts +31 -0
- package/dist/screen/index.js +1 -0
- package/dist/screen/lib/admin-bridge.d.ts +105 -0
- package/dist/screen/lib/admin-bridge.js +1 -0
- package/dist/screen/lib/backend-error.d.ts +106 -0
- package/dist/screen/lib/backend-error.js +1 -0
- package/dist/screen/lib/chrome-theme.d.ts +21 -0
- package/dist/screen/lib/chrome-theme.js +1 -0
- package/dist/screen/lib/client-only.d.ts +24 -0
- package/dist/screen/lib/client-only.js +1 -0
- package/dist/screen/lib/content/view-tiers.d.ts +25 -0
- package/dist/screen/lib/content/view-tiers.js +1 -0
- package/dist/screen/lib/document-addressing.d.ts +20 -0
- package/dist/screen/lib/document-addressing.js +1 -0
- package/dist/screen/lib/document-contract.d.ts +237 -0
- package/dist/screen/lib/document-contract.js +1 -0
- package/dist/screen/lib/document-hooks.d.ts +71 -0
- package/dist/screen/lib/document-hooks.js +0 -0
- package/dist/screen/lib/document-switch.d.ts +74 -0
- package/dist/screen/lib/document-switch.js +1 -0
- package/dist/screen/lib/failure.d.ts +54 -0
- package/dist/screen/lib/failure.js +1 -0
- package/dist/screen/lib/host-chrome.d.ts +181 -0
- package/dist/screen/lib/host-chrome.js +1 -0
- package/dist/screen/lib/host-inbound.d.ts +20 -0
- package/dist/screen/lib/host-inbound.js +1 -0
- package/dist/screen/lib/host.d.ts +20 -0
- package/dist/screen/lib/host.js +1 -0
- package/dist/screen/lib/key-scope.d.ts +23 -0
- package/dist/screen/lib/key-scope.js +1 -0
- package/dist/screen/lib/links/link-filters.d.ts +41 -0
- package/dist/screen/lib/links/link-filters.js +0 -0
- package/dist/screen/lib/load-error.d.ts +29 -0
- package/dist/screen/lib/load-error.js +1 -0
- package/dist/screen/lib/media-panel.d.ts +94 -0
- package/dist/screen/lib/media-panel.js +1 -0
- package/dist/screen/lib/media-picker.d.ts +68 -0
- package/dist/screen/lib/media-picker.js +1 -0
- package/dist/screen/lib/page-lock.d.ts +5 -0
- package/dist/screen/lib/page-lock.js +1 -0
- package/dist/screen/lib/puck/add-target-types.d.ts +55 -0
- package/dist/screen/lib/puck/add-target-types.js +0 -0
- package/dist/screen/lib/puck/block-choice.d.ts +52 -0
- package/dist/screen/lib/puck/block-choice.js +1 -0
- package/dist/screen/lib/puck/block-types-in.d.ts +39 -0
- package/dist/screen/lib/puck/block-types-in.js +1 -0
- package/dist/screen/lib/puck/content-tree.d.ts +196 -0
- package/dist/screen/lib/puck/content-tree.js +1 -0
- package/dist/screen/lib/puck/device-fields.d.ts +128 -0
- package/dist/screen/lib/puck/device-fields.js +1 -0
- package/dist/screen/lib/puck/field-buckets.d.ts +22 -0
- package/dist/screen/lib/puck/field-buckets.js +1 -0
- package/dist/screen/lib/puck/field-markers.d.ts +205 -0
- package/dist/screen/lib/puck/field-markers.js +1 -0
- package/dist/screen/lib/puck/hidable.d.ts +44 -0
- package/dist/screen/lib/puck/hidable.js +1 -0
- package/dist/screen/lib/puck/palette-sections.d.ts +96 -0
- package/dist/screen/lib/puck/palette-sections.js +1 -0
- package/dist/screen/lib/puck/panel-fields.d.ts +47 -0
- package/dist/screen/lib/puck/panel-fields.js +1 -0
- package/dist/screen/lib/puck/panel-no-control-mark.d.ts +74 -0
- package/dist/screen/lib/puck/panel-no-control-mark.js +1 -0
- package/dist/screen/lib/puck/part-id.d.ts +23 -0
- package/dist/screen/lib/puck/part-id.js +1 -0
- package/dist/screen/lib/puck/preview-click.d.ts +49 -0
- package/dist/screen/lib/puck/preview-click.js +1 -0
- package/dist/screen/lib/puck/preview-dom.d.ts +8 -0
- package/dist/screen/lib/puck/preview-dom.js +1 -0
- package/dist/screen/lib/puck/preview-events.d.ts +25 -0
- package/dist/screen/lib/puck/preview-events.js +1 -0
- package/dist/screen/lib/puck/preview-selection-context.d.ts +72 -0
- package/dist/screen/lib/puck/preview-selection-context.js +1 -0
- package/dist/screen/lib/puck/section-doc.d.ts +20 -0
- package/dist/screen/lib/puck/section-doc.js +1 -0
- package/dist/screen/lib/puck/slot-child-name.d.ts +186 -0
- package/dist/screen/lib/puck/slot-child-name.js +1 -0
- package/dist/screen/lib/puck/slot-heal.d.ts +5 -0
- package/dist/screen/lib/puck/slot-heal.js +1 -0
- package/dist/screen/lib/puck/slot-section-spec.d.ts +96 -0
- package/dist/screen/lib/puck/slot-section-spec.js +0 -0
- package/dist/screen/lib/puck/style-clipboard.d.ts +78 -0
- package/dist/screen/lib/puck/style-clipboard.js +1 -0
- package/dist/screen/lib/puck/text-control-kinds.d.ts +71 -0
- package/dist/screen/lib/puck/text-control-kinds.js +1 -0
- package/dist/screen/lib/puck/tree-reveal.d.ts +62 -0
- package/dist/screen/lib/puck/tree-reveal.js +1 -0
- package/dist/screen/lib/puck/use-section-ops.d.ts +86 -0
- package/dist/screen/lib/puck/use-section-ops.js +1 -0
- package/dist/screen/lib/screen-parts.d.ts +748 -0
- package/dist/screen/lib/screen-parts.js +1 -0
- package/dist/screen/lib/section-template-types.d.ts +49 -0
- package/dist/screen/lib/section-template-types.js +0 -0
- package/dist/screen/lib/section-templates.d.ts +23 -0
- package/dist/screen/lib/section-templates.js +1 -0
- package/dist/screen/lib/session-context.d.ts +30 -0
- package/dist/screen/lib/session-context.js +1 -0
- package/dist/screen/lib/session.d.ts +255 -0
- package/dist/screen/lib/session.js +1 -0
- package/dist/screen/screen.css +1102 -0
- package/dist/screen/words.d.ts +42 -0
- package/dist/screen/words.js +1 -0
- package/dist/session-DSQFmIvx.d.ts +43 -0
- package/dist/strings/catalogue.d.ts +13 -4
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +5 -2
- package/dist/strings/index.js +1 -1
- package/dist/style-clipboard/index.js +1 -1
- package/dist/{types-DGcCsxs8.d.ts → types-CqY85foL.d.ts} +3 -65
- package/dist/words-D_Lnw1Gr.d.ts +59 -0
- package/package.json +348 -2
- package/dist/chunk-IG3U5NWJ.js +0 -1
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { RefObject, ReactNode } from 'react';
|
|
3
|
+
import { Data } from './blocks/index.js';
|
|
4
|
+
import { EaselDocumentAdapter, EaselCapabilities } from './screen/lib/document-contract.js';
|
|
5
|
+
import { SessionBackend, SessionBlocks } from './screen/lib/session.js';
|
|
6
|
+
import { SaveStatus } from './screen/lib/document-switch.js';
|
|
7
|
+
import { BridgedCapabilities } from './screen/lib/admin-bridge.js';
|
|
8
|
+
import { EditAccess, SaveConflict } from './edit-lock/index.js';
|
|
9
|
+
import { A as AutosaveSnapshot } from './engine-DBxp_v6B.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* lib/document-addressing.ts — HOW A DOCUMENT IS ADDRESSED: what the
|
|
13
|
+
* layer that knows its documents hands the provider that loads and saves them
|
|
14
|
+
* (doc/adr/0003, seam W5).
|
|
15
|
+
*
|
|
16
|
+
* The provider (components/ScreenDocumentContext) is the document's
|
|
17
|
+
* load-and-save: which one is open, its autosave, its edit lock, the switch
|
|
18
|
+
* from one to the next. Any editor has that. What it is told, and does not
|
|
19
|
+
* know: which document stands for "home", whether an editor may be LOADED on a
|
|
20
|
+
* target at all, what a switch of document does to the layer's own
|
|
21
|
+
* bookkeeping, what stores the document a target names, and what a stored
|
|
22
|
+
* layout needs before the canvas reads it. A website's answers are its Home
|
|
23
|
+
* page, its template entry and the page that keeps its footer, its two record
|
|
24
|
+
* types and its renamed props (lib/website-document-addressing).
|
|
25
|
+
*
|
|
26
|
+
* A PROP of the provider, and not one more of the screen's parts
|
|
27
|
+
* (lib/screen-parts): those reach the screen through the store's provider,
|
|
28
|
+
* and the document's provider stands above that one. And a module of its own
|
|
29
|
+
* for what it would otherwise load: lib/screen-parts carries the engine's
|
|
30
|
+
* canvas and inspector for its defaults, and the provider is imported by
|
|
31
|
+
* fields and panels that mount no screen.
|
|
32
|
+
*
|
|
33
|
+
* ONE object for the life of a mount, like the session. The provider lists
|
|
34
|
+
* these rules among the dependencies of what it memoises, the adapter first:
|
|
35
|
+
* rules built anew on a render would build a new adapter on it, and a new
|
|
36
|
+
* adapter opens the document again.
|
|
37
|
+
*
|
|
38
|
+
* FOR ONE KIND OF TARGET (0.103.0). A layer's rules answer for the targets it
|
|
39
|
+
* names: a website's for its pages and templates (`ScreenTarget`, the default,
|
|
40
|
+
* so the website's rules are typed as they always were), a host's own for its
|
|
41
|
+
* documents (`DocumentAddressing<DocumentTarget>`). The rules are asked about
|
|
42
|
+
* a target and never hand one of their own kind back, except where the editor
|
|
43
|
+
* goes instead of where it was loaded (`entryBounce`), which may be any.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
interface DocumentAddressing<T extends AnyScreenTarget = ScreenTarget> {
|
|
47
|
+
/**
|
|
48
|
+
* The slug of the HOME document: the one a target stands for when it names
|
|
49
|
+
* no document within its record, and the one an editor falls back to when
|
|
50
|
+
* the document it was pointed at has gone. Null when there is none: such a
|
|
51
|
+
* target then names the empty slug, and a document that has gone is
|
|
52
|
+
* reported and not replaced.
|
|
53
|
+
*/
|
|
54
|
+
homeSlug: string | null;
|
|
55
|
+
/**
|
|
56
|
+
* May an editor LOADED on `target` be sent somewhere else before it opens
|
|
57
|
+
* anything? Asked of the target a mount starts on, as it first renders:
|
|
58
|
+
* while the answer is yes the provider shows its "Loading…" and not the
|
|
59
|
+
* document, until `entryBounce` has said where the editor goes — or that it
|
|
60
|
+
* stays after all.
|
|
61
|
+
*/
|
|
62
|
+
entryMayBounce: (target: T) => boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Where an editor loaded on `target` goes INSTEAD: the target the host's
|
|
65
|
+
* address is then loaded on, or null and it stays. Asked once per mount, of
|
|
66
|
+
* the target it started on, with the query of the host's address. A switch
|
|
67
|
+
* made in place loads nothing, so it is never asked.
|
|
68
|
+
*/
|
|
69
|
+
entryBounce: (target: T, search: string) => AnyScreenTarget | null;
|
|
70
|
+
/**
|
|
71
|
+
* A switch of document, in place, is going ahead and `next` is where it
|
|
72
|
+
* goes: whatever the layer keeps of its own that depends on where the
|
|
73
|
+
* editor is, it brings up to date here. Called once per switch, after what
|
|
74
|
+
* belonged to the document being left has been cleared and before the
|
|
75
|
+
* provider moves to the new one.
|
|
76
|
+
*/
|
|
77
|
+
onSwitch: (next: T) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Is the host told that the editor moved to `next`? The host remembers the
|
|
80
|
+
* last target it was told, and reopens the editor there on a reload — so a
|
|
81
|
+
* target the editor must not be reopened on is one the host is not told.
|
|
82
|
+
*/
|
|
83
|
+
tellsHost: (next: T) => boolean;
|
|
84
|
+
/**
|
|
85
|
+
* What stores the document `target` names: its adapter, over the backend in
|
|
86
|
+
* force and the sets of blocks the host offers (both the session's, and the
|
|
87
|
+
* provider's to read). The provider asks again when the target moves to
|
|
88
|
+
* another record — not on every switch of document within one.
|
|
89
|
+
*
|
|
90
|
+
* The backend comes as the session holds it (lib/session
|
|
91
|
+
* `SessionBackend`): the layer that handed the session its backend knows its
|
|
92
|
+
* own type, and the provider names none.
|
|
93
|
+
*/
|
|
94
|
+
adapterFor: (target: T, backend: SessionBackend, blocks: SessionBlocks | null) => EaselDocumentAdapter;
|
|
95
|
+
/**
|
|
96
|
+
* Carry the stored answer of every prop the layer has RENAMED to its new
|
|
97
|
+
* key, in a layout as it was stored and before the canvas reads it. The
|
|
98
|
+
* canvas reads a node's props by the keys its fields declare, so an answer
|
|
99
|
+
* left under an old key would be shown as the default and then saved as it.
|
|
100
|
+
* Answers with the same object when it carried nothing.
|
|
101
|
+
*/
|
|
102
|
+
migrateRenamedProps: <D>(data: D) => D;
|
|
103
|
+
/**
|
|
104
|
+
* The sentence the editor shows for a document that is NOT THERE (the
|
|
105
|
+
* adapter resolved `target` to null, and there was no Home to fall back to):
|
|
106
|
+
* the layer's words for its own kind of document — "Couldn't open this
|
|
107
|
+
* campaign." Asked once, when it is found missing. Absent, the screen says
|
|
108
|
+
* its own (`EaselStrings.screen`: `missingPage`, `missingTemplatePage`,
|
|
109
|
+
* `missingDocument`), the website's sentences among them.
|
|
110
|
+
*/
|
|
111
|
+
describeMissing?: (target: T) => string;
|
|
112
|
+
/**
|
|
113
|
+
* The document `target` names did not open, and the editor shows why
|
|
114
|
+
* instead of it. `err` is what the load was refused with, or `null` when the
|
|
115
|
+
* backend said there is no such document (and there was no Home to fall back
|
|
116
|
+
* to). Called once per failed load, after the sentence is chosen — for a
|
|
117
|
+
* layer that has bookkeeping of its own to let go of (the campaign designer's
|
|
118
|
+
* window forgets the campaign it would reopen). Absent, nobody is told.
|
|
119
|
+
*/
|
|
120
|
+
onLoadFailed?: (target: T, err: unknown) => void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The rules a provider may be handed: a website's, for its pages and
|
|
124
|
+
* templates, or a host's own, for its documents. Whichever it is handed it
|
|
125
|
+
* asks of every target it opens, so a layer hands the rules of the kind of
|
|
126
|
+
* target it mounts the editor on.
|
|
127
|
+
*/
|
|
128
|
+
type AnyDocumentAddressing = DocumentAddressing<ScreenTarget> | DocumentAddressing<DocumentTarget>;
|
|
129
|
+
/**
|
|
130
|
+
* With no layer: there is no home, so nothing is fallen back to; an editor
|
|
131
|
+
* stays on whatever target it is loaded on; a switch of document has nothing
|
|
132
|
+
* of a layer's to bring up to date, and the host is told of every one; the
|
|
133
|
+
* document is the one nothing stores; and a stored layout is read as it was
|
|
134
|
+
* stored, there being no layer to have renamed a prop. It answers for every
|
|
135
|
+
* kind of target, so it stands in for the rules of either. It describes no
|
|
136
|
+
* missing document of its own (the screen says its words) and tells nobody of
|
|
137
|
+
* one that would not open.
|
|
138
|
+
*/
|
|
139
|
+
declare const NO_DOCUMENT_ADDRESSING: DocumentAddressing<AnyScreenTarget>;
|
|
140
|
+
|
|
141
|
+
type ScreenTarget = {
|
|
142
|
+
kind: "page";
|
|
143
|
+
slug: string;
|
|
144
|
+
siteId?: string;
|
|
145
|
+
originSlug?: string;
|
|
146
|
+
} | {
|
|
147
|
+
kind: "template";
|
|
148
|
+
id: string;
|
|
149
|
+
pageSlug?: string;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* A DOCUMENT OF A HOST'S OWN — not a website's page or template: what the
|
|
153
|
+
* campaign designer opens (0.103.0). `record` is the record that stores it (a
|
|
154
|
+
* campaign's id), and `slug` the document within that record (one of its
|
|
155
|
+
* variants), the empty slug when it names none.
|
|
156
|
+
*
|
|
157
|
+
* The provider asks no more of it than that. One record is one adapter (it
|
|
158
|
+
* re-keys on `record`, as a page target re-keys on its site); two of these are
|
|
159
|
+
* the same document when record and slug match; and a document that has gone
|
|
160
|
+
* is reported, never replaced by a Home, which is a website's.
|
|
161
|
+
*
|
|
162
|
+
* Beside `ScreenTarget` and not in it: that union is the website's two kinds,
|
|
163
|
+
* as its hosts name and build them (and as the storefront publishes them), and
|
|
164
|
+
* its host messages carry one. A host's own document reaches the host through
|
|
165
|
+
* its address (`EaselHostAddress.show`), and never as `navigated`.
|
|
166
|
+
*/
|
|
167
|
+
type DocumentTarget = {
|
|
168
|
+
kind: "document";
|
|
169
|
+
record: string;
|
|
170
|
+
slug?: string;
|
|
171
|
+
};
|
|
172
|
+
/** Every target the document's provider opens: a website's page or template
|
|
173
|
+
* (`ScreenTarget`), or a document of a host's own (`DocumentTarget`). */
|
|
174
|
+
type AnyScreenTarget = ScreenTarget | DocumentTarget;
|
|
175
|
+
|
|
176
|
+
type ScreenDocumentValue = {
|
|
177
|
+
/** The document the editor is currently pointed at (runtime, retargetable). */
|
|
178
|
+
target: AnyScreenTarget;
|
|
179
|
+
/** Record-type plumbing (load/save/list/create/delete) for the pointed-at
|
|
180
|
+
* document. Chrome and panels consult `capabilities`, never the record type. */
|
|
181
|
+
adapter: EaselDocumentAdapter;
|
|
182
|
+
/** What this document type supports — the ONLY sanctioned mode switch. */
|
|
183
|
+
capabilities: EaselCapabilities;
|
|
184
|
+
/** Id of the website template being edited (template mode only). */
|
|
185
|
+
templateId: string | null;
|
|
186
|
+
/** Slug of the page being edited — the template page's slug in template mode,
|
|
187
|
+
* and a host's own document's `slug` (or the empty slug) for one of those. */
|
|
188
|
+
currentSlug: string;
|
|
189
|
+
/** Kind of the loaded page (`dynamic` drives the product-binding controls), or
|
|
190
|
+
* null while loading / in template mode where the record carries no kind. */
|
|
191
|
+
currentKind: string | null;
|
|
192
|
+
/** Id of the website this page belongs to (page mode only; null in template
|
|
193
|
+
* mode or when the editor was opened without a site). The list/save paths and
|
|
194
|
+
* the page switcher scope to this so they act on one site's pages, not the
|
|
195
|
+
* whole tenant's. */
|
|
196
|
+
siteId: string | null;
|
|
197
|
+
/** Whether the editor's backend may be called yet. Under the EFFICIENT backend
|
|
198
|
+
* that is "the console's token has arrived"; an embedder's own backend
|
|
199
|
+
* authorises its calls itself and is ready from the first render. THE gate
|
|
200
|
+
* for anything that goes through the backend — never `token`, which an
|
|
201
|
+
* embedder's backend does not have. */
|
|
202
|
+
ready: boolean;
|
|
203
|
+
/** The bridged admin JWT once it arrives (null while waiting, and always null
|
|
204
|
+
* under an embedder's own backend). Only for the callers that still pass it
|
|
205
|
+
* to the EFFICIENT client themselves. */
|
|
206
|
+
token: string | null;
|
|
207
|
+
/** Latest token for imperative reads (custom fields, pickers, panels). */
|
|
208
|
+
tokenRef: RefObject<string | null>;
|
|
209
|
+
/** Bridge editor events to the embedding admin portal. */
|
|
210
|
+
notifyParent: SendToHost;
|
|
211
|
+
/** Operator capabilities the ADMIN CONSOLE granted over the origin-gated
|
|
212
|
+
* bridge. Distinct from `capabilities` above: those describe the DOCUMENT
|
|
213
|
+
* (can it publish, has it site settings), these describe the PERSON, and the
|
|
214
|
+
* editor is never allowed to infer them for itself. */
|
|
215
|
+
bridgeCapabilities: BridgedCapabilities;
|
|
216
|
+
/** Run an authed op; on 401 ask the parent for a fresh token and retry once. */
|
|
217
|
+
runAuthed: (op: (token: string) => Promise<unknown>) => Promise<boolean>;
|
|
218
|
+
/** Backend id of the loaded document — the identity of what the editor is
|
|
219
|
+
* editing right now. Null while loading and between retargets, so it also
|
|
220
|
+
* keys any once-per-document work (e.g. the pinned-chrome seed). */
|
|
221
|
+
docId: string | null;
|
|
222
|
+
/** The document exactly as it was LOADED from the backend: Puck's initial
|
|
223
|
+
* state, and the persisted snapshot a load-time seed must measure itself
|
|
224
|
+
* against. Null while loading. Edits live in Puck's own store, so this does
|
|
225
|
+
* NOT track them — it stays the last-loaded layout for the whole session. */
|
|
226
|
+
data: Data | null;
|
|
227
|
+
/** The freshest layout the merchant is actually viewing — the latest edit made
|
|
228
|
+
* since load (tracked on every onChange, even after the autosave settles), else
|
|
229
|
+
* the last-loaded `data`. Lets a feature snapshot the live view (e.g. the
|
|
230
|
+
* read-only origin backdrop in footer focus) without reaching into Puck's store.
|
|
231
|
+
* Lean accessor (ISP) — never exposes the ref. */
|
|
232
|
+
getLiveData: () => Data | null;
|
|
233
|
+
/** FOOTER FOCUS: the slug of the page the footer was opened from, or null. Rides
|
|
234
|
+
* the nav target, so it's atomic with the retarget (never stale). */
|
|
235
|
+
footerOriginSlug: string | null;
|
|
236
|
+
error: string | null;
|
|
237
|
+
/** True while the template-entry bounce is redirecting to the Home page. */
|
|
238
|
+
redirecting: boolean;
|
|
239
|
+
/** The pinned-seed gate's four words for where the autosave stands. */
|
|
240
|
+
saveStatus: SaveStatus;
|
|
241
|
+
/** The autosave's state (efficient-easel/autosave) — what the toolbar pill
|
|
242
|
+
* draws, through `saveIndicator`. */
|
|
243
|
+
saveState: AutosaveSnapshot;
|
|
244
|
+
/** Whether autosave is running. The toolbar pill is a switch: clicking it
|
|
245
|
+
* flips this. OFF = edits are HELD (kept in memory, still flushable by Publish
|
|
246
|
+
* / navigation / re-enabling) but never written on a timer. Session-scoped —
|
|
247
|
+
* survives in-place page switches. */
|
|
248
|
+
autoSaveEnabled: boolean;
|
|
249
|
+
/** Auto-save stopped because a save was REFUSED, not because the operator
|
|
250
|
+
* paused it — so a stopped auto-save can never read as a switch somebody
|
|
251
|
+
* flicked themselves. */
|
|
252
|
+
autoSaveStoppedByConflict: boolean;
|
|
253
|
+
/** True when an edit hasn't been persisted yet — including one held while the
|
|
254
|
+
* claim is in flight. Drives the guard that prompts before an in-place
|
|
255
|
+
* navigation would abandon held-but-unsaved edits. */
|
|
256
|
+
hasUnsavedEdits: boolean;
|
|
257
|
+
/** Flip autosave on/off. Turning it back ON writes any held edits at once, so
|
|
258
|
+
* "on" always means caught up. */
|
|
259
|
+
toggleAutoSave: () => void;
|
|
260
|
+
/** "Retry now": a failed save goes again at once instead of waiting out its
|
|
261
|
+
* backoff. */
|
|
262
|
+
retrySave: () => void;
|
|
263
|
+
/** Autosave — hand every Puck onChange to this. */
|
|
264
|
+
onChange: (next: Data) => void;
|
|
265
|
+
/** Persist the pending edit immediately; resolves to whether nothing is left
|
|
266
|
+
* unsaved. */
|
|
267
|
+
flushSave: () => Promise<boolean>;
|
|
268
|
+
/** Persist + publish the current document (Save for templates). */
|
|
269
|
+
onPublish: (next: Data) => Promise<void>;
|
|
270
|
+
/** Whether this editor may write the open page, and why not when it may not.
|
|
271
|
+
* `editing` is the only writable state; the gate is on the save path itself,
|
|
272
|
+
* so hiding or showing chrome from this can't be the thing that protects the
|
|
273
|
+
* document. Always `editing` in template mode (no lock there). */
|
|
274
|
+
access: EditAccess;
|
|
275
|
+
/** SOMEBODY ELSE holds this page, so this editor is read-only: it may look and
|
|
276
|
+
* select, but not move, add, duplicate or delete anything — until they take
|
|
277
|
+
* control themselves. The ONE answer the chrome asks; no panel re-derives it,
|
|
278
|
+
* so none of them can drift.
|
|
279
|
+
*
|
|
280
|
+
* NOT what protects the document — `persistLayout` refuses the write, and it
|
|
281
|
+
* refuses it in more cases than this (while the claim is still `checking`, and
|
|
282
|
+
* after a refused save). This is the narrower question the CHROME asks, and it
|
|
283
|
+
* is narrower on purpose: during `checking` nobody is named yet, and the
|
|
284
|
+
* pinned Header/Footer seed runs in the chrome's mount commit and must still
|
|
285
|
+
* land. Its write is held by `onChange` and released by the claim if it is
|
|
286
|
+
* granted, or never released if it is not — card 1096.
|
|
287
|
+
*
|
|
288
|
+
* …or the document itself is FROZEN (`readOnlyReason`): nobody holds it, and
|
|
289
|
+
* nobody may write it, ever. */
|
|
290
|
+
readOnly: boolean;
|
|
291
|
+
/** Why the open document may never be written, as the backend said it
|
|
292
|
+
* (`EaselDocument.readOnlyReason`: a campaign that has been sent), or null
|
|
293
|
+
* for every document that may. Such a document is read-only for good: its
|
|
294
|
+
* saves are refused, its lock is never claimed, and the save pill's place
|
|
295
|
+
* says this instead. Optional for a context built by hand, where it is
|
|
296
|
+
* absent and means null. */
|
|
297
|
+
readOnlyReason?: string | null;
|
|
298
|
+
/** Take the page: from the "someone else is editing" choice, or back after
|
|
299
|
+
* somebody took it from you. */
|
|
300
|
+
takeOverEditing: () => void;
|
|
301
|
+
/** Choose to look without touching (keeps the holder for the ribbon). */
|
|
302
|
+
viewReadOnly: () => void;
|
|
303
|
+
/** A save the backend REFUSED because the stored page moved on. Non-null means
|
|
304
|
+
* autosave has stopped and the operator's work is still only on their screen.
|
|
305
|
+
* Told in a bar under the top bar (efficient-easel/chrome `EditNotice`),
|
|
306
|
+
* never a dialog, so there is nothing to dismiss: the operator reads and
|
|
307
|
+
* copies from the screen it is warning them about. */
|
|
308
|
+
saveConflict: SaveConflict | null;
|
|
309
|
+
/** Abandon this editor's version and reload what is stored. The ONLY path that
|
|
310
|
+
* throws the operator's work away, and only they can ask for it. */
|
|
311
|
+
reloadFromServer: () => void;
|
|
312
|
+
/** Retarget the editor in place (guards unsaved changes before it swaps). */
|
|
313
|
+
navigate: (target: AnyScreenTarget) => void;
|
|
314
|
+
/** A retarget held behind the unsaved-changes prompt (null = no prompt). */
|
|
315
|
+
pendingNav: AnyScreenTarget | null;
|
|
316
|
+
cancelPendingNav: () => void;
|
|
317
|
+
discardAndNavigate: () => void;
|
|
318
|
+
saveAndNavigate: () => Promise<void>;
|
|
319
|
+
};
|
|
320
|
+
declare const ScreenDocumentContext: react.Context<ScreenDocumentValue | null>;
|
|
321
|
+
declare function useScreenDocument(): ScreenDocumentValue;
|
|
322
|
+
declare function ScreenDocumentProvider({ target, addressing: handed, onHostMessage, children, }: {
|
|
323
|
+
target: AnyScreenTarget;
|
|
324
|
+
/** How this editor's documents are ADDRESSED — the layer's rules, handed in
|
|
325
|
+
* by whoever mounts the provider (the website's entry hands the website's:
|
|
326
|
+
* lib/website-document-addressing). Without them there is one document that
|
|
327
|
+
* nothing stores. ONE object for the life of the mount, like the session. */
|
|
328
|
+
addressing?: AnyDocumentAddressing;
|
|
329
|
+
/** The layer's own host messages, asked before the ones every editor answers
|
|
330
|
+
* (lib/host-inbound): the website's are lib/website-host-inbound.
|
|
331
|
+
* Returns true when it handled one. */
|
|
332
|
+
onHostMessage?: (raw: unknown) => boolean;
|
|
333
|
+
children: ReactNode;
|
|
334
|
+
}): react.JSX.Element;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* The editor's HOST — whatever embeds the storefront editor, and the one way the
|
|
338
|
+
* editor talks to it.
|
|
339
|
+
*
|
|
340
|
+
* The editor asks its host for the things it cannot do itself (open the media
|
|
341
|
+
* picker, the form builder, a product's window; say that a save failed) and
|
|
342
|
+
* hears back from it (the admin token, a category that was edited elsewhere, a
|
|
343
|
+
* retarget to another page). It used to be the shop's own `/edit/*` route,
|
|
344
|
+
* framed by the admin portal in a cross-origin iframe, and every one of those
|
|
345
|
+
* calls was a `postMessage` to `window.parent`. The admin portal now mounts the
|
|
346
|
+
* editor in its own window (the `efficient-web-builder` package) and builds its host
|
|
347
|
+
* with {@link createEaselHost}: the same `storefront-editor:*` messages, as
|
|
348
|
+
* function calls — no origin, no serialisation, no handshake race. Surfaces
|
|
349
|
+
* still read inbound messages defensively; the protocol kept its shape.
|
|
350
|
+
*
|
|
351
|
+
* A surface with no provider above it (a dev harness, a guard rendering one
|
|
352
|
+
* panel) gets {@link DETACHED_EASEL_HOST}: nobody listening, nothing sent — a
|
|
353
|
+
* request that needs an answer settles empty instead of waiting forever.
|
|
354
|
+
*/
|
|
355
|
+
/** A picked media item, as the host's media picker returns it. */
|
|
356
|
+
interface HostPickedMedia {
|
|
357
|
+
id: string;
|
|
358
|
+
url: string;
|
|
359
|
+
kind: "image" | "video";
|
|
360
|
+
}
|
|
361
|
+
/** The SECTION editor's target (the standalone one-section surface). */
|
|
362
|
+
type SectionScreenTarget = {
|
|
363
|
+
kind: "section";
|
|
364
|
+
id: string;
|
|
365
|
+
type?: string;
|
|
366
|
+
name?: string;
|
|
367
|
+
};
|
|
368
|
+
/** Every message the editor sends its host, by name. */
|
|
369
|
+
type EaselToHostMessage =
|
|
370
|
+
/** The editor is listening; send (or re-send) `auth`. Repeats until a token lands. */
|
|
371
|
+
{
|
|
372
|
+
type: "storefront-editor:ready";
|
|
373
|
+
}
|
|
374
|
+
/** A call was refused 401; refresh the token and send `auth` again. */
|
|
375
|
+
| {
|
|
376
|
+
type: "storefront-editor:auth-expired";
|
|
377
|
+
}
|
|
378
|
+
/** The document changed in the editor (every edit). */
|
|
379
|
+
| {
|
|
380
|
+
type: "storefront-editor:dirty";
|
|
381
|
+
}
|
|
382
|
+
/** An explicit Save landed (autosaves stay quiet). */
|
|
383
|
+
| {
|
|
384
|
+
type: "storefront-editor:saved";
|
|
385
|
+
}
|
|
386
|
+
/** The page was published. */
|
|
387
|
+
| {
|
|
388
|
+
type: "storefront-editor:published";
|
|
389
|
+
}
|
|
390
|
+
/** A save failed (first failure of a retry run only). */
|
|
391
|
+
| {
|
|
392
|
+
type: "storefront-editor:save-failed";
|
|
393
|
+
}
|
|
394
|
+
/** The editor moved in place to another page (page targets only). */
|
|
395
|
+
| {
|
|
396
|
+
type: "storefront-editor:navigated";
|
|
397
|
+
target: ScreenTarget;
|
|
398
|
+
}
|
|
399
|
+
/** Open the media picker; answer `media-picked` / `media-pick-cancelled` with the same id. */
|
|
400
|
+
| {
|
|
401
|
+
type: "storefront-editor:open-media-picker";
|
|
402
|
+
requestId: string;
|
|
403
|
+
accept: string;
|
|
404
|
+
title: string;
|
|
405
|
+
file?: File;
|
|
406
|
+
}
|
|
407
|
+
/** A form. `mode: "create"` asks for a new one and carries a `requestId`:
|
|
408
|
+
* answer `form-saved` / `form-closed` with the same id. `mode: "edit"` opens
|
|
409
|
+
* the form builder on `formId` and carries none: nothing waits on it. */
|
|
410
|
+
| {
|
|
411
|
+
type: "storefront-editor:open-form";
|
|
412
|
+
requestId?: string;
|
|
413
|
+
mode: "create" | "edit";
|
|
414
|
+
formId?: string;
|
|
415
|
+
} | {
|
|
416
|
+
type: "storefront-editor:open-category";
|
|
417
|
+
categoryId: string;
|
|
418
|
+
name?: string;
|
|
419
|
+
} | {
|
|
420
|
+
type: "storefront-editor:open-product";
|
|
421
|
+
slug: string;
|
|
422
|
+
name?: string;
|
|
423
|
+
} | {
|
|
424
|
+
type: "storefront-editor:open-post";
|
|
425
|
+
slug: string;
|
|
426
|
+
title?: string;
|
|
427
|
+
} | {
|
|
428
|
+
type: "storefront-editor:open-menus";
|
|
429
|
+
menuId?: string | null;
|
|
430
|
+
} | {
|
|
431
|
+
type: "storefront-editor:open-page";
|
|
432
|
+
slug: string;
|
|
433
|
+
} | {
|
|
434
|
+
type: "storefront-editor:new-page";
|
|
435
|
+
}
|
|
436
|
+
/** Ask the host to save this website as a platform template (it decides). */
|
|
437
|
+
| {
|
|
438
|
+
type: "storefront-editor:save-as-template";
|
|
439
|
+
siteId: string;
|
|
440
|
+
slug: string;
|
|
441
|
+
};
|
|
442
|
+
/** Every message a host sends the editor, by name. */
|
|
443
|
+
type HostToEaselMessage = {
|
|
444
|
+
type: "storefront-editor:auth";
|
|
445
|
+
token: string;
|
|
446
|
+
siteId?: string;
|
|
447
|
+
brandId?: string;
|
|
448
|
+
theme?: string;
|
|
449
|
+
can?: {
|
|
450
|
+
canCreatePlatformTemplate?: boolean;
|
|
451
|
+
};
|
|
452
|
+
} | {
|
|
453
|
+
type: "storefront-editor:navigate";
|
|
454
|
+
target: ScreenTarget | SectionScreenTarget;
|
|
455
|
+
} | {
|
|
456
|
+
type: "storefront-editor:category-updated";
|
|
457
|
+
categoryId?: string;
|
|
458
|
+
} | {
|
|
459
|
+
type: "storefront-editor:menus-updated";
|
|
460
|
+
} | {
|
|
461
|
+
type: "storefront-editor:form-saved";
|
|
462
|
+
requestId?: string;
|
|
463
|
+
form?: {
|
|
464
|
+
id: string;
|
|
465
|
+
slug: string;
|
|
466
|
+
};
|
|
467
|
+
} | {
|
|
468
|
+
type: "storefront-editor:form-closed";
|
|
469
|
+
requestId?: string;
|
|
470
|
+
} | {
|
|
471
|
+
type: "storefront-editor:media-picked";
|
|
472
|
+
requestId: string;
|
|
473
|
+
media: HostPickedMedia;
|
|
474
|
+
} | {
|
|
475
|
+
type: "storefront-editor:media-pick-cancelled";
|
|
476
|
+
requestId: string;
|
|
477
|
+
};
|
|
478
|
+
type EaselMessageType = EaselToHostMessage["type"];
|
|
479
|
+
type PayloadOf<T extends EaselMessageType> = Omit<Extract<EaselToHostMessage, {
|
|
480
|
+
type: T;
|
|
481
|
+
}>, "type">;
|
|
482
|
+
/** Send one message to the host — `send("storefront-editor:open-page", { slug })`.
|
|
483
|
+
* The payload is required exactly when the message carries one. */
|
|
484
|
+
type SendToHost = <T extends EaselMessageType>(type: T, ...payload: Record<string, never> extends PayloadOf<T> ? [PayloadOf<T>?] : [PayloadOf<T>]) => void;
|
|
485
|
+
/** What reaches a surface's listener: a named message whose fields the surface
|
|
486
|
+
* reads defensively (over the iframe transport it is untrusted data). */
|
|
487
|
+
type InboundHostMessage = {
|
|
488
|
+
type: string;
|
|
489
|
+
} & Record<string, unknown>;
|
|
490
|
+
/**
|
|
491
|
+
* The editor's address. An iframe editor IS a document with a URL — a refresh
|
|
492
|
+
* must reopen the page being edited, so the address follows it. An editor
|
|
493
|
+
* mounted inside another app has no address of its own; that app keeps its own
|
|
494
|
+
* notion of "where" (it hears `navigated`) and implements these as retargets.
|
|
495
|
+
*/
|
|
496
|
+
interface EaselHostAddress {
|
|
497
|
+
/** The query the editor was opened with (`?editTemplate=1`, `?site=` …). */
|
|
498
|
+
search(): string;
|
|
499
|
+
/** Keep the address in step with the open document (no load). A host's own
|
|
500
|
+
* document (`DocumentTarget`, 0.103.0) is told here and only here: the
|
|
501
|
+
* `navigated` message carries a website's targets. */
|
|
502
|
+
show(target: ScreenTarget | SectionScreenTarget | DocumentTarget): void;
|
|
503
|
+
/** Leave for another document by LOADING it (an entry bounce, a deleted page). */
|
|
504
|
+
load(target: ScreenTarget | DocumentTarget): void;
|
|
505
|
+
/** Reload the editor from scratch (abandon this tab's copy of the document). */
|
|
506
|
+
reload(): void;
|
|
507
|
+
}
|
|
508
|
+
interface EaselHost {
|
|
509
|
+
/** Whether anything is listening. False on a bare `/edit` page no admin embeds. */
|
|
510
|
+
readonly connected: boolean;
|
|
511
|
+
/**
|
|
512
|
+
* Whether the editor IS the page — the shop's `/edit` routes, where nothing
|
|
513
|
+
* else shares the document, so page-wide shortcuts (undo, copy style) listen
|
|
514
|
+
* on `document` and the editor may stamp `<html>`. False for an embedder that
|
|
515
|
+
* mounts the editor inside its own page: there a key belongs to the editor
|
|
516
|
+
* only while focus is inside it, and the page's `<html>` is not the editor's.
|
|
517
|
+
*/
|
|
518
|
+
readonly ownsDocument: boolean;
|
|
519
|
+
send: SendToHost;
|
|
520
|
+
/** Listen to the host. Returns the unsubscribe. */
|
|
521
|
+
subscribe(listener: (message: InboundHostMessage) => void): () => void;
|
|
522
|
+
readonly address: EaselHostAddress;
|
|
523
|
+
}
|
|
524
|
+
/** The host of a surface nobody embeds: nothing sent, nothing heard, an address
|
|
525
|
+
* that stays put. */
|
|
526
|
+
declare const DETACHED_EASEL_HOST: EaselHost;
|
|
527
|
+
declare const EaselHostContext: react.Context<EaselHost>;
|
|
528
|
+
declare function EaselHostProvider({ host, children }: {
|
|
529
|
+
host: EaselHost;
|
|
530
|
+
children: ReactNode;
|
|
531
|
+
}): react.JSX.Element;
|
|
532
|
+
/** The host of the editor this component renders in. */
|
|
533
|
+
declare function useEaselHost(): EaselHost;
|
|
534
|
+
/**
|
|
535
|
+
* A host for an embedder that mounts the editor in its own page — the admin
|
|
536
|
+
* portal's native editor window. `onMessage` receives everything the editor
|
|
537
|
+
* sends (typed); the returned `deliver` hands a message to the editor, exactly
|
|
538
|
+
* as a trusted postMessage would have arrived.
|
|
539
|
+
*
|
|
540
|
+
* One per mounted editor: a host carries one editor's conversation, so two
|
|
541
|
+
* editors open at once (a page and a section) each get their own and a retarget
|
|
542
|
+
* meant for one never reaches the other.
|
|
543
|
+
*/
|
|
544
|
+
declare function createEaselHost(options: {
|
|
545
|
+
onMessage: (message: EaselToHostMessage) => void;
|
|
546
|
+
address: EaselHostAddress;
|
|
547
|
+
}): {
|
|
548
|
+
host: EaselHost;
|
|
549
|
+
deliver: (message: HostToEaselMessage) => void;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
export { type AnyDocumentAddressing as A, DETACHED_EASEL_HOST as D, type EaselHost as E, type HostPickedMedia as H, type InboundHostMessage as I, NO_DOCUMENT_ADDRESSING as N, type SectionScreenTarget as S, type DocumentAddressing as a, type EaselHostAddress as b, EaselHostContext as c, EaselHostProvider as d, type EaselMessageType as e, type EaselToHostMessage as f, type HostToEaselMessage as g, type SendToHost as h, createEaselHost as i, type AnyScreenTarget as j, type DocumentTarget as k, ScreenDocumentContext as l, ScreenDocumentProvider as m, type ScreenDocumentValue as n, type ScreenTarget as o, useScreenDocument as p, useEaselHost as u };
|
package/dist/menu/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{menuPortalTarget}from"../chunk-RW4XBUUW.js";export{ES_MENU_SKIN,EaselContextMenu}from"../chunk-KTVH2ZRL.js";
|
package/dist/node-ops/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export{createNodeClipboard,nodeMenuItems}from"../chunk-2LK54I4E.js";import"../chunk-WK3AFPXY.js";export{canStep,fromItemSelector,parentStep,planDuplicate,planMove,planPaste,planRemove,planSetProps,planStep,toItemSelector,useNodeOps}from"../chunk-D2BCHTQR.js";import"../chunk-L5KW4HG5.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The side-panel widths every editor opens on and drags between (px).
|
|
5
|
+
*
|
|
6
|
+
* Lifted from `efficient-storefront/components/panel-widths.ts`, where the website
|
|
7
|
+
* editor measured them:
|
|
8
|
+
*
|
|
9
|
+
* RIGHT is 320, not 308 (card 8810). At 308 the settings tab strip was left
|
|
10
|
+
* 269px once the inspector's 14px sides and its 11px scrollbar were off it —
|
|
11
|
+
* one pixel under the 270 the strip's widest tier needs, so the tab words
|
|
12
|
+
* turned into glyphs at the width every merchant opens on.
|
|
13
|
+
*
|
|
14
|
+
* MIN_PANEL_W is load-bearing on the top bar: six 34px rail buttons are 204px,
|
|
15
|
+
* and at 220 the rail column spreads them with nothing to spare.
|
|
16
|
+
*
|
|
17
|
+
* The campaign designer opened at 288 / 288 with a 520 ceiling until the
|
|
18
|
+
* 2026-09-17 redesign. One set of numbers now, here.
|
|
19
|
+
*/
|
|
20
|
+
declare const DEFAULT_PANEL_W: {
|
|
21
|
+
readonly left: 288;
|
|
22
|
+
readonly right: 320;
|
|
23
|
+
};
|
|
24
|
+
declare const MIN_PANEL_W = 220;
|
|
25
|
+
declare const MAX_PANEL_W = 560;
|
|
26
|
+
/** Which side panel a width belongs to. */
|
|
27
|
+
type PanelSide = 'left' | 'right';
|
|
28
|
+
type PanelWidths = {
|
|
29
|
+
left: number;
|
|
30
|
+
right: number;
|
|
31
|
+
};
|
|
32
|
+
/** Clamp a width into the panel band and round to a whole pixel. */
|
|
33
|
+
declare function clampPanelWidth(width: number): number;
|
|
34
|
+
/**
|
|
35
|
+
* The inline style that carries the widths, as `--es-left-w` / `--es-right-w`.
|
|
36
|
+
*
|
|
37
|
+
* ⚠️ PUT IT ON THE EDITOR ROOT, the nearest ancestor of EVERYTHING that reads
|
|
38
|
+
* it. The website editor learned this on 2026-09-04: the vars sat on the panel
|
|
39
|
+
* row, the top bar is that row's SIBLING, and the rail column read a width with
|
|
40
|
+
* no declaration in scope — which is not an error, it silently falls back to
|
|
41
|
+
* `auto` and the column shrinks to its buttons. (Since 2026-10-06 chrome.css
|
|
42
|
+
* falls back to `DEFAULT_PANEL_W` instead: the column keeps its width and
|
|
43
|
+
* simply stops following the grip.)
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ A SERVER RENDERS THIS AS A `style=""` ATTRIBUTE, and a
|
|
46
|
+
* Content-Security-Policy without `'unsafe-inline'` for styles refuses those.
|
|
47
|
+
* A client render is not affected: React writes a `style` prop through the
|
|
48
|
+
* CSSOM. A server-rendered editor under such a policy uses
|
|
49
|
+
* {@link setPanelWidthVars} instead.
|
|
50
|
+
*/
|
|
51
|
+
declare function panelWidthVars(widths: PanelWidths): CSSProperties;
|
|
52
|
+
/**
|
|
53
|
+
* The same two variables, written onto the editor root through the CSSOM
|
|
54
|
+
* (second host, 2026-10-06) — so the server's HTML carries no `style` attribute for a strict
|
|
55
|
+
* Content-Security-Policy to refuse:
|
|
56
|
+
*
|
|
57
|
+
* <div className="es-editor" ref={(el) => { if (el) setPanelWidthVars(el, widths); }}>
|
|
58
|
+
*
|
|
59
|
+
* A ref runs on the client only, before the browser paints, and again on each
|
|
60
|
+
* render — so it follows the widths as a grip is dragged. Until it runs (the
|
|
61
|
+
* server's HTML, before hydration) chrome.css draws the panels at
|
|
62
|
+
* `DEFAULT_PANEL_W`. Touches nothing but the element it is handed.
|
|
63
|
+
*/
|
|
64
|
+
declare function setPanelWidthVars(el: HTMLElement, widths: PanelWidths): void;
|
|
65
|
+
|
|
66
|
+
export { DEFAULT_PANEL_W as D, MAX_PANEL_W as M, type PanelSide as P, MIN_PANEL_W as a, type PanelWidths as b, clampPanelWidth as c, panelWidthVars as p, setPanelWidthVars as s };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { BlockChoice } from '../lib/puck/block-choice.js';
|
|
3
|
+
|
|
4
|
+
declare function AddBlockRow({ choices, onPick, open, onToggle, }: {
|
|
5
|
+
/** The block types this slot accepts, from `canAddTo(parentType)?.choices`. */
|
|
6
|
+
choices: BlockChoice[];
|
|
7
|
+
/** Insert the chosen type. The caller knows the zone and the index. */
|
|
8
|
+
onPick: (type: string) => void;
|
|
9
|
+
/** Host-owned open state — omitted where the caller draws only one row. */
|
|
10
|
+
open?: boolean;
|
|
11
|
+
onToggle?: () => void;
|
|
12
|
+
}): react.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { AddBlockRow as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{AddBlockRow as default}from"../../chunk-66ICOE3I.js";import"../../chunk-HQ4VVRIC.js";import"../../chunk-NBJ2YY6Y.js";import"../../chunk-P67FP7PG.js";import"../../chunk-AELNNAFM.js";import"../../chunk-BXZ6WLHC.js";import"../../chunk-EOJNJCMJ.js";import"../../chunk-ZFDCDJNZ.js";import"../../chunk-ZNS7727Y.js";import"../../chunk-3EDSDPIP.js";import"../../chunk-QTLAVDJE.js";import"../../chunk-YRLPFZW3.js";import"../../chunk-KTVH2ZRL.js";import"../../chunk-D2BCHTQR.js";import"../../chunk-EWVJSRRY.js";import"../../chunk-P6O363EE.js";import"../../chunk-FPOKPNO4.js";import"../../chunk-MFIRYGHW.js";import"../../chunk-BZ5ASXOL.js";import"../../chunk-67GNT6PF.js";import"../../chunk-ZNCEOSXO.js";import"../../chunk-L5KW4HG5.js";import"../../chunk-KRXQM65X.js";import"../../chunk-NKB3KVAB.js";
|