efficient-easel 0.99.2 → 0.100.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 +233 -17
- package/dist/autosave/index.d.ts +11 -5
- package/dist/blocks/index.d.ts +1 -1
- package/dist/canvas/index.d.ts +2 -2
- package/dist/canvas/index.js +1 -1
- package/dist/chrome/chrome.css +96 -29
- package/dist/chrome/index.d.ts +67 -18
- package/dist/chrome/index.js +17 -21
- package/dist/chunk-3EDSDPIP.js +1 -0
- package/dist/chunk-67GNT6PF.js +1 -0
- package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
- package/dist/chunk-A5UK76FC.js +6 -0
- package/dist/chunk-AZT7V4UM.js +10 -0
- package/dist/chunk-DICUMYMG.js +12 -0
- package/dist/chunk-HDVD27VB.js +1 -0
- package/dist/chunk-JQM3V7XQ.js +1 -0
- package/dist/chunk-JUQ6YJCG.js +1 -0
- package/dist/chunk-LA54QLP5.js +1 -0
- package/dist/chunk-LGKQXSKO.js +16 -0
- package/dist/chunk-M6F6LS3H.js +1 -0
- package/dist/chunk-MH5GUZFQ.js +9 -0
- package/dist/chunk-P6O363EE.js +6 -0
- package/dist/chunk-PAELDYYS.js +1 -0
- package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
- package/dist/chunk-SAJUCHOX.js +1 -0
- package/dist/chunk-TRVZ7C23.js +1 -0
- package/dist/chunk-V7GIIXFB.js +16 -0
- package/dist/chunk-WZ7TGAAT.js +3 -0
- package/dist/chunk-ZJEBF4NB.js +1 -0
- package/dist/copy/copy.css +388 -5
- package/dist/copy/index.d.ts +268 -5
- package/dist/copy/index.js +31 -10
- package/dist/drag/drag.css +10 -1
- package/dist/drag/index.d.ts +99 -8
- package/dist/drag/index.js +18 -17
- package/dist/easel/easel.css +15 -0
- package/dist/easel/index.d.ts +104 -33
- package/dist/easel/index.js +9 -1
- package/dist/edit-lock/index.d.ts +1 -3
- package/dist/edit-lock/index.js +1 -1
- package/dist/fields/fields.css +103 -26
- package/dist/fields/index.d.ts +47 -9
- package/dist/fields/index.js +30 -46
- package/dist/gold/index.js +1 -1
- package/dist/icons/index.d.ts +10 -1
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/markup/index.d.ts +94 -10
- package/dist/markup/index.js +1 -1
- package/dist/menu/index.d.ts +58 -5
- package/dist/menu/index.js +15 -15
- package/dist/menu/menu.css +17 -6
- package/dist/node-ops/index.d.ts +1 -1
- package/dist/node-ops/index.js +1 -1
- package/dist/panel/index.d.ts +72 -4
- package/dist/panel/index.js +18 -16
- package/dist/panel/panel.css +56 -1
- package/dist/pick/index.d.ts +39 -1
- package/dist/pick/index.js +7 -14
- package/dist/pick/pick.css +14 -0
- package/dist/rail/index.d.ts +3 -7
- package/dist/rail/index.js +1 -1
- package/dist/strings/catalogue.d.ts +13 -35
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +12 -18
- package/dist/strings/index.js +2 -2
- package/dist/style-clipboard/index.d.ts +1 -1
- package/dist/style-clipboard/index.js +1 -1
- package/dist/text-styles/index.d.ts +328 -0
- package/dist/text-styles/index.js +38 -0
- package/dist/text-styles/text-styles.css +309 -0
- package/dist/tree/index.d.ts +43 -2
- package/dist/tree/index.js +1 -1
- package/dist/tree/tree.css +71 -0
- package/dist/{types-p9j2Fac7.d.ts → types-DGcCsxs8.d.ts} +72 -7
- package/dist/{types-Bs_gVkVI.d.ts → types-DWS-s9z-.d.ts} +1 -9
- package/dist/{types-DO-b0LNj.d.ts → types-Djdq6Xkd.d.ts} +9 -8
- package/dist/{types-BOSGNvil.d.ts → types-E3HrTPg2.d.ts} +7 -13
- package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
- package/dist/{watch-B5RTR-WX.d.ts → watch-BTYOJpQU.d.ts} +18 -1
- package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
- package/dist/{words-c-3h9xQQ.d.ts → words-BMzV04b1.d.ts} +1 -1
- package/dist/words-CJjUKcV5.d.ts +37 -0
- package/dist/words-CRYvAiHX.d.ts +105 -0
- package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
- package/dist/{words-C74EUpFr.d.ts → words-DBq7vfHy.d.ts} +57 -4
- package/dist/{words-N4ebT88_.d.ts → words-DgHcY5qB.d.ts} +9 -3
- package/package.json +8 -8
- package/dist/chunk-66CKSTXP.js +0 -14
- package/dist/chunk-672FAEKU.js +0 -1
- package/dist/chunk-67VZRQLG.js +0 -13
- package/dist/chunk-6PS6STGA.js +0 -1
- package/dist/chunk-7A7O2JWQ.js +0 -1
- package/dist/chunk-7JTL3P6P.js +0 -1
- package/dist/chunk-F2PIG3AA.js +0 -10
- package/dist/chunk-H4B72XCJ.js +0 -1
- package/dist/chunk-KDIVA6WD.js +0 -1
- package/dist/chunk-MCLBHENY.js +0 -1
- package/dist/chunk-QB3BZIRA.js +0 -5
- package/dist/chunk-SJQG5ENJ.js +0 -1
- package/dist/chunk-SUO5627P.js +0 -1
- package/dist/chunk-XUE5O62R.js +0 -3
- package/dist/chunk-ZT7M24XD.js +0 -1
- package/dist/editor/index.d.ts +0 -10
- package/dist/editor/index.js +0 -1
- /package/dist/{chunk-2PHD4L6A.js → chunk-OWBO4WKA.js} +0 -0
package/dist/drag/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
import { P as Place, S as SlotAddress } from '../types-41704JE4.js';
|
|
4
|
-
import { C as CanvasTarget$1 } from '../watch-
|
|
4
|
+
import { C as CanvasTarget$1 } from '../watch-BTYOJpQU.js';
|
|
5
5
|
import { D as DragWords } from '../words-BDignMl_.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -117,6 +117,12 @@ declare function stepGap(from: Place, dir: -1 | 1): Place;
|
|
|
117
117
|
*
|
|
118
118
|
* A drop the host refuses draws nothing and cannot land; a drop that would leave
|
|
119
119
|
* the row where it was draws nothing either. Leaving the tree clears the line.
|
|
120
|
+
*
|
|
121
|
+
* An EMPTY list is not a seam: a seam is the gap between two rows and takes
|
|
122
|
+
* back the space it adds, so alone in a list it is a strip nobody can aim at.
|
|
123
|
+
* Draw `efficient-easel/tree`'s `TreeEmptySlot` there, with the same `seam()`:
|
|
124
|
+
*
|
|
125
|
+
* <TreeEmptySlot {...drag.seam({ place: { ...list, index: 0 } })} onAdd={…} />
|
|
120
126
|
*/
|
|
121
127
|
|
|
122
128
|
type TreeDragOptions<I> = {
|
|
@@ -179,7 +185,8 @@ declare function useTreeDrag<I>(options: TreeDragOptions<I>): TreeDrag<I>;
|
|
|
179
185
|
* pixels apart); a parent is picked up by hovering its own padding.
|
|
180
186
|
* - THE ZONE: the innermost list under the pointer that will take the drop. A
|
|
181
187
|
* refused inner zone falls through to the next one out — a section dragged
|
|
182
|
-
* over a column lands between sections, not nowhere.
|
|
188
|
+
* over a column lands between sections, not nowhere. (Decided again on
|
|
189
|
+
* 2026-10-07; see `canvasTarget`.)
|
|
183
190
|
* - THE GAP: along the zone's own axis — down a column, ACROSS a row of
|
|
184
191
|
* columns — counted against the children's midpoints; the line is drawn in
|
|
185
192
|
* the middle of that gap, horizontal or vertical to match.
|
|
@@ -239,8 +246,27 @@ type CanvasTarget = {
|
|
|
239
246
|
* outside it. A drop that would leave the thing where it is lands NOWHERE — it
|
|
240
247
|
* does not fall through to an outer list, which would move it somewhere the
|
|
241
248
|
* pointer is not.
|
|
249
|
+
*
|
|
250
|
+
* ── THE FALL-THROUGH STAYS, AND A HOST MAY END IT (second host, 2026-10-07) ──
|
|
251
|
+
* A host reported it as a surprise: a Columns block dragged onto a column,
|
|
252
|
+
* which refuses columns, landed at the top level instead of being refused; and
|
|
253
|
+
* a block picked up INSIDE a container, held over a part of that container
|
|
254
|
+
* that will not take it, left the container for the page.
|
|
255
|
+
*
|
|
256
|
+
* It stays the rule, for three reasons. A page is covered by its inner lists:
|
|
257
|
+
* without the fall-through a section could be dropped only on the few pixels
|
|
258
|
+
* of the page's own list that show between sections. Both editors this was
|
|
259
|
+
* built for have shipped on it. And it is not silent: the line is drawn where
|
|
260
|
+
* the drop WILL land before the button is let go, across the page for a drop
|
|
261
|
+
* the page takes.
|
|
262
|
+
*
|
|
263
|
+
* But what surprises is the host's to know — the engine never learns what a
|
|
264
|
+
* column is — so the host may answer for each refusal: `fallThrough(refused)`
|
|
265
|
+
* is asked with the place that just refused, and `false` ends it there. The
|
|
266
|
+
* drop lands nowhere, no line is drawn, and the browser shows it refused.
|
|
267
|
+
* Left out, every refusal falls through, as before.
|
|
242
268
|
*/
|
|
243
|
-
declare function canvasTarget(zones: readonly CanvasZone[], x: number, y: number, accept: (to: Place) => boolean, isNoOp?: (to: Place) => boolean): CanvasTarget;
|
|
269
|
+
declare function canvasTarget(zones: readonly CanvasZone[], x: number, y: number, accept: (to: Place) => boolean, isNoOp?: (to: Place) => boolean, fallThrough?: (refused: Place) => boolean): CanvasTarget;
|
|
244
270
|
/** The seams between a zone's children — where "+ Add section" goes. */
|
|
245
271
|
declare function seamsBetween(zone: CanvasZone, keyPrefix?: string): CanvasSeam[];
|
|
246
272
|
|
|
@@ -271,6 +297,19 @@ type CanvasDragLayerProps<I> = {
|
|
|
271
297
|
model: (measured: MeasuredCanvas) => CanvasDragModel<I>;
|
|
272
298
|
canDrop: (item: I, to: Place) => boolean;
|
|
273
299
|
onDrop: (item: I, to: Place) => void;
|
|
300
|
+
/**
|
|
301
|
+
* A drop the innermost list under the pointer refuses is offered to the next
|
|
302
|
+
* list out: a section held over a column lands between sections, and the
|
|
303
|
+
* line shows where (./canvasHit). Answer `false` here to END it at the list
|
|
304
|
+
* that refused — nothing is drawn and nothing lands — for a drop where
|
|
305
|
+
* falling through would surprise: a Columns block over a column, or a block
|
|
306
|
+
* leaving the container it was picked up in.
|
|
307
|
+
*
|
|
308
|
+
* Asked only about a place `canDrop` has just refused: `refused` is that
|
|
309
|
+
* place, `from` where the thing was picked up (absent for a new one, from
|
|
310
|
+
* the Add list). Left out, every refusal falls through.
|
|
311
|
+
*/
|
|
312
|
+
fallThrough?: (item: I, refused: Place, from?: Place) => boolean;
|
|
274
313
|
/** The handle CLICKED, not dragged: select what it names. Absent: a click does nothing. */
|
|
275
314
|
onPick?: (item: I) => void;
|
|
276
315
|
/** "+ Add section" in a seam: open the Add panel at that place. */
|
|
@@ -296,6 +335,15 @@ type CanvasDragLayerProps<I> = {
|
|
|
296
335
|
declare const HANDLE_GRACE_MS = 140;
|
|
297
336
|
declare function CanvasDragLayer<I>(props: CanvasDragLayerProps<I>): react.JSX.Element;
|
|
298
337
|
|
|
338
|
+
/**
|
|
339
|
+
* One thing the Add list offers.
|
|
340
|
+
*
|
|
341
|
+
* `readOnly` is the whole panel's; `disabled` is one tile's (second host,
|
|
342
|
+
* 2026-10-07): a block that may not be added JUST NOW — a second Header —
|
|
343
|
+
* stays where a merchant looks for it, dimmed, and says why. A block that may
|
|
344
|
+
* be added only in some places is not disabled: that is the host's `canDrop`
|
|
345
|
+
* to refuse and its `onInsert` to place.
|
|
346
|
+
*/
|
|
299
347
|
type AddTile = {
|
|
300
348
|
/** The block's type — what `onInsert` and `itemFor` are given. */
|
|
301
349
|
type: string;
|
|
@@ -309,6 +357,16 @@ type AddTile = {
|
|
|
309
357
|
/** A picture of what it adds — a section's thumbnail. Every tile of a group
|
|
310
358
|
* having one lays the group out as cards. */
|
|
311
359
|
cover?: ReactNode;
|
|
360
|
+
/**
|
|
361
|
+
* It cannot be added just now. The tile stays in the list, dimmed, and is
|
|
362
|
+
* still found by search and counted by its group; a click adds nothing and
|
|
363
|
+
* a drag does not start. `aria-disabled`, not the native attribute, so the
|
|
364
|
+
* tile keeps the focus and its reason can be reached from the keyboard.
|
|
365
|
+
*/
|
|
366
|
+
disabled?: boolean;
|
|
367
|
+
/** Why, in the host's words ("A page has one header"): a disabled tile's
|
|
368
|
+
* tooltip, in place of "Add …". Left out, a disabled tile has none. */
|
|
369
|
+
disabledReason?: string;
|
|
312
370
|
};
|
|
313
371
|
type AddGroup = {
|
|
314
372
|
title: string;
|
|
@@ -342,6 +400,26 @@ type AddPanelProps<I> = {
|
|
|
342
400
|
};
|
|
343
401
|
declare function AddPanel<I>({ groups, session, itemFor, onInsert, at, hint: ownHint, searchLabel: ownSearchLabel, readOnly, words, }: AddPanelProps<I>): react.JSX.Element;
|
|
344
402
|
|
|
403
|
+
/**
|
|
404
|
+
* The effect a drop target names (second host, 2026-10-06).
|
|
405
|
+
*
|
|
406
|
+
* A browser lands a drop only if the `dropEffect` the target named in its last
|
|
407
|
+
* `dragover` is one the source's `effectAllowed` includes. Otherwise the cursor
|
|
408
|
+
* says "no" and `drop` NEVER FIRES: the line is drawn and nothing lands.
|
|
409
|
+
*
|
|
410
|
+
* The surfaces here start two kinds of drag. A row or a block picked up is a
|
|
411
|
+
* MOVE (`effectAllowed = 'move'`); a tile from the Add list is a COPY (it stays
|
|
412
|
+
* in the list). So a target cannot name one effect for both — it names one the
|
|
413
|
+
* source allowed, and the cursor then says what will happen: a move, or a "+".
|
|
414
|
+
*
|
|
415
|
+
* Read from the event, not from the session: it is the browser that holds the
|
|
416
|
+
* drop to it. And ONE function for every surface. Until then the canvas had
|
|
417
|
+
* this rule inline and the tree named "move" for everything, so a tile could be
|
|
418
|
+
* dropped on the canvas and never on the tree — and jsdom, which does not
|
|
419
|
+
* enforce drag effects, let the spec for it pass.
|
|
420
|
+
*/
|
|
421
|
+
declare function dropEffectFor(effectAllowed: string): 'move' | 'copy';
|
|
422
|
+
|
|
345
423
|
/**
|
|
346
424
|
* Scroll the list while a drag is held near its top or bottom edge (blueprint
|
|
347
425
|
* step 3.1).
|
|
@@ -357,7 +435,7 @@ declare function AddPanel<I>({ groups, session, itemFor, onInsert, at, hint: own
|
|
|
357
435
|
* - further than 56px OUTSIDE the box, nothing: the pointer has gone elsewhere.
|
|
358
436
|
*
|
|
359
437
|
* Nothing here reads a global at import; the document and the frame clock come
|
|
360
|
-
* from the element
|
|
438
|
+
* from the element the pointer is held against.
|
|
361
439
|
*/
|
|
362
440
|
declare const AUTO_SCROLL_EDGE = 56;
|
|
363
441
|
declare const AUTO_SCROLL_MAX_SPEED = 16;
|
|
@@ -369,11 +447,24 @@ declare function autoScrollDelta(y: number, top: number, bottom: number): number
|
|
|
369
447
|
declare function scrollParent(el: Element | null): HTMLElement | null;
|
|
370
448
|
/** `el` itself if it scrolls, else the nearest ancestor that does. */
|
|
371
449
|
declare function scrollBoxOf(el: HTMLElement | null): HTMLElement | null;
|
|
450
|
+
/**
|
|
451
|
+
* A canvas frame's own scrolling element, if its document is longer than the
|
|
452
|
+
* frame — a frame that fills its pane and scrolls itself
|
|
453
|
+
* (`EaselCanvas height="fill"`). Null for a frame as tall as its content,
|
|
454
|
+
* which the host's pane scrolls.
|
|
455
|
+
*/
|
|
456
|
+
declare function frameScrollBox(doc: Document): HTMLElement | null;
|
|
372
457
|
/**
|
|
373
458
|
* Scroll `box` while a drag is live. Reads the pointer from a capturing
|
|
374
|
-
* `dragover` on the
|
|
375
|
-
*
|
|
459
|
+
* `dragover` on the document the drag is IN, and holds it against the top and
|
|
460
|
+
* bottom of `edges`. Returns the stop.
|
|
461
|
+
*
|
|
462
|
+
* `edges` is the box itself, for a list or a pane in the page. For a canvas
|
|
463
|
+
* frame that scrolls itself it is the FRAME: what scrolls is the frame's
|
|
464
|
+
* document, but the drag never enters it — the drag layer lies over the frame,
|
|
465
|
+
* in the host page — so the pointer is the host's, and the edges it is held
|
|
466
|
+
* near are the frame element's (second host, 2026-10-06).
|
|
376
467
|
*/
|
|
377
|
-
declare function startAutoScroll(box: HTMLElement): () => void;
|
|
468
|
+
declare function startAutoScroll(box: HTMLElement, edges?: Element): () => void;
|
|
378
469
|
|
|
379
|
-
export { AUTO_SCROLL_EDGE, AUTO_SCROLL_MAX_SPEED, type AddGroup, AddPanel, type AddPanelProps, type AddTile, type Box, CanvasDragLayer, type CanvasDragLayerProps, type CanvasDragModel, type CanvasTarget as CanvasDropTarget, type CanvasSeam, type CanvasSource, type CanvasZone, type DragHeld, type DragSession, DragWords, type DropRow, type DropSide, type DropSpot, EMPTY_MEASURE, HANDLE_GRACE_MS, type MeasuredCanvas, type MeasuredNode, type TreeDrag, type TreeDragOptions, type TreeDragRowOptions, type TreeDragRowProps, type TreeDragSeamOptions, type TreeDragSeamProps, autoScrollDelta, autoScrollSpeed, canvasTarget, contains, createDragSession, dropOnRow, gapInZone, gapLine, gapToMoveIndex, isNoOpDrop, measureCanvas, pickSource, scrollBoxOf, scrollParent, seamsBetween, startAutoScroll, stepGap, useTreeDrag };
|
|
470
|
+
export { AUTO_SCROLL_EDGE, AUTO_SCROLL_MAX_SPEED, type AddGroup, AddPanel, type AddPanelProps, type AddTile, type Box, CanvasDragLayer, type CanvasDragLayerProps, type CanvasDragModel, type CanvasTarget as CanvasDropTarget, type CanvasSeam, type CanvasSource, type CanvasZone, type DragHeld, type DragSession, DragWords, type DropRow, type DropSide, type DropSpot, EMPTY_MEASURE, HANDLE_GRACE_MS, type MeasuredCanvas, type MeasuredNode, type TreeDrag, type TreeDragOptions, type TreeDragRowOptions, type TreeDragRowProps, type TreeDragSeamOptions, type TreeDragSeamProps, autoScrollDelta, autoScrollSpeed, canvasTarget, contains, createDragSession, dropEffectFor, dropOnRow, frameScrollBox, gapInZone, gapLine, gapToMoveIndex, isNoOpDrop, measureCanvas, pickSource, scrollBoxOf, scrollParent, seamsBetween, startAutoScroll, stepGap, useTreeDrag };
|
package/dist/drag/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import{DEFAULT_DRAG_WORDS as e}from"../chunk-O2NLQBFX.js";import{
|
|
2
|
-
/* @__PURE__ */
|
|
3
|
-
/* @__PURE__ */
|
|
4
|
-
return
|
|
5
|
-
/* @__PURE__ */
|
|
6
|
-
/* @__PURE__ */
|
|
7
|
-
/* @__PURE__ */
|
|
8
|
-
/* @__PURE__ */
|
|
9
|
-
/* @__PURE__ */
|
|
10
|
-
/* @__PURE__ */
|
|
11
|
-
/* @__PURE__ */
|
|
12
|
-
/* @__PURE__ */
|
|
13
|
-
/* @__PURE__ */
|
|
14
|
-
/* @__PURE__ */
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
/* @__PURE__ */
|
|
17
|
-
|
|
1
|
+
import{DEFAULT_DRAG_WORDS as e}from"../chunk-O2NLQBFX.js";import{dropEffectFor as t,scrollBoxOf as n,frameScrollBox as l,startAutoScroll as r,isNoOpDrop as a}from"../chunk-67GNT6PF.js";export{AUTO_SCROLL_EDGE,AUTO_SCROLL_MAX_SPEED,autoScrollDelta,autoScrollSpeed,createDragSession,dropEffectFor,dropOnRow,frameScrollBox,gapToMoveIndex,isNoOpDrop,scrollBoxOf,scrollParent,startAutoScroll,stepGap,useTreeDrag}from"../chunk-67GNT6PF.js";import{useCanvasLayout as o,useCanvasEvent as s}from"../chunk-PAELDYYS.js";import{framePointToHost as i,elementScale as c,frameRectToLayer as d,clientPointToLayer as u}from"../chunk-ZNCEOSXO.js";import{CloseIcon as h,SearchIcon as p}from"../chunk-6EIVTKZZ.js";import{parseZoneKey as f}from"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";import{useRef as m,useEffect as g,useState as b,useCallback as y,useMemo as v,useSyncExternalStore as x,useId as k,useLayoutEffect as w}from"react";import{jsxs as N,jsx as D}from"react/jsx-runtime";var A=(e,t,n)=>t>=e.left&&t<=e.left+e.width&&n>=e.top&&n<=e.top+e.height,S=e=>e.width*e.height;function T(e,t,n){let l=null;for(const r of e)A(r.box,t,n)&&(!l||S(r.box)<=S(l.box))&&(l=r);return l}function z(e,t,n){const l="x"===e.axis?t:n;let r=0;for(const t of e.children){l>("x"===e.axis?t.left+t.width/2:t.top+t.height/2)&&(r+=1)}return r}function E(e,t){const n=e.children;if("x"===e.axis){const l=n[t-1],r=n[t],a=l&&r?(l.left+l.width+r.left)/2:l?l.left+l.width:r?r.left:e.box.left,o=r??l??e.box;return{left:a-1,top:o.top,width:2,height:o.height}}const l=n[t-1],r=n[t],a=l&&r?(l.top+l.height+r.top)/2:l?l.top+l.height:r?r.top:e.box.top;return{left:e.box.left,top:a-1,width:e.box.width,height:2}}function C(e,t,n,l,r=()=>!1,a=()=>!0){const o=e.filter(e=>A(e.box,t,n)).sort((e,t)=>S(e.box)-S(t.box));for(const e of o){const o=z(e,t,n),s={...e.list,index:o};if(r(s))return null;if(l(s))return{zone:e,to:s,line:E(e,o)};if(!a(s))return null}return null}function L(e,t=e.key){const n=[];for(let l=1;l<e.children.length;l++){const r=e.children[l-1],a=e.children[l],o=r.top+r.height;n.push({key:`${t}:${l}`,place:{...e.list,index:l},box:{left:e.box.left,top:o,width:e.box.width,height:Math.max(a.top-o,0)}})}return n}var O={nodes:[],zones:[]},j="data-puck-dropzone",B="data-puck-component";function K(e,t){if(e.length>=2){const[t,n]=e;return Math.abs(n.top-t.top)<Math.min(t.height,n.height)/2&&n.left>t.left?"x":"y"}const n=t.ownerDocument.defaultView?.getComputedStyle(t);return n&&n.display.includes("flex")&&n.flexDirection.startsWith("row")?"x":"y"}function M(e,t){const{frame:n,document:l}=e,r=e=>d(n,function(e){const t=e.getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}(e),t),a=[],o=[];for(const e of l.querySelectorAll(`[${j}]`)){const t=e.getAttribute(j)??"";let n;try{n=f(t)}catch{continue}const l=[...e.querySelectorAll(`[${B}]`)].filter(t=>t.parentElement?.closest(`[${j}]`)===e),s=l.map(r);o.push({key:t,list:n,box:r(e),axis:K(s,e),children:s}),l.forEach((e,t)=>{const l=e.getAttribute(B);l&&a.push({id:l,place:{...n,index:t},box:s[t]})})}return{nodes:a,zones:o}}var $="data-es-empty-cell",P="data-puck-dropzone",X=140;var R=e=>({left:e.left,top:e.top,width:e.width,height:e.height});function q(d){const{canvas:h,session:p,readOnly:f,words:k=e.canvas}=d,A=m(d);g(()=>{A.current=d});const S=m(null),z=o(h),[E,L]=b(0),j=y(()=>L(e=>e+1),[]),[B,K]=b(O);g(()=>{const e=S.current;h&&e&&K((A.current.measure??M)(h,e))},[h,z,d.revision,E]);const X=d.model,q=v(()=>X(B),[X,B]),F=x(p.subscribe,p.shown,p.shown),[Z,_]=b(null),[G,Y]=b(null),I=m(null),V=()=>{I.current&&clearTimeout(I.current),I.current=null},Q=()=>{V(),I.current=setTimeout(()=>{p.get()||_(null)},140)};g(()=>V,[]);const U=m(null);s(h,"mousemove",e=>{const t=S.current;if(!h||!t)return;const n=i(h.frame,e.clientX,e.clientY,t),l=c(t),r={x:n.x/l,y:n.y/l};if(U.current=r,A.current.readOnly||p.get())return;V();const a=T(q.sources,r.x,r.y);_(e=>e?.key===a?.key&&e?.box===a?.box?e:a)}),s(h,"mouseout",e=>{e.relatedTarget||(U.current=null,Q())}),s(h,"mouseover",e=>{e.relatedTarget||j()});const W=m(null),H=y(()=>{W.current?.(),W.current=null,Y(null)},[]);g(()=>p.subscribe(()=>{p.get()?j():H()}),[p,H,j]),g(()=>H,[H]),("undefined"==typeof document?g:w)(()=>{if(p.get())return;const e=U.current;_(t=>f?null:e?T(q.sources,e.x,e.y):t?q.sources.find(e=>e.key===t.key)??null:null)},[q,F,p,f]);const J=e=>{const t=p.get(),n=S.current;if(!t||!n)return null;const l=u(n,e.clientX,e.clientY);U.current=l;const r=C(q.zones,l.x,l.y,e=>A.current.canDrop(t.item,e),e=>!!t.from&&a(t.from,e),e=>A.current.fallThrough?.(t.item,e,t.from)??!0);return r?{h:t,t:r}:null},ee={onDragEnter:e=>{if(W.current)return;const t=n(e.currentTarget.parentElement?.parentElement??null),a=h?l(h.document):null,o=[];t&&o.push(r(t)),a&&h&&o.push(r(a,h.frame)),W.current=o.length?()=>o.forEach(e=>e()):null},onDragOver:e=>{const n=J(e);if(!n)return void Y(null);e.preventDefault(),e.dataTransfer.dropEffect=t(e.dataTransfer.effectAllowed);const l={zoneKey:n.t.zone.key,line:n.t.line,axis:n.t.zone.axis};Y(e=>e&&e.zoneKey===l.zoneKey&&e.line.left===l.line.left&&e.line.top===l.line.top?e:l)},onDragLeave:e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||(U.current=null,Y(null))},onDrop:e=>{const t=J(e);t&&(e.preventDefault(),p.end(),H(),A.current.onDrop(t.h.item,t.t.to))}},te={draggable:!f&&!!Z,onMouseEnter:V,onMouseLeave:()=>!p.get()&&Q(),onDragStart:e=>{if(Z&&!f){p.start({key:Z.key,item:Z.item,from:Z.from}),e.dataTransfer.effectAllowed="move";try{e.dataTransfer.setData("text/plain",Z.key)}catch{}}else e.preventDefault()},onDragEnd:()=>{p.end(),H()},onClick:()=>{Z&&!f&&A.current.onPick?.(Z.item)}},{seams:ne=[]}=q,le=q.zones.filter(e=>0===e.children.length),re=d.onZoneAdd&&!f?le:[],ae=re.map(e=>e.key).join("\n");return g(()=>{const e=h?.document;if(!e)return;const t=new Set(ae?ae.split("\n"):[]);for(const n of e.querySelectorAll(`[${P}]`))n.toggleAttribute($,t.has(n.getAttribute(P)??""));return()=>{for(const t of e.querySelectorAll(`[${$}]`))t.removeAttribute($)}},[h,ae,B,z,E]),/* @__PURE__ */N("div",{ref:S,className:"es-canvas-layer",children:[F||!d.onSeamAdd||f?null:ne.map(e=>/* @__PURE__ */D("div",{className:"es-canvas-seam",style:{left:e.box.left,top:e.box.top+e.box.height/2-8,width:e.box.width,height:16},children:/* @__PURE__ */D("button",{type:"button",className:"es-canvas-seam-add",onClick:()=>d.onSeamAdd?.(e.place),children:k.addButton({label:d.seamLabel??k.addSection})})},e.key)),re.length?re.map(e=>/* @__PURE__ */D("button",{type:"button",className:G?.zoneKey===e.key?"es-canvas-empty is-over":"es-canvas-empty",style:R(e.box),onClick:()=>d.onZoneAdd?.({...e.list,index:0}),children:/* @__PURE__ */D("span",{className:"es-canvas-empty-add",children:k.addButton({label:d.zoneAddLabel??k.addBlock})})},e.key)):null,F?/* @__PURE__ */D("div",{className:"es-canvas-catch",...ee}):null,G&&!le.some(e=>e.key===G.zoneKey)?/* @__PURE__ */D("div",{className:`es-canvas-line is-${G.axis}`,style:R(G.line)}):null,
|
|
2
|
+
/* @__PURE__ */N("div",{className:["es-canvas-handle",Z&&!f?"is-shown":"",F?"is-dragging":""].filter(Boolean).join(" "),style:Z?{left:Z.box.left+2,top:Math.max(Z.box.top-11,0)}:void 0,title:Z?Z.title??k.handle({label:Z.label}):void 0,...te,children:[
|
|
3
|
+
/* @__PURE__ */D("span",{className:"es-canvas-grip","aria-hidden":"true",children:"⋮⋮"}),Z?.label]})]})}var F=e=>e.tiles.length>0&&e.tiles.every(e=>null!=e.cover);function Z({groups:t,session:n,itemFor:l,onInsert:r,at:a,hint:o,searchLabel:s,readOnly:i,words:c=e.add}){const d=o??c.hint,u=s??c.search,[f,m]=b(""),g=k(),y=f.trim().toLowerCase(),v=t.map(e=>({...e,tiles:y?e.tiles.filter(e=>((e,t)=>e.label.toLowerCase().includes(t)||(e.keywords??[]).some(e=>e.toLowerCase().includes(t)))(e,y)):e.tiles})).filter(e=>e.tiles.length>0),x=(e,t)=>r=>{if(t)r.preventDefault();else{n.start({key:`new:${e}`,item:l(e)}),r.dataTransfer.effectAllowed="copy";try{r.dataTransfer.setData("text/plain",e)}catch{}}};/* @__PURE__ */
|
|
4
|
+
return N("div",{className:"es-add",children:[a?/* @__PURE__ */N("div",{className:"es-add-at",role:"status",children:[
|
|
5
|
+
/* @__PURE__ */D("span",{children:a.label}),
|
|
6
|
+
/* @__PURE__ */D("button",{type:"button",className:"es-add-at-clear","aria-label":c.stop,title:c.stop,onClick:a.onClear,children:/* @__PURE__ */D(h,{size:12,"aria-hidden":"true"})})]}):null,
|
|
7
|
+
/* @__PURE__ */D("p",{className:"es-add-hint",children:d}),
|
|
8
|
+
/* @__PURE__ */N("div",{className:"es-add-search",children:[
|
|
9
|
+
/* @__PURE__ */D(p,{size:16,"aria-hidden":"true"}),
|
|
10
|
+
/* @__PURE__ */D("input",{id:g,type:"search","aria-label":u,placeholder:c.searchPlaceholder({label:u}),value:f,onChange:e=>m(e.target.value)}),f?/* @__PURE__ */D("button",{type:"button",className:"es-add-search-clear","aria-label":c.clearSearch,onClick:()=>m(""),children:/* @__PURE__ */D(h,{size:12,"aria-hidden":"true"})}):null]}),0===v.length?/* @__PURE__ */N("div",{className:"es-add-empty",role:"status",children:[
|
|
11
|
+
/* @__PURE__ */D("div",{className:"es-add-empty-title",children:c.nothing({query:f.trim()})}),
|
|
12
|
+
/* @__PURE__ */D("div",{className:"es-add-empty-sub",children:c.tryAnother})]}):v.map(e=>/* @__PURE__ */N("section",{className:"es-add-group","aria-label":e.title,children:[
|
|
13
|
+
/* @__PURE__ */N("div",{className:"es-add-group-head",children:[
|
|
14
|
+
/* @__PURE__ */D("span",{className:"es-add-group-title",children:e.title}),
|
|
15
|
+
/* @__PURE__ */D("span",{className:"es-add-group-count",children:e.tiles.length})]}),
|
|
16
|
+
/* @__PURE__ */D("div",{className:F(e)?"es-add-grid is-cards":"es-add-grid",children:e.tiles.map(e=>{const t=Boolean(i||e.disabled),l=i?void 0:e.disabled?e.disabledReason:e.title??c.tile({label:e.label});/* @__PURE__ */
|
|
17
|
+
return N("button",{type:"button",className:null!=e.cover?"es-add-tile has-cover":"es-add-tile",draggable:!t,"aria-disabled":t||void 0,"aria-label":c.tile({label:e.label}),title:l,onDragStart:x(e.type,t),onDragEnd:()=>n.end(),onClick:()=>!t&&r(e.type),children:[null!=e.cover?/* @__PURE__ */D("span",{className:"es-add-tile-cover","aria-hidden":"true",children:e.cover}):e.icon?/* @__PURE__ */D("span",{className:"es-add-tile-glyph","aria-hidden":"true",children:e.icon}):null,
|
|
18
|
+
/* @__PURE__ */D("span",{className:"es-add-tile-label",children:e.label})]},e.type)})})]},e.title))]})}export{Z as AddPanel,q as CanvasDragLayer,O as EMPTY_MEASURE,X as HANDLE_GRACE_MS,C as canvasTarget,A as contains,z as gapInZone,E as gapLine,M as measureCanvas,T as pickSource,L as seamsBetween};
|
package/dist/easel/easel.css
CHANGED
|
@@ -9,6 +9,21 @@
|
|
|
9
9
|
* no `.es-editor` root to define them.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
/* The frame itself, in the host page (CanvasFrame): no border, the pane's
|
|
13
|
+
width, and — when it fills (`height="fill"`) — the pane's height. Rules, not
|
|
14
|
+
a `style` attribute (second host, 2026-10-06): a server-rendered editor under a
|
|
15
|
+
Content-Security-Policy without 'unsafe-inline' for styles had the attribute
|
|
16
|
+
refused, and drew the browser's own 300×150 bordered frame. An `auto`
|
|
17
|
+
frame's height is measured and written on the client. */
|
|
18
|
+
.es-canvas-frame {
|
|
19
|
+
border: 0;
|
|
20
|
+
width: 100%;
|
|
21
|
+
display: block;
|
|
22
|
+
}
|
|
23
|
+
.es-canvas-frame.is-fill {
|
|
24
|
+
height: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
/* The frame's root (CanvasFrame). Puck's `[data-puck-entry]` rule: a stacking
|
|
13
28
|
context of its own, so a block's z-index stays inside the page. */
|
|
14
29
|
[data-puck-entry] {
|
package/dist/easel/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AppState, e as EaselHistory, f as EditorAction, g as EditorConfig, h as EditorCore, i as EditorHistory, j as EditorUi, k as EditorView, H as HistoryEntry, S as SetDataPatch } from '../types-BOSGNvil.js';
|
|
1
|
+
import { DataInput } from '../data/index.js';
|
|
3
2
|
import { N as NodeSelection } from '../plan-DChbUXdS.js';
|
|
4
3
|
export { I as ItemSelector } from '../plan-DChbUXdS.js';
|
|
5
|
-
import {
|
|
4
|
+
import { E as EaselConfig, a as EaselView, b as EaselAction, P as Permissions, c as EaselCore, d as EaselUi } from '../types-E3HrTPg2.js';
|
|
5
|
+
export { A as AppState, e as EaselHistory, H as HistoryEntry, S as SetDataPatch } from '../types-E3HrTPg2.js';
|
|
6
6
|
import { S as SlotAddress, D as Data, P as Place } from '../types-41704JE4.js';
|
|
7
7
|
import { c as ResolveTrigger, a as ResolveCache, R as ResolvableItem } from '../resolve-D68pb3Bx.js';
|
|
8
8
|
import * as react from 'react';
|
|
9
9
|
import { ReactNode, CSSProperties, ComponentType, ReactElement } from 'react';
|
|
10
10
|
import { b as NodeOpsHost, C as ClipboardEntry } from '../useNodeOps-BF0fQsif.js';
|
|
11
|
-
import { I as InspectorFields } from '../types-
|
|
11
|
+
import { I as InspectorFields } from '../types-VqL6t5HH.js';
|
|
12
12
|
import '../buckets-CuLM47h9.js';
|
|
13
13
|
|
|
14
14
|
interface EaselOptions<C extends EaselConfig = EaselConfig> {
|
|
@@ -17,8 +17,15 @@ interface EaselOptions<C extends EaselConfig = EaselConfig> {
|
|
|
17
17
|
data: DataInput | Data;
|
|
18
18
|
/** The host's own UI keys to start with (and an `itemSelector`, if any). */
|
|
19
19
|
ui?: Record<string, unknown>;
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
20
|
+
/**
|
|
21
|
+
* Called with the new document after every change that changed it — once
|
|
22
|
+
* per `batch`, once per undo / redo. Not called for `load`.
|
|
23
|
+
*
|
|
24
|
+
* THIS is what feeds autosave (`autosave.push`), not `subscribe`: a
|
|
25
|
+
* subscriber is also told of a `load()`, a selection and a permission, and a
|
|
26
|
+
* host that pushed every notification would save the document it had just
|
|
27
|
+
* loaded as if it were an edit.
|
|
28
|
+
*/
|
|
22
29
|
onChange?: (data: Data) => void;
|
|
23
30
|
/** Easel-wide permissions, under each block's own (Puck's `permissions`). */
|
|
24
31
|
permissions?: Partial<Permissions>;
|
|
@@ -32,11 +39,21 @@ interface EaselOptions<C extends EaselConfig = EaselConfig> {
|
|
|
32
39
|
/** The clock, for tests. */
|
|
33
40
|
now?: () => number;
|
|
34
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* `EaselProvider` takes an `Easel<EaselConfig>`, and `createEasel` infers `C`
|
|
44
|
+
* from the config it is handed. A config typed more narrowly than
|
|
45
|
+
* `EaselConfig` (a `Config<…>` from `efficient-easel/blocks`) therefore infers
|
|
46
|
+
* an `Easel<ThatConfig>`, which the provider does not accept (`setConfig`
|
|
47
|
+
* takes a `C`). Say the type: `createEasel<EaselConfig>({ config, … })`.
|
|
48
|
+
*/
|
|
35
49
|
interface Easel<C extends EaselConfig = EaselConfig> {
|
|
36
50
|
/** What `useEasel` reads. The same object until the state changes. */
|
|
37
51
|
getState: () => EaselView<C>;
|
|
38
52
|
subscribe: (listener: () => void) => () => void;
|
|
39
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* One Puck action. Outside a `batch`, one undo step when it records.
|
|
55
|
+
* Permissions are not checked here (see `setPermissions`).
|
|
56
|
+
*/
|
|
40
57
|
dispatch: (action: EaselAction) => void;
|
|
41
58
|
/**
|
|
42
59
|
* Run several changes as ONE: one undo step, one `onChange`, and one
|
|
@@ -65,6 +82,18 @@ interface Easel<C extends EaselConfig = EaselConfig> {
|
|
|
65
82
|
}) => void;
|
|
66
83
|
undo: () => void;
|
|
67
84
|
redo: () => void;
|
|
85
|
+
/**
|
|
86
|
+
* Replace the easel-wide permissions (not merged over the last ones: name
|
|
87
|
+
* every key you mean). Subscribers are told, and `getPermissions` becomes a
|
|
88
|
+
* new function, so a reader of either re-renders — a settings panel reading
|
|
89
|
+
* `getPermissions().edit` follows an edit lock as it is claimed and lost.
|
|
90
|
+
* The same permissions again tell nobody, so it is safe in an effect.
|
|
91
|
+
*
|
|
92
|
+
* These are what the PARTS read (the settings panel, the menus, the undo
|
|
93
|
+
* keys). The store itself enforces none of them: `dispatch`, `run`, `undo`
|
|
94
|
+
* and `redo` write whatever they are asked to. A host that must not write —
|
|
95
|
+
* somebody else holds the document — gates its own calls.
|
|
96
|
+
*/
|
|
68
97
|
setPermissions: (permissions: Partial<Permissions>) => void;
|
|
69
98
|
/**
|
|
70
99
|
* Run every block's `resolveData` over the document, as `<Puck>` did when it
|
|
@@ -78,6 +107,31 @@ interface Easel<C extends EaselConfig = EaselConfig> {
|
|
|
78
107
|
trigger?: ResolveTrigger;
|
|
79
108
|
metadata?: Record<string, unknown>;
|
|
80
109
|
}) => Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Run ONE node's `resolveData`, and that of everything in its slots, and
|
|
112
|
+
* write what changed folded into the step it happens in — `resolveAll`, for
|
|
113
|
+
* one node. Resolves to whether anything was written.
|
|
114
|
+
*
|
|
115
|
+
* It is what Puck's own insert ran: a block dropped from its component list
|
|
116
|
+
* was resolved with trigger `'insert'` (`insertComponent`), which is how a
|
|
117
|
+
* block seeds its children or stamps a default the moment it arrives. The
|
|
118
|
+
* `insert` ACTION never did — Puck's reducer was pure, and so is this one —
|
|
119
|
+
* and the engine has no drop of its own: the Add list's click and the drag's
|
|
120
|
+
* drop are the host's. So a host that puts a new block in, by `dispatch` or
|
|
121
|
+
* by `run`, follows it with this (second host, 2026-10-07):
|
|
122
|
+
*
|
|
123
|
+
* easel.dispatch({ type: 'insert', componentType, destinationZone, destinationIndex, id });
|
|
124
|
+
* void easel.resolveNode(id, { trigger: 'insert' });
|
|
125
|
+
*
|
|
126
|
+
* ONE undo step with the insert (Puck made the resolver's write a second
|
|
127
|
+
* one, and a single undo left a block that had never been resolved). A node
|
|
128
|
+
* changed by hand, or taken out, while its resolver ran is left as it is.
|
|
129
|
+
* `trigger` is `'replace'` when not given, as `resolveNodeData`'s is.
|
|
130
|
+
*/
|
|
131
|
+
resolveNode: (id: string, options?: {
|
|
132
|
+
trigger?: ResolveTrigger;
|
|
133
|
+
metadata?: Record<string, unknown>;
|
|
134
|
+
}) => Promise<boolean>;
|
|
81
135
|
/** This easel's memory of the last change each node was resolved for —
|
|
82
136
|
* Puck kept one per editor, shared by every write that resolves. */
|
|
83
137
|
readonly resolveCache: ResolveCache;
|
|
@@ -103,12 +157,6 @@ declare const DEFAULT_UI: Record<string, unknown>;
|
|
|
103
157
|
* never had. Framework-free — `useEasel` (./react) is the React binding.
|
|
104
158
|
*/
|
|
105
159
|
declare function createEasel<C extends EaselConfig>(options: EaselOptions<C>): Easel<C>;
|
|
106
|
-
/** @deprecated The name before the Easel rename: `EaselOptions`. */
|
|
107
|
-
type EditorOptions<C extends EaselConfig = EaselConfig> = EaselOptions<C>;
|
|
108
|
-
/** @deprecated The name before the Easel rename: `Easel`. */
|
|
109
|
-
type Editor<C extends EaselConfig = EaselConfig> = Easel<C>;
|
|
110
|
-
/** @deprecated The name before the Easel rename: `createEasel`. */
|
|
111
|
-
declare const createEditor: typeof createEasel;
|
|
112
160
|
|
|
113
161
|
/**
|
|
114
162
|
* Puck 0.20's reducer, on `efficient-easel/data` — blueprint step 5.1.
|
|
@@ -139,6 +187,13 @@ declare function reduce(core: EaselCore, action: EaselAction, config: EaselConfi
|
|
|
139
187
|
|
|
140
188
|
interface EaselProviderProps {
|
|
141
189
|
easel: Easel;
|
|
190
|
+
/**
|
|
191
|
+
* Bind undo / redo: to the page here, and in the canvas frame
|
|
192
|
+
* (`EaselCanvas`, whose own `hotkeys` can say otherwise for the frame
|
|
193
|
+
* alone). `false` binds NEITHER, for a host that binds its own. On by
|
|
194
|
+
* default. Whatever this says, the keys do nothing while the easel-wide
|
|
195
|
+
* `edit` permission is off (`bindUndoKeys`).
|
|
196
|
+
*/
|
|
142
197
|
hotkeys?: boolean;
|
|
143
198
|
/** Run every block's `resolveData` once the easel mounts, as `<Puck>` did
|
|
144
199
|
* (`easel.resolveAll`). On by default. */
|
|
@@ -168,17 +223,6 @@ declare function useEasel<T, C extends EaselConfig = EaselConfig>(selector: (vie
|
|
|
168
223
|
* a file that made its own typed hook keeps the one line that made it.
|
|
169
224
|
*/
|
|
170
225
|
declare function createUseEasel<C extends EaselConfig = EaselConfig>(): <T>(selector: (view: EaselView<C>) => T) => T;
|
|
171
|
-
/** @deprecated The name before the Easel rename: `EaselProvider`, whose prop
|
|
172
|
-
* is `easel`. This one still takes the store as `editor`. */
|
|
173
|
-
declare function EditorProvider({ editor, ...rest }: Omit<EaselProviderProps, 'easel'> & {
|
|
174
|
-
editor: Easel;
|
|
175
|
-
}): react.JSX.Element;
|
|
176
|
-
/** @deprecated The name before the Easel rename: `useEaselApi`. */
|
|
177
|
-
declare const useEditorApi: typeof useEaselApi;
|
|
178
|
-
/** @deprecated The name before the Easel rename: `useEasel`. */
|
|
179
|
-
declare const useEditor: typeof useEasel;
|
|
180
|
-
/** @deprecated The name before the Easel rename: `createUseEasel`. */
|
|
181
|
-
declare const createUseEditor: typeof createUseEasel;
|
|
182
226
|
|
|
183
227
|
/** What a slot component accepts — Puck's. */
|
|
184
228
|
interface CanvasSlotProps {
|
|
@@ -198,7 +242,9 @@ interface CanvasFrameProps {
|
|
|
198
242
|
* language (`EaselStrings.canvas.frame`).
|
|
199
243
|
*/
|
|
200
244
|
title?: string;
|
|
245
|
+
/** Added to the frame's own classes (`es-canvas-frame`, and `is-fill` when it fills). */
|
|
201
246
|
className?: string;
|
|
247
|
+
/** The host's own style for the frame. The engine writes none: see the note on `CanvasFrame`. */
|
|
202
248
|
style?: CSSProperties;
|
|
203
249
|
/** Copy the host page's stylesheets into the frame, and keep them in step.
|
|
204
250
|
* On by default: the blocks are styled by the app's own CSS. */
|
|
@@ -239,6 +285,15 @@ interface CanvasFrameProps {
|
|
|
239
285
|
* empty slot grew to the frame's full height), tables stop inheriting the
|
|
240
286
|
* page's font, and an image's line box changes. (0.89.0–0.92.0 shipped the
|
|
241
287
|
* quirks-mode frame.)
|
|
288
|
+
*
|
|
289
|
+
* ── Its look is a CLASS, not a `style` (second host, 2026-10-06) ───────────
|
|
290
|
+
* No border, the pane's width, and the pane's height when it fills are rules
|
|
291
|
+
* in easel.css (`.es-canvas-frame`, `.is-fill`). They were a `style` prop,
|
|
292
|
+
* which a server renders as a `style=""` attribute — and a Content-Security-
|
|
293
|
+
* Policy without `'unsafe-inline'` for styles refuses those: a server-rendered
|
|
294
|
+
* editor showed a bordered 300×150 frame, and hydration does not put a refused
|
|
295
|
+
* attribute right. The measured height of an `auto` frame is still written to
|
|
296
|
+
* `style`, on the client, through the CSSOM, which no policy governs.
|
|
242
297
|
*/
|
|
243
298
|
declare function CanvasFrame({ children, id, title, className, style, mirrorStyles, onDocument, height, nonce, }: CanvasFrameProps): react.JSX.Element;
|
|
244
299
|
/**
|
|
@@ -283,6 +338,16 @@ interface EaselCanvasProps {
|
|
|
283
338
|
title?: string;
|
|
284
339
|
/** The page's CSP nonce for the frame's stylesheets — see `CanvasFrameProps.nonce`. Unused with `frame={false}`. */
|
|
285
340
|
nonce?: string;
|
|
341
|
+
/**
|
|
342
|
+
* Bind undo / redo in the frame's document — a key pressed in the frame
|
|
343
|
+
* never reaches the page. Left out, it follows `EaselProvider`'s `hotkeys`,
|
|
344
|
+
* so one switch turns the easel's keys off everywhere. Say `true` for a
|
|
345
|
+
* host that binds the PAGE's keys itself (to its own root, because the page
|
|
346
|
+
* is another app's) and still wants the frame's; `false` for the frame
|
|
347
|
+
* alone. Either way the keys do nothing while the easel-wide `edit`
|
|
348
|
+
* permission is off (`bindUndoKeys`). Unused with `frame={false}`.
|
|
349
|
+
*/
|
|
350
|
+
hotkeys?: boolean;
|
|
286
351
|
onDocument?: (doc: Document | null) => void;
|
|
287
352
|
/**
|
|
288
353
|
* Wraps everything drawn in the frame, and is handed the frame's document —
|
|
@@ -302,11 +367,7 @@ interface EaselCanvasProps {
|
|
|
302
367
|
* `<Puck.Preview>`, ours: the document for editing, its outlines, and the
|
|
303
368
|
* clicks that select. Must sit under an `EaselProvider`.
|
|
304
369
|
*/
|
|
305
|
-
declare function EaselCanvas({ frame, className, style, metadata, mirrorStyles, onDocument, height, title, nonce, frameWrapper: FrameWrapper, overlay, children, }: EaselCanvasProps): ReactElement;
|
|
306
|
-
/** @deprecated The name before the Easel rename: `EaselCanvasProps`. */
|
|
307
|
-
type EditorCanvasProps = EaselCanvasProps;
|
|
308
|
-
/** @deprecated The name before the Easel rename: `EaselCanvas`. */
|
|
309
|
-
declare const EditorCanvas: typeof EaselCanvas;
|
|
370
|
+
declare function EaselCanvas({ frame, className, style, metadata, mirrorStyles, onDocument, height, title, nonce, hotkeys, frameWrapper: FrameWrapper, overlay, children, }: EaselCanvasProps): ReactElement;
|
|
310
371
|
|
|
311
372
|
/**
|
|
312
373
|
* THE PARTS, ON THE STORE (blueprint step 5.2).
|
|
@@ -361,8 +422,6 @@ interface SelectedFields {
|
|
|
361
422
|
* selected when the change began.
|
|
362
423
|
*/
|
|
363
424
|
declare function useSelectedFields(): SelectedFields;
|
|
364
|
-
/** @deprecated The name before the Easel rename: `useEaselNodeOps`. */
|
|
365
|
-
declare const useEditorNodeOps: typeof useEaselNodeOps;
|
|
366
425
|
|
|
367
426
|
/**
|
|
368
427
|
* UNDO AND REDO ON THE KEYBOARD — Puck's own six bindings, which both editors
|
|
@@ -379,7 +438,19 @@ declare const useEditorNodeOps: typeof useEaselNodeOps;
|
|
|
379
438
|
*
|
|
380
439
|
* Bound per DOCUMENT: the host page (`EaselProvider`) and the canvas frame
|
|
381
440
|
* (`EaselCanvas`), because a key pressed in the frame never reaches the page.
|
|
441
|
+
* ONE switch turns both off (`EaselProvider hotkeys={false}`); the frame's
|
|
442
|
+
* alone is `EaselCanvas hotkeys`.
|
|
443
|
+
*
|
|
444
|
+
* ── Held with editing (second host, 2026-10-06) ─────────────────────────────
|
|
445
|
+
* While the easel-wide `edit` permission is off — somebody else holds the
|
|
446
|
+
* document, a save was refused, a read-only view — the keys do NOTHING: an
|
|
447
|
+
* undo is a write, and the screen may be the only copy of what it would
|
|
448
|
+
* rewind. The key is not taken either (no `preventDefault`), so a text field
|
|
449
|
+
* outside the document keeps the browser's own undo. Read at each key press,
|
|
450
|
+
* so a binding made once follows `setPermissions`. A block's own
|
|
451
|
+
* `permissions.edit` is that block's fields and is not asked. Handed only
|
|
452
|
+
* `undo` / `redo` (no `getState`), there is nothing to ask and the keys work.
|
|
382
453
|
*/
|
|
383
|
-
declare function bindUndoKeys(doc: Document, easel: Pick<Easel, 'undo' | 'redo'>): () => void;
|
|
454
|
+
declare function bindUndoKeys(doc: Document, easel: Pick<Easel, 'undo' | 'redo'> & Partial<Pick<Easel, 'getState'>>): () => void;
|
|
384
455
|
|
|
385
|
-
export { CanvasFrame, type CanvasFrameProps, type CanvasOverlay, type CanvasSlotProps, DEFAULT_UI, type Easel, EaselAction, EaselCanvas, type EaselCanvasProps, EaselConfig, EaselCore, type EaselOptions, EaselProvider, type EaselProviderProps, EaselUi, EaselView, EditDocument,
|
|
456
|
+
export { CanvasFrame, type CanvasFrameProps, type CanvasOverlay, type CanvasSlotProps, 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, recordsByDefault, reduce, uiView, useEasel, useEaselApi, useEaselNodeOps, useSelectedFields, validSelection };
|
package/dist/easel/index.js
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
export{CanvasFrame,DEFAULT_UI,EaselCanvas,EaselProvider,EditDocument,EditorCanvas,EditorProvider,bindUndoKeys,createEasel,createEditor,createUseEasel,createUseEditor,recordsByDefault,reduce,uiView,useEasel,useEaselApi,useEaselNodeOps,useEditor,useEditorApi,useEditorNodeOps,useSelectedFields,validSelection}from"../chunk-F2PIG3AA.js";import"../chunk-D2BCHTQR.js";import"../chunk-AELNNAFM.js";import"../chunk-YRLPFZW3.js";import"../chunk-MFIRYGHW.js";import"../chunk-ZNCEOSXO.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";
|
|
1
|
+
import{DEFAULT_CANVAS_WORDS as e}from"../chunk-AELNNAFM.js";import{useResolvedFields as t}from"../chunk-YRLPFZW3.js";import{toItemSelector as n,fromItemSelector as o,useNodeOps as r}from"../chunk-D2BCHTQR.js";import{useWords as a}from"../chunk-MFIRYGHW.js";import{setCanvasNonce as i}from"../chunk-ZNCEOSXO.js";import{find as s,ROOT_ID as d,getList as l,remove as c,parseZoneKey as u,move as p,duplicate as f,replaceNode as h,createNode as m,insert as v,normalizeData as y,createResolveCache as g,resolveNodeData as k,ROOT_SLOT as b}from"../chunk-KRXQM65X.js";import{topLevelSlotKeys as w,fieldsFrom as S,defaultsFrom as I}from"../chunk-NKB3KVAB.js";import{createContext as C,useEffect as O,useContext as x,useRef as E,useSyncExternalStore as A,useState as D,useMemo as z,useCallback as M,useLayoutEffect as Z}from"react";import{jsx as N,jsxs as $}from"react/jsx-runtime";import{createPortal as j}from"react-dom";function R(e){return!["setData","setUi","set"].includes(e.type)}var B=(e,t,n,o)=>{const r=l(e,t,u(n));return r?.[o]??null},P=(e,t,n,o,r)=>{const a=B(e,t,n,o);if(!a)throw new Error(`${r}: nothing at ${n}[${o}]`);return a};function L(e,t){const{selection:o}=e;return{...e.ui,itemSelector:n(e.data,t,o),selectedSlot:o&&"slot"===o.kind?{parentId:o.parentId,slot:o.slot}:null}}function K(e,t,n){return n?"node"===n.kind?s(e,t,n.id)?n:null:n.parentId===d?l(e,t,n)?n:null:s(e,t,n.parentId)&&l(e,t,n)?n:null:null}function F(e,t,n,r=!1){const{itemSelector:a,selectedSlot:i,...s}=n;let d=e.selection;var l;return"itemSelector"in n&&(d=o(e.data,t,a??null)),"selectedSlot"in n&&(i?d=(l=i)?{kind:"slot",parentId:l.parentId,slot:l.slot}:null:"slot"===d?.kind&&(d=null)),{...e,selection:d,ui:r?s:{...e.ui,...s}}}function H(e,t,n){const o=V(e,t,n);if(o===e)return e;const r=K(o.data,n,o.selection);return r===o.selection?o:{...o,selection:r}}function V(e,t,n){const{data:o}=e;switch(t.type){case"setData":{const n="function"==typeof t.data?t.data(o):t.data;return{...e,data:{...o,...n}}}case"setUi":return F(e,n,"function"==typeof t.ui?t.ui(L(e,n)):t.ui);case"set":{const r={data:o,ui:L(e,n)},a="function"==typeof t.state?t.state(r):t.state;let i=a.data?{...e,data:a.data}:e;return a.ui&&(i=F(i,n,a.ui,!0)),i}case"insert":{const r={...u(t.destinationZone),index:t.destinationIndex},a=m(n,t.componentType,{},t.id?{id:t.id}:{});return{...e,data:v(o,n,r,a)}}case"replace":{const r=P(o,n,t.destinationZone,t.destinationIndex,"replace");if(r.props.id!==t.data.props.id)throw new Error("Can't change the id during a replace action. Use remove and insert for a new node.");return{...e,data:h(o,n,r.props.id,t.data)}}case"replaceRoot":{const n={...o.root,props:{...o.root.props,...t.root.props},readOnly:t.root.readOnly};return{...e,data:{...o,root:n}}}case"duplicate":{const r=P(o,n,t.sourceZone,t.sourceIndex,"duplicate"),a=f(o,n,r.props.id),i=B(a,n,t.sourceZone,t.sourceIndex+1);return{...e,data:a,selection:i?{kind:"node",id:i.props.id}:e.selection}}case"reorder":return V(e,{...t,type:"move",sourceZone:t.destinationZone},n);case"move":{if(t.sourceZone===t.destinationZone&&t.sourceIndex===t.destinationIndex)return e;const r=B(o,n,t.sourceZone,t.sourceIndex);if(!r)return e;const a={...u(t.destinationZone),index:t.destinationIndex};return{...e,data:p(o,n,r.props.id,a)}}case"remove":{const r=P(o,n,t.zone,t.index,"remove");return{...e,data:c(o,n,r.props.id)}}default:return e}}var T={drag:!0,duplicate:!0,delete:!0,edit:!0,insert:!0},q={leftSideBarVisible:!0,rightSideBarVisible:!0,arrayState:{},componentList:{},isDragging:!1,previewMode:"edit",viewports:{current:{width:360,height:"auto"},options:[],controlsVisible:!0},field:{focus:null}},Y=0,U=()=>`history-${Y+=1}`;function W(e){let t=e.config;const r=e.now??(()=>Date.now()),a=e.historyCoalesceMs??250;let i=e.permissions??{};const d=y(e.data,t);let c={data:d,selection:null,ui:{...q}};if(e.ui){const{itemSelector:n,selectedSlot:r,...a}=e.ui;c={data:d,selection:r?{kind:"slot",...r}:o(d,t,n??null),ui:{...q,...a}}}let u=[{core:c,at:-1/0,sealed:!0,id:U()}],p=0;const f=e=>{const t=u[p],n=r();!e&&p===u.length-1&&p>0&&!t.sealed&&n-t.at<a?u=[...u.slice(0,p),{...t,core:c,at:n}]:(u=[...u.slice(0,p+1),{core:c,at:n,sealed:e,id:U()}],p=u.length-1)},m=/* @__PURE__ */new Set;let v=null,b=null,w=0,S=null,I=!1;const C=()=>{for(const e of[...m])e()},O=()=>{u=[...u.slice(0,p),{...u[p],core:c},...u.slice(p+1)]},x=(t,n)=>{w>0?I=I||n:(n?f(!1):c!==t&&O(),c.data!==t.data&&e.onChange?.(c.data),c!==t&&C())},E=e=>{const n=c;if(c=H(c,e,t),c===n)return;const o=e.recordHistory??R(e);x(n,o&&c.data!==n.data)},A=t=>{0===w&&(S=c,I=!1),w+=1;try{t()}catch(e){throw w-=1,0===w&&S&&(c=S,S=null),e}if(w-=1,w>0||!S)return;const n=S;S=null,I&&c.data!==n.data?f(!0):c!==n&&O(),c.data!==n.data&&e.onChange?.(c.data),c!==n&&C()},D=e=>{const n=c,o=K(c.data,t,e);var r,a;(r=o,a=c.selection,r===a||r&&a&&r.kind===a.kind&&("node"===r.kind&&"node"===a.kind?r.id===a.id:"slot"===r.kind&&"slot"===a.kind&&r.parentId===a.parentId&&r.slot===a.slot))||(c={...c,selection:o},x(n,!1))},z=t=>{const n=c;p=t,c=u[p].core,c.data!==n.data&&e.onChange?.(c.data),c!==n&&C()},M=()=>(e={})=>{const n=e.root?t.root?.permissions:t.components[e.item?.type??e.type??""]?.permissions;return{...T,...i,...n}};let Z=M();const N=g(),$={resolveCache:N,async resolveAll({trigger:e="load",metadata:n}={}){const o=c.data,r={type:"root",props:{...o.root.props??{}}},a=[...o.content,...Object.values(o.zones??{}).flat()],[i,...d]=await Promise.all([k(r,t,{cache:N,trigger:e,metadata:n}),...a.map(o=>k(o,t,{cache:N,trigger:e,metadata:n}))]);A(()=>{const e=c;let n=c.data;d.forEach((e,r)=>{if(!e.didChange)return;const i=a[r].props.id,d=s(n,t,i)?.node;d&&d===s(o,t,i)?.node&&(n=h(n,t,i,e.node))}),i.didChange&&n.root===o.root&&(n={...n,root:{...n.root,props:i.node.props,readOnly:i.node.readOnly??n.root.readOnly}}),n!==c.data&&(c={...c,data:n,selection:K(n,t,c.selection)},x(e,!1))})},async resolveNode(e,{trigger:n="replace",metadata:o}={}){const r=s(c.data,t,e)?.node;if(!r)return!1;const a=await k(r,t,{cache:N,trigger:n,metadata:o});if(!a.didChange)return!1;let i=!1;return A(()=>{const n=c;if(s(c.data,t,e)?.node!==r)return;const o=h(c.data,t,e,a.node);o!==c.data&&(c={...c,data:o,selection:K(o,t,c.selection)},x(n,!1),i=!0)}),i},get config(){return t},getState(){if(v&&b===c)return v;const e=c,o={data:e.data,ui:L(e,t)},r="node"===e.selection?.kind?s(e.data,t,e.selection.id)?.node??null:null;return v={appState:o,selection:e.selection,selectedItem:r,config:t,dispatch:E,history:{back:()=>$.undo(),forward:()=>$.redo(),hasPast:p>0,hasFuture:p<u.length-1,histories:u.map(e=>({id:e.id,state:{data:e.core.data,ui:L(e.core,t)}})),index:p,setHistoryIndex:e=>{e>=0&&e<u.length&&e!==p&&z(e)}},getPermissions:Z,getItemById:n=>s(e.data,t,n)?.node,getItemBySelector:n=>function(e,t,n){const[o,r]=(n.zone??"root:default-zone").split(/:(.*)/s);return l(e,t,{parentId:o,slot:r})?.[n.index]}(e.data,t,n),getSelectorForId:o=>{const r=n(e.data,t,{kind:"node",id:o});return r?{index:r.index,zone:r.zone??"root:default-zone"}:void 0}},b=e,v},subscribe:e=>(m.add(e),()=>{m.delete(e)}),dispatch:E,batch:A,select:e=>D(e?{kind:"node",id:e}:null),selectSlot:e=>D(e?{kind:"slot",parentId:e.parentId,slot:e.slot}:null),run(e){A(()=>{const n=c,o=void 0===e.select?c.selection:e.select;c={...c,data:e.data,selection:K(e.data,t,o)},x(n,e.data!==n.data)})},load(e,n={}){const o=c,r=y(e,t);c={...c,data:r,selection:K(r,t,n.selection??c.selection)},n.keepHistory||(u=[{core:c,at:-1/0,sealed:!0,id:U()}],p=0),c!==o&&C()},undo(){p>0&&z(p-1)},redo(){p<u.length-1&&z(p+1)},setPermissions(e){(function(e,t){if(e===t)return!0;const n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>e[n]===t[n])})(e,i)||(i=e,Z=M(),v=null,C())},setConfig(e){e!==t&&(t=e,Z=M(),v=null,C())}};return $}function X(e,t){const n=e=>{if(e.altKey)return;if(!(e.metaKey!==e.ctrlKey))return;const n="KeyZ"===e.code,o="KeyY"===e.code&&!e.shiftKey;(n||o)&&!1!==t.getState?.().getPermissions().edit&&(e.preventDefault(),o||e.shiftKey?t.redo():t.undo())};return e.addEventListener("keydown",n),()=>e.removeEventListener("keydown",n)}var Q=C(null),G=C(!0);function J({easel:e,hotkeys:t=!0,resolveOnMount:n=!0,children:o}){return O(()=>{n&&e.resolveAll()},[e,n]),O(()=>{if(t&&"undefined"!=typeof document)return X(document,e)},[e,t]),/* @__PURE__ */N(Q.Provider,{value:e,children:/* @__PURE__ */N(G.Provider,{value:t,children:o})})}function _(){const e=x(Q);if(!e)throw new Error("useEasel: no <EaselProvider> above this component");return e}function ee(e){const t=_(),n=E({view:null,selector:null,value:void 0,has:!1}),o=()=>{const o=t.getState(),r=n.current;if(r.has&&r.view===o&&r.selector===e)return r.value;const a=e(o);return r.has&&Object.is(r.value,a)?(n.current={view:o,selector:e,value:r.value,has:!0},r.value):(n.current={view:o,selector:e,value:a,has:!0},a)};return A(t.subscribe,o,o)}function te(){return function(e){return ee(e)}}var ne="data-puck-component",oe="data-puck-dropzone",re={},ae="data-es-mirror",ie="undefined"==typeof window?O:Z;function se(e,t,n){for(const e of Array.from(t.head.querySelectorAll(`[${ae}]`)))e.remove();for(const o of Array.from(e.head.querySelectorAll('style, link[rel="stylesheet"]'))){const e=o.cloneNode(!0);e.setAttribute(ae,""),n&&e.setAttribute("nonce",n),t.head.appendChild(e)}}function de({children:t,id:n="preview-frame",title:o,className:r,style:s,mirrorStyles:d=!0,onDocument:l,height:c="auto",nonce:u}){const p=a("canvas",e),f=E(null),[h,m]=D(null);return ie(()=>{const e=f.current,t=h?.ownerDocument.defaultView;if("auto"!==c||!e||!h||!t)return;const n=()=>{e.style.height=`${Math.ceil(h.getBoundingClientRect().height)}px`};n();const o=t.ResizeObserver,r=o?new o(n):null;return r?.observe(h),()=>r?.disconnect()},[h,c]),ie(()=>{let e=f.current?.contentDocument;if(!e)return;"CSS1Compat"!==e.compatMode&&(e.open(),e.write("<!DOCTYPE html><html><head></head><body></body></html>"),e.close(),e=f.current?.contentDocument??e),e.body||e.documentElement.appendChild(e.createElement("body")),e.body.style.margin="0";const t=e.createElement("div");t.setAttribute("data-puck-entry",""),t.id="frame-root","fill"===c&&t.classList.add("es-frame-fill"),e.body.appendChild(t),i(e,u),m(t),l?.(e);let n=null;const o=f.current?.ownerDocument;if(d&&o){se(o,e,u);const t=o.defaultView;t&&"MutationObserver"in t&&(n=new t.MutationObserver(()=>se(o,e,u)),n.observe(o.head,{childList:!0,subtree:!0,characterData:!0}))}return()=>{n?.disconnect(),t.remove(),m(null),l?.(null)}},[]),/* @__PURE__ */N("iframe",{ref:f,id:n,title:o??p.frame,className:["es-canvas-frame","fill"===c?"is-fill":"",r??""].filter(Boolean).join(" "),style:s,children:h?j(t,h):null})}var le=C(null),ce=C(re),ue=[];function pe({parentId:e,slot:t,className:n,style:o,minEmptyHeight:r=128}){const a=_(),i=ee(n=>l(n.appState.data,a.config,{parentId:e,slot:t})??ue),s=ee(t=>"node"===t.selection?.kind&&t.selection.id===e&&e!==d),c=ee(n=>"slot"===n.selection?.kind&&n.selection.parentId===e&&n.selection.slot===t),u=x(le),p=["es-zone"];return i.length&&p.push("has-children"),e===d&&p.push("is-root"),(s||c)&&p.push("is-area-selected"),null!==u&&u===e&&e!==d&&p.push("is-hovering-area"),n&&p.push(n),/* @__PURE__ */N("div",{className:p.join(" "),[oe]:`${e}:${t}`,style:{...o,"--min-empty-height":`${r}px`},children:i.map(e=>/* @__PURE__ */N(me,{node:e},e.props.id))})}function fe(e,t,n,o){const r="root"===t?e.root:e.components[t],a={...o};for(const e of w(S(r)))a[e]=function(t={}){/* @__PURE__ */
|
|
2
|
+
return N(pe,{parentId:n,slot:e,...t})};return a}function he(e){return function({zone:t,...n}){/* @__PURE__ */
|
|
3
|
+
return N(pe,{parentId:e,slot:t,...n})}}function me({node:e}){const t=_().config,n=t.components[e.type],o=e.props.id,r=function(e){const t=E(null);return z(()=>n=>{const o=t.current;o&&o!==n&&(o.removeAttribute(ne),o.removeAttribute("data-puck-dnd")),t.current=n,n&&(n.setAttribute(ne,e),n.setAttribute("data-puck-dnd",e),n.style.position="relative")},[e])}(o),a=x(ce);if(!n?.render)return null;const i=n.render,s=fe(t,e.type,o,{...I(n),...e.props}),d={renderDropZone:he(o),isEditing:!0,dragRef:n.inline?r:null,metadata:{...a,...n.metadata}};return n.inline?/* @__PURE__ */N(i,{...s,puck:d,editMode:!0}):/* @__PURE__ */N("div",{[ne]:o,"data-puck-dnd":o,style:{position:"relative"},children:/* @__PURE__ */N(i,{...s,puck:d,editMode:!0})})}function ve({metadata:e}){const t=ee(e=>e.config),n=ee(e=>e.appState.data.root).props??{},o=t.root?.render,r=/* @__PURE__ */N(pe,{parentId:d,slot:b}),a=o?/* @__PURE__ */N(o,{id:"puck-root",...fe(t,"root",d,n),puck:{renderDropZone:he(d),isEditing:!0,dragRef:null,metadata:e??{}},editMode:!0,children:r}):r;/* @__PURE__ */
|
|
4
|
+
return N(ce.Provider,{value:e??re,children:a})}function ye({id:e,kind:t,overlay:n}){const o=E(null),[r,a]=D(null);ie(()=>{const t=o.current?.ownerDocument,n=t?.defaultView;if(!t||!n||!e)return void a(null);let r=0;const i=()=>{r=0;const i=function(e,t){if(!e||!t)return null;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect();return{top:n.top-o.top,left:n.left-o.left,width:n.width,height:n.height}}(t.querySelector(`[${ne}="${n.CSS?.escape?n.CSS.escape(e):e}"]`),o.current?.parentElement??null);a(e=>{return(t=e)===(n=i)||t&&n&&t.top===n.top&&t.left===n.left&&t.width===n.width&&t.height===n.height?e:i;var t,n})},s=()=>{r||(r=(n.requestAnimationFrame??(e=>n.setTimeout(e,16)))(i))};i();const d="MutationObserver"in n?new n.MutationObserver(s):null;d?.observe(t.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0});const l="ResizeObserver"in n?new n.ResizeObserver(s):null;return l?.observe(t.documentElement),n.addEventListener("resize",s),()=>{d?.disconnect(),l?.disconnect(),n.removeEventListener("resize",s),r&&(n.cancelAnimationFrame??n.clearTimeout)(r)}},[e]);const i=/* @__PURE__ */N("div",{ref:o,"aria-hidden":"true",className:`es-canvas-outline is-${t}`,style:r?{position:"absolute",top:r.top,left:r.left,width:r.width,height:r.height}:{display:"none"}});return n&&e?/* @__PURE__ */N(n,{componentId:e,kind:t,children:i}):i}function ge({frame:e=!0,className:t,style:n,metadata:o,mirrorStyles:r,onDocument:a,height:i,title:s,nonce:d,hotkeys:l,frameWrapper:c,overlay:u,children:p}){const f=_(),h=x(G),m=l??h,[v,y]=D(void 0),g=ee(e=>"node"===e.selection?.kind?e.selection.id:null),[k,b]=D(null),w=/* @__PURE__ */$("div",{className:"es-canvas-content",style:{position:"relative"},onClick:e=>{const t=e.target;t.closest?.("a[href]")&&e.preventDefault();const n=t.closest?.(`[${ne}]`);n?f.select(n.getAttribute(ne)):t.hasAttribute?.(oe)||f.select(null)},onMouseOver:e=>{const t=e.target.closest?.(`[${ne}]`),n=t?.getAttribute(ne)??null;n!==k&&b(n)},onMouseLeave:()=>b(null),children:[
|
|
5
|
+
/* @__PURE__ */N(le.Provider,{value:k,children:/* @__PURE__ */N(ve,{metadata:o})}),
|
|
6
|
+
/* @__PURE__ */$("div",{className:"es-canvas-outlines",style:{position:"absolute",top:0,left:0,pointerEvents:"none"},children:[
|
|
7
|
+
/* @__PURE__ */N(ye,{id:k&&k!==g?k:null,kind:"hover",overlay:u}),
|
|
8
|
+
/* @__PURE__ */N(ye,{id:g,kind:"selected",overlay:u})]}),p]}),S=c?/* @__PURE__ */N(c,{document:v,children:w}):w;O(()=>{if(v&&m)return X(v,f)},[v,m,f]);/* @__PURE__ */
|
|
9
|
+
return N("div",{className:"es-canvas"+(t?` ${t}`:""),style:n,"data-puck-preview":"",children:e?/* @__PURE__ */N(de,{mirrorStyles:r,onDocument:e=>{y(e??void 0),a?.(e)},height:i,title:s,nonce:d,children:S}):/* @__PURE__ */N("div",{id:"preview-frame","data-puck-entry":"",children:S})})}function ke(e={}){const t=_(),n=ee(e=>e.appState.data);return r({...e,data:n,config:t.config,commit:(e,{select:n})=>t.run({data:e,select:n})})}function be(){const e=_(),n=ee(e=>e.config),o=e.resolveCache,r=ee(e=>e.selectedItem),a=ee(e=>e.appState.data.root),i=r?r.props.id:"root",d=a.props??{},l=z(()=>r||{type:"root",props:d},[r,d]),c=r?n.components[r.type]:n.root,u=e.getState(),p=r?s(u.appState.data,n,i):null,f=p&&"root"!==p.place.parentId?p.place.parentId:null,h=f?u.getItemById(f)??null:null,{fields:m}=t({id:i,node:l,block:c,parent:h,appState:u.appState}),v=ee(e=>!1===e.getPermissions(r?{item:r}:{root:!0}).edit),y=M((t,r)=>{(async()=>{const a=e.getState();if("root"!==i){const s=a.getItemById(i),d=a.getSelectorForId(i);if(!s||!d)return;const l={...s,props:{...s.props,[t]:r}},{node:c}=await k(l,n,{cache:o,trigger:"replace"}),u=e.getState().getSelectorForId(i);if(!u)return;return void e.dispatch({type:"replace",destinationZone:u.zone??"root:default-zone",destinationIndex:u.index,data:c})}const s=a.appState.data.root.props??{},{node:d}=await k({type:"root",props:{...s,[t]:r}},n,{cache:o,trigger:"replace"});e.dispatch({type:"replaceRoot",root:{props:d.props,readOnly:d.readOnly},recordHistory:!0})})()},[e,n,o,i]);return{id:i,node:l,fields:m,values:l.props,readOnly:v,onChange:y}}export{de as CanvasFrame,q as DEFAULT_UI,ge as EaselCanvas,J as EaselProvider,ve as EditDocument,X as bindUndoKeys,W as createEasel,te as createUseEasel,R as recordsByDefault,H as reduce,L as uiView,ee as useEasel,_ as useEaselApi,ke as useEaselNodeOps,be as useSelectedFields,K as validSelection};
|
|
@@ -193,8 +193,6 @@ declare const nameOrSomeone: (name: string, words?: LockWords) => string;
|
|
|
193
193
|
* claim look alive.
|
|
194
194
|
*/
|
|
195
195
|
declare function newEaselClientId(): string;
|
|
196
|
-
/** @deprecated The name before the Easel rename: `newEaselClientId`. */
|
|
197
|
-
declare const newEditorClientId: typeof newEaselClientId;
|
|
198
196
|
/**
|
|
199
197
|
* The `code` of a document write refused because somebody else TOOK the
|
|
200
198
|
* document from this tab (backend `efficient/editlock.py`,
|
|
@@ -353,4 +351,4 @@ type EditLock = {
|
|
|
353
351
|
/** Bind the decisions to one editor's HTTP client and document type. */
|
|
354
352
|
declare function createEditLock(adapter: EditLockAdapter): EditLock;
|
|
355
353
|
|
|
356
|
-
export { type ClaimBeatDeps, type DocumentPermissions, EDIT_LOCK_TAKEN, type EditAccess, type EditLock, type EditLockAdapter, type EditLockBody, type EditLockFailure, type HeldWrite, type LockHolder, type LockWords, type SaveConflict, accessForNewDocument, canWriteDocument, createEditLock, describeAge, documentPermissions, documentVersionMoved, holderOf, nameOrSomeone, newEaselClientId,
|
|
354
|
+
export { type ClaimBeatDeps, type DocumentPermissions, EDIT_LOCK_TAKEN, type EditAccess, type EditLock, type EditLockAdapter, type EditLockBody, type EditLockFailure, type HeldWrite, type LockHolder, type LockWords, type SaveConflict, accessForNewDocument, canWriteDocument, createEditLock, describeAge, documentPermissions, documentVersionMoved, holderOf, nameOrSomeone, newEaselClientId, readLockHolder, reloadIfVersionMoved, shouldReleaseHeldWrite, shouldReloadAfterTakeover };
|
package/dist/edit-lock/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{EDIT_LOCK_TAKEN,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEaselClientId,
|
|
1
|
+
export{EDIT_LOCK_TAKEN,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEaselClientId,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-JUQ6YJCG.js";import"../chunk-RE4LP46F.js";
|