efficient-web-builder 24.0.0 → 25.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.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 25.0.0 - 2026-10-19
|
|
6
|
+
|
|
7
|
+
**The letter cases are one code, easel's (#159), and the builder runs on efficient-shell 8** (SSOT cleanup, GG 2026-10-17; keep editor code off shopper pages, efficient-shell #553). Every site draws what it drew. A MAJOR for hosts, for the two reasons below.
|
|
8
|
+
|
|
9
|
+
### Changed for hosts (breaking)
|
|
10
|
+
|
|
11
|
+
- **BREAKING: `efficient-easel` peer and dev range `^13.2.0`** (it was `^13.1.1`). The case code comes from `efficient-easel/draw`, which carries it since 13.2.0 (efficient-easel #296): a published page may take easel only through `render`, `draw` and `draw/client`. 13.2.0 also accepts efficient-shell 8 and names its render group in its `package.json` (`entryGroups.render`).
|
|
12
|
+
- **BREAKING: `PART_CASES` and `PartCase` are gone from `render/lib/puck/part-styles`.** They were second names for easel's `TEXT_STYLE_CASES` and `TextStyleCase`; import those from `efficient-easel/draw` (no host imports them today).
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- The efficient-shell peer range is `^7.75.0 || ^8.0.0`. Shell 8 moves its icon maps to `efficient-shell/icons/sets` and makes every drawing a module of its own; the builder imports drawings by name and no map (24.0.0), so nothing it uses moves. The dev copy is `^8.0.0`, so the build and the guards run on 8.
|
|
17
|
+
- `scripts/entry-sides.mjs` reads the easel entries a render module may import from that field. It no longer writes the 11 entries out, so the list has one home: easel's. The build fails if the installed easel names no render group.
|
|
18
|
+
- `partCaseTransform` / `partCaseOfTransform` read easel's `textStyleCaseCss` / `textStyleCaseOfCss`. Their own `CASE_TRANSFORM` table is gone, and so is `site-text-styles.ts`'s `CASE_CSS`. The CSS each case draws is the same.
|
|
19
|
+
|
|
20
|
+
### Guards
|
|
21
|
+
|
|
22
|
+
- `scripts/test-one-text-case-code.ts`: the four cases turn into their CSS and back, and no file in `src/` spells a case list, a case-to-CSS table, `PART_CASES` or `PartCase` again.
|
|
23
|
+
- `test-render-closure`: on shell 8 the looks map lives in `efficient-shell/icons/sets`; a shopper file that imports it is a finding, and the byte ceiling now reads the map's own chunk (the one `icons/looks/map.js` re-exports), not `icons/efficient-looks`, which only re-exports since 8.0.0.
|
|
24
|
+
- `test-clear-formatting`: the shell toolbar's buttons keep the field's focus through one named handler in shell 8's build (`onMouseDown:i`, `i=e=>e.preventDefault()`); the check reads both forms, and a handler that does not prevent the default still fails.
|
|
25
|
+
- `test-image-copies-sized`: shell 8.1.0's contract names the live copies host, so "no host" is now `host: null` set on purpose, and a new §2b checks that a page asks for copies by default.
|
|
26
|
+
- `test-corners-and-grid-from-the-shell` no longer checks the shell range a second time (`test-shell-peer-range` holds it).
|
|
27
|
+
|
|
28
|
+
### For hosts
|
|
29
|
+
|
|
30
|
+
- A host may move to efficient-shell 8 with this release, and moves its efficient-easel to 13.2.0. A host on shell 7.75 or later needs no other change.
|
|
31
|
+
- ⚠️ **efficient-shell 8.1.0 turns image copies on**: every image the builder draws from an upload asks for a resized copy from the live copies host. Before a host takes shell 8.1.0, its pages must allow that host in `img-src` (efficient-shell 8.1.0's CHANGELOG). Shell 8.0.x still hands the original back.
|
|
32
|
+
|
|
5
33
|
## 24.0.0 - 2026-10-19
|
|
6
34
|
|
|
7
35
|
**Three sides: render, format and editor, and the package exports them and nothing else** (keep editor code off shopper pages, PR 1c; plan approved by JJ, `doc/adr/0005`). A published page draws from the `render` side, which cannot reach the editor. A MAJOR: every import path a host writes moves.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PartWeight } from "../../render/lib/puck/part-styles.js";
|
|
2
|
+
import type { TextStyleCase } from "efficient-easel/draw";
|
|
2
3
|
export declare function WeightGlyph({ weight }: {
|
|
3
4
|
weight?: PartWeight;
|
|
4
5
|
}): import("react").JSX.Element;
|
|
5
6
|
export declare function CaseGlyph({ letterCase }: {
|
|
6
|
-
letterCase?:
|
|
7
|
+
letterCase?: TextStyleCase;
|
|
7
8
|
}): import("react").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{FONT_OPTIONS as
|
|
2
|
-
`)}const Q={"heading-1":"headingLarge","heading-2":"headingMedium","heading-3":"headingSmall","body-1":"body","body-5":"label"};function
|
|
1
|
+
import{textStyleCaseCss as D}from"efficient-easel/draw";import{FONT_OPTIONS as J,normalizeFonts as F}from"../../format/lib/fonts.js";import{PART_PHONE_MAX_CSS as B,partSpacingOf as G}from"../../render/lib/puck/part-styles.js";import{compressionMetrics as U,headingTypographyFromRow as W,normalizeHeadingCompression as C,normalizeSizes as I}from"../../format/lib/theme.js";const H=e=>e==="sentence"?"none":void 0,h=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,_=e=>typeof e=="string"&&e?e:void 0,M=["font","color","size","sizePhone","weight","italic","lineHeight","letterSpacing","paragraphSpacing","letterCase","largestSize"];function p(e){const i={};for(const n of M)e[n]!==void 0&&(i[n]=e[n]);return i}function O(e,i){const{auto:n,...t}=e,a=new Set(i??[]),s=M.filter(o=>a.has(o)&&e.values[o]===void 0);return s.length?{...t,auto:s}:t}function w(e){const i=e.fonts,n=e.sizes,t=e.typography,a=U(e.compression),s=(l,r)=>({id:`heading-${l}`,kind:"heading",name:`Heading ${l}`,values:p(r)}),o=(l,r={})=>({id:`body-${l}`,kind:"body",name:`Body ${l}`,values:p(r)});return[s(1,{font:_(i.heading),size:h(n.headingLarge),weight:h(t.weight),lineHeight:a.lineHeight,letterSpacing:a.letterSpacing,letterCase:H(t.case),largestSize:h(t.maxPx)}),s(2,{font:_(i.heading2),size:h(n.headingMedium),weight:h(t.weight2),lineHeight:a.lineHeight,letterSpacing:a.letterSpacing,letterCase:H(t.case2)}),s(3,{font:_(i.heading3),size:h(n.headingSmall),weight:h(t.weight3),lineHeight:a.lineHeight,letterSpacing:a.letterSpacing,letterCase:H(t.case3)}),o(1,{font:_(i.body),size:h(n.body)}),o(2),o(3),o(4),o(5,{font:_(i.label),size:h(n.label)})]}function $(e){return Array.isArray(e)&&e.every(n=>n&&typeof n=="object"&&typeof n.id=="string"&&(n.kind==="heading"||n.kind==="body")&&typeof n.name=="string")?e.map(n=>O({...n,values:p(n.values??{})},Array.isArray(n.auto)?n.auto:void 0)):null}function ae(e){return $(e)??[]}function T(e,i){const n=w(i),t=$(e);return t?t.map(a=>{const s={...P(n,a.id)};for(const o of a.auto??[])delete s[o];return{...a,values:p({...s,...a.values})}}):n}const P=(e,i)=>e.find(n=>n.id===i)?.values??{},E=["heading-1","heading-2","heading-3"];function oe({saved:e,old:i,cur:n,next:t,sizeOf:a}){const s=w(i),o=$(e)??s.map(d=>({...d,values:{}})),l=T(o,i),r=[],y=t.map(d=>{const g=n.find(u=>u.id===d.id),S=o.find(u=>u.id===d.id);if(!g||!S)return X([d],a)[0];const c={...S.values},z=new Set(S.auto??[]),v=d.values,N=g.values,A=[...new Set([...Object.keys(v),...Object.keys(N)])].filter(u=>JSON.stringify(v[u])!==JSON.stringify(N[u]));A.sort((u,m)=>+(u==="letterSpacing")-+(m==="letterSpacing"));for(const u of A){const m=u==="lineSpacing"?"lineHeight":u,k=v[u];if(k===void 0){delete c[m],P(s,d.id)[m]!==void 0&&(r.push([d.id,m]),z.add(m));continue}if(z.delete(m),u==="lineSpacing")c.lineHeight=x(k/100,3);else if(u==="letterSpacing"){const R=l.find(V=>V.id===d.id),j=a({...d,values:p({...R?.values??{},...c})});c.letterSpacing=j?x(k/j,4):0}else c[m]=k}return O({id:d.id,kind:d.kind,name:d.name,values:p(c)},z)});let f=i.compression;if(r.some(([d,g])=>(g==="lineHeight"||g==="letterSpacing")&&E.includes(d))&&C(f)!=="normal"){for(const d of E){const g=y.find(c=>c.id===d);if(!g)continue;const S={...g.values};for(const c of["lineHeight","letterSpacing"])r.some(([z,v])=>z===d&&v===c)||S[c]===void 0&&!(g.auto??[]).includes(c)&&(S[c]=P(s,d)[c]);g.values=p(S)}f="normal"}return{saved:y,old:{...i,compression:f}}}function se(e,i){const n={text_styles:e.saved};return e.old.compression!==i.compression&&(n.heading_compression=C(e.old.compression)),n}const x=(e,i)=>Number(e.toFixed(i));function re(e,i){return e.map(n=>{const{lineHeight:t,letterSpacing:a,...s}=n.values,o={...s};return t!==void 0&&(o.lineSpacing=x(t*100,1)),a!==void 0&&(o.letterSpacing=x(a*i(n),2)),{id:n.id,kind:n.kind,name:n.name,values:o}})}function X(e,i){return e.map(n=>{const{lineSpacing:t,letterSpacing:a,...s}=n.values,o={id:n.id,kind:n.kind,name:n.name,values:p({...s})},l={...o.values};if(t!==void 0&&(l.lineHeight=x(t/100,3)),a!==void 0){const r=i({...o,values:{...o.values}});l.letterSpacing=r?x(a/r,4):0}return{...o,values:p(l)}})}function de(e){const i={fonts:F({heading:e.heading_font??void 0,heading2:e.heading_2_font??void 0,heading3:e.heading_3_font??void 0,body:e.body_font??void 0,accent:e.accent_font??void 0,label:e.label_font??void 0}),sizes:I({headingLarge:e.heading_size_large_px,headingMedium:e.heading_size_medium_px,headingSmall:e.heading_size_small_px,accent:e.accent_size_px,body:e.body_size_px,label:e.label_size_px}),compression:C(e.heading_compression),typography:W(e)},n=e.text_styles??null,t=Array.isArray(n)?L(T(n,i),i):i;return{fonts:F(t.fonts),sizes:I(t.sizes),compression:C(t.compression),typography:t.typography,textStyles:n}}function L(e,i){const n=d=>e.find(g=>g.id===d)?.values??{},t=n("heading-1"),a=n("heading-2"),s=n("heading-3"),o=n("body-1"),l=n("body-5"),r=i.fonts,y=i.sizes,f=i.typography,b=d=>d==="none"?"sentence":"authored";return{fonts:{...r,heading:t.font??r.heading,heading2:a.font??t.font??r.heading2,heading3:s.font??t.font??r.heading3,body:o.font??r.body,label:l.font??r.label},sizes:{...y,headingLarge:t.size??null,headingMedium:a.size??null,headingSmall:s.size??null,body:o.size??null,label:l.size??null},compression:i.compression,typography:{...f,case:b(t.letterCase),weight:t.weight??null,maxPx:t.largestSize??null,weight2:a.weight??null,weight3:s.weight??null,case2:b(a.letterCase),case3:b(s.letterCase)}}}function le(e){const i=$(e.textStyles);if(!i||i.every(a=>Object.keys(a.values).length===0&&!a.auto))return e;const n={fonts:e.fonts??{},sizes:e.sizes??{},compression:String(e.headingCompression??"normal"),typography:e.headingTypography??{}},t=L(T(i,n),n);return{...e,fonts:t.fonts,sizes:t.sizes,headingCompression:t.compression,headingTypography:t.typography}}function Z(e){switch(e.id){case"heading-1":return"font-display";case"heading-2":return"font-heading2";case"heading-3":return"font-heading3";case"body-1":return"font-body";case"body-5":return"font-mono";default:return`font-${e.id}`}}function q(e){return e==="accent"?"var(--accent)":e==="text"?"var(--fg)":e==="labels"?"var(--fg-dim)":/^#[0-9a-f]{6}$/i.test(e)?e:null}function K(e){const i=":is([data-sf-bullet], [data-sf-number])";return[`${e} br:not(br + br) { display: block; content: ""; margin-top: var(--sf-part-para) }`,`${e} ${i}:not(:first-child) { margin-top: var(--sf-part-para) }`,`${e} ${i}:not(:last-child) { margin-bottom: var(--sf-part-para) }`]}function ce(e){const i=[];for(const n of e){const t=n.values,a=`.${Z(n)}`,s=[],o=t.font!==void 0?J.find(f=>f.key===t.font)?.cssVar:void 0;if(o&&s.push(`font-family: var(${o})`),t.size!==void 0){const f=t.largestSize!==void 0?Math.min(t.size,t.largestSize):t.size;s.push(`font-size: ${f}px`)}const l=t.color!==void 0?q(t.color):null;l&&s.push(`color: ${l}`),t.italic===!0&&s.push("font-style: italic"),t.weight!==void 0&&s.push(`font-weight: ${t.weight}`);const r=[];t.lineHeight!==void 0&&r.push(`line-height: ${t.lineHeight}`),t.letterSpacing!==void 0&&r.push(`letter-spacing: ${t.letterSpacing}em`),n.kind==="body"&&s.push(...r);const y=D(t.letterCase);if(y&&s.push(`text-transform: ${y}`),t.paragraphSpacing&&s.push(`--sf-part-para: ${t.paragraphSpacing}px`),s.length&&i.push(`${a} { ${s.join("; ")} }`),n.kind==="heading"&&r.length&&i.push(`${a}, ${a}:is(h1, h2, h3, h4) { ${r.join("; ")} }`),t.paragraphSpacing&&i.push(...K(a)),t.sizePhone!==void 0){const f=Q[n.id],b=[`${a} { font-size: ${t.sizePhone}px }`];f&&b.push(`.sf-themed-content { --size-${f}: ${t.sizePhone}px !important }`),i.push(`@media ${B} { ${b.join(" ")} }`)}}return i.join(`
|
|
2
|
+
`)}const Q={"heading-1":"headingLarge","heading-2":"headingMedium","heading-3":"headingSmall","body-1":"body","body-5":"label"};function ue(e){return e!==!0&&e!==!1?"":`em.text-accent { font-style: ${e?"italic":"normal"} }`}function fe(e){switch(e){case"heading":return"heading-1";case"heading2":return"heading-2";case"heading3":return"heading-3";case"body":return"body-1";case"label":return"body-5";default:return}}function Y(e){const i=G(e);return p({font:e.font,color:e.color,size:e.size,weight:e.weight,italic:e.italic,lineHeight:i.lineHeight,letterSpacing:i.letterSpacingEm,paragraphSpacing:e.paragraphSpacing,letterCase:e.case})}function ge(e){return Object.keys(Y(e)).length>0}function pe({saved:e,old:i,styleId:n,values:t}){return{saved:($(e)??w(i).map(o=>({...o,values:{}}))).map(o=>o.id===n?O({...o,values:p({...o.values,...t})},o.auto):o),old:i}}function he(e){const i=e.filter(n=>n.kind==="body").map(n=>Number(/^body-(\d+)$/.exec(n.id)?.[1])).filter(n=>Number.isInteger(n)&&n>0);return i.length?`body-${Math.max(...i)}`:"body-1"}export{ue as accentItalicCss,oe as applyListChange,he as eyebrowStyleId,Z as faceClassOf,X as fromPanelStyles,ge as hasStyleChange,se as listChangePatch,Y as partStyleToTextStyleValues,pe as pushIntoStyle,T as resolveTextStyles,de as siteTextFromRow,ae as storedTextStyles,fe as styleIdOfRole,ce as textStylesCss,w as textStylesFromOld,L as textStylesToOld,le as themeWithTextStyles,re as toPanelStyles};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import { type TextStyleCase } from "efficient-easel/draw";
|
|
1
2
|
import { type FontRole } from "../../../format/lib/fonts.js";
|
|
2
3
|
import type { PartEl } from "../../../editor/lib/puck/part-anchors.js";
|
|
3
4
|
import { type PartNeedle } from "./text-parts.js";
|
|
4
5
|
export declare const PART_STYLES_PROP = "_partStyles";
|
|
5
6
|
export declare const PART_STYLED_ATTR = "data-sf-part-styled";
|
|
6
|
-
export declare const PART_CASES: readonly ["none", "upper", "capitalize", "lower"];
|
|
7
|
-
export type PartCase = (typeof PART_CASES)[number];
|
|
8
7
|
export declare const PART_WEIGHTS: readonly [400, 500, 600, 700];
|
|
9
8
|
export type PartWeight = (typeof PART_WEIGHTS)[number];
|
|
10
9
|
export declare const PART_ALIGNS: readonly ["left", "center", "right", "justify"];
|
|
@@ -62,7 +61,7 @@ export type PartStyle = {
|
|
|
62
61
|
lineHeight?: number;
|
|
63
62
|
letterSpacing?: number;
|
|
64
63
|
paragraphSpacing?: number;
|
|
65
|
-
case?:
|
|
64
|
+
case?: TextStyleCase;
|
|
66
65
|
align?: PartAlign;
|
|
67
66
|
padding?: number;
|
|
68
67
|
width?: number;
|
|
@@ -77,7 +76,7 @@ export type PartStyleBase = {
|
|
|
77
76
|
lineRatio: number;
|
|
78
77
|
letterEm: number;
|
|
79
78
|
align: PartAlign;
|
|
80
|
-
case:
|
|
79
|
+
case: TextStyleCase;
|
|
81
80
|
paddingPx: number;
|
|
82
81
|
widthPx: number;
|
|
83
82
|
};
|
|
@@ -95,8 +94,8 @@ export declare function readPartStyle(props: Record<string, unknown> | undefined
|
|
|
95
94
|
export declare function partStyleCount(props: Record<string, unknown> | undefined, partKey: string): number;
|
|
96
95
|
export declare function propsWithPartStyleValue<K extends keyof PartStyle>(props: Record<string, unknown>, partKey: string, prop: K, value: PartStyle[K] | null): Record<string, unknown>;
|
|
97
96
|
export declare function propsWithoutPartStyle(props: Record<string, unknown>, partKey: string): Record<string, unknown>;
|
|
98
|
-
export declare function partCaseOfTransform(transform: string | null | undefined):
|
|
99
|
-
export declare function partCaseTransform(value:
|
|
97
|
+
export declare function partCaseOfTransform(transform: string | null | undefined): TextStyleCase;
|
|
98
|
+
export declare function partCaseTransform(value: TextStyleCase | undefined): string;
|
|
100
99
|
export declare function partSpacingOf(style: PartStyle): {
|
|
101
100
|
lineHeight?: number;
|
|
102
101
|
letterSpacingEm?: number;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{FONT_OPTIONS as
|
|
2
|
-
`)}function Kt(t){const e=`var(${S})`,n=":is([data-sf-bullet], [data-sf-number])";return[`${t} br:not(br + br) { display: block; content: ""; margin-top: ${e} }`,`${t} ${n}:not(:first-child) { margin-top: ${e} }`,`${t} ${n}:not(:last-child) { margin-bottom: ${e} }`]}const Gt=t=>t.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`);function
|
|
1
|
+
import{textStyleCaseCss as B,textStyleCaseOfCss as V}from"efficient-easel/draw";import{FONT_OPTIONS as Y,FONT_ROLES as I,fontOption as Z,SIZE_STEP_OF_ROLE as v}from"../../../format/lib/fonts.js";import{encodePartKey as q}from"../../../format/lib/puck/part-key.js";import{decodePartId as $,normalizePartText as b}from"./text-parts.js";import{COLOUR_TOKEN as M}from"../../../format/lib/word-styles.js";const E="_partStyles",J="data-sf-part-styled",Q=[400,500,600,700],H=["left","center","right","justify"],F=5,z=1e3,tt=-5,et=10,nt=0,rt=64,ot=2,it=120,T=1280,st=10,L={size:{min:F,max:z,step:1},sizePhone:{min:F,max:z,step:1},padding:{min:nt,max:rt,step:ot},width:{min:it,max:T,step:st}},at=.05,ct=.01,lt=["line","letter"],ft=.5,ut=2.5,pt=-1,dt=1,xt=0,ht=400;function g(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function j(t){return g(t?.[E])??{}}function k(t,e){const n=j(t);return Object.hasOwn(n,e)?g(n[e])??{}:{}}function vt(t,e){return Object.values(k(t,e)).filter(n=>n!==void 0).length}function C(t,e,n){const r={...j(t)};if(mt(n).length?r[e]=n:delete r[e],!Object.keys(r).length){const{[E]:o,...s}=t;return s}return{...t,[E]:r}}function mt(t){return Object.entries(t).filter(([,e])=>e!==void 0)}function Pt(t){return lt.includes(t)}const _=(t,e,n)=>Math.min(n,Math.max(e,t));function gt(t,e){if(Pt(t)){const n=Math.round(Number(e));return!Number.isFinite(n)||n===0?null:_(n,tt,et)}if(t==="lineHeight"){const n=Number(e);return Number.isFinite(n)?m(_(n,ft,ut),3):null}if(t==="letterSpacing"){const n=Number(e);return Number.isFinite(n)?m(_(n,pt,dt),4):null}if(t==="paragraphSpacing"){const n=Math.round(Number(e));return!Number.isFinite(n)||n<=0?null:_(n,xt,ht)}if(Object.hasOwn(L,t)){const{min:n,max:r}=L[t],o=Math.round(Number(e));return Number.isFinite(o)?_(o,n,r):null}return t==="italic"?typeof e=="boolean"?e:null:t==="role"?I.includes(String(e))?e:null:e}const _t=["weight","size","sizePhone","line","letter","lineHeight","letterSpacing","paragraphSpacing","padding","width"];function W(t){let e=null;const n=r=>{e??={...t},delete e[r]};for(const r of _t){const o=t[r];o!==void 0&&!(typeof o=="number"&&Number.isFinite(o))&&n(r)}return t.align!==void 0&&!H.includes(t.align)&&n("align"),e??t}const St=[["font","role"],["line","lineHeight"],["letter","letterSpacing"]];function At(t){const e=[];for(const[n,r]of St)n===t?e.push(r):r===t&&e.push(n);return e}function qt(t,e,n,r){const o={...k(t,e)},s=r==null?null:gt(n,r);if(s===null)delete o[n];else{o[n]=s;for(const i of At(n))delete o[i]}return C(t,e,o)}function Jt(t,e){return C(t,e,{})}function Tt(t){return V(t)??"none"}function Rt(t){return B(t)??""}const bt={heading:"--font-role-heading",heading2:"--font-role-heading2",heading3:"--font-role-heading3",body:"--font-role-body",accent:"--font-role-accent",label:"--font-role-label"};function Et(t){const e=t.role;return e&&I.includes(e)?e:null}const Nt={headingLarge:"min(clamp(64px,9vw,144px), var(--sf-heading-max,9999px))",headingMedium:"min(32px, var(--sf-heading-max,9999px))",headingSmall:"min(24px, var(--sf-heading-max,9999px))",accent:"32px",body:"14px",label:"12px"};function Ot(t){const e=v[t],n=Nt[e];return n?`var(--size-${e}, ${n})`:`var(--size-${e})`}function wt(t){const e={};return typeof t.lineHeight=="number"?e.lineHeight=t.lineHeight:t.line&&(e.lineHeight=m(yt+t.line*at,3)),typeof t.letterSpacing=="number"?e.letterSpacingEm=t.letterSpacing:t.letter&&(e.letterSpacingEm=m(t.letter*ct,4)),e}const yt=1,S="--sf-part-para",It="(max-width: 719.98px)";function D(t){return t=W(t),typeof t.sizePhone=="number"&&t.sizePhone>0?{fontSize:`${t.sizePhone}px`}:{}}function $t(t,e){return e&&typeof t.sizePhone=="number"&&t.sizePhone>0?{...t,size:t.sizePhone}:t}function R(t,e){t=W(t);const n=Et(t),r=wt(t),o=t.size?`${t.size}px`:n?Ot(n):"";return{fontFamily:t.font?zt(t.font):n?`var(${bt[n]})`:"",fontWeight:t.weight?String(t.weight):"",fontSize:o,minWidth:o?"0":"",overflowWrap:o?"break-word":"",lineHeight:r.lineHeight!==void 0?String(r.lineHeight):"",letterSpacing:r.letterSpacingEm!==void 0?`${r.letterSpacingEm}em`:"",[S]:t.paragraphSpacing?`${t.paragraphSpacing}px`:"",textTransform:Rt(t.case),textAlign:t.align??"",paddingTop:N(t.padding),paddingBottom:N(t.padding),maxWidth:N(t.width),color:Mt(t.color),fontStyle:t.italic===!0?"italic":t.italic===!1?"normal":""}}const Mt=t=>t===void 0||t===""?"":Object.hasOwn(M,t)?M[t]:K.test(t)?t:"",K=/^#[0-9a-fA-F]{6}$/;function Qt(t){return K.test(t)}const N=t=>t===void 0?"":`${t}px`,m=(t,e)=>Number(t.toFixed(e));function te(t,e){const n=Number.parseFloat(t.fontSize)||16,r=Number.parseFloat(t.lineHeight),o=Number.parseFloat(t.letterSpacing),s=Number.parseFloat(t.paddingTop),i=Number.parseFloat(t.maxWidth);return{fontKey:e,sizePx:n,weight:Ht(Number.parseInt(t.fontWeight,10)),lineRatio:Number.isFinite(r)?m(r/n,3):1.2,letterEm:Number.isFinite(o)?m(o/n,4):0,align:Ft(t.textAlign),case:Tt(t.textTransform),paddingPx:Number.isFinite(s)?Math.round(s):0,widthPx:Number.isFinite(i)&&i<T?Math.round(i):T}}function Ht(t){return Number.isFinite(t)?Q.reduce((e,n)=>Math.abs(n-t)<Math.abs(e-t)?n:e):400}function Ft(t){for(const e of H)if(e===t)return e;return t==="end"?"right":"left"}function ee(t,e){const n=G(t);if(!n)return"";for(const r of Y)if(G(e(r.cssVar))===n)return r.key;return""}const G=t=>(t.split(",")[0]??"").replace(/["']/g,"").replace(/\s+/g," ").trim().toLowerCase();function zt(t){const e=Z(t);return e?`var(${e.cssVar})`:""}function ne(t,e,n,r){return!e||$(e)?.nodeId!==t?null:n.find(s=>r(s.getAttribute("class")))??n[0]??null}function re(t,e,n=()=>A,r=i=>i,o=kt,s=!1){let i=0;for(const{element:a,partId:f}of t){const c=$(f)?.propKey;if(!c)continue;const l=r(c),x=Object.hasOwn(e,l)?g(e[l])??{}:{},p=R($t(x,s),A),u=w.some(h=>a.style[h]);let d=!1;for(const[h,P]of Object.entries(p))Ct(a,h,P),P&&(d=!0);if(u||w.some(h=>p[h]))for(const h of Lt(a,o))for(const P of w)h.style[P]=p[P]??"";d&&(i+=1)}return i}function Lt(t,e){const n=b(t.textContent??""),r=[];let o=t;for(let s=0;s<jt&&e(o);s+=1){const i=o.parentElement;if(!i||b(i.textContent??"")!==n)break;r.push(i),o=i}return r}const jt=8;function kt(t){const e=t;return typeof window>"u"||!e?.ownerDocument?!1:window.getComputedStyle(e).display==="inline"}const A={fontKey:"",sizePx:16,weight:400,lineRatio:1,letterEm:0,align:"left",case:"none",paddingPx:0,widthPx:T};function Ct(t,e,n){if(!e.startsWith("--")){t.style[e]=n;return}const r=t.style;typeof r.setProperty=="function"?n?r.setProperty(e,n):r.removeProperty?.(e):r[e]=n;const o=t;e===S&&(n?o.setAttribute?.(X,""):o.removeAttribute?.(X))}const X="data-sf-part-para",Wt=Object.keys(R({},A)),O=new Set(["color","overflowWrap",S,"fontStyle"]),w=Wt.filter(t=>!O.has(t));function oe(t,e,n,r=o=>o){const o=new Map;for(const a of t){const f=q(a.key,a.row);for(const c of a.texts){const l=o.get(c);l?(l.keys.add(a.key),l.partKeys.add(f)):o.set(c,{keys:new Set([a.key]),partKeys:new Set([f])})}}const s=new Map;for(const a of Object.keys(e)){if(!Dt(a))continue;const f=g(e[a])??{},c=R(f,A),l=D(f);!Object.values(c).some(Boolean)&&!Object.keys(l).length||s.set(a,{stamp:U(n,a),declarations:c,...Object.keys(l).length?{phone:l}:{}})}const i=new Map;for(const[a,{keys:f,partKeys:c}]of o){const l=c.size===1?[...c][0]:f.size===1?[...f][0]:null;if(!l)continue;const x=r(l);if(!Object.hasOwn(e,x))continue;const p=g(e[x])??{},u=R(p,A),d=D(p);!Object.values(u).some(Boolean)&&!Object.keys(d).length||i.set(a,{stamp:U(n,l),declarations:u,...Object.keys(d).length?{phone:d}:{}})}return i.size||s.size?{rules:i,kindRules:s,drawn:new Set(o.keys())}:null}function Dt(t){return t.startsWith("@")}function ie(t,e){return t?.kindRules.get(e)??null}function U(t,e){const n=r=>r.replace(/[^A-Za-z0-9_-]+/g,"-");return`${n(t)}~${n(e)}`}function se(t){const e=[],n=new Set,r=o=>{const{stamp:s,declarations:i}=o;if(n.has(s))return;n.add(s);const a=Object.entries(i).filter(([,u])=>u!==""),f=u=>u.map(([d,y])=>`${Gt(d)}: ${y}`).join("; "),c=`[${J}="${s}"]`,l=a.filter(([u])=>!O.has(u)),x=a.filter(([u])=>O.has(u));l.length&&e.push(`${c}, *:has(> ${c}) { ${f(l)} }`),x.length&&e.push(`${c} { ${f(x)} }`),i[S]&&e.push(...Kt(c));const p=Object.entries(o.phone??{}).filter(([,u])=>u!=="");p.length&&e.push(`@media ${It} { ${c}, *:has(> ${c}) { ${f(p)} } }`)};for(const o of t.rules.values())r(o);for(const o of t.kindRules.values())r(o);return e.join(`
|
|
2
|
+
`)}function Kt(t){const e=`var(${S})`,n=":is([data-sf-bullet], [data-sf-number])";return[`${t} br:not(br + br) { display: block; content: ""; margin-top: ${e} }`,`${t} ${n}:not(:first-child) { margin-top: ${e} }`,`${t} ${n}:not(:last-child) { margin-bottom: ${e} }`]}const Gt=t=>t.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`);function ae(t,e){if(!t)return null;const n=b(e),r=t.rules.get(n);if(r)return r;if(n.length<Xt||t.drawn.has(n))return null;let o=null;for(const[s,i]of t.rules)if(s.includes(n)){if(o&&o.stamp!==i.stamp)return null;o=i}return o}const Xt=8;export{H as PART_ALIGNS,dt as PART_LETTER_EM_MAX,pt as PART_LETTER_EM_MIN,ct as PART_LETTER_STEP,ut as PART_LINE_HEIGHT_MAX,ft as PART_LINE_HEIGHT_MIN,at as PART_LINE_STEP,L as PART_MEASURED_TRACKS,et as PART_NUDGE_MAX,tt as PART_NUDGE_MIN,rt as PART_PADDING_MAX,nt as PART_PADDING_MIN,ot as PART_PADDING_STEP,X as PART_PARAGRAPH_ATTR,ht as PART_PARAGRAPH_MAX,xt as PART_PARAGRAPH_MIN,S as PART_PARAGRAPH_VAR,It as PART_PHONE_MAX_CSS,lt as PART_RELATIVE_PROPS,z as PART_SIZE_MAX,F as PART_SIZE_MIN,J as PART_STYLED_ATTR,E as PART_STYLES_PROP,Wt as PART_STYLE_PROPERTIES,Q as PART_WEIGHTS,T as PART_WIDTH_MAX,it as PART_WIDTH_MIN,st as PART_WIDTH_STEP,w as SHARED_PART_PROPERTIES,re as applyPartStyles,Qt as isHexColour,Dt as isPartKindKey,Kt as paragraphRules,Tt as partCaseOfTransform,Rt as partCaseTransform,ee as partFontKeyOf,D as partPhoneDeclarations,ie as partRuleForKind,ae as partRuleForText,wt as partSpacingOf,te as partStyleBase,vt as partStyleCount,se as partStyleCss,R as partStyleDeclarations,$t as partStyleForScreen,ne as partStyleSource,qt as propsWithPartStyleValue,Jt as propsWithoutPartStyle,oe as publishedPartStyles,k as readPartStyle,j as readPartStyles};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "efficient-web-builder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "25.0.0",
|
|
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",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@tabler/icons-react": "^3.46.0",
|
|
55
|
-
"efficient-easel": "^13.
|
|
56
|
-
"efficient-shell": "^7.75.0",
|
|
55
|
+
"efficient-easel": "^13.2.0",
|
|
56
|
+
"efficient-shell": "^7.75.0 || ^8.0.0",
|
|
57
57
|
"isomorphic-dompurify": "^3.18.0",
|
|
58
58
|
"next": ">=16",
|
|
59
59
|
"react": ">=19",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"@types/node": "^20",
|
|
73
73
|
"@types/react": "^19",
|
|
74
74
|
"@types/react-dom": "^19",
|
|
75
|
-
"efficient-easel": "^13.
|
|
76
|
-
"efficient-shell": "^
|
|
75
|
+
"efficient-easel": "^13.2.0",
|
|
76
|
+
"efficient-shell": "^8.0.0",
|
|
77
77
|
"esbuild": "^0.28.0",
|
|
78
78
|
"happy-dom": "^20.14.5",
|
|
79
79
|
"isomorphic-dompurify": "^3.18.0",
|