efficient-easel 0.106.0 → 1.0.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 (168) hide show
  1. package/README.md +70 -29
  2. package/dist/{LinkPicker-W2Rtxetz.d.ts → LinkPicker-hPEr1MJx.d.ts} +6 -4
  3. package/dist/autosave/index.d.ts +5 -5
  4. package/dist/chrome/chrome.css +50 -273
  5. package/dist/chrome/index.d.ts +61 -56
  6. package/dist/chrome/index.js +1 -1
  7. package/dist/chunk-4GNPKHV4.js +64 -0
  8. package/dist/chunk-5545A3PC.js +4 -0
  9. package/dist/chunk-7SQF6LZL.js +1 -0
  10. package/dist/chunk-BXMXTO36.js +1 -0
  11. package/dist/{chunk-JWMNPRTT.js → chunk-CKEPQNSQ.js} +1 -1
  12. package/dist/{chunk-LY4K2ECT.js → chunk-DJMMTWFP.js} +1 -1
  13. package/dist/chunk-EA2HTX37.js +5 -0
  14. package/dist/{chunk-VINYARYJ.js → chunk-FEK3S6HN.js} +1 -1
  15. package/dist/chunk-FPAVNX3Y.js +6 -0
  16. package/dist/chunk-HMJS344F.js +1 -0
  17. package/dist/chunk-JLTZQ4US.js +1 -0
  18. package/dist/chunk-JMGPPXNQ.js +24 -0
  19. package/dist/chunk-K56YDHYQ.js +1 -0
  20. package/dist/chunk-LOMEH6DG.js +1 -0
  21. package/dist/{chunk-FS5BLARH.js → chunk-MAEXP3KE.js} +1 -1
  22. package/dist/chunk-MJM6SFD3.js +3 -0
  23. package/dist/chunk-NLRW4BGG.js +8 -0
  24. package/dist/chunk-OJAJVH7S.js +5 -0
  25. package/dist/chunk-ONRYLR2D.js +2 -0
  26. package/dist/{chunk-WTMHT7BI.js → chunk-ORR3Q4WV.js} +1 -1
  27. package/dist/chunk-OTEXGJDU.js +5 -0
  28. package/dist/chunk-P2VEMZH5.js +1 -0
  29. package/dist/{chunk-MHKBLPQ2.js → chunk-PT6V53OO.js} +1 -1
  30. package/dist/{chunk-6WH7FA2M.js → chunk-PYCLHOSA.js} +2 -2
  31. package/dist/chunk-Q27BB5ZC.js +14 -0
  32. package/dist/chunk-QLD57GBB.js +6 -0
  33. package/dist/{chunk-PBSEUZD6.js → chunk-QMNML7XH.js} +1 -1
  34. package/dist/chunk-QR4DLZ3P.js +5 -0
  35. package/dist/chunk-TJ7YIRWQ.js +21 -0
  36. package/dist/{chunk-3P6AMTOS.js → chunk-VPFNZ7TB.js} +1 -1
  37. package/dist/chunk-W3XX2CNW.js +16 -0
  38. package/dist/chunk-X6DQWK2C.js +1 -0
  39. package/dist/chunk-XWR5YVA7.js +9 -0
  40. package/dist/chunk-YABL4EWX.js +7 -0
  41. package/dist/chunk-ZNNATBDC.js +1 -0
  42. package/dist/chunk-ZP4G3X44.js +4 -0
  43. package/dist/copy/copy.css +66 -177
  44. package/dist/copy/index.d.ts +0 -2
  45. package/dist/copy/index.js +31 -32
  46. package/dist/drag/drag.css +31 -11
  47. package/dist/drag/index.js +1 -1
  48. package/dist/easel/index.js +1 -1
  49. package/dist/fields/fields.css +35 -304
  50. package/dist/fields/index.d.ts +87 -95
  51. package/dist/fields/index.js +1 -1
  52. package/dist/gold/gold.css +3 -3
  53. package/dist/gold/index.d.ts +6 -5
  54. package/dist/gold/index.js +1 -1
  55. package/dist/index.d.ts +3 -3
  56. package/dist/index.js +1 -1
  57. package/dist/menu/index.d.ts +49 -93
  58. package/dist/menu/index.js +1 -1
  59. package/dist/menu/menu.css +37 -246
  60. package/dist/node-ops/index.d.ts +1 -1
  61. package/dist/panel/index.d.ts +46 -72
  62. package/dist/panel/index.js +17 -18
  63. package/dist/panel/panel.css +143 -372
  64. package/dist/pick/index.d.ts +52 -33
  65. package/dist/pick/index.js +7 -7
  66. package/dist/pick/pick.css +19 -150
  67. package/dist/rail/index.d.ts +48 -90
  68. package/dist/rail/index.js +1 -1
  69. package/dist/rail/rail.css +21 -108
  70. package/dist/screen/components/AddBlockRow.d.ts +8 -2
  71. package/dist/screen/components/AddBlockRow.js +1 -1
  72. package/dist/screen/components/AddChildRow.d.ts +4 -3
  73. package/dist/screen/components/AddChildRow.js +1 -1
  74. package/dist/screen/components/AddSidePanel.js +1 -1
  75. package/dist/screen/components/MediaSidePanel.d.ts +1 -1
  76. package/dist/screen/components/MediaSidePanel.js +1 -1
  77. package/dist/screen/components/NodeContextMenu.d.ts +12 -8
  78. package/dist/screen/components/NodeContextMenu.js +1 -1
  79. package/dist/screen/components/PageEditGuardNotices.js +1 -1
  80. package/dist/screen/components/ScreenChrome.js +1 -1
  81. package/dist/screen/components/ScreenDocumentContext.d.ts +1 -1
  82. package/dist/screen/components/ScreenDocumentContext.js +1 -1
  83. package/dist/screen/components/ScreenMount.d.ts +7 -7
  84. package/dist/screen/components/ScreenMount.js +1 -1
  85. package/dist/screen/components/ScreenStoreProvider.d.ts +7 -7
  86. package/dist/screen/components/ScreenStoreProvider.js +1 -1
  87. package/dist/screen/components/SectionScreenShell.js +16 -16
  88. package/dist/screen/components/SidePanelHead.d.ts +4 -2
  89. package/dist/screen/components/SidePanelHead.js +1 -1
  90. package/dist/screen/components/UiIcon.d.ts +10 -26
  91. package/dist/screen/components/UiIcon.js +2 -1
  92. package/dist/screen/components/panel-widths.js +1 -1
  93. package/dist/screen/components/usePartBridge.d.ts +7 -7
  94. package/dist/screen/components/usePartBridge.js +1 -1
  95. package/dist/screen/index.d.ts +7 -7
  96. package/dist/screen/index.js +1 -1
  97. package/dist/screen/lib/admin-bridge.d.ts +1 -1
  98. package/dist/screen/lib/admin-bridge.js +1 -1
  99. package/dist/screen/lib/chrome-theme.d.ts +20 -12
  100. package/dist/screen/lib/chrome-theme.js +1 -1
  101. package/dist/screen/lib/document-addressing.d.ts +1 -1
  102. package/dist/screen/lib/host-chrome.d.ts +1 -1
  103. package/dist/screen/lib/host.d.ts +1 -1
  104. package/dist/screen/lib/key-scope.js +1 -1
  105. package/dist/screen/lib/links/link-filters.d.ts +1 -1
  106. package/dist/screen/lib/media-panel.d.ts +1 -1
  107. package/dist/screen/lib/media-picker.d.ts +1 -1
  108. package/dist/screen/lib/page-lock.d.ts +1 -1
  109. package/dist/screen/lib/puck/style-clipboard.d.ts +7 -7
  110. package/dist/screen/lib/puck/use-section-ops.js +1 -1
  111. package/dist/screen/lib/screen-parts.d.ts +9 -8
  112. package/dist/screen/lib/screen-parts.js +1 -1
  113. package/dist/screen/lib/section-templates.d.ts +1 -1
  114. package/dist/screen/lib/session-context.d.ts +1 -1
  115. package/dist/screen/lib/session.d.ts +1 -1
  116. package/dist/screen/screen.css +33 -206
  117. package/dist/shell/index.d.ts +134 -118
  118. package/dist/shell/index.js +1 -1
  119. package/dist/shell/shell.css +130 -88
  120. package/dist/strings/catalogue.d.ts +5 -5
  121. package/dist/strings/catalogue.js +1 -1
  122. package/dist/strings/index.d.ts +5 -5
  123. package/dist/strings/index.js +1 -1
  124. package/dist/style-clipboard/index.d.ts +1 -1
  125. package/dist/text-styles/index.d.ts +12 -3
  126. package/dist/text-styles/index.js +33 -38
  127. package/dist/text-styles/text-styles.css +39 -71
  128. package/dist/tree/index.d.ts +49 -44
  129. package/dist/tree/index.js +1 -1
  130. package/dist/tree/tree.css +31 -653
  131. package/dist/{types-DJDBtdB2.d.ts → types-BqGnUVX5.d.ts} +32 -32
  132. package/dist/types-BsyPh6EW.d.ts +99 -0
  133. package/dist/{types-DWS-s9z-.d.ts → types-CsgMwHHa.d.ts} +14 -11
  134. package/dist/{types-CqY85foL.d.ts → types-Dt1CFR1S.d.ts} +4 -2
  135. package/dist/{wordFit-D4S36PvB.d.ts → wordFit-7XpmhcaW.d.ts} +3 -5
  136. package/dist/words-Cl9xMUYY.d.ts +41 -0
  137. package/dist/{words-D_Lnw1Gr.d.ts → words-CvFnwGSr.d.ts} +1 -1
  138. package/package.json +5 -1
  139. package/dist/chunk-2UX75JDP.js +0 -1
  140. package/dist/chunk-37OCQYNX.js +0 -65
  141. package/dist/chunk-3EDSDPIP.js +0 -1
  142. package/dist/chunk-3QVB4AG2.js +0 -3
  143. package/dist/chunk-3WSPDAK2.js +0 -1
  144. package/dist/chunk-5MZ3RNQQ.js +0 -13
  145. package/dist/chunk-5ZBBXZPV.js +0 -6
  146. package/dist/chunk-BZ5ASXOL.js +0 -1
  147. package/dist/chunk-C6BJB5AC.js +0 -2
  148. package/dist/chunk-DX4XELD6.js +0 -18
  149. package/dist/chunk-EOJNJCMJ.js +0 -16
  150. package/dist/chunk-EWVJSRRY.js +0 -6
  151. package/dist/chunk-H24N5TMZ.js +0 -11
  152. package/dist/chunk-I6T4TZ5Q.js +0 -8
  153. package/dist/chunk-KTVH2ZRL.js +0 -15
  154. package/dist/chunk-M7N2V4TG.js +0 -2
  155. package/dist/chunk-MS4QRBJ6.js +0 -5
  156. package/dist/chunk-ND55LTCA.js +0 -5
  157. package/dist/chunk-OWBO4WKA.js +0 -0
  158. package/dist/chunk-P6O363EE.js +0 -6
  159. package/dist/chunk-RW4XBUUW.js +0 -1
  160. package/dist/chunk-UEVTQBM7.js +0 -10
  161. package/dist/chunk-VCQVNPTG.js +0 -22
  162. package/dist/chunk-WZ7TGAAT.js +0 -3
  163. package/dist/chunk-YC4TB3CJ.js +0 -25
  164. package/dist/chunk-Z6SOLDWV.js +0 -1
  165. package/dist/chunk-ZFDCDJNZ.js +0 -16
  166. package/dist/chunk-ZNS7727Y.js +0 -12
  167. package/dist/types-Djdq6Xkd.d.ts +0 -138
  168. package/dist/words-DgHcY5qB.d.ts +0 -33
@@ -1,4 +1,4 @@
1
- import { E as EaselContextMenuItem } from '../types-Djdq6Xkd.js';
1
+ import { E as EaselContextMenuItem } from '../types-BsyPh6EW.js';
2
2
  import { S as StyleClipboardWords } from '../words-CnnHb9jo.js';
3
3
  import 'react';
4
4
 
@@ -316,9 +316,18 @@ interface ColourSwatchRowProps {
316
316
  }
317
317
  /**
318
318
  * THE COLOR ROW — the theme's colours in a row, then Any color, which opens
319
- * the one colour window (`ColourWindow`). Exported so a second host draws the
320
- * same row instead of a copy (plan S2: the website's part panel; design final
321
- * 2026-10-06). The text-styles list draws it through this export, unchanged.
319
+ * the one colour window (`ColourWindow`, the shell's `ColorPickerPanel`).
320
+ * Exported so a second host draws the same row instead of a copy (plan S2:
321
+ * the website's part panel; design final 2026-10-06). The text-styles list
322
+ * draws it through this export, unchanged.
323
+ *
324
+ * The swatches are the shell's `ColorSwatch`, named on hover by its `Tooltip`
325
+ * (easel#199 step 4, harness UI-24). Any color opens the panel UNDER the row,
326
+ * in the list's own flow, as before: the shell's `ColorPicker` cannot take a
327
+ * trigger of its own (this one is a swatch painted with the hue wheel, pressed
328
+ * while the colour is a hex), and the window is closed as the colour row's
329
+ * always was — Escape (focus back on Any color) and a click outside the row.
330
+ * The row's name, the readout and the swatch group stay this row's.
322
331
  *
323
332
  * What a press means is the host's: a swatch writes its key, the window a
324
333
  * hex. Clearing, and what "nothing chosen" reads, are the host's too.
@@ -1,38 +1,33 @@
1
- import{DEFAULT_TEXT_STYLES_WORDS as e}from"../chunk-M6F6LS3H.js";export{DEFAULT_TEXT_STYLES_WORDS}from"../chunk-M6F6LS3H.js";import{FieldSelect as t,FieldSlider as n}from"../chunk-EOJNJCMJ.js";import{hexReadout as s,ColourWindow as i,typedHex as a}from"../chunk-H24N5TMZ.js";import{DEFAULT_PICK_WORDS as l}from"../chunk-ZAOM6PFH.js";import"../chunk-EWVJSRRY.js";import"../chunk-FPOKPNO4.js";import{useWords as r}from"../chunk-MFIRYGHW.js";import{ChevronIcon as o,TrashIcon as d,BoldIcon as c,ItalicIcon as u,CaseLowerIcon as m,CaseUpperIcon as p,CaseNormalIcon as f}from"../chunk-L5KW4HG5.js";import{useState as h,useRef as v,useId as g,useEffect as y,Fragment as k}from"react";import{jsxs as b,jsx as w,Fragment as x}from"react/jsx-runtime";var S=["font","color","size","weight","emphasis","lineSpacing","letterSpacing","paragraphSpacing","letterCase","largestSize"],N=["font","color","size","weight","lineSpacing","letterSpacing","paragraphSpacing","letterCase"],C=["heading","body"],M=7,O={heading:3,body:5},z={min:5,max:void 0,sliderMin:12,sliderMax:72,step:1,shiftStep:10,unit:"px"},$={size:z,weight:{min:100,max:900,sliderMin:300,sliderMax:900,step:100,shiftStep:100,unit:""},lineSpacing:{min:50,max:250,sliderMin:50,sliderMax:250,step:1,shiftStep:10,unit:"%"},letterSpacing:{min:-10,max:void 0,sliderMin:-5,sliderMax:10,step:.1,shiftStep:1,unit:"px"},paragraphSpacing:{min:0,max:void 0,sliderMin:0,sliderMax:48,step:1,shiftStep:10,unit:"px"},largestSize:z},j=(e,t)=>`${"heading"===e?"Heading":"Body"} ${t}`;function A(e=({kind:e,n:t})=>j(e,t)){return C.flatMap(t=>Array.from({length:O[t]},(n,s)=>({id:`${t}-${s+1}`,kind:t,name:e({kind:t,n:s+1}),values:{}})))}function L(e,t,n=M){return e.filter(e=>e.kind===t).length<n}function W(e,t){const n=new RegExp(`^${t}-([1-9]\\d*)$`).exec(e);return n?Number(n[1]):void 0}function E(e){const t=W(e.id,e.kind);return void 0!==t&&t<=O[e.kind]}function F(e,t,n={}){const{max:s=M,name:i=({kind:e,n:t})=>j(e,t),make:a}=n;if(!L(e,t,s))return null;const l=e.filter(e=>e.kind===t);let r=l.length+1;const o=new Set(e.map(e=>e.name));for(;o.has(i({kind:t,n:r}));)r+=1;const d=new Set(e.map(e=>e.id));let c=Math.max(r,...l.map(e=>(W(e.id,t)??0)+1));for(;d.has(`${t}-${c}`);)c+=1;const u=l.at(-1),m=a?a(t,r):{id:`${t}-${c}`,kind:t,name:i({kind:t,n:r}),values:{...u?.values??{}}},p=u?e.indexOf(u)+1:"heading"===t?0:e.length;return{styles:[...e.slice(0,p),m,...e.slice(p)],added:m}}function H(e,t,n={}){const{name:s=({kind:e,n:t})=>j(e,t)}=n,i=e.find(e=>e.id===t);if(!i||E(i))return null;const a=e.filter(e=>e.kind===i.kind),l=a.indexOf(i),r=/* @__PURE__ */new Map;return a.forEach((e,t)=>{t>l&&e.name===s({kind:e.kind,n:t+1})&&r.set(e,s({kind:e.kind,n:t}))}),{styles:e.filter(e=>e!==i).map(e=>r.has(e)?{...e,name:r.get(e)}:e),removed:i}}function R(e,t){const n=e.find(e=>e.id===t);if(n)return n;for(const n of C){const s=W(t,n);if(void 0===s)continue;let i;for(const t of e){const e=t.kind===n?W(t.id,n):void 0;void 0!==e&&e<s&&(!i||e>i.n)&&(i={n:e,style:t})}return i?.style}}function T(e,t,n){return e.map(e=>{if(e.id!==t)return e;const s={...e.values};for(const[e,t]of Object.entries(n))void 0===t?delete s[e]:s[e]=t;return{...e,values:s}})}function D(e){return Math.min(20,Math.max(12,Math.round(.5*e+6)))}function I(e,t){const n=t.weights;return[n.thin,n.extraLight,n.light,n.regular,n.medium,n.semibold,n.bold,n.extraBold,n.black][Math.min(8,Math.max(0,Math.round(e/100)-1))]}function B(e,t,n,s={}){const i=t.find(t=>t.value===e.font)?.label??e.font??"",a=void 0===e.size?s.autoSize?n.auto:"":n.px({n:e.size});return n.summary({font:i,size:a,weight:I(e.weight??400,n)})}function J({value:e,hex:t,colours:n,label:a,followsWord:o,anyWord:d,onChange:c,readOnly:u=!1}){const m=r("pick",l),[p,f]=h(!1),k=v(null),x=v(null),S=g(),N=void 0!==e&&n.some(t=>t.key===e),C=void 0!==e&&!N;return y(()=>{if(!p)return;const e=k.current?.ownerDocument;if(!e)return;const t=e=>{k.current&&!k.current.contains(e.target)&&f(!1)};return e.addEventListener("click",t,!0),()=>e.removeEventListener("click",t,!0)},[p]),/* @__PURE__ */b("div",{ref:k,className:"es-ts-set","data-ts-setting":"color",children:[
2
- /* @__PURE__ */b("div",{className:"es-ts-top",children:[
3
- /* @__PURE__ */w("span",{className:"es-ts-sub",children:a}),
4
- /* @__PURE__ */w("span",{className:"es-ts-colour-read",children:t?s(t):o})]}),
5
- /* @__PURE__ */b("div",{className:"es-ts-swatches",role:"group","aria-label":a,children:[n.map(t=>/* @__PURE__ */w("button",{type:"button",className:"es-ts-swatch",style:{background:t.value},"aria-label":t.name,title:`${t.name} · ${s(t.value)}`,"aria-pressed":e===t.key,disabled:u,onClick:()=>c(t.key)},t.key)),
6
- /* @__PURE__ */w("button",{ref:x,type:"button",className:"es-ts-swatch es-ts-swatch--any","aria-label":d,title:d,"aria-pressed":C,"aria-expanded":p,"aria-controls":p?S:void 0,disabled:u,onClick:()=>f(e=>!e)})]}),p?/* @__PURE__ */w(i,{id:S,value:t??"",onChange:e=>c(e),label:a,words:m.colour,readOnly:u,onClose:()=>{f(!1),x.current?.focus()}}):null]})}function q({styles:t,onChange:n,fonts:s,colours:i=[],settings:a=N,auto:l=[],fallback:c,sample:u,openId:m,defaultOpenId:p=null,onOpenChange:f,onAdd:x,rowActions:O,onRemove:z,max:$=M,readOnly:j=!1}){const A=r("textStyles",e),W=g(),[R,I]=h(p),J=void 0!==m?m:R,q=e=>{void 0===m&&I(e),f?.(e)},K=new Set(l),P=S.filter(e=>a.includes(e)),_=v(null),[G,U]=h(null);y(()=>{if(!G||!_.current)return;const e=[..._.current.querySelectorAll(".es-ts-item")].find(e=>e.dataset.tsId===G.id),t=e?e.querySelector(".es-ts-row"):_.current.querySelector(`.es-ts-add[data-ts-kind="${G.kind}"]`);t?.focus(),U(null)},[G]);/* @__PURE__ */
7
- return w("div",{className:"es-ts",ref:_,children:C.map(e=>{const a=t.filter(t=>t.kind===e),l=`${W}-${e}`,r=!j&&L(t,e,$);/* @__PURE__ */
8
- return b("section",{className:"es-ts-section","aria-labelledby":l,children:[
9
- /* @__PURE__ */w("div",{className:"es-ts-group",id:l,children:A.groups[e]}),a.map(e=>{const a=J===e.id,l={...c?.(e)??{},...e.values},r=s.find(e=>e.value===l.font),m=`${W}-open-${e.id}`,p=O?.(e),f=null!=p&&!1!==p,h=Boolean(z)&&!j&&!E(e),v={fontFamily:r?.family,fontSize:`${D(l.size??16)}px`,fontWeight:l.weight,fontStyle:l.italic?"italic":void 0};/* @__PURE__ */
10
- return b(k,{children:[
11
- /* @__PURE__ */b("div",{className:"es-ts-item","data-ts-id":e.id,children:[
12
- /* @__PURE__ */b("button",{type:"button",className:"es-ts-row","aria-expanded":a,"aria-controls":a?m:void 0,onClick:()=>q(a?null:e.id),children:[
13
- /* @__PURE__ */w("span",{className:"es-ts-chev","aria-hidden":"true",children:/* @__PURE__ */w(o,{size:12})}),
14
- /* @__PURE__ */w("span",{className:"es-ts-name",style:v,children:e.name}),
15
- /* @__PURE__ */w("span",{className:"es-ts-meta",children:B(l,s,A,{autoSize:K.has("size")&&void 0===e.values.size})})]}),h||f?/* @__PURE__ */b("div",{className:"es-ts-actions",children:[h?/* @__PURE__ */w("button",{type:"button",className:"es-ts-del",title:A.remove,"aria-label":A.removeNamed({name:e.name}),onClick:()=>(e=>{if(j||!z)return;const s=H(t,e.id,{name:A.styleName});if(!s)return;const i=t.filter(t=>t.kind===e.kind),a=i[i.indexOf(e)+1];J===e.id&&q(null),n(s.styles),z(s.removed),U({id:a?.id??null,kind:e.kind})})(e),children:/* @__PURE__ */w(d,{size:14,"aria-hidden":"true"})}):null,f?p:null]}):null]}),a?/* @__PURE__ */w("div",{className:"es-ts-open",id:m,children:/* @__PURE__ */w(Y,{style:e,values:l,fonts:s,colours:i,settings:P,autoSet:K,sample:u??A.sample,words:A,readOnly:j,set:s=>n(T(t,e.id,s))})}):null]},e.id)}),
16
- /* @__PURE__ */b("button",{type:"button",className:"es-ts-add","data-ts-kind":e,disabled:!r,title:r?void 0:A.full({kind:e,max:$}),onClick:()=>(e=>{if(j)return;const s=F(t,e,{max:$,name:A.styleName,make:x});s&&n(s.styles)})(e),children:[
17
- /* @__PURE__ */w("span",{className:"es-ts-add-word",children:A.add[e]}),
18
- /* @__PURE__ */w("span",{className:"es-ts-count",children:A.count({n:a.length,max:$})})]})]},e)})})}var K={none:f,upper:p,lower:m},P={none:"none",upper:"uppercase",lower:"lowercase"};function Y({style:e,values:t,fonts:s,colours:i,settings:l,autoSet:r,sample:o,words:d,readOnly:m,set:p}){const f=e.values,h=s.find(e=>e.value===t.font),v=function(e,t){return e?t.find(t=>t.key===e)?.value??a(e)??void 0:void 0}(t.color,i),g=e=>"largestSize"===e||r.has(e),y=e=>g(e)?f[e]:t[e],k=y("size"),S=y("lineSpacing"),N=y("letterSpacing"),C=g("letterCase")?f.letterCase:t.letterCase,M={fontFamily:h?.family,fontSize:void 0===k?void 0:`${k}px`,fontWeight:t.weight,fontStyle:t.italic?"italic":void 0,lineHeight:void 0===S?void 0:String(S/100),letterSpacing:void 0===N?void 0:`${N}px`,color:v,textTransform:C?P[C]:void 0},O=e=>{const s=$[e],i=g(e);/* @__PURE__ */
19
- return w("div",{className:"es-ts-slider","data-ts-setting":e,children:/* @__PURE__ */w(n,{label:d.settings[e],value:f[e],onChange:t=>p({[e]:t}),min:s.min,max:s.max,step:s.step,shiftStep:s.shiftStep,sliderMin:s.sliderMin,sliderMax:s.sliderMax,unit:s.unit||void 0,styleValue:i?void 0:t[e],auto:i?d.auto:void 0,readOnly:m})},e)};/* @__PURE__ */
20
- return b(x,{children:[
21
- /* @__PURE__ */w("div",{className:"es-ts-preview",style:M,"aria-label":d.preview,children:o}),l.map(n=>{switch(n){case"font":/* @__PURE__ */
22
- return w(_,{value:f.font,fonts:s,words:d,readOnly:m,set:p},n);case"color":/* @__PURE__ */
23
- return w(G,{value:f.color,hex:v,colours:i,words:d,readOnly:m,set:p},n);case"emphasis":{const e=(t.weight??400)>=600,s=!1!==h?.italic;/* @__PURE__ */
24
- return b("div",{className:"es-ts-set","data-ts-setting":n,children:[
25
- /* @__PURE__ */w("span",{className:"es-ts-sub",children:d.settings.emphasis}),
26
- /* @__PURE__ */b("div",{className:"es-ts-icons",children:[
27
- /* @__PURE__ */w("button",{type:"button",className:"es-ts-icon","aria-label":d.bold,title:d.bold,"aria-pressed":e,disabled:m,onClick:()=>p({weight:e?400:700}),children:/* @__PURE__ */w(c,{size:16})}),
28
- /* @__PURE__ */w("button",{type:"button",className:"es-ts-icon","aria-label":d.italic,title:s?d.italic:d.italicMissing,"aria-pressed":Boolean(t.italic),disabled:m||!s,onClick:()=>p({italic:!t.italic||void 0}),children:/* @__PURE__ */w(u,{size:16})})]})]},n)}case"letterCase":/* @__PURE__ */
29
- return w(U,{value:f.letterCase??t.letterCase,auto:g("letterCase"),words:d,readOnly:m,set:p},n);case"largestSize":return"heading"===e.kind?O(n):null;default:return O(n)}})]})}function _({value:e,fonts:n,words:s,readOnly:i,set:a}){const l=g();/* @__PURE__ */
30
- return b("div",{className:"es-ts-set","data-ts-setting":"font",children:[
31
- /* @__PURE__ */w("span",{className:"es-ts-sub",id:l,children:s.settings.font}),
32
- /* @__PURE__ */w(t,{value:e,options:n.map(e=>({label:e.label,value:e.value})),onChange:e=>a({font:e}),ariaLabelledBy:l,readOnly:i})]})}function G({value:e,hex:t,colours:n,words:s,readOnly:i,set:a}){/* @__PURE__ */
33
- return w(J,{value:e,hex:t,colours:n,label:s.settings.color,followsWord:s.colour.follows,anyWord:s.colour.any,readOnly:i,onChange:e=>a({color:e})})}function U({value:e,auto:t,words:n,readOnly:s,set:i}){const a=t?["auto","none","upper","lower"]:["none","upper","lower"],l=e??(t?"auto":"none"),r=v([]),o=e=>i({letterCase:"auto"===e?void 0:e});/* @__PURE__ */
34
- return b("div",{className:"es-ts-set","data-ts-setting":"letterCase",children:[
35
- /* @__PURE__ */w("span",{className:"es-ts-sub",children:n.settings.letterCase}),
36
- /* @__PURE__ */w("div",{className:"es-ts-icons",role:"radiogroup","aria-label":n.settings.letterCase,onKeyDown:e=>{const t="ArrowRight"===e.key||"ArrowDown"===e.key?1:"ArrowLeft"===e.key||"ArrowUp"===e.key?-1:0;if(!t||s)return;e.preventDefault();const n=(a.indexOf(l)+t+a.length)%a.length;o(a[n]),r.current[n]?.focus()},children:a.map((e,t)=>{const i=e===l;if("auto"===e)/* @__PURE__ */
37
- return w("button",{ref:e=>{r.current[t]=e},type:"button",role:"radio",className:"es-ts-icon es-ts-icon--word","aria-checked":i,tabIndex:i?0:-1,title:n.case.autoTitle,disabled:s,onClick:()=>o(e),children:n.case.auto},e);const a=K[e];/* @__PURE__ */
38
- return w("button",{ref:e=>{r.current[t]=e},type:"button",role:"radio",className:"es-ts-icon","aria-checked":i,"aria-label":n.case[e],title:n.case[e],tabIndex:i?0:-1,disabled:s,onClick:()=>o(e),children:/* @__PURE__ */w(a,{size:16})},e)})})]})}export{N as CAMPAIGN_TEXT_STYLE_SETTINGS,J as ColourSwatchRow,O as TEXT_STYLE_DEFAULT_COUNT,C as TEXT_STYLE_KINDS,M as TEXT_STYLE_MAX,$ as TEXT_STYLE_RANGES,S as TEXT_STYLE_SETTINGS,q as TextStylesList,F as addTextStyle,L as canAddTextStyle,A as defaultTextStyles,B as describeTextStyle,E as isDefaultTextStyle,H as removeTextStyle,R as resolveTextStyle,D as textStyleRowSize,T as updateTextStyle,I as weightWord};
1
+ import{hexReadout as e,ColourWindow as n,typedHex as t}from"../chunk-FPAVNX3Y.js";import{DEFAULT_TEXT_STYLES_WORDS as s}from"../chunk-M6F6LS3H.js";export{DEFAULT_TEXT_STYLES_WORDS}from"../chunk-M6F6LS3H.js";import"../chunk-ZAOM6PFH.js";import{FieldSelect as i,FieldSlider as a}from"../chunk-NLRW4BGG.js";import"../chunk-FPOKPNO4.js";import{useWords as l}from"../chunk-MFIRYGHW.js";import{withTip as r}from"../chunk-P2VEMZH5.js";import{ChevronIcon as o,TrashIcon as d,BoldIcon as c,ItalicIcon as u,CaseLowerIcon as m,CaseUpperIcon as h,CaseNormalIcon as f}from"../chunk-L5KW4HG5.js";import{hsvToHex as p,Tooltip as v,ColorSwatch as g,IconButton as y,iconButtonClasses as k}from"efficient-shell/ui";import{useState as b,useRef as x,useId as w,useEffect as N,Fragment as S}from"react";import{jsxs as C,jsx as M,Fragment as $}from"react/jsx-runtime";var z=["font","color","size","weight","emphasis","lineSpacing","letterSpacing","paragraphSpacing","letterCase","largestSize"],O=["font","color","size","weight","lineSpacing","letterSpacing","paragraphSpacing","letterCase"],j=["heading","body"],A=7,L={heading:3,body:5},F={min:5,max:void 0,sliderMin:12,sliderMax:72,step:1,shiftStep:10,unit:"px"},W={size:F,weight:{min:100,max:900,sliderMin:300,sliderMax:900,step:100,shiftStep:100,unit:""},lineSpacing:{min:50,max:250,sliderMin:50,sliderMax:250,step:1,shiftStep:10,unit:"%"},letterSpacing:{min:-10,max:void 0,sliderMin:-5,sliderMax:10,step:.1,shiftStep:1,unit:"px"},paragraphSpacing:{min:0,max:void 0,sliderMin:0,sliderMax:48,step:1,shiftStep:10,unit:"px"},largestSize:F},E=(e,n)=>`${"heading"===e?"Heading":"Body"} ${n}`;function H(e=({kind:e,n:n})=>E(e,n)){return j.flatMap(n=>Array.from({length:L[n]},(t,s)=>({id:`${n}-${s+1}`,kind:n,name:e({kind:n,n:s+1}),values:{}})))}function B(e,n,t=A){return e.filter(e=>e.kind===n).length<t}function D(e,n){const t=new RegExp(`^${n}-([1-9]\\d*)$`).exec(e);return t?Number(t[1]):void 0}function I(e){const n=D(e.id,e.kind);return void 0!==n&&n<=L[e.kind]}function R(e,n,t={}){const{max:s=A,name:i=({kind:e,n:n})=>E(e,n),make:a}=t;if(!B(e,n,s))return null;const l=e.filter(e=>e.kind===n);let r=l.length+1;const o=new Set(e.map(e=>e.name));for(;o.has(i({kind:n,n:r}));)r+=1;const d=new Set(e.map(e=>e.id));let c=Math.max(r,...l.map(e=>(D(e.id,n)??0)+1));for(;d.has(`${n}-${c}`);)c+=1;const u=l.at(-1),m=a?a(n,r):{id:`${n}-${c}`,kind:n,name:i({kind:n,n:r}),values:{...u?.values??{}}},h=u?e.indexOf(u)+1:"heading"===n?0:e.length;return{styles:[...e.slice(0,h),m,...e.slice(h)],added:m}}function T(e,n,t={}){const{name:s=({kind:e,n:n})=>E(e,n)}=t,i=e.find(e=>e.id===n);if(!i||I(i))return null;const a=e.filter(e=>e.kind===i.kind),l=a.indexOf(i),r=/* @__PURE__ */new Map;return a.forEach((e,n)=>{n>l&&e.name===s({kind:e.kind,n:n+1})&&r.set(e,s({kind:e.kind,n:n}))}),{styles:e.filter(e=>e!==i).map(e=>r.has(e)?{...e,name:r.get(e)}:e),removed:i}}function P(e,n){const t=e.find(e=>e.id===n);if(t)return t;for(const t of j){const s=D(n,t);if(void 0===s)continue;let i;for(const n of e){const e=n.kind===t?D(n.id,t):void 0;void 0!==e&&e<s&&(!i||e>i.n)&&(i={n:e,style:n})}return i?.style}}function G(e,n,t){return e.map(e=>{if(e.id!==n)return e;const s={...e.values};for(const[e,n]of Object.entries(t))void 0===n?delete s[e]:s[e]=n;return{...e,values:s}})}function q(e){return Math.min(20,Math.max(12,Math.round(.5*e+6)))}function K(e,n){const t=n.weights;return[t.thin,t.extraLight,t.light,t.regular,t.medium,t.semibold,t.bold,t.extraBold,t.black][Math.min(8,Math.max(0,Math.round(e/100)-1))]}function V(e,n,t,s={}){const i=n.find(n=>n.value===e.font)?.label??e.font??"",a=void 0===e.size?s.autoSize?t.auto:"":t.px({n:e.size});return t.summary({font:i,size:a,weight:K(e.weight??400,t)})}var Y=`conic-gradient(${[0,60,120,180,240,300,0].map(e=>p({h:e,s:1,v:1})).join(", ")})`;function _({value:t,hex:s,colours:i,label:a,followsWord:l,anyWord:r,onChange:o,readOnly:d=!1}){const[c,u]=b(!1),m=x(null),h=x(null),f=w(),p=void 0!==t&&i.some(e=>e.key===t),y=void 0!==t&&!p;return N(()=>{if(!c)return;const e=m.current?.ownerDocument;if(!e)return;const n=e=>{m.current&&!m.current.contains(e.target)&&u(!1)};return e.addEventListener("click",n,!0),()=>e.removeEventListener("click",n,!0)},[c]),/* @__PURE__ */C("div",{ref:m,className:"es-ts-set","data-ts-setting":"color",children:[
2
+ /* @__PURE__ */C("div",{className:"es-ts-top",children:[
3
+ /* @__PURE__ */M("span",{className:"es-ts-sub",children:a}),
4
+ /* @__PURE__ */M("span",{className:"es-ts-colour-read",children:s?e(s):l})]}),
5
+ /* @__PURE__ */C("div",{className:"es-ts-swatches",role:"group","aria-label":a,children:[i.map(n=>/* @__PURE__ */M(v,{content:`${n.name} · ${e(n.value)}`,children:/* @__PURE__ */M(g,{color:n.value,size:"sm",className:"es-ts-swatch","aria-label":n.name,selected:t===n.key,disabled:d,onClick:()=>o(n.key)})},n.key)),
6
+ /* @__PURE__ */M(v,{content:r,children:/* @__PURE__ */M(g,{ref:h,color:Y,size:"sm",className:"es-ts-swatch es-ts-swatch--any","aria-label":r,selected:y,"aria-expanded":c,"aria-controls":c?f:void 0,disabled:d,onClick:()=>u(e=>!e)})})]}),c?/* @__PURE__ */M(n,{id:f,value:s??"",onChange:e=>o(e),label:a,readOnly:d,onClose:()=>{u(!1),h.current?.focus()}}):null]})}function U({styles:e,onChange:n,fonts:t,colours:i=[],settings:a=O,auto:c=[],fallback:u,sample:m,openId:h,defaultOpenId:f=null,onOpenChange:p,onAdd:v,rowActions:g,onRemove:y,max:k=A,readOnly:$=!1}){const L=l("textStyles",s),F=w(),[W,E]=b(f),H=void 0!==h?h:W,D=e=>{void 0===h&&E(e),p?.(e)},P=new Set(c),K=z.filter(e=>a.includes(e)),Y=x(null),[_,U]=b(null);N(()=>{if(!_||!Y.current)return;const e=[...Y.current.querySelectorAll(".es-ts-item")].find(e=>e.dataset.tsId===_.id),n=e?e.querySelector(".es-ts-row"):Y.current.querySelector(`.es-ts-add[data-ts-kind="${_.kind}"]`);n?.focus(),U(null)},[_]);/* @__PURE__ */
7
+ return M("div",{className:"es-ts",ref:Y,children:j.map(s=>{const a=e.filter(e=>e.kind===s),l=`${F}-${s}`,c=!B(e,s,k),h=!$&&!c;/* @__PURE__ */
8
+ return C("section",{className:"es-ts-section","aria-labelledby":l,children:[
9
+ /* @__PURE__ */M("div",{className:"es-ts-group",id:l,children:L.groups[s]}),a.map(s=>{const a=H===s.id,l={...u?.(s)??{},...s.values},c=t.find(e=>e.value===l.font),h=`${F}-open-${s.id}`,f=g?.(s),p=null!=f&&!1!==f,v=Boolean(y)&&!$&&!I(s),k={fontFamily:c?.family,fontSize:`${q(l.size??16)}px`,fontWeight:l.weight,fontStyle:l.italic?"italic":void 0};/* @__PURE__ */
10
+ return C(S,{children:[
11
+ /* @__PURE__ */C("div",{className:"es-ts-item","data-ts-id":s.id,children:[
12
+ /* @__PURE__ */C("button",{type:"button",className:"es-ts-row","aria-expanded":a,"aria-controls":a?h:void 0,onClick:()=>D(a?null:s.id),children:[
13
+ /* @__PURE__ */M("span",{className:"es-ts-chev","aria-hidden":"true",children:/* @__PURE__ */M(o,{size:12})}),
14
+ /* @__PURE__ */M("span",{className:"es-ts-name",style:k,children:s.name}),
15
+ /* @__PURE__ */M("span",{className:"es-ts-meta",children:V(l,t,L,{autoSize:P.has("size")&&void 0===s.values.size})})]}),v||p?/* @__PURE__ */C("div",{className:"es-ts-actions",children:[v?r(L.remove,/* @__PURE__ */M("button",{type:"button",className:"es-ts-del","aria-label":L.removeNamed({name:s.name}),onClick:()=>(t=>{if($||!y)return;const s=T(e,t.id,{name:L.styleName});if(!s)return;const i=e.filter(e=>e.kind===t.kind),a=i[i.indexOf(t)+1];H===t.id&&D(null),n(s.styles),y(s.removed),U({id:a?.id??null,kind:t.kind})})(s),children:/* @__PURE__ */M(d,{size:14,"aria-hidden":"true"})})):null,p?f:null]}):null]}),a?/* @__PURE__ */M("div",{className:"es-ts-open",id:h,children:/* @__PURE__ */M(J,{style:s,values:l,fonts:t,colours:i,settings:K,autoSet:P,sample:m??L.sample,words:L,readOnly:$,set:t=>n(G(e,s.id,t))})}):null]},s.id)}),r(!$&&c?L.full({kind:s,max:k}):void 0,/* @__PURE__ */C("button",{type:"button",className:"es-ts-add","data-ts-kind":s,disabled:$,"aria-disabled":!($||!c)||void 0,"aria-describedby":!$&&c?`${F}-full-${s}`:void 0,onClick:()=>{h&&(t=>{if($)return;const s=R(e,t,{max:k,name:L.styleName,make:v});s&&n(s.styles)})(s)},children:[
16
+ /* @__PURE__ */M("span",{className:"es-ts-add-word",children:L.add[s]}),
17
+ /* @__PURE__ */M("span",{className:"es-ts-count",children:L.count({n:a.length,max:k})})]})),$||!c?null:/* @__PURE__ */M("span",{id:`${F}-full-${s}`,className:"es-vh",children:L.full({kind:s,max:k})})]},s)})})}var X={none:f,upper:h,lower:m},Z={none:"none",upper:"uppercase",lower:"lowercase"};function J({style:e,values:n,fonts:s,colours:i,settings:l,autoSet:o,sample:d,words:m,readOnly:h,set:f}){const p=w(),v=e.values,g=s.find(e=>e.value===n.font),k=function(e,n){return e?n.find(n=>n.key===e)?.value??t(e)??void 0:void 0}(n.color,i),b=e=>"largestSize"===e||o.has(e),x=e=>b(e)?v[e]:n[e],N=x("size"),S=x("lineSpacing"),z=x("letterSpacing"),O=b("letterCase")?v.letterCase:n.letterCase,j={fontFamily:g?.family,fontSize:void 0===N?void 0:`${N}px`,fontWeight:n.weight,fontStyle:n.italic?"italic":void 0,lineHeight:void 0===S?void 0:String(S/100),letterSpacing:void 0===z?void 0:`${z}px`,color:k,textTransform:O?Z[O]:void 0},A=e=>{const t=W[e],s=b(e);/* @__PURE__ */
18
+ return M("div",{className:"es-ts-slider","data-ts-setting":e,children:/* @__PURE__ */M(a,{label:m.settings[e],value:v[e],onChange:n=>f({[e]:n}),min:t.min,max:t.max,step:t.step,shiftStep:t.shiftStep,sliderMin:t.sliderMin,sliderMax:t.sliderMax,unit:t.unit||void 0,styleValue:s?void 0:n[e],auto:s?m.auto:void 0,readOnly:h})},e)};/* @__PURE__ */
19
+ return C($,{children:[
20
+ /* @__PURE__ */M("div",{className:"es-ts-preview",style:j,"aria-label":m.preview,children:d}),l.map(t=>{switch(t){case"font":/* @__PURE__ */
21
+ return M(Q,{value:v.font,fonts:s,words:m,readOnly:h,set:f},t);case"color":/* @__PURE__ */
22
+ return M(ee,{value:v.color,hex:k,colours:i,words:m,readOnly:h,set:f},t);case"emphasis":{const e=(n.weight??400)>=600,s=!1!==g?.italic;/* @__PURE__ */
23
+ return C("div",{className:"es-ts-set","data-ts-setting":t,children:[
24
+ /* @__PURE__ */M("span",{className:"es-ts-sub",children:m.settings.emphasis}),
25
+ /* @__PURE__ */C("div",{className:"es-ts-icons",children:[r(m.bold,/* @__PURE__ */M(y,{className:"es-ts-icon","aria-label":m.bold,"aria-pressed":e,disabled:h,onClick:()=>f({weight:e?400:700}),children:/* @__PURE__ */M(c,{size:16})})),r(s?m.italic:m.italicMissing,/* @__PURE__ */M(y,{className:"es-ts-icon","aria-label":m.italic,"aria-pressed":Boolean(n.italic),disabled:h,"aria-disabled":!h&&!s||void 0,"aria-describedby":h||s?void 0:`${p}-no-italic`,onClick:()=>{s&&f({italic:!n.italic||void 0})},children:/* @__PURE__ */M(u,{size:16})})),h||s?null:/* @__PURE__ */M("span",{id:`${p}-no-italic`,className:"es-vh",children:m.italicMissing})]})]},t)}case"letterCase":/* @__PURE__ */
26
+ return M(ne,{value:v.letterCase??n.letterCase,auto:b("letterCase"),words:m,readOnly:h,set:f},t);case"largestSize":return"heading"===e.kind?A(t):null;default:return A(t)}})]})}function Q({value:e,fonts:n,words:t,readOnly:s,set:a}){const l=w();/* @__PURE__ */
27
+ return C("div",{className:"es-ts-set","data-ts-setting":"font",children:[
28
+ /* @__PURE__ */M("span",{className:"es-ts-sub",id:l,children:t.settings.font}),
29
+ /* @__PURE__ */M(i,{value:e,options:n.map(e=>({label:e.label,value:e.value})),onChange:e=>a({font:e}),ariaLabelledBy:l,readOnly:s})]})}function ee({value:e,hex:n,colours:t,words:s,readOnly:i,set:a}){/* @__PURE__ */
30
+ return M(_,{value:e,hex:n,colours:t,label:s.settings.color,followsWord:s.colour.follows,anyWord:s.colour.any,readOnly:i,onChange:e=>a({color:e})})}function ne({value:e,auto:n,words:t,readOnly:s,set:i}){const a=n?["auto","none","upper","lower"]:["none","upper","lower"],l=e??(n?"auto":"none"),o=x([]),d=e=>i({letterCase:"auto"===e?void 0:e});/* @__PURE__ */
31
+ return C("div",{className:"es-ts-set","data-ts-setting":"letterCase",children:[
32
+ /* @__PURE__ */M("span",{className:"es-ts-sub",children:t.settings.letterCase}),
33
+ /* @__PURE__ */M("div",{className:"es-ts-icons",role:"radiogroup","aria-label":t.settings.letterCase,onKeyDown:e=>{const n="ArrowRight"===e.key||"ArrowDown"===e.key?1:"ArrowLeft"===e.key||"ArrowUp"===e.key?-1:0;if(!n||s)return;e.preventDefault();const t=(a.indexOf(l)+n+a.length)%a.length;d(a[t]),o.current[t]?.focus()},children:a.map((e,n)=>{const i=e===l;if("auto"===e)return r(t.case.autoTitle,/* @__PURE__ */M("button",{ref:e=>{o.current[n]=e},type:"button",role:"radio",className:k({pressed:i,className:"es-ts-icon es-ts-icon--word"}),"aria-checked":i,tabIndex:i?0:-1,disabled:s,onClick:()=>d(e),children:t.case.auto},e));const a=X[e];return r(t.case[e],/* @__PURE__ */M("button",{ref:e=>{o.current[n]=e},type:"button",role:"radio",className:k({pressed:i,className:"es-ts-icon"}),"aria-checked":i,"aria-label":t.case[e],tabIndex:i?0:-1,disabled:s,onClick:()=>d(e),children:/* @__PURE__ */M(a,{size:16})},e))})})]})}export{O as CAMPAIGN_TEXT_STYLE_SETTINGS,_ as ColourSwatchRow,L as TEXT_STYLE_DEFAULT_COUNT,j as TEXT_STYLE_KINDS,A as TEXT_STYLE_MAX,W as TEXT_STYLE_RANGES,z as TEXT_STYLE_SETTINGS,U as TextStylesList,R as addTextStyle,B as canAddTextStyle,H as defaultTextStyles,V as describeTextStyle,I as isDefaultTextStyle,T as removeTextStyle,P as resolveTextStyle,q as textStyleRowSize,G as updateTextStyle,K as weightWord};
@@ -16,8 +16,9 @@
16
16
  * row is the one thing on the page not drawn here; the 12 px padding
17
17
  * separates them.
18
18
  *
19
- * Builds on fields.css (the sliders, the dropdown) and pick.css (the colour
20
- * window). Light only, like the rest of the editor.
19
+ * Builds on fields.css (the sliders, the dropdown); the colour swatches and
20
+ * window are efficient-shell's. It follows the shell's theme, dark included, like the rest of the
21
+ * editor chrome (UI-24).
21
22
  */
22
23
 
23
24
  .es-ts {
@@ -40,7 +41,7 @@
40
41
  font-weight: 600;
41
42
  letter-spacing: 0.06em;
42
43
  text-transform: uppercase;
43
- color: var(--es-muted, #6b7280);
44
+ color: var(--es-muted, var(--ink-faint));
44
45
  }
45
46
 
46
47
  /* ── a style's row: the chevron, its name in its own face, the grey line ── */
@@ -65,7 +66,7 @@
65
66
  align-items: center;
66
67
  gap: var(--es-space-2, 2px);
67
68
  padding-left: var(--es-space-16, 16px);
68
- background: linear-gradient(to right, transparent 0, var(--es-panel, #ffffff) 16px);
69
+ background: linear-gradient(to right, transparent 0, var(--es-panel, var(--surface)) 16px);
69
70
  opacity: 0;
70
71
  pointer-events: none;
71
72
  transition: opacity 0.12s;
@@ -92,8 +93,8 @@
92
93
  justify-content: center;
93
94
  width: 22px;
94
95
  height: 22px;
95
- border-radius: 5px;
96
- color: var(--es-danger, #dc2626);
96
+ border-radius: var(--radius-md);
97
+ color: var(--es-danger, var(--status-danger-soft-ink));
97
98
  opacity: 0.7;
98
99
  cursor: pointer;
99
100
  transition: opacity 0.12s, background 0.12s, color 0.12s;
@@ -102,10 +103,10 @@
102
103
  .es-ts-del:hover,
103
104
  .es-ts-del:focus-visible {
104
105
  opacity: 1;
105
- background: var(--es-danger-tint, #fef2f2);
106
- color: var(--es-danger-strong, #b91c1c);
106
+ background: var(--es-danger-tint, var(--status-danger-soft));
107
+ color: var(--es-danger-strong, var(--status-danger-soft-ink));
107
108
  }
108
- .es-ts-del:focus-visible { outline: 2px solid var(--es-accent, #2563eb); outline-offset: 0; }
109
+ .es-ts-del:focus-visible { outline: 2px solid var(--es-accent, var(--accent-600, var(--submit-bg))); outline-offset: 0; }
109
110
  @media (prefers-reduced-motion: reduce) { .es-ts-del { transition: none; } }
110
111
 
111
112
  .es-ts-row {
@@ -120,7 +121,7 @@
120
121
  padding: var(--es-space-12, 12px) 0;
121
122
  cursor: pointer;
122
123
  }
123
- .es-ts-row:focus-visible { outline: 2px solid var(--es-accent, #2563eb); outline-offset: 2px; border-radius: 4px; }
124
+ .es-ts-row:focus-visible { outline: 2px solid var(--es-accent, var(--accent-600, var(--submit-bg))); outline-offset: 2px; border-radius: var(--radius-sm); }
124
125
  .es-ts-row[aria-expanded='true'] { padding-bottom: var(--es-space-8, 8px); }
125
126
 
126
127
  .es-ts-chev {
@@ -128,7 +129,7 @@
128
129
  grid-row: 1;
129
130
  width: 12px;
130
131
  height: 12px;
131
- color: var(--es-field-placeholder, #9ca3af);
132
+ color: var(--es-field-placeholder, var(--ink-faintest));
132
133
  transition: transform 0.12s ease;
133
134
  }
134
135
  .es-ts-row[aria-expanded='true'] .es-ts-chev { transform: rotate(90deg); }
@@ -141,7 +142,7 @@
141
142
  text-overflow: ellipsis;
142
143
  white-space: nowrap;
143
144
  line-height: 1.2;
144
- color: var(--es-text, #111827);
145
+ color: var(--es-text, var(--ink-strongest));
145
146
  }
146
147
  .es-ts-meta {
147
148
  grid-column: 2;
@@ -152,7 +153,7 @@
152
153
  white-space: nowrap;
153
154
  font-size: 12px;
154
155
  line-height: 1.4;
155
- color: var(--es-muted, #6b7280);
156
+ color: var(--es-muted, var(--ink-faint));
156
157
  }
157
158
 
158
159
  /* ── an open style ────────────────────────────────────────────────────────── */
@@ -174,10 +175,10 @@
174
175
  box-sizing: border-box;
175
176
  overflow: hidden;
176
177
  padding: var(--es-space-12, 12px);
177
- border: 1px solid var(--es-line, #e5e7eb);
178
- border-radius: var(--es-row-radius, 8px);
179
- background: var(--es-panel, #ffffff);
180
- color: var(--es-text, #111827);
178
+ border: 1px solid var(--es-line, var(--line));
179
+ border-radius: var(--es-row-radius, var(--radius-lg));
180
+ background: var(--es-panel, var(--surface));
181
+ color: var(--es-text, var(--ink-strongest));
181
182
  white-space: nowrap;
182
183
  -webkit-mask-image: linear-gradient(to right, #000 85%, transparent);
183
184
  mask-image: linear-gradient(to right, #000 85%, transparent);
@@ -197,7 +198,7 @@
197
198
  white-space: nowrap;
198
199
  font-size: 12px;
199
200
  font-weight: 500;
200
- color: var(--es-text-secondary, #374151);
201
+ color: var(--es-text-secondary, var(--ink));
201
202
  }
202
203
  .es-ts-top {
203
204
  display: flex;
@@ -209,39 +210,22 @@
209
210
  .es-ts-colour-read {
210
211
  flex: none;
211
212
  font: 500 12px ui-monospace, SFMono-Regular, Menlo, monospace;
212
- color: var(--es-muted, #6b7280);
213
+ color: var(--es-muted, var(--ink-faint));
213
214
  }
214
215
 
215
- /* The theme's colours in a row, then Any color — the colour window's swatches. */
216
+ /* The theme's colours in a row, then Any color: efficient-shell `ColorSwatch`es
217
+ (easel#199 step 4, harness UI-24) — their look is the shell's, only the row
218
+ is drawn here. */
216
219
  .es-ts-swatches {
217
220
  display: flex;
218
221
  flex-wrap: wrap;
219
222
  gap: var(--es-space-8, 8px);
220
223
  }
221
224
  /* Under 260 px the step down the scale keeps a six-colour theme and Any color
222
- on one line (7 × 22 + 6 × 4 = 178 of the 196 px a 220 px panel has). */
225
+ on one line (7 × 20 + 6 × 4 = 164 of the 196 px a 220 px panel has). */
223
226
  @container (width < 260px) {
224
227
  .es-ts-swatches { gap: var(--es-space-4, 4px); }
225
228
  }
226
- .es-ts-swatch {
227
- box-sizing: border-box;
228
- width: 22px;
229
- height: 22px;
230
- padding: 0;
231
- border: 0;
232
- border-radius: 6px;
233
- box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1);
234
- cursor: pointer;
235
- }
236
- .es-ts-swatch[aria-pressed='true'] {
237
- box-shadow:
238
- inset 0 0 0 1px rgb(0 0 0 / 0.1),
239
- 0 0 0 2px var(--es-panel, #ffffff),
240
- 0 0 0 4px var(--es-accent, #2563eb);
241
- }
242
- .es-ts-swatch:focus-visible { outline: 2px solid var(--es-accent, #2563eb); outline-offset: 2px; }
243
- .es-ts-swatch:disabled { cursor: default; opacity: 0.6; }
244
- .es-ts-swatch--any { background: conic-gradient(#f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); }
245
229
 
246
230
  /* B · I and Letter case: the text box's 32 px buttons (react-os-shell
247
231
  IconButton md); pressed = the light blue the toolbar's pressed marks wear. */
@@ -250,40 +234,23 @@
250
234
  flex-wrap: wrap;
251
235
  gap: var(--es-space-2, 2px);
252
236
  }
253
- .es-ts-icon {
254
- box-sizing: border-box;
255
- display: inline-flex;
256
- align-items: center;
257
- justify-content: center;
258
- width: 32px;
259
- height: 32px;
260
- padding: 0;
261
- border: 0;
262
- border-radius: 6px;
263
- background: transparent;
264
- color: var(--es-text-secondary, #374151);
265
- font: inherit;
266
- cursor: pointer;
267
- }
237
+ /* An icon is efficient-shell's IconButton look (harness UI-24): a toggle its
238
+ `IconButton`, lit from `aria-pressed`; a case radio the same look from
239
+ `iconButtonClasses({ pressed })`. What stays is the word button's width. */
268
240
  .es-ts-icon--word {
269
241
  width: auto;
270
242
  padding: 0 var(--es-space-8, 8px);
271
243
  font-size: 13px;
272
244
  font-weight: 500;
273
245
  }
274
- .es-ts-icon:hover:not(:disabled) { background: var(--es-hover, #f3f4f6); color: var(--es-text, #111827); }
275
- .es-ts-icon[aria-pressed='true'],
276
- .es-ts-icon[aria-checked='true'],
277
- .es-ts-icon[aria-pressed='true']:hover:not(:disabled),
278
- .es-ts-icon[aria-checked='true']:hover:not(:disabled) {
279
- background: var(--es-accent-tint, #eff6ff);
280
- color: var(--es-accent-text, #1d4ed8);
281
- }
282
- .es-ts-icon:focus-visible { outline: 2px solid var(--es-accent, #2563eb); outline-offset: 1px; }
283
- .es-ts-icon:disabled { opacity: 0.6; cursor: not-allowed; }
284
246
 
285
- /* The window Any color opens: under the row, in the panel's flow. */
286
- .es-ts-set > .es-pick-window { margin-top: var(--es-space-4, 4px); }
247
+ /* The window Any color opens (the shell's ColorPickerPanel): under the row, in
248
+ the panel's flow, as wide as the row — not the panel's own popover width,
249
+ which is wider than a 220 px panel's row. */
250
+ .es-ts-set > .es-pick-window {
251
+ width: auto;
252
+ margin-top: var(--es-space-4, 4px);
253
+ }
287
254
 
288
255
  /* ── "+ Add heading" · 3 / 7 ──────────────────────────────────────────────── */
289
256
 
@@ -297,13 +264,14 @@
297
264
  padding: var(--es-space-12, 12px) 0 0;
298
265
  font-size: 13px;
299
266
  font-weight: 500;
300
- color: var(--es-accent, #2563eb);
267
+ color: var(--es-accent, var(--accent-600, var(--submit-bg)));
301
268
  cursor: pointer;
302
269
  }
303
- .es-ts-add:focus-visible { outline: 2px solid var(--es-accent, #2563eb); outline-offset: 2px; border-radius: 4px; }
304
- .es-ts-add:disabled { color: var(--es-disabled, #9ca3af); cursor: not-allowed; }
270
+ .es-ts-add:focus-visible { outline: 2px solid var(--es-accent, var(--accent-600, var(--submit-bg))); outline-offset: 2px; border-radius: var(--radius-sm); }
271
+ .es-ts-add:disabled,
272
+ .es-ts-add[aria-disabled='true'] { color: var(--es-disabled, var(--ink-faintest)); cursor: not-allowed; }
305
273
  .es-ts-count {
306
274
  font-size: 12px;
307
275
  font-weight: 400;
308
- color: var(--es-field-placeholder, #9ca3af);
276
+ color: var(--es-field-placeholder, var(--ink-faintest));
309
277
  }
@@ -1,75 +1,80 @@
1
1
  import * as react from 'react';
2
- import { L as LayersTreeProps, S as SubtreeProps, a as TreeGroupLabelProps, b as TreeEmptySlotProps, c as TreeRowProps, d as TreeRowActionProps, e as TreeSeamProps } from '../types-DJDBtdB2.js';
3
- export { f as TreeRowFold, T as TreeRowMark } from '../types-DJDBtdB2.js';
4
- export { T as TreeWords } from '../words-DgHcY5qB.js';
2
+ import { L as LayersTreeProps, S as SubtreeProps, a as TreeGroupLabelProps, b as TreeEmptySlotProps, c as TreeRowProps, d as TreeRowActionProps, e as TreeSeamProps } from '../types-BqGnUVX5.js';
3
+ export { f as TreeRowFold, T as TreeRowMark } from '../types-BqGnUVX5.js';
4
+ export { T as TreeWords } from '../words-Cl9xMUYY.js';
5
5
 
6
6
  /**
7
- * The Layers tree's container. It declares the TREE's own rhythm — 10px above a
8
- * group label, 6px between rows — under the shell's names, so the settings panel
9
- * beside it keeps its own 48 / 38 (the owner picked the tree's two numbers by eye,
10
- * 2026-08-31; they are not a scale of the panel's).
7
+ * The Layers tree's container: the shell's `Tree` (`role="tree"`, its roving tab
8
+ * stop and arrow keys; harness UI-24). `es-tree` stays on it as the hook
9
+ * `screen/lib/puck/tree-reveal` scrolls, and the scroll box `tree.css` keeps.
11
10
  */
12
- declare function LayersTree({ className, children, rootProps }: LayersTreeProps): react.JSX.Element;
13
- /** A quiet uppercase label over a run of rows — "Header", "Body", "Footer". */
11
+ declare function LayersTree({ className, children, rootProps, ariaLabel, words }: LayersTreeProps): react.JSX.Element;
12
+ /** A quiet uppercase label over a run of rows — the shell's `TreeGroupLabel`. */
14
13
  declare function TreeGroupLabel({ children }: TreeGroupLabelProps): react.JSX.Element;
15
14
  /**
16
- * The rows one level down. THE ONLY THING IN THE TREE THAT SAYS DEPTH: 16px of
17
- * indent and a hairline down the left that runs the height of the group, so a
18
- * child eight rows down still shows which parent it is under.
15
+ * The rows one level down: the shell's `TreeGroup` (`role="group"`, the indent
16
+ * and the hairline — the only thing in the tree that says depth), and one more
17
+ * level for every `TreeRow` inside it.
19
18
  */
20
19
  declare function Subtree({ children }: SubtreeProps): react.JSX.Element;
21
20
 
22
21
  /** What a draggable row says after 0.7 s on it. */
23
22
  declare const TREE_DRAG_HINT: string;
24
23
  /**
25
- * ONE row, at every depth (the owner's "One Ladder", 2026-09-04).
24
+ * ONE row, at every depth: the shell's `TreeRow` (`role="treeitem"`; harness
25
+ * UI-24, efficient-easel#199). The shell draws the row — caret, glyph, name,
26
+ * the thing's own first words, the badge, the actions over the end of the name,
27
+ * the drop line, the selected, muted and dragging looks — and owns its keys.
28
+ * This keeps the props both editors already pass:
26
29
  *
27
- * Lifted from the website editor's `.sf-row` (efficient-storefront). Left to right:
28
- * the drag handle (out of flow, in the row's left padding), the caret — or a
29
- * spacer holding its column open, so every glyph below lines up whether its row
30
- * folds or not — the type glyph, then the name box. The actions are laid over
31
- * the END of the name rather than holding space beside it; that choice won the
32
- * name 138px → 223px of room in the website tree.
30
+ * name → label · hidden → muted · fold → expanded / onToggle ·
31
+ * nameSlot → rename · the depth from the nearest `Subtree` → aria-level.
33
32
  *
34
- * Depth is said by `Subtree` and by nothing here. A row's look never changes
35
- * with how deep it sits.
33
+ * What the shell has no piece for is composed here and kept small:
34
+ * · `marks`, `trailing` and `children` ride in the label, after the name —
35
+ * a mark is a named picture (`role="img"`) with the shell's `Tooltip`;
36
+ * · a `draggable` row is the shell's draggable row (efficient-shell
37
+ * 4.165.0): its grip on hover and focus, its hint in the shell's Tooltip
38
+ * and the grab cursor — this file used to draw them through tree.css. The
39
+ * drag itself, and the Alt+Arrow keys that move a row, stay
40
+ * `efficient-easel/drag`'s (its `rowProps`), said as `aria-keyshortcuts`;
41
+ * · `es-tree-row` and its `is-*` state classes stay on the row, and
42
+ * `es-tree-name` round the name — hooks, not looks: the screen's reveal
43
+ * finds `.es-tree-row.is-selected`, the drag lifts `is-lifting`, and hosts
44
+ * find a row's name.
36
45
  *
37
- * Hook-free and controlled: selection, folding, hiding and dragging all belong
38
- * to the host. So are its words: the drag hint and the caret's come in as
39
- * `words` (./words), English when left out — a hook-free row reads no provider.
46
+ * ONE CLICK, ONE SELECTION. The shell row selects on its own click. A row that
47
+ * passes `onSelect` AND a `rowProps.onClick` (the hosts' "row click", which
48
+ * selected wherever the old name button did not) is selected by that onClick
49
+ * alone on a click, and by `onSelect` from the keyboard (Enter, Space).
40
50
  */
41
- declare function TreeRow({ icon, name, preview, selected, hidden, draggable, dragHint, dragging, drop, fold, handle, actions, nameSlot, onSelect, marks, badge, trailing, children, rowProps, words, }: TreeRowProps): react.JSX.Element;
51
+ declare function TreeRow({ icon, name, preview, selected, hidden, draggable, dragHint, dragging, drop, fold, actions, nameSlot, onSelect, marks, badge, trailing, children, rowProps, level, words, }: TreeRowProps): react.JSX.Element;
42
52
  /**
43
- * A 22px action over the end of a row's name — delete (red) or show / hide.
44
- * Pressing it never selects the row underneath.
53
+ * An action over the end of a row's name — delete (the danger tone) or show /
54
+ * hide, or any other: the shell's `IconButton` with its `Tooltip`. Pressing it
55
+ * never selects the row underneath.
45
56
  */
46
57
  declare function TreeRowAction({ kind, label, onClick, pressed, disabled, children }: TreeRowActionProps): react.JSX.Element;
47
58
  /**
48
59
  * The gap between two rows, as a place (0.74.0): a drop between them lands here,
49
- * and — when the host offers it — a "+" adds here. It takes exactly the space
50
- * the gap already had, so a list reads the same with seams or without.
60
+ * and — when the host offers it — a "+" adds here. The shell's `TreeSeam`
61
+ * since efficient-shell 4.165.0 (harness UI-24): it takes exactly the room the
62
+ * gap already had, draws the drop line and the "+" (named by its Tooltip).
63
+ * This keeps the props both editors pass — `onAdd` is the shell's `onInsert`.
51
64
  *
52
65
  * ⚠️ NOT FOR AN EMPTY LIST. A seam hands its height back to the rows either
53
- * side of it; alone in a list there are none, and what is left is a strip a
54
- * few pixels tall with nothing drawn in it. Draw `TreeEmptySlot` there.
66
+ * side of it; alone in a list there are none. Draw `TreeEmptySlot` there.
55
67
  */
56
68
  declare function TreeSeam({ drop, onAdd, label, seamProps }: TreeSeamProps): react.JSX.Element;
57
69
  /**
58
- * AN EMPTY LIST, AS A PLACE (second host, 2026-10-06): where a slot holds
59
- * nothing yet — a column with no blocks — a dashed box the size of a row. A
60
- * drop on it lands in the slot, and when the host offers it the box is a
61
- * button that adds there. While a drag may land it lights up and says so.
62
- *
63
- * Until then an empty list was drawn as its one seam, and a seam is a gap: a
64
- * drop aimed at "into this empty column" missed its few pixels and landed on
65
- * whatever row or seam was really under the pointer. The canvas has always
66
- * drawn the same idea as its "+ Add block" cell (`efficient-easel/drag`).
67
- *
68
- * Lifted from the campaign designer's `.cd-tree-add` (efficient-admin-portal
69
- * `EmailOutline`), which had drawn one of its own. Hook-free and controlled,
70
- * like every part of the tree: the drag is `efficient-easel/drag`'s —
70
+ * AN EMPTY LIST, AS A PLACE: the shell's `TreeEmptySlot` — a dashed box the
71
+ * size of a row that takes the drop and, with `onAdd`, is a button that adds
72
+ * there. The drag is `efficient-easel/drag`'s:
71
73
  *
72
74
  * <TreeEmptySlot {...drag.seam({ place: { ...list, index: 0 } })} onAdd={…} />
75
+ *
76
+ * Its words at rest are the tree's (`words.addBlock` / `words.emptySlot`); while
77
+ * a drag is over it, it says the shell's own "Drop here".
73
78
  */
74
79
  declare function TreeEmptySlot({ drop, onAdd, label, seamProps, words }: TreeEmptySlotProps): react.JSX.Element;
75
80
 
@@ -1 +1 @@
1
- export{LayersTree,Subtree,TREE_DRAG_HINT,TreeEmptySlot,TreeGroupLabel,TreeRow,TreeRowAction,TreeSeam}from"../chunk-ZFDCDJNZ.js";import"../chunk-3EDSDPIP.js";import"../chunk-L5KW4HG5.js";
1
+ export{LayersTree,Subtree,TREE_DRAG_HINT,TreeEmptySlot,TreeGroupLabel,TreeRow,TreeRowAction,TreeSeam}from"../chunk-XWR5YVA7.js";import"../chunk-K56YDHYQ.js";