efficient-easel 0.99.2 → 0.101.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 (108) 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 +25 -21
  9. package/dist/{chunk-JYPOOHII.js → chunk-2FZJWH24.js} +3 -3
  10. package/dist/chunk-3EDSDPIP.js +1 -0
  11. package/dist/chunk-546BBOPE.js +1 -0
  12. package/dist/chunk-67GNT6PF.js +1 -0
  13. package/dist/chunk-EOJNJCMJ.js +16 -0
  14. package/dist/chunk-EWVJSRRY.js +6 -0
  15. package/dist/chunk-FPOKPNO4.js +1 -0
  16. package/dist/chunk-H24N5TMZ.js +11 -0
  17. package/dist/chunk-IG3U5NWJ.js +1 -0
  18. package/dist/chunk-JUQ6YJCG.js +1 -0
  19. package/dist/chunk-KTVH2ZRL.js +15 -0
  20. package/dist/{chunk-PI26YXYD.js → chunk-L5KW4HG5.js} +16 -8
  21. package/dist/chunk-M6F6LS3H.js +1 -0
  22. package/dist/chunk-P6O363EE.js +6 -0
  23. package/dist/chunk-PAELDYYS.js +1 -0
  24. package/dist/chunk-QTLAVDJE.js +1 -0
  25. package/dist/chunk-UH7IGZKF.js +1 -0
  26. package/dist/chunk-WZ7TGAAT.js +3 -0
  27. package/dist/chunk-ZFDCDJNZ.js +16 -0
  28. package/dist/chunk-ZJEBF4NB.js +1 -0
  29. package/dist/chunk-ZNS7727Y.js +12 -0
  30. package/dist/copy/copy.css +442 -5
  31. package/dist/copy/index.d.ts +302 -5
  32. package/dist/copy/index.js +32 -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 +270 -38
  42. package/dist/fields/index.d.ts +209 -26
  43. package/dist/fields/index.js +22 -53
  44. package/dist/gold/index.js +1 -1
  45. package/dist/icons/index.d.ts +13 -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 +111 -10
  50. package/dist/markup/index.js +1 -1
  51. package/dist/menu/index.d.ts +58 -5
  52. package/dist/menu/index.js +1 -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 +83 -4
  57. package/dist/panel/index.js +18 -16
  58. package/dist/panel/panel.css +135 -62
  59. package/dist/pick/index.d.ts +78 -2
  60. package/dist/pick/index.js +7 -14
  61. package/dist/pick/pick.css +197 -10
  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-BGrHZAJJ.d.ts +46 -0
  84. package/dist/{words-c-3h9xQQ.d.ts → words-BMzV04b1.d.ts} +1 -1
  85. package/dist/words-CRYvAiHX.d.ts +105 -0
  86. package/dist/words-D8kf071T.d.ts +93 -0
  87. package/dist/{words-N4ebT88_.d.ts → words-DgHcY5qB.d.ts} +9 -3
  88. package/dist/{words-C74EUpFr.d.ts → words-XH0TvZPg.d.ts} +60 -4
  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/words-CD3WADyb.d.ts +0 -51
  108. /package/dist/{chunk-2PHD4L6A.js → chunk-OWBO4WKA.js} +0 -0
@@ -1,53 +1,22 @@
1
- import{LayersTree as e,TreeSeam as n,TreeRow as t,TreeRowAction as r}from"../chunk-66CKSTXP.js";import{SettingsField as l,SETTINGS_BUCKETS as a,SettingsTabs as i,SettingsGroup as s}from"../chunk-67VZRQLG.js";import{DEFAULT_FIELDS_WORDS as o}from"../chunk-SUO5627P.js";import{DEFAULT_TREE_WORDS as c}from"../chunk-H4B72XCJ.js";import{DEFAULT_PANEL_WORDS as d}from"../chunk-7A7O2JWQ.js";export{useResolvedFields}from"../chunk-YRLPFZW3.js";import{SettingsSegmented as u}from"../chunk-QB3BZIRA.js";import{useWords as m}from"../chunk-MFIRYGHW.js";import"../chunk-BZ5ASXOL.js";import{useTreeDrag as p,gapToMoveIndex as h}from"../chunk-6PS6STGA.js";import"../chunk-PI26YXYD.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";import{useState as f,useRef as b,useEffect as v,useId as y}from"react";import{jsxs as g,jsx as k,Fragment as x}from"react/jsx-runtime";function w(e,n,t){let r=e;return"number"==typeof n&&r<n&&(r=n),"number"==typeof t&&r>t&&(r=t),r}function N(e){const n=e.trim().replace(",",".");if(""===n||"-"===n||"."===n||"-."===n)return null;const t=Number(n);return Number.isFinite(t)?t:null}function C(e){const n=String(e),t=n.indexOf(".");return t<0?0:n.length-t-1}function O({value:e,onChange:n,min:t,max:r,step:l=1,shiftStep:a,styleValue:i,readOnly:s=!1}){const o="number"==typeof e&&Number.isFinite(e)?e:void 0,c=void 0===o?"":String(o),[d,u]=f(c),m=b(o),p=b(o);v(()=>{m.current=o,u(e=>N(e)===(o??null)?e:c)},[o,c]);const h=e=>{s||(m.current=e,n(e))},y=e=>{s||(u(void 0===e?"":String(e)),e!==m.current&&h(e))},g=(e,n=!1)=>{if(s)return;const o=w(function(e,n){const t=Math.max(C(e),C(n));return Number((e+n).toFixed(t))}(m.current??i??t??0,e*(n?a??10*l:l)),t,r);u(String(o)),h(o)},k=()=>{const e=N(d);null!==e?y(w(e,t,r)):u(void 0===m.current?"":String(m.current))};return{inputProps:{value:d,readOnly:s,placeholder:void 0===i?void 0:String(i),onFocus:()=>{p.current=m.current},onChange:e=>{const n=e.target.value;if(u(n),""===n.trim())h(void 0);else{const e=N(n);null!==e&&h(e)}},onBlur:k,onKeyDown:e=>{"ArrowUp"===e.key||"ArrowDown"===e.key?(e.preventDefault(),g("ArrowUp"===e.key?1:-1,e.shiftKey)):"Enter"===e.key?(e.preventDefault(),k(),p.current=m.current):"Escape"===e.key&&(e.preventDefault(),y(p.current))}},nudge:g,set:y,isStyle:void 0!==i&&""===d.trim()}}function S({dir:e,label:n,disabled:t,nudge:r}){const l=b(null),a=b(r);a.current=r;const i=b({}),s=()=>{const e=i.current;void 0!==e.wait&&clearTimeout(e.wait),void 0!==e.every&&clearInterval(e.every),e.off?.(),i.current={}};v(()=>{const e=l.current;return e?.addEventListener("pointerleave",s),e?.addEventListener("pointercancel",s),()=>{e?.removeEventListener("pointerleave",s),e?.removeEventListener("pointercancel",s),s()}},[]);/* @__PURE__ */
2
- return k("button",{ref:l,type:"button",tabIndex:-1,className:"es-fnum-arrow es-fnum-arrow--"+(e>0?"up":"down"),"aria-label":n,disabled:t,onPointerDown:n=>{if(0!==n.button||t)return;n.preventDefault(),s();const r=n.shiftKey;a.current(e,r);const l=n.currentTarget.ownerDocument;l.addEventListener("pointerup",s),i.current={off:()=>l.removeEventListener("pointerup",s),wait:setTimeout(()=>{i.current.every=setInterval(()=>a.current(e,r),60)},350)}},onClick:n=>{0===n.detail&&a.current(e,n.shiftKey)},children:/* @__PURE__ */k("svg",{viewBox:"0 0 10 10","aria-hidden":"true",focusable:"false",children:/* @__PURE__ */k("path",{d:e>0?"M2.5 6.25 5 3.75l2.5 2.5":"M2.5 3.75 5 6.25l2.5-2.5"})})})}function $({id:e,value:n,onChange:t,min:r,max:l,step:a=1,shiftStep:i,styleValue:s,icon:c,unit:d,steppers:u=!1,placeholder:p,readOnly:h=!1,ariaLabel:f,ariaLabelledBy:b}){const v=m("fields",o),{inputProps:y,nudge:x,isStyle:w}=O({value:n,onChange:t,min:r,max:l,step:a,shiftStep:i,styleValue:s,readOnly:h});/* @__PURE__ */
3
- return g("div",{className:`es-fnum${u?" es-fnum--arrows":""}${w?" is-style":""}${h?" is-readonly":""}`,children:[c?/* @__PURE__ */k("span",{className:"es-fnum-icon","aria-hidden":"true",children:c}):null,
4
- /* @__PURE__ */k("input",{id:e,type:"text",inputMode:"decimal",className:"es-fnum-box","aria-label":f,"aria-labelledby":b,...y,placeholder:y.placeholder??p}),d?/* @__PURE__ */k("span",{className:"es-fnum-unit",children:d}):null,u?/* @__PURE__ */g("span",{className:"es-fnum-arrows",children:[
5
- /* @__PURE__ */k(S,{dir:1,label:v.more,disabled:h,nudge:x}),
6
- /* @__PURE__ */k(S,{dir:-1,label:v.less,disabled:h,nudge:x})]}):null]})}function I(e,n){return e.find(e=>Object.is(e.value,n))}function L({id:e,value:n,options:t,onChange:r,placeholder:l,readOnly:a=!1,ariaLabel:i,ariaLabelledBy:s}){const c=m("fields",o),d=y(),[u,p]=f(!1),[h,x]=f(0),w=b(null),N=b(null),C=b(null),O=I(t,n),S=O?t.indexOf(O):-1,$=()=>{a||0===t.length||(x(S>=0?S:0),p(!0))},L=e=>{p(!1),e&&N.current?.focus()},j=e=>{const l=t[e];l&&!l.disabled&&(Object.is(l.value,n)||r(l.value),L(!0))};v(()=>{if(!u)return;C.current?.focus();const e=w.current?.ownerDocument;if(!e)return;const n=e=>{w.current&&!w.current.contains(e.target)&&p(!1)};return e.addEventListener("click",n,!0),()=>e.removeEventListener("click",n,!0)},[u]);const D=e=>{const n=t.length;if(0===n)return;let r=(e%n+n)%n;for(let l=0;l<n&&t[r]?.disabled;l++)r=(r+(e>=h?1:-1)+n)%n;x(r)};/* @__PURE__ */
7
- return g("div",{className:"es-fsel",ref:w,children:[
8
- /* @__PURE__ */g("button",{ref:N,id:e,type:"button",className:"es-fin es-fsel-button","aria-haspopup":"listbox","aria-expanded":u,"aria-controls":u?d:void 0,"aria-label":i,"aria-labelledby":s,disabled:a,onClick:()=>u?L(!1):$(),onKeyDown:e=>{"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),$())},children:[
9
- /* @__PURE__ */k("span",{className:O?"es-fsel-value":"es-fsel-value is-empty",children:O?O.label:l??c.choose}),
10
- /* @__PURE__ */k("span",{className:"es-fsel-chev","aria-hidden":"true"})]}),u?/* @__PURE__ */k("ul",{ref:C,id:d,role:"listbox",tabIndex:-1,className:"es-fsel-list","aria-activedescendant":`${d}-${h}`,"aria-labelledby":s,"aria-label":s?void 0:i,onKeyDown:e=>{switch(e.key){case"ArrowDown":return e.preventDefault(),void D(h+1);case"ArrowUp":return e.preventDefault(),void D(h-1);case"Home":return e.preventDefault(),void D(0);case"End":return e.preventDefault(),void D(t.length-1);case"Enter":case" ":return e.preventDefault(),void j(h);case"Escape":return e.preventDefault(),e.stopPropagation(),void L(!0);case"Tab":return void L(!1);default:if(1===e.key.length&&/\S/.test(e.key)){const n=e.key.toLowerCase(),r=t.length;for(let e=1;e<=r;e++){const l=(h+e)%r;if(!t[l]?.disabled&&t[l]?.label.toLowerCase().startsWith(n))return void x(l)}}}},children:t.map((e,n)=>/* @__PURE__ */k("li",{id:`${d}-${n}`,role:"option","aria-selected":n===S,"aria-disabled":e.disabled||void 0,className:`es-fsel-option${n===h?" is-active":""}${n===S?" is-chosen":""}`,onMouseEnter:()=>x(n),onClick:()=>j(n),children:e.label},`${n}-${String(e.value)}`))}):null]})}function j({id:e,value:n,onChange:t,placeholder:r,multiline:l=!1,rows:a=3,readOnly:i=!1,ariaLabel:s,ariaLabelledBy:o}){const c=n??"";return l?/* @__PURE__ */k("textarea",{id:e,className:"es-fin es-fin--area",value:c,rows:a,placeholder:r,readOnly:i,"aria-label":s,"aria-labelledby":o,onChange:e=>t(e.target.value)}):/* @__PURE__ */k("input",{id:e,type:"text",className:"es-fin",value:c,placeholder:r,readOnly:i,"aria-label":s,"aria-labelledby":o,onChange:e=>t(e.target.value)})}function D(e,n,t){const r=e.slice();return r.splice(Math.max(0,Math.min(n,r.length)),0,t),r}function M(e,n,t){const r=e.slice(),[l]=r.splice(n,1);return r.splice(Math.max(0,Math.min(t,r.length)),0,l),r}function P(e,n){return e.filter((e,t)=>t!==n)}function A(e){return null===e||"object"!=typeof e?e:JSON.parse(JSON.stringify(e))}function B(){/* @__PURE__ */
11
- return g("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:[
12
- /* @__PURE__ */k("circle",{cx:"9",cy:"6",r:"1.6"}),
13
- /* @__PURE__ */k("circle",{cx:"15",cy:"6",r:"1.6"}),
14
- /* @__PURE__ */k("circle",{cx:"9",cy:"12",r:"1.6"}),
15
- /* @__PURE__ */k("circle",{cx:"15",cy:"12",r:"1.6"}),
16
- /* @__PURE__ */k("circle",{cx:"9",cy:"18",r:"1.6"}),
17
- /* @__PURE__ */k("circle",{cx:"15",cy:"18",r:"1.6"})]})}var E={parentId:"list",slot:"items"};function F({label:l,icon:a,noun:i,items:s,onChange:d,newItem:u,summary:f,itemName:b,thumb:v,min:y=0,max:w,readOnly:N=!1,open:C,onOpen:O,renderItem:S}){const $=m("fields",o).list,I=m("tree",c),L=i??$.item,j=!N&&("number"!=typeof w||s.length<w),F=!N&&s.length>y,K=(e,n)=>b?b(e,n):$.itemName({noun:L,n:n+1}),V=p({keyOf:e=>String(e),canDrop:(e,n)=>n.parentId===E.parentId&&n.slot===E.slot,onDrop:(e,n)=>{const t=h({...E,index:e},n);t!==e&&d(M(s,e,t))},onStep:(e,n)=>d(M(s,e,e+n)),canStep:(e,n)=>e+n>=0&&e+n<s.length,readOnly:N}),T=e=>{j&&d(D(s,e,u()))},R=e=>{j&&d(D(s,e+1,A(s[e])))},W=e=>{F&&(d(P(s,e)),null!==C&&O(null))};if(null!==C&&C>=0&&C<s.length){const e=s[C];/* @__PURE__ */
18
- return g("div",{className:"es-list is-open",children:[
19
- /* @__PURE__ */g("button",{type:"button",className:"es-list-back",onClick:()=>O(null),children:[
20
- /* @__PURE__ */k("span",{className:"es-list-back-chev","aria-hidden":"true"}),l]}),
21
- /* @__PURE__ */g("div",{className:"es-list-title",children:[
22
- /* @__PURE__ */k("span",{className:"es-list-name",children:K(e,C)}),
23
- /* @__PURE__ */k("span",{className:"es-list-count",children:$.position({n:C+1,total:s.length})})]}),
24
- /* @__PURE__ */k("div",{className:"es-list-item",children:S(e,C,e=>{const n=s.slice();n[C]=e,d(n)})}),N?null:/* @__PURE__ */g("div",{className:"es-list-item-actions",children:[
25
- /* @__PURE__ */k("button",{type:"button",className:"es-fbtn",disabled:!j,onClick:()=>R(C),children:$.duplicate}),
26
- /* @__PURE__ */k("button",{type:"button",className:"es-fbtn es-fbtn--danger",disabled:!F,onClick:()=>W(C),children:$.deleteItem({noun:L})})]})]})}/* @__PURE__ */
27
- return g("div",{className:"es-list",children:[
28
- /* @__PURE__ */g("div",{className:"es-list-head",children:[
29
- /* @__PURE__ */g("span",{className:"es-list-label",children:[a?/* @__PURE__ */k("span",{className:"es-field-icon","aria-hidden":"true",children:a}):null,l]}),
30
- /* @__PURE__ */k("span",{className:"es-list-count",children:s.length})]}),s.length?/* @__PURE__ */g(e,{className:"es-list-tree",rootProps:V.rootProps(),children:[s.map((e,l)=>{const a={...E,index:l},i=V.row({item:l,place:a});/* @__PURE__ */
31
- return g("div",{className:"es-list-entry",children:[l>0?/* @__PURE__ */k(n,{...V.seam({place:a}),onAdd:j?()=>T(l):void 0,label:$.addHere({noun:L})}):null,
32
- /* @__PURE__ */k(t,{icon:v?v(e,l):/* @__PURE__ */k(B,{}),name:K(e,l),preview:f?f(e,l):void 0,draggable:i.draggable,dragging:i.dragging,drop:i.drop,rowProps:i.rowProps,words:I,onSelect:()=>O(l),actions:N?void 0:/* @__PURE__ */g(x,{children:[
33
- /* @__PURE__ */k(r,{kind:"plain",label:$.duplicateItem({noun:L}),disabled:!j,onClick:()=>R(l),children:/* @__PURE__ */g("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[
34
- /* @__PURE__ */k("rect",{x:"9",y:"9",width:"11",height:"11",rx:"2"}),
35
- /* @__PURE__ */k("path",{d:"M5 15V6a2 2 0 0 1 2-2h9"})]})}),
36
- /* @__PURE__ */k(r,{kind:"delete",label:$.deleteItem({noun:L}),disabled:!F,onClick:()=>W(l),children:/* @__PURE__ */k("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round","aria-hidden":"true",children:/* @__PURE__ */k("path",{d:"M4 7h16M10 11v6M14 11v6M6 7l1 12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-12M9 7V4h6v3"})})})]})})]},l)}),
37
- /* @__PURE__ */k(n,{...V.seam({place:{...E,index:s.length}})})]}):null,N?null:/* @__PURE__ */k("button",{type:"button",className:"es-list-add",disabled:!j,onClick:()=>T(s.length),children:$.add({noun:L})})]})}var K=(e,n)=>"string"==typeof e.label&&e.label?e.label:n;function V({field:e,name:n,id:t,value:r,onChange:l,readOnly:a,context:i,renderers:o}){const[c,d]=f(!0),u=r&&"object"==typeof r?r:{};/* @__PURE__ */
38
- return k(s,{id:`${t}-group`,title:K(e,n),open:c,onToggle:d,children:Object.entries(e.objectFields).map(([e,r])=>/* @__PURE__ */k(R,{field:r,name:`${n}.${e}`,id:`${t}-${e}`,value:u[e],onChange:n=>l({...u,[e]:n}),readOnly:a,context:i,renderers:o},e))})}function T({field:e,name:n,id:t,value:r,onChange:l,readOnly:a,context:i,renderers:s,openItem:o,onOpenItem:c}){const[d,u]=f(null),m=c?o??null:d,p=c??u,h=Array.isArray(r)?r:[],b=e.getItemSummary;/* @__PURE__ */
39
- return k(F,{label:K(e,n),icon:e.icon,noun:"string"==typeof e.noun?e.noun:void 0,items:h,onChange:l,newItem:()=>A({...e.defaultItemProps??{}}),summary:b?(e,n)=>b(e,n):void 0,min:e.min,max:e.max,readOnly:a,open:m,onOpen:p,renderItem:(r,l,o)=>Object.entries(e.arrayFields).map(([e,c])=>/* @__PURE__ */k(R,{field:c,name:`${n}[${l}].${e}`,id:`${t}-${l}-${e}`,value:r?.[e],onChange:n=>o({...r,[e]:n}),readOnly:a,context:i,renderers:s},e))})}function R(e){const{field:n,name:t,id:r,value:a,onChange:i,readOnly:s,context:o,renderers:c}=e;if(!n||n.marker||!1===n.visible)return null;const d=c?.[n.type];if(d)return d({field:n,name:t,id:r,value:a,onChange:i,readOnly:s});switch(n.type){case"custom":{const e={...o,field:n,name:t,id:r,value:a,onChange:i,readOnly:s};return n.render(e)}case"text":case"textarea":/* @__PURE__ */
40
- return k(l,{label:K(n,t),htmlFor:r,icon:n.icon,hint:n.hint,children:/* @__PURE__ */k(j,{id:r,value:"string"==typeof a?a:null==a?"":String(a),onChange:i,placeholder:n.placeholder,multiline:"textarea"===n.type,readOnly:s})});case"number":/* @__PURE__ */
41
- return k(l,{label:K(n,t),htmlFor:r,icon:n.icon,hint:n.hint,children:/* @__PURE__ */k($,{id:r,value:"number"==typeof a?a:void 0,onChange:i,min:n.min,max:n.max,step:n.step,placeholder:n.placeholder,readOnly:s})});case"select":/* @__PURE__ */
42
- return k(l,{label:K(n,t),htmlFor:r,icon:n.icon,hint:n.hint,children:/* @__PURE__ */k(L,{id:r,value:a,options:n.options,onChange:i,readOnly:s})});case"radio":/* @__PURE__ */
43
- return k(l,{label:K(n,t),icon:n.icon,hint:n.hint,children:/* @__PURE__ */k(u,{ariaLabel:K(n,t),value:a,options:n.options.map(e=>({id:e.value,label:e.label,icon:e.icon,disabled:e.disabled||s})),onChange:e=>{s||i(e)}})});case"object":/* @__PURE__ */
44
- return k(V,{...e,field:n});case"array":/* @__PURE__ */
45
- return k(T,{...e,field:n});case"slot":return null}}var W=e=>a.includes(e);function X(e){let n=a[0];const t=[],r=/* @__PURE__ */new Set;for(const[l,a]of Object.entries(e))a&&(W(a.bucket)&&(n=a.bucket),a.marker||!1===a.visible||(t.push({name:l,field:a,bucket:n}),"slot"!==a.type&&r.add(n)));return{rows:t,buckets:a.filter(e=>r.has(e))}}function U(e){return new Map(X(e).rows.map(e=>[e.name,e.bucket]))}function H({fields:e,values:n,onChange:t,readOnly:r=!1,context:l,tab:a,onTab:s,tabs:o=!0,tabIcons:c,renderers:u,idPrefix:p,ariaLabel:h,children:b}){const v=m("panel",d),x=y(),w=p??`es-insp${x.replace(/:/g,"")}`,N=X(e),[C,O]=f(void 0),S=a??C,$=S&&N.buckets.includes(S)?S:N.buckets[0],[I,L]=f(null),j=I&&I.panel===w&&N.rows.some(e=>e.name===I.name)?I:null,D=o&&N.buckets.length>1&&!j,M=`${w}-rows`,P=e=>`${w}-tab-${e.toLowerCase()}`;/* @__PURE__ */
46
- return g("div",{className:"es-insp",children:[D?/* @__PURE__ */k("div",{className:"es-insp-tabs",children:/* @__PURE__ */k(i,{ariaLabel:h??v.settings,activeId:$,onSelect:e=>{const n=e;void 0===a&&O(n),s?.(n)},items:N.buckets.map(e=>({id:e,label:v.buckets[e],icon:c?.[e],htmlId:P(e),panelId:M}))})}):null,
47
- /* @__PURE__ */g("div",{className:"es-insp-rows",id:M,role:D?"tabpanel":void 0,"aria-labelledby":D&&$?P($):void 0,children:[N.rows.map(({name:e,field:a,bucket:i})=>/* @__PURE__ */k("div",{className:"es-insp-row","data-field":e,"data-bucket":i,hidden:!!(j?j.name!==e:D&&i!==$)||void 0,children:/* @__PURE__ */k(R,{field:a,name:e,id:`${w}-${e}`,value:n[e],onChange:n=>t(e,n),readOnly:r,context:l,renderers:u,openItem:j&&j.name===e?j.index:null,onOpenItem:n=>L(null===n?null:{panel:w,name:e,index:n})})},e)),j?null:b]})]})}function J({id:e,label:n,value:t,onChange:r,min:l,max:a,step:i=1,shiftStep:s,styleValue:o,unit:c,sliderMin:d,sliderMax:u,readOnly:m=!1}){const p=y(),h=e??p,{inputProps:f,set:b,isStyle:v}=O({value:t,onChange:r,min:l,max:a,step:i,shiftStep:s,styleValue:o,readOnly:m}),x="number"==typeof t&&Number.isFinite(t)?t:o??d;/* @__PURE__ */
48
- return g("div",{className:"es-fslider"+(v?" is-style":""),children:[
49
- /* @__PURE__ */g("div",{className:"es-fslider-top",children:[
50
- /* @__PURE__ */k("label",{className:"es-fslider-name",htmlFor:h,children:n}),
51
- /* @__PURE__ */g("span",{className:"es-fslider-read",children:[
52
- /* @__PURE__ */k("input",{id:h,type:"text",inputMode:"decimal",className:"es-fslider-value",...f}),c?/* @__PURE__ */k("span",{className:"es-fslider-unit",children:c}):null]})]}),
53
- /* @__PURE__ */k("input",{type:"range",className:"es-fslider-range",min:d,max:u,step:i,value:w(x,d,u),disabled:m,"aria-label":n,onChange:e=>b(Number(e.target.value))})]})}export{$ as FieldNumber,L as FieldSelect,J as FieldSlider,j as FieldText,H as Inspector,R as InspectorField,F as ListField,U as bucketsOf,w as clampNumber,A as copyItem,D as insertAt,K as labelOf,M as moveTo,I as optionFor,N as parseTyped,X as planFields,P as removeAt,O as useNumberEntry};
1
+ import{FieldSelect as e}from"../chunk-EOJNJCMJ.js";export{FieldSelect,FieldSlider,optionFor}from"../chunk-EOJNJCMJ.js";import{TreeSeam as n}from"../chunk-ZFDCDJNZ.js";import{SettingsField as l,SETTINGS_BUCKETS as t,SettingsTabs as a,SettingsGroup as r}from"../chunk-ZNS7727Y.js";import{DEFAULT_TREE_WORDS as i}from"../chunk-3EDSDPIP.js";import{DEFAULT_PANEL_WORDS as o}from"../chunk-QTLAVDJE.js";export{useResolvedFields}from"../chunk-YRLPFZW3.js";import{EaselContextMenu as s}from"../chunk-KTVH2ZRL.js";import{FieldNumber as c}from"../chunk-EWVJSRRY.js";export{FieldNumber,clampNumber,parseTyped,useNumberEntry}from"../chunk-EWVJSRRY.js";import{SettingsSegmented as u}from"../chunk-P6O363EE.js";import{DEFAULT_FIELDS_WORDS as d}from"../chunk-FPOKPNO4.js";import{useWords as m}from"../chunk-MFIRYGHW.js";import"../chunk-BZ5ASXOL.js";import{useTreeDrag as p,gapToMoveIndex as h}from"../chunk-67GNT6PF.js";import{ChevronIcon as b,LockIcon as f,MoveUpIcon as v,MoveDownIcon as g,DuplicateIcon as y,TrashIcon as x}from"../chunk-L5KW4HG5.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";import{useRef as k,useState as N,useLayoutEffect as O,useId as w}from"react";import{jsx as C,jsxs as j}from"react/jsx-runtime";function S({id:e,value:n,onChange:l,placeholder:t,multiline:a=!1,rows:r=3,readOnly:i=!1,ariaLabel:o,ariaLabelledBy:s}){const c=n??"";return a?/* @__PURE__ */C("textarea",{id:e,className:"es-fin es-fin--area",value:c,rows:r,placeholder:t,readOnly:i,"aria-label":o,"aria-labelledby":s,onChange:e=>l(e.target.value)}):/* @__PURE__ */C("input",{id:e,type:"text",className:"es-fin",value:c,placeholder:t,readOnly:i,"aria-label":o,"aria-labelledby":s,onChange:e=>l(e.target.value)})}function I(e,n,l){const t=e.slice();return t.splice(Math.max(0,Math.min(n,t.length)),0,l),t}function D(e,n,l){const t=e.slice(),[a]=t.splice(n,1);return t.splice(Math.max(0,Math.min(l,t.length)),0,a),t}function F(e,n){return e.filter((e,l)=>l!==n)}function $(e){return null===e||"object"!=typeof e?e:JSON.parse(JSON.stringify(e))}var L='input, textarea, select, button, [contenteditable]:not([contenteditable="false"]), [tabindex]',E={parentId:"list",slot:"items"};function P({label:e,icon:l,noun:t,items:a,onChange:r,newItem:o,summary:c,itemName:u,thumb:w,min:S=0,max:P,readOnly:R=!1,open:A,onOpen:M,renderItem:J,renderRow:T,canRemove:K,lockedReason:B,fixed:z=!1,removeOnRow:H=!0,canDuplicate:V,above:W,head:Y=!0}){const Z=m("fields",d).list,X=m("tree",i),q=t??Z.item,G=!R&&!z&&("number"!=typeof P||a.length<P),Q=a.length<=S,U=e=>!!K&&!K(a[e],e),_=e=>!R&&!z&&H&&!Q&&!U(e),ee=e=>G&&(!V||V(a[e],e)),ne=(e,n)=>u?u(e,n):Z.itemName({noun:q,n:n+1}),le=k([]),te=k(null),[ae,re]=N(null),ie=k(null),[oe,se]=N(null),[ce,ue]=N("");O(()=>{for(const e of le.current){if(!e)continue;null!==e.querySelector(L)||R?e.removeAttribute("tabindex"):e.tabIndex=0}}),O(()=>{const e=te.current;if(!e)return;te.current=null;const n=le.current[e.index]?.querySelectorAll(L)[e.nth]??le.current[e.index];if(n?.focus(),n&&null!==e.start&&"setSelectionRange"in n)try{n.setSelectionRange(e.start,e.end)}catch{}});const de=(e,n)=>{if(n<0||n>=a.length||n===e)return;const l=le.current[e],t=l?.ownerDocument.activeElement;if(l&&t&&l.contains(t)){const e=[...l.querySelectorAll(L)].indexOf(t),a=t;te.current={index:n,nth:e,start:"number"==typeof a.selectionStart?a.selectionStart:null,end:"number"==typeof a.selectionEnd?a.selectionEnd:null}}r(D(a,e,n));const i=function(e,n,l){return null===e?null:e===n?l:n<e&&l>=e?e-1:n>e&&l<=e?e+1:e}(A,e,n);i!==A&&M(i),ue(Z.moved({n:n+1,total:a.length}))},me=e=>{G&&(r(I(a,e,o())),T?(te.current={index:e,nth:0,start:null,end:null},null!==A&&A>=e&&M(A+1)):M(e))},pe=e=>{_(e)&&(r(F(a,e)),A===e?M(null):null!==A&&A>e&&M(A-1))},he=p({keyOf:e=>String(e),canDrop:(e,n)=>n.parentId===E.parentId&&n.slot===E.slot,onDrop:(e,n)=>{const l=h({...E,index:e},n);l!==e&&de(e,l)},onStep:(e,n)=>de(e,e+n),canStep:(e,n)=>e+n>=0&&e+n<a.length,readOnly:R}),be=e=>{const n=[];return e>0&&n.push({label:Z.moveUp,icon:/* @__PURE__ */C(v,{size:14}),shortcut:"⌥↑",onClick:()=>de(e,e-1)}),e<a.length-1&&n.push({label:Z.moveDown,icon:/* @__PURE__ */C(g,{size:14}),shortcut:"⌥↓",onClick:()=>de(e,e+1)}),ee(e)&&n.push({label:Z.duplicate,icon:/* @__PURE__ */C(y,{size:14}),onClick:()=>(e=>{ee(e)&&(r(I(a,e+1,$(a[e]))),null!==A&&A>e&&M(A+1))})(e)}),_(e)&&n.push({label:Z.delete,icon:/* @__PURE__ */C(x,{size:14}),danger:!0,onClick:()=>pe(e)}),n},fe=(e,n,l)=>{R||0===be(e).length||se({index:e,x:n,y:l})},ve=e=>n=>{const l=a.slice();l[e]=n,r(l)};/* @__PURE__ */
2
+ return j("div",{className:"es-list",children:[Y?/* @__PURE__ */j("div",{className:"es-list-head",children:[
3
+ /* @__PURE__ */j("span",{className:"es-list-label",children:[l?/* @__PURE__ */C("span",{className:"es-field-icon","aria-hidden":"true",children:l}):null,e]}),
4
+ /* @__PURE__ */C("span",{className:"es-list-count",children:a.length})]}):null,W?/* @__PURE__ */C("div",{className:"es-list-above",children:W}):null,a.length?/* @__PURE__ */j("div",{className:"es-list-rows",...he.rootProps(),children:[a.map((e,l)=>{const t=he.row({item:l,place:{...E,index:l}}),a=t.draggable&&ae!==l,r=!T&&A===l,i=!R&&!z&&H&&U(l),o=["es-list-row",T?"is-inline":"is-item",r?"is-open":"",a?"is-draggable":"",t.dragging?"is-dragging":"",t.drop?`is-drop-${t.drop}`:""].filter(Boolean).join(" ");/* @__PURE__ */
5
+ return j("div",{className:"es-list-entry",children:[l>0?/* @__PURE__ */C(n,{...he.seam({place:{...E,index:l}}),onAdd:G?()=>me(l):void 0,label:Z.addHere({noun:q})}):null,
6
+ /* @__PURE__ */j("div",{...t.rowProps,ref:e=>{le.current[l]=e},className:o,draggable:a||void 0,"aria-keyshortcuts":t.draggable?"Alt+ArrowUp Alt+ArrowDown":void 0,onPointerDown:e=>{const n=e.target.closest?.('input, textarea, select, [contenteditable]:not([contenteditable="false"])'),a=!!n&&n===n.ownerDocument.activeElement;e.currentTarget.draggable=t.draggable&&!a,ie.current=n&&!a?n:null,re(a?l:null)},onDragStart:e=>{const n=ie.current;ie.current=null,n&&n.ownerDocument.activeElement===n&&n.blur(),t.rowProps.onDragStart?.(e)},onContextMenu:e=>{R||(e.preventDefault(),e.stopPropagation(),fe(l,e.clientX,e.clientY))},onKeyDown:e=>{if("ContextMenu"===e.key||e.shiftKey&&"F10"===e.key){e.preventDefault();const n=e.currentTarget.ownerDocument,t=e=>e.preventDefault();n.addEventListener("contextmenu",t,{capture:!0,once:!0}),n.defaultView?.setTimeout(()=>n.removeEventListener("contextmenu",t,{capture:!0}),500);const a=e.currentTarget.getBoundingClientRect();return void fe(l,a.left+24,a.bottom)}t.rowProps.onKeyDown?.(e)},children:[a?/* @__PURE__ */C("span",{className:"es-list-hint","aria-hidden":"true",children:X.dragHint}):null,T?/* @__PURE__ */C("div",{className:"es-list-row-main",children:T(e,l,ve(l))}):/* @__PURE__ */j("button",{type:"button",className:"es-list-open","aria-expanded":r,onClick:()=>M(r?null:l),children:[w?/* @__PURE__ */C("span",{className:"es-list-thumb","aria-hidden":"true",children:w(e,l)}):null,
7
+ /* @__PURE__ */C("span",{className:"es-list-row-name",children:ne(e,l)}),/* @__PURE__ */C("span",c?{className:"es-list-row-summary",children:c(e,l)}:{className:"es-list-row-summary"}),
8
+ /* @__PURE__ */C(b,{size:14,className:"es-list-chev","aria-hidden":"true"})]}),R||z||!H?null:i?/* @__PURE__ */C("span",{className:"es-list-lock",role:"img","aria-label":B?B(e,l):Z.locked,title:B?B(e,l):Z.locked,children:/* @__PURE__ */C(f,{size:13})}):/* @__PURE__ */C("button",{type:"button",className:"es-list-x","aria-label":Z.deleteItem({noun:q}),title:Z.deleteItem({noun:q}),disabled:!_(l),onClick:()=>pe(l),children:"×"})]}),r?/* @__PURE__ */C("div",{className:"es-list-item",children:J(e,l,ve(l))}):null]},l)}),
9
+ /* @__PURE__ */C(n,{...he.seam({place:{...E,index:a.length}})})]}):null,R||z?null:/* @__PURE__ */C("button",{type:"button",className:"es-list-add",disabled:!G,onClick:()=>me(a.length),children:Z.add({noun:q})}),
10
+ /* @__PURE__ */C("span",{className:"es-list-said","aria-live":"polite",children:ce}),oe&&oe.index<a.length?/* @__PURE__ */C(s,{x:oe.x,y:oe.y,items:be(oe.index),onClose:()=>se(null)}):null]})}var R=(e,n)=>"string"==typeof e.label&&e.label?e.label:n;function A({field:e,name:n,id:l,value:t,onChange:a,readOnly:i,context:o,renderers:s}){const[c,u]=N(!0),d=t&&"object"==typeof t?t:{};/* @__PURE__ */
11
+ return C(r,{id:`${l}-group`,title:R(e,n),open:c,onToggle:u,children:Object.entries(e.objectFields).map(([e,t])=>/* @__PURE__ */C(J,{field:t,name:`${n}.${e}`,id:`${l}-${e}`,value:d[e],onChange:n=>a({...d,[e]:n}),readOnly:i,context:o,renderers:s},e))})}function M({field:e,name:n,id:l,value:t,onChange:a,readOnly:r,context:i,renderers:o,openItem:s,onOpenItem:c}){const[u,d]=N(null),m=c?s??null:u,p=c??d,h=Array.isArray(t)?t:[],b=e.getItemSummary;/* @__PURE__ */
12
+ return C(P,{label:R(e,n),icon:e.icon,noun:"string"==typeof e.noun?e.noun:void 0,items:h,onChange:a,newItem:()=>$({...e.defaultItemProps??{}}),summary:b?(e,n)=>b(e,n):void 0,min:e.min,max:e.max,readOnly:r,open:m,onOpen:p,renderItem:(t,a,s)=>Object.entries(e.arrayFields).map(([e,c])=>/* @__PURE__ */C(J,{field:c,name:`${n}[${a}].${e}`,id:`${l}-${a}-${e}`,value:t?.[e],onChange:n=>s({...t,[e]:n}),readOnly:r,context:i,renderers:o},e))})}function J(n){const{field:t,name:a,id:r,value:i,onChange:o,readOnly:s,context:d,renderers:m}=n;if(!t||t.marker||!1===t.visible)return null;const p=m?.[t.type];if(p)return p({field:t,name:a,id:r,value:i,onChange:o,readOnly:s});switch(t.type){case"custom":{const e={...d,field:t,name:a,id:r,value:i,onChange:o,readOnly:s};return t.render(e)}case"text":case"textarea":/* @__PURE__ */
13
+ return C(l,{label:R(t,a),htmlFor:r,icon:t.icon,hint:t.hint,children:/* @__PURE__ */C(S,{id:r,value:"string"==typeof i?i:null==i?"":String(i),onChange:o,placeholder:t.placeholder,multiline:"textarea"===t.type,readOnly:s})});case"number":/* @__PURE__ */
14
+ return C(l,{label:R(t,a),htmlFor:r,icon:t.icon,hint:t.hint,children:/* @__PURE__ */C(c,{id:r,value:"number"==typeof i?i:void 0,onChange:o,min:t.min,max:t.max,step:t.step,placeholder:t.placeholder,readOnly:s})});case"select":{const n=`${r}-label`;/* @__PURE__ */
15
+ return C(l,{label:R(t,a),labelId:n,htmlFor:r,icon:t.icon,hint:t.hint,children:/* @__PURE__ */C(e,{id:r,value:i,options:t.options,onChange:o,readOnly:s,ariaLabelledBy:n})})}case"radio":/* @__PURE__ */
16
+ return C(l,{label:R(t,a),icon:t.icon,hint:t.hint,children:/* @__PURE__ */C(u,{ariaLabel:R(t,a),value:i,options:t.options.map(e=>({id:e.value,label:e.label,icon:e.icon,disabled:e.disabled||s})),onChange:e=>{s||o(e)}})});case"object":/* @__PURE__ */
17
+ return C(A,{...n,field:t});case"array":/* @__PURE__ */
18
+ return C(M,{...n,field:t});case"slot":return null}}var T=e=>t.includes(e);function K(e){let n=t[0];const l=[],a=/* @__PURE__ */new Set;for(const[t,r]of Object.entries(e))r&&(T(r.bucket)&&(n=r.bucket),r.marker||!1===r.visible||(l.push({name:t,field:r,bucket:n}),"slot"!==r.type&&a.add(n)));return{rows:l,buckets:t.filter(e=>a.has(e))}}function B(e){return new Map(K(e).rows.map(e=>[e.name,e.bucket]))}function z({fields:e,values:n,onChange:l,readOnly:t=!1,context:r,tab:i,onTab:s,tabs:c=!0,tabIcons:u,renderers:d,idPrefix:p,ariaLabel:h,children:b}){const f=m("panel",o),v=w(),g=p??`es-insp${v.replace(/:/g,"")}`,y=K(e),[x,k]=N(void 0),O=i??x,S=O&&y.buckets.includes(O)?O:y.buckets[0],[I,D]=N(null),F=I&&I.panel===g&&y.rows.some(e=>e.name===I.name)?I:null,$=c&&y.buckets.length>1,L=`${g}-rows`,E=e=>`${g}-tab-${e.toLowerCase()}`;/* @__PURE__ */
19
+ return j("div",{className:"es-insp",children:[$?/* @__PURE__ */C("div",{className:"es-insp-tabs",children:/* @__PURE__ */C(a,{ariaLabel:h??f.settings,activeId:S,onSelect:e=>{const n=e;void 0===i&&k(n),s?.(n)},items:y.buckets.map(e=>({id:e,label:f.buckets[e],icon:u?.[e],htmlId:E(e),panelId:L}))})}):null,
20
+ /* @__PURE__ */j("div",{className:"es-insp-rows",id:L,role:$?"tabpanel":void 0,"aria-labelledby":$&&S?E(S):void 0,children:[y.rows.map(({name:e,field:a,bucket:i})=>/* @__PURE__ */C("div",{className:"es-insp-row","data-field":e,"data-bucket":i,hidden:!(!$||i===S)||void 0,children:/* @__PURE__ */C(J,{field:a,name:e,id:`${g}-${e}`,value:n[e],onChange:n=>l(e,n),readOnly:t,context:r,renderers:d,openItem:F&&F.name===e?F.index:null,onOpenItem:n=>D(null===n?null:{panel:g,name:e,index:n})})},e)),b]})]})}function H(e){return"select"===e.type?e.options:"groups"===e.type?e.groups.flatMap(e=>e.options):[]}function V({value:n,onChange:l,kinds:t,rules:a,filtersFor:r,label:i,readOnly:o}){const s=m("fields",d).link??d.link,[c,u]=N(null),[p,h]=N(null),b=c??a.kindOf(n),f=t.filter(e=>!e.hideWhenEmpty||H(e.target).length>0||e.value===b),v=f.find(e=>"text"===e.target.type),g=f.find(e=>e.value===b)??v??f[0];if(!g)return null;const y="text"!==g.target.type,x=y?a.targetOf(n):n,k=H(g.target),O=k.find(e=>e.value===x),w=e=>({value:e,label:s.unavailable({value:e})}),S="select"===g.target.type&&x&&r?r(x):null,I=S?a.readFilter(n):null,D=I?S?.find(e=>e.param===I.param):void 0,F=p&&p.against===n?p.text:n,$=!y&&""!==F.trim()&&!a.isSafe(F),L=e=>{if(!e)return l("");const n=k.find(n=>n.value===e);l(e,n?.label)},E=(e,n)=>n&&!e.some(e=>e.value===n)?[w(n),...e]:[...e];let P;if("text"===g.target.type)P=/* @__PURE__ */C("input",{type:"text",className:"es-fin","aria-label":s.address,"aria-invalid":$||void 0,placeholder:s.addressPlaceholder,value:F,readOnly:o,onChange:e=>(e=>{const t=e.trim();t?a.isSafe(e)?(h({text:e,against:t}),l(t)):h({text:e,against:n}):(h({text:e,against:""}),l(""))})(e.target.value)});else{const n="groups"===g.target.type?g.target.groups.flatMap(e=>e.options.map(n=>({value:n.value,label:n.label,group:e.label}))):g.target.options.map(e=>({value:e.value,label:e.label}));P=/* @__PURE__ */C(e,{ariaLabel:g.label,value:x,options:[{value:"",label:g.target.placeholder},...E(n,x)],searchable:n.length>10,readOnly:o,onChange:L})}/* @__PURE__ */
21
+ return j("div",{className:"es-flink",role:i?"group":void 0,"aria-label":i,children:[
22
+ /* @__PURE__ */C(e,{ariaLabel:s.linkType,value:g.value,options:f.map(e=>({value:e.value,label:e.label})),readOnly:o,onChange:e=>{u(e),h(null);const n=f.find(n=>n.value===e);if(!n||"text"===n.target.type)return;const t=H(n.target)[0];t?l(t.value,t.label):l("")}}),P,S&&/* @__PURE__ */C(e,{ariaLabel:s.filter,value:I?.param??"",options:[{value:"",label:s.noFilter},...I&&!D?[w(I.param)]:[],...S.map(e=>({value:e.param,label:e.label}))],readOnly:o,onChange:e=>{if(!e)return l(x,O?.label);const n=S?.find(n=>n.param===e),t=n?.values[0];t&&l(a.withFilter(x,{param:e,value:t.value}),t.label)}}),S&&I&&/* @__PURE__ */C(e,{ariaLabel:s.value,value:I.value,options:E((D?.values??[]).map(e=>({value:e.value,label:e.label})),I.value),searchable:(D?.values.length??0)>10,readOnly:o,onChange:e=>{if(!I)return;const n=D?.values.find(n=>n.value===e);l(a.withFilter(x,{param:I.param,value:e}),n?.label)}}),$&&/* @__PURE__ */C("p",{className:"es-flink-error",role:"alert",children:s.unsafe}),g.hint&&/* @__PURE__ */C("p",{className:"es-flink-hint",children:g.hint}),S&&/* @__PURE__ */C("p",{className:"es-flink-hint",children:s.filterHint})]})}export{S as FieldText,z as Inspector,J as InspectorField,V as LinkPicker,P as ListField,B as bucketsOf,$ as copyItem,I as insertAt,R as labelOf,D as moveTo,K as planFields,F as removeAt};
@@ -1 +1 @@
1
- export{GoldLayer,GoldTextInput,goldSegments}from"../chunk-JYPOOHII.js";import"../chunk-SJQG5ENJ.js";var e={accent:"var(--gold, #c9a461)",quiet:"var(--es-muted, #6b7280)",caret:"var(--es-text, #111827)",placeholder:"var(--es-field-placeholder, #9ca3af)",delimiterOpacity:"0.35",delimiterRestingOpacity:"0.25",boldShadow:"0 0 0.4px currentColor",italicDecoration:"underline dotted",strikeDecoration:"line-through",pad:"0"},t={accent:"--es-gold-accent",quiet:"--es-gold-quiet",caret:"--es-gold-caret",placeholder:"--es-gold-placeholder",delimiterOpacity:"--es-gold-delim-opacity",delimiterRestingOpacity:"--es-gold-delim-resting-opacity",boldShadow:"--es-gold-bold-shadow",italicDecoration:"--es-gold-italic-decoration",strikeDecoration:"--es-gold-strike-decoration",pad:"--es-gold-pad"};export{t as goldCssVars,e as goldTokens};
1
+ export{GoldLayer,GoldTextInput,goldSegments}from"../chunk-2FZJWH24.js";import"../chunk-546BBOPE.js";var e={accent:"var(--gold, #c9a461)",quiet:"var(--es-muted, #6b7280)",caret:"var(--es-text, #111827)",placeholder:"var(--es-field-placeholder, #9ca3af)",delimiterOpacity:"0.35",delimiterRestingOpacity:"0.25",boldShadow:"0 0 0.4px currentColor",italicDecoration:"underline dotted",strikeDecoration:"line-through",pad:"0"},t={accent:"--es-gold-accent",quiet:"--es-gold-quiet",caret:"--es-gold-caret",placeholder:"--es-gold-placeholder",delimiterOpacity:"--es-gold-delim-opacity",delimiterRestingOpacity:"--es-gold-delim-resting-opacity",boldShadow:"--es-gold-bold-shadow",italicDecoration:"--es-gold-italic-decoration",strikeDecoration:"--es-gold-strike-decoration",pad:"--es-gold-pad"};export{t as goldCssVars,e as goldTokens};
@@ -167,6 +167,10 @@ declare const iconMeanings: {
167
167
  readonly "case-normal": "letter case LEFT AS TYPED — `Aa`, the `Normal` option of the Letter case buttons (Normal / Uppercase / Lowercase) on the campaign editor's Text block, and of the storefront part panel's Case strip. The plan calls it sentence case; it changes nothing the merchant typed. A capital A beside a one-storey a. Decided 2026-10-06.";
168
168
  readonly "case-upper": "letter case ALL CAPITALS — `AA`, the `Uppercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two capital A's. Decided 2026-10-06.";
169
169
  readonly "case-lower": "letter case ALL SMALL LETTERS — `aa`, the `Lowercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two one-storey a's. Decided 2026-10-06.";
170
+ readonly "align-justify": "JUSTIFY — text whose rows run edge to edge. Worn by the Justify button on the final text box's second toolbar row, beside Left, Center and Right, and by the Justify chip of the alignment strip. Three full-width rows on the same three heights the other alignment glyphs use. Decided 2026-10-06 (the design was made final that day).";
171
+ readonly "panel-left": "the LEFT SIDE PANEL itself — worn by the Hide panel button at the end of a left panel's head (`MediaPanelHead`, both editors' SidePanelHeads) and by the Show panel button in the strip a hidden left panel leaves. One control, so one drawing: hiding and showing the panel wear the same glyph. A frame with its left column ruled off. ⛔ NOT an ✕: an ✕ closes a dialog, and a panel head has none (owner, 2026-10-04).";
172
+ readonly "panel-right": "the RIGHT SIDE PANEL itself — the twin of `panel-left` for the settings panel: its head's Hide panel button and the strip a hidden right panel leaves. A frame with its right column ruled off.";
173
+ readonly braces: "INSERT A MERGE TAG — a word that fills in for each reader ({{first_name}}, a coupon code). Worn by the Insert button the campaign designer puts in the 9th cell of the final text box's first toolbar row (`CopyBox` `lastTool`), which opens its list of tags. Two curly braces, the shape a merge tag is written in. Decided 2026-10-07. ⛔ NOT `code` or a pair of angle brackets: nothing here is code, and the braces are the tag's own spelling.";
170
174
  };
171
175
  type IconName = keyof typeof iconMeanings;
172
176
  /** Delete · keep · efficient-shop · components/UiIcon.tsx:99 */
@@ -491,5 +495,13 @@ declare function CaseNormalIcon({ size, ...rest }: IconProps): react.JSX.Element
491
495
  declare function CaseUpperIcon({ size, ...rest }: IconProps): react.JSX.Element;
492
496
  /** letter case ALL SMALL LETTERS — `aa`, the `Lowercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two one-storey a's. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. MOVED FROM THE STOREFRONT: efficient-storefront `components/PartGlyphs.tsx` `CaseGlyph` (`aa`, live text); the set is the one source now. ⛔ NOT `case-normal`, a capital A beside the a. ⛔ NOT `quiet`, ONE small a drawn under the set's box, which is the quiet mark on a phrase. ⛔ NOT `case`, the row's T + a. A 3-unit channel between the first stem and the second bowl keeps them two letters at 16px. */
493
497
  declare function CaseLowerIcon({ size, ...rest }: IconProps): react.JSX.Element;
498
+ /** JUSTIFY — text whose rows run edge to edge. Worn by the Justify button on the final text box's second toolbar row, beside Left, Center and Right, and by the Justify chip of the alignment strip. Three full-width rows on the same three heights the other alignment glyphs use. Decided 2026-10-06 (the design was made final that day). · new · efficient-easel · E5b, the final text box, design final 2026-10-06: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H — its toolbar draws Justify as `M4 6.5h16M4 12h16M4 17.5h16`, and this is that drawing. ⛔ NOT `align-separate`, whose own entry says "NOT `justify`": it opens a channel down the middle of each row, which is where rows SIT, not how text runs. The package drew Justify with it until now; that was a borrowed meaning. ⛔ NOT `text-lines`, three rules with a short last one, which is a paragraph of body copy. ⛔ NOT `align-left`, whose rows are of three lengths. */
499
+ declare function AlignJustifyIcon({ size, ...rest }: IconProps): react.JSX.Element;
500
+ /** the LEFT SIDE PANEL itself — worn by the Hide panel button at the end of a left panel's head (`MediaPanelHead`, both editors' SidePanelHeads) and by the Show panel button in the strip a hidden left panel leaves. One control, so one drawing: hiding and showing the panel wear the same glyph. A frame with its left column ruled off. ⛔ NOT an ✕: an ✕ closes a dialog, and a panel head has none (owner, 2026-10-04). · new · efficient-easel · card [MERGE] One Media Panel Head For Both Editors, 2026-10-06 — the drawing both editors already carried twice: efficient-storefront components/PanelToggleIcon.tsx and efficient-admin-portal src/components/email/CampaignTopBar.tsx `PanelToggleGlyph`. */
501
+ declare function PanelLeftIcon({ size, ...rest }: IconProps): react.JSX.Element;
502
+ /** the RIGHT SIDE PANEL itself — the twin of `panel-left` for the settings panel: its head's Hide panel button and the strip a hidden right panel leaves. A frame with its right column ruled off. · new · efficient-easel · card [MERGE] One Media Panel Head For Both Editors, 2026-10-06 — the drawing both editors already carried twice: efficient-storefront components/PanelToggleIcon.tsx and efficient-admin-portal src/components/email/CampaignTopBar.tsx `PanelToggleGlyph`. */
503
+ declare function PanelRightIcon({ size, ...rest }: IconProps): react.JSX.Element;
504
+ /** INSERT A MERGE TAG — a word that fills in for each reader ({{first_name}}, a coupon code). Worn by the Insert button the campaign designer puts in the 9th cell of the final text box's first toolbar row (`CopyBox` `lastTool`), which opens its list of tags. Two curly braces, the shape a merge tag is written in. Decided 2026-10-07. ⛔ NOT `code` or a pair of angle brackets: nothing here is code, and the braces are the tag's own spelling. · new · efficient-easel · card [CHANGE] Undo Button Becomes Clear Style, 2026-10-07 — Lewis's ruling on mockup v2 https://claude.ai/artifact/GiyeV3xazepzArKGVkFM8T, which draws Insert with this path; asked for by GG for the admin card [CHANGE] Email Insert Moves Into The Toolbar (icons come from easel). */
505
+ declare function BracesIcon({ size, ...rest }: IconProps): react.JSX.Element;
494
506
 
495
- export { AccentIcon, AccountIcon, AddIcon, AlignCenterIcon, AlignLeftIcon, AlignRightIcon, AlignSeparateIcon, AnchorIcon, AnimationIcon, BackgroundIcon, BellIcon, BlackAndWhiteIcon, BlockBadgeIcon, BlockBannerIcon, BlockBoxIcon, BlockButtonIcon, BlockColumnIcon, BlockCouponIcon, BlockDividerIcon, BlockFooterIcon, BlockHeadingIcon, BlockIncludedListIcon, BlockLayeredImagesIcon, BlockProductIcon, BlockSectionIcon, BlockSocialIcon, BlockSpacerIcon, BlockTextIcon, BlockVideoIcon, BlogPostIcon, BoldIcon, BreadcrumbIcon, ButtonArrowIcon, ButtonIcon, CarIcon, CartIcon, CaseIcon, CaseLowerIcon, CaseNormalIcon, CaseUpperIcon, CategoryIcon, ChatIcon, CheckIcon, ChevronIcon, ClearMarksIcon, ClockIcon, CloseIcon, ColumnGapIcon, ColumnWidthsIcon, ColumnsIcon, ContrastIcon, CopyIcon, CopyStyleIcon, CopyToPageIcon, CornerIcon, DesktopIcon, DiagramIcon, DirectionDownIcon, DirectionIcon, DirectionLeftIcon, DirectionRightIcon, DirectionUpIcon, DollarIcon, DragIcon, DropIcon, DuplicateIcon, EmphasisIcon, ExternalIcon, EyeIcon, EyeOffIcon, FinishIcon, FullWidthIcon, GapIcon, GlobeIcon, GridIcon, GroundIcon, HashIcon, HeadquartersIcon, HeightIcon, HoverIcon, type IconName, type IconProps, ImageIcon, ItalicIcon, LayersIcon, LayoutIcon, LetterSpacingIcon, LineBetweenIcon, LineStyleIcon, LinkIcon, ListIcon, LocationIcon, LockIcon, LogoIcon, MediaIcon, MenuIcon, MetaIcon, MoveDownIcon, MoveUpIcon, NoteIcon, NudgeIcon, NumberedListIcon, OpacityIcon, OwnTextIcon, PaddingBottomIcon, PaddingLeftIcon, PaddingRightIcon, PaddingTopIcon, PaddingXIcon, PaddingYIcon, PageIcon, ParagraphSpacingIcon, PasteIcon, PasteStyleIcon, PhoneIcon, PlacementIcon, PlayIcon, PlusMinusIcon, ProductFieldIcon, ProductSizeIcon, QuietIcon, RadiusIcon, RedoIcon, RenameIcon, RevertIcon, RotateIcon, ScrollPointIcon, SearchIcon, SendIcon, SettingsIcon, ShadowIcon, SitemapIcon, SortIcon, SpecTableIcon, SquareIcon, StateIcon, StickyIcon, StrikeIcon, StylesIcon, SubscriptIcon, SuperscriptIcon, TabletIcon, TabsIcon, TagIcon, TemplateIcon, TextColorIcon, TextLinesIcon, TextSizeIcon, TextSmallIcon, ThemeIcon, TitleIcon, TrashIcon, TriggerIcon, TypeIcon, UnderlineIcon, UndoIcon, VAlignIcon, WarningIcon, WeightIcon, WheelIcon, WidthIcon, WordsFromIcon, WrapIcon, iconMeanings };
507
+ export { AccentIcon, AccountIcon, AddIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, AlignSeparateIcon, AnchorIcon, AnimationIcon, BackgroundIcon, BellIcon, BlackAndWhiteIcon, BlockBadgeIcon, BlockBannerIcon, BlockBoxIcon, BlockButtonIcon, BlockColumnIcon, BlockCouponIcon, BlockDividerIcon, BlockFooterIcon, BlockHeadingIcon, BlockIncludedListIcon, BlockLayeredImagesIcon, BlockProductIcon, BlockSectionIcon, BlockSocialIcon, BlockSpacerIcon, BlockTextIcon, BlockVideoIcon, BlogPostIcon, BoldIcon, BracesIcon, BreadcrumbIcon, ButtonArrowIcon, ButtonIcon, CarIcon, CartIcon, CaseIcon, CaseLowerIcon, CaseNormalIcon, CaseUpperIcon, CategoryIcon, ChatIcon, CheckIcon, ChevronIcon, ClearMarksIcon, ClockIcon, CloseIcon, ColumnGapIcon, ColumnWidthsIcon, ColumnsIcon, ContrastIcon, CopyIcon, CopyStyleIcon, CopyToPageIcon, CornerIcon, DesktopIcon, DiagramIcon, DirectionDownIcon, DirectionIcon, DirectionLeftIcon, DirectionRightIcon, DirectionUpIcon, DollarIcon, DragIcon, DropIcon, DuplicateIcon, EmphasisIcon, ExternalIcon, EyeIcon, EyeOffIcon, FinishIcon, FullWidthIcon, GapIcon, GlobeIcon, GridIcon, GroundIcon, HashIcon, HeadquartersIcon, HeightIcon, HoverIcon, type IconName, type IconProps, ImageIcon, ItalicIcon, LayersIcon, LayoutIcon, LetterSpacingIcon, LineBetweenIcon, LineStyleIcon, LinkIcon, ListIcon, LocationIcon, LockIcon, LogoIcon, MediaIcon, MenuIcon, MetaIcon, MoveDownIcon, MoveUpIcon, NoteIcon, NudgeIcon, NumberedListIcon, OpacityIcon, OwnTextIcon, PaddingBottomIcon, PaddingLeftIcon, PaddingRightIcon, PaddingTopIcon, PaddingXIcon, PaddingYIcon, PageIcon, PanelLeftIcon, PanelRightIcon, ParagraphSpacingIcon, PasteIcon, PasteStyleIcon, PhoneIcon, PlacementIcon, PlayIcon, PlusMinusIcon, ProductFieldIcon, ProductSizeIcon, QuietIcon, RadiusIcon, RedoIcon, RenameIcon, RevertIcon, RotateIcon, ScrollPointIcon, SearchIcon, SendIcon, SettingsIcon, ShadowIcon, SitemapIcon, SortIcon, SpecTableIcon, SquareIcon, StateIcon, StickyIcon, StrikeIcon, StylesIcon, SubscriptIcon, SuperscriptIcon, TabletIcon, TabsIcon, TagIcon, TemplateIcon, TextColorIcon, TextLinesIcon, TextSizeIcon, TextSmallIcon, ThemeIcon, TitleIcon, TrashIcon, TriggerIcon, TypeIcon, UnderlineIcon, UndoIcon, VAlignIcon, WarningIcon, WeightIcon, WheelIcon, WidthIcon, WordsFromIcon, WrapIcon, iconMeanings };
@@ -1 +1 @@
1
- export{AccentIcon,AccountIcon,AddIcon,AlignCenterIcon,AlignLeftIcon,AlignRightIcon,AlignSeparateIcon,AnchorIcon,AnimationIcon,BackgroundIcon,BellIcon,BlackAndWhiteIcon,BlockBadgeIcon,BlockBannerIcon,BlockBoxIcon,BlockButtonIcon,BlockColumnIcon,BlockCouponIcon,BlockDividerIcon,BlockFooterIcon,BlockHeadingIcon,BlockIncludedListIcon,BlockLayeredImagesIcon,BlockProductIcon,BlockSectionIcon,BlockSocialIcon,BlockSpacerIcon,BlockTextIcon,BlockVideoIcon,BlogPostIcon,BoldIcon,BreadcrumbIcon,ButtonArrowIcon,ButtonIcon,CarIcon,CartIcon,CaseIcon,CaseLowerIcon,CaseNormalIcon,CaseUpperIcon,CategoryIcon,ChatIcon,CheckIcon,ChevronIcon,ClearMarksIcon,ClockIcon,CloseIcon,ColumnGapIcon,ColumnWidthsIcon,ColumnsIcon,ContrastIcon,CopyIcon,CopyStyleIcon,CopyToPageIcon,CornerIcon,DesktopIcon,DiagramIcon,DirectionDownIcon,DirectionIcon,DirectionLeftIcon,DirectionRightIcon,DirectionUpIcon,DollarIcon,DragIcon,DropIcon,DuplicateIcon,EmphasisIcon,ExternalIcon,EyeIcon,EyeOffIcon,FinishIcon,FullWidthIcon,GapIcon,GlobeIcon,GridIcon,GroundIcon,HashIcon,HeadquartersIcon,HeightIcon,HoverIcon,ImageIcon,ItalicIcon,LayersIcon,LayoutIcon,LetterSpacingIcon,LineBetweenIcon,LineStyleIcon,LinkIcon,ListIcon,LocationIcon,LockIcon,LogoIcon,MediaIcon,MenuIcon,MetaIcon,MoveDownIcon,MoveUpIcon,NoteIcon,NudgeIcon,NumberedListIcon,OpacityIcon,OwnTextIcon,PaddingBottomIcon,PaddingLeftIcon,PaddingRightIcon,PaddingTopIcon,PaddingXIcon,PaddingYIcon,PageIcon,ParagraphSpacingIcon,PasteIcon,PasteStyleIcon,PhoneIcon,PlacementIcon,PlayIcon,PlusMinusIcon,ProductFieldIcon,ProductSizeIcon,QuietIcon,RadiusIcon,RedoIcon,RenameIcon,RevertIcon,RotateIcon,ScrollPointIcon,SearchIcon,SendIcon,SettingsIcon,ShadowIcon,SitemapIcon,SortIcon,SpecTableIcon,SquareIcon,StateIcon,StickyIcon,StrikeIcon,StylesIcon,SubscriptIcon,SuperscriptIcon,TabletIcon,TabsIcon,TagIcon,TemplateIcon,TextColorIcon,TextLinesIcon,TextSizeIcon,TextSmallIcon,ThemeIcon,TitleIcon,TrashIcon,TriggerIcon,TypeIcon,UnderlineIcon,UndoIcon,VAlignIcon,WarningIcon,WeightIcon,WheelIcon,WidthIcon,WordsFromIcon,WrapIcon,iconMeanings}from"../chunk-PI26YXYD.js";
1
+ export{AccentIcon,AccountIcon,AddIcon,AlignCenterIcon,AlignJustifyIcon,AlignLeftIcon,AlignRightIcon,AlignSeparateIcon,AnchorIcon,AnimationIcon,BackgroundIcon,BellIcon,BlackAndWhiteIcon,BlockBadgeIcon,BlockBannerIcon,BlockBoxIcon,BlockButtonIcon,BlockColumnIcon,BlockCouponIcon,BlockDividerIcon,BlockFooterIcon,BlockHeadingIcon,BlockIncludedListIcon,BlockLayeredImagesIcon,BlockProductIcon,BlockSectionIcon,BlockSocialIcon,BlockSpacerIcon,BlockTextIcon,BlockVideoIcon,BlogPostIcon,BoldIcon,BracesIcon,BreadcrumbIcon,ButtonArrowIcon,ButtonIcon,CarIcon,CartIcon,CaseIcon,CaseLowerIcon,CaseNormalIcon,CaseUpperIcon,CategoryIcon,ChatIcon,CheckIcon,ChevronIcon,ClearMarksIcon,ClockIcon,CloseIcon,ColumnGapIcon,ColumnWidthsIcon,ColumnsIcon,ContrastIcon,CopyIcon,CopyStyleIcon,CopyToPageIcon,CornerIcon,DesktopIcon,DiagramIcon,DirectionDownIcon,DirectionIcon,DirectionLeftIcon,DirectionRightIcon,DirectionUpIcon,DollarIcon,DragIcon,DropIcon,DuplicateIcon,EmphasisIcon,ExternalIcon,EyeIcon,EyeOffIcon,FinishIcon,FullWidthIcon,GapIcon,GlobeIcon,GridIcon,GroundIcon,HashIcon,HeadquartersIcon,HeightIcon,HoverIcon,ImageIcon,ItalicIcon,LayersIcon,LayoutIcon,LetterSpacingIcon,LineBetweenIcon,LineStyleIcon,LinkIcon,ListIcon,LocationIcon,LockIcon,LogoIcon,MediaIcon,MenuIcon,MetaIcon,MoveDownIcon,MoveUpIcon,NoteIcon,NudgeIcon,NumberedListIcon,OpacityIcon,OwnTextIcon,PaddingBottomIcon,PaddingLeftIcon,PaddingRightIcon,PaddingTopIcon,PaddingXIcon,PaddingYIcon,PageIcon,PanelLeftIcon,PanelRightIcon,ParagraphSpacingIcon,PasteIcon,PasteStyleIcon,PhoneIcon,PlacementIcon,PlayIcon,PlusMinusIcon,ProductFieldIcon,ProductSizeIcon,QuietIcon,RadiusIcon,RedoIcon,RenameIcon,RevertIcon,RotateIcon,ScrollPointIcon,SearchIcon,SendIcon,SettingsIcon,ShadowIcon,SitemapIcon,SortIcon,SpecTableIcon,SquareIcon,StateIcon,StickyIcon,StrikeIcon,StylesIcon,SubscriptIcon,SuperscriptIcon,TabletIcon,TabsIcon,TagIcon,TemplateIcon,TextColorIcon,TextLinesIcon,TextSizeIcon,TextSmallIcon,ThemeIcon,TitleIcon,TrashIcon,TriggerIcon,TypeIcon,UnderlineIcon,UndoIcon,VAlignIcon,WarningIcon,WeightIcon,WheelIcon,WidthIcon,WordsFromIcon,WrapIcon,iconMeanings}from"../chunk-L5KW4HG5.js";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { EaselRail, EaselRailButton, EditorRail, EditorRailButton, RailTokens, railCssVars, railTokens } from './rail/index.js';
1
+ export { EaselRail, EaselRailButton, RailTokens, railCssVars, railTokens } from './rail/index.js';
2
2
  export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, IconProps as RailIconProps, SitemapIcon, StylesIcon } from './icons/index.js';
3
3
  export { W as WordFit } from './wordFit-D4S36PvB.js';
4
- export { E as EaselRailButtonProps, a as EaselRailItem, b as EaselRailOrientation, c as EaselRailProps, d as EditorRailButtonProps, e as EditorRailItem, f as EditorRailOrientation, g as EditorRailProps } from './types-Bs_gVkVI.js';
4
+ export { E as EaselRailButtonProps, a as EaselRailItem, b as EaselRailOrientation, c as EaselRailProps } from './types-DWS-s9z-.js';
5
5
  export { SPACING_SCALE, ShellTokens, shellCssVars, shellTokens } from './shell/index.js';
6
6
  import 'react';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"./chunk-2PHD4L6A.js";export{SPACING_SCALE,shellCssVars,shellTokens}from"./chunk-2UX75JDP.js";export{EaselRail,EaselRailButton,EditorRail,EditorRailButton,railCssVars,railTokens}from"./chunk-XUE5O62R.js";import"./chunk-2OAZYSWJ.js";import"./chunk-BZ5ASXOL.js";export{AddIcon,LayersIcon,MediaIcon,PageIcon as PagesIcon,SitemapIcon,StylesIcon}from"./chunk-PI26YXYD.js";
1
+ import"./chunk-OWBO4WKA.js";export{SPACING_SCALE,shellCssVars,shellTokens}from"./chunk-2UX75JDP.js";export{EaselRail,EaselRailButton,railCssVars,railTokens}from"./chunk-WZ7TGAAT.js";import"./chunk-2OAZYSWJ.js";import"./chunk-BZ5ASXOL.js";export{AddIcon,LayersIcon,MediaIcon,PageIcon as PagesIcon,SitemapIcon,StylesIcon}from"./chunk-L5KW4HG5.js";
@@ -50,11 +50,12 @@
50
50
  * [words]{sup} superscript
51
51
  * [words]{sub} subscript
52
52
  * [words]{color=name} a theme colour, by NAME ({@link isColorName})
53
+ * [words]{color=#rrggbb} any colour, six hex digits ({@link isColorValue})
53
54
  *
54
55
  * THE SPANS AND THE NUMBERED LINE (plan step E1, approved by GG 2026-10-06)
55
56
  * are the final text box's marks. One shape for all four, so one reading rule:
56
57
  * `[`, words, `]`, then EXACTLY one of those blocks. Anything else after the
57
- * `]` — `{foo}`, `{color=#ff0000}`, a merge tag's `{{` — is not a span, and the
58
+ * `]` — `{foo}`, `{color=#f00}`, a merge tag's `{{` — is not a span, and the
58
59
  * whole thing stays as typed. Two marks on the same words nest
59
60
  * (`[[x]{sup}]{color=accent}`); one block never holds two.
60
61
  *
@@ -132,9 +133,18 @@ type SpanKind = 'underline' | 'sup' | 'sub' | 'color';
132
133
  * from one to the other invisible. */
133
134
  type InlineKind = 'text' | 'bold' | 'italic' | 'strike' | 'code' | 'highlight' | 'accent' | 'quiet';
134
135
  /** A theme colour's name as a span saves it: lowercase letters, digits and
135
- * `-`, starting with a letter (`accent`, `brand-2`). Never a hex: a colour is
136
- * the theme's, so changing the theme recolours the words. */
136
+ * `-`, starting with a letter (`accent`, `brand-2`). A name is the theme's,
137
+ * so changing the theme recolours the words. Never a hex — that is the other
138
+ * kind of colour value ({@link isColorValue}). */
137
139
  declare function isColorName(name: string): boolean;
140
+ /** A colour a span may carry: a theme NAME ({@link isColorName}), or "any
141
+ * colour" as EXACTLY six hex digits after a `#` (`#0b5cff`). Either case
142
+ * reads; the writers save lowercase ({@link colorValue}). Nothing else —
143
+ * `#f00`, `rgb()`, a typo — is a colour, so it stays plain text.
144
+ *
145
+ * WIDENS E1 (GG 2026-10-06): the final design draws "Any color", and a
146
+ * feature is never cut to fit. A hex does not follow the theme; a name does. */
147
+ declare function isColorValue(value: string): boolean;
138
148
  /**
139
149
  * The words a press WRITES when nothing is selected — `**bold text**`, left
140
150
  * selected so the next keystroke replaces it. English unless the caller of
@@ -160,11 +170,12 @@ interface WrapResult {
160
170
  */
161
171
  declare function applyMark(text: string, start: number, end: number, style: MarkStyle, rules?: readonly InlineRule[], placeholders?: MarkPlaceholders): WrapResult;
162
172
  /**
163
- * Colour `text[start:end]` with the theme colour `name`, writing
173
+ * Colour `text[start:end]` with `name` — a theme colour name or a 6-digit hex
174
+ * ({@link isColorValue}; a hex is saved lowercase) — writing
164
175
  * `[words]{color=name}` and leaving the words selected. On words that are
165
- * already exactly one colour span it changes the name; `null` takes the colour
166
- * off. A name {@link isColorName} refuses changes nothing — a hex or a typo is
167
- * never saved as a block the reader would print as text.
176
+ * already exactly one colour span it changes the colour; `null` takes it
177
+ * off. A value {@link isColorValue} refuses changes nothing — `#f00` or a typo
178
+ * is never saved as a block the reader would print as text.
168
179
  *
169
180
  * Separate from {@link applyMark} because a colour carries a value, as a link
170
181
  * does ({@link writeLink}).
@@ -298,6 +309,14 @@ interface InlineRule {
298
309
  * what actually does the work.
299
310
  */
300
311
  declare const STANDARD_MARKUP: readonly InlineRule[];
312
+ /**
313
+ * Marks the copy box no longer OFFERS (E5a, 2026-10-06: Lewis dropped
314
+ * Emphasis `==` and Quiet `^^` from the final design). They are still read,
315
+ * drawn and written back byte for byte — saved copy wears them — but no bar
316
+ * button writes them, and `CopyBox` draws none for them even when a host asks.
317
+ * Declared before {@link COPY_FIELD_TOOLS} reads it at module load.
318
+ */
319
+ declare const RETIRED_MARKS: readonly MarkStyle[];
301
320
  /**
302
321
  * The buttons a COPY FIELD offers — a storefront section's copy box and a
303
322
  * campaign block's copy box show exactly these, so a merchant meets one toolbar
@@ -458,8 +477,8 @@ interface MarkSpan {
458
477
  }
459
478
  /**
460
479
  * A NEW run, as the toolbar writes it: `**` for bold, `_` for italic, and so on
461
- * ({@link applyMark}'s own fences), a link to `value`, or a colour span named
462
- * `value` ({@link isColorName}). Null for a style that writes no run (a line
480
+ * ({@link applyMark}'s own fences), a link to `value`, or a colour span of
481
+ * `value` — a theme name or a 6-digit hex, saved lowercase ({@link isColorValue}). Null for a style that writes no run (a line
463
482
  * prefix, clear) and for a link or colour with no usable value. A paste filter
464
483
  * or an editor making a run asks here, so no delimiter is spelled outside this
465
484
  * module (E8).
@@ -524,5 +543,87 @@ declare function sameMarks(a: readonly MarkedLine[], b: readonly MarkedLine[]):
524
543
  * literal underscore. And if even that would not read back, nothing changes.
525
544
  */
526
545
  declare function clearMarks(text: string, start: number, end: number, rules?: readonly InlineRule[]): WrapResult;
546
+ /**
547
+ * The final toolbar's Clear style (owner ruling, 2026-10-07): take EVERY mark
548
+ * off the WORDS in `text[start:end]` but a link, keeping the words selected —
549
+ * the bar's (bold, italic, underline, strikethrough, colour, superscript,
550
+ * subscript) and the retired ones it no longer offers (Emphasis, Quiet, the
551
+ * legacy accent), so the words come back plain (GG, 2026-10-07). A link is
552
+ * content, not style; a line's bullet or number is a line, not a mark.
553
+ *
554
+ * A run the selection only partly covers is split, so the rest of it keeps
555
+ * its mark; a split the grammar cannot hold (the middle of `_word_`) takes the
556
+ * run off whole; and if even that would not read back, nothing changes.
557
+ *
558
+ * With nothing selected nothing changes: the button is disabled then, so a
559
+ * press can never wipe a whole paragraph. Unlike {@link clearMarks} (the 0.94
560
+ * bar's Clear marks), which with a caret takes off the runs it touches.
561
+ */
562
+ declare function clearStyle(text: string, start: number, end: number, rules?: readonly InlineRule[]): WrapResult;
563
+ /**
564
+ * Press `style` on the WORDS in `text[start:end]`, whichever runs they sit in —
565
+ * what a view that hides the delimiters needs, where `applyMark` (which wraps
566
+ * exactly the characters selected) would cross or strand a delimiter.
567
+ *
568
+ * - Every selected word already wears the mark: it comes off them. Part of a
569
+ * run is split off; the rest keeps the mark.
570
+ * - Otherwise the mark goes on, as ONE run over the words and any run of the
571
+ * same mark they touch (`**half** off` → `**half off**`).
572
+ * - Nothing is written that would not read back: a third level of nesting,
573
+ * or `_` inside a word, leaves the text as it was.
574
+ * - With nothing selected it is {@link applyMark}: a selected placeholder.
575
+ *
576
+ * Offsets are the saved string's, before and after.
577
+ */
578
+ declare function toggleMark(text: string, start: number, end: number, style: MarkStyle, rules?: readonly InlineRule[]): WrapResult;
579
+ /**
580
+ * The marks every word in `text[start:end]` wears — `bold`, `link`, a legacy
581
+ * `accent` … — or, with nothing selected, the marks of the word just before the
582
+ * caret on its line: what typing there would continue. What a toolbar draws
583
+ * as pressed in a view without delimiters.
584
+ */
585
+ declare function marksIn(text: string, start: number, end: number, rules?: readonly InlineRule[]): Set<string>;
586
+ /**
587
+ * Link the WORDS in `text[start:end]` to `href`, nesting with any run they
588
+ * sit in rather than crossing it: words inside a bold run become a link inside
589
+ * it (`**Book [a fitting](/book)**`), a whole bold run goes inside the link.
590
+ *
591
+ * With nothing selected, inside a link it re-points that link; anywhere else
592
+ * it writes the address as its own words ({@link writeLink}). The caret lands
593
+ * after the link. ⚠️ The address is the caller's to check ({@link isSafeLinkHref}).
594
+ */
595
+ declare function linkOver(text: string, start: number, end: number, href: string, rules?: readonly InlineRule[]): WrapResult;
596
+ /** Take off the link the caret or selection touches, keeping its words —
597
+ * selected, so a second press of the link button puts it straight back. */
598
+ declare function unlinkAt(text: string, start: number, end: number, rules?: readonly InlineRule[]): WrapResult;
599
+ /**
600
+ * Colour the WORDS in `text[start:end]` with `name` — a theme colour name or
601
+ * a 6-digit hex, saved lowercase (`[words]{color=name}`), nesting with any run they sit in rather than
602
+ * crossing it — the colour window's write, as {@link linkOver} is the link
603
+ * window's. A colour the words already wear is replaced; `null` takes the
604
+ * colour off them, splitting a run that only partly covers them.
605
+ *
606
+ * A value {@link isColorValue} refuses (`#f00`, a word with a space) changes
607
+ * nothing: a block the reader would print as text is never written. With
608
+ * nothing selected nothing changes either — the box keeps a pending colour
609
+ * for the words typed next instead.
610
+ */
611
+ declare function colorOver(text: string, start: number, end: number, name: string | null, rules?: readonly InlineRule[]): WrapResult;
612
+ /** The ONE colour every word in `text[start:end]` wears — or, with nothing
613
+ * selected, the word before the caret on its line — or null. What the colour
614
+ * window draws as chosen, and the colour under the A. */
615
+ declare function colorIn(text: string, start: number, end: number, rules?: readonly InlineRule[]): string | null;
616
+ /**
617
+ * Make every line `text[start:end]` touches (the caret's line, with nothing
618
+ * selected) a bulleted list, a numbered list, or — `null` — no list. The
619
+ * words and their marks keep their bytes; only the line prefixes change. A
620
+ * numbered list counts on from a numbered line just above it, else from 1.
621
+ * An empty line becomes an empty list line (`- `), which the rich view draws
622
+ * as a bullet with nothing after it yet. The selection keeps its words.
623
+ */
624
+ declare function setList(text: string, start: number, end: number, kind: 'bullet' | 'number' | null, rules?: readonly InlineRule[]): WrapResult;
625
+ /** `bullet` or `number` when every line `text[start:end]` touches is that
626
+ * kind of list line, else null — what the list buttons draw as pressed. */
627
+ declare function listIn(text: string, start: number, end: number, rules?: readonly InlineRule[]): 'bullet' | 'number' | null;
527
628
 
528
- export { CAMPAIGN_MARKUP, COPY_FIELD_TOOLS, type InlineKind, type InlineRule, type InlineToken, type LinkSpan, MARKUP_TOOLS, MARK_NAMES, MARK_PLACEHOLDERS, type MarkPlaceholders, type MarkSpan, type MarkStyle, type MarkedChar, type MarkedLine, type MarkupLine, type MarkupLink, type MarkupNode, type MarkupRun, type MarkupText, type MarkupTool, STANDARD_MARKUP, STOREFRONT_MARKUP, type SpanKind, type WrapResult, applyColor, applyMark, clearMarks, findLink, isColorName, isSafeLinkHref, markedAt, markedLines, markupTools, parseMarkup, removeLink, sameMarks, serializeMarkup, spanFor, stripInline, tokenizeInline, writeLink, writeMarkedLines };
629
+ export { CAMPAIGN_MARKUP, COPY_FIELD_TOOLS, type InlineKind, type InlineRule, type InlineToken, type LinkSpan, MARKUP_TOOLS, MARK_NAMES, MARK_PLACEHOLDERS, type MarkPlaceholders, type MarkSpan, type MarkStyle, type MarkedChar, type MarkedLine, type MarkupLine, type MarkupLink, type MarkupNode, type MarkupRun, type MarkupText, type MarkupTool, RETIRED_MARKS, STANDARD_MARKUP, STOREFRONT_MARKUP, type SpanKind, type WrapResult, applyColor, applyMark, clearMarks, clearStyle, colorIn, colorOver, findLink, isColorName, isColorValue, isSafeLinkHref, linkOver, listIn, markedAt, markedLines, marksIn, markupTools, parseMarkup, removeLink, sameMarks, serializeMarkup, setList, spanFor, stripInline, toggleMark, tokenizeInline, unlinkAt, writeLink, writeMarkedLines };
@@ -1 +1 @@
1
- export{CAMPAIGN_MARKUP,COPY_FIELD_TOOLS,MARKUP_TOOLS,MARK_NAMES,MARK_PLACEHOLDERS,STANDARD_MARKUP,STOREFRONT_MARKUP,applyColor,applyMark,clearMarks,findLink,isColorName,isSafeLinkHref,markedAt,markedLines,markupTools,parseMarkup,removeLink,sameMarks,serializeMarkup,spanFor,stripInline,tokenizeInline,writeLink,writeMarkedLines}from"../chunk-SJQG5ENJ.js";
1
+ export{CAMPAIGN_MARKUP,COPY_FIELD_TOOLS,MARKUP_TOOLS,MARK_NAMES,MARK_PLACEHOLDERS,RETIRED_MARKS,STANDARD_MARKUP,STOREFRONT_MARKUP,applyColor,applyMark,clearMarks,clearStyle,colorIn,colorOver,findLink,isColorName,isColorValue,isSafeLinkHref,linkOver,listIn,markedAt,markedLines,marksIn,markupTools,parseMarkup,removeLink,sameMarks,serializeMarkup,setList,spanFor,stripInline,toggleMark,tokenizeInline,unlinkAt,writeLink,writeMarkedLines}from"../chunk-546BBOPE.js";
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { a as EaselContextMenuProps, b as EaselContextMenuSkin } from '../types-DO-b0LNj.js';
3
- export { E as EaselContextMenuItem, c as EditorContextMenuItem, d as EditorContextMenuProps, e as EditorContextMenuSkin } from '../types-DO-b0LNj.js';
2
+ import { a as EaselContextMenuProps, b as EaselContextMenuSkin } from '../types-Djdq6Xkd.js';
3
+ export { E as EaselContextMenuItem } from '../types-Djdq6Xkd.js';
4
4
 
5
5
  /**
6
6
  * The right-click menu box, shared by both editors (card 66400.d).
@@ -29,8 +29,61 @@ export { E as EaselContextMenuItem, c as EditorContextMenuItem, d as EditorConte
29
29
  * client boundary.
30
30
  */
31
31
  declare function EaselContextMenu({ x, y, items, onClose, maxHeight, skin, portalTo, }: EaselContextMenuProps): react.ReactPortal | null;
32
- /** @deprecated The name before the Easel rename: `EaselContextMenu`. */
33
- declare const EditorContextMenu: typeof EaselContextMenu;
32
+
33
+ /**
34
+ * WHERE THE MENU BOX LIVES — the decision, and the one check behind it
35
+ * (second host, 2026-10-07).
36
+ *
37
+ * The box is portalled to `<body>`. A host's axe-core run flags that under
38
+ * `region` (a best-practice rule, moderate): a `role="menu"` hanging off the
39
+ * body is page content outside every landmark. Two answers were on the table.
40
+ *
41
+ * A. Wrap the box in something a landmark check lets through — a
42
+ * `role="region"`, a `role="dialog"`. REFUSED.
43
+ * A menu is neither. A region is a landmark, and one that appears in the
44
+ * page's landmark list each time a menu opens is noise for the very
45
+ * people landmarks are for; a dialog is announced as one and is expected
46
+ * to hold the focus like one. Changing what a thing IS so a checker
47
+ * stops reading it is the wrong way round.
48
+ *
49
+ * B. Portal the box INTO the editor's root, which sits inside whatever
50
+ * landmark the host put its editor in. TAKEN,
51
+ * as the host's choice (`portalTo`), with this check.
52
+ *
53
+ * WHY IT IS NOT THE DEFAULT. The box is `position: fixed` and placed at the
54
+ * pointer in the VIEWPORT's coordinates. An ancestor that is transformed,
55
+ * filtered or contained becomes the containing block of a fixed box inside it:
56
+ * the box is then placed against that ancestor and clipped by it — the menu
57
+ * opens somewhere the pointer is not, or is cut off. `<body>` is the one place
58
+ * that can never happen, the box does not know where a host's root is, and
59
+ * every surface that draws it today ships on the body. So the body stays the
60
+ * default, and a host that wants the box in its landmarks says where:
61
+ *
62
+ * <EaselContextMenu portalTo={menuPortalTarget(rootRef.current)} … />
63
+ *
64
+ * `menuPortalTarget` hands the root back only when a fixed box in it is still
65
+ * placed against the viewport, and `null` — the body — otherwise. So a root
66
+ * that is scaled on one screen and not on another gets the right answer on
67
+ * both, with no rule of the host's own.
68
+ *
69
+ * Two things the host still owns: the root's stacking (the box is `z-index:
70
+ * 9999` INSIDE the root's stacking context, so an overlay the host draws above
71
+ * its editor is above the menu too), and its tokens (the default skin names
72
+ * `es-editor` on the box, which re-declares the token defaults there — a
73
+ * re-themed root passes a skin without it; see `ES_MENU_SKIN`).
74
+ *
75
+ * Pure DOM, no React, nothing read at import.
76
+ */
77
+ /**
78
+ * The element to hand `EaselContextMenu` as `portalTo` so the box lives inside
79
+ * the editor: `root` itself when a fixed box in it is still placed against the
80
+ * viewport, `null` (the body, the default) when the root or anything around it
81
+ * would place and clip the box instead — or when there is no root yet.
82
+ *
83
+ * Call it when the menu opens, not once: whether a root is transformed can
84
+ * change with the screen (a host that scales its editor to fit).
85
+ */
86
+ declare function menuPortalTarget(root: Element | null | undefined): HTMLElement | null;
34
87
 
35
88
  /**
36
89
  * The default skin — the storefront editor's approved look, in classes that
@@ -48,4 +101,4 @@ declare const EditorContextMenu: typeof EaselContextMenu;
48
101
  */
49
102
  declare const ES_MENU_SKIN: EaselContextMenuSkin;
50
103
 
51
- export { ES_MENU_SKIN, EaselContextMenu, EaselContextMenuProps, EaselContextMenuSkin, EditorContextMenu };
104
+ export { ES_MENU_SKIN, EaselContextMenu, EaselContextMenuProps, EaselContextMenuSkin, menuPortalTarget };
@@ -1,15 +1 @@
1
- import{useRef as e,useState as n,useLayoutEffect as t,useEffect as l}from"react";import{createPortal as r}from"react-dom";import{jsxs as i,Fragment as a,jsx as o}from"react/jsx-runtime";var c={menu:"es-editor es-menu",menuSub:"es-editor es-menu",item:"es-menu-item",itemDanger:"es-menu-item is-danger",divider:"es-menu-divider",header:"es-menu-header",icon:"es-menu-icon",shortcut:"es-menu-shortcut",label:"es-menu-label",labelSub:"es-menu-label es-menu-label-sub",chevron:"es-menu-chevron",tick:"es-menu-tick"};function u({x:u,y:s,items:d,onClose:m,maxHeight:h,skin:b,portalTo:y}){const p=e(null),g=e(null),[f,v]=n(null),[w,x]=n({x:u,y:s}),[N,k]=n({x:u,y:s});if(N.x===u&&N.y===s||(k({x:u,y:s}),x({x:u,y:s})),t(()=>{const e=p.current;if(!e)return;const{width:n,height:t}=e.getBoundingClientRect(),l=window.innerWidth,r=window.innerHeight;let i=s;s+t>r-8&&(i=s-t>=8?s-t:Math.max(8,r-t-8));let a=u;u+n>l-8&&(a=u-n>=8?u-n:Math.max(8,l-n-8)),a===w.x&&i===w.y||x({x:a,y:i})},[u,s,d,w.x,w.y]),l(()=>{const e=document.activeElement;return p.current?.querySelector('[role="menuitem"]')?.focus(),()=>e?.focus?.()},[]),l(()=>{const e=e=>{const n=e.target;g.current?.contains(n)||p.current&&!p.current.contains(n)&&m()},n=e=>{"Escape"===e.key&&m()},t=setTimeout(()=>{window.addEventListener("mousedown",e),window.addEventListener("contextmenu",e),window.addEventListener("keydown",n)},0);return()=>{clearTimeout(t),window.removeEventListener("mousedown",e),window.removeEventListener("contextmenu",e),window.removeEventListener("keydown",n)}},[m]),0===d.length)return null;const C=b??c,E=e=>e.danger?C.itemDanger:C.item,S=({on:e})=>/* @__PURE__ */o("span",{className:C.tick,"aria-hidden":"true",children:e?"✓":""}),L=({of:e})=>null==e.icon?null:/* @__PURE__ */o("span",{className:C.icon,"aria-hidden":"true",children:e.icon}),T=({of:e})=>null==e.shortcut?null:/* @__PURE__ */o("span",{className:C.shortcut,"aria-hidden":"true",children:e.shortcut}),B=e=>null!=e.icon||null!=e.shortcut,M=(e,n,t)=>{if(!e.children?.length)return void v(null);const l=t.getBoundingClientRect(),r=p.current,i=r?parseFloat(getComputedStyle(r).minWidth):NaN,a=Number.isFinite(i)&&i>0?i:r?.getBoundingClientRect().width??0,o=l.right+a>window.innerWidth-8?l.left-a:l.right;v({i:n,x:Math.max(8,o),y:l.top})},F=f?d[f.i]:null,H=e=>({...C.surface,...e});return r(
2
- /* @__PURE__ */i(a,{children:[
3
- /* @__PURE__ */o("div",{ref:p,"data-es-menu":"",role:"menu","aria-label":d.find(e=>e.header)?.label,className:C.menu,style:H({left:w.x,top:w.y,maxHeight:h||void 0}),children:d.map((e,n)=>"—"===e.label?
4
- /* @__PURE__ */o("div",{role:"separator",className:C.divider},n):e.header?/* @__PURE__ */o("div",{className:C.header,children:e.label},n):e.children?.length?/* @__PURE__ */i("button",{type:"button",role:"menuitem","aria-haspopup":"menu","aria-expanded":f?.i===n,onMouseEnter:t=>M(e,n,t.currentTarget),onFocus:t=>M(e,n,t.currentTarget),onClick:t=>M(e,n,t.currentTarget),className:E(e),style:C.itemStyle,children:[
5
- /* @__PURE__ */o(L,{of:e}),
6
- /* @__PURE__ */o("span",{className:C.label,children:e.label}),
7
- /* @__PURE__ */o(T,{of:e}),
8
- /* @__PURE__ */o("span",{"aria-hidden":"true",className:C.chevron,children:"›"})]},n):/* @__PURE__ */o("button",{type:"button",role:"menuitem",onMouseEnter:()=>v(null),onClick:()=>{e.onClick(),m()},className:E(e),style:C.itemStyle,children:B(e)?/* @__PURE__ */i(a,{children:[
9
- /* @__PURE__ */o(L,{of:e}),
10
- /* @__PURE__ */o("span",{className:C.label,children:e.label}),
11
- /* @__PURE__ */o(T,{of:e})]}):e.label},n))}),F?.children?.length&&f?/* @__PURE__ */o("div",{ref:g,"data-es-menu":"",role:"menu","aria-label":F.label,className:C.menuSub??C.menu,style:H({left:f.x,top:f.y}),children:F.children.map((e,n)=>/* @__PURE__ */i("button",{type:"button",role:"menuitemradio","aria-checked":Boolean(e.checked),onClick:()=>{e.onClick(),m()},className:E(e),style:C.itemStyle,children:[
12
- /* @__PURE__ */o(S,{on:Boolean(e.checked)}),
13
- /* @__PURE__ */o(L,{of:e}),
14
- /* @__PURE__ */o("span",{className:C.labelSub??C.label,children:e.label}),
15
- /* @__PURE__ */o(T,{of:e})]},n))}):null]}),y??document.body)}var s=u;export{c as ES_MENU_SKIN,u as EaselContextMenu,s as EditorContextMenu};
1
+ export{ES_MENU_SKIN,EaselContextMenu}from"../chunk-KTVH2ZRL.js";var e=/\b(transform|translate|rotate|scale|perspective|filter|backdrop-filter|contain)\b/;function t(t){const n=e=>t.getPropertyValue(e).trim(),r=(e,t)=>{const r=n(e);return""!==r&&!t.includes(r)};return!!r("transform",["none"])||(!!(r("translate",["none"])||r("rotate",["none"])||r("scale",["none"]))||(!!r("perspective",["none"])||(!!r("filter",["none"])||(!(!r("backdrop-filter",["none"])&&!r("-webkit-backdrop-filter",["none"]))||(!!/\b(layout|paint|strict|content)\b/.test(n("contain"))||(!!r("container-type",["normal"])||(!!r("content-visibility",["visible"])||e.test(n("will-change")))))))))}function n(e){const n=e?.ownerDocument,r=n?.defaultView;if(!(e&&n&&r&&e.isConnected))return null;for(let o=e;o&&o!==n.body&&o!==n.documentElement;o=o.parentElement)if(t(r.getComputedStyle(o)))return null;return e}export{n as menuPortalTarget};
@@ -115,12 +115,16 @@
115
115
  than copied as a literal. */
116
116
  --es-menu-danger-fg: var(--es-danger-strong);
117
117
 
118
- /* THE SHORTCUT COLUMN'S INK — quieter than a label, quieter than `--es-muted`,
119
- because a shortcut is a reminder and never the thing being read.
120
- ⚠️ The one value here with no shell token behind it: the drawing's own
121
- `#b6bcc4`, which is lighter than `--es-disabled` (#9ca3af). Named here
122
- rather than reaching for a token that is not this colour. */
123
- --es-menu-shortcut-fg: #b6bcc4;
118
+ /* THE SHORTCUT COLUMN'S INK — quieter than a label, because a shortcut is a
119
+ reminder and never the thing being read; but it IS read, so it is a grey
120
+ that can be: `--es-muted`, 4.8:1 on the box at 11px.
121
+ ⚠️ It was the drawing's own `#b6bcc4` until 2026-10-07 — lighter than
122
+ `--es-disabled`, 1.9:1 on white, the lowest contrast of any text in the
123
+ package. A second host's axe-core run failed it (WCAG AA, 4.5:1) and the
124
+ host put `--es-muted` here itself; this is that, at the source. Still
125
+ behind ONE var, so the design can pick another grey that can be read.
126
+ Held by ratio in tests/contrast-small-text.test.ts. */
127
+ --es-menu-shortcut-fg: var(--es-muted);
124
128
  }
125
129
 
126
130
 
@@ -225,6 +229,13 @@
225
229
  color: var(--es-menu-shortcut-fg);
226
230
  font-size: 11px;
227
231
  }
232
+ /* On the row that is pointed at the ground is tinted, and the grey that passes
233
+ on white does not pass on the tint (4.4:1). So the shortcut takes the ROW's
234
+ ink there — the accent on a plain row (4.7:1), the red on one that destroys
235
+ (5.9:1): one ink per row, and no new colour. */
236
+ .es-menu-item:hover .es-menu-shortcut {
237
+ color: inherit;
238
+ }
228
239
 
229
240
  /* Present on every row of a flyout that uses one, so the labels line up whether
230
241
  or not the row is the state you are already on. */
@@ -1,7 +1,7 @@
1
1
  export { A as AfterRemove, I as ItemSelector, N as NodeSelection, P as Planned, S as StepBounds, c as canStep, f as fromItemSelector, p as parentStep, a as planDuplicate, b as planMove, d as planPaste, e as planRemove, g as planSetProps, h as planStep, t as toItemSelector } from '../plan-DChbUXdS.js';
2
2
  export { C as ClipboardEntry, N as NodeClipboard, a as NodeOps, b as NodeOpsHost, c as createNodeClipboard, u as useNodeOps } from '../useNodeOps-BF0fQsif.js';
3
3
  import { ReactNode } from 'react';
4
- import { E as EaselContextMenuItem } from '../types-DO-b0LNj.js';
4
+ import { E as EaselContextMenuItem } from '../types-Djdq6Xkd.js';
5
5
  import { N as NodeMenuWords } from '../words-DMG4dYq2.js';
6
6
  import '../types-41704JE4.js';
7
7