efficient-web-builder 37.0.0 → 37.2.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 +56 -0
- package/dist/editor/components/AnchorField.d.ts +8 -0
- package/dist/editor/components/AnchorField.js +1 -0
- package/dist/editor/components/PartSettingsPanel.js +1 -1
- package/dist/editor/components/SiteTextStylesField.d.ts +1 -1
- package/dist/editor/components/SiteTextStylesField.js +1 -1
- package/dist/editor/components/StorefrontEditor.js +1 -1
- package/dist/editor/components/StylesPanel.js +1 -1
- package/dist/editor/components/ThemeCard.js +1 -1
- package/dist/editor/components/WebsiteScreenParts.js +1 -1
- package/dist/editor/components/WebsiteSettingsPanel.js +1 -1
- package/dist/editor/components/storefront-editor.css +31 -7
- package/dist/editor/lib/puck/blocks/general/Footprint/fields.d.ts +1 -0
- package/dist/editor/lib/puck/blocks/general/Footprint/fields.js +1 -1
- package/dist/editor/lib/puck/controls.d.ts +0 -1
- package/dist/editor/lib/puck/controls.js +1 -1
- package/dist/editor/lib/puck/page-root.js +1 -1
- package/dist/editor/lib/puck/section-width-fields.js +1 -1
- package/dist/editor/lib/site-text-styles-writer.d.ts +1 -1
- package/dist/editor/lib/site-text-styles-writer.js +1 -1
- package/dist/editor/lib/site-text-styles.d.ts +1 -83
- package/dist/editor/lib/site-text-styles.js +1 -2
- package/dist/format/lib/content/footprint.d.ts +3 -0
- package/dist/format/lib/content/footprint.js +1 -1
- package/dist/format/lib/content/subscribe.d.ts +2 -18
- package/dist/format/lib/content/subscribe.js +2 -2
- package/dist/format/lib/editor-words-catalogue.d.ts +13 -10
- package/dist/format/lib/editor-words-catalogue.js +4 -4
- package/dist/format/lib/popup/behavior.d.ts +43 -0
- package/dist/format/lib/popup/behavior.js +1 -0
- package/dist/format/lib/popup/look.d.ts +28 -0
- package/dist/format/lib/popup/look.js +1 -0
- package/dist/format/lib/popup/rules.d.ts +35 -0
- package/dist/format/lib/popup/rules.js +1 -0
- package/dist/format/lib/source-rules/panel-no-divider-lines.js +1 -1
- package/dist/format/lib/web-backend.d.ts +3 -0
- package/dist/render/components/Footprint.js +1 -1
- package/dist/render/lib/puck/blocks/general/Footprint/render.js +2 -2
- package/dist/render/lib/text-styles/site-text-styles.d.ts +83 -0
- package/dist/render/lib/text-styles/site-text-styles.js +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SUBSCRIBE_POPUP_SLUG as a}from"../content/subscribe.js";import{canPersist as i}from"../safe-storage.js";const c=1440*60*1e3,p=["/checkout","/cart"];function u(t){return t===a?{seen:"storefront-subscribe-seen",closedAt:"storefront-popup-closed-at",sentAt:"storefront-popup-sent-at"}:{seen:`storefront-popup:${t}:seen`,closedAt:`storefront-popup:${t}:closed-at`,sentAt:`storefront-popup:${t}:sent-at`}}function f(t){const e=t.split(/[?#]/)[0]||"/",r=e.startsWith("/")?e:`/${e}`;return r.length>1?r.replace(/\/+$/,"")||"/":r}function d(t,e,r){const n=f(t);if(p.some(s=>n===s||n.startsWith(`${s}/`)))return!1;if(e==="all")return!0;const o=r.some(s=>f(s)===n);return e==="chosen"?o:!o}function m(t,e){return t==="all"?!0:t==="phone"?e:!e}function h(t,e,r){return!(t&&r<t||e&&r>e)}function l(t,e){const r=Number(t.getItem(e));return Number.isFinite(r)&&r>0?r:null}function A(t,e,r,n){const o=u(t);if(e.afterSubmit==="stop"&&l(r.local,o.sentAt)!==null)return!0;if(e.hideAfter==="never")return!1;if(r.session.getItem(o.seen)==="1")return!0;if(e.hideAfter==="visit")return!1;const s=l(r.local,o.closedAt);return s===null?!1:e.hideAfter==="once"?!0:n-s<e.hideDays*c}function S(t,e,r){const n=u(t);e.session.setItem(n.seen,"1"),e.local.setItem(n.closedAt,String(r))}function y(t,e,r){S(t,e,r),e.local.setItem(u(t).sentAt,String(r))}function P(t,e,r,n,o){return!e.autoOpen||r.inEditor||!d(r.path,e.showOn,e.showOnPages)||!m(e.devices,r.isPhone)||!h(e.startDate,e.endDate,r.today)||(e.hideAfter!=="never"||e.afterSubmit==="stop")&&(!i(n.session)||!i(n.local))?!1:!A(t,e,n,o)}function $(t,e,r,n){return t.find(o=>P(o.id,o.behavior,e,r,n))??null}function O(t,e){return t==="exit"&&!e?"delay":t}function k(t,e,r){const n=r-e;return n<=0?100:Math.min(100,Math.max(0,t/n*100))}function v(t){const e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${e}-${r}-${n}`}export{p as POPUP_NEVER_ON,O as effectiveTrigger,v as localDay,S as markPopupClosed,y as markPopupSent,P as mayAutoOpen,f as normalizePath,$ as pickAutoPopup,m as popupAllowedOnDevice,d as popupAllowedOnPath,A as popupHidden,h as popupInSchedule,u as popupStorageKeys,k as scrolledPercent};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{ruleChecks as O}from"./rule.js";function j(r){const s=r.split(`
|
|
2
2
|
`),n=[];return s.forEach((g,a)=>{if(!/border-(top|bottom|left|right)[a-z-]*\s*:[^;]*\bsolid\b/.test(g))return;let $=0,c="?";for(let i=a-1;i>=0;i-=1)if($+=(s[i].match(/\}/g)??[]).length-(s[i].match(/\{/g)??[]).length,$<0){c=s[i].split("{")[0].trim();let h=i-1;for(;h>=0&&s[h].trim().endsWith(",");)c=`${s[h].trim()} ${c}`,h-=1;break}n.push({line:a+1,selector:c,decl:g.trim()})}),n}const y=r=>r.split(/[\s,+>~]/)[0].trim(),k=(r,s)=>s in r||y(s)in r,L=/\bzinc-|--sf-line\b|--sf-divider\b|--sf-input-border\b|--sf-chip-bg\b|--es-line\b|--es-divider\b|--sf-text-secondary\b/,S=[["utility",/(^|["'`\s])border-(t|b|l|r)($|["'`\s])/],["style object",/border(Top|Bottom|Left|Right)\s*:/],["css in a string",/border-(top|bottom|left|right)\s*:/]];function E(r){return/radius/i.test(r)||!L.test(r)?null:S.find(([,s])=>s.test(r))?.[0]??null}function T(r,s){const{check:n,report:g}=O("panel divider lines"),a=s.allowed??{},$=s.pendingElsewhere??{},c=s.allowedTsx??[];{const e=u=>["border",u].join("-"),t=[".a,",".b + .c {",` ${e("top")}: 1px solid red;`,"}",`.d { ${e("radius")}: 4px; }`].join(`
|
|
3
3
|
`),l=j(t);n("the census finds a directional solid border, with its whole multi-line selector",l.length===1&&l[0].selector===".a, .b + .c"&&y(l[0].selector)===".a",JSON.stringify(l));const d=["zinc","200"].join("-"),f=[["a utility",`<div className="${e("t")} border-${d}" />`,"utility"],["a style object",`style={{ ${["border","Top"].join("")}: "1px solid var(--sf-line)" }}`,"style object"],["CSS in a string",`const s = "${e("left")}: 1px solid var(--es-divider)";`,"css in a string"],["a border in the storefront's own ink",`<div className="${e("t")} border-line" />`,null],["a radius",`<div className="${e("t")} border-${d} rounded" style={{ borderRadius: 4 }} />`,null]];for(const[u,o,p]of f)n(`the sweep reads ${u} as ${p??"no hairline"}`,E(o)===p,o)}const i=[];for(const e of s.panelSheets??[]){const t=r.find(o=>o.path===e)?.text??"",l=j(t);n(`${e} was read and parsed`,t.length>1e4&&l.length>0,`${t.length} bytes, ${l.length} directional border(s)`),i.push(...l.map(o=>({...o,sheet:e})));const f=(t.replace(/\/\*[\s\S]*?\*\//g,"").match(/\[class\*="_PuckFields[^"]*"\][^{]*\{/g)??[]).length;n(`${e} reaches for no Puck field wrapper`,f===0,`${f} rule(s) still select \`[class*="_PuckFields…"]\` — the rows are \`.es-insp-row\` now`);const u=t.replace(/,\s*\n\s*/g,", ");for(const o of s.fullBleed??[]){if(!(o in a))continue;const p=u.indexOf(`
|
|
4
|
-
${o} {`);if(!n(`the allowed full-bleed rule is still in ${e}`,p>=0,o))continue;const v=u.slice(p,u.indexOf("}",p));for(const[w,x]of[["left","--es-insp-pad-x"],["right","--
|
|
4
|
+
${o} {`);if(!n(`the allowed full-bleed rule is still in ${e}`,p>=0,o))continue;const v=u.slice(p,u.indexOf("}",p));for(const[w,x]of[["left","--es-insp-pad-x"],["right","--es-insp-pad-end"]])n(`the full-bleed rule cancels the panel's ${w} padding, so it reaches the edge`,new RegExp(`margin-${w}:\\s*calc\\(var\\(${x}\\)\\s*\\*\\s*-1\\)`).test(v),"inset, this is the line the owner rejected — full bleed is the exemption"),n(`…and puts that ${w} padding back inside, so the words stay on the rows' edge`,new RegExp(`padding-${w}:\\s*var\\(${x}\\)`).test(v))}}for(const e of s.fullBleed??[])n(`the full-bleed selector is an ALLOWED entry: ${e}`,e in a);if(s.panelSheets?.length){const e=i.filter(t=>!k(a,t.selector)&&!k($,t.selector));n(`no unlisted directional border survives in a panel stylesheet (${i.length} censused)`,e.length===0,`${e.length} neither removed, allowed, nor owed to another card — delete it and let the rhythm tokens separate, or add it to the allow-list with a reason if it is a control edge:
|
|
5
5
|
`+e.map(t=>`${t.sheet}:${t.line} ${t.selector} — ${t.decl}`).join(`
|
|
6
6
|
`))}const h=e=>i.some(t=>t.selector===e||y(t.selector)===e);for(const[e,t]of Object.entries(a))n(`ALLOWED entry ${e} still names a real rule (${t.slice(0,48)}…)`,h(e),"the rule is gone: delete this entry with it");for(const[e,t]of Object.entries($))n(`PENDING entry ${e} is still owed — ${t}`,h(e),"that card has landed and the rule is gone: delete this entry");const b=r.filter(e=>/\.tsx?$/.test(e.path));n(`the repository's own TS/TSX files were swept (${b.length}, at least ${s.minFiles})`,b.length>=s.minFiles);const m=[];for(const e of b)e.text.split(`
|
|
7
7
|
`).forEach((t,l)=>{const d=E(t);d&&(c.some(f=>f.file===e.path&&t.includes(f.util))||m.push(`${e.path}:${l+1} (${d}) ${t.trim().slice(0,80)}`))});n("no editor panel file draws an unlisted directional border",m.length===0,`${m.length} found:
|
|
@@ -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
|
-
"use client";import{jsx as e,jsxs as
|
|
1
|
+
"use client";import{jsx as e,jsxs as o}from"react/jsx-runtime";import{useEffect as L,useMemo as F,useState as M}from"react";import{footprintPins as A}from"../../format/lib/content/footprint.js";import{bucketByGroup as B,groupColsClass as G}from"../../format/lib/locations-grid.js";import K from"./EditorialSectionHead.js";import{LocationGroupHeader as P}from"./LocationGroupHeader.js";import{renderGold as q,renderHeadline as D}from"./goldPhrases.js";import Q from"./PartStyledText.js";import{say as j}from"../../format/lib/editor-words.js";import{parseFootprintSource as I}from"../lib/dealer-source.js";import O from"./DealerFinder.js";import W from"./SiteMap.js";const n={bodySmall:"text-[length:var(--size-body,10px)]",bodyLarge:"text-[length:var(--size-body,18px)]",labelSmall:"text-[length:var(--size-label,11px)]",labelLarge:"text-[length:var(--size-label,12px)]"};function X({sectionNumber:c="",heading:i="",tagline:f="",offices:a=[],mapTheme:x="auto",padTop:b,padBottom:p,editing:d,omitHead:v=!1,source:s,search:u=!1,searchHint:r="",noMatchText:k="",listPosition:m="below",showDistance:C=!0}){const h=I(s)==="dealers",H=typeof b=="number"?b:120,T=typeof p=="number"?p:120,[S,N]=M(null),_=a.length===0&&!h&&!c&&!i&&!f;if(L(()=>{N(t=>t!==null&&t>=a.length?null:t)},[a]),_&&!d)return null;const z=B(a,t=>String(t.group??""),()=>"");return e("section",{className:"relative z-[2] bg-bg",children:o("div",{className:"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))]",style:{paddingTop:H,paddingBottom:T},children:[!v&&(c||i||f)&&e(K,{num:c,title:i?D(i):void 0,desc:f||void 0,spaceBelow:"mb-12"}),h?e(O,{mapLabel:i.replace(/[=*]/g,"").replace(/\s+/g," ").trim(),mapTheme:x,search:u,searchHint:r,noMatchText:k,listPosition:m,showDistance:C,editing:d}):e(Z,{offices:a,mapLabel:i.replace(/[=*]/g,"").replace(/\s+/g," ").trim(),mapTheme:x,activeIndex:S,onSelect:N,editing:d}),!h&&a.length>0&&e("div",{className:"mt-12 flex flex-col gap-8",children:z.map((t,E)=>o("div",{children:[t.key&&e(P,{groupKey:t.key,count:t.items.length}),e("div",{className:["grid gap-[2px] bg-bg",G(t.items.length),t.items.length>2?"max-[1100px]:grid-cols-2 max-[700px]:grid-cols-1":t.items.length===2?"max-[700px]:grid-cols-1":""].join(" "),children:t.items.map(({item:l,index:y})=>{const w=S===y,g=l.href&&l.linkLabel?{href:l.href,label:l.linkLabel}:null,$=o("button",{type:"button",onClick:()=>N(y),"aria-pressed":w,className:["flex flex-col gap-1.5 bg-bg px-6 py-5 text-left transition-colors outline outline-1 -outline-offset-1",w?"outline-accent":"outline-transparent hover:outline-line",g?"w-full pb-11":""].filter(Boolean).join(" "),children:[o("span",{className:`flex items-center gap-2.5 font-mono ${n.labelSmall} uppercase tracking-[0.28em]`,children:[l.hq&&e("span",{className:`border border-accent bg-accent px-1.5 py-0.5 ${n.bodySmall} text-bg`,children:"HQ"}),l.role&&e("span",{className:"text-accent",children:l.role})]}),l.city&&e("span",{className:`font-display ${n.bodyLarge} font-medium leading-[1.2] tracking-[-0.01em] text-fg`,children:e(Q,{value:l.city,children:l.city})}),l.country&&e("span",{className:`font-mono ${n.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:l.country}),l.address&&e("span",{className:`font-mono ${n.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:q(l.address)})]},g?void 0:y);return g?o("div",{className:"relative flex",children:[$,e("a",{href:g.href,className:`absolute bottom-5 left-6 font-mono ${n.labelSmall} uppercase tracking-[0.24em] text-accent hover:underline`,children:`→ ${g.label}`})]},y):$})})]},t.key?`g:${t.key}`:`ungrouped:${E}`))}),!h&&a.length===0&&d&&e("p",{className:`mt-8 font-mono ${n.labelLarge} uppercase tracking-[0.24em] text-fg-dim`,children:j("Add an office in the inspector")})]})})}function Z({offices:c,mapLabel:i,mapTheme:f,activeIndex:a,onSelect:x,editing:b}){const p=F(()=>A(c),[c]),[d,v]=M(null),s=a===null?null:String(a),u=s!==null&&p.some(m=>m.key===s);if(L(()=>{s!==null&&u&&v(m=>({key:s,n:(m?.n??0)+1}))},[s,u]),p.length===0)return b?e("div",{className:"relative flex aspect-[16/9] w-full items-center justify-center overflow-hidden border border-line bg-bg px-6 text-center max-[720px]:aspect-[4/5]",children:e("span",{className:`font-mono ${n.labelLarge} uppercase tracking-[0.24em] text-fg-dim`,children:j("Add office coordinates to plot the map")})}):null;const r=u&&a!==null?c[a]:null,k=r?o("div",{className:"flex items-start gap-3 border border-line bg-bg px-3.5 py-2.5 text-fg shadow-[0_8px_24px_rgba(0,0,0,.4)]",children:[o("div",{className:"min-w-0 flex-1",children:[o("div",{className:`flex items-center gap-2 font-mono ${n.labelSmall} uppercase tracking-[0.28em]`,children:[r.hq&&e("span",{className:`bg-accent px-1.5 py-px ${n.bodySmall} text-bg`,children:"HQ"}),r.role&&e("span",{className:"text-accent",children:r.role})]}),r.city&&e("div",{className:`mt-1.5 font-display ${n.bodyLarge} font-medium leading-[1.2] text-fg`,children:r.city}),r.country&&e("div",{className:`mt-1 font-mono ${n.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:r.country})]}),e("button",{type:"button",onClick:()=>x(null),"aria-label":"Close",className:"-mr-1 grid h-6 w-6 shrink-0 place-items-center text-fg-dim hover:text-fg",children:e("svg",{"aria-hidden":!0,width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e("path",{d:"M2 2l8 8M10 2l-8 8"})})})]}):null;return e(W,{pins:p,mapTheme:f,ariaLabel:i||"Offices",className:"sf-card relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",selectedKey:u?s:null,focus:d,onSelect:m=>x(Number(m)),card:k})}export{X as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as
|
|
2
|
-
*${
|
|
1
|
+
import{jsx as f}from"react/jsx-runtime";import u from"../../../../../components/Footprint.js";import{FOOTPRINT_DEFAULTS as s,footprintOfficeOfRow as l}from"../../../../../../format/lib/content/footprint.js";import{declaredBlockSource as d,sourcedRows as h}from"../../../../../../format/lib/content/block-sources.js";import{parseDealerListPosition as y,parseFootprintSource as g}from"../../../../dealer-source.js";import{hidableText as m}from"efficient-easel/draw";import{parseSectionHeadPlacement as T}from"../../../../../../format/lib/sections/section-head-placement.js";import{PH as r}from"../../../../../../format/lib/puck/blocks/placeholders.js";import{phRows as b,phHide as a}from"../../scaffold.js";import{say as t}from"../../../../../../format/lib/editor-words.js";const c={sectionNumber:r.sectionNumber,heading:`${r.heading}
|
|
2
|
+
*${r.accent}*`,tagline:r.body},w=()=>[{role:t("Headquarters"),city:t("City"),country:t("Country"),address:t("Street address"),lat:0,lng:0,hq:!0},{role:t("Office"),city:t("City"),country:t("Country"),address:t("Street address"),lat:0,lng:0,hq:!1}],P=()=>[{role:t("Headquarters"),city:t("City"),country:t("Country"),address:t("Street address"),hq:"true"},{role:t("Office"),city:t("City"),country:t("Country"),address:t("Street address")}];function S(e){const o=()=>b(e.offices,w(),e.puck);if(!d(e))return o();const i=e.puck?.isEditing===!0,n=h(e,i,P());return!n.sample&&!n.rows.length?o():n.rows.map(l)}const q={label:"Locations Map",defaultProps:{sectionNumber:"",heading:"",tagline:"",offices:[],mapTheme:s.mapTheme,padTop:120,padBottom:120,source:"typed",search:!1,searchHint:"",noMatchText:"",listPosition:"below",showDistance:!0},render:e=>{const o=T(e.headPlacement)==="own-box",i=n=>o?void 0:n;return f(u,{sectionNumber:i(a(e.sectionNumber,c.sectionNumber,e.puck)),heading:i(a(e.heading,c.heading,e.puck)),tagline:i(a(e.tagline,c.tagline,e.puck)),omitHead:o,offices:S(e),mapTheme:e.mapTheme??s.mapTheme,padTop:o?0:typeof e.padTop=="number"?e.padTop:120,padBottom:typeof e.padBottom=="number"?e.padBottom:120,editing:e.puck?.isEditing,source:d(e)?"typed":g(e.source),search:e.search===!0,searchHint:m(e.searchHint),noMatchText:m(e.noMatchText),listPosition:y(e.listPosition),showDistance:e.showDistance!==!1})}};export{c as FOOTPRINT_PH,q as FootprintRender};
|
|
@@ -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": "37.
|
|
3
|
+
"version": "37.2.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",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@types/node": "^20",
|
|
73
73
|
"@types/react": "^19",
|
|
74
74
|
"@types/react-dom": "^19",
|
|
75
|
-
"efficient-easel": "^18.
|
|
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",
|