efficient-easel 0.103.0 → 0.105.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 +92 -7
- package/dist/CanvasDragLayer-zgYT1xwY.d.ts +168 -0
- package/dist/chrome/index.js +1 -1
- package/dist/chunk-3P6AMTOS.js +1 -0
- package/dist/chunk-4XQUWGIV.js +65 -0
- package/dist/{chunk-6UJ3Y6FC.js → chunk-53G47SWO.js} +1 -1
- package/dist/{chunk-IWAPPEL4.js → chunk-5ZBBXZPV.js} +1 -1
- package/dist/chunk-7FBDZTUD.js +2 -0
- package/dist/chunk-7V5WZ46F.js +2 -0
- package/dist/chunk-BVN33R76.js +1 -0
- package/dist/chunk-CLOS6SSX.js +1 -0
- package/dist/chunk-ERR437B5.js +1 -0
- package/dist/chunk-GMCZXMOV.js +1 -0
- package/dist/{chunk-OYX47SL7.js → chunk-HNKB2ZYR.js} +1 -1
- package/dist/{chunk-AKFJK65Z.js → chunk-IE4GFYKO.js} +1 -1
- package/dist/{chunk-KDYIMJTZ.js → chunk-KCOBHPN6.js} +1 -1
- package/dist/chunk-KG7RJWOK.js +1 -0
- package/dist/chunk-N7VRF7PR.js +5 -0
- package/dist/chunk-NYKIQJT2.js +4 -0
- package/dist/{chunk-6TZTKAB5.js → chunk-O7Q4DDJT.js} +1 -1
- package/dist/chunk-PA3PNTVV.js +1 -0
- package/dist/chunk-PLVEGYK6.js +1 -0
- package/dist/chunk-PQXIFBDY.js +1 -0
- package/dist/{chunk-66ICOE3I.js → chunk-QH6LCNOX.js} +1 -1
- package/dist/chunk-R6WTQWAC.js +2 -0
- package/dist/{chunk-Z3KBLIEH.js → chunk-RQHC4TD6.js} +3 -3
- package/dist/chunk-RSCMJIWS.js +1 -0
- package/dist/{chunk-7MU3RJ6S.js → chunk-S4AWJX4Q.js} +1 -1
- package/dist/{chunk-MSBF7IW3.js → chunk-SARZN4M7.js} +2 -2
- package/dist/chunk-SQTY6CJD.js +1 -0
- package/dist/chunk-TBF5CVPA.js +1 -0
- package/dist/chunk-THWO5YVZ.js +1 -0
- package/dist/chunk-TLZG2FCF.js +1 -0
- package/dist/chunk-U3JP4VGF.js +2 -0
- package/dist/{chunk-LG436UTD.js → chunk-V4LF7D4F.js} +1 -1
- package/dist/chunk-VSHV6KJQ.js +5 -0
- package/dist/{chunk-OM67AJQC.js → chunk-VSOP4GUM.js} +1 -1
- package/dist/{chunk-6DJHRLCU.js → chunk-YC4TB3CJ.js} +9 -9
- package/dist/{chunk-GXN65JMA.js → chunk-YN4KND5F.js} +1 -1
- package/dist/chunk-ZTTWFAAC.js +1 -0
- package/dist/drag/index.d.ts +4 -164
- package/dist/edit-lock/index.d.ts +55 -1
- package/dist/edit-lock/index.js +1 -1
- package/dist/{host-DJ8Gzsx7.d.ts → host-BQ_b9Qzk.d.ts} +27 -1
- package/dist/screen/components/AddBlockRow.js +1 -1
- package/dist/screen/components/AddSidePanel.js +1 -1
- package/dist/screen/components/MediaSidePanel.d.ts +3 -2
- package/dist/screen/components/MediaSidePanel.js +1 -1
- package/dist/screen/components/NodeContextMenu.d.ts +208 -5
- package/dist/screen/components/NodeContextMenu.js +1 -1
- package/dist/screen/components/PageEditGuardNotices.js +1 -1
- package/dist/screen/components/ScreenChrome.js +1 -1
- package/dist/screen/components/ScreenDocumentContext.d.ts +2 -1
- package/dist/screen/components/ScreenDocumentContext.js +1 -1
- package/dist/screen/components/ScreenMount.d.ts +14 -3
- package/dist/screen/components/ScreenMount.js +1 -1
- package/dist/screen/components/ScreenStoreProvider.d.ts +20 -5
- package/dist/screen/components/ScreenStoreProvider.js +1 -1
- package/dist/screen/components/SectionScreenShell.js +16 -16
- package/dist/screen/components/SidePanelHead.js +1 -1
- package/dist/screen/components/panel-widths.js +1 -1
- package/dist/screen/components/usePartBridge.d.ts +20 -5
- package/dist/screen/components/usePartBridge.js +1 -1
- package/dist/screen/index.d.ts +17 -6
- package/dist/screen/index.js +1 -1
- package/dist/screen/lib/admin-bridge.d.ts +2 -0
- package/dist/screen/lib/admin-bridge.js +1 -1
- package/dist/screen/lib/backend-error.d.ts +20 -5
- package/dist/screen/lib/backend-error.js +1 -1
- package/dist/screen/lib/document-addressing.d.ts +2 -1
- package/dist/screen/lib/document-switch.js +1 -1
- package/dist/screen/lib/failure.d.ts +6 -2
- package/dist/screen/lib/failure.js +1 -1
- package/dist/screen/lib/host-inbound.js +1 -1
- package/dist/screen/lib/host.d.ts +3 -2
- package/dist/screen/lib/host.js +1 -1
- package/dist/screen/lib/key-scope.js +1 -1
- package/dist/screen/lib/load-error.d.ts +9 -3
- package/dist/screen/lib/load-error.js +1 -1
- package/dist/screen/lib/media-panel.d.ts +81 -17
- package/dist/screen/lib/media-panel.js +1 -1
- package/dist/screen/lib/media-picker.d.ts +14 -2
- package/dist/screen/lib/media-picker.js +1 -1
- package/dist/screen/lib/page-lock.d.ts +45 -1
- package/dist/screen/lib/page-lock.js +1 -1
- package/dist/screen/lib/puck/content-tree.d.ts +27 -1
- package/dist/screen/lib/puck/content-tree.js +1 -1
- package/dist/screen/lib/puck/palette-sections.d.ts +7 -0
- package/dist/screen/lib/puck/palette-sections.js +1 -1
- package/dist/screen/lib/puck/section-doc.js +1 -1
- package/dist/screen/lib/puck/slot-child-name.d.ts +42 -3
- package/dist/screen/lib/puck/slot-child-name.js +1 -1
- package/dist/screen/lib/puck/style-clipboard.d.ts +53 -1
- package/dist/screen/lib/puck/style-clipboard.js +1 -1
- package/dist/screen/lib/puck/use-section-ops.d.ts +6 -0
- package/dist/screen/lib/puck/use-section-ops.js +1 -1
- package/dist/screen/lib/screen-parts.d.ts +619 -10
- package/dist/screen/lib/screen-parts.js +1 -1
- package/dist/screen/lib/section-templates.d.ts +25 -1
- package/dist/screen/lib/section-templates.js +1 -1
- package/dist/screen/lib/session-context.d.ts +5 -1
- package/dist/screen/lib/session-context.js +1 -1
- package/dist/screen/lib/session.d.ts +58 -5
- package/dist/screen/lib/session.js +1 -1
- package/dist/screen/screen.css +18 -0
- package/dist/screen/words.d.ts +96 -2
- package/dist/screen/words.js +1 -1
- package/dist/strings/catalogue.d.ts +4 -2
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +1 -1
- package/dist/strings/index.js +1 -1
- package/dist/tree/index.d.ts +4 -142
- package/dist/types-DJDBtdB2.d.ts +143 -0
- package/package.json +1 -1
- package/dist/chunk-3M3A3DN2.js +0 -4
- package/dist/chunk-4MXFKJUY.js +0 -1
- package/dist/chunk-6FY3PZS3.js +0 -1
- package/dist/chunk-A7ZJII7O.js +0 -1
- package/dist/chunk-AJBJ74ME.js +0 -1
- package/dist/chunk-AKZWUV5Z.js +0 -1
- package/dist/chunk-F6CCTEIX.js +0 -1
- package/dist/chunk-FUDHI5I4.js +0 -1
- package/dist/chunk-GENAF3P6.js +0 -1
- package/dist/chunk-HDKTR5TZ.js +0 -62
- package/dist/chunk-HMX55DYT.js +0 -1
- package/dist/chunk-HWW4XJOH.js +0 -1
- package/dist/chunk-JUQ6YJCG.js +0 -1
- package/dist/chunk-NBJ2YY6Y.js +0 -4
- package/dist/chunk-OORDMLL4.js +0 -5
- package/dist/chunk-Q2HPBMG5.js +0 -1
- package/dist/chunk-Q3SQBNJB.js +0 -1
- package/dist/chunk-R5ZVNJLJ.js +0 -2
- package/dist/chunk-SERF2FAU.js +0 -1
- package/dist/chunk-VV5ADNBR.js +0 -1
- package/dist/chunk-YJXEHK6I.js +0 -2
- package/dist/chunk-ZWK3CBRU.js +0 -1
- package/dist/chunk-ZZ7VLIHQ.js +0 -1
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, MouseEvent, ComponentType } from 'react';
|
|
3
3
|
import { Data } from '../../blocks/index.js';
|
|
4
|
+
import { C as CanvasTarget } from '../../watch-BTYOJpQU.js';
|
|
4
5
|
import { D as DeviceOption } from '../../types-CqY85foL.js';
|
|
6
|
+
import { P as Place } from '../../types-41704JE4.js';
|
|
7
|
+
import { M as MeasuredCanvas, C as CanvasDragModel } from '../../CanvasDragLayer-zgYT1xwY.js';
|
|
8
|
+
import { E as EaselContextMenuItem } from '../../types-Djdq6Xkd.js';
|
|
5
9
|
import { a as EaselRailItem } from '../../types-DWS-s9z-.js';
|
|
10
|
+
import { StyleRow } from '../../style-clipboard/index.js';
|
|
11
|
+
import { T as TreeRowMark } from '../../types-DJDBtdB2.js';
|
|
12
|
+
import { AddKey } from '../components/AddSidePanel.js';
|
|
13
|
+
import { k as AnyScreenTarget } from '../../host-BQ_b9Qzk.js';
|
|
6
14
|
import { HostProduct } from './host-chrome.js';
|
|
7
15
|
import { EaselSession } from './session.js';
|
|
8
16
|
import { AddTarget } from './puck/add-target-types.js';
|
|
17
|
+
import { SlotConfigView } from './puck/content-tree.js';
|
|
9
18
|
import '../../types-E3HrTPg2.js';
|
|
10
19
|
import '../../data/index.js';
|
|
11
|
-
import '../../types-41704JE4.js';
|
|
12
20
|
import '../../resolve-D68pb3Bx.js';
|
|
13
21
|
import '../../plan-DChbUXdS.js';
|
|
14
22
|
import '../../edit-lock/index.js';
|
|
15
23
|
import '../../panelWidths-D9hTLR25.js';
|
|
24
|
+
import '../../session-DSQFmIvx.js';
|
|
25
|
+
import '../../words-BDignMl_.js';
|
|
16
26
|
import '../../wordFit-D4S36PvB.js';
|
|
27
|
+
import '../../words-CnnHb9jo.js';
|
|
28
|
+
import '../../words-DgHcY5qB.js';
|
|
29
|
+
import './section-template-types.js';
|
|
30
|
+
import './puck/block-choice.js';
|
|
31
|
+
import './document-contract.js';
|
|
32
|
+
import './document-switch.js';
|
|
33
|
+
import '../../engine-DBxp_v6B.js';
|
|
34
|
+
import './admin-bridge.js';
|
|
35
|
+
import './backend-error.js';
|
|
17
36
|
import './links/link-filters.js';
|
|
18
37
|
import '../../LinkPicker-W2Rtxetz.js';
|
|
19
|
-
import './document-contract.js';
|
|
20
38
|
import './document-hooks.js';
|
|
21
|
-
import './section-template-types.js';
|
|
22
|
-
import './puck/content-tree.js';
|
|
23
|
-
import './puck/block-choice.js';
|
|
24
39
|
import './puck/slot-section-spec.js';
|
|
25
40
|
|
|
26
41
|
/**
|
|
@@ -92,6 +107,28 @@ type ScreenPartMode = {
|
|
|
92
107
|
* member by member, so the screen can answer without knowing what a layer
|
|
93
108
|
* keeps beside the kind. */
|
|
94
109
|
declare function sameInspectorMode(a: ScreenInspectorMode, b: ScreenInspectorMode): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* A SLOT's own panel (0.105.0): the mode the screen opens when the row of a
|
|
112
|
+
* slot it draws as a rung is pressed (`ScreenSlot.panel`) — the campaign
|
|
113
|
+
* designer's Column inspector. `kind` is the layer's (`panel`), and beside it
|
|
114
|
+
* the node the slot is a slot of and the slot's own name. The screen makes it
|
|
115
|
+
* and hands it back to the layer's inspector; a layer may name one itself to
|
|
116
|
+
* `ScreenInspector.select`.
|
|
117
|
+
*/
|
|
118
|
+
interface ScreenSlotMode extends ScreenInspectorMode {
|
|
119
|
+
nodeId: string;
|
|
120
|
+
slot: string;
|
|
121
|
+
}
|
|
122
|
+
/** Is a panel a slot's own ({@link ScreenSlotMode}) — about a node's slot, not
|
|
123
|
+
* the node? */
|
|
124
|
+
declare function isSlotMode(mode: ScreenInspectorMode): mode is ScreenSlotMode;
|
|
125
|
+
/** An address of a node the screen selects, as its own ops spell one: its
|
|
126
|
+
* index, in the list `zone` names (left out for the top-level list); or null,
|
|
127
|
+
* for nothing selected. */
|
|
128
|
+
type ScreenSelector = {
|
|
129
|
+
index: number;
|
|
130
|
+
zone?: string;
|
|
131
|
+
} | null;
|
|
95
132
|
/** The inspector, as far as a layer needs it: which panel it shows, and how to
|
|
96
133
|
* show one of the layer's own. */
|
|
97
134
|
interface ScreenInspector {
|
|
@@ -113,6 +150,18 @@ interface ScreenInspector {
|
|
|
113
150
|
show: (mode: ScreenInspectorMode) => void;
|
|
114
151
|
/** Bring the inspector into view if it is hidden. What it shows stays. */
|
|
115
152
|
reveal: () => void;
|
|
153
|
+
/**
|
|
154
|
+
* Move the selection AND put a panel of the layer's own in the inspector, in
|
|
155
|
+
* one step (0.105.0): what the campaign designer's Column needs, which is a
|
|
156
|
+
* slot and not a node — nothing is selected (`null`) and the Column
|
|
157
|
+
* inspector shows. `show` then a selection would not hold: the screen puts
|
|
158
|
+
* the inspector back to the selection's own panel whenever the selection
|
|
159
|
+
* changes, so the mode is kept pending and that reset honours it for this
|
|
160
|
+
* one change. The inspector is left as it stands, in view or hidden, as
|
|
161
|
+
* `show` leaves it. A slot's own panel ({@link ScreenSlotMode}) for a slot
|
|
162
|
+
* the tree draws as a rung also unfolds the tree to that rung's row.
|
|
163
|
+
*/
|
|
164
|
+
select: (selector: ScreenSelector, mode: ScreenInspectorMode) => void;
|
|
116
165
|
}
|
|
117
166
|
/**
|
|
118
167
|
* What the screen hands THE INSPECTOR it mounts in its right panel
|
|
@@ -143,6 +192,23 @@ interface ScreenInspectorPanelProps {
|
|
|
143
192
|
/** Hide the panel: the last button of its head. Omitted by a screen whose
|
|
144
193
|
* inspector is always in view. */
|
|
145
194
|
onHidePanel?: () => void;
|
|
195
|
+
/**
|
|
196
|
+
* Which of the head's two node actions the selected node's BLOCK allows
|
|
197
|
+
* (0.103.0): its config's `permissions.duplicate` and `permissions.delete`,
|
|
198
|
+
* each true unless the config says false — the answer the screen's own tree
|
|
199
|
+
* rows and menu honour, handed on so the head the layer draws honours it
|
|
200
|
+
* too, hiding or greying a refused one. With nothing selected both are true.
|
|
201
|
+
* Handed by the page screen; a layer that never reads it draws its head as
|
|
202
|
+
* it did.
|
|
203
|
+
*/
|
|
204
|
+
nodeActions?: ScreenNodeActions;
|
|
205
|
+
}
|
|
206
|
+
/** What a block's config allows of the two actions that make another node or
|
|
207
|
+
* take one away (`ComponentConfig.permissions`): `false` only where the config
|
|
208
|
+
* says so (lib/puck/content-tree `blockNodeActions`). */
|
|
209
|
+
interface ScreenNodeActions {
|
|
210
|
+
duplicate: boolean;
|
|
211
|
+
delete: boolean;
|
|
146
212
|
}
|
|
147
213
|
/**
|
|
148
214
|
* The document and its tree of rows, as far as a layer needs them to wire and
|
|
@@ -374,10 +440,26 @@ interface ScreenBridges {
|
|
|
374
440
|
* scroll; absent, the screen scrolls.
|
|
375
441
|
*/
|
|
376
442
|
holdCanvasOn?: (id: string) => void;
|
|
443
|
+
/**
|
|
444
|
+
* THE LAYER'S OWN ROWS IN A NODE'S RIGHT-CLICK MENU (0.105.0), by the group
|
|
445
|
+
* each joins (`ScreenMenuRows`): the campaign designer's "Check this image
|
|
446
|
+
* loads" and its phone rows. Asked of the node the menu was opened on, and
|
|
447
|
+
* where it sits, every time the menu is drawn; what comes back is placed at
|
|
448
|
+
* the end of its group, after the screen's own rows, as it is handed — a row
|
|
449
|
+
* that writes runs a component or an op of the layer's that reaches the
|
|
450
|
+
* document itself. Nothing handed back adds nothing. Absent: the screen's
|
|
451
|
+
* rows alone, as the menu has always drawn them.
|
|
452
|
+
*/
|
|
453
|
+
menuRows?: (node: ScreenNode, zone: string, index: number) => ScreenMenuRows | null | undefined;
|
|
377
454
|
/** The layer's own context, stood round the whole screen. What it is handed
|
|
378
455
|
* is the screen; what it returns is rendered in the screen's place. */
|
|
379
456
|
wrap?: (screen: ReactNode) => ReactNode;
|
|
380
457
|
}
|
|
458
|
+
/** A layer's own rows in a node's menu, by the group of the menu each goes at
|
|
459
|
+
* the end of (efficient-easel/node-ops `nodeMenuItems`' `extras`): `pick`
|
|
460
|
+
* (Select layer), `make` (Duplicate … Paste), `change` (Rename, Hide …) and
|
|
461
|
+
* `remove` (Delete). */
|
|
462
|
+
type ScreenMenuRows = Partial<Record<"pick" | "make" | "change" | "remove", EaselContextMenuItem[]>>;
|
|
381
463
|
/** A block type's own default props, read off the config the screen holds.
|
|
382
464
|
* The screen's to look up and a layer's to be lent: a layer that reached into
|
|
383
465
|
* the config for itself would be holding a second copy of it. */
|
|
@@ -442,15 +524,126 @@ interface ScreenBlockRules {
|
|
|
442
524
|
* tree, the panel, the menu, the Add panel), so no two of them can come to
|
|
443
525
|
* offer one node different lists; what each of the layer's blocks takes is
|
|
444
526
|
* the layer's catalogue, and the screen is not told it.
|
|
527
|
+
*
|
|
528
|
+
* `slot` (0.105.0) is asked where the screen means ONE slot of a node that
|
|
529
|
+
* has several: a gap or an empty slot in the tree, a slot place Add was
|
|
530
|
+
* opened at, a drop into a slot. The answer is that slot's (the campaign
|
|
531
|
+
* designer's Column 2 answers `col2`); a layer that keeps one slot per node
|
|
532
|
+
* may ignore it, and the screen then offers that slot alone, as before.
|
|
533
|
+
*/
|
|
534
|
+
canAddTo: (nodeType: string, nestDepth?: number, slot?: string) => AddTarget | null;
|
|
535
|
+
/**
|
|
536
|
+
* THE SLOTS OF A NODE, IN ORDER, AS THE SCREEN DRAWS THEM (0.105.0). A slot
|
|
537
|
+
* that is a `rung` is a row of its own in the Layers tree, with its children
|
|
538
|
+
* under it, a level of the Select layer flyout and a place of its own in a
|
|
539
|
+
* drag: the campaign designer's section draws Column 1 and Column 2 so from
|
|
540
|
+
* two columns up, and its lone column not at all. Every other slot's children
|
|
541
|
+
* hang straight off the node's row, as they do today. A slot left out of the
|
|
542
|
+
* answer is not drawn (a column the section's layout hides). The tree, the
|
|
543
|
+
* Add panel's "Adding to …", the drag and the flyout read it; where a node's
|
|
544
|
+
* children are FOUND (the menu, a write, a drop's checks) is still every
|
|
545
|
+
* slot field.
|
|
546
|
+
*
|
|
547
|
+
* Answered for every node the tree draws; null or undefined for one is the
|
|
548
|
+
* screen's own reading of it, so a layer may answer for its sections alone.
|
|
549
|
+
* Absent: every slot field the config declares, in its order, none of them a
|
|
550
|
+
* rung — the tree the website has.
|
|
551
|
+
*/
|
|
552
|
+
slotsOf?: (node: ScreenNode) => ReadonlyArray<ScreenSlot> | null | undefined;
|
|
553
|
+
/**
|
|
554
|
+
* A RUNG MOVED (0.105.0): the rung at `from` in the node's run of rungs (its
|
|
555
|
+
* place among `slotsOf`'s rungs) dropped so it rests at `to` — a drag in the
|
|
556
|
+
* tree, or ⌥↑ / ⌥↓ on its row. The layer writes the move (the campaign
|
|
557
|
+
* designer swaps two columns' blocks, or reorders the phone stack) and may
|
|
558
|
+
* answer the slot to select after it, which the screen selects as a press
|
|
559
|
+
* on that rung's row does. Absent: no rung is picked up.
|
|
560
|
+
*/
|
|
561
|
+
moveSlot?: (nodeId: string, from: number, to: number) => string | null | void;
|
|
562
|
+
/**
|
|
563
|
+
* What a rung's row offers besides its fold (0.105.0): the campaign
|
|
564
|
+
* designer's Duplicate and Delete of a column, drawn in the order handed,
|
|
565
|
+
* among the row's actions. The screen confirms nothing: what a press asks
|
|
566
|
+
* first (Delete a column that still holds blocks) is the layer's `run`.
|
|
567
|
+
* Withheld while the document is read-only. Absent, or nothing handed: the
|
|
568
|
+
* row has none.
|
|
445
569
|
*/
|
|
446
|
-
|
|
570
|
+
slotActions?: (node: ScreenNode, slot: string) => ReadonlyArray<ScreenSlotAction> | null | undefined;
|
|
447
571
|
/**
|
|
448
572
|
* Does the host of this editor offer the type? Asked of the editor's own
|
|
449
573
|
* session where the screen holds it, else of the editor on the page. Where
|
|
450
574
|
* no host chose its blocks, every type is.
|
|
451
575
|
*/
|
|
452
576
|
blockIsOffered: (type: string, session?: EaselSession) => boolean;
|
|
577
|
+
/**
|
|
578
|
+
* Is a new block RESOLVED as it goes in (0.103.0)? With true, every insert
|
|
579
|
+
* the screen makes — a section, a block into a slot, a saved template, a
|
|
580
|
+
* seeded slot child — is followed by `easel.resolveNode(id, { trigger:
|
|
581
|
+
* 'insert' })`, as the campaign designer's own inserts are: the block's
|
|
582
|
+
* `resolveData` runs the moment it arrives (seeding its children, stamping a
|
|
583
|
+
* default), in the insert's own undo step, not at its first edit or the next
|
|
584
|
+
* time the document opens. Absent, false: an insert runs no resolver, as
|
|
585
|
+
* the website's never has.
|
|
586
|
+
*/
|
|
587
|
+
resolveOnInsert?: boolean;
|
|
453
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* ONE SLOT OF A NODE, as the screen draws it (`ScreenBlockRules.slotsOf`,
|
|
591
|
+
* 0.105.0). Only `slot` and `rung` are read of a slot that is not a rung.
|
|
592
|
+
*/
|
|
593
|
+
interface ScreenSlot {
|
|
594
|
+
/** The slot field's name (`col2`): its children are `props[slot]`, its list
|
|
595
|
+
* is `${nodeId}:${slot}`. */
|
|
596
|
+
slot: string;
|
|
597
|
+
/** What the rung's row says ("Column 2"), and the flyout, and Add's
|
|
598
|
+
* "Adding to …". */
|
|
599
|
+
label: string;
|
|
600
|
+
/** The rung's glyph, drawn as handed. Absent: none. */
|
|
601
|
+
glyph?: ReactNode;
|
|
602
|
+
/** Drawn as a row of its own, its children under it. False: its children
|
|
603
|
+
* hang straight off the node's row. */
|
|
604
|
+
rung: boolean;
|
|
605
|
+
/**
|
|
606
|
+
* The kind of the layer's panel this rung is edited in (the Column
|
|
607
|
+
* inspector): a press on its row selects nothing and shows that panel, as a
|
|
608
|
+
* {@link ScreenSlotMode} naming the node and the slot, and the row is lit
|
|
609
|
+
* while it shows; the flyout lists it as a level. Absent: the rung only
|
|
610
|
+
* folds, its press selects the node it is a slot of, and the flyout leaves
|
|
611
|
+
* it out.
|
|
612
|
+
*/
|
|
613
|
+
panel?: string;
|
|
614
|
+
/** A pill after the name ("2 of 3", the phone stack's place). */
|
|
615
|
+
badge?: ReactNode;
|
|
616
|
+
/** The hint the row shows when it may be dragged. Absent: the tree's own. */
|
|
617
|
+
dragHint?: string;
|
|
618
|
+
/** Drawn above the rung's row, as handed: the campaign designer's "Phone
|
|
619
|
+
* order" label over its first column. */
|
|
620
|
+
heading?: ReactNode;
|
|
621
|
+
/** False: the rung keeps its place, and is not picked up (a pinned
|
|
622
|
+
* section's columns). Absent: it moves where `moveSlot` is handed. */
|
|
623
|
+
movable?: boolean;
|
|
624
|
+
}
|
|
625
|
+
/** What a rung's row offers (`ScreenBlockRules.slotActions`, 0.105.0). */
|
|
626
|
+
interface ScreenSlotAction {
|
|
627
|
+
/** Which action: the screen draws its glyph, and the delete in its red. */
|
|
628
|
+
kind: "duplicate" | "delete";
|
|
629
|
+
/** Its tooltip and accessible name: "Duplicate Column 2", or why not. */
|
|
630
|
+
label: string;
|
|
631
|
+
/** Drawn, and not pressed: the label says why. */
|
|
632
|
+
disabled?: boolean;
|
|
633
|
+
/**
|
|
634
|
+
* The action, the layer's whole: it asks what it must ask first and writes.
|
|
635
|
+
* It may answer the slot to select after it (the copy, the column that took
|
|
636
|
+
* a deleted one's place), which the screen selects as a press on that rung's
|
|
637
|
+
* row does; nothing, and the selection stays.
|
|
638
|
+
*/
|
|
639
|
+
run: () => string | null | void | Promise<string | null | void>;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* The slots of `node` as the screen draws them: the layer's answer
|
|
643
|
+
* (`slotsOf`), else — with no `slotsOf`, or none for this node — every slot
|
|
644
|
+
* field the config declares, in its order, none of them a rung.
|
|
645
|
+
*/
|
|
646
|
+
declare function screenSlotsOf(rules: ScreenBlockRules, config: SlotConfigView, node: ScreenNode): ReadonlyArray<ScreenSlot>;
|
|
454
647
|
/** The tier a node is NAMED at: a node at the top of the document is a section,
|
|
455
648
|
* a node inside another is a block. */
|
|
456
649
|
type ScreenNodeLevel = "section" | "block";
|
|
@@ -516,6 +709,56 @@ interface ScreenBlockLook {
|
|
|
516
709
|
* the screen read the products itself, so its effect keeps its place.
|
|
517
710
|
*/
|
|
518
711
|
useProducts: () => readonly HostProduct[] | null;
|
|
712
|
+
/**
|
|
713
|
+
* THE LAYER'S LAST WORD ON WHAT A LAYERS ROW SAYS (0.103.0): handed a node,
|
|
714
|
+
* the level it is named at and `fallback` — what the screen's own naming
|
|
715
|
+
* rule answered (lib/puck/slot-child-name: a name the node carries, else its
|
|
716
|
+
* type's label; a pinned row's word) — it answers the row's name. Asked of
|
|
717
|
+
* every node row the page screen's Layers tree draws, and of the menu's
|
|
718
|
+
* Select layer flyout, a block's canvas handle and a section's own list of
|
|
719
|
+
* its children in the inspector, which say the same words. The campaign
|
|
720
|
+
* designer's rows read its own labels ("Section 2", "Header"). Absent: the
|
|
721
|
+
* screen's rule, as it named every row.
|
|
722
|
+
*/
|
|
723
|
+
rowName?: (node: ScreenNode, level: ScreenNodeLevel, fallback: string) => string;
|
|
724
|
+
/**
|
|
725
|
+
* THE PROP A RENAME WRITES, by the layer (0.105.0; owner ruling R11, Victor
|
|
726
|
+
* Mau, 2026-10-09: Rename works on top-level sections in both editors). The
|
|
727
|
+
* write side of `rowName`: handed a node, the level it is named at and
|
|
728
|
+
* `base` — what the screen's own rule answered (lib/puck/slot-child-name
|
|
729
|
+
* `slotChildRenameProp` for a block, `sectionRenameProp` for a section) — it
|
|
730
|
+
* answers the prop the Layers row's rename box writes, or null for a node
|
|
731
|
+
* that has no name of its own, which takes Rename out of its menu. Answer the
|
|
732
|
+
* prop `rowName` reads, so a renamed row says its new name: the campaign
|
|
733
|
+
* designer's sections are named by their `label` ("Section name"). Asked of
|
|
734
|
+
* every node the menu opens on, a pinned node and a section group's too.
|
|
735
|
+
* Absent: the screen's rule — a block's declared name, and a section's
|
|
736
|
+
* `name`, which its row reads.
|
|
737
|
+
*/
|
|
738
|
+
renamePropOf?: (node: ScreenNode, level: ScreenNodeLevel, base: string | null) => string | null;
|
|
739
|
+
/**
|
|
740
|
+
* The quieter words a node row draws after its name (`TreeRow`'s
|
|
741
|
+
* `preview`): a node's own first words, so a tree of rows all called
|
|
742
|
+
* "Section" can be told apart by eye. The layer chooses and shortens them;
|
|
743
|
+
* nothing (null, undefined, "") draws nothing. Absent: no row has any.
|
|
744
|
+
*/
|
|
745
|
+
rowPreview?: (node: ScreenNode) => string | null | undefined;
|
|
746
|
+
/**
|
|
747
|
+
* The small marks a node row draws right after its name (`TreeRow`'s
|
|
748
|
+
* `marks`): a state the row only SHOWS, such as "Shown on phones only".
|
|
749
|
+
* Absent, or nothing handed back: no marks.
|
|
750
|
+
*/
|
|
751
|
+
rowMarks?: (node: ScreenNode) => ReadonlyArray<TreeRowMark> | null | undefined;
|
|
752
|
+
/**
|
|
753
|
+
* The layer's own buttons on a node row, by the node and where it sits:
|
|
754
|
+
* `TreeRowAction`s (efficient-easel/tree), placed between the screen's trash
|
|
755
|
+
* and its eye — the campaign designer's phone switch. Asked of every node
|
|
756
|
+
* row, a locked one and a pinned one too, so the layer decides; what comes
|
|
757
|
+
* back is placed as it is, and nothing draws nothing. A button that writes
|
|
758
|
+
* renders a component of the layer's that reaches the document itself.
|
|
759
|
+
* Absent: the screen's two, as it drew them.
|
|
760
|
+
*/
|
|
761
|
+
rowActions?: (node: ScreenNode, zone: string, index: number) => ReactNode;
|
|
519
762
|
}
|
|
520
763
|
/**
|
|
521
764
|
* THE DEVICES the canvas can be looked at on. That the top bar has a switch,
|
|
@@ -543,6 +786,116 @@ interface ScreenDevices {
|
|
|
543
786
|
/** The width each device is drawn at, in CSS px, by id. For `fluid` it is
|
|
544
787
|
* only the width of the frame before the pane has been measured. */
|
|
545
788
|
widths: Readonly<Record<string, number>>;
|
|
789
|
+
/**
|
|
790
|
+
* How a fixed device is fitted to the pane (0.105.0). `"fill"`: scaled to
|
|
791
|
+
* the pane's width, up to twice its size, so a phone reads big and clear in
|
|
792
|
+
* a wide pane — the website's view tiers. `"shrink"`: scaled DOWN when the
|
|
793
|
+
* pane is narrower than the device and never up, so a device is drawn at its
|
|
794
|
+
* real size or smaller — the campaign designer's phone, a mail preview of
|
|
795
|
+
* the width the recipient's phone has. The fluid device is drawn at the
|
|
796
|
+
* pane's width either way. Absent: `"fill"`.
|
|
797
|
+
*/
|
|
798
|
+
fit?: "fill" | "shrink";
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* WHAT A DRAG ON THE PAGE SCREEN CARRIES (0.105.0): a node of the document —
|
|
802
|
+
* its id, the list it sits in (a zone key, `<parentId>:<slot>`), its index
|
|
803
|
+
* there and its type — or, with `add`, a NEW one from the Add panel, which
|
|
804
|
+
* has no place yet. One kind of thing for the ONE drag the Layers tree, the
|
|
805
|
+
* canvas and the Add panel share, so a block picked up on one lands on
|
|
806
|
+
* another. A layer's own canvas sources (`ScreenCanvasDrag.model`) carry it
|
|
807
|
+
* too; a thing of the layer's that is not a node (the campaign designer's
|
|
808
|
+
* column) is told apart by a `zone` and a `type` of the layer's own — a list
|
|
809
|
+
* the document has none of, so the screen's writes find no node there and
|
|
810
|
+
* do nothing, and the Layers tree, which draws no gap in it, takes none. A
|
|
811
|
+
* layer that offers one answers for it on the canvas (`canDrop`, `drop`,
|
|
812
|
+
* `pick`).
|
|
813
|
+
*/
|
|
814
|
+
interface ScreenDragItem {
|
|
815
|
+
id: string;
|
|
816
|
+
zone: string;
|
|
817
|
+
index: number;
|
|
818
|
+
type: string;
|
|
819
|
+
add?: AddKey;
|
|
820
|
+
/** A slot the Layers tree draws as a row of its own (`slotsOf`, a rung),
|
|
821
|
+
* picked up by its row: `index` is its place in its node's run of rungs. */
|
|
822
|
+
rung?: {
|
|
823
|
+
nodeId: string;
|
|
824
|
+
slot: string;
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* What the screen tells a layer's canvas drag each time it asks
|
|
829
|
+
* (`ScreenCanvasDrag`, 0.105.0). Its rules are plain functions, the same for
|
|
830
|
+
* the life of the mount like the block rules, so what they reason about is
|
|
831
|
+
* handed to them: the document as it stands, the device the canvas is drawn
|
|
832
|
+
* as, and — for a drop or a pick that does what the screen's own would not —
|
|
833
|
+
* the screen's writes and its inspector.
|
|
834
|
+
*/
|
|
835
|
+
interface ScreenCanvasDragContext {
|
|
836
|
+
/** The working document (`{ root, content, zones }`), as the store holds it
|
|
837
|
+
* now: what the measure and the model are of. */
|
|
838
|
+
data: unknown;
|
|
839
|
+
/** The device the canvas is drawn as, one of the layer's own
|
|
840
|
+
* (`ScreenDevices.options`): a phone may stack what a desktop lays across. */
|
|
841
|
+
device: string;
|
|
842
|
+
/** The screen's writes (`ScreenDocumentOps`, refused while somebody else
|
|
843
|
+
* holds the document), for a drop of the layer's own. */
|
|
844
|
+
ops: ScreenDocumentOps;
|
|
845
|
+
/** The inspector, for a drop or a pick that opens a panel of the layer's
|
|
846
|
+
* own on what it moved or named (a column's). */
|
|
847
|
+
inspector: ScreenInspector;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* THE CANVAS DRAG, AS A LAYER HAS IT (`ScreenParts.canvasDrag`, 0.105.0).
|
|
851
|
+
* That there is a drag on the canvas — the handle on the smallest box under
|
|
852
|
+
* the pointer, the one drop line, the catch surface, the session it shares
|
|
853
|
+
* with the Layers tree and the Add panel — is the screen's
|
|
854
|
+
* (efficient-easel/drag `CanvasDragLayer`). How the canvas is MEASURED, what
|
|
855
|
+
* may be picked up on it and what may land where on it may be the layer's: an
|
|
856
|
+
* email lays its sections out in columns, measured from cells of its own, and
|
|
857
|
+
* a column is grabbed by a strip down its edge that is the column's and not its
|
|
858
|
+
* blocks'.
|
|
859
|
+
*
|
|
860
|
+
* Each member is optional and falls back on the screen's own; each is handed
|
|
861
|
+
* the screen's own answer (`base`) as well, so a layer may add to it, narrow it
|
|
862
|
+
* or answer only for what is its own and leave the rest to the screen. They
|
|
863
|
+
* answer for the canvas only: a drop on the Layers tree is the tree's rules',
|
|
864
|
+
* whatever surface the thing was picked up on.
|
|
865
|
+
*
|
|
866
|
+
* Plain functions, the same object for the life of the mount, like the block
|
|
867
|
+
* rules; what they reason about is handed to them (`ScreenCanvasDragContext`).
|
|
868
|
+
*/
|
|
869
|
+
interface ScreenCanvasDrag {
|
|
870
|
+
/** How the canvas is measured into boxes, in the coordinates of `layer`
|
|
871
|
+
* (the element the drag layer draws in). Absent: Puck's markers, the slots
|
|
872
|
+
* and the blocks directly in them (efficient-easel/drag `measureCanvas`). */
|
|
873
|
+
measure?: (canvas: CanvasTarget, layer: Element, context: ScreenCanvasDragContext) => MeasuredCanvas;
|
|
874
|
+
/**
|
|
875
|
+
* What may be picked up on what was measured, and which lists take drops,
|
|
876
|
+
* handed the screen's own model of it (`base`: every node but the pinned
|
|
877
|
+
* ones — asked through `isPinnedFirst` / `isPinnedLast` — a locked block, a
|
|
878
|
+
* group of sections, and a section with nothing to trade places with). It
|
|
879
|
+
* is asked of an EMPTY measure too, before the frame is first measured.
|
|
880
|
+
* Absent: `base`.
|
|
881
|
+
*/
|
|
882
|
+
model?: (measured: MeasuredCanvas, base: CanvasDragModel<ScreenDragItem>, context: ScreenCanvasDragContext) => CanvasDragModel<ScreenDragItem>;
|
|
883
|
+
/** May the thing in hand land at `to` on the canvas? Handed the screen's
|
|
884
|
+
* own rule (`base`, the Layers tree's). Absent: `base`. */
|
|
885
|
+
canDrop?: (item: ScreenDragItem, to: Place, base: (item: ScreenDragItem, to: Place) => boolean, context: ScreenCanvasDragContext) => boolean;
|
|
886
|
+
/** Land it, at a place `canDrop` said yes to. Handed the screen's own write
|
|
887
|
+
* (`base`, the tree's: a section moved, a block moved, a new one added).
|
|
888
|
+
* Absent: `base`. */
|
|
889
|
+
drop?: (item: ScreenDragItem, to: Place, base: (item: ScreenDragItem, to: Place) => void, context: ScreenCanvasDragContext) => void;
|
|
890
|
+
/** A handle CLICKED, not dragged: select what it names. Handed the screen's
|
|
891
|
+
* own (`base`: the node, as a press on its row selects it). Absent: `base`. */
|
|
892
|
+
pick?: (item: ScreenDragItem, base: (item: ScreenDragItem) => void, context: ScreenCanvasDragContext) => void;
|
|
893
|
+
}
|
|
894
|
+
/** What a layer's head over the canvas is handed (`ScreenParts.CanvasHead`,
|
|
895
|
+
* 0.105.0): the device the canvas is drawn as, so it can say what is the
|
|
896
|
+
* device's (the campaign designer's mail-app switch is desktop's only). */
|
|
897
|
+
interface ScreenCanvasHeadProps {
|
|
898
|
+
device: string;
|
|
546
899
|
}
|
|
547
900
|
/**
|
|
548
901
|
* WHAT IS PINNED in the document's top-level list. That the list has a BAND
|
|
@@ -566,9 +919,15 @@ interface ScreenDevices {
|
|
|
566
919
|
* selected and where a pinned node's row is pressed, and shows what it is
|
|
567
920
|
* handed.
|
|
568
921
|
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
922
|
+
* And HOW THE LAYERS TREE FRAMES THEM (0.103.0): which node is pinned where it
|
|
923
|
+
* is not one type (`isFirst`, `isLast` — the campaign designer's Header and
|
|
924
|
+
* Footer are both sections, told apart by a prop), how the first one's row is
|
|
925
|
+
* drawn (`firstRow`) and what the band of sections between them looks like
|
|
926
|
+
* (`band`). Each is optional, and its default is the tree the website has.
|
|
927
|
+
*
|
|
928
|
+
* The same object for the life of a mount, its functions plain functions of
|
|
929
|
+
* what they are passed: the screen reads it anywhere, inside the callbacks and
|
|
930
|
+
* effects it does not rebuild for it.
|
|
572
931
|
*/
|
|
573
932
|
interface ScreenPinnedNodes {
|
|
574
933
|
/** The type of the node pinned FIRST: the band starts after it. Null when
|
|
@@ -576,6 +935,32 @@ interface ScreenPinnedNodes {
|
|
|
576
935
|
first: string | null;
|
|
577
936
|
/** The type of the node pinned LAST: the band ends at it. */
|
|
578
937
|
last: string | null;
|
|
938
|
+
/**
|
|
939
|
+
* Is this top-level node the one pinned first (0.103.0)? Where every node
|
|
940
|
+
* of the pinned type is not pinned — the campaign designer's Header is an
|
|
941
|
+
* `EmailSection` with `_region: "header"`, beside body sections of the same
|
|
942
|
+
* type — the layer says which. The page screen asks it wherever it tested
|
|
943
|
+
* a node against `first`: the band, the tree, the canvas handles, the menu.
|
|
944
|
+
* (The section screen, which holds one node, still asks the type.) The
|
|
945
|
+
* first node that answers yes is the one. Absent: a node of type `first`.
|
|
946
|
+
*/
|
|
947
|
+
isFirst?: (node: ScreenNode) => boolean;
|
|
948
|
+
/** …and the one pinned last (the Footer). Absent: a node of type `last`. */
|
|
949
|
+
isLast?: (node: ScreenNode) => boolean;
|
|
950
|
+
/**
|
|
951
|
+
* How the Layers tree draws the node pinned first (0.103.0). `"panel"`: a
|
|
952
|
+
* row of its own that opens the layer's panel for it (`panelOf`), drawn
|
|
953
|
+
* whether or not the document holds the node, and none of its children —
|
|
954
|
+
* the website's Header, whose settings are a panel. `"node"`: the node
|
|
955
|
+
* itself, selected by its row and folding open into its children, exactly
|
|
956
|
+
* as the node pinned last is drawn — the campaign designer's Header, a
|
|
957
|
+
* section with blocks in it. Absent: `"panel"`.
|
|
958
|
+
*/
|
|
959
|
+
firstRow?: "panel" | "node";
|
|
960
|
+
/** What the band of sections between the two pins looks like in the tree
|
|
961
|
+
* (0.103.0). Absent: a group label in the screen's words, the sections at
|
|
962
|
+
* the tree's own depth, and no row after them. */
|
|
963
|
+
band?: ScreenPinnedBand;
|
|
579
964
|
/** The type of the group of sections pinned first, ahead of everything. */
|
|
580
965
|
firstGroup: string | null;
|
|
581
966
|
/** …and of the one pinned last. */
|
|
@@ -593,6 +978,31 @@ interface ScreenPinnedNodes {
|
|
|
593
978
|
*/
|
|
594
979
|
panelOf: (type: string | null | undefined) => ScreenInspectorMode | null;
|
|
595
980
|
}
|
|
981
|
+
/**
|
|
982
|
+
* THE BAND, AS THE LAYERS TREE FRAMES IT (`ScreenPinnedNodes.band`, 0.103.0):
|
|
983
|
+
* the sections between the two pins. Where the band starts and ends is the
|
|
984
|
+
* screen's arithmetic either way; this is only how it is drawn.
|
|
985
|
+
*/
|
|
986
|
+
interface ScreenPinnedBand {
|
|
987
|
+
/** What the band is called. Absent: the screen's words, `screen.pageSections`
|
|
988
|
+
* ("Template · Home page") on a document with the edit guard and
|
|
989
|
+
* `screen.templateSections` ("Template · Template") on one without. */
|
|
990
|
+
label?: string;
|
|
991
|
+
/** The band is a ROW that folds, its sections under it — the campaign
|
|
992
|
+
* designer's Body. Absent or false: a group label over the sections, which
|
|
993
|
+
* sit at the tree's own depth. */
|
|
994
|
+
foldable?: boolean;
|
|
995
|
+
/** The band ends with an "Add section" row (`screen.addSection`) that opens
|
|
996
|
+
* Add at the end of the band, where the band's last "+" does. Hidden while
|
|
997
|
+
* the document is read-only, as every "+" is. Absent or false: the band ends
|
|
998
|
+
* at its last gap. */
|
|
999
|
+
addAtEnd?: boolean;
|
|
1000
|
+
}
|
|
1001
|
+
/** Is `node` the one the layer pins FIRST — its own test (`isFirst`), else a
|
|
1002
|
+
* node of the `first` type, the test the screen has always made. */
|
|
1003
|
+
declare function isPinnedFirst(pinned: ScreenPinnedNodes, node: ScreenNode): boolean;
|
|
1004
|
+
/** …and LAST (`isLast`, else a node of the `last` type). */
|
|
1005
|
+
declare function isPinnedLast(pinned: ScreenPinnedNodes, node: ScreenNode): boolean;
|
|
596
1006
|
/**
|
|
597
1007
|
* THE VIEW THE LEFT PANEL IS ON, from one mount to the next. That the panel
|
|
598
1008
|
* has views, that one of them is current and that the choice is kept is the
|
|
@@ -615,6 +1025,100 @@ interface ScreenLeftViewRules {
|
|
|
615
1025
|
* view to be on. */
|
|
616
1026
|
forSelection: (selectedId: string | null | undefined, current: string) => string;
|
|
617
1027
|
}
|
|
1028
|
+
/**
|
|
1029
|
+
* THE SELECTION, as the screen hands it to a rule that asks where it is
|
|
1030
|
+
* (`ScreenAdd.railTarget`, 0.105.0): the node selected, and the panel the
|
|
1031
|
+
* inspector is showing — the selection's own (`SELECTION_MODE`), or one of the
|
|
1032
|
+
* layer's, such as the campaign designer's column, which is a slot and no
|
|
1033
|
+
* node.
|
|
1034
|
+
*/
|
|
1035
|
+
interface ScreenSelection {
|
|
1036
|
+
node: ScreenNode | null;
|
|
1037
|
+
mode: ScreenInspectorMode;
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* WHERE ADD PUTS WHAT IT ADDS, where that is the layer's to say (0.105.0, seam
|
|
1041
|
+
* E9). That there is an Add panel, what it lists and where a tile dragged out
|
|
1042
|
+
* of it may land are the screen's. Plain data and a plain function, the same
|
|
1043
|
+
* for the life of a mount, for the reason the block rules are.
|
|
1044
|
+
*/
|
|
1045
|
+
interface ScreenAdd {
|
|
1046
|
+
/**
|
|
1047
|
+
* Where the rail's "+" aims Add: handed the working document and the
|
|
1048
|
+
* selection, the place a BLOCK the panel adds goes — the campaign designer's
|
|
1049
|
+
* last body section's first column, at its end, where its own drawer put a
|
|
1050
|
+
* block — or null for the screen's own. Asked as the panel draws while it is
|
|
1051
|
+
* open at no place of its own (from the rail, or after its place was
|
|
1052
|
+
* cleared), so a place at the end of a list stays at its end as blocks go in.
|
|
1053
|
+
* A place in a slot heads the panel with what that slot takes ("Inside
|
|
1054
|
+
* Section 3"), and a block tile pressed lands there; the sections still
|
|
1055
|
+
* follow, and land where they always did. A place in the top-level list is
|
|
1056
|
+
* where a section or a saved one lands. No "Adding to …" line is drawn for it:
|
|
1057
|
+
* that line is for a place a "+" named. Absent, or null: the rail's "+" opens
|
|
1058
|
+
* Add at no place — the selected container's blocks, then the blank section,
|
|
1059
|
+
* the saved sections and the sections — as it always has.
|
|
1060
|
+
*/
|
|
1061
|
+
railTarget?: (data: unknown, selection: ScreenSelection) => Place | null;
|
|
1062
|
+
/**
|
|
1063
|
+
* Is Add a picker of BLOCKS first, as the campaign designer's drawer is? With
|
|
1064
|
+
* true, where Add offers the blocks of a container — the rail's target, or
|
|
1065
|
+
* the container selected — those blocks are the whole panel, with no
|
|
1066
|
+
* section catalogue after them; and a gap between two sections, where what
|
|
1067
|
+
* goes in is a new section, offers the catalogue alone, with no container's
|
|
1068
|
+
* blocks before it. So one panel never lists the same blocks twice, under the
|
|
1069
|
+
* same headings, for two different places (a container's runs and the
|
|
1070
|
+
* catalogue's groups). A place a "+" names in a slot offers that slot's
|
|
1071
|
+
* blocks alone either way. Absent, false: a container's blocks, then the
|
|
1072
|
+
* catalogue, wherever there is a container to offer — as it always has.
|
|
1073
|
+
*/
|
|
1074
|
+
blocksFirst?: boolean;
|
|
1075
|
+
}
|
|
1076
|
+
/** What a style clipboard's scope is read off (`ScreenStyleClipboard.scope`):
|
|
1077
|
+
* the document the screen has open. */
|
|
1078
|
+
interface ScreenStyleDocument {
|
|
1079
|
+
/** What the screen is pointed at: a website's page, or a host's own
|
|
1080
|
+
* document (`{ kind: "document", record }`). */
|
|
1081
|
+
target: AnyScreenTarget;
|
|
1082
|
+
/** The website the page belongs to, or null. */
|
|
1083
|
+
siteId: string | null;
|
|
1084
|
+
/** The backend's id of the loaded document, or null while it loads. */
|
|
1085
|
+
docId: string | null;
|
|
1086
|
+
}
|
|
1087
|
+
/** What a Paste style onto one node would do: its new props, whether they
|
|
1088
|
+
* changed, how many rows were pasted, and the words the merchant reads. */
|
|
1089
|
+
interface ScreenStylePastePlan {
|
|
1090
|
+
props: Record<string, unknown>;
|
|
1091
|
+
changed: boolean;
|
|
1092
|
+
pasted: number;
|
|
1093
|
+
message: string;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* COPY STYLE / PASTE STYLE, where it is the layer's (0.105.0, seam E10). The
|
|
1097
|
+
* clipboard, the matching rule, the menu rows, their words and the ⌥⌘C / ⌥⌘V
|
|
1098
|
+
* keys are efficient-easel/style-clipboard's and the screen's; WHICH rows of a
|
|
1099
|
+
* node are its look, and how far a copied look travels (its scope), are the
|
|
1100
|
+
* layer's — the website's look is its Style and Layout tabs and travels across
|
|
1101
|
+
* one site's pages, the campaign designer's is its own panels' and stays in
|
|
1102
|
+
* one campaign. Each member is optional, and one left out is the website's
|
|
1103
|
+
* (lib/puck/style-clipboard): a layer may hand only its scope. Plain functions,
|
|
1104
|
+
* the same object for the life of the mount.
|
|
1105
|
+
*/
|
|
1106
|
+
interface ScreenStyleClipboard {
|
|
1107
|
+
/** The clipboard's scope for the open document: in another scope nothing is
|
|
1108
|
+
* held. Absent: `siteStyleScope(siteId)`, one site across its pages. */
|
|
1109
|
+
scope?: (doc: ScreenStyleDocument) => string;
|
|
1110
|
+
/** A node's look, as rows the clipboard holds and matches. Absent: the
|
|
1111
|
+
* website's (`nodeStyleRows`), the Style and Layout tabs. */
|
|
1112
|
+
rows?: (config: unknown, node: ScreenNode) => StyleRow[];
|
|
1113
|
+
/** Copy a node's look into `scope`, named `label` (the menu's word for it).
|
|
1114
|
+
* Absent: its `rows`, copied as they are stored. */
|
|
1115
|
+
copy?: (scope: string, node: ScreenNode, label: string, config: unknown) => void;
|
|
1116
|
+
/** What a paste onto a node would do, or null when nothing is held in
|
|
1117
|
+
* `scope`. The screen writes `props` through its one replace op when
|
|
1118
|
+
* `changed`, and always shows `message`. Absent: the held look laid over the
|
|
1119
|
+
* node's `rows` (efficient-easel/style-clipboard `planPaste`). */
|
|
1120
|
+
plan?: (scope: string, node: ScreenNode, label: string, config: unknown) => ScreenStylePastePlan | null;
|
|
1121
|
+
}
|
|
618
1122
|
interface ScreenParts {
|
|
619
1123
|
/**
|
|
620
1124
|
* The name a panel's head gives what is being edited — the website's name,
|
|
@@ -622,6 +1126,13 @@ interface ScreenParts {
|
|
|
622
1126
|
* reads it (components/MediaSidePanel), through `useScreenOwnerName`.
|
|
623
1127
|
*/
|
|
624
1128
|
useOwnerName?: () => string;
|
|
1129
|
+
/**
|
|
1130
|
+
* The Layers head's context line — what the open document is, under the
|
|
1131
|
+
* word "Layers" — as the hook the head calls (0.103.0). The campaign
|
|
1132
|
+
* designer's names the campaign and its variant. Absent: the document's
|
|
1133
|
+
* address, `/${slug}`, as the website's head has always said it.
|
|
1134
|
+
*/
|
|
1135
|
+
useDocumentLabel?: () => string;
|
|
625
1136
|
/**
|
|
626
1137
|
* The layer's wiring between the inspector and what the layer draws in the
|
|
627
1138
|
* canvas, as ONE hook the screen calls where it used to hold that wiring: a
|
|
@@ -680,6 +1191,47 @@ interface ScreenParts {
|
|
|
680
1191
|
* website has it.
|
|
681
1192
|
*/
|
|
682
1193
|
saveSwitch?: boolean;
|
|
1194
|
+
/**
|
|
1195
|
+
* Does a field's media pick give way to a change of selection (0.103.0)? A
|
|
1196
|
+
* field of the selected block asks the host's panel to choose (lib/
|
|
1197
|
+
* media-panel); with true, selecting another block, or none, while it waits
|
|
1198
|
+
* leaves pick mode and settles the field with null, as Cancel would — the
|
|
1199
|
+
* campaign designer's picker belongs to the block it was opened for. Absent,
|
|
1200
|
+
* false: a pick outlives a change of selection, as the website's does.
|
|
1201
|
+
*/
|
|
1202
|
+
pickFollowsSelection?: boolean;
|
|
1203
|
+
/** Where Add puts what it adds, and whether it is a picker of blocks first
|
|
1204
|
+
* (0.105.0; `ScreenAdd`). Absent: the screen's Add, as it always was. */
|
|
1205
|
+
add?: ScreenAdd;
|
|
1206
|
+
/** Copy style / Paste style's scope and a node's look, where they are the
|
|
1207
|
+
* layer's (0.105.0; `ScreenStyleClipboard`). Absent: the website's. */
|
|
1208
|
+
styleClipboard?: ScreenStyleClipboard;
|
|
1209
|
+
/**
|
|
1210
|
+
* Do ⌘C / ⌘X / ⌘V (Ctrl on Windows) copy, cut and paste the SELECTED block
|
|
1211
|
+
* (0.105.0)? The keyboard door to the menu's Copy, Cut and Paste rows, which
|
|
1212
|
+
* print these keys beside them: the menu's rules, the menu's place for a
|
|
1213
|
+
* paste, and a paste with nowhere to go there refused aloud
|
|
1214
|
+
* (`screen.pasteRefused`). Heard on the editor and in the canvas frame, never
|
|
1215
|
+
* where a person types or has words selected, nor with ⌥ (Copy style) or ⇧
|
|
1216
|
+
* held. Nothing is cut or pasted on a document this editor cannot write; a
|
|
1217
|
+
* copy is allowed there.
|
|
1218
|
+
*
|
|
1219
|
+
* Owner ruling R12/R13 (Victor Mau, 2026-10-09): Copy and Paste work the same
|
|
1220
|
+
* way in both editors. So the keys are on unless the layer says false.
|
|
1221
|
+
*/
|
|
1222
|
+
nodeKeys?: boolean;
|
|
1223
|
+
/**
|
|
1224
|
+
* THE HOST'S OWN TOASTS (0.105.0; owner ruling R17, Victor Mau, 2026-10-09).
|
|
1225
|
+
* Every line the screen would say in its toast — "Copied Text", "Added
|
|
1226
|
+
* “Hero” section", a refused paste, a pasted style, what a panel of the
|
|
1227
|
+
* layer's or the inspector says through the screen's toast — goes to the host
|
|
1228
|
+
* instead, with its tone: `"error"` for what went wrong, `"info"` for the
|
|
1229
|
+
* rest; and the screen draws no toast of its own. The campaign designer
|
|
1230
|
+
* hands the admin portal's toast, so the designer's lines stand where every
|
|
1231
|
+
* other window's do. Called as each line is said, so it may change between
|
|
1232
|
+
* renders. Absent: the screen's own toast (`.sf-toast`), as before.
|
|
1233
|
+
*/
|
|
1234
|
+
notify?: (message: string, tone: "info" | "error") => void;
|
|
683
1235
|
/**
|
|
684
1236
|
* THE CANVAS the screen frames: the engine's, as the layer dresses it — the
|
|
685
1237
|
* layer's own sheet and theme in the frame, its own say over the outline
|
|
@@ -689,8 +1241,31 @@ interface ScreenParts {
|
|
|
689
1241
|
*
|
|
690
1242
|
* ONE function for the life of a mount: the screen renders it as an element
|
|
691
1243
|
* type, and a type that changed identity would remount the whole canvas.
|
|
1244
|
+
*
|
|
1245
|
+
* The frame it draws is published to it, and to the head over it
|
|
1246
|
+
* (`CanvasHead`), as the screen found it: `useScreenCanvasTarget()`.
|
|
692
1247
|
*/
|
|
693
1248
|
Canvas?: ComponentType;
|
|
1249
|
+
/**
|
|
1250
|
+
* A HEAD OVER THE CANVAS (0.105.0): the layer's own row above the frame, in
|
|
1251
|
+
* the canvas's well and at its own size — never scaled with a device — such
|
|
1252
|
+
* as the campaign designer's Subject line, its mail-app switch and its dark
|
|
1253
|
+
* mail app's bar, which sit above the email the way an inbox shows them. The
|
|
1254
|
+
* frame fills what is left of the well under it, and is fitted to that. It is
|
|
1255
|
+
* handed the device the canvas is drawn as. Absent: nothing is drawn above
|
|
1256
|
+
* the frame, and the frame fills the well.
|
|
1257
|
+
*
|
|
1258
|
+
* ONE function for the life of a mount, for the reason `Canvas` is.
|
|
1259
|
+
*/
|
|
1260
|
+
CanvasHead?: ComponentType<ScreenCanvasHeadProps>;
|
|
1261
|
+
/**
|
|
1262
|
+
* The canvas drag's measure, model and rules, where they are the layer's
|
|
1263
|
+
* (0.105.0; `ScreenCanvasDrag`). Each member absent, and the whole object
|
|
1264
|
+
* absent, is the screen's own: Puck's markers, every node but the pinned
|
|
1265
|
+
* ones, the Layers tree's rules. Plain functions, and handed here for the
|
|
1266
|
+
* reason the rules are.
|
|
1267
|
+
*/
|
|
1268
|
+
canvasDrag?: ScreenCanvasDrag;
|
|
694
1269
|
/**
|
|
695
1270
|
* THE INSPECTOR the screen mounts in its right panel: the panel of whatever
|
|
696
1271
|
* is selected and, in its place, each panel of the layer's own — frame, head
|
|
@@ -713,6 +1288,9 @@ declare function useScreenParts(): ScreenParts;
|
|
|
713
1288
|
/** The layer's bridges, run in the screen. With no layer, nothing runs. */
|
|
714
1289
|
/** The name a panel's head gives what is being edited (`useOwnerName`). */
|
|
715
1290
|
declare function useScreenOwnerName(): string;
|
|
1291
|
+
/** The Layers head's context line (`useDocumentLabel`), or null with no
|
|
1292
|
+
* layer's, and the screen says the document's address. */
|
|
1293
|
+
declare function useScreenDocumentLabel(): string | null;
|
|
716
1294
|
declare function useScreenBridges(inspector: ScreenInspector, tree: ScreenTree, canvas: ScreenCanvas, left: ScreenLeftPanel): ScreenBridges;
|
|
717
1295
|
/** The layer's bridges for the screen that holds one node by itself. With no
|
|
718
1296
|
* layer, nothing runs. */
|
|
@@ -738,11 +1316,42 @@ declare function useScreenPinned(): ScreenPinnedNodes;
|
|
|
738
1316
|
/** Whether the save pill is the autosave's switch. With no layer, it is, as
|
|
739
1317
|
* the screen has always drawn it. */
|
|
740
1318
|
declare function useScreenSaveSwitch(): boolean;
|
|
1319
|
+
/** Leave a field's pick when `selection` changes, if the layer says a pick
|
|
1320
|
+
* follows the selection (`pickFollowsSelection`). With no layer, a pick
|
|
1321
|
+
* outlives a change of selection, as it always has. */
|
|
1322
|
+
declare function useScreenPickFollowsSelection(selection: unknown): void;
|
|
1323
|
+
/** Where Add puts what it adds (`add`). With no layer's, nothing: the
|
|
1324
|
+
* screen's own Add. */
|
|
1325
|
+
declare function useScreenAdd(): ScreenAdd;
|
|
1326
|
+
/** The layer's style clipboard (`styleClipboard`), or null: the website's. */
|
|
1327
|
+
declare function useScreenStyleClipboard(): ScreenStyleClipboard | null;
|
|
1328
|
+
/** Whether ⌘C / ⌘X / ⌘V reach the selected block (`nodeKeys`). They do
|
|
1329
|
+
* unless the layer says not (owner ruling R12/R13). */
|
|
1330
|
+
declare function useScreenNodeKeys(): boolean;
|
|
1331
|
+
/** The host's toast (`notify`), or null: with none, the screen says its lines
|
|
1332
|
+
* in its own (R17). */
|
|
1333
|
+
declare function useScreenNotify(): ((message: string, tone: "info" | "error") => void) | null;
|
|
741
1334
|
/** The canvas the layer dresses for the screen to frame. With no layer, the
|
|
742
1335
|
* engine's plain one. */
|
|
743
1336
|
declare function useScreenCanvasFrame(): ComponentType;
|
|
1337
|
+
/** The layer's head over the canvas (`CanvasHead`), or null: with no layer's,
|
|
1338
|
+
* nothing is drawn above the frame. */
|
|
1339
|
+
declare function useScreenCanvasHead(): ComponentType<ScreenCanvasHeadProps> | null;
|
|
1340
|
+
/** The layer's canvas drag (`canvasDrag`), or null: with no layer's, every
|
|
1341
|
+
* answer is the screen's own. */
|
|
1342
|
+
declare function useScreenCanvasDrag(): ScreenCanvasDrag | null;
|
|
1343
|
+
/** Publishes the frame the page screen found. The screen's own: it stands round
|
|
1344
|
+
* the chrome, and adds nothing to the page. */
|
|
1345
|
+
declare function ScreenCanvasTargetProvider({ target, children }: {
|
|
1346
|
+
target: CanvasTarget | null;
|
|
1347
|
+
children?: ReactNode;
|
|
1348
|
+
}): react.JSX.Element;
|
|
1349
|
+
/** The canvas frame the page screen found: its frame, document and window, or
|
|
1350
|
+
* null while there is none — and always null outside the page screen (the
|
|
1351
|
+
* section screen watches for no frame). */
|
|
1352
|
+
declare function useScreenCanvasTarget(): CanvasTarget | null;
|
|
744
1353
|
/** The inspector the layer draws for the screen to mount. With no layer, the
|
|
745
1354
|
* engine's plain rows for the selection. */
|
|
746
1355
|
declare function useScreenInspectorPanel(): ComponentType<ScreenInspectorPanelProps>;
|
|
747
1356
|
|
|
748
|
-
export { type NodeDefaults, SELECTION_MODE, type ScreenBlockLook, type ScreenBlockRules, type ScreenBridges, type ScreenCanvas, type ScreenDevices, type ScreenDocumentOps, type ScreenInspector, type ScreenInspectorMode, type ScreenInspectorPanelProps, type ScreenLeftPanel, type ScreenLeftView, type ScreenLeftViewFrame, type ScreenLeftViewRules, type ScreenNewNode, type ScreenNode, type ScreenNodeLevel, type ScreenNodeMaker, type ScreenPartMode, type ScreenParts, ScreenPartsProvider, type ScreenPinnedNodes, type ScreenRailItem, type ScreenTree, type ScreenTreeFolds, type ScreenTreeRows, sameInspectorMode, useScreenBlockLook, useScreenBlockRules, useScreenBridges, useScreenCanvasFrame, useScreenDevices, useScreenDocumentPass, useScreenInspectorPanel, useScreenLeftView, useScreenOwnerName, useScreenParts, useScreenPinned, useScreenSaveSwitch, useStandaloneScreenBridges };
|
|
1357
|
+
export { type NodeDefaults, SELECTION_MODE, type ScreenAdd, type ScreenBlockLook, type ScreenBlockRules, type ScreenBridges, type ScreenCanvas, type ScreenCanvasDrag, type ScreenCanvasDragContext, type ScreenCanvasHeadProps, ScreenCanvasTargetProvider, type ScreenDevices, type ScreenDocumentOps, type ScreenDragItem, type ScreenInspector, type ScreenInspectorMode, type ScreenInspectorPanelProps, type ScreenLeftPanel, type ScreenLeftView, type ScreenLeftViewFrame, type ScreenLeftViewRules, type ScreenMenuRows, type ScreenNewNode, type ScreenNode, type ScreenNodeActions, type ScreenNodeLevel, type ScreenNodeMaker, type ScreenPartMode, type ScreenParts, ScreenPartsProvider, type ScreenPinnedBand, type ScreenPinnedNodes, type ScreenRailItem, type ScreenSelection, type ScreenSelector, type ScreenSlot, type ScreenSlotAction, type ScreenSlotMode, type ScreenStyleClipboard, type ScreenStyleDocument, type ScreenStylePastePlan, type ScreenTree, type ScreenTreeFolds, type ScreenTreeRows, isPinnedFirst, isPinnedLast, isSlotMode, sameInspectorMode, screenSlotsOf, useScreenAdd, useScreenBlockLook, useScreenBlockRules, useScreenBridges, useScreenCanvasDrag, useScreenCanvasFrame, useScreenCanvasHead, useScreenCanvasTarget, useScreenDevices, useScreenDocumentLabel, useScreenDocumentPass, useScreenInspectorPanel, useScreenLeftView, useScreenNodeKeys, useScreenNotify, useScreenOwnerName, useScreenParts, useScreenPickFollowsSelection, useScreenPinned, useScreenSaveSwitch, useScreenStyleClipboard, useStandaloneScreenBridges };
|