efficient-web-builder 36.0.0 → 37.1.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 (37) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/editor/components/PartSettingsPanel.js +1 -1
  3. package/dist/editor/components/PinnedChromeLoadNotice.d.ts +6 -0
  4. package/dist/editor/components/PinnedChromeLoadNotice.js +1 -1
  5. package/dist/editor/components/PreviewPartAnchors.js +1 -1
  6. package/dist/editor/components/SiteTextStylesField.d.ts +1 -1
  7. package/dist/editor/components/SiteTextStylesField.js +1 -1
  8. package/dist/editor/components/StorefrontEditor.js +1 -1
  9. package/dist/editor/components/ThemeCard.js +1 -1
  10. package/dist/editor/components/WebsiteScreenParts.js +1 -1
  11. package/dist/editor/components/storefront-editor.css +23 -3
  12. package/dist/editor/lib/editor-document-adapter.d.ts +7 -0
  13. package/dist/editor/lib/editor-document-adapter.js +1 -1
  14. package/dist/editor/lib/puck/page-root.js +1 -1
  15. package/dist/editor/lib/shared-sections-layer.d.ts +8 -0
  16. package/dist/editor/lib/shared-sections-layer.js +1 -0
  17. package/dist/editor/lib/site-text-styles-writer.d.ts +1 -1
  18. package/dist/editor/lib/site-text-styles-writer.js +1 -1
  19. package/dist/editor/lib/site-text-styles.d.ts +1 -83
  20. package/dist/editor/lib/site-text-styles.js +1 -2
  21. package/dist/format/lib/editor-words-catalogue.d.ts +12 -1
  22. package/dist/format/lib/editor-words-catalogue.js +3 -3
  23. package/dist/format/lib/puck/container-blocks.js +1 -1
  24. package/dist/format/lib/puck/text-seeds.d.ts +2 -0
  25. package/dist/format/lib/puck/text-seeds.js +1 -0
  26. package/dist/format/lib/sections/section-presets.js +1 -1
  27. package/dist/format/lib/shared-section-docs.d.ts +27 -0
  28. package/dist/format/lib/shared-section-docs.js +1 -0
  29. package/dist/format/lib/shared-sections-active.d.ts +42 -0
  30. package/dist/format/lib/shared-sections-active.js +1 -0
  31. package/dist/format/lib/web-backend.d.ts +3 -0
  32. package/dist/render/components/Text.js +1 -1
  33. package/dist/render/lib/puck/blocks/general/Text/render.js +1 -1
  34. package/dist/render/lib/puck/slot-specs.js +1 -1
  35. package/dist/render/lib/text-styles/site-text-styles.d.ts +83 -0
  36. package/dist/render/lib/text-styles/site-text-styles.js +2 -0
  37. package/package.json +3 -3
@@ -0,0 +1,42 @@
1
+ export type SharedSectionRecord = {
2
+ id: string;
3
+ title: string;
4
+ layout: unknown;
5
+ layout_updated_at: string | null;
6
+ used_on: readonly {
7
+ id: string;
8
+ slug: string;
9
+ title: string;
10
+ }[];
11
+ };
12
+ export interface SharedSectionsInPlace {
13
+ sectionOf(nodeId: string): string | null;
14
+ heldElsewhere(nodeId: string): boolean;
15
+ adopt(nodeId: string, section: SharedSectionRecord): void;
16
+ place(section: SharedSectionRecord): {
17
+ type: string;
18
+ props: {
19
+ id: string;
20
+ [key: string]: unknown;
21
+ };
22
+ } | null;
23
+ usedOn(section: string): readonly {
24
+ id: string;
25
+ slug: string;
26
+ title: string;
27
+ }[] | null;
28
+ learn(sections: readonly SharedSectionRecord[]): void;
29
+ }
30
+ export declare function setActiveSharedSections(api: SharedSectionsInPlace | null): void;
31
+ export declare function activeSharedSections(): SharedSectionsInPlace | null;
32
+ export type SharedEditor = {
33
+ openPage: (page: {
34
+ id: string;
35
+ slug: string;
36
+ title: string;
37
+ }) => void;
38
+ reload: () => void;
39
+ config: unknown;
40
+ };
41
+ export declare function setSharedEditor(next: SharedEditor | null): void;
42
+ export declare function sharedEditor(): SharedEditor | null;
@@ -0,0 +1 @@
1
+ let e=null;function n(t){e=t}function o(){return e}let r=null;function i(t){r=t}function c(){return r}export{o as activeSharedSections,n as setActiveSharedSections,i as setSharedEditor,c as sharedEditor};
@@ -2,6 +2,7 @@ import type { EaselPageRow as EditorPageRow, SiteRecord, SiteRecordPatch, Websit
2
2
  import type { HostPickedMedia } from "efficient-easel/screen/lib/host";
3
3
  import type { SiteThemeRow, SiteThemeRowPatch } from "./site-theme-row.js";
4
4
  import type { SectionTemplate, SectionTemplateRecord } from "efficient-easel/screen/lib/section-template-types";
5
+ import type { SharedSectionStore } from "efficient-easel/screen/lib/shared-section-types";
5
6
  export type PageLayout = Record<string, unknown>;
6
7
  export type { EditorPageRow, SiteRecord, SiteRecordPatch, WebsiteEditLock };
7
8
  export type PageBundle = {
@@ -136,6 +137,7 @@ export interface WebsiteSectionTemplates {
136
137
  rename(id: string, name: string): Promise<SectionTemplateRecord>;
137
138
  remove(id: string): Promise<void>;
138
139
  }
140
+ export type WebsiteSharedSections = SharedSectionStore;
139
141
  export interface WebsiteTemplates {
140
142
  get(id: string): Promise<{
141
143
  id: string;
@@ -191,6 +193,7 @@ export interface WebsiteBackend {
191
193
  site: WebsiteSite;
192
194
  media: WebsiteMedia;
193
195
  sectionTemplates?: WebsiteSectionTemplates;
196
+ sharedSections?: WebsiteSharedSections;
194
197
  templates?: WebsiteTemplates;
195
198
  preview?: WebsitePreview;
196
199
  blog?: WebsiteBlog;
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import p from"./BlockFrame.js";import{renderGold as n,renderHeadline as b,splitParagraphs as u}from"./goldPhrases.js";import{headingLook as N}from"./Heading.js";import{textTagOf as T}from"../../format/lib/content/text-tag.js";import{isTextStyleId as v}from"../lib/puck/part-styles.js";import{faceClassOf as x}from"../../format/lib/text-style-face.js";const s={bodyUpTo800:"max-[800px]:text-[length:var(--size-body,14px)]",bodySmall:"text-[length:var(--size-body,15px)]",bodyLarge:"text-[length:var(--size-body,17px)]",label:"text-[length:var(--size-label,13px)]"},$={left:"text-left",center:"text-center mx-auto",right:"text-right ml-auto"},S=`max-w-[380px] ${s.bodySmall} leading-[1.5] opacity-80 ${s.bodyUpTo800}`,L={default:"text-fg",dim:"text-fg-dim"};function z({text:a,align:d,tone:h,contained:m,hero:g=!1,pad:l,tag:y,textStyle:c}){if(g)return t("p",{className:S,children:n(a)});const e=v(c)?c:void 0,f=`${e?`${x({id:e})} `:""}max-w-[680px] whitespace-pre-line ${e==="body-5"?s.label:s.bodyLarge} leading-[1.7] ${$[d]} ${L[h]}`,o=T(y);if(e?.startsWith("heading-")){const i=String(Math.min(Number(e.slice(8)),6)),r=N(i,d,x({id:e}));return t(p,{contained:m,className:"py-4",pad:l?{values:l,frame:16}:void 0,children:t(o,{className:r.className,style:r.style,children:b(a.trim(),!1)})})}return t(p,{contained:m,className:"py-4",pad:l?{values:l,frame:16}:void 0,children:o==="p"?u(a).map((i,r)=>t("p",{className:f,children:n(i)},r)):t(o,{className:f,children:n(a.trim())})})}export{z as default};
1
+ import{jsx as t}from"react/jsx-runtime";import p from"./BlockFrame.js";import{renderGold as n,renderHeadline as b,splitParagraphs as u}from"./goldPhrases.js";import{headingLook as N}from"./Heading.js";import{textTagOf as T}from"../../format/lib/content/text-tag.js";import{isTextStyleId as v}from"../lib/puck/part-styles.js";import{faceClassOf as x}from"../../format/lib/text-style-face.js";const s={bodyUpTo800:"max-[800px]:text-[length:var(--size-body,14px)]",bodySmall:"text-[length:var(--size-body,15px)]",bodyLarge:"text-[length:var(--size-body,17px)]",label:"text-[length:var(--size-label,13px)]"},$={left:"text-left",center:"text-center mx-auto",right:"text-right ml-auto"},S=`max-w-[380px] ${s.bodySmall} leading-[1.5] opacity-80 ${s.bodyUpTo800}`,L={default:"text-fg",dim:"text-fg-dim"};function z({text:a,align:d,tone:h,contained:m,hero:g=!1,pad:l,tag:y,textStyle:c}){if(g)return t("p",{className:S,children:n(a)});const e=v(c)?c:void 0,f=`${e?`${x({id:e})} `:""}max-w-[680px] whitespace-pre-line ${e==="body-5"?s.label:s.bodyLarge} leading-[1.7] ${$[d]} ${L[h]}`,o=T(y);if(e?.startsWith("heading-")){const i=String(Math.min(Number(e.slice(8)),6)),r=N(i,d,x({id:e}));return t(p,{contained:m,className:"py-6",pad:l?{values:l,frame:24}:void 0,children:t(o,{className:r.className,style:r.style,children:b(a.trim(),!1)})})}return t(p,{contained:m,className:"py-4",pad:l?{values:l,frame:16}:void 0,children:o==="p"?u(a).map((i,r)=>t("p",{className:f,children:n(i)},r)):t(o,{className:f,children:n(a.trim())})})}export{z as default};
@@ -1 +1 @@
1
- import{Fragment as m,jsx as r}from"react/jsx-runtime";import{padValuesOf as l}from"../../../../../../format/lib/content/section-padding.js";import x from"../../../../../components/Text.js";import{hidableText as f,readHidable as p}from"efficient-easel/draw";import{PH as g}from"../../../../../../format/lib/puck/blocks/placeholders.js";import{phPrev as u}from"../../scaffold.js";import{readPartStyle as c}from"../../../part-styles.js";const j={label:"Text",defaultProps:{text:"",align:"left",tone:"default",tag:"p",contained:!0},render:t=>{const{text:e,align:a,tone:o,tag:n,contained:i,puck:d}=t;return p(e).hidden?r(m,{}):r(x,{text:u(f(e),g.body,d)??"",align:a,tone:o,tag:n,textStyle:c(t,"text").textStyle,contained:i,pad:l(t)})}};export{j as TextRender};
1
+ import{Fragment as f,jsx as a}from"react/jsx-runtime";import{padValuesOf as p}from"../../../../../../format/lib/content/section-padding.js";import g from"../../../../../components/Text.js";import{hidableText as s,readHidable as c}from"efficient-easel/draw";import{PH as o}from"../../../../../../format/lib/puck/blocks/placeholders.js";import{phPrev as h}from"../../scaffold.js";import{readPartStyle as u}from"../../../part-styles.js";const H={label:"Text",defaultProps:{text:"",align:"left",tone:"default",tag:"p",contained:!0},render:t=>{const{text:e,align:n,tone:i,tag:d,contained:l,puck:m}=t;if(c(e).hidden)return a(f,{});const r=u(t,"text").textStyle,x=r?.startsWith("heading-")?o.heading:o.body;return a(g,{text:h(s(e),x,m)??"",align:n,tone:i,tag:d,textStyle:r,contained:l,pad:p(t)})}};export{H as TextRender};
@@ -1 +1 @@
1
- import{HERO_SLIDE_SEEDS as a}from"../../components/HeroSlide.js";import{heroGroupAddBlocked as l,heroGroupOverCapNotice as c}from"../../../format/lib/hero-group-placement.js";import{newNodeId as p}from"efficient-easel/draw";import{BOX_TYPE as t,CONTAINER_BLOCKS_SLOT as n}from"../../../format/lib/puck/container-blocks.js";import{BOX_LABEL as i}from"../../../format/lib/puck/section-catalog.js";const m="ImageBlock",E=3,d=(e,r,o={})=>({type:e,props:{...r?.(e)??{},id:p(e),...o}}),T=e=>({...e?.(t)??{},direction:"column",[n]:[d(m,e),d(t,e,{direction:"column",[n]:[d("Heading",e),d("Text",e)]})]}),s={Hero:{slot:"slides",childType:"HeroSlide",addLabel:"Add slide",slider:!0,seeds:()=>a.map(e=>({...e}))},HeroSlide:{slot:"groups",childType:"HeroGroup",addLabel:`Add ${i.toLowerCase()}`,seeds:()=>[],addBlocked:l,notice:c},HeroSingle:{slot:"boxes",childType:"HeroGroup",addLabel:`Add ${i.toLowerCase()}`,seeds:()=>[],addBlocked:l,notice:c},ProcessSteps:{slot:"boxes",childType:t,addLabel:`Add ${i.toLowerCase()}`,seeds:e=>Array.from({length:E},()=>T(e)),skipSeed:e=>Array.isArray(e.steps)&&e.steps.length>0}};function u(e){for(const[r,o]of Object.entries(e)){if(r in s&&s[r]!==o)throw new Error(`lib/puck/slot-specs: "${r}" already has a slot spec`);s[r]=o}}function A(e,r){const o=s[e];return o?{slot:o.slot,children:o.seeds(r).map(S=>({type:o.childType,props:{id:p(o.childType),...S}}))}:null}export{s as SLOT_SECTION_SPECS,A as buildSlotSeedChildren,u as registerSlotSectionSpecs};
1
+ import{HERO_SLIDE_SEEDS as a}from"../../components/HeroSlide.js";import{heroGroupAddBlocked as l,heroGroupOverCapNotice as c}from"../../../format/lib/hero-group-placement.js";import{newNodeId as p}from"efficient-easel/draw";import{BOX_TYPE as t,CONTAINER_BLOCKS_SLOT as n}from"../../../format/lib/puck/container-blocks.js";import{BOX_LABEL as i}from"../../../format/lib/puck/section-catalog.js";import{headingTextSeed as m}from"../../../format/lib/puck/text-seeds.js";const T="ImageBlock",E=3,d=(e,r,o={})=>({type:e,props:{...r?.(e)??{},id:p(e),...o}}),h=e=>({...e?.(t)??{},direction:"column",[n]:[d(T,e),d(t,e,{direction:"column",[n]:[d("Text",e,m()),d("Text",e)]})]}),s={Hero:{slot:"slides",childType:"HeroSlide",addLabel:"Add slide",slider:!0,seeds:()=>a.map(e=>({...e}))},HeroSlide:{slot:"groups",childType:"HeroGroup",addLabel:`Add ${i.toLowerCase()}`,seeds:()=>[],addBlocked:l,notice:c},HeroSingle:{slot:"boxes",childType:"HeroGroup",addLabel:`Add ${i.toLowerCase()}`,seeds:()=>[],addBlocked:l,notice:c},ProcessSteps:{slot:"boxes",childType:t,addLabel:`Add ${i.toLowerCase()}`,seeds:e=>Array.from({length:E},()=>h(e)),skipSeed:e=>Array.isArray(e.steps)&&e.steps.length>0}};function b(e){for(const[r,o]of Object.entries(e)){if(r in s&&s[r]!==o)throw new Error(`lib/puck/slot-specs: "${r}" already has a slot spec`);s[r]=o}}function y(e,r){const o=s[e];return o?{slot:o.slot,children:o.seeds(r).map(S=>({type:o.childType,props:{id:p(o.childType),...S}}))}:null}export{s as SLOT_SECTION_SPECS,y as buildSlotSeedChildren,b as registerSlotSectionSpecs};
@@ -0,0 +1,83 @@
1
+ import { type TextStyle, type TextStyleCase } from "efficient-easel/text-styles/model";
2
+ import { type FontRole, type FontsValue } from "../../../format/lib/fonts.js";
3
+ import { type PartStyle } from "../puck/part-styles.js";
4
+ import { faceClassOf } from "../../../format/lib/text-style-face.js";
5
+ export { faceClassOf };
6
+ import type { SiteThemeRow, SiteThemeRowPatch } from "../../../format/lib/site-theme-row.js";
7
+ import { type HeadingCompression, type ResolvedHeadingTypography, type SizesValue } from "../../../format/lib/theme.js";
8
+ export type StoredTextStyleValues = {
9
+ font?: string;
10
+ color?: string;
11
+ size?: number;
12
+ weight?: number;
13
+ italic?: boolean;
14
+ lineHeight?: number;
15
+ letterSpacing?: number;
16
+ paragraphSpacing?: number;
17
+ letterCase?: TextStyleCase;
18
+ largestSize?: number;
19
+ sizePhone?: number;
20
+ };
21
+ export type StoredTextStyle = {
22
+ id: string;
23
+ kind: "heading" | "body";
24
+ name: string;
25
+ values: StoredTextStyleValues;
26
+ auto?: (keyof StoredTextStyleValues)[];
27
+ };
28
+ export type OldSiteText = {
29
+ fonts: Partial<FontsValue> | Record<string, string>;
30
+ sizes: Partial<SizesValue> | Record<string, number | null>;
31
+ compression: string;
32
+ typography: Partial<ResolvedHeadingTypography> | Record<string, unknown>;
33
+ };
34
+ export declare function textStylesFromOld(old: OldSiteText): StoredTextStyle[];
35
+ export declare function storedTextStyles(value: unknown): StoredTextStyle[];
36
+ export declare function resolveTextStyles(saved: unknown, old: OldSiteText): StoredTextStyle[];
37
+ export declare function applyListChange({ saved, old, cur, next, sizeOf, }: {
38
+ saved: unknown;
39
+ old: OldSiteText;
40
+ cur: readonly TextStyle[];
41
+ next: readonly TextStyle[];
42
+ sizeOf: (style: StoredTextStyle) => number;
43
+ }): {
44
+ saved: StoredTextStyle[];
45
+ old: OldSiteText;
46
+ };
47
+ export declare function listChangePatch(next: {
48
+ saved: StoredTextStyle[];
49
+ old: OldSiteText;
50
+ }, prev: OldSiteText): SiteThemeRowPatch;
51
+ export declare function toPanelStyles(stored: readonly StoredTextStyle[], sizeOf: (s: StoredTextStyle) => number): TextStyle[];
52
+ export declare function fromPanelStyles(list: readonly TextStyle[], sizeOf: (s: StoredTextStyle) => number): StoredTextStyle[];
53
+ export type SiteTextSeed = {
54
+ fonts: FontsValue;
55
+ sizes: SizesValue;
56
+ compression: HeadingCompression;
57
+ typography: ResolvedHeadingTypography;
58
+ textStyles: unknown;
59
+ };
60
+ export declare function siteTextFromRow(row: Partial<SiteThemeRow>): SiteTextSeed;
61
+ export declare function textStylesToOld(list: readonly StoredTextStyle[], prev: OldSiteText): OldSiteText;
62
+ export declare function themeWithTextStyles<T extends {
63
+ fonts?: unknown;
64
+ sizes?: unknown;
65
+ headingCompression?: unknown;
66
+ headingTypography?: unknown;
67
+ textStyles?: unknown;
68
+ }>(theme: T): T;
69
+ export declare function textStylesCss(list: readonly StoredTextStyle[]): string;
70
+ export declare function accentItalicCss(italic: boolean | null | undefined): string;
71
+ export declare function styleIdOfRole(role: FontRole | null | undefined): string | undefined;
72
+ export declare function partStyleToTextStyleValues(style: PartStyle): StoredTextStyleValues;
73
+ export declare function hasStyleChange(style: PartStyle): boolean;
74
+ export declare function pushIntoStyle({ saved, old, styleId, values, }: {
75
+ saved: unknown;
76
+ old: OldSiteText;
77
+ styleId: string;
78
+ values: StoredTextStyleValues;
79
+ }): {
80
+ saved: StoredTextStyle[];
81
+ old: OldSiteText;
82
+ };
83
+ export declare function eyebrowStyleId(list: readonly Pick<StoredTextStyle, "id" | "kind">[]): string;
@@ -0,0 +1,2 @@
1
+ import{defaultTextStyles as J,textStyleCaseCss as X}from"efficient-easel/text-styles/model";import{FONT_OPTIONS as Y,normalizeFonts as F}from"../../../format/lib/fonts.js";import{PART_PHONE_MAX_CSS as G,STYLE_ID_OF_ROLE as U,TEXT_STYLE_ATTR as W,partSpacingOf as Z}from"../puck/part-styles.js";import{faceClassOf as I}from"../../../format/lib/text-style-face.js";import{compressionMetrics as q,headingTypographyFromRow as B,normalizeHeadingCompression as C,normalizeSizes as L}from"../../../format/lib/theme.js";const T=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,j=["font","color","size","sizePhone","weight","italic","lineHeight","letterSpacing","paragraphSpacing","letterCase","largestSize"];function p(e){const i={};for(const n of j)e[n]!==void 0&&(i[n]=e[n]);return i}function H(e,i){const{auto:n,...t}=e,s=new Set(i??[]),r=j.filter(o=>s.has(o)&&e.values[o]===void 0);return r.length?{...t,auto:r}:t}function O(e){const i=e.fonts,n=e.sizes,t=e.typography,s=q(e.compression),r={"heading-1":{font:_(i.heading),size:h(n.headingLarge),weight:h(t.weight),lineHeight:s.lineHeight,letterSpacing:s.letterSpacing,letterCase:T(t.case),largestSize:h(t.maxPx)},"heading-2":{font:_(i.heading2),size:h(n.headingMedium),weight:h(t.weight2),lineHeight:s.lineHeight,letterSpacing:s.letterSpacing,letterCase:T(t.case2)},"heading-3":{font:_(i.heading3),size:h(n.headingSmall),weight:h(t.weight3),lineHeight:s.lineHeight,letterSpacing:s.letterSpacing,letterCase:T(t.case3)},"body-1":{font:_(i.body),size:h(n.body)},"body-5":{font:_(i.label),size:h(n.label)}};return J().map(({id:o,kind:l,name:d})=>({id:o,kind:l,name:d,values:p(r[o]??{})}))}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=>H({...n,values:p(n.values??{})},Array.isArray(n.auto)?n.auto:void 0)):null}function le(e){return $(e)??[]}function w(e,i){const n=O(i),t=$(e);return t?t.map(s=>{const r={...P(n,s.id)};for(const o of s.auto??[])delete r[o];return{...s,values:p({...r,...s.values})}}):n}const P=(e,i)=>e.find(n=>n.id===i)?.values??{},R=["heading-1","heading-2","heading-3"];function de({saved:e,old:i,cur:n,next:t,sizeOf:s}){const r=O(i),o=$(e)??r.map(a=>({...a,values:{}})),l=w(o,i),d=[],y=t.map(a=>{const c=n.find(f=>f.id===a.id),b=o.find(f=>f.id===a.id);if(!c||!b)return K([a],s)[0];const u={...b.values},z=new Set(b.auto??[]),v=a.values,A=c.values,N=[...new Set([...Object.keys(v),...Object.keys(A)])].filter(f=>JSON.stringify(v[f])!==JSON.stringify(A[f]));N.sort((f,m)=>+(f==="letterSpacing")-+(m==="letterSpacing"));for(const f of N){const m=f==="lineSpacing"?"lineHeight":f,k=v[f];if(k===void 0){delete u[m],P(r,a.id)[m]!==void 0&&(d.push([a.id,m]),z.add(m));continue}if(z.delete(m),f==="lineSpacing")u.lineHeight=x(k/100,3);else if(f==="letterSpacing"){const V=l.find(D=>D.id===a.id),E=s({...a,values:p({...V?.values??{},...u})});u.letterSpacing=E?x(k/E,4):0}else u[m]=k}return H({id:a.id,kind:a.kind,name:a.name,values:p(u)},z)});let g=i.compression;if(d.some(([a,c])=>(c==="lineHeight"||c==="letterSpacing")&&R.includes(a))&&C(g)!=="normal"){for(const a of R){const c=y.find(u=>u.id===a);if(!c)continue;const b={...c.values};for(const u of["lineHeight","letterSpacing"])d.some(([z,v])=>z===a&&v===u)||b[u]===void 0&&!(c.auto??[]).includes(u)&&(b[u]=P(r,a)[u]);c.values=p(b)}g="normal"}return{saved:y,old:{...i,compression:g}}}function ce(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 ue(e,i){return e.map(n=>{const{lineHeight:t,letterSpacing:s,...r}=n.values,o={...r};return t!==void 0&&(o.lineSpacing=x(t*100,1)),s!==void 0&&(o.letterSpacing=x(s*i(n),2)),{id:n.id,kind:n.kind,name:n.name,values:o}})}function K(e,i){return e.map(n=>{const{lineSpacing:t,letterSpacing:s,...r}=n.values,o={id:n.id,kind:n.kind,name:n.name,values:p({...r})},l={...o.values};if(t!==void 0&&(l.lineHeight=x(t/100,3)),s!==void 0){const d=i({...o,values:{...o.values}});l.letterSpacing=d?x(s/d,4):0}return{...o,values:p(l)}})}function fe(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:L({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:B(e)},n=e.text_styles??null,t=Array.isArray(n)?M(w(n,i),i):i;return{fonts:F(t.fonts),sizes:L(t.sizes),compression:C(t.compression),typography:t.typography,textStyles:n}}function M(e,i){const n=a=>e.find(c=>c.id===a)?.values??{},t=n("heading-1"),s=n("heading-2"),r=n("heading-3"),o=n("body-1"),l=n("body-5"),d=i.fonts,y=i.sizes,g=i.typography,S=a=>a==="none"?"sentence":"authored";return{fonts:{...d,heading:t.font??d.heading,heading2:s.font??t.font??d.heading2,heading3:r.font??t.font??d.heading3,body:o.font??d.body,label:l.font??d.label},sizes:{...y,headingLarge:t.size??null,headingMedium:s.size??null,headingSmall:r.size??null,body:o.size??null,label:l.size??null},compression:i.compression,typography:{...g,case:S(t.letterCase),weight:t.weight??null,maxPx:t.largestSize??null,weight2:s.weight??null,weight3:r.weight??null,case2:S(s.letterCase),case3:S(r.letterCase)}}}function ge(e){const i=$(e.textStyles);if(!i||i.every(s=>Object.keys(s.values).length===0&&!s.auto))return e;const n={fonts:e.fonts??{},sizes:e.sizes??{},compression:String(e.headingCompression??"normal"),typography:e.headingTypography??{}},t=M(w(i,n),n);return{...e,fonts:t.fonts,sizes:t.sizes,headingCompression:t.compression,headingTypography:t.typography}}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 ee(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 pe(e){const i=[];for(const n of e){const t=n.values,s=`.${I(n)}`,r=`[${W}="${n.id}"]`,o=`${s}, ${r}`,l=[],d=t.font!==void 0?Y.find(a=>a.key===t.font)?.cssVar:void 0;if(d&&l.push(`font-family: var(${d})`),t.size!==void 0){const a=t.largestSize!==void 0?Math.min(t.size,t.largestSize):t.size;l.push(`font-size: ${a}px`)}const y=t.color!==void 0?Q(t.color):null;y&&l.push(`color: ${y}`),t.italic===!0&&l.push("font-style: italic"),t.weight!==void 0&&l.push(`font-weight: ${t.weight}`);const g=[];t.lineHeight!==void 0&&g.push(`line-height: ${t.lineHeight}`),t.letterSpacing!==void 0&&g.push(`letter-spacing: ${t.letterSpacing}em`),n.kind==="body"&&l.push(...g);const S=X(t.letterCase);if(S&&l.push(`text-transform: ${S}`),t.paragraphSpacing&&l.push(`--sf-part-para: ${t.paragraphSpacing}px`),l.length&&i.push(`${o} { ${l.join("; ")} }`),n.kind==="heading"&&g.length&&i.push(`${o}, ${s}:is(h1, h2, h3, h4), ${r}:is(h1, h2, h3, h4) { ${g.join("; ")} }`),t.paragraphSpacing&&i.push(...ee(`:is(${o})`)),t.sizePhone!==void 0){const a=ne[n.id],c=[`${o} { font-size: ${t.sizePhone}px }`];a&&c.push(`.sf-themed-content { --size-${a}: ${t.sizePhone}px !important }`),i.push(`@media ${G} { ${c.join(" ")} }`)}}return i.join(`
2
+ `)}const ne={"heading-1":"headingLarge","heading-2":"headingMedium","heading-3":"headingSmall","body-1":"body","body-5":"label"};function he(e){return e!==!0&&e!==!1?"":`em.text-accent { font-style: ${e?"italic":"normal"} }`}function me(e){return e?U[e]:void 0}function te(e){const i=Z(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 ye(e){return Object.keys(te(e)).length>0}function Se({saved:e,old:i,styleId:n,values:t}){return{saved:($(e)??O(i).map(o=>({...o,values:{}}))).map(o=>o.id===n?H({...o,values:p({...o.values,...t})},o.auto):o),old:i}}function be(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{he as accentItalicCss,de as applyListChange,be as eyebrowStyleId,I as faceClassOf,K as fromPanelStyles,ye as hasStyleChange,ce as listChangePatch,te as partStyleToTextStyleValues,Se as pushIntoStyle,w as resolveTextStyles,fe as siteTextFromRow,le as storedTextStyles,me as styleIdOfRole,pe as textStylesCss,O as textStylesFromOld,M as textStylesToOld,ge as themeWithTextStyles,ue as toPanelStyles};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "36.0.0",
3
+ "version": "37.1.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",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@tabler/icons-react": "^3.46.0",
56
- "efficient-easel": "^18.0.0",
56
+ "efficient-easel": "^18.1.0",
57
57
  "efficient-shell": "^8.20.0",
58
58
  "isomorphic-dompurify": "^3.18.0",
59
59
  "next": ">=16",
@@ -72,7 +72,7 @@
72
72
  "@types/node": "^20",
73
73
  "@types/react": "^19",
74
74
  "@types/react-dom": "^19",
75
- "efficient-easel": "^18.0.0",
75
+ "efficient-easel": "^18.2.0",
76
76
  "efficient-shell": "^8.20.0",
77
77
  "esbuild": "^0.28.0",
78
78
  "happy-dom": "^20.14.5",