efficient-easel 0.99.0 → 0.99.2

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 (58) hide show
  1. package/README.md +55 -26
  2. package/dist/autosave/index.d.ts +5 -5
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/canvas/index.d.ts +3 -3
  5. package/dist/chrome/index.d.ts +13 -9
  6. package/dist/chrome/index.js +9 -9
  7. package/dist/chunk-672FAEKU.js +1 -0
  8. package/dist/chunk-7JTL3P6P.js +1 -0
  9. package/dist/chunk-F2PIG3AA.js +10 -0
  10. package/dist/chunk-XUE5O62R.js +3 -0
  11. package/dist/copy/index.d.ts +5 -5
  12. package/dist/data/index.d.ts +4 -4
  13. package/dist/drag/drag.css +26 -6
  14. package/dist/drag/index.d.ts +4 -4
  15. package/dist/drag/index.js +5 -6
  16. package/dist/{editor/editor.css → easel/easel.css} +10 -1
  17. package/dist/easel/index.d.ts +385 -0
  18. package/dist/easel/index.js +1 -0
  19. package/dist/edit-lock/index.d.ts +5 -3
  20. package/dist/edit-lock/index.js +1 -1
  21. package/dist/editor/index.d.ts +9 -360
  22. package/dist/editor/index.js +1 -9
  23. package/dist/fields/index.d.ts +4 -4
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.js +1 -1
  26. package/dist/menu/index.d.ts +8 -6
  27. package/dist/menu/index.js +4 -4
  28. package/dist/node-ops/index.d.ts +9 -9
  29. package/dist/panel/index.d.ts +1 -1
  30. package/dist/pick/index.d.ts +3 -3
  31. package/dist/rail/index.d.ts +10 -6
  32. package/dist/rail/index.js +1 -1
  33. package/dist/rail/rail.css +1 -1
  34. package/dist/strings/catalogue.d.ts +23 -17
  35. package/dist/strings/catalogue.js +1 -1
  36. package/dist/strings/index.d.ts +28 -20
  37. package/dist/strings/index.js +2 -2
  38. package/dist/style-clipboard/index.d.ts +5 -5
  39. package/dist/tree/index.d.ts +2 -2
  40. package/dist/{types-Dy6oR6Z2.d.ts → types-BOSGNvil.d.ts} +26 -14
  41. package/dist/{types-DNrn_w4V.d.ts → types-Bs_gVkVI.d.ts} +18 -10
  42. package/dist/{types-pGBXevBU.d.ts → types-DO-b0LNj.d.ts} +13 -7
  43. package/dist/{types-CnRzp9oc.d.ts → types-p9j2Fac7.d.ts} +11 -9
  44. package/dist/{watch-DmasQA61.d.ts → watch-B5RTR-WX.d.ts} +1 -1
  45. package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
  46. package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
  47. package/dist/{words-bOMsUJk9.d.ts → words-C74EUpFr.d.ts} +2 -2
  48. package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
  49. package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
  50. package/dist/{words-BK-npta-.d.ts → words-N4ebT88_.d.ts} +1 -1
  51. package/dist/{words-Cqmyey0s.d.ts → words-c-3h9xQQ.d.ts} +2 -2
  52. package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
  53. package/package.json +9 -3
  54. package/dist/chunk-IBOFSS56.js +0 -3
  55. package/dist/chunk-JE63JHKO.js +0 -1
  56. package/dist/chunk-TDA4HH54.js +0 -1
  57. /package/dist/{chunk-OWBO4WKA.js → chunk-2PHD4L6A.js} +0 -0
  58. /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
@@ -1,7 +1,6 @@
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 D(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 S(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 A(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 T(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=S(e,t,n),o={...e.list,index:r};if(a(o))return null;if(l(o))return{zone:e,to:o,line:A(e,r)}}return null}function z(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=140,M=e=>({left:e.left,top:e.top,width:e.width,height:e.height});function K(i){const{canvas:d,session:u,readOnly:h,words:v=e.canvas}=i,w=p(i);m(()=>{w.current=i});const N=p(null),S=a(d),[A,z]=f(0),E=g(()=>z(e=>e+1),[]),[L,O]=f(C);m(()=>{const e=N.current;d&&e&&O((w.current.measure??j)(d,e))},[d,S,i.revision,A]);const B=i.model,K=b(()=>B(L),[B,L]),X=y(u.subscribe,u.shown,u.shown),[P,$]=f(null),[R,Y]=f(null),_=p(null),G=()=>{_.current&&clearTimeout(_.current),_.current=null},q=()=>{G(),_.current=setTimeout(()=>{u.get()||$(null)},140)};m(()=>G,[]),r(d,"mousemove",e=>{const t=N.current;if(!d||!t||w.current.readOnly||u.get())return;G();const n=o(d.frame,e.clientX,e.clientY,t),l=s(t),a=D(K.sources,n.x/l,n.y/l);$(e=>e?.key===a?.key&&e?.box===a?.box?e:a)}),r(d,"mouseout",e=>{e.relatedTarget||q()}),r(d,"mouseover",e=>{e.relatedTarget||E()});const I=p(null),Z=g(()=>{I.current?.(),I.current=null,Y(null)},[]);m(()=>u.subscribe(()=>{u.get()?E():Z()}),[u,Z,E]),m(()=>Z,[Z]);const F=e=>{const t=u.get(),n=N.current;if(!t||!n)return null;const a=c(n,e.clientX,e.clientY),r=T(K.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},Q={onDragEnter:e=>{if(I.current)return;const l=t(e.currentTarget.parentElement?.parentElement??null);I.current=l?n(l):null},onDragOver:e=>{const t=F(e);if(!t)return void Y(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};Y(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)||Y(null)},onDrop:e=>{const t=F(e);t&&(e.preventDefault(),u.end(),Z(),w.current.onDrop(t.h.item,t.t.to))}},U={draggable:!h&&!!P,onMouseEnter:G,onMouseLeave:()=>!u.get()&&q(),onDragStart:e=>{if(P&&!h){u.start({key:P.key,item:P.item,from:P.from}),e.dataTransfer.effectAllowed="move";try{e.dataTransfer.setData("text/plain",P.key)}catch{}}else e.preventDefault()},onDragEnd:()=>{u.end(),Z()},onClick:()=>{P&&!h&&w.current.onPick?.(P.item)}},{seams:V=[]}=K,H=K.zones.filter(e=>0===e.children.length);/* @__PURE__ */
2
- return x("div",{ref:N,className:"es-canvas-layer",children:[X||!i.onSeamAdd||h?null:V.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)),i.onZoneAdd&&!h?H.map(e=>/* @__PURE__ */k("button",{type:"button",className:R?.zoneKey===e.key?"es-canvas-empty is-over":"es-canvas-empty",style:M(e.box),onClick:()=>i.onZoneAdd?.({...e.list,index:0}),children:v.addButton({label:i.zoneAddLabel??v.addBlock})},e.key)):null,X?/* @__PURE__ */k("div",{className:"es-canvas-catch",...Q}):null,R&&!H.some(e=>e.key===R.zoneKey)?/* @__PURE__ */k("div",{className:`es-canvas-line is-${R.axis}`,style:M(R.line)}):null,
3
- /* @__PURE__ */x("div",{className:["es-canvas-handle",P&&!h?"is-shown":"",X?"is-dragging":""].filter(Boolean).join(" "),style:P?{left:P.box.left+2,top:Math.max(P.box.top-11,0)}:void 0,title:P?P.title??v.handle({label:P.label}):void 0,...U,children:[
4
- /* @__PURE__ */k("span",{className:"es-canvas-grip","aria-hidden":"true",children:"⋮⋮"}),P?.label]})]})}var X=e=>e.tiles.length>0&&e.tiles.every(e=>null!=e.cover);function P({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__ */
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__ */
5
4
  return x("div",{className:"es-add",children:[r?/* @__PURE__ */x("div",{className:"es-add-at",role:"status",children:[
6
5
  /* @__PURE__ */k("span",{children:r.label}),
7
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,
@@ -14,5 +13,5 @@ return x("div",{className:"es-add",children:[r?/* @__PURE__ */x("div",{className
14
13
  /* @__PURE__ */x("div",{className:"es-add-group-head",children:[
15
14
  /* @__PURE__ */k("span",{className:"es-add-group-title",children:e.title}),
16
15
  /* @__PURE__ */k("span",{className:"es-add-group-count",children:e.tiles.length})]}),
17
- /* @__PURE__ */k("div",{className:X(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,
18
- /* @__PURE__ */k("span",{className:"es-add-tile-label",children:e.label})]},e.type);var t})})]},e.title))]})}export{P as AddPanel,K as CanvasDragLayer,C as EMPTY_MEASURE,B as HANDLE_GRACE_MS,T as canvasTarget,w as contains,S as gapInZone,A as gapLine,j as measureCanvas,D as pickSource,z as seamsBetween};
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,5 +1,5 @@
1
1
  /*
2
- * efficient-easel/editor — the canvas's own marks (blueprint 5.1): the
2
+ * efficient-easel/easel — the canvas's own marks (blueprint 5.1): the
3
3
  * lists' empty and selected states, and the outlines over the selected and
4
4
  * hovered block. Puck's `puck.css` drew these until now; the rules follow it.
5
5
  *
@@ -42,6 +42,15 @@
42
42
  background: color-mix(in srgb, var(--es-accent, #2563eb) 6%, transparent);
43
43
  outline: 2px dashed color-mix(in srgb, var(--es-accent, #2563eb) 35%, transparent);
44
44
  }
45
+ /* …except an empty list the drag layer draws its "+ Add block" cell over
46
+ (`data-es-empty-cell`, efficient-easel/drag): at rest that slot draws
47
+ NOTHING, and the cell shows on hover (owner design B, 2026-10-06). The
48
+ states above still draw on it. A rule of its own rather than a :not() on
49
+ `.es-zone:empty`: hosts read that selector by its spelling. */
50
+ .es-zone:empty[data-es-empty-cell]:not(.is-area-selected):not(.is-hovering-area:not(.is-root)) {
51
+ background: none;
52
+ outline: none;
53
+ }
45
54
 
46
55
  .es-canvas-outline {
47
56
  pointer-events: none;
@@ -0,0 +1,385 @@
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';
3
+ import { N as NodeSelection } from '../plan-DChbUXdS.js';
4
+ export { I as ItemSelector } from '../plan-DChbUXdS.js';
5
+ import { DataInput } from '../data/index.js';
6
+ import { S as SlotAddress, D as Data, P as Place } from '../types-41704JE4.js';
7
+ import { c as ResolveTrigger, a as ResolveCache, R as ResolvableItem } from '../resolve-D68pb3Bx.js';
8
+ import * as react from 'react';
9
+ import { ReactNode, CSSProperties, ComponentType, ReactElement } from 'react';
10
+ import { b as NodeOpsHost, C as ClipboardEntry } from '../useNodeOps-BF0fQsif.js';
11
+ import { I as InspectorFields } from '../types-C7HFvdtk.js';
12
+ import '../buckets-CuLM47h9.js';
13
+
14
+ interface EaselOptions<C extends EaselConfig = EaselConfig> {
15
+ config: C;
16
+ /** The document — Puck 0.20's shape, unchanged. */
17
+ data: DataInput | Data;
18
+ /** The host's own UI keys to start with (and an `itemSelector`, if any). */
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`. */
22
+ onChange?: (data: Data) => void;
23
+ /** Easel-wide permissions, under each block's own (Puck's `permissions`). */
24
+ permissions?: Partial<Permissions>;
25
+ /**
26
+ * Changes recorded closer together than this collapse into ONE undo step —
27
+ * Puck's 250 ms history debounce, so a word typed into a field is undone as
28
+ * a word and not as letters. A `batch` is never collapsed into its
29
+ * neighbours. 0 records every change on its own.
30
+ */
31
+ historyCoalesceMs?: number;
32
+ /** The clock, for tests. */
33
+ now?: () => number;
34
+ }
35
+ interface Easel<C extends EaselConfig = EaselConfig> {
36
+ /** What `useEasel` reads. The same object until the state changes. */
37
+ getState: () => EaselView<C>;
38
+ subscribe: (listener: () => void) => () => void;
39
+ /** One Puck action. Outside a `batch`, one undo step when it records. */
40
+ dispatch: (action: EaselAction) => void;
41
+ /**
42
+ * Run several changes as ONE: one undo step, one `onChange`, and one
43
+ * notification to subscribers. Each dispatch inside sees the ones before it.
44
+ * Throwing inside puts everything back. Batches nest; only the outer one
45
+ * records.
46
+ */
47
+ batch: (fn: () => void) => void;
48
+ /** Select a node by id, or nothing. Selection is not an undo step. */
49
+ select: (id: string | null) => void;
50
+ /** Select a slot — a column — or nothing. */
51
+ selectSlot: (address: SlotAddress | null) => void;
52
+ /** Apply a node-ops plan (`{ data, select }`) as one change. */
53
+ run: (plan: {
54
+ data: Data;
55
+ select?: NodeSelection | undefined;
56
+ }) => void;
57
+ /**
58
+ * Put a different document in WITHOUT remounting anything — Puck needed a
59
+ * new `key` on `<Puck>` for that, which threw away every subscriber's state.
60
+ * The history starts again at this document unless `keepHistory`.
61
+ */
62
+ load: (data: DataInput | Data, options?: {
63
+ keepHistory?: boolean;
64
+ selection?: NodeSelection;
65
+ }) => void;
66
+ undo: () => void;
67
+ redo: () => void;
68
+ setPermissions: (permissions: Partial<Permissions>) => void;
69
+ /**
70
+ * Run every block's `resolveData` over the document, as `<Puck>` did when it
71
+ * mounted (trigger `'load'`), and write what changed as ONE change folded
72
+ * into the step it happens in — a resolver bringing a stale document up to
73
+ * date is not an undo step (Puck made it one, which undid back to the stale
74
+ * document). `onChange` hears it, as Puck's did. `EaselProvider` runs this
75
+ * on mount; a node changed by hand while it ran is left as the hand left it.
76
+ */
77
+ resolveAll: (options?: {
78
+ trigger?: ResolveTrigger;
79
+ metadata?: Record<string, unknown>;
80
+ }) => Promise<void>;
81
+ /** This easel's memory of the last change each node was resolved for —
82
+ * Puck kept one per editor, shared by every write that resolves. */
83
+ readonly resolveCache: ResolveCache;
84
+ /**
85
+ * Swap the config in place — `<Puck>` took a new `config` prop live. The
86
+ * website editor rebuilds a few blocks' fields when the site's gap moves; the
87
+ * document, the selection and the history are untouched.
88
+ */
89
+ setConfig: (config: C) => void;
90
+ /** The config in force now. */
91
+ readonly config: C;
92
+ }
93
+ /**
94
+ * Puck 0.20's UI at mount (`defaultAppState.ui`), less the selection, which
95
+ * the store holds by id. A host's chrome reads these — the website editor
96
+ * opens its side panels from `leftSideBarVisible` / `rightSideBarVisible` — so
97
+ * a host moving off `<Puck>` finds them where they were.
98
+ */
99
+ declare const DEFAULT_UI: Record<string, unknown>;
100
+ /**
101
+ * THE EASEL STORE (blueprint step 5.1): the document, the selection by id and
102
+ * the host's UI keys, with Puck's actions, Puck's history and a `batch` Puck
103
+ * never had. Framework-free — `useEasel` (./react) is the React binding.
104
+ */
105
+ 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
+
113
+ /**
114
+ * Puck 0.20's reducer, on `efficient-easel/data` — blueprint step 5.1.
115
+ *
116
+ * Each action means what it meant to Puck, so the apps' `dispatch` calls move
117
+ * over unchanged (`reorder`'s and `move`'s indexes, `replaceRoot` MERGING
118
+ * props, `duplicate` selecting the copy, `insert` leaving the selection where
119
+ * it was). Two things differ, on purpose:
120
+ *
121
+ * - THE SELECTION IS BY ID. Puck held `itemSelector` — a place — so a node
122
+ * inserted or removed above the selected one silently moved the selection
123
+ * onto its neighbour, and both editors carried patches for exactly that.
124
+ * Here `itemSelector` is derived from the id on every read, and a
125
+ * selection whose node is gone becomes nothing rather than whatever now
126
+ * sits in its place.
127
+ * - A SLOT CAN BE SELECTED (a column): `ui.selectedSlot`, which Puck had no
128
+ * way to say.
129
+ */
130
+ /** Whether Puck records an action in history when the action does not say:
131
+ * everything but the state-setters. */
132
+ declare function recordsByDefault(action: EaselAction): boolean;
133
+ /** The UI as Puck shows it: the host's keys, with the selection translated. */
134
+ declare function uiView(core: EaselCore, config: EaselConfig): EaselUi;
135
+ /** A selection that still points at something; otherwise nothing. */
136
+ declare function validSelection(data: Data, config: EaselConfig, selection: NodeSelection): NodeSelection;
137
+ /** One action, applied. Pure: the same core and action give the same core. */
138
+ declare function reduce(core: EaselCore, action: EaselAction, config: EaselConfig): EaselCore;
139
+
140
+ interface EaselProviderProps {
141
+ easel: Easel;
142
+ hotkeys?: boolean;
143
+ /** Run every block's `resolveData` once the easel mounts, as `<Puck>` did
144
+ * (`easel.resolveAll`). On by default. */
145
+ resolveOnMount?: boolean;
146
+ children?: ReactNode;
147
+ }
148
+ /** Puts one easel in reach of everything under it — `<Puck>`'s provider
149
+ * half — and, as `<Puck>` did, binds undo / redo to the page's keyboard
150
+ * (`hotkeys={false}` for a host that binds its own) and runs every block's
151
+ * `resolveData` once on mount (`resolveOnMount={false}` to skip). */
152
+ declare function EaselProvider({ easel, hotkeys, resolveOnMount, children }: EaselProviderProps): react.JSX.Element;
153
+ /** The easel itself, for handlers that read the state at the moment they run
154
+ * (`useGetPuck`'s job) and for `dispatch` / `batch` / `select`. */
155
+ declare function useEaselApi<C extends EaselConfig = EaselConfig>(): Easel<C>;
156
+ /**
157
+ * Read a slice of the easel and re-render when it changes — `usePuck` /
158
+ * `createUsePuck()`'s selector form, over the same state shape, so the apps'
159
+ * selectors move over by renaming the hook.
160
+ *
161
+ * A selector may return a fresh object; the snapshot is cached per state and
162
+ * per selector, so React sees the same value for the same state and does not
163
+ * loop. A primitive or an unchanged reference does not re-render.
164
+ */
165
+ declare function useEasel<T, C extends EaselConfig = EaselConfig>(selector: (view: EaselView<C>) => T): T;
166
+ /**
167
+ * A typed `useEasel` for one config — `createUsePuck<Config>()`'s shape, so
168
+ * a file that made its own typed hook keeps the one line that made it.
169
+ */
170
+ 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
+
183
+ /** What a slot component accepts — Puck's. */
184
+ interface CanvasSlotProps {
185
+ className?: string;
186
+ style?: CSSProperties;
187
+ allow?: string[];
188
+ disallow?: string[];
189
+ minEmptyHeight?: number;
190
+ collisionAxis?: unknown;
191
+ }
192
+ interface CanvasFrameProps {
193
+ children?: ReactNode;
194
+ /** `preview-frame` by default — the id the apps' canvas watchers look for. */
195
+ id?: string;
196
+ /**
197
+ * The frame's accessible name. Default "Canvas", in the strings provider's
198
+ * language (`EaselStrings.canvas.frame`).
199
+ */
200
+ title?: string;
201
+ className?: string;
202
+ style?: CSSProperties;
203
+ /** Copy the host page's stylesheets into the frame, and keep them in step.
204
+ * On by default: the blocks are styled by the app's own CSS. */
205
+ mirrorStyles?: boolean;
206
+ /** Called with the frame's document once it is ready, and null when it goes. */
207
+ onDocument?: (doc: Document | null) => void;
208
+ /**
209
+ * `'auto'` (the default, Puck's): the frame is as tall as its content, and
210
+ * the host's pane scrolls it — so the canvas reads like the page it is.
211
+ * `'fill'`: the frame fills its parent and scrolls itself.
212
+ */
213
+ height?: 'auto' | 'fill';
214
+ /**
215
+ * The page's CSP nonce, for a host whose policy allows styles by nonce
216
+ * (`style-src 'nonce-…'`). The frame is the host page's own document, so the
217
+ * same policy applies in it, and a stylesheet without the nonce is refused.
218
+ * Given, it is set on every stylesheet the canvas puts in the frame: each
219
+ * `<style>` and `<link rel="stylesheet">` copied in from the host
220
+ * (`mirrorStyles`), and each sheet `useCanvasStyle` / `upsertCanvasStyle`
221
+ * (`efficient-easel/canvas`) creates there. Left out, nothing changes.
222
+ *
223
+ * Read when the frame is built, like `mirrorStyles`: a nonce is the page's
224
+ * for as long as the page lives.
225
+ */
226
+ nonce?: string;
227
+ }
228
+ /**
229
+ * An iframe of the easel's own, with the content portalled in. No `src`: the
230
+ * frame's first document is used — there to write into at once, with no load
231
+ * to wait for and nothing fetched. The host's stylesheets are copied into its
232
+ * head and copied again whenever the host's head changes (a route's CSS
233
+ * arriving late, a dev reload).
234
+ *
235
+ * ⚠️ THAT FIRST DOCUMENT HAS NO DOCTYPE, SO IT RENDERS IN QUIRKS MODE, and it
236
+ * is rewritten with one before anything is drawn. Puck's frame was a
237
+ * `<!DOCTYPE html>` srcdoc, so every block was written against standards mode;
238
+ * in quirks mode a `height: 100%` resolves through auto-height ancestors (an
239
+ * empty slot grew to the frame's full height), tables stop inheriting the
240
+ * page's font, and an image's line box changes. (0.89.0–0.92.0 shipped the
241
+ * quirks-mode frame.)
242
+ */
243
+ declare function CanvasFrame({ children, id, title, className, style, mirrorStyles, onDocument, height, nonce, }: CanvasFrameProps): react.JSX.Element;
244
+ /**
245
+ * The whole document, for editing. Works in a `CanvasFrame` or on its own.
246
+ *
247
+ * `metadata` is the easel-wide metadata: the root's `puck.metadata`, and —
248
+ * under each block's own — every block's (see the header).
249
+ */
250
+ declare function EditDocument({ metadata }: {
251
+ metadata?: Record<string, unknown>;
252
+ }): react.JSX.Element;
253
+ /** What a host may wrap an outline in — Puck's `componentOverlay`: render
254
+ * `children` to draw it, or nothing to hide it (a text part open on the
255
+ * block, say). */
256
+ type CanvasOverlay = ComponentType<{
257
+ componentId: string;
258
+ kind: 'selected' | 'hover';
259
+ children: ReactNode;
260
+ }>;
261
+ interface EaselCanvasProps {
262
+ /** Draw in an iframe of the easel's own (default), or straight into the page. */
263
+ frame?: boolean;
264
+ className?: string;
265
+ style?: CSSProperties;
266
+ /**
267
+ * The easel-wide metadata — what the published page passes `Render` as
268
+ * `metadata`. Every block reads it as `puck.metadata` (its own `metadata`
269
+ * laid over it) and the root as it is. Change it whenever the host's data
270
+ * changes: the blocks redraw in place, nothing remounts, and it never enters
271
+ * the document or the undo history.
272
+ */
273
+ metadata?: Record<string, unknown>;
274
+ /** Copy the host's stylesheets into the frame (default true). */
275
+ mirrorStyles?: boolean;
276
+ /** The frame's height: as tall as its content (default, Puck's), or filling its parent. */
277
+ height?: 'auto' | 'fill';
278
+ /**
279
+ * The frame's accessible name — an iframe with none is announced as "frame".
280
+ * Default "Canvas", in the strings provider's language. Unused with
281
+ * `frame={false}`, where there is no frame to name.
282
+ */
283
+ title?: string;
284
+ /** The page's CSP nonce for the frame's stylesheets — see `CanvasFrameProps.nonce`. Unused with `frame={false}`. */
285
+ nonce?: string;
286
+ onDocument?: (doc: Document | null) => void;
287
+ /**
288
+ * Wraps everything drawn in the frame, and is handed the frame's document —
289
+ * Puck's `overrides.iframe`: where a host syncs its theme onto the frame's
290
+ * `<html>` or adds frame-only CSS.
291
+ */
292
+ frameWrapper?: ComponentType<{
293
+ document?: Document;
294
+ children: ReactNode;
295
+ }>;
296
+ /** Wraps each outline — Puck's `componentOverlay`; see `CanvasOverlay`. */
297
+ overlay?: CanvasOverlay;
298
+ /** Drawn inside the frame, after the document — a host's canvas-only layer. */
299
+ children?: ReactNode;
300
+ }
301
+ /**
302
+ * `<Puck.Preview>`, ours: the document for editing, its outlines, and the
303
+ * clicks that select. Must sit under an `EaselProvider`.
304
+ */
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;
310
+
311
+ /**
312
+ * THE PARTS, ON THE STORE (blueprint step 5.2).
313
+ *
314
+ * Every part built in steps 2.1–4.9 takes a HOST — what to read, how to write
315
+ * — so it never knew Puck. Until now each app wrote that host twice, once per
316
+ * editor, against Puck's store: `EmailFields` and `SiteFields` for the settings
317
+ * panel, the node-ops host for the menus. These are the hosts, written ONCE,
318
+ * against the engine's store; the parts' own APIs do not change.
319
+ */
320
+ /** `useNodeOps` with the store as its host: reads the document, and writes one
321
+ * `run` — one undo step, the selection travelling with it. */
322
+ declare function useEaselNodeOps(options?: Omit<NodeOpsHost, 'data' | 'config' | 'commit'>): {
323
+ held: ClipboardEntry | null;
324
+ remove: (id: string) => boolean;
325
+ duplicate: (id: string) => boolean;
326
+ move: (id: string, to: Place) => boolean;
327
+ step: (id: string, dir: -1 | 1) => boolean;
328
+ canStep: (id: string, dir: -1 | 1) => boolean;
329
+ setProps: (id: string, patch: Record<string, unknown>) => boolean;
330
+ copy: (id: string, label: string) => boolean;
331
+ cut: (id: string, label: string) => boolean;
332
+ paste: (at: Place) => boolean;
333
+ parentOf: (selection: NodeSelection) => NodeSelection;
334
+ };
335
+ interface SelectedFields {
336
+ /** The selected node's id, or `"root"` with nothing selected. */
337
+ id: string;
338
+ /** The node the fields are for — the selected one, or the root as `{ type: 'root', props }`. */
339
+ node: ResolvableItem;
340
+ /** Its fields, resolved as Puck resolved them (`resolveFields` with Puck's params, parent included). */
341
+ fields: InspectorFields;
342
+ /** What the fields show. */
343
+ values: Record<string, unknown>;
344
+ /** The block's (or the root's) `edit` permission is off. */
345
+ readOnly: boolean;
346
+ /** Write one field: `resolveData` as Puck ran it, then ONE replace — one undo step. */
347
+ onChange: (name: string, value: unknown) => void;
348
+ }
349
+ /**
350
+ * The settings panel's host: the selected node's fields and the write that
351
+ * changes one — what `EmailFields` and `SiteFields` each did against Puck,
352
+ * here once:
353
+ * - fields resolve through `useResolvedFields` (Puck's
354
+ * `useRegisterFieldsSlice`: `changed`, `lastFields`, `appState`, `parent`);
355
+ * - a change runs the block's `resolveData` (`resolveNodeData`, Puck's
356
+ * `resolveComponentData`, with this easel's own memory of the last
357
+ * change) and then writes ONE `replace` of the node, or ONE `replaceRoot`.
358
+ *
359
+ * The write reads the node AT THE MOMENT IT RUNS, by id: a field changed while
360
+ * a resolver is still running writes onto what is current, never onto what was
361
+ * selected when the change began.
362
+ */
363
+ declare function useSelectedFields(): SelectedFields;
364
+ /** @deprecated The name before the Easel rename: `useEaselNodeOps`. */
365
+ declare const useEditorNodeOps: typeof useEaselNodeOps;
366
+
367
+ /**
368
+ * UNDO AND REDO ON THE KEYBOARD — Puck's own six bindings, which both editors
369
+ * relied on without writing any: ⌘Z / Ctrl+Z undo; ⇧⌘Z, ⌘Y, Ctrl+Shift+Z and
370
+ * Ctrl+Y redo.
371
+ *
372
+ * Exact combinations, read off the physical key (`code`, as Puck read it), so
373
+ * a layout that moves Z still undoes and ⌥⌘Z does nothing.
374
+ *
375
+ * ⚠️ PUCK FIRED THESE IN A TEXT FIELD TOO, and so does this: ⌘Z while typing
376
+ * in a setting undoes the easel's last step — which, since a field writes as
377
+ * it is typed, is the typing — and the browser's own text undo is prevented,
378
+ * so there are never two undo histories answering one key.
379
+ *
380
+ * Bound per DOCUMENT: the host page (`EaselProvider`) and the canvas frame
381
+ * (`EaselCanvas`), because a key pressed in the frame never reaches the page.
382
+ */
383
+ declare function bindUndoKeys(doc: Document, easel: Pick<Easel, 'undo' | 'redo'>): () => void;
384
+
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 };
@@ -0,0 +1 @@
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";
@@ -177,7 +177,7 @@ declare const documentPermissions: (canEdit: boolean) => DocumentPermissions;
177
177
  /**
178
178
  * "just now" / "2 minutes ago" — one phrasing, shared by every notice.
179
179
  *
180
- * `words` is the host's language (`useEditorStrings().lock`, 0.95.0); left out,
180
+ * `words` is the host's language (`useEaselStrings().lock`, 0.95.0); left out,
181
181
  * it is the English it always was. The thresholds are not words and do not
182
182
  * move: under 45 seconds is "just now", then whole minutes, then whole hours.
183
183
  */
@@ -192,7 +192,9 @@ declare const nameOrSomeone: (name: string, words?: LockWords) => string;
192
192
  * a reload IS a new editor session, and a remembered id would let a closed tab's
193
193
  * claim look alive.
194
194
  */
195
- declare function newEditorClientId(): string;
195
+ declare function newEaselClientId(): string;
196
+ /** @deprecated The name before the Easel rename: `newEaselClientId`. */
197
+ declare const newEditorClientId: typeof newEaselClientId;
196
198
  /**
197
199
  * The `code` of a document write refused because somebody else TOOK the
198
200
  * document from this tab (backend `efficient/editlock.py`,
@@ -351,4 +353,4 @@ type EditLock = {
351
353
  /** Bind the decisions to one editor's HTTP client and document type. */
352
354
  declare function createEditLock(adapter: EditLockAdapter): EditLock;
353
355
 
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, newEditorClientId, readLockHolder, reloadIfVersionMoved, shouldReleaseHeldWrite, shouldReloadAfterTakeover };
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 };
@@ -1 +1 @@
1
- export{EDIT_LOCK_TAKEN,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEditorClientId,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-TDA4HH54.js";import"../chunk-RE4LP46F.js";
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";