efficient-easel 24.2.0 → 25.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -2
- package/dist/{CanvasDragLayer-NZpaX6aq.d.ts → CanvasDragLayer-DXeQGrwJ.d.ts} +42 -3
- package/dist/canvas/index.d.ts +2 -139
- package/dist/canvas/index.js +1 -1
- package/dist/chrome/index.js +1 -1
- package/dist/{chunk-6NJHYXJM.js → chunk-3XECMGXX.js} +1 -1
- package/dist/{chunk-FRAIEWRC.js → chunk-62UGN7VM.js} +1 -1
- package/dist/{chunk-HNKB2ZYR.js → chunk-6ATIYLUL.js} +1 -1
- package/dist/{chunk-Y53EKN35.js → chunk-6EDVZBUO.js} +1 -1
- package/dist/{chunk-JMAOCKB2.js → chunk-6WTWYHC2.js} +3 -3
- package/dist/chunk-7UFKEX72.js +1 -0
- package/dist/chunk-BBD3FLU3.js +16 -0
- package/dist/chunk-CEC5XLN4.js +1 -0
- package/dist/chunk-CWELHADJ.js +1 -0
- package/dist/chunk-DX3VILZ3.js +6 -0
- package/dist/chunk-ERB6FAZT.js +2 -0
- package/dist/{chunk-TGZCD6IP.js → chunk-EUFDQ4KL.js} +1 -1
- package/dist/chunk-FEP6XMNX.js +1 -0
- package/dist/chunk-FR7EEKFF.js +1 -0
- package/dist/chunk-GDO4QJ4G.js +1 -0
- package/dist/{chunk-GMCZXMOV.js → chunk-GR3XRILS.js} +1 -1
- package/dist/chunk-H6BER2EU.js +1 -0
- package/dist/{chunk-G67G63O5.js → chunk-ITIVCER6.js} +1 -1
- package/dist/chunk-IW5QXREH.js +64 -0
- package/dist/chunk-JIP5JNRB.js +1 -0
- package/dist/chunk-JQQFB7EZ.js +1 -0
- package/dist/{chunk-AGWKB77Q.js → chunk-K53PQAMP.js} +1 -1
- package/dist/{chunk-4ESG53BH.js → chunk-KF3LT7J2.js} +1 -1
- package/dist/{chunk-CLOS6SSX.js → chunk-KO47WAWR.js} +1 -1
- package/dist/chunk-KVIEUWTX.js +11 -0
- package/dist/{chunk-QORC32JO.js → chunk-LUHGBFOD.js} +3 -3
- package/dist/{chunk-DDH2DYQP.js → chunk-LUOY3A3Q.js} +1 -1
- package/dist/chunk-MIX7EGRG.js +2 -0
- package/dist/{chunk-2FYFAAAK.js → chunk-OXOUGEAT.js} +1 -1
- package/dist/chunk-PMRN5Z3T.js +1 -0
- package/dist/{chunk-55KKGABA.js → chunk-PVBDKBJB.js} +1 -1
- package/dist/{chunk-RPMSET77.js → chunk-QTHQPJWA.js} +1 -1
- package/dist/{chunk-ISS72IKO.js → chunk-QZJKWKGH.js} +1 -1
- package/dist/{chunk-IYHO4XQX.js → chunk-S6YOIRXQ.js} +1 -1
- package/dist/{chunk-5PXVT7JY.js → chunk-SBVIW3KJ.js} +1 -1
- package/dist/chunk-SC6E3UUS.js +13 -0
- package/dist/{chunk-LN43DP2A.js → chunk-SQTVXE5D.js} +13 -13
- package/dist/chunk-TOKMFZPB.js +1 -0
- package/dist/chunk-U3LTJSBU.js +20 -0
- package/dist/{chunk-75C6WFNF.js → chunk-UCZQWQNS.js} +1 -1
- package/dist/chunk-UDWXBS46.js +1 -0
- package/dist/{chunk-WYTPBF3Q.js → chunk-VBEVZZTV.js} +11 -11
- package/dist/{chunk-OITNWE52.js → chunk-XLC7HWW3.js} +1 -1
- package/dist/chunk-XTDOSL2M.js +8 -0
- package/dist/chunk-YYD257TD.js +1 -0
- package/dist/copy/index.js +13 -13
- package/dist/copy-place-CQIemdtU.d.ts +25 -0
- package/dist/data/index.d.ts +4 -1
- package/dist/data/index.js +1 -1
- package/dist/dom-BpxMcHFP.d.ts +200 -0
- package/dist/drag/index.d.ts +2 -3
- package/dist/drag/index.js +1 -1
- package/dist/draw/index.d.ts +1 -1
- package/dist/draw/index.js +1 -1
- package/dist/easel/index.d.ts +67 -1
- package/dist/easel/index.js +1 -1
- package/dist/edit-lock/index.d.ts +0 -46
- package/dist/edit-lock/index.js +1 -1
- package/dist/fields/fields.css +6 -40
- package/dist/fields/index.d.ts +1 -6
- package/dist/fields/index.js +1 -1
- package/dist/node-ops/index.js +1 -1
- package/dist/page-copy/index.d.ts +110 -0
- package/dist/page-copy/index.js +5 -0
- package/dist/panel/index.d.ts +29 -34
- package/dist/panel/index.js +1 -1
- package/dist/panel/panel.css +0 -78
- package/dist/screen/components/AddBlockRow.js +1 -1
- package/dist/screen/components/AddSidePanel.d.ts +37 -57
- package/dist/screen/components/AddSidePanel.js +1 -1
- package/dist/screen/components/NodeContextMenu.d.ts +19 -11
- package/dist/screen/components/NodeContextMenu.js +1 -1
- package/dist/screen/components/PageEditGuardNotices.js +1 -1
- package/dist/screen/components/SaveControls.d.ts +10 -11
- package/dist/screen/components/SaveControls.js +1 -1
- package/dist/screen/components/ScreenChrome.js +1 -1
- package/dist/screen/components/ScreenDocumentContext.js +1 -1
- package/dist/screen/components/ScreenMount.d.ts +5 -6
- package/dist/screen/components/ScreenMount.js +1 -1
- package/dist/screen/components/ScreenStoreProvider.d.ts +8 -9
- package/dist/screen/components/ScreenStoreProvider.js +1 -1
- package/dist/screen/components/SectionScreenShell.js +17 -17
- package/dist/screen/components/SidePanelHead.js +1 -1
- package/dist/screen/components/panel-widths.js +1 -1
- package/dist/screen/components/usePartBridge.d.ts +10 -11
- package/dist/screen/components/usePartBridge.js +1 -1
- package/dist/screen/index.d.ts +9 -10
- package/dist/screen/index.js +1 -1
- package/dist/screen/lib/document/block-set-host.d.ts +55 -0
- package/dist/screen/lib/document/block-set-host.js +1 -0
- package/dist/screen/lib/document/block-types-in.js +1 -1
- package/dist/screen/lib/document/box-fields.d.ts +160 -5
- package/dist/screen/lib/document/box-fields.js +1 -9
- package/dist/screen/lib/document/device-fields.js +1 -1
- package/dist/screen/lib/document/palette-sections.d.ts +33 -97
- package/dist/screen/lib/document/palette-sections.js +1 -1
- package/dist/screen/lib/document/preview-dom.js +1 -1
- package/dist/screen/lib/document/section-doc.js +1 -1
- package/dist/screen/lib/document/style-clipboard.d.ts +10 -11
- package/dist/screen/lib/document/style-clipboard.js +1 -1
- package/dist/screen/lib/document/use-section-ops.js +1 -1
- package/dist/screen/lib/document-switch.js +1 -1
- package/dist/screen/lib/failure.js +1 -1
- package/dist/screen/lib/host-inbound.js +1 -1
- package/dist/screen/lib/key-scope.js +1 -1
- package/dist/screen/lib/media-picker.js +1 -1
- package/dist/screen/lib/page-lock.js +1 -1
- package/dist/screen/lib/screen-parts.d.ts +251 -12
- package/dist/screen/lib/screen-parts.js +1 -1
- package/dist/screen/screen.css +6 -0
- package/dist/screen/words.d.ts +9 -0
- package/dist/screen/words.js +1 -1
- package/dist/strings/index.d.ts +4 -1
- package/dist/strings/index.js +2 -2
- package/dist/style-clipboard/index.d.ts +0 -32
- package/dist/style-clipboard/index.js +1 -1
- package/dist/text-styles/index.d.ts +7 -6
- package/dist/text-styles/index.js +37 -36
- package/dist/text-styles/text-styles.css +5 -53
- package/dist/tree/index.d.ts +2 -2
- package/dist/{types-DBy3L69b.d.ts → types-CoUTWUwB.d.ts} +1 -1
- package/dist/words-Dl8Qja4K.d.ts +32 -0
- package/package.json +15 -3
- package/dist/chunk-3FIS2FRS.js +0 -1
- package/dist/chunk-7RSE6KKY.js +0 -1
- package/dist/chunk-CMPFUJ26.js +0 -8
- package/dist/chunk-CZAAGBVL.js +0 -7
- package/dist/chunk-DSKNJXB4.js +0 -1
- package/dist/chunk-FJTCSQWK.js +0 -16
- package/dist/chunk-G7ISR6DI.js +0 -1
- package/dist/chunk-H4Z2V56N.js +0 -21
- package/dist/chunk-K7MMLCTT.js +0 -2
- package/dist/chunk-KRL3IUV3.js +0 -1
- package/dist/chunk-LF3FUSCQ.js +0 -1
- package/dist/chunk-THWO5YVZ.js +0 -1
- package/dist/chunk-TOHOGVAE.js +0 -15
- package/dist/chunk-UKPZ2YWE.js +0 -64
- package/dist/chunk-V7U33NF2.js +0 -1
- package/dist/chunk-VKPOH6MK.js +0 -1
- package/dist/chunk-YU3WHLGI.js +0 -1
- package/dist/repeat-D65bJS8d.d.ts +0 -49
- package/dist/session-EsjORLQ0.d.ts +0 -43
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** One drawn copy's place. */
|
|
2
|
+
interface RepeatCopy {
|
|
3
|
+
/** The block whose slot is drawn once per row. */
|
|
4
|
+
ownerId: string;
|
|
5
|
+
/** That slot (`template`). */
|
|
6
|
+
slot: string;
|
|
7
|
+
/** The row this copy is drawn for; 0 is the main copy. */
|
|
8
|
+
index: number;
|
|
9
|
+
/** How many copies the owner draws (greys a host's "move later" on the last). */
|
|
10
|
+
count: number;
|
|
11
|
+
/**
|
|
12
|
+
* The copy of an OUTER template this copy's owner is drawn in, when there
|
|
13
|
+
* is one: the inner index alone names no row (row 2 of the cards in outer
|
|
14
|
+
* row 1). Left out at the top.
|
|
15
|
+
*/
|
|
16
|
+
outer?: RepeatCopy;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The copy `el` is in — the NEAREST wrapper with both names, with the chain
|
|
20
|
+
* of outer copies round it — or null outside every copy, or where the
|
|
21
|
+
* wrapper's zone key or index cannot be read.
|
|
22
|
+
*/
|
|
23
|
+
declare function repeatCopyAt(el: Element): RepeatCopy | null;
|
|
24
|
+
|
|
25
|
+
export { type RepeatCopy as R, repeatCopyAt as r };
|
package/dist/data/index.d.ts
CHANGED
|
@@ -316,6 +316,9 @@ declare function getList(data: Data, config: DataConfig, address: SlotAddress):
|
|
|
316
316
|
* A document already in shape is returned as the same object.
|
|
317
317
|
*/
|
|
318
318
|
declare function normalizeData(data: DataInput | Data, config: DataConfig): Data;
|
|
319
|
+
/** A plain copy that shares nothing with the original; `undefined` stays
|
|
320
|
+
* `undefined`. The one deep copy of the package (a document is JSON). */
|
|
321
|
+
declare function clone<T>(value: T): T;
|
|
319
322
|
/**
|
|
320
323
|
* A new block, the way the Add panel makes one — the old library's `insert` recipe:
|
|
321
324
|
* `{ ...defaultProps, id }`, plus any `props` the caller starts it with. The
|
|
@@ -380,4 +383,4 @@ declare function replaceNode(data: Data, config: DataConfig, id: string, node: N
|
|
|
380
383
|
/** Merge `patch` into the root's props, the same way `setProps` does. */
|
|
381
384
|
declare function setRoot(data: Data, config: DataConfig, patch: Record<string, unknown>): Data;
|
|
382
385
|
|
|
383
|
-
export { Data, DataConfig, DataError, type DataErrorCode, type DataInput, Found, Node, Place, ROOT_ID, ROOT_LIST, ROOT_SLOT, type Segment, SlotAddress, SlotEntry, type TranslatableItem, type TranslatablePath, type TranslatedValue, type TranslationEntries, type TranslationOverlay, type TranslationRef, type TranslationStatus, WalkInfo, applyTranslation, copyNode, copyTranslation, createNode, duplicate, extractTranslation, find, getIn, getList, insert, isNode, isNodeList, mapIds, move, newId, normalizeData, parseZoneKey, pruneTranslation, rebaseTranslation, remove, replaceNode, setProps, setRoot, slotsOf, translatablePaths, translationFingerprint, translationStatus, walk, zoneKey };
|
|
386
|
+
export { Data, DataConfig, DataError, type DataErrorCode, type DataInput, Found, Node, Place, ROOT_ID, ROOT_LIST, ROOT_SLOT, type Segment, SlotAddress, SlotEntry, type TranslatableItem, type TranslatablePath, type TranslatedValue, type TranslationEntries, type TranslationOverlay, type TranslationRef, type TranslationStatus, WalkInfo, applyTranslation, clone, copyNode, copyTranslation, createNode, duplicate, extractTranslation, find, getIn, getList, insert, isNode, isNodeList, mapIds, move, newId, normalizeData, parseZoneKey, pruneTranslation, rebaseTranslation, remove, replaceNode, setProps, setRoot, slotsOf, translatablePaths, translationFingerprint, translationStatus, walk, zoneKey };
|
package/dist/data/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{DataError,ROOT_ID,ROOT_LIST,ROOT_SLOT,applyTranslation,changedProps,copyNode,copyTranslation,createNode,createResolveCache,deepEqual,duplicate,extractTranslation,find,getList,insert,mapIds,move,newId,normalizeData,parseZoneKey,pruneTranslation,rebaseTranslation,remove,replaceNode,resolveNodeData,setProps,setRoot,slotsOf,translatablePaths,translationFingerprint,translationStatus,walk,zoneKey}from"../chunk-
|
|
1
|
+
export{DataError,ROOT_ID,ROOT_LIST,ROOT_SLOT,applyTranslation,changedProps,clone,copyNode,copyTranslation,createNode,createResolveCache,deepEqual,duplicate,extractTranslation,find,getList,insert,mapIds,move,newId,normalizeData,parseZoneKey,pruneTranslation,rebaseTranslation,remove,replaceNode,resolveNodeData,setProps,setRoot,slotsOf,translatablePaths,translationFingerprint,translationStatus,walk,zoneKey}from"../chunk-EUFDQ4KL.js";export{getIn,isNode,isNodeList}from"../chunk-KXM6YRG2.js";
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A TEMPLATE DRAWN MANY TIMES (section parts plan §3.2, row B5, 2026-10-23).
|
|
3
|
+
*
|
|
4
|
+
* A data block (a product grid, a list of posts) holds ONE `template` slot of
|
|
5
|
+
* real blocks and draws it once per data row. So the same block ids are in the
|
|
6
|
+
* canvas several times. The host wraps each drawn copy:
|
|
7
|
+
*
|
|
8
|
+
* <div data-sf-repeat="<ownerId>:template" data-sf-repeat-index={i}>
|
|
9
|
+
*
|
|
10
|
+
* Index 0 is the MAIN copy. The blocks inside keep their real
|
|
11
|
+
* `data-easel-block` / `data-easel-dnd` ids in every copy, so a click on any
|
|
12
|
+
* copy selects the template block. What the canvas does with the copies:
|
|
13
|
+
* - the hover and the selected outline are drawn on every copy;
|
|
14
|
+
* - only the main copy's lists are drop targets (the others are pictures);
|
|
15
|
+
* - a lookup of one element by id reads the main copy.
|
|
16
|
+
*
|
|
17
|
+
* The two names are written HERE, once. The website draws the wrappers with
|
|
18
|
+
* them (it imports them from `efficient-easel/draw`, a render entry), so the
|
|
19
|
+
* string is never typed twice. Pure DOM, no import, nothing run at import.
|
|
20
|
+
*
|
|
21
|
+
* A page with no `data-sf-repeat` gets the same answers as before: every
|
|
22
|
+
* helper below falls back to the first match.
|
|
23
|
+
*/
|
|
24
|
+
/** The wrapper round one drawn copy of a template: `"<ownerId>:<slot>"`. */
|
|
25
|
+
declare const REPEAT_ATTRIBUTE = "data-sf-repeat";
|
|
26
|
+
/** Which copy the wrapper holds: `"0"` is the main copy. */
|
|
27
|
+
declare const REPEAT_INDEX_ATTRIBUTE = "data-sf-repeat-index";
|
|
28
|
+
/**
|
|
29
|
+
* Is `el` in a copy that is NOT the main one — inside (or itself) a wrapper
|
|
30
|
+
* whose index is not 0, at any depth (a template inside a copy of an outer
|
|
31
|
+
* template is a copy too)? False for a block in no wrapper at all.
|
|
32
|
+
*/
|
|
33
|
+
declare function isRepeatCopy(el: Element): boolean;
|
|
34
|
+
/** The main copy among `matches`: the first that is not a copy, else the first. */
|
|
35
|
+
declare function mainCopyOf<T extends Element>(matches: Iterable<T>): T | null;
|
|
36
|
+
/**
|
|
37
|
+
* `root.querySelector(selector)`, but the main copy when a template is drawn
|
|
38
|
+
* many times. With no `data-sf-repeat` it is exactly `querySelector`.
|
|
39
|
+
*/
|
|
40
|
+
declare function queryMainCopy<T extends Element = Element>(root: ParentNode, selector: string): T | null;
|
|
41
|
+
/**
|
|
42
|
+
* The element for `selector` in every drawn copy: the main copy first, then
|
|
43
|
+
* each other copy in page order. With no `data-sf-repeat` it is the first
|
|
44
|
+
* match alone, as `querySelector` answers — a second element with the same id
|
|
45
|
+
* that is not a drawn copy is never added.
|
|
46
|
+
*/
|
|
47
|
+
declare function queryAllCopies<T extends Element = Element>(root: ParentNode, selector: string): T[];
|
|
48
|
+
/**
|
|
49
|
+
* THE WRAPPER ROUND ONE DRAWN COPY (card copy typing, 2026-10-30): the
|
|
50
|
+
* nearest element with BOTH names (a wrapper missing its index is passed
|
|
51
|
+
* over), its zone key as written (`"<ownerId>:<slot>"`) and its index — or
|
|
52
|
+
* null outside every copy, or where the index is not a whole number. The
|
|
53
|
+
* zone key is read by the data layer's one parser (`efficient-easel/data`
|
|
54
|
+
* `parseZoneKey`, in `easel/copy-place`): this file imports nothing, because
|
|
55
|
+
* `draw` reads it.
|
|
56
|
+
*/
|
|
57
|
+
declare function repeatWrapperAt(el: Element): {
|
|
58
|
+
wrapper: Element;
|
|
59
|
+
zone: string;
|
|
60
|
+
index: number;
|
|
61
|
+
} | null;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The small facts every canvas surface needs, written once — pure DOM, no
|
|
65
|
+
* React, nothing run at import.
|
|
66
|
+
*
|
|
67
|
+
* Each answers a question both editors used to answer for themselves, and
|
|
68
|
+
* sometimes differently (the blueprint's §2 rows 6–10):
|
|
69
|
+
*
|
|
70
|
+
* isTypingTarget is this keystroke someone TYPING, so a shortcut must stay out?
|
|
71
|
+
* nodeIdAt which block did this pointer event land on?
|
|
72
|
+
* frameScale how much is the canvas frame scaled (a phone view drawn small)?
|
|
73
|
+
* frameRectToHost where is a box measured INSIDE the frame, on the host page?
|
|
74
|
+
* fitCanvas how wide is the canvas, and at what scale does it fit?
|
|
75
|
+
* canvas styles a stylesheet that lives in the canvas document ONLY.
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Is the event's target somewhere a person TYPES — a text field, a textarea, a
|
|
79
|
+
* native select, an editable region? A shortcut (undo, delete, copy style) must
|
|
80
|
+
* not fire there: the key belongs to the field. Duck-typed rather than
|
|
81
|
+
* `instanceof`, because a canvas element belongs to the frame's own realm and
|
|
82
|
+
* is not an instance of the host's `HTMLElement`.
|
|
83
|
+
*/
|
|
84
|
+
declare function isTypingTarget(target: EventTarget | null): boolean;
|
|
85
|
+
/** The attribute on every block the canvas draws. */
|
|
86
|
+
declare const BLOCK_ATTRIBUTE = "data-easel-block";
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The id of the block a pointer event landed on: the NEAREST ancestor (or the
|
|
90
|
+
* target itself) carrying `attribute`. `null` on bare canvas.
|
|
91
|
+
*/
|
|
92
|
+
declare function nodeIdAt(target: EventTarget | null, attribute?: string): string | null;
|
|
93
|
+
/**
|
|
94
|
+
* The box a block DREW, in its frame's viewport (8.2.0). Most blocks draw inside
|
|
95
|
+
* the canvas's wrapper, and the wrapper's own box is the answer. A block whose
|
|
96
|
+
* drawing leaves the wrapper's flow (the website's header bar is
|
|
97
|
+
* `position: fixed`) leaves the wrapper with no height; then the union of what
|
|
98
|
+
* it drew is the box: each child element with a box of its own, and inside a
|
|
99
|
+
* child with none (a host's own wrapper divs round the bar), what that child
|
|
100
|
+
* drew, the same way. Never null: a wrapper with nothing drawn is its own empty
|
|
101
|
+
* box.
|
|
102
|
+
*/
|
|
103
|
+
declare function drawnBox(el: Element): Box;
|
|
104
|
+
/** Whether one element holds the other (or is it): the same words, however the host stamps them. */
|
|
105
|
+
declare function related(a: Element, b: Element): boolean;
|
|
106
|
+
/** How far the box round typed or selected words stands clear of them, in px
|
|
107
|
+
* (Lewis 2026-10-14). The one home: the canvas sets `--es-words-clear` from
|
|
108
|
+
* it (`.is-typing`, `.is-selected.is-words` read that, easel.css) and the
|
|
109
|
+
* drag layer measures the handle's corner from it. */
|
|
110
|
+
declare const WORDS_CLEAR = 4;
|
|
111
|
+
interface Box {
|
|
112
|
+
left: number;
|
|
113
|
+
top: number;
|
|
114
|
+
width: number;
|
|
115
|
+
height: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* How much the frame is drawn scaled on the host page: its on-screen width over
|
|
119
|
+
* its layout width. The storefront draws tablet and phone at their real widths
|
|
120
|
+
* and scales the frame down to fit the pane; the campaign designer does not
|
|
121
|
+
* scale. 1 when the frame has no layout width yet.
|
|
122
|
+
*/
|
|
123
|
+
declare function frameScale(frame: HTMLElement): number;
|
|
124
|
+
/**
|
|
125
|
+
* A box measured INSIDE the frame (an element's getBoundingClientRect in the
|
|
126
|
+
* frame's own viewport) as a box on the HOST page, relative to `origin` — the
|
|
127
|
+
* overlay layer the box will be drawn in — and through the frame's scale. The
|
|
128
|
+
* scale is the term both apps' own conversions left out on a scaled view.
|
|
129
|
+
*/
|
|
130
|
+
declare function frameRectToHost(frame: HTMLElement, box: Box, origin?: Element | null): Box;
|
|
131
|
+
/**
|
|
132
|
+
* How much `el` is drawn scaled on screen: its on-screen width over its layout
|
|
133
|
+
* width. 1 when it is not scaled, or has no layout width yet. An overlay that
|
|
134
|
+
* shares a scaled ancestor with the frame (the storefront scales the whole
|
|
135
|
+
* device box, frame and overlay together) is scaled too, and its own CSS pixels
|
|
136
|
+
* are then that much smaller or larger than the screen's.
|
|
137
|
+
*/
|
|
138
|
+
declare function elementScale(el: Element): number;
|
|
139
|
+
/**
|
|
140
|
+
* A box measured inside the frame as a box in `layer`'s OWN CSS coordinates —
|
|
141
|
+
* what an absolutely positioned child of `layer` is placed with. The same as
|
|
142
|
+
* `frameRectToHost` when the layer is not scaled; when it shares a scaled
|
|
143
|
+
* ancestor with the frame, every screen distance is divided back into the
|
|
144
|
+
* layer's pixels, or everything it draws lands the scale's factor away.
|
|
145
|
+
*/
|
|
146
|
+
declare function frameRectToLayer(frame: HTMLElement, box: Box, layer: Element): Box;
|
|
147
|
+
/** A pointer position on the HOST page (clientX/clientY there) in `layer`'s own CSS coordinates. */
|
|
148
|
+
declare function clientPointToLayer(layer: Element, x: number, y: number): {
|
|
149
|
+
x: number;
|
|
150
|
+
y: number;
|
|
151
|
+
};
|
|
152
|
+
/** A pointer position inside the frame (clientX/clientY there) on the host page. */
|
|
153
|
+
declare function framePointToHost(frame: HTMLElement, x: number, y: number, origin?: Element | null): {
|
|
154
|
+
x: number;
|
|
155
|
+
y: number;
|
|
156
|
+
};
|
|
157
|
+
interface CanvasFit {
|
|
158
|
+
/** The canvas's layout width — the device's, or the pane's for a fluid view. */
|
|
159
|
+
width: number;
|
|
160
|
+
/** The scale that fits `width` into the pane, capped at `maxScale`. */
|
|
161
|
+
scale: number;
|
|
162
|
+
/** What the canvas occupies on screen: `width * scale`. */
|
|
163
|
+
shownWidth: number;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The canvas width and scale for a pane `available` px wide. A device with no
|
|
167
|
+
* width of its own (desktop, an email's inbox view) takes the pane's width at
|
|
168
|
+
* scale 1; a device width that does not fit is scaled down to fit, and one that
|
|
169
|
+
* does is scaled up no further than `maxScale` (the storefront allows 2; pass 1
|
|
170
|
+
* for "never enlarge").
|
|
171
|
+
*/
|
|
172
|
+
declare function fitCanvas({ available, width, maxScale, }: {
|
|
173
|
+
available: number;
|
|
174
|
+
width?: number | null;
|
|
175
|
+
maxScale?: number;
|
|
176
|
+
}): CanvasFit;
|
|
177
|
+
/**
|
|
178
|
+
* Say which CSP nonce the stylesheets this module puts in `doc` must carry —
|
|
179
|
+
* for a host whose policy allows inline styles by nonce (`style-src
|
|
180
|
+
* 'nonce-…'`), where a `<style>` without it is refused. Every sheet
|
|
181
|
+
* `upsertCanvasStyle` / `useCanvasStyle` creates in `doc` afterwards wears it.
|
|
182
|
+
*
|
|
183
|
+
* `CanvasFrame` (`efficient-easel/easel`) calls this with its `nonce` prop as
|
|
184
|
+
* it builds the frame, so a host says it once; a host that builds its own
|
|
185
|
+
* frame calls it itself. `undefined` (or `''`) forgets it.
|
|
186
|
+
*/
|
|
187
|
+
declare function setCanvasNonce(doc: Document, nonce: string | undefined): void;
|
|
188
|
+
/**
|
|
189
|
+
* Put `css` in the canvas document's `<head>` under `key`, replacing what that
|
|
190
|
+
* key held before. It lives in the canvas ONLY — not mirrored from the host
|
|
191
|
+
* head, so it cannot leak into the host page, and not dependent on anyone
|
|
192
|
+
* noticing a change to it. Writes nothing when the text is already current.
|
|
193
|
+
* A new sheet carries the document's nonce, when it was given one
|
|
194
|
+
* ({@link setCanvasNonce}).
|
|
195
|
+
*/
|
|
196
|
+
declare function upsertCanvasStyle(doc: Document, key: string, css: string): HTMLStyleElement;
|
|
197
|
+
/** Take `key`'s stylesheet out of the canvas document, if it is there. */
|
|
198
|
+
declare function removeCanvasStyle(doc: Document, key: string): void;
|
|
199
|
+
|
|
200
|
+
export { BLOCK_ATTRIBUTE as B, type CanvasFit as C, REPEAT_ATTRIBUTE as R, WORDS_CLEAR as W, REPEAT_INDEX_ATTRIBUTE as a, type Box as b, clientPointToLayer as c, drawnBox as d, elementScale as e, fitCanvas as f, framePointToHost as g, frameRectToHost as h, frameRectToLayer as i, frameScale as j, isRepeatCopy as k, isTypingTarget as l, mainCopyOf as m, nodeIdAt as n, queryMainCopy as o, removeCanvasStyle as p, queryAllCopies as q, related as r, repeatWrapperAt as s, setCanvasNonce as t, upsertCanvasStyle as u };
|
package/dist/drag/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, CSSProperties, ReactNode } from 'react';
|
|
3
3
|
import { P as Place } from '../types-Dq180WRV.js';
|
|
4
|
-
import { D as DragSession } from '../
|
|
5
|
-
export { a as
|
|
6
|
-
export { B as Box, a as CanvasDragLayer, b as CanvasDragLayerProps, C as CanvasDragModel, c as CanvasDropTarget, d as CanvasSeam, e as CanvasSource, f as CanvasZone, E as EMPTY_MEASURE, H as HANDLE_GRACE_MS, M as MeasuredCanvas, g as MeasuredNode, h as canvasTarget, i as contains, j as gapInZone, k as gapLine, l as insertSeams, m as measureCanvas, p as pickSource, s as seamsBetween, n as sourcesAt } from '../CanvasDragLayer-NZpaX6aq.js';
|
|
4
|
+
import { D as DragSession } from '../CanvasDragLayer-DXeQGrwJ.js';
|
|
5
|
+
export { B as Box, a as CanvasDragLayer, b as CanvasDragLayerProps, C as CanvasDragModel, c as CanvasDropTarget, d as CanvasSeam, e as CanvasSource, f as CanvasZone, g as DragHeld, E as EMPTY_MEASURE, H as HANDLE_GRACE_MS, M as MeasuredCanvas, h as MeasuredNode, i as canvasTarget, j as contains, k as createDragSession, l as gapInZone, m as gapLine, n as insertSeams, o as measureCanvas, p as pickSource, s as seamsBetween, q as sourcesAt } from '../CanvasDragLayer-DXeQGrwJ.js';
|
|
7
6
|
import { D as DragWords } from '../words-SD4neL0n.js';
|
|
8
7
|
import '../watch-Unf6SfUf.js';
|
|
9
8
|
|
package/dist/drag/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{AddPanel,CanvasDragLayer,CanvasInsert,EMPTY_MEASURE,HANDLE_GRACE_MS,canvasTarget,contains,gapInZone,gapLine,insertSeams,measureCanvas,pickSource,seamsBetween,sourcesAt}from"../chunk-
|
|
1
|
+
export{AddPanel,CanvasDragLayer,CanvasInsert,EMPTY_MEASURE,HANDLE_GRACE_MS,canvasTarget,contains,gapInZone,gapLine,insertSeams,measureCanvas,pickSource,seamsBetween,sourcesAt}from"../chunk-SQTVXE5D.js";import"../chunk-TQ5Y6S2X.js";export{AUTO_SCROLL_EDGE,AUTO_SCROLL_MAX_SPEED,autoScrollDelta,autoScrollSpeed,createDragSession,dropEffectFor,dropOnRow,frameScrollBox,gapToMoveIndex,isNoOpDrop,scrollBoxOf,scrollParent,startAutoScroll,stepGap,useTreeDrag}from"../chunk-3XECMGXX.js";import"../chunk-P2VEMZH5.js";import"../chunk-TOKMFZPB.js";import"../chunk-FR7EEKFF.js";import"../chunk-7UFKEX72.js";import"../chunk-EUFDQ4KL.js";import"../chunk-KXM6YRG2.js";
|
package/dist/draw/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export { RowNameRule, rootRowName, sectionRenameProp, slotChildName, slotChildRe
|
|
|
6
6
|
export { FOOTER_TYPE, HEADER_TYPE, NodeLocation, ROOT_ZONE, SlotConfigView, TREE_MAX_DEPTH, TreeItem, blockNodeActions, childSlotsOf, locateNode, missingPinnedTypes, nestsInTree, newNodeId, pinnedDuplicateIds, pinnedDuplicateIndices, slotChildrenIn, slotFieldsOf } from '../screen/lib/document/content-tree.js';
|
|
7
7
|
export { AUTO_RULES, AutoRule, FOLLOW_RULES, VIEW_DESKTOP_MIN, VIEW_TABLET_MIN, VIEW_TIERS, VIEW_TIER_LABEL, ViewTier, ViewValueKind, ViewValues, isAuto, phoneKey, resolveViewValue, tabletKey, viewTierForWidth } from '../screen/lib/content/view-tiers.js';
|
|
8
8
|
export { HERO_SLIDER_GOTO_EVENT, HeroSliderGotoDetail } from '../screen/lib/document/preview-events.js';
|
|
9
|
-
export { R as REPEAT_ATTRIBUTE, a as REPEAT_INDEX_ATTRIBUTE } from '../
|
|
9
|
+
export { B as BLOCK_ATTRIBUTE, R as REPEAT_ATTRIBUTE, a as REPEAT_INDEX_ATTRIBUTE } from '../dom-BpxMcHFP.js';
|
|
10
10
|
export { TEXT_STYLE_CASES, TEXT_STYLE_CASE_CSS, TextStyleCase, TextStyleCaseCss, isTextStyleCase, textStyleCaseCss, textStyleCaseOfCss } from '../text-styles/model.js';
|
|
11
11
|
import '../words-B5Gb7KFq.js';
|
package/dist/draw/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{SCALAR_TEXT_CONTROLS,TEXT_CONTROL_KINDS}from"../chunk-I6SK6ZDT.js";export{AUTO_RULES,FOLLOW_RULES,VIEW_DESKTOP_MIN,VIEW_TABLET_MIN,VIEW_TIERS,VIEW_TIER_LABEL,isAuto,phoneKey,resolveViewValue,tabletKey,viewTierForWidth}from"../chunk-E52W3M5I.js";export{rootRowName,sectionRenameProp,slotChildName,slotChildRenameProp,slotChildRowName}from"../chunk-5NHQ452C.js";export{hidableText,readHidable}from"../chunk-6UAEFOJ4.js";export{
|
|
1
|
+
export{SCALAR_TEXT_CONTROLS,TEXT_CONTROL_KINDS}from"../chunk-I6SK6ZDT.js";export{AUTO_RULES,FOLLOW_RULES,VIEW_DESKTOP_MIN,VIEW_TABLET_MIN,VIEW_TIERS,VIEW_TIER_LABEL,isAuto,phoneKey,resolveViewValue,tabletKey,viewTierForWidth}from"../chunk-E52W3M5I.js";export{HERO_SLIDER_GOTO_EVENT}from"../chunk-AJ2SUSET.js";export{rootRowName,sectionRenameProp,slotChildName,slotChildRenameProp,slotChildRowName}from"../chunk-5NHQ452C.js";export{hidableText,readHidable}from"../chunk-6UAEFOJ4.js";export{ANCHOR_FIELD_KEYS,FOLD_FIELD_MARKER,LINK_FIELD_MARKER,MEDIA_FIELD_MARKER,SCAFFOLD_FIELD_MARKER,TEXT_FIELD_MARKER,foldMetaOf,textFieldIdentifier}from"../chunk-ANPOR6EY.js";export{PART_SEP,decodePartId,encodePartId}from"../chunk-R4AUZVA3.js";export{FOOTER_TYPE,HEADER_TYPE,ROOT_ZONE,TREE_MAX_DEPTH,blockNodeActions,childSlotsOf,locateNode,missingPinnedTypes,nestsInTree,newNodeId,pinnedDuplicateIds,pinnedDuplicateIndices,slotChildrenIn,slotFieldsOf}from"../chunk-TCAAOYQY.js";export{TEXT_STYLE_CASES,TEXT_STYLE_CASE_CSS,isTextStyleCase,textStyleCaseCss,textStyleCaseOfCss}from"../chunk-YHZSBL2N.js";export{BLOCK_ATTRIBUTE}from"../chunk-FR7EEKFF.js";export{REPEAT_ATTRIBUTE,REPEAT_INDEX_ATTRIBUTE}from"../chunk-7UFKEX72.js";
|
package/dist/easel/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { c as ResolveTrigger, a as ResolveCache, R as ResolvableItem } from '../
|
|
|
8
8
|
import * as react from 'react';
|
|
9
9
|
import { ReactNode, CSSProperties, ComponentType, ReactElement } from 'react';
|
|
10
10
|
import { TextToolbarProps } from 'efficient-shell/ui';
|
|
11
|
+
import { R as RepeatCopy } from '../copy-place-CQIemdtU.js';
|
|
12
|
+
export { r as repeatCopyAt } from '../copy-place-CQIemdtU.js';
|
|
11
13
|
import { C as CopyBoxLastTool, a as CopyThemeColor, b as CanvasTypingEnd } from '../canvas-typing-DOBx8dD3.js';
|
|
12
14
|
import { InlineRule } from 'efficient-shell/markup';
|
|
13
15
|
import { b as NodeOpsHost, C as ClipboardEntry } from '../useNodeOps-igxrnEhq.js';
|
|
@@ -452,6 +454,13 @@ interface CanvasTypingTarget {
|
|
|
452
454
|
skip?: string;
|
|
453
455
|
/** The host's ONE writer for these words — the panel's text box's. */
|
|
454
456
|
write: (next: string) => void;
|
|
457
|
+
/**
|
|
458
|
+
* The prop of the words' block these words are saved in (`text`). Given,
|
|
459
|
+
* words typed in a drawn copy of a card template go to the host's
|
|
460
|
+
* `CanvasTyping.onCopyText` with it; left out, they are written through
|
|
461
|
+
* `write` as before.
|
|
462
|
+
*/
|
|
463
|
+
key?: string;
|
|
455
464
|
/** Draw the words afresh (after an IME composition wrote into them). */
|
|
456
465
|
remount?: () => void;
|
|
457
466
|
/**
|
|
@@ -500,6 +509,58 @@ interface CanvasTyping {
|
|
|
500
509
|
atSelection?: () => CanvasTypingTarget | null;
|
|
501
510
|
/** Typing started or ended: the host's text toolbar comes to the words, its panel follows. */
|
|
502
511
|
onChange?: (state: CanvasTypingState) => void;
|
|
512
|
+
/**
|
|
513
|
+
* Words typed in a DRAWN COPY of a card template (card copy typing,
|
|
514
|
+
* 2026-10-30). A copy is drawn for a row of its owner's data, so what it
|
|
515
|
+
* shows is the row's, not the template's: each write of the session (every
|
|
516
|
+
* edit step, an undo in the words included) comes here with the copy's
|
|
517
|
+
* place instead of going through the target's `write`. Asked only when the
|
|
518
|
+
* words are inside a `data-sf-repeat` wrapper (`repeatCopyAt`) — the
|
|
519
|
+
* main copy, row 0, too — and the target names its `key`. The session
|
|
520
|
+
* starts from `copyValue`'s answer; with none, from the template's string
|
|
521
|
+
* when the copy draws it, else from the words the copy SHOWS (plain: their
|
|
522
|
+
* marks are not known). Enter after a click on a copy types that copy.
|
|
523
|
+
*
|
|
524
|
+
* Return `false` to say these words are the template's own (the block is
|
|
525
|
+
* not bound to the row): easel writes them through the target's `write`,
|
|
526
|
+
* as before. Left out, typing in a copy is what it was.
|
|
527
|
+
*/
|
|
528
|
+
onCopyText?: (edit: CanvasCopyText) => boolean | void;
|
|
529
|
+
/**
|
|
530
|
+
* The copy's words AS SAVED, in the string's grammar (`rules`): the row's
|
|
531
|
+
* value with its marks (bold, a link, a colour), for the session to start
|
|
532
|
+
* from, so the first key keeps them. Asked when a copy session starts.
|
|
533
|
+
* `undefined`, or left out: the session starts as `onCopyText` says.
|
|
534
|
+
* Return `undefined` wherever `onCopyText` would return `false` (words
|
|
535
|
+
* that are the template's own): a row's string there would start the
|
|
536
|
+
* session from words `write` does not hold.
|
|
537
|
+
*/
|
|
538
|
+
copyValue?: (copy: CanvasCopyPlace) => string | undefined;
|
|
539
|
+
}
|
|
540
|
+
/** A drawn copy's words: the copy's place (`RepeatCopy`, its `outer` chain
|
|
541
|
+
* included), the template block the words are in and the prop they are
|
|
542
|
+
* saved in (`CanvasTypingTarget.key`). */
|
|
543
|
+
type CanvasCopyPlace = RepeatCopy & {
|
|
544
|
+
nodeId: string;
|
|
545
|
+
key: string;
|
|
546
|
+
};
|
|
547
|
+
/** Words typed in a drawn copy (`CanvasTyping.onCopyText`): where, and what. */
|
|
548
|
+
interface CanvasCopyText {
|
|
549
|
+
/** The block whose slot is drawn once per row. */
|
|
550
|
+
ownerId: string;
|
|
551
|
+
/** That slot (`template`). */
|
|
552
|
+
slot: string;
|
|
553
|
+
/** The row the copy is drawn for; 0 is the main copy. */
|
|
554
|
+
index: number;
|
|
555
|
+
/** The copy of an outer template this copy's owner is drawn in, when
|
|
556
|
+
* there is one (`RepeatCopy.outer`): the inner index alone names no row. */
|
|
557
|
+
outer?: RepeatCopy;
|
|
558
|
+
/** The template block the words are in. */
|
|
559
|
+
nodeId: string;
|
|
560
|
+
/** The prop the words are saved in (`CanvasTypingTarget.key`). */
|
|
561
|
+
key: string;
|
|
562
|
+
/** The words, in the string's grammar (`rules`), after this edit. */
|
|
563
|
+
text: string;
|
|
503
564
|
}
|
|
504
565
|
interface EaselCanvasProps {
|
|
505
566
|
/** Draw in an iframe of the easel's own (default), or straight into the page. */
|
|
@@ -632,6 +693,11 @@ interface SelectedFields {
|
|
|
632
693
|
* selected when the change began.
|
|
633
694
|
*/
|
|
634
695
|
declare function useSelectedFields(): SelectedFields;
|
|
696
|
+
/** The selected node's host, or `null` outside an editor (a guard, a harness),
|
|
697
|
+
* where `useSelectedFields` throws: a row then reads nothing and writes
|
|
698
|
+
* nothing. The ONE place that catch is made. Called unconditionally, so hook
|
|
699
|
+
* order never changes. */
|
|
700
|
+
declare function useSelectedHost(): SelectedFields | null;
|
|
635
701
|
/**
|
|
636
702
|
* The ROOT's fields and write, whatever is selected: `useSelectedFields` with
|
|
637
703
|
* nothing selected, for a panel that edits the page beside a selection — the
|
|
@@ -679,4 +745,4 @@ declare function bindUndoKeys(doc: Document, easel: Pick<Easel, 'undo' | 'redo'>
|
|
|
679
745
|
leaveTyping?: boolean;
|
|
680
746
|
}): () => void;
|
|
681
747
|
|
|
682
|
-
export { CHROME_ATTR, type CanvasChrome, CanvasChromeContext, CanvasFrame, type CanvasFrameProps, type CanvasOverlay, type CanvasPart, type CanvasParts, CanvasPartsContext, CanvasPassThroughContext, CanvasSharedContext, type CanvasSlotProps, type CanvasTyping, type CanvasTypingState, type CanvasTypingTarget, DEFAULT_UI, type Easel, EaselAction, EaselCanvas, type EaselCanvasProps, EaselConfig, EaselCore, type EaselOptions, EaselProvider, type EaselProviderProps, EaselUi, EaselView, EditDocument, NodeSelection, Permissions, type SelectedFields, bindUndoKeys, createEasel, createUseEasel, partHasOwnBox, recordsByDefault, reduce, uiView, useEasel, useEaselApi, useEaselNodeOps, useRootFields, useSelectedFields, validSelection };
|
|
748
|
+
export { CHROME_ATTR, type CanvasChrome, CanvasChromeContext, type CanvasCopyPlace, type CanvasCopyText, CanvasFrame, type CanvasFrameProps, type CanvasOverlay, type CanvasPart, type CanvasParts, CanvasPartsContext, CanvasPassThroughContext, CanvasSharedContext, type CanvasSlotProps, type CanvasTyping, type CanvasTypingState, type CanvasTypingTarget, DEFAULT_UI, type Easel, EaselAction, EaselCanvas, type EaselCanvasProps, EaselConfig, EaselCore, type EaselOptions, EaselProvider, type EaselProviderProps, EaselUi, EaselView, EditDocument, NodeSelection, Permissions, RepeatCopy, type SelectedFields, bindUndoKeys, createEasel, createUseEasel, partHasOwnBox, recordsByDefault, reduce, uiView, useEasel, useEaselApi, useEaselNodeOps, useRootFields, useSelectedFields, useSelectedHost, validSelection };
|
package/dist/easel/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{CHROME_ATTR,CanvasChromeContext,CanvasFrame,CanvasPartsContext,CanvasPassThroughContext,CanvasSharedContext,DEFAULT_UI,EaselCanvas,EaselProvider,EditDocument,bindUndoKeys,createEasel,createUseEasel,partHasOwnBox,recordsByDefault,reduce,uiView,useEasel,useEaselApi,useEaselNodeOps,useRootFields,useSelectedFields,validSelection}from"../chunk-
|
|
1
|
+
export{CHROME_ATTR,CanvasChromeContext,CanvasFrame,CanvasPartsContext,CanvasPassThroughContext,CanvasSharedContext,DEFAULT_UI,EaselCanvas,EaselProvider,EditDocument,bindUndoKeys,createEasel,createUseEasel,partHasOwnBox,recordsByDefault,reduce,uiView,useEasel,useEaselApi,useEaselNodeOps,useRootFields,useSelectedFields,useSelectedHost,validSelection}from"../chunk-BBD3FLU3.js";export{repeatCopyAt}from"../chunk-JQQFB7EZ.js";import"../chunk-TBY3DFKS.js";import"../chunk-K53PQAMP.js";import"../chunk-QTHQPJWA.js";import"../chunk-HZSZT3BE.js";import"../chunk-PMRN5Z3T.js";import"../chunk-MFIRYGHW.js";import"../chunk-TOKMFZPB.js";import"../chunk-FR7EEKFF.js";import"../chunk-7UFKEX72.js";import"../chunk-EUFDQ4KL.js";import"../chunk-KXM6YRG2.js";
|
|
@@ -20,52 +20,6 @@ type LockWords = {
|
|
|
20
20
|
someone: string;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
/**
|
|
24
|
-
* Who may WRITE the open document, and what to tell the operator when they may
|
|
25
|
-
* not — for EVERY editor in the house.
|
|
26
|
-
*
|
|
27
|
-
* This module is the merge of two files that had grown side by side and said
|
|
28
|
-
* the same things in two places (card 11161):
|
|
29
|
-
*
|
|
30
|
-
* * `efficient-admin-portal/src/components/email/campaignEditLock.ts` — the
|
|
31
|
-
* campaign designer's copy, which alone had the TAKE-OVER half;
|
|
32
|
-
* * `efficient-storefront/lib/editor-page-lock.ts` — the storefront editor's copy,
|
|
33
|
-
* which alone had the claim/heartbeat driver, the auth-rejection rule and
|
|
34
|
-
* the "a template has no lock" rule.
|
|
35
|
-
*
|
|
36
|
-
* Neither was a subset of the other, so this file keeps EVERY capability of
|
|
37
|
-
* both, and both editors now import it instead of carrying a copy.
|
|
38
|
-
*
|
|
39
|
-
* TWO INDEPENDENT PROTECTIONS, and it matters which is which:
|
|
40
|
-
*
|
|
41
|
-
* * the SAVE-TIME version check is what actually protects work. The backend
|
|
42
|
-
* refuses a document write whose base version has moved on, so no amount of
|
|
43
|
-
* client-side confusion can erase a colleague's edits. Nothing here can
|
|
44
|
-
* weaken it — the token travels with the write and the server decides.
|
|
45
|
-
* * this advisory LOCK only stops two people STARTING, and is soft on
|
|
46
|
-
* purpose: it expires, it can always be taken over, and — see
|
|
47
|
-
* `accessAfterClaimFailure` — it FAILS OPEN. A lock that could refuse to
|
|
48
|
-
* let anybody edit would be worse than no lock at all. A save consults it
|
|
49
|
-
* in one case only: a tab somebody TOOK the document from is refused
|
|
50
|
-
* (`EDIT_LOCK_TAKEN`, read by `readLockTaken`), so it stops at its next
|
|
51
|
-
* save instead of its next heartbeat.
|
|
52
|
-
*
|
|
53
|
-
* The backend rule is one rule shared by both (efficient/editlock.py). These
|
|
54
|
-
* are two CONSUMERS of one server-side contract, which is exactly why one
|
|
55
|
-
* client module can serve them.
|
|
56
|
-
*
|
|
57
|
-
* WHAT IS NOT SHARED, and why there is a factory rather than plain functions:
|
|
58
|
-
* the two editors talk to the backend through different HTTP clients, so a
|
|
59
|
-
* failure arrives as an `AxiosError` in one and as an `ApiError` in the other,
|
|
60
|
-
* and the refused-save payload carries a different `code`. Those two facts —
|
|
61
|
-
* and nothing else — are handed in by the consumer through `createEditLock`.
|
|
62
|
-
* The module itself imports no HTTP client and knows about no repo.
|
|
63
|
-
*
|
|
64
|
-
* LEAF DISCIPLINE: pure TypeScript. No React, no `document`/`window`, no
|
|
65
|
-
* dependency at all. `crypto` is touched inside a function, never at module
|
|
66
|
-
* eval, so a Next server component may import this module safely.
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
23
|
/** The `edit-lock` body — identical for every editable document. */
|
|
70
24
|
type EditLockBody = {
|
|
71
25
|
held_by_you: boolean;
|
package/dist/edit-lock/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{CLAIM_FAIL_OPEN_MS,EDIT_LOCK_TAKEN,FAIL_OPEN_RETRY_MS,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEaselClientId,openUnansweredClaim,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-
|
|
1
|
+
export{CLAIM_FAIL_OPEN_MS,EDIT_LOCK_TAKEN,FAIL_OPEN_RETRY_MS,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEaselClientId,openUnansweredClaim,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-YYD257TD.js";import"../chunk-RE4LP46F.js";import"../chunk-EUFDQ4KL.js";import"../chunk-KXM6YRG2.js";
|
package/dist/fields/fields.css
CHANGED
|
@@ -129,46 +129,12 @@ span:has(> .es-fnum) { display: flex; min-width: 0; }
|
|
|
129
129
|
.es-list-row-main { flex: 1 1 auto; min-width: 0; min-height: 32px; display: flex; align-items: center; font-size: var(--text-xs, 12px); color: var(--es-text); }
|
|
130
130
|
.es-list-row-main > * { flex: 1 1 auto; min-width: 0; }
|
|
131
131
|
|
|
132
|
-
/* A many-field item:
|
|
133
|
-
.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
gap: 4px;
|
|
139
|
-
height: 32px;
|
|
140
|
-
padding: 0;
|
|
141
|
-
border: 0;
|
|
142
|
-
background: none;
|
|
143
|
-
color: var(--es-text);
|
|
144
|
-
font: inherit;
|
|
145
|
-
font-size: var(--text-xs, 12px);
|
|
146
|
-
text-align: left;
|
|
147
|
-
cursor: inherit;
|
|
148
|
-
}
|
|
149
|
-
.es-list-open:focus-visible { outline: 2px solid var(--es-accent); outline-offset: 1px; border-radius: var(--radius-sm); }
|
|
150
|
-
.es-list-thumb { flex: none; display: inline-flex; align-items: center; }
|
|
151
|
-
.es-list-row-name { flex: none; font-weight: 600; white-space: nowrap; }
|
|
152
|
-
.es-list-row-summary { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--es-muted); }
|
|
153
|
-
.es-list-chev { flex: none; color: var(--es-icon); transition: transform 0.12s; }
|
|
154
|
-
.es-list-row.is-open .es-list-chev { transform: rotate(90deg); }
|
|
155
|
-
|
|
156
|
-
.es-list-x {
|
|
157
|
-
flex: none;
|
|
158
|
-
width: 28px;
|
|
159
|
-
height: 32px;
|
|
160
|
-
border: 0;
|
|
161
|
-
border-radius: var(--es-row-radius);
|
|
162
|
-
background: transparent;
|
|
163
|
-
color: var(--es-muted);
|
|
164
|
-
font: inherit;
|
|
165
|
-
font-size: var(--text-base, 16px);
|
|
166
|
-
line-height: 1;
|
|
167
|
-
cursor: pointer;
|
|
168
|
-
}
|
|
169
|
-
.es-list-x:hover:not(:disabled) { background: var(--es-danger-tint); color: var(--es-danger); }
|
|
170
|
-
.es-list-x:disabled { color: var(--es-disabled); cursor: default; }
|
|
171
|
-
.es-list-x:focus-visible { outline: 2px solid var(--es-accent); outline-offset: 2px; }
|
|
132
|
+
/* A many-field item: the shell's fold button (`ListRow` `title` / `onToggle`)
|
|
133
|
+
holds its name and, after it, its summary — quiet beside the bold name. */
|
|
134
|
+
.es-list-row-name,
|
|
135
|
+
.es-list-row-summary { font-size: var(--text-xs, 12px); }
|
|
136
|
+
.es-list-row-summary { margin-left: var(--es-space-4, 4px); font-weight: 400; color: var(--es-muted); }
|
|
137
|
+
|
|
172
138
|
.es-list-lock {
|
|
173
139
|
flex: none;
|
|
174
140
|
width: 28px;
|
package/dist/fields/index.d.ts
CHANGED
|
@@ -433,11 +433,6 @@ declare function insertAt<T>(items: readonly T[], index: number, item: T): T[];
|
|
|
433
433
|
declare function moveTo<T>(items: readonly T[], from: number, to: number): T[];
|
|
434
434
|
/** The list without the item at `index`. */
|
|
435
435
|
declare function removeAt<T>(items: readonly T[], index: number): T[];
|
|
436
|
-
/**
|
|
437
|
-
* A copy of an item: a deep copy of plain data, so editing the copy never
|
|
438
|
-
* writes through to the original (a list item is JSON — the old library stored it so).
|
|
439
|
-
*/
|
|
440
|
-
declare function copyItem<T>(item: T): T;
|
|
441
436
|
declare function ListField<T>({ label, icon, noun: ownNoun, items, onChange, newItem, summary, itemName, thumb, min, max, readOnly, open, onOpen, renderItem, renderRow, canRemove: removable, lockedReason, fixed, removeOnRow, canDuplicate, above, head, }: ListFieldProps<T>): react.JSX.Element;
|
|
442
437
|
|
|
443
438
|
/**
|
|
@@ -552,4 +547,4 @@ declare function optionFor<V>(options: readonly FieldOption<V>[], value: V | und
|
|
|
552
547
|
declare function FieldSelect<V>(props: FieldSelectManyProps<V>): ReactNode;
|
|
553
548
|
declare function FieldSelect<V>(props: FieldSelectOneProps<V>): ReactNode;
|
|
554
549
|
|
|
555
|
-
export { FieldNumber, FieldNumberProps, FieldOption, type FieldPlan, FieldRenderer, FieldSelect, FieldSelectManyProps, FieldSelectOneProps, FieldSlider, FieldSliderProps, FieldText, FieldTextProps, type FieldsBlock, Inspector, InspectorField, InspectorFieldDef, type InspectorFieldProps, InspectorFields, type InspectorProps, ListField, type ListFieldProps, type PlannedFold, type PlannedRow, type ResolvedFieldsInput, SettingsBucket, type ShowWhenInput, bucketsOf,
|
|
550
|
+
export { FieldNumber, FieldNumberProps, FieldOption, type FieldPlan, FieldRenderer, FieldSelect, FieldSelectManyProps, FieldSelectOneProps, FieldSlider, FieldSliderProps, FieldText, FieldTextProps, type FieldsBlock, Inspector, InspectorField, InspectorFieldDef, type InspectorFieldProps, InspectorFields, type InspectorProps, ListField, type ListFieldProps, type PlannedFold, type PlannedRow, type ResolvedFieldsInput, SettingsBucket, type ShowWhenInput, bucketsOf, fieldIsShown, fieldShownInView, insertAt, labelOf, moveTo, optionFor, planFields, removeAt, shownFields, useResolvedFields };
|
package/dist/fields/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{FieldText,Inspector,InspectorField,LinkPicker,ListField,bucketsOf,
|
|
1
|
+
export{FieldText,Inspector,InspectorField,LinkPicker,ListField,bucketsOf,fieldShownInView,insertAt,labelOf,moveTo,planFields,removeAt}from"../chunk-U3LTJSBU.js";export{fieldIsShown,showWhenOf,shownFields,withShowWhen}from"../chunk-BPXEFVSQ.js";import"../chunk-YCSZAP7T.js";export{FieldSlider}from"../chunk-ZEH6QLBH.js";import"../chunk-WHS6Y55E.js";import"../chunk-FM6JO4WF.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";export{useResolvedFields}from"../chunk-K53PQAMP.js";import"../chunk-FIVU2COQ.js";export{FieldNumber}from"../chunk-Y2T3JX7K.js";export{FieldSelect,optionFor}from"../chunk-KFWNGPW3.js";import"../chunk-MIX7EGRG.js";import"../chunk-DX3VILZ3.js";import"../chunk-JACEEVVF.js";import"../chunk-MFIRYGHW.js";import"../chunk-3XECMGXX.js";import"../chunk-P2VEMZH5.js";import"../chunk-EUFDQ4KL.js";import"../chunk-KXM6YRG2.js";
|
package/dist/node-ops/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{createNodeClipboard,nodeMenuItems}from"../chunk-P5VYGWYO.js";import"../chunk-WK3AFPXY.js";export{canStep,clickPick,clickPickPart,fromItemSelector,nextInChain,nodeChain,parentStep,planDuplicate,planMove,planPaste,planRemove,planRestore,planSetProps,planStep,planSwap,toItemSelector,useNodeOps}from"../chunk-
|
|
1
|
+
export{createNodeClipboard,nodeMenuItems}from"../chunk-P5VYGWYO.js";import"../chunk-WK3AFPXY.js";export{canStep,clickPick,clickPickPart,fromItemSelector,nextInChain,nodeChain,parentStep,planDuplicate,planMove,planPaste,planRemove,planRestore,planSetProps,planStep,planSwap,toItemSelector,useNodeOps}from"../chunk-QTHQPJWA.js";import"../chunk-EUFDQ4KL.js";import"../chunk-KXM6YRG2.js";
|