efficient-easel 0.101.0 → 0.102.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.
Files changed (232) hide show
  1. package/README.md +37 -0
  2. package/dist/LinkPicker-W2Rtxetz.d.ts +111 -0
  3. package/dist/autosave/index.d.ts +6 -3
  4. package/dist/autosave/index.js +1 -1
  5. package/dist/chrome/index.d.ts +3 -2
  6. package/dist/chrome/index.js +1 -25
  7. package/dist/chunk-26OOWIJJ.js +1 -0
  8. package/dist/chunk-2LK54I4E.js +1 -0
  9. package/dist/chunk-3QVB4AG2.js +3 -0
  10. package/dist/chunk-3U4GP5VA.js +10 -0
  11. package/dist/chunk-3WSPDAK2.js +1 -0
  12. package/dist/chunk-4ES5JGGX.js +1 -0
  13. package/dist/chunk-5464H65G.js +4 -0
  14. package/dist/chunk-57DJOKXT.js +1 -0
  15. package/dist/chunk-5MZ3RNQQ.js +13 -0
  16. package/dist/chunk-5ZBY24K7.js +1 -0
  17. package/dist/chunk-6DJHRLCU.js +25 -0
  18. package/dist/chunk-6FY3PZS3.js +1 -0
  19. package/dist/chunk-6TZTKAB5.js +1 -0
  20. package/dist/chunk-6W7WLPZH.js +1 -0
  21. package/dist/chunk-7F52SZOI.js +2 -0
  22. package/dist/chunk-7MU3RJ6S.js +1 -0
  23. package/dist/chunk-7RNTMJER.js +5 -0
  24. package/dist/chunk-A7ZJII7O.js +1 -0
  25. package/dist/chunk-AJBJ74ME.js +1 -0
  26. package/dist/chunk-AKFJK65Z.js +1 -0
  27. package/dist/chunk-AKZWUV5Z.js +1 -0
  28. package/dist/chunk-BDTITTMW.js +1 -0
  29. package/dist/chunk-BSPCSC45.js +1 -0
  30. package/dist/chunk-BXZ6WLHC.js +22 -0
  31. package/dist/chunk-D7M6IRPJ.js +8 -0
  32. package/dist/chunk-DUVRZ456.js +1 -0
  33. package/dist/chunk-E7GGVILG.js +1 -0
  34. package/dist/chunk-F2FPZIZV.js +62 -0
  35. package/dist/chunk-F6CCTEIX.js +1 -0
  36. package/dist/chunk-FGNR22NY.js +1 -0
  37. package/dist/chunk-FT35FX7D.js +2 -0
  38. package/dist/chunk-FUDHI5I4.js +1 -0
  39. package/dist/chunk-GENAF3P6.js +1 -0
  40. package/dist/chunk-GOTN2KY4.js +2 -0
  41. package/dist/chunk-GXQCZJOP.js +1 -0
  42. package/dist/chunk-GZO72N3Q.js +0 -0
  43. package/dist/chunk-HMX55DYT.js +1 -0
  44. package/dist/chunk-HQ4VVRIC.js +1 -0
  45. package/dist/chunk-HWW4XJOH.js +1 -0
  46. package/dist/chunk-I54UCYOU.js +1 -0
  47. package/dist/chunk-IQ5TA7AM.js +1 -0
  48. package/dist/chunk-IWAPPEL4.js +6 -0
  49. package/dist/chunk-IYT6NN2J.js +1 -0
  50. package/dist/chunk-J4RAY75C.js +1 -0
  51. package/dist/chunk-KCBEE2MC.js +2 -0
  52. package/dist/chunk-KDYIMJTZ.js +1 -0
  53. package/dist/chunk-KQMML6JM.js +4 -0
  54. package/dist/chunk-OM67AJQC.js +1 -0
  55. package/dist/chunk-OYX47SL7.js +1 -0
  56. package/dist/chunk-P67FP7PG.js +9 -0
  57. package/dist/chunk-PP44LCJM.js +1 -0
  58. package/dist/chunk-PWZOS45R.js +2 -0
  59. package/dist/chunk-Q3SQBNJB.js +1 -0
  60. package/dist/chunk-R2HLPNQF.js +1 -0
  61. package/dist/chunk-R5L2E7JX.js +1 -0
  62. package/dist/chunk-R5ZVNJLJ.js +2 -0
  63. package/dist/chunk-RLBXE4EU.js +1 -0
  64. package/dist/chunk-RW4XBUUW.js +1 -0
  65. package/dist/chunk-SERF2FAU.js +1 -0
  66. package/dist/chunk-TEZ6V6PA.js +4 -0
  67. package/dist/chunk-TTJ54QGG.js +18 -0
  68. package/dist/chunk-UH7TGWHR.js +1 -0
  69. package/dist/chunk-UVWVYMMZ.js +1 -0
  70. package/dist/chunk-VLSTGOVD.js +2 -0
  71. package/dist/chunk-VV5ADNBR.js +1 -0
  72. package/dist/chunk-ZE7I3PLX.js +1 -0
  73. package/dist/chunk-ZZ7VLIHQ.js +1 -0
  74. package/dist/drag/index.d.ts +3 -41
  75. package/dist/drag/index.js +1 -18
  76. package/dist/easel/index.js +1 -9
  77. package/dist/{words-BMzV04b1.d.ts → engine-DBxp_v6B.d.ts} +1 -58
  78. package/dist/fields/index.d.ts +2 -109
  79. package/dist/fields/index.js +1 -22
  80. package/dist/gold/index.d.ts +4 -2
  81. package/dist/host-B-byaQxg.d.ts +480 -0
  82. package/dist/menu/index.js +1 -1
  83. package/dist/node-ops/index.js +1 -1
  84. package/dist/panel/index.js +16 -16
  85. package/dist/panelWidths-D9hTLR25.d.ts +66 -0
  86. package/dist/screen/components/AddBlockRow.d.ts +14 -0
  87. package/dist/screen/components/AddBlockRow.js +1 -0
  88. package/dist/screen/components/AddChildRow.d.ts +39 -0
  89. package/dist/screen/components/AddChildRow.js +1 -0
  90. package/dist/screen/components/AddSidePanel.d.ts +54 -0
  91. package/dist/screen/components/AddSidePanel.js +1 -0
  92. package/dist/screen/components/MediaSidePanel.d.ts +47 -0
  93. package/dist/screen/components/MediaSidePanel.js +1 -0
  94. package/dist/screen/components/NodeContextMenu.d.ts +364 -0
  95. package/dist/screen/components/NodeContextMenu.js +1 -0
  96. package/dist/screen/components/PageEditGuardNotices.d.ts +5 -0
  97. package/dist/screen/components/PageEditGuardNotices.js +1 -0
  98. package/dist/screen/components/PanelToggleIcon.d.ts +14 -0
  99. package/dist/screen/components/PanelToggleIcon.js +1 -0
  100. package/dist/screen/components/PreviewDeviceContext.d.ts +28 -0
  101. package/dist/screen/components/PreviewDeviceContext.js +1 -0
  102. package/dist/screen/components/PreviewPartsContext.d.ts +33 -0
  103. package/dist/screen/components/PreviewPartsContext.js +1 -0
  104. package/dist/screen/components/ScreenChrome.d.ts +5 -0
  105. package/dist/screen/components/ScreenChrome.js +1 -0
  106. package/dist/screen/components/ScreenDocumentContext.d.ts +20 -0
  107. package/dist/screen/components/ScreenDocumentContext.js +1 -0
  108. package/dist/screen/components/ScreenMount.d.ts +75 -0
  109. package/dist/screen/components/ScreenMount.js +1 -0
  110. package/dist/screen/components/ScreenStoreProvider.d.ts +63 -0
  111. package/dist/screen/components/ScreenStoreProvider.js +1 -0
  112. package/dist/screen/components/SectionScreenShell.d.ts +5 -0
  113. package/dist/screen/components/SectionScreenShell.js +16 -0
  114. package/dist/screen/components/SidePanelHead.d.ts +81 -0
  115. package/dist/screen/components/SidePanelHead.js +1 -0
  116. package/dist/screen/components/SlotChildActionsContext.d.ts +41 -0
  117. package/dist/screen/components/SlotChildActionsContext.js +1 -0
  118. package/dist/screen/components/UiIcon.d.ts +52 -0
  119. package/dist/screen/components/UiIcon.js +1 -0
  120. package/dist/screen/components/panel-widths.d.ts +37 -0
  121. package/dist/screen/components/panel-widths.js +1 -0
  122. package/dist/screen/components/usePartBridge.d.ts +66 -0
  123. package/dist/screen/components/usePartBridge.js +1 -0
  124. package/dist/screen/index.d.ts +31 -0
  125. package/dist/screen/index.js +1 -0
  126. package/dist/screen/lib/admin-bridge.d.ts +105 -0
  127. package/dist/screen/lib/admin-bridge.js +1 -0
  128. package/dist/screen/lib/backend-error.d.ts +106 -0
  129. package/dist/screen/lib/backend-error.js +1 -0
  130. package/dist/screen/lib/chrome-theme.d.ts +21 -0
  131. package/dist/screen/lib/chrome-theme.js +1 -0
  132. package/dist/screen/lib/client-only.d.ts +24 -0
  133. package/dist/screen/lib/client-only.js +1 -0
  134. package/dist/screen/lib/content/view-tiers.d.ts +25 -0
  135. package/dist/screen/lib/content/view-tiers.js +1 -0
  136. package/dist/screen/lib/document-addressing.d.ts +20 -0
  137. package/dist/screen/lib/document-addressing.js +1 -0
  138. package/dist/screen/lib/document-contract.d.ts +230 -0
  139. package/dist/screen/lib/document-contract.js +1 -0
  140. package/dist/screen/lib/document-hooks.d.ts +71 -0
  141. package/dist/screen/lib/document-hooks.js +0 -0
  142. package/dist/screen/lib/document-switch.d.ts +74 -0
  143. package/dist/screen/lib/document-switch.js +1 -0
  144. package/dist/screen/lib/failure.d.ts +54 -0
  145. package/dist/screen/lib/failure.js +1 -0
  146. package/dist/screen/lib/host-chrome.d.ts +181 -0
  147. package/dist/screen/lib/host-chrome.js +1 -0
  148. package/dist/screen/lib/host-inbound.d.ts +20 -0
  149. package/dist/screen/lib/host-inbound.js +1 -0
  150. package/dist/screen/lib/host.d.ts +20 -0
  151. package/dist/screen/lib/host.js +1 -0
  152. package/dist/screen/lib/key-scope.d.ts +23 -0
  153. package/dist/screen/lib/key-scope.js +1 -0
  154. package/dist/screen/lib/links/link-filters.d.ts +41 -0
  155. package/dist/screen/lib/links/link-filters.js +0 -0
  156. package/dist/screen/lib/load-error.d.ts +29 -0
  157. package/dist/screen/lib/load-error.js +1 -0
  158. package/dist/screen/lib/media-panel.d.ts +94 -0
  159. package/dist/screen/lib/media-panel.js +1 -0
  160. package/dist/screen/lib/media-picker.d.ts +68 -0
  161. package/dist/screen/lib/media-picker.js +1 -0
  162. package/dist/screen/lib/page-lock.d.ts +5 -0
  163. package/dist/screen/lib/page-lock.js +1 -0
  164. package/dist/screen/lib/puck/add-target-types.d.ts +55 -0
  165. package/dist/screen/lib/puck/add-target-types.js +0 -0
  166. package/dist/screen/lib/puck/block-choice.d.ts +52 -0
  167. package/dist/screen/lib/puck/block-choice.js +1 -0
  168. package/dist/screen/lib/puck/block-types-in.d.ts +39 -0
  169. package/dist/screen/lib/puck/block-types-in.js +1 -0
  170. package/dist/screen/lib/puck/content-tree.d.ts +196 -0
  171. package/dist/screen/lib/puck/content-tree.js +1 -0
  172. package/dist/screen/lib/puck/device-fields.d.ts +126 -0
  173. package/dist/screen/lib/puck/device-fields.js +1 -0
  174. package/dist/screen/lib/puck/field-buckets.d.ts +22 -0
  175. package/dist/screen/lib/puck/field-buckets.js +1 -0
  176. package/dist/screen/lib/puck/field-markers.d.ts +205 -0
  177. package/dist/screen/lib/puck/field-markers.js +1 -0
  178. package/dist/screen/lib/puck/hidable.d.ts +44 -0
  179. package/dist/screen/lib/puck/hidable.js +1 -0
  180. package/dist/screen/lib/puck/palette-sections.d.ts +96 -0
  181. package/dist/screen/lib/puck/palette-sections.js +1 -0
  182. package/dist/screen/lib/puck/panel-fields.d.ts +47 -0
  183. package/dist/screen/lib/puck/panel-fields.js +1 -0
  184. package/dist/screen/lib/puck/panel-no-control-mark.d.ts +74 -0
  185. package/dist/screen/lib/puck/panel-no-control-mark.js +1 -0
  186. package/dist/screen/lib/puck/part-id.d.ts +23 -0
  187. package/dist/screen/lib/puck/part-id.js +1 -0
  188. package/dist/screen/lib/puck/preview-click.d.ts +49 -0
  189. package/dist/screen/lib/puck/preview-click.js +1 -0
  190. package/dist/screen/lib/puck/preview-dom.d.ts +8 -0
  191. package/dist/screen/lib/puck/preview-dom.js +1 -0
  192. package/dist/screen/lib/puck/preview-events.d.ts +25 -0
  193. package/dist/screen/lib/puck/preview-events.js +1 -0
  194. package/dist/screen/lib/puck/preview-selection-context.d.ts +72 -0
  195. package/dist/screen/lib/puck/preview-selection-context.js +1 -0
  196. package/dist/screen/lib/puck/section-doc.d.ts +20 -0
  197. package/dist/screen/lib/puck/section-doc.js +1 -0
  198. package/dist/screen/lib/puck/slot-child-name.d.ts +186 -0
  199. package/dist/screen/lib/puck/slot-child-name.js +1 -0
  200. package/dist/screen/lib/puck/slot-heal.d.ts +5 -0
  201. package/dist/screen/lib/puck/slot-heal.js +1 -0
  202. package/dist/screen/lib/puck/slot-section-spec.d.ts +96 -0
  203. package/dist/screen/lib/puck/slot-section-spec.js +0 -0
  204. package/dist/screen/lib/puck/style-clipboard.d.ts +78 -0
  205. package/dist/screen/lib/puck/style-clipboard.js +1 -0
  206. package/dist/screen/lib/puck/text-control-kinds.d.ts +71 -0
  207. package/dist/screen/lib/puck/text-control-kinds.js +1 -0
  208. package/dist/screen/lib/puck/tree-reveal.d.ts +62 -0
  209. package/dist/screen/lib/puck/tree-reveal.js +1 -0
  210. package/dist/screen/lib/puck/use-section-ops.d.ts +86 -0
  211. package/dist/screen/lib/puck/use-section-ops.js +1 -0
  212. package/dist/screen/lib/screen-parts.d.ts +727 -0
  213. package/dist/screen/lib/screen-parts.js +1 -0
  214. package/dist/screen/lib/section-template-types.d.ts +49 -0
  215. package/dist/screen/lib/section-template-types.js +0 -0
  216. package/dist/screen/lib/section-templates.d.ts +23 -0
  217. package/dist/screen/lib/section-templates.js +1 -0
  218. package/dist/screen/lib/session-context.d.ts +30 -0
  219. package/dist/screen/lib/session-context.js +1 -0
  220. package/dist/screen/lib/session.d.ts +255 -0
  221. package/dist/screen/lib/session.js +1 -0
  222. package/dist/screen/screen.css +1088 -0
  223. package/dist/session-DSQFmIvx.d.ts +43 -0
  224. package/dist/strings/catalogue.d.ts +4 -2
  225. package/dist/strings/catalogue.js +1 -1
  226. package/dist/strings/index.d.ts +4 -2
  227. package/dist/strings/index.js +1 -1
  228. package/dist/style-clipboard/index.js +1 -1
  229. package/dist/{types-DGcCsxs8.d.ts → types-CqY85foL.d.ts} +3 -65
  230. package/dist/words-D_Lnw1Gr.d.ts +59 -0
  231. package/package.json +343 -2
  232. package/dist/chunk-IG3U5NWJ.js +0 -1
@@ -0,0 +1,480 @@
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
+
39
+ interface DocumentAddressing {
40
+ /**
41
+ * The slug of the HOME document: the one a target stands for when it names
42
+ * no document within its record, and the one an editor falls back to when
43
+ * the document it was pointed at has gone. Null when there is none: such a
44
+ * target then names the empty slug, and a document that has gone is
45
+ * reported and not replaced.
46
+ */
47
+ homeSlug: string | null;
48
+ /**
49
+ * May an editor LOADED on `target` be sent somewhere else before it opens
50
+ * anything? Asked of the target a mount starts on, as it first renders:
51
+ * while the answer is yes the provider shows its "Loading…" and not the
52
+ * document, until `entryBounce` has said where the editor goes — or that it
53
+ * stays after all.
54
+ */
55
+ entryMayBounce: (target: ScreenTarget) => boolean;
56
+ /**
57
+ * Where an editor loaded on `target` goes INSTEAD: the target the host's
58
+ * address is then loaded on, or null and it stays. Asked once per mount, of
59
+ * the target it started on, with the query of the host's address. A switch
60
+ * made in place loads nothing, so it is never asked.
61
+ */
62
+ entryBounce: (target: ScreenTarget, search: string) => ScreenTarget | null;
63
+ /**
64
+ * A switch of document, in place, is going ahead and `next` is where it
65
+ * goes: whatever the layer keeps of its own that depends on where the
66
+ * editor is, it brings up to date here. Called once per switch, after what
67
+ * belonged to the document being left has been cleared and before the
68
+ * provider moves to the new one.
69
+ */
70
+ onSwitch: (next: ScreenTarget) => void;
71
+ /**
72
+ * Is the host told that the editor moved to `next`? The host remembers the
73
+ * last target it was told, and reopens the editor there on a reload — so a
74
+ * target the editor must not be reopened on is one the host is not told.
75
+ */
76
+ tellsHost: (next: ScreenTarget) => boolean;
77
+ /**
78
+ * What stores the document `target` names: its adapter, over the backend in
79
+ * force and the sets of blocks the host offers (both the session's, and the
80
+ * provider's to read). The provider asks again when the target moves to
81
+ * another record — not on every switch of document within one.
82
+ *
83
+ * The backend comes as the session holds it (lib/session
84
+ * `SessionBackend`): the layer that handed the session its backend knows its
85
+ * own type, and the provider names none.
86
+ */
87
+ adapterFor: (target: ScreenTarget, backend: SessionBackend, blocks: SessionBlocks | null) => EaselDocumentAdapter;
88
+ /**
89
+ * Carry the stored answer of every prop the layer has RENAMED to its new
90
+ * key, in a layout as it was stored and before the canvas reads it. The
91
+ * canvas reads a node's props by the keys its fields declare, so an answer
92
+ * left under an old key would be shown as the default and then saved as it.
93
+ * Answers with the same object when it carried nothing.
94
+ */
95
+ migrateRenamedProps: <T>(data: T) => T;
96
+ }
97
+ /**
98
+ * With no layer: there is no home, so nothing is fallen back to; an editor
99
+ * stays on whatever target it is loaded on; a switch of document has nothing
100
+ * of a layer's to bring up to date, and the host is told of every one; the
101
+ * document is the one nothing stores; and a stored layout is read as it was
102
+ * stored, there being no layer to have renamed a prop.
103
+ */
104
+ declare const NO_DOCUMENT_ADDRESSING: DocumentAddressing;
105
+
106
+ type ScreenTarget = {
107
+ kind: "page";
108
+ slug: string;
109
+ siteId?: string;
110
+ originSlug?: string;
111
+ } | {
112
+ kind: "template";
113
+ id: string;
114
+ pageSlug?: string;
115
+ };
116
+
117
+ type ScreenDocumentValue = {
118
+ /** The document the editor is currently pointed at (runtime, retargetable). */
119
+ target: ScreenTarget;
120
+ /** Record-type plumbing (load/save/list/create/delete) for the pointed-at
121
+ * document. Chrome and panels consult `capabilities`, never the record type. */
122
+ adapter: EaselDocumentAdapter;
123
+ /** What this document type supports — the ONLY sanctioned mode switch. */
124
+ capabilities: EaselCapabilities;
125
+ /** Id of the website template being edited (template mode only). */
126
+ templateId: string | null;
127
+ /** Slug of the page being edited — the template page's slug in template mode. */
128
+ currentSlug: string;
129
+ /** Kind of the loaded page (`dynamic` drives the product-binding controls), or
130
+ * null while loading / in template mode where the record carries no kind. */
131
+ currentKind: string | null;
132
+ /** Id of the website this page belongs to (page mode only; null in template
133
+ * mode or when the editor was opened without a site). The list/save paths and
134
+ * the page switcher scope to this so they act on one site's pages, not the
135
+ * whole tenant's. */
136
+ siteId: string | null;
137
+ /** Whether the editor's backend may be called yet. Under the EFFICIENT backend
138
+ * that is "the console's token has arrived"; an embedder's own backend
139
+ * authorises its calls itself and is ready from the first render. THE gate
140
+ * for anything that goes through the backend — never `token`, which an
141
+ * embedder's backend does not have. */
142
+ ready: boolean;
143
+ /** The bridged admin JWT once it arrives (null while waiting, and always null
144
+ * under an embedder's own backend). Only for the callers that still pass it
145
+ * to the EFFICIENT client themselves. */
146
+ token: string | null;
147
+ /** Latest token for imperative reads (custom fields, pickers, panels). */
148
+ tokenRef: RefObject<string | null>;
149
+ /** Bridge editor events to the embedding admin portal. */
150
+ notifyParent: SendToHost;
151
+ /** Operator capabilities the ADMIN CONSOLE granted over the origin-gated
152
+ * bridge. Distinct from `capabilities` above: those describe the DOCUMENT
153
+ * (can it publish, has it site settings), these describe the PERSON, and the
154
+ * editor is never allowed to infer them for itself. */
155
+ bridgeCapabilities: BridgedCapabilities;
156
+ /** Run an authed op; on 401 ask the parent for a fresh token and retry once. */
157
+ runAuthed: (op: (token: string) => Promise<unknown>) => Promise<boolean>;
158
+ /** Backend id of the loaded document — the identity of what the editor is
159
+ * editing right now. Null while loading and between retargets, so it also
160
+ * keys any once-per-document work (e.g. the pinned-chrome seed). */
161
+ docId: string | null;
162
+ /** The document exactly as it was LOADED from the backend: Puck's initial
163
+ * state, and the persisted snapshot a load-time seed must measure itself
164
+ * against. Null while loading. Edits live in Puck's own store, so this does
165
+ * NOT track them — it stays the last-loaded layout for the whole session. */
166
+ data: Data | null;
167
+ /** The freshest layout the merchant is actually viewing — the latest edit made
168
+ * since load (tracked on every onChange, even after the autosave settles), else
169
+ * the last-loaded `data`. Lets a feature snapshot the live view (e.g. the
170
+ * read-only origin backdrop in footer focus) without reaching into Puck's store.
171
+ * Lean accessor (ISP) — never exposes the ref. */
172
+ getLiveData: () => Data | null;
173
+ /** FOOTER FOCUS: the slug of the page the footer was opened from, or null. Rides
174
+ * the nav target, so it's atomic with the retarget (never stale). */
175
+ footerOriginSlug: string | null;
176
+ error: string | null;
177
+ /** True while the template-entry bounce is redirecting to the Home page. */
178
+ redirecting: boolean;
179
+ /** The pinned-seed gate's four words for where the autosave stands. */
180
+ saveStatus: SaveStatus;
181
+ /** The autosave's state (efficient-easel/autosave) — what the toolbar pill
182
+ * draws, through `saveIndicator`. */
183
+ saveState: AutosaveSnapshot;
184
+ /** Whether autosave is running. The toolbar pill is a switch: clicking it
185
+ * flips this. OFF = edits are HELD (kept in memory, still flushable by Publish
186
+ * / navigation / re-enabling) but never written on a timer. Session-scoped —
187
+ * survives in-place page switches. */
188
+ autoSaveEnabled: boolean;
189
+ /** Auto-save stopped because a save was REFUSED, not because the operator
190
+ * paused it — so a stopped auto-save can never read as a switch somebody
191
+ * flicked themselves. */
192
+ autoSaveStoppedByConflict: boolean;
193
+ /** True when an edit hasn't been persisted yet — including one held while the
194
+ * claim is in flight. Drives the guard that prompts before an in-place
195
+ * navigation would abandon held-but-unsaved edits. */
196
+ hasUnsavedEdits: boolean;
197
+ /** Flip autosave on/off. Turning it back ON writes any held edits at once, so
198
+ * "on" always means caught up. */
199
+ toggleAutoSave: () => void;
200
+ /** "Retry now": a failed save goes again at once instead of waiting out its
201
+ * backoff. */
202
+ retrySave: () => void;
203
+ /** Autosave — hand every Puck onChange to this. */
204
+ onChange: (next: Data) => void;
205
+ /** Persist the pending edit immediately; resolves to whether nothing is left
206
+ * unsaved. */
207
+ flushSave: () => Promise<boolean>;
208
+ /** Persist + publish the current document (Save for templates). */
209
+ onPublish: (next: Data) => Promise<void>;
210
+ /** Whether this editor may write the open page, and why not when it may not.
211
+ * `editing` is the only writable state; the gate is on the save path itself,
212
+ * so hiding or showing chrome from this can't be the thing that protects the
213
+ * document. Always `editing` in template mode (no lock there). */
214
+ access: EditAccess;
215
+ /** SOMEBODY ELSE holds this page, so this editor is read-only: it may look and
216
+ * select, but not move, add, duplicate or delete anything — until they take
217
+ * control themselves. The ONE answer the chrome asks; no panel re-derives it,
218
+ * so none of them can drift.
219
+ *
220
+ * NOT what protects the document — `persistLayout` refuses the write, and it
221
+ * refuses it in more cases than this (while the claim is still `checking`, and
222
+ * after a refused save). This is the narrower question the CHROME asks, and it
223
+ * is narrower on purpose: during `checking` nobody is named yet, and the
224
+ * pinned Header/Footer seed runs in the chrome's mount commit and must still
225
+ * land. Its write is held by `onChange` and released by the claim if it is
226
+ * granted, or never released if it is not — card 1096. */
227
+ readOnly: boolean;
228
+ /** Take the page: from the "someone else is editing" choice, or back after
229
+ * somebody took it from you. */
230
+ takeOverEditing: () => void;
231
+ /** Choose to look without touching (keeps the holder for the ribbon). */
232
+ viewReadOnly: () => void;
233
+ /** A save the backend REFUSED because the stored page moved on. Non-null means
234
+ * autosave has stopped and the operator's work is still only on their screen.
235
+ * Told in a bar under the top bar (efficient-easel/chrome `EditNotice`),
236
+ * never a dialog, so there is nothing to dismiss: the operator reads and
237
+ * copies from the screen it is warning them about. */
238
+ saveConflict: SaveConflict | null;
239
+ /** Abandon this editor's version and reload what is stored. The ONLY path that
240
+ * throws the operator's work away, and only they can ask for it. */
241
+ reloadFromServer: () => void;
242
+ /** Retarget the editor in place (guards unsaved changes before it swaps). */
243
+ navigate: (target: ScreenTarget) => void;
244
+ /** A retarget held behind the unsaved-changes prompt (null = no prompt). */
245
+ pendingNav: ScreenTarget | null;
246
+ cancelPendingNav: () => void;
247
+ discardAndNavigate: () => void;
248
+ saveAndNavigate: () => Promise<void>;
249
+ };
250
+ declare const ScreenDocumentContext: react.Context<ScreenDocumentValue | null>;
251
+ declare function useScreenDocument(): ScreenDocumentValue;
252
+ declare function ScreenDocumentProvider({ target, addressing, onHostMessage, children, }: {
253
+ target: ScreenTarget;
254
+ /** How this editor's documents are ADDRESSED — the layer's rules, handed in
255
+ * by whoever mounts the provider (the website's entry hands the website's:
256
+ * lib/website-document-addressing). Without them there is one document that
257
+ * nothing stores. ONE object for the life of the mount, like the session. */
258
+ addressing?: DocumentAddressing;
259
+ /** The layer's own host messages, asked before the ones every editor answers
260
+ * (lib/host-inbound): the website's are lib/website-host-inbound.
261
+ * Returns true when it handled one. */
262
+ onHostMessage?: (raw: unknown) => boolean;
263
+ children: ReactNode;
264
+ }): react.JSX.Element;
265
+
266
+ /**
267
+ * The editor's HOST — whatever embeds the storefront editor, and the one way the
268
+ * editor talks to it.
269
+ *
270
+ * The editor asks its host for the things it cannot do itself (open the media
271
+ * picker, the form builder, a product's window; say that a save failed) and
272
+ * hears back from it (the admin token, a category that was edited elsewhere, a
273
+ * retarget to another page). It used to be the shop's own `/edit/*` route,
274
+ * framed by the admin portal in a cross-origin iframe, and every one of those
275
+ * calls was a `postMessage` to `window.parent`. The admin portal now mounts the
276
+ * editor in its own window (the `efficient-web-builder` package) and builds its host
277
+ * with {@link createEaselHost}: the same `storefront-editor:*` messages, as
278
+ * function calls — no origin, no serialisation, no handshake race. Surfaces
279
+ * still read inbound messages defensively; the protocol kept its shape.
280
+ *
281
+ * A surface with no provider above it (a dev harness, a guard rendering one
282
+ * panel) gets {@link DETACHED_EASEL_HOST}: nobody listening, nothing sent — a
283
+ * request that needs an answer settles empty instead of waiting forever.
284
+ */
285
+ /** A picked media item, as the host's media picker returns it. */
286
+ interface HostPickedMedia {
287
+ id: string;
288
+ url: string;
289
+ kind: "image" | "video";
290
+ }
291
+ /** The SECTION editor's target (the standalone one-section surface). */
292
+ type SectionScreenTarget = {
293
+ kind: "section";
294
+ id: string;
295
+ type?: string;
296
+ name?: string;
297
+ };
298
+ /** Every message the editor sends its host, by name. */
299
+ type EaselToHostMessage =
300
+ /** The editor is listening; send (or re-send) `auth`. Repeats until a token lands. */
301
+ {
302
+ type: "storefront-editor:ready";
303
+ }
304
+ /** A call was refused 401; refresh the token and send `auth` again. */
305
+ | {
306
+ type: "storefront-editor:auth-expired";
307
+ }
308
+ /** The document changed in the editor (every edit). */
309
+ | {
310
+ type: "storefront-editor:dirty";
311
+ }
312
+ /** An explicit Save landed (autosaves stay quiet). */
313
+ | {
314
+ type: "storefront-editor:saved";
315
+ }
316
+ /** The page was published. */
317
+ | {
318
+ type: "storefront-editor:published";
319
+ }
320
+ /** A save failed (first failure of a retry run only). */
321
+ | {
322
+ type: "storefront-editor:save-failed";
323
+ }
324
+ /** The editor moved in place to another page (page targets only). */
325
+ | {
326
+ type: "storefront-editor:navigated";
327
+ target: ScreenTarget;
328
+ }
329
+ /** Open the media picker; answer `media-picked` / `media-pick-cancelled` with the same id. */
330
+ | {
331
+ type: "storefront-editor:open-media-picker";
332
+ requestId: string;
333
+ accept: string;
334
+ title: string;
335
+ file?: File;
336
+ }
337
+ /** A form. `mode: "create"` asks for a new one and carries a `requestId`:
338
+ * answer `form-saved` / `form-closed` with the same id. `mode: "edit"` opens
339
+ * the form builder on `formId` and carries none: nothing waits on it. */
340
+ | {
341
+ type: "storefront-editor:open-form";
342
+ requestId?: string;
343
+ mode: "create" | "edit";
344
+ formId?: string;
345
+ } | {
346
+ type: "storefront-editor:open-category";
347
+ categoryId: string;
348
+ name?: string;
349
+ } | {
350
+ type: "storefront-editor:open-product";
351
+ slug: string;
352
+ name?: string;
353
+ } | {
354
+ type: "storefront-editor:open-post";
355
+ slug: string;
356
+ title?: string;
357
+ } | {
358
+ type: "storefront-editor:open-menus";
359
+ menuId?: string | null;
360
+ } | {
361
+ type: "storefront-editor:open-page";
362
+ slug: string;
363
+ } | {
364
+ type: "storefront-editor:new-page";
365
+ }
366
+ /** Ask the host to save this website as a platform template (it decides). */
367
+ | {
368
+ type: "storefront-editor:save-as-template";
369
+ siteId: string;
370
+ slug: string;
371
+ };
372
+ /** Every message a host sends the editor, by name. */
373
+ type HostToEaselMessage = {
374
+ type: "storefront-editor:auth";
375
+ token: string;
376
+ siteId?: string;
377
+ brandId?: string;
378
+ theme?: string;
379
+ can?: {
380
+ canCreatePlatformTemplate?: boolean;
381
+ };
382
+ } | {
383
+ type: "storefront-editor:navigate";
384
+ target: ScreenTarget | SectionScreenTarget;
385
+ } | {
386
+ type: "storefront-editor:category-updated";
387
+ categoryId?: string;
388
+ } | {
389
+ type: "storefront-editor:menus-updated";
390
+ } | {
391
+ type: "storefront-editor:form-saved";
392
+ requestId?: string;
393
+ form?: {
394
+ id: string;
395
+ slug: string;
396
+ };
397
+ } | {
398
+ type: "storefront-editor:form-closed";
399
+ requestId?: string;
400
+ } | {
401
+ type: "storefront-editor:media-picked";
402
+ requestId: string;
403
+ media: HostPickedMedia;
404
+ } | {
405
+ type: "storefront-editor:media-pick-cancelled";
406
+ requestId: string;
407
+ };
408
+ type EaselMessageType = EaselToHostMessage["type"];
409
+ type PayloadOf<T extends EaselMessageType> = Omit<Extract<EaselToHostMessage, {
410
+ type: T;
411
+ }>, "type">;
412
+ /** Send one message to the host — `send("storefront-editor:open-page", { slug })`.
413
+ * The payload is required exactly when the message carries one. */
414
+ type SendToHost = <T extends EaselMessageType>(type: T, ...payload: Record<string, never> extends PayloadOf<T> ? [PayloadOf<T>?] : [PayloadOf<T>]) => void;
415
+ /** What reaches a surface's listener: a named message whose fields the surface
416
+ * reads defensively (over the iframe transport it is untrusted data). */
417
+ type InboundHostMessage = {
418
+ type: string;
419
+ } & Record<string, unknown>;
420
+ /**
421
+ * The editor's address. An iframe editor IS a document with a URL — a refresh
422
+ * must reopen the page being edited, so the address follows it. An editor
423
+ * mounted inside another app has no address of its own; that app keeps its own
424
+ * notion of "where" (it hears `navigated`) and implements these as retargets.
425
+ */
426
+ interface EaselHostAddress {
427
+ /** The query the editor was opened with (`?editTemplate=1`, `?site=` …). */
428
+ search(): string;
429
+ /** Keep the address in step with the open document (no load). */
430
+ show(target: ScreenTarget | SectionScreenTarget): void;
431
+ /** Leave for another document by LOADING it (an entry bounce, a deleted page). */
432
+ load(target: ScreenTarget): void;
433
+ /** Reload the editor from scratch (abandon this tab's copy of the document). */
434
+ reload(): void;
435
+ }
436
+ interface EaselHost {
437
+ /** Whether anything is listening. False on a bare `/edit` page no admin embeds. */
438
+ readonly connected: boolean;
439
+ /**
440
+ * Whether the editor IS the page — the shop's `/edit` routes, where nothing
441
+ * else shares the document, so page-wide shortcuts (undo, copy style) listen
442
+ * on `document` and the editor may stamp `<html>`. False for an embedder that
443
+ * mounts the editor inside its own page: there a key belongs to the editor
444
+ * only while focus is inside it, and the page's `<html>` is not the editor's.
445
+ */
446
+ readonly ownsDocument: boolean;
447
+ send: SendToHost;
448
+ /** Listen to the host. Returns the unsubscribe. */
449
+ subscribe(listener: (message: InboundHostMessage) => void): () => void;
450
+ readonly address: EaselHostAddress;
451
+ }
452
+ /** The host of a surface nobody embeds: nothing sent, nothing heard, an address
453
+ * that stays put. */
454
+ declare const DETACHED_EASEL_HOST: EaselHost;
455
+ declare const EaselHostContext: react.Context<EaselHost>;
456
+ declare function EaselHostProvider({ host, children }: {
457
+ host: EaselHost;
458
+ children: ReactNode;
459
+ }): react.JSX.Element;
460
+ /** The host of the editor this component renders in. */
461
+ declare function useEaselHost(): EaselHost;
462
+ /**
463
+ * A host for an embedder that mounts the editor in its own page — the admin
464
+ * portal's native editor window. `onMessage` receives everything the editor
465
+ * sends (typed); the returned `deliver` hands a message to the editor, exactly
466
+ * as a trusted postMessage would have arrived.
467
+ *
468
+ * One per mounted editor: a host carries one editor's conversation, so two
469
+ * editors open at once (a page and a section) each get their own and a retarget
470
+ * meant for one never reaches the other.
471
+ */
472
+ declare function createEaselHost(options: {
473
+ onMessage: (message: EaselToHostMessage) => void;
474
+ address: EaselHostAddress;
475
+ }): {
476
+ host: EaselHost;
477
+ deliver: (message: HostToEaselMessage) => void;
478
+ };
479
+
480
+ export { 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 ScreenTarget as j, ScreenDocumentContext as k, ScreenDocumentProvider as l, type ScreenDocumentValue as m, useScreenDocument as n, useEaselHost as u };
@@ -1 +1 @@
1
- export{ES_MENU_SKIN,EaselContextMenu}from"../chunk-KTVH2ZRL.js";var e=/\b(transform|translate|rotate|scale|perspective|filter|backdrop-filter|contain)\b/;function t(t){const n=e=>t.getPropertyValue(e).trim(),r=(e,t)=>{const r=n(e);return""!==r&&!t.includes(r)};return!!r("transform",["none"])||(!!(r("translate",["none"])||r("rotate",["none"])||r("scale",["none"]))||(!!r("perspective",["none"])||(!!r("filter",["none"])||(!(!r("backdrop-filter",["none"])&&!r("-webkit-backdrop-filter",["none"]))||(!!/\b(layout|paint|strict|content)\b/.test(n("contain"))||(!!r("container-type",["normal"])||(!!r("content-visibility",["visible"])||e.test(n("will-change")))))))))}function n(e){const n=e?.ownerDocument,r=n?.defaultView;if(!(e&&n&&r&&e.isConnected))return null;for(let o=e;o&&o!==n.body&&o!==n.documentElement;o=o.parentElement)if(t(r.getComputedStyle(o)))return null;return e}export{n as menuPortalTarget};
1
+ export{menuPortalTarget}from"../chunk-RW4XBUUW.js";export{ES_MENU_SKIN,EaselContextMenu}from"../chunk-KTVH2ZRL.js";
@@ -1 +1 @@
1
- import{DEFAULT_NODE_MENU_WORDS as e}from"../chunk-WK3AFPXY.js";export{canStep,fromItemSelector,parentStep,planDuplicate,planMove,planPaste,planRemove,planSetProps,planStep,toItemSelector,useNodeOps}from"../chunk-D2BCHTQR.js";import{TrashIcon as n,EyeIcon as t,EyeOffIcon as o,RenameIcon as p,PasteIcon as l,CopyIcon as c,MoveDownIcon as s,MoveUpIcon as a,DuplicateIcon as i,AddIcon as r,LayersIcon as u}from"../chunk-L5KW4HG5.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";import{jsx as h}from"react/jsx-runtime";function d(){let e=null;const n=/* @__PURE__ */new Set;return{get:()=>e,set(t){e=t;for(const e of[...n])e()},subscribe:e=>(n.add(e),()=>n.delete(e))}}var m={layer:{icon:/* @__PURE__ */h(u,{})},addInside:{icon:/* @__PURE__ */h(r,{})},duplicate:{icon:/* @__PURE__ */h(i,{})},moveUp:{icon:/* @__PURE__ */h(a,{})},moveDown:{icon:/* @__PURE__ */h(s,{})},copy:{icon:/* @__PURE__ */h(c,{}),shortcut:"⌘C"},cut:{icon:/* @__PURE__ */h(c,{}),shortcut:"⌘X"},paste:{icon:/* @__PURE__ */h(l,{}),shortcut:"⌘V"},rename:{icon:/* @__PURE__ */h(p,{})},hide:{icon:/* @__PURE__ */h(o,{})},show:{icon:/* @__PURE__ */h(t,{})},upLevel:{},delete:{icon:/* @__PURE__ */h(n,{}),danger:!0}};function v(n){const{actions:t,rows:o={},extras:p={},words:l=e}=n,c=e=>({...m[e],label:l[e],...o[e]}),s=(e,n,t)=>{const o=c(e),p={label:t??o.label??e,onClick:n};return o.icon&&(p.icon=o.icon),o.shortcut&&(p.shortcut=o.shortcut),o.danger&&(p.danger=!0),p},a=()=>{const e=c("layer"),t={label:e.label??l.layer,onClick:()=>{},children:n.layer.items};return e.icon&&(t.icon=e.icon),t},i=[],r=[],u=[],h=[],d=!!n.layer&&n.layer.items.length>1;if(d&&"pick"===(n.layer.group??"pick")&&i.push(a()),t.addInside&&r.push(s("addInside",t.addInside)),t.duplicate&&r.push(s("duplicate",t.duplicate)),t.moveUp&&r.push(s("moveUp",t.moveUp)),t.moveDown&&r.push(s("moveDown",t.moveDown)),t.copy&&r.push(s("copy",t.copy)),t.cut&&r.push(s("cut",t.cut)),t.paste){const e=c("paste").label??l.paste;r.push(s("paste",t.paste.run,l.pasteNamed({paste:e,label:t.paste.label})))}t.rename&&u.push(s("rename",t.rename)),t.hide&&u.push(t.hide.hidden?s("show",t.hide.run):s("hide",t.hide.run)),d&&"change"===n.layer.group&&u.push(a()),t.upLevel&&u.push(s("upLevel",t.upLevel)),t.delete&&h.push(s("delete",t.delete)),i.push(...p.pick??[]),r.push(...p.make??[]),u.push(...p.change??[]),h.push(...p.remove??[]);const v=[i,r,n.style??[],u,h].filter(e=>e.length>0),g=i.length+r.length+u.length+h.length===0,k=[{label:n.title,header:!0,onClick:()=>{}}];return g&&n.pinnedLine&&k.push({label:n.pinnedLine,header:!0,onClick:()=>{}}),v.forEach((e,t)=>{(t>0||g&&n.pinnedLine)&&k.push({label:"—",onClick:()=>{}}),k.push(...e)}),k}export{d as createNodeClipboard,v as nodeMenuItems};
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";
@@ -1,18 +1,18 @@
1
- export{SETTINGS_BUCKETS,SettingsField,SettingsGroup,SettingsTabs}from"../chunk-ZNS7727Y.js";import{DEFAULT_PANEL_WORDS as e}from"../chunk-QTLAVDJE.js";export{SettingsSegmented,SettingsSwitch}from"../chunk-P6O363EE.js";import"../chunk-BZ5ASXOL.js";import{RevertIcon as a}from"../chunk-L5KW4HG5.js";import{jsx as l,jsxs as s}from"react/jsx-runtime";function i({title:e,level:a=3,id:s,className:i}){/* @__PURE__ */
2
- return l(`h${a}`,{id:s,className:i?`es-group-head ${i}`:"es-group-head",children:e})}function n({title:e,level:a=4,id:s,className:i}){/* @__PURE__ */
3
- return l(`h${a}`,{id:s,className:i?`es-group-sub ${i}`:"es-group-sub",children:e})}function t({label:s,changed:i,onReset:n,detail:t,disabled:r,defaultAction:d,words:o,className:u}){const p={...e,...o},m=["es-default-reset"];if(i&&m.push("is-changed"),u&&m.push(u),!i&&d)return m.push("is-pressable"),/* @__PURE__ */l("button",{type:"button",className:m.join(" "),"aria-label":d.title,title:d.title,disabled:r,onClick:d.onPress,children:d.icon});if(!i)/* @__PURE__ */
4
- return l("span",{className:m.join(" "),"aria-hidden":"true"});const b=p.resetName({label:s});/* @__PURE__ */
5
- return l("button",{type:"button",className:m.join(" "),"aria-label":b,"aria-description":t||void 0,title:t?p.resetTitle({label:s,detail:t}):b,disabled:r,onClick:e=>{n(),function(e){const a=e.currentTarget.closest(".es-field"),l=a?.querySelector(c(".es-field-ctl"))??a?.querySelector(c(".es-field-head"));l?.focus()}(e)},children:/* @__PURE__ */l(a,{size:15})})}var r=['input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","button:not([disabled]):not(.es-default-reset)",'[tabindex]:not([tabindex="-1"])'].join(", "),c=e=>r.split(", ").map(a=>`${e} ${a}`).join(", ");function d({name:e,preview:a,offPage:i,status:n,onOpen:t,id:r,className:c}){const d=null!=a;/* @__PURE__ */
6
- return s("button",{type:"button",id:r,className:c?`es-drill ${c}`:"es-drill",onClick:t,children:[
1
+ export{SETTINGS_BUCKETS,SettingsField,SettingsGroup,SettingsTabs}from"../chunk-ZNS7727Y.js";import{DEFAULT_PANEL_WORDS as e}from"../chunk-QTLAVDJE.js";export{SettingsSegmented,SettingsSwitch}from"../chunk-P6O363EE.js";import"../chunk-BZ5ASXOL.js";import{RevertIcon as a}from"../chunk-L5KW4HG5.js";import{jsx as l,jsxs as s}from"react/jsx-runtime";function n({title:e,level:a=3,id:s,className:n}){/* @__PURE__ */
2
+ return l(`h${a}`,{id:s,className:n?`es-group-head ${n}`:"es-group-head",children:e})}function i({title:e,level:a=4,id:s,className:n}){/* @__PURE__ */
3
+ return l(`h${a}`,{id:s,className:n?`es-group-sub ${n}`:"es-group-sub",children:e})}function t({label:s,changed:n,onReset:i,detail:t,disabled:d,defaultAction:u,words:p,className:m}){const b={...e,...p},h=["es-default-reset"];if(n&&h.push("is-changed"),m&&h.push(m),!n&&u)return h.push("is-pressable"),/* @__PURE__ */l("button",{type:"button",className:h.join(" "),"aria-label":u.title,title:u.title,disabled:d,onClick:u.onPress,children:u.icon});if(!n)/* @__PURE__ */
4
+ return l("span",{className:h.join(" "),"aria-hidden":"true"});const N=b.resetName({label:s});/* @__PURE__ */
5
+ return l("button",{type:"button",className:h.join(" "),"aria-label":N,"aria-description":t||void 0,title:t?b.resetTitle({label:s,detail:t}):N,disabled:d,onClick:e=>{i(),function(e){const a=e.currentTarget,l=a.closest(".es-field");let s=l?.querySelector(o(".es-field-ctl"))??l?.querySelector(o(".es-field-head"))??null,n=l?null:a.parentElement;for(let e=0;!s&&n&&e<c;e+=1,n=n.parentElement)s=[...n.querySelectorAll(r)].find(e=>e!==a)??null;s?.focus()}(e)},children:/* @__PURE__ */l(a,{size:15})})}var r=['input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","button:not([disabled]):not(.es-default-reset)",'[tabindex]:not([tabindex="-1"])'].join(", "),o=e=>r.split(", ").map(a=>`${e} ${a}`).join(", "),c=4;function d({name:e,preview:a,offPage:n,status:i,onOpen:t,id:r,className:o}){const c=null!=a;/* @__PURE__ */
6
+ return s("button",{type:"button",id:r,className:o?`es-drill ${o}`:"es-drill",onClick:t,children:[
7
7
  /* @__PURE__ */s("span",{className:"es-drill-text",children:[
8
- /* @__PURE__ */l("span",{className:"es-drill-name",children:e}),d?/* @__PURE__ */l("span",{className:i?"es-drill-preview is-offpage":"es-drill-preview",children:a}):null]}),n?/* @__PURE__ */l("span",{className:"es-drill-status",children:n}):null,
9
- /* @__PURE__ */l("span",{className:"es-drill-chev","aria-hidden":"true"})]})}function o({label:e,value:a,points:s,onChange:i,id:n,className:t}){/* @__PURE__ */
10
- return l("div",{id:n,className:"es-placement"+(t?` ${t}`:""),role:"radiogroup","aria-label":e,children:s.map(e=>{const s=a===e.value,n=!0===e.disabled;/* @__PURE__ */
11
- return l("button",{type:"button",role:"radio","aria-checked":s,"aria-label":e.label,"aria-disabled":n||void 0,disabled:n,title:e.title??e.label,className:`es-placement-cell${s?" is-active":""}${n?" is-off":""}`,onClick:()=>i(e.value),children:e.icon?/* @__PURE__ */l("span",{className:"es-placement-icon","aria-hidden":"true",children:e.icon}):/* @__PURE__ */l("span",{className:"es-placement-dot"})},e.value)})})}function u({label:e,value:a,corners:i,onChange:n,id:t,className:r}){/* @__PURE__ */
8
+ /* @__PURE__ */l("span",{className:"es-drill-name",children:e}),c?/* @__PURE__ */l("span",{className:n?"es-drill-preview is-offpage":"es-drill-preview",children:a}):null]}),i?/* @__PURE__ */l("span",{className:"es-drill-status",children:i}):null,
9
+ /* @__PURE__ */l("span",{className:"es-drill-chev","aria-hidden":"true"})]})}function u({label:e,value:a,points:s,onChange:n,id:i,className:t}){/* @__PURE__ */
10
+ return l("div",{id:i,className:"es-placement"+(t?` ${t}`:""),role:"radiogroup","aria-label":e,children:s.map(e=>{const s=a===e.value,i=!0===e.disabled;/* @__PURE__ */
11
+ return l("button",{type:"button",role:"radio","aria-checked":s,"aria-label":e.label,"aria-disabled":i||void 0,disabled:i,title:e.title??e.label,className:`es-placement-cell${s?" is-active":""}${i?" is-off":""}`,onClick:()=>n(e.value),children:e.icon?/* @__PURE__ */l("span",{className:"es-placement-icon","aria-hidden":"true",children:e.icon}):/* @__PURE__ */l("span",{className:"es-placement-dot"})},e.value)})})}function p({label:e,value:a,corners:n,onChange:i,id:t,className:r}){/* @__PURE__ */
12
12
  return s("div",{id:t,className:"es-corners"+(r?` ${r}`:""),role:"group","aria-label":e,children:[
13
- /* @__PURE__ */l("span",{className:"es-corners-frame","aria-hidden":"true"}),i.map(e=>{const s=a.includes(e.value),i=!0===e.disabled;/* @__PURE__ */
14
- return l("button",{type:"button","aria-pressed":s,"aria-label":e.label,"aria-disabled":i||void 0,disabled:i,title:e.title??e.label,className:`es-corners-cell es-corners-${e.value}${s?" is-on":""}${i?" is-off":""}`,onClick:()=>n(s?a.filter(a=>a!==e.value):[...a,e.value]),children:/* @__PURE__ */l("span",{className:"es-corners-mark","aria-hidden":"true"})},e.value)})]})}function p({label:e,onPress:a,disabled:i,note:n,done:t,doneLabel:r,icon:c,id:d,className:o}){const u=void 0===r?e:r,p=t?u:e,m=null!=n,b=m&&d?`${d}-note`:void 0;/* @__PURE__ */
15
- return s("div",{className:o?`es-action-wrap ${o}`:"es-action-wrap",children:[
16
- /* @__PURE__ */s("button",{type:"button",id:d,className:t?"es-action is-done":"es-action",disabled:i,"aria-describedby":b,onClick:a,children:[c?/* @__PURE__ */l("span",{className:"es-action-icon","aria-hidden":"true",children:c}):null,
17
- /* @__PURE__ */l("span",{className:"es-action-label",children:p})]}),m?/* @__PURE__ */l("p",{id:b,className:"es-action-note",children:n}):null,
18
- /* @__PURE__ */l("span",{className:"es-action-live",role:"status","aria-live":"polite",children:t?u:null})]})}export{p as SettingsAction,u as SettingsCorners,t as SettingsDefaultReset,d as SettingsDrill,i as SettingsGroupHead,n as SettingsGroupSub,o as SettingsPlacement};
13
+ /* @__PURE__ */l("span",{className:"es-corners-frame","aria-hidden":"true"}),n.map(e=>{const s=a.includes(e.value),n=!0===e.disabled;/* @__PURE__ */
14
+ return l("button",{type:"button","aria-pressed":s,"aria-label":e.label,"aria-disabled":n||void 0,disabled:n,title:e.title??e.label,className:`es-corners-cell es-corners-${e.value}${s?" is-on":""}${n?" is-off":""}`,onClick:()=>i(s?a.filter(a=>a!==e.value):[...a,e.value]),children:/* @__PURE__ */l("span",{className:"es-corners-mark","aria-hidden":"true"})},e.value)})]})}function m({label:e,onPress:a,disabled:n,note:i,done:t,doneLabel:r,icon:o,id:c,className:d}){const u=void 0===r?e:r,p=t?u:e,m=null!=i,b=m&&c?`${c}-note`:void 0;/* @__PURE__ */
15
+ return s("div",{className:d?`es-action-wrap ${d}`:"es-action-wrap",children:[
16
+ /* @__PURE__ */s("button",{type:"button",id:c,className:t?"es-action is-done":"es-action",disabled:n,"aria-describedby":b,onClick:a,children:[o?/* @__PURE__ */l("span",{className:"es-action-icon","aria-hidden":"true",children:o}):null,
17
+ /* @__PURE__ */l("span",{className:"es-action-label",children:p})]}),m?/* @__PURE__ */l("p",{id:b,className:"es-action-note",children:i}):null,
18
+ /* @__PURE__ */l("span",{className:"es-action-live",role:"status","aria-live":"polite",children:t?u:null})]})}export{m as SettingsAction,p as SettingsCorners,t as SettingsDefaultReset,d as SettingsDrill,n as SettingsGroupHead,i as SettingsGroupSub,u as SettingsPlacement};
@@ -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-D7M6IRPJ.js";import"../../chunk-HQ4VVRIC.js";import"../../chunk-5464H65G.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";