efficient-web-builder 13.0.0 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 13.0.1 - 2026-10-15
4
+
5
+ - **A settings band with no row in it is not drawn** (JJ's panel pin,
6
+ approved by GG 2026-10-14). Process Steps drew an empty "Header" band:
7
+ its three text rows (step number, title, description) are in the Text
8
+ band, and its `boxes` slot draws nothing, so the band had a title and
9
+ nothing under it. `bandIsDropped` (`lib/puck/panel-bands`) now drops a
10
+ band with 0 shown rows, as well as §2b.1's band of one labelled row; its
11
+ rows stand alone at that place, as they do for §2b.1. A band with one
12
+ unlabelled row still keeps its band. No data change. Across the 53
13
+ tabbed section panels (default props), 1 band was empty before and 0
14
+ are now.
15
+ - Dev range: `efficient-easel ^7.2.0`, so the guards run on 7.2.0. The
16
+ peer range (`^7.0.4`) is unchanged.
17
+ - Guard: `scripts/test-panel-one-level-bands.tsx` §4 holds the 0-row
18
+ branches; new §6 draws every tabbed section panel as the section screen
19
+ draws it and fails on any band over 0 shown rows.
20
+
3
21
  ## 13.0.0 - 2026-10-14
4
22
 
5
23
  **Double-click the words on the canvas to type them where they are** (Lewis 2026-10-14, for Victor; card [DESIGN] Typing On The Canvas). A major only because the `efficient-easel` and `efficient-shell` peer ranges are narrowed (harness CI-3). Also: **the Pages panel's delete-with-Undo now uses the shell's one copy, `toast.undoable`**.
@@ -1 +1 @@
1
- "use client";import{jsx as S}from"react/jsx-runtime";import{useLayoutEffect as O,useMemo as B,useRef as k,useState as T}from"react";import{useSelectedFields as D}from"efficient-easel/easel";import{Inspector as K,planFields as x}from"efficient-easel/fields";import{BUCKET_ICONS as j,entriesHiddenForTab as v}from"../lib/puck/controls.js";import{BUCKETS as L}from"../lib/puck/field-groups.js";import{say as q}from"../lib/editor-words.js";import{bandIsDropped as R,droppedBands as U,sameKeys as X,TEXT_BAND_KEY as F,TEXT_BAND_TITLE as G,withoutBands as H}from"../lib/puck/panel-bands.js";const E=new Map,f=new Set;function P(n,r){const s=new Map;for(const l of n.querySelectorAll(".es-insp-row[data-field]"))s.set(l.getAttribute("data-field")??"",l);const o=[];for(const[l,m]of r)o.push({key:l,rows:m.map(p=>{const d=s.get(p),c=!!d&&[...d.children].some(w=>!w.hidden),i=d?.querySelector(".es-field-label, .es-list-label")?.textContent?.trim();return{shown:c,labelled:c&&!!i}})});return o}const Y=Object.fromEntries(L.map(n=>{const r=j[n];return[n,S(r,{},n)]}));function te({entries:n,entryCount:r=0}){const{id:s,fields:o,values:l,readOnly:m,onChange:p}=D(),[d,c]=T(()=>new Set(f)),[i,w]=T(()=>new Set),g=k(null),C=B(()=>{const e=new Map;for(const t of x(o).rows){if(!t.fold)continue;const a=e.get(t.fold.key)??[];a.push(t.name),e.set(t.fold.key,a)}return e},[o]);O(()=>{const e=g.current?.parentElement;if(!e)return;const t=new Set(U(P(e,C)));w(a=>X(a,t)?a:t)});const _=B(()=>H(o,i),[o,i]),A={key:F,rows:Array.from({length:r},()=>({shown:!0,labelled:!0}))},I=r>0&&!R(A)?{key:F,title:G}:void 0,[b,M]=T(()=>E.get(s)),h=E.get(s),u=x(o).buckets,y=h&&u.includes(h)?h:b&&u.includes(b)?b:u[0],N=y===void 0||v(u,y)!==!0;return S(K,{fields:_,values:l,onChange:p,readOnly:m,tab:y,onTab:e=>{E.set(s,e),M(e)},tabIcons:Y,idPrefix:s,ariaLabel:q("Section settings"),lead:N?n:null,leadFold:I,closedFolds:d,onFold:(e,t)=>{t?f.delete(e):f.add(e),c(new Set(f))},children:S("span",{ref:g,hidden:!0})})}export{te as SiteFields,Y as TAB_ICONS};
1
+ "use client";import{jsx as S}from"react/jsx-runtime";import{useLayoutEffect as O,useMemo as B,useRef as k,useState as T}from"react";import{useSelectedFields as D}from"efficient-easel/easel";import{Inspector as K,planFields as x}from"efficient-easel/fields";import{BUCKET_ICONS as j,entriesHiddenForTab as v}from"../lib/puck/controls.js";import{BUCKETS as L}from"../lib/puck/field-groups.js";import{say as q}from"../lib/editor-words.js";import{bandIsDropped as R,droppedBands as U,sameKeys as X,TEXT_BAND_KEY as C,TEXT_BAND_TITLE as G,withoutBands as H}from"../lib/puck/panel-bands.js";const E=new Map,f=new Set;function P(n,l){const s=new Map;for(const r of n.querySelectorAll(".es-insp-row[data-field]"))s.set(r.getAttribute("data-field")??"",r);const o=[];for(const[r,m]of l)o.push({key:r,rows:m.map(p=>{const d=s.get(p),c=!!d&&[...d.children].some(w=>!w.hidden),i=d?.querySelector(".es-field-label, .es-list-label")?.textContent?.trim();return{shown:c,labelled:c&&!!i}})});return o}const Y=Object.fromEntries(L.map(n=>{const l=j[n];return[n,S(l,{},n)]}));function te({entries:n,entryCount:l=0}){const{id:s,fields:o,values:r,readOnly:m,onChange:p}=D(),[d,c]=T(()=>new Set(f)),[i,w]=T(()=>new Set),g=k(null),F=B(()=>{const e=new Map;for(const t of x(o).rows){if(!t.fold)continue;const a=e.get(t.fold.key)??[];a.push(t.name),e.set(t.fold.key,a)}return e},[o]);O(()=>{const e=g.current?.parentElement;if(!e)return;const t=new Set(U(P(e,F)));w(a=>X(a,t)?a:t)});const _=B(()=>H(o,i),[o,i]),A={key:C,rows:Array.from({length:l},()=>({shown:!0,labelled:!0}))},I=R(A)?void 0:{key:C,title:G},[b,M]=T(()=>E.get(s)),y=E.get(s),u=x(o).buckets,h=y&&u.includes(y)?y:b&&u.includes(b)?b:u[0],N=h===void 0||v(u,h)!==!0;return S(K,{fields:_,values:r,onChange:p,readOnly:m,tab:h,onTab:e=>{E.set(s,e),M(e)},tabIcons:Y,idPrefix:s,ariaLabel:q("Section settings"),lead:N?n:null,leadFold:I,closedFolds:d,onFold:(e,t)=>{t?f.delete(e):f.add(e),c(new Set(f))},children:S("span",{ref:g,hidden:!0})})}export{te as SiteFields,Y as TAB_ICONS};
@@ -1 +1 @@
1
- const f=" text",u="Text";function s(t){const e=t.rows.filter(o=>o.shown);return e.length===1&&e[0].labelled}function i(t){return t.filter(s).map(e=>e.key)}function l(t,e){let o=null;for(const r of e){const n=t[r];!n||n.marker!==!0||typeof n.fold!="string"||(o??={...t},o[r]={...n,fold:!1})}return o??t}function p(t,e){if(t.size!==e.size)return!1;for(const o of t)if(!e.has(o))return!1;return!0}export{f as TEXT_BAND_KEY,u as TEXT_BAND_TITLE,s as bandIsDropped,i as droppedBands,p as sameKeys,l as withoutBands};
1
+ const f=" text",u="Text";function s(t){const e=t.rows.filter(n=>n.shown);return e.length===0||e.length===1&&e[0].labelled}function l(t){return t.filter(s).map(e=>e.key)}function i(t,e){let n=null;for(const r of e){const o=t[r];!o||o.marker!==!0||typeof o.fold!="string"||(n??={...t},n[r]={...o,fold:!1})}return n??t}function p(t,e){if(t.size!==e.size)return!1;for(const n of t)if(!e.has(n))return!1;return!0}export{f as TEXT_BAND_KEY,u as TEXT_BAND_TITLE,s as bandIsDropped,l as droppedBands,p as sameKeys,i as withoutBands};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "13.0.0",
3
+ "version": "13.0.1",
4
4
  "description": "The EFFICIENT website builder: the website editor, the general sections and the renderer that draws them, compiled. Hostable by any EFFICIENT product; nothing here imports a host.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Efficient Pty Ltd",
@@ -59,7 +59,7 @@
59
59
  "@types/node": "^20",
60
60
  "@types/react": "^19",
61
61
  "@types/react-dom": "^19",
62
- "efficient-easel": "^7.0.4",
62
+ "efficient-easel": "^7.2.0",
63
63
  "efficient-shell": "^7.29.0",
64
64
  "esbuild": "^0.28.0",
65
65
  "happy-dom": "^20.14.5",