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.
Files changed (107) hide show
  1. package/README.md +233 -17
  2. package/dist/autosave/index.d.ts +11 -5
  3. package/dist/blocks/index.d.ts +1 -1
  4. package/dist/canvas/index.d.ts +2 -2
  5. package/dist/canvas/index.js +1 -1
  6. package/dist/chrome/chrome.css +96 -29
  7. package/dist/chrome/index.d.ts +67 -18
  8. package/dist/chrome/index.js +17 -21
  9. package/dist/chunk-3EDSDPIP.js +1 -0
  10. package/dist/chunk-67GNT6PF.js +1 -0
  11. package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
  12. package/dist/chunk-A5UK76FC.js +6 -0
  13. package/dist/chunk-AZT7V4UM.js +10 -0
  14. package/dist/chunk-DICUMYMG.js +12 -0
  15. package/dist/chunk-HDVD27VB.js +1 -0
  16. package/dist/chunk-JQM3V7XQ.js +1 -0
  17. package/dist/chunk-JUQ6YJCG.js +1 -0
  18. package/dist/chunk-LA54QLP5.js +1 -0
  19. package/dist/chunk-LGKQXSKO.js +16 -0
  20. package/dist/chunk-M6F6LS3H.js +1 -0
  21. package/dist/chunk-MH5GUZFQ.js +9 -0
  22. package/dist/chunk-P6O363EE.js +6 -0
  23. package/dist/chunk-PAELDYYS.js +1 -0
  24. package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
  25. package/dist/chunk-SAJUCHOX.js +1 -0
  26. package/dist/chunk-TRVZ7C23.js +1 -0
  27. package/dist/chunk-V7GIIXFB.js +16 -0
  28. package/dist/chunk-WZ7TGAAT.js +3 -0
  29. package/dist/chunk-ZJEBF4NB.js +1 -0
  30. package/dist/copy/copy.css +388 -5
  31. package/dist/copy/index.d.ts +268 -5
  32. package/dist/copy/index.js +31 -10
  33. package/dist/drag/drag.css +10 -1
  34. package/dist/drag/index.d.ts +99 -8
  35. package/dist/drag/index.js +18 -17
  36. package/dist/easel/easel.css +15 -0
  37. package/dist/easel/index.d.ts +104 -33
  38. package/dist/easel/index.js +9 -1
  39. package/dist/edit-lock/index.d.ts +1 -3
  40. package/dist/edit-lock/index.js +1 -1
  41. package/dist/fields/fields.css +103 -26
  42. package/dist/fields/index.d.ts +47 -9
  43. package/dist/fields/index.js +30 -46
  44. package/dist/gold/index.js +1 -1
  45. package/dist/icons/index.d.ts +10 -1
  46. package/dist/icons/index.js +1 -1
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.js +1 -1
  49. package/dist/markup/index.d.ts +94 -10
  50. package/dist/markup/index.js +1 -1
  51. package/dist/menu/index.d.ts +58 -5
  52. package/dist/menu/index.js +15 -15
  53. package/dist/menu/menu.css +17 -6
  54. package/dist/node-ops/index.d.ts +1 -1
  55. package/dist/node-ops/index.js +1 -1
  56. package/dist/panel/index.d.ts +72 -4
  57. package/dist/panel/index.js +18 -16
  58. package/dist/panel/panel.css +56 -1
  59. package/dist/pick/index.d.ts +39 -1
  60. package/dist/pick/index.js +7 -14
  61. package/dist/pick/pick.css +14 -0
  62. package/dist/rail/index.d.ts +3 -7
  63. package/dist/rail/index.js +1 -1
  64. package/dist/strings/catalogue.d.ts +13 -35
  65. package/dist/strings/catalogue.js +1 -1
  66. package/dist/strings/index.d.ts +12 -18
  67. package/dist/strings/index.js +2 -2
  68. package/dist/style-clipboard/index.d.ts +1 -1
  69. package/dist/style-clipboard/index.js +1 -1
  70. package/dist/text-styles/index.d.ts +328 -0
  71. package/dist/text-styles/index.js +38 -0
  72. package/dist/text-styles/text-styles.css +309 -0
  73. package/dist/tree/index.d.ts +43 -2
  74. package/dist/tree/index.js +1 -1
  75. package/dist/tree/tree.css +71 -0
  76. package/dist/{types-p9j2Fac7.d.ts → types-DGcCsxs8.d.ts} +72 -7
  77. package/dist/{types-Bs_gVkVI.d.ts → types-DWS-s9z-.d.ts} +1 -9
  78. package/dist/{types-DO-b0LNj.d.ts → types-Djdq6Xkd.d.ts} +9 -8
  79. package/dist/{types-BOSGNvil.d.ts → types-E3HrTPg2.d.ts} +7 -13
  80. package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
  81. package/dist/{watch-B5RTR-WX.d.ts → watch-BTYOJpQU.d.ts} +18 -1
  82. package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
  83. package/dist/{words-c-3h9xQQ.d.ts → words-BMzV04b1.d.ts} +1 -1
  84. package/dist/words-CJjUKcV5.d.ts +37 -0
  85. package/dist/words-CRYvAiHX.d.ts +105 -0
  86. package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
  87. package/dist/{words-C74EUpFr.d.ts → words-DBq7vfHy.d.ts} +57 -4
  88. package/dist/{words-N4ebT88_.d.ts → words-DgHcY5qB.d.ts} +9 -3
  89. package/package.json +8 -8
  90. package/dist/chunk-66CKSTXP.js +0 -14
  91. package/dist/chunk-672FAEKU.js +0 -1
  92. package/dist/chunk-67VZRQLG.js +0 -13
  93. package/dist/chunk-6PS6STGA.js +0 -1
  94. package/dist/chunk-7A7O2JWQ.js +0 -1
  95. package/dist/chunk-7JTL3P6P.js +0 -1
  96. package/dist/chunk-F2PIG3AA.js +0 -10
  97. package/dist/chunk-H4B72XCJ.js +0 -1
  98. package/dist/chunk-KDIVA6WD.js +0 -1
  99. package/dist/chunk-MCLBHENY.js +0 -1
  100. package/dist/chunk-QB3BZIRA.js +0 -5
  101. package/dist/chunk-SJQG5ENJ.js +0 -1
  102. package/dist/chunk-SUO5627P.js +0 -1
  103. package/dist/chunk-XUE5O62R.js +0 -3
  104. package/dist/chunk-ZT7M24XD.js +0 -1
  105. package/dist/editor/index.d.ts +0 -10
  106. package/dist/editor/index.js +0 -1
  107. /package/dist/{chunk-2PHD4L6A.js → chunk-OWBO4WKA.js} +0 -0
@@ -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-B5RTR-WX.js';
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 being scrolled.
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 box's document (a drag over the canvas frame never reaches
375
- * it, which is right: the canvas scrolls itself). Returns the stop.
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 };
@@ -1,17 +1,18 @@
1
- import{DEFAULT_DRAG_WORDS as e}from"../chunk-O2NLQBFX.js";import{scrollBoxOf as t,startAutoScroll as n,isNoOpDrop as l}from"../chunk-6PS6STGA.js";export{AUTO_SCROLL_EDGE,AUTO_SCROLL_MAX_SPEED,autoScrollDelta,autoScrollSpeed,createDragSession,dropOnRow,gapToMoveIndex,isNoOpDrop,scrollBoxOf,scrollParent,startAutoScroll,stepGap,useTreeDrag}from"../chunk-6PS6STGA.js";import{useCanvasLayout as a,useCanvasEvent as r}from"../chunk-MCLBHENY.js";import{framePointToHost as o,elementScale as s,frameRectToLayer as i,clientPointToLayer as c}from"../chunk-ZNCEOSXO.js";import{CloseIcon as d,SearchIcon as u}from"../chunk-PI26YXYD.js";import{parseZoneKey as h}from"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";import{useRef as p,useEffect as m,useState as f,useCallback as g,useMemo as b,useSyncExternalStore as y,useId as v}from"react";import{jsxs as x,jsx as k}from"react/jsx-runtime";var w=(e,t,n)=>t>=e.left&&t<=e.left+e.width&&n>=e.top&&n<=e.top+e.height,N=e=>e.width*e.height;function A(e,t,n){let l=null;for(const a of e)w(a.box,t,n)&&(!l||N(a.box)<=N(l.box))&&(l=a);return l}function D(e,t,n){const l="x"===e.axis?t:n;let a=0;for(const t of e.children){l>("x"===e.axis?t.left+t.width/2:t.top+t.height/2)&&(a+=1)}return a}function S(e,t){const n=e.children;if("x"===e.axis){const l=n[t-1],a=n[t],r=l&&a?(l.left+l.width+a.left)/2:l?l.left+l.width:a?a.left:e.box.left,o=a??l??e.box;return{left:r-1,top:o.top,width:2,height:o.height}}const l=n[t-1],a=n[t],r=l&&a?(l.top+l.height+a.top)/2:l?l.top+l.height:a?a.top:e.box.top;return{left:e.box.left,top:r-1,width:e.box.width,height:2}}function z(e,t,n,l,a=()=>!1){const r=e.filter(e=>w(e.box,t,n)).sort((e,t)=>N(e.box)-N(t.box));for(const e of r){const r=D(e,t,n),o={...e.list,index:r};if(a(o))return null;if(l(o))return{zone:e,to:o,line:S(e,r)}}return null}function T(e,t=e.key){const n=[];for(let l=1;l<e.children.length;l++){const a=e.children[l-1],r=e.children[l],o=a.top+a.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(r.top-o,0)}})}return n}var C={nodes:[],zones:[]},E="data-puck-dropzone",L="data-puck-component";function O(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 j(e,t){const{frame:n,document:l}=e,a=e=>i(n,function(e){const t=e.getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}(e),t),r=[],o=[];for(const e of l.querySelectorAll(`[${E}]`)){const t=e.getAttribute(E)??"";let n;try{n=h(t)}catch{continue}const l=[...e.querySelectorAll(`[${L}]`)].filter(t=>t.parentElement?.closest(`[${E}]`)===e),s=l.map(a);o.push({key:t,list:n,box:a(e),axis:O(s,e),children:s}),l.forEach((e,t)=>{const l=e.getAttribute(L);l&&r.push({id:l,place:{...n,index:t},box:s[t]})})}return{nodes:r,zones:o}}var B="data-es-empty-cell",M="data-puck-dropzone",$=140,K=e=>({left:e.left,top:e.top,width:e.width,height:e.height});function X(i){const{canvas:d,session:u,readOnly:h,words:v=e.canvas}=i,w=p(i);m(()=>{w.current=i});const N=p(null),D=a(d),[S,T]=f(0),E=g(()=>T(e=>e+1),[]),[L,O]=f(C);m(()=>{const e=N.current;d&&e&&O((w.current.measure??j)(d,e))},[d,D,i.revision,S]);const $=i.model,X=b(()=>$(L),[$,L]),P=y(u.subscribe,u.shown,u.shown),[q,R]=f(null),[Y,_]=f(null),G=p(null),I=()=>{G.current&&clearTimeout(G.current),G.current=null},Z=()=>{I(),G.current=setTimeout(()=>{u.get()||R(null)},140)};m(()=>I,[]),r(d,"mousemove",e=>{const t=N.current;if(!d||!t||w.current.readOnly||u.get())return;I();const n=o(d.frame,e.clientX,e.clientY,t),l=s(t),a=A(X.sources,n.x/l,n.y/l);R(e=>e?.key===a?.key&&e?.box===a?.box?e:a)}),r(d,"mouseout",e=>{e.relatedTarget||Z()}),r(d,"mouseover",e=>{e.relatedTarget||E()});const F=p(null),Q=g(()=>{F.current?.(),F.current=null,_(null)},[]);m(()=>u.subscribe(()=>{u.get()?E():Q()}),[u,Q,E]),m(()=>Q,[Q]);const U=e=>{const t=u.get(),n=N.current;if(!t||!n)return null;const a=c(n,e.clientX,e.clientY),r=z(X.zones,a.x,a.y,e=>w.current.canDrop(t.item,e),e=>!!t.from&&l(t.from,e));return r?{h:t,t:r}:null},V={onDragEnter:e=>{if(F.current)return;const l=t(e.currentTarget.parentElement?.parentElement??null);F.current=l?n(l):null},onDragOver:e=>{const t=U(e);if(!t)return void _(null);e.preventDefault(),e.dataTransfer.dropEffect=/move|all|uninitialized/i.test(e.dataTransfer.effectAllowed)?"move":"copy";const n={zoneKey:t.t.zone.key,line:t.t.line,axis:t.t.zone.axis};_(e=>e&&e.zoneKey===n.zoneKey&&e.line.left===n.line.left&&e.line.top===n.line.top?e:n)},onDragLeave:e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||_(null)},onDrop:e=>{const t=U(e);t&&(e.preventDefault(),u.end(),Q(),w.current.onDrop(t.h.item,t.t.to))}},H={draggable:!h&&!!q,onMouseEnter:I,onMouseLeave:()=>!u.get()&&Z(),onDragStart:e=>{if(q&&!h){u.start({key:q.key,item:q.item,from:q.from}),e.dataTransfer.effectAllowed="move";try{e.dataTransfer.setData("text/plain",q.key)}catch{}}else e.preventDefault()},onDragEnd:()=>{u.end(),Q()},onClick:()=>{q&&!h&&w.current.onPick?.(q.item)}},{seams:W=[]}=X,J=X.zones.filter(e=>0===e.children.length),ee=i.onZoneAdd&&!h?J:[],te=ee.map(e=>e.key).join("\n");return m(()=>{const e=d?.document;if(!e)return;const t=new Set(te?te.split("\n"):[]);for(const n of e.querySelectorAll(`[${M}]`))n.toggleAttribute(B,t.has(n.getAttribute(M)??""));return()=>{for(const t of e.querySelectorAll(`[${B}]`))t.removeAttribute(B)}},[d,te,L,D,S]),/* @__PURE__ */x("div",{ref:N,className:"es-canvas-layer",children:[P||!i.onSeamAdd||h?null:W.map(e=>/* @__PURE__ */k("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__ */k("button",{type:"button",className:"es-canvas-seam-add",onClick:()=>i.onSeamAdd?.(e.place),children:v.addButton({label:i.seamLabel??v.addSection})})},e.key)),ee.length?ee.map(e=>/* @__PURE__ */k("button",{type:"button",className:Y?.zoneKey===e.key?"es-canvas-empty is-over":"es-canvas-empty",style:K(e.box),onClick:()=>i.onZoneAdd?.({...e.list,index:0}),children:/* @__PURE__ */k("span",{className:"es-canvas-empty-add",children:v.addButton({label:i.zoneAddLabel??v.addBlock})})},e.key)):null,P?/* @__PURE__ */k("div",{className:"es-canvas-catch",...V}):null,Y&&!J.some(e=>e.key===Y.zoneKey)?/* @__PURE__ */k("div",{className:`es-canvas-line is-${Y.axis}`,style:K(Y.line)}):null,
2
- /* @__PURE__ */x("div",{className:["es-canvas-handle",q&&!h?"is-shown":"",P?"is-dragging":""].filter(Boolean).join(" "),style:q?{left:q.box.left+2,top:Math.max(q.box.top-11,0)}:void 0,title:q?q.title??v.handle({label:q.label}):void 0,...H,children:[
3
- /* @__PURE__ */k("span",{className:"es-canvas-grip","aria-hidden":"true",children:"⋮⋮"}),q?.label]})]})}var P=e=>e.tiles.length>0&&e.tiles.every(e=>null!=e.cover);function q({groups:t,session:n,itemFor:l,onInsert:a,at:r,hint:o,searchLabel:s,readOnly:i,words:c=e.add}){const h=o??c.hint,p=s??c.search,[m,g]=f(""),b=v(),y=m.trim().toLowerCase(),w=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);/* @__PURE__ */
4
- return x("div",{className:"es-add",children:[r?/* @__PURE__ */x("div",{className:"es-add-at",role:"status",children:[
5
- /* @__PURE__ */k("span",{children:r.label}),
6
- /* @__PURE__ */k("button",{type:"button",className:"es-add-at-clear","aria-label":c.stop,title:c.stop,onClick:r.onClear,children:/* @__PURE__ */k(d,{size:12,"aria-hidden":"true"})})]}):null,
7
- /* @__PURE__ */k("p",{className:"es-add-hint",children:h}),
8
- /* @__PURE__ */x("div",{className:"es-add-search",children:[
9
- /* @__PURE__ */k(u,{size:16,"aria-hidden":"true"}),
10
- /* @__PURE__ */k("input",{id:b,type:"search","aria-label":p,placeholder:c.searchPlaceholder({label:p}),value:m,onChange:e=>g(e.target.value)}),m?/* @__PURE__ */k("button",{type:"button",className:"es-add-search-clear","aria-label":c.clearSearch,onClick:()=>g(""),children:/* @__PURE__ */k(d,{size:12,"aria-hidden":"true"})}):null]}),0===w.length?/* @__PURE__ */x("div",{className:"es-add-empty",role:"status",children:[
11
- /* @__PURE__ */k("div",{className:"es-add-empty-title",children:c.nothing({query:m.trim()})}),
12
- /* @__PURE__ */k("div",{className:"es-add-empty-sub",children:c.tryAnother})]}):w.map(e=>/* @__PURE__ */x("section",{className:"es-add-group","aria-label":e.title,children:[
13
- /* @__PURE__ */x("div",{className:"es-add-group-head",children:[
14
- /* @__PURE__ */k("span",{className:"es-add-group-title",children:e.title}),
15
- /* @__PURE__ */k("span",{className:"es-add-group-count",children:e.tiles.length})]}),
16
- /* @__PURE__ */k("div",{className:P(e)?"es-add-grid is-cards":"es-add-grid",children:e.tiles.map(e=>{/* @__PURE__ */return x("button",{type:"button",className:null!=e.cover?"es-add-tile has-cover":"es-add-tile",draggable:!i,"aria-disabled":i||void 0,"aria-label":c.tile({label:e.label}),title:i?void 0:e.title??c.tile({label:e.label}),onDragStart:(t=e.type,e=>{if(i)e.preventDefault();else{n.start({key:`new:${t}`,item:l(t)}),e.dataTransfer.effectAllowed="copy";try{e.dataTransfer.setData("text/plain",t)}catch{}}}),onDragEnd:()=>n.end(),onClick:()=>!i&&a(e.type),children:[null!=e.cover?/* @__PURE__ */k("span",{className:"es-add-tile-cover","aria-hidden":"true",children:e.cover}):e.icon?/* @__PURE__ */k("span",{className:"es-add-tile-glyph","aria-hidden":"true",children:e.icon}):null,
17
- /* @__PURE__ */k("span",{className:"es-add-tile-label",children:e.label})]},e.type);var t})})]},e.title))]})}export{q as AddPanel,X as CanvasDragLayer,C as EMPTY_MEASURE,$ as HANDLE_GRACE_MS,z as canvasTarget,w as contains,D as gapInZone,S as gapLine,j as measureCanvas,A as pickSource,T as seamsBetween};
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};
@@ -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] {
@@ -1,14 +1,14 @@
1
- import { E as EaselConfig, a as EaselView, b as EaselAction, P as Permissions, c as EaselCore, d as EaselUi } from '../types-BOSGNvil.js';
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 { DataInput } from '../data/index.js';
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-C7HFvdtk.js';
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
- /** Called with the new document after every change that changed it — once
21
- * per `batch`, once per undo / redo. Not called for `load`. */
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
- /** One Puck action. Outside a `batch`, one undo step when it records. */
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, type Editor, EditorCanvas, type EditorCanvasProps, type EditorOptions, EditorProvider, NodeSelection, Permissions, type SelectedFields, bindUndoKeys, createEasel, createEditor, createUseEasel, createUseEditor, recordsByDefault, reduce, uiView, useEasel, useEaselApi, useEaselNodeOps, useEditor, useEditorApi, useEditorNodeOps, useSelectedFields, validSelection };
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 };
@@ -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, newEditorClientId, readLockHolder, reloadIfVersionMoved, shouldReleaseHeldWrite, shouldReloadAfterTakeover };
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 };
@@ -1 +1 @@
1
- export{EDIT_LOCK_TAKEN,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEaselClientId,newEditorClientId,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-672FAEKU.js";import"../chunk-RE4LP46F.js";
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";