efficient-web-builder 27.0.0 → 28.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,36 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 28.0.0 - 2026-10-20
6
+
7
+ A MAJOR: the `efficient-shell` peer range rises from `^7.75.0 || ^8.0.0` to `^8.2.0`, so a host on shell 7 or 8.0-8.1 must upgrade. Two changes ship: the Site styles tab strip (#207) and a card's blocks with no site gutter (#158).
8
+
9
+ **Site styles draws the shell's tab strip, like the section panel** (SSOT, harness UI-24; Lewis approved the look 2026-10-20).
10
+
11
+ ### Changed
12
+
13
+ - **The Site styles tabs are efficient-shell's `Tabs`**, drawn the way the section panel draws its own: the underline strip, equal shares (`block`), a glyph on each tab. Each tab shows its word beside the glyph while the words fit the panel, and drops it in three steps as the panel narrows (`labelsFit`, efficient-shell 8.2.0): every word, then only the open tab's word, then glyphs only. A hidden word still names its tab, and the tab's Tooltip says it. At 270px with Basics open the strip shows glyphs only (equal shares; Lewis 2026-10-20).
14
+ - It replaces efficient-easel's deprecated `SettingsTabs` (the pill strip with its own word-dropping sheet). No file in `src/` uses `SettingsTabs` now.
15
+ - `SITE_STYLES_TABS` is typed `SiteStylesTabItem[]`. The label-vocabulary rule reads any `<Name>TabItem[]` list; the old `SettingsTabItem[]` still matches.
16
+
17
+ ### For hosts
18
+
19
+ - **efficient-shell `^8.2.0`** (peer and dev; was `^7.75.0 || ^8.0.0`): `Tabs`' `labelsFit` is new in 8.2.0.
20
+
21
+ ### Guard
22
+
23
+ - `scripts/test-one-settings-tab-strip.ts`: no file in `src/` names `SettingsTabs` or `SettingsTabItem` in code, and Site styles draws the shell's `Tabs` with `labelsFit`.
24
+
25
+ **A Full-width card's blocks draw no site gutter** (plan item 13; Lewis approved the look, 2026-10-20). A visible change to live cards.
26
+
27
+ ### Changed for merchants
28
+
29
+ - **In a Box with a picture (a card), the card's own Padding is the only room at its sides: 40px, 24px on a phone.** The owner's A (2026-09-09). `.sf-box-sides > *` reached only the slot's element, so in a Full-width card every block still drew the site gutter on top of the Padding. The card's words layer now sets `--sf-site-gutter: 0px`, which reaches the blocks at any depth, on the page and in the editor. ⚠️ The words of every published Full-width card move 40px (24px on a phone) toward its edges. A Contained card does not move (its blocks already took the fill class).
30
+
31
+ ### Guards
32
+
33
+ - New `scripts/test-box-card-sides.tsx`: a card's words layer sets `--sf-site-gutter` to 0, with or without a wash, Full width or Contained; a Box with no picture keeps the gutter. Red before the change.
34
+
5
35
  ## 27.0.0 - 2026-10-20
6
36
 
7
37
  **The settings panels read easel's one side inset** (GG option A, 2026-10-20). A MAJOR: the `efficient-easel` peer range rises from `^13.3.0 || ^14.0.0` to `^14.1.0`, and the dev range from `^14.0.0`.
@@ -1,5 +1,4 @@
1
- import { type RefObject } from "react";
2
- import { type SettingsTabItem } from "efficient-easel/panel";
1
+ import { type ReactNode, type RefObject } from "react";
3
2
  import type { SiteThemeRowPatch } from "../../format/lib/site-theme-row.js";
4
3
  import { type CardShadow, type HoverEffect } from "../../format/lib/theme.js";
5
4
  export declare const SITE_STYLES_ID_PREFIX = "sf-site-styles";
@@ -10,7 +9,12 @@ export declare function HintsToggle({ shown, onChange, }: {
10
9
  onChange: (v: boolean) => void;
11
10
  }): import("react").JSX.Element;
12
11
  export declare const SITE_STYLES_TEXT_TAB = "text";
13
- export declare const SITE_STYLES_TABS: SettingsTabItem[];
12
+ export type SiteStylesTabItem = {
13
+ id: string;
14
+ label: string;
15
+ icon?: ReactNode;
16
+ };
17
+ export declare const SITE_STYLES_TABS: SiteStylesTabItem[];
14
18
  export declare function siteWidthPatch(v: number | null): SiteThemeRowPatch;
15
19
  export declare function blockGapPatch(v: number | null): SiteThemeRowPatch;
16
20
  export declare function siteGutterPatch(v: number | null): SiteThemeRowPatch;
@@ -45,3 +49,7 @@ export default function WebsiteSettingsPanel({ themeFromDocument, tokenRef, site
45
49
  onTabChange?: (id: string) => void;
46
50
  onNotify?: (msg: string, tone?: "success" | "error") => void;
47
51
  }): import("react").JSX.Element;
52
+ export declare function SiteStylesTabStrip({ activeId, onSelect, }: {
53
+ activeId: string;
54
+ onSelect: (id: string) => void;
55
+ }): import("react").JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as o,jsxs as _,Fragment as x}from"react/jsx-runtime";import{useEasel as F}from"efficient-easel/easel";import{useState as P}from"react";import N from"./ThemeField.js";import k from"./CornersField.js";import z from"./CardShadowField.js";import O from"./ShadowColourField.js";import W from"./BlockGapField.js";import v from"./HoverEffectField.js";import G from"./HeroImageField.js";import Y from"./PhotographyField.js";import j from"./ShareButtonField.js";import X from"./SideSpaceField.js";import U from"./SiteWidthField.js";import q from"./SiteAccentField.js";import K from"./SiteTextStylesField.js";import{usePreviewHeader as p}from"../../render/components/PreviewHeaderContext.js";import{SettingsTabs as M}from"efficient-easel/panel";import{Tooltip as $,tabButtonId as J,tabPanelId as Q}from"efficient-shell/ui";import{ContrastIcon as V,NoteIcon as Z,SettingsIcon as D,TypeIcon as ee}from"efficient-easel/icons";import{useThemeRowPersist as te}from"../lib/theme-row-persist.js";import{themeSaveNotice as oe}from"../../format/lib/theme-save-message.js";import{say as S}from"../../format/lib/editor-words.js";import{NEUTRAL_SITE_NAME as ne}from"../../format/lib/content/site-name.js";import{previewFrame as re}from"../lib/puck/preview-dom.js";import{useSiteTextStylesWriter as ie}from"../lib/site-text-styles-writer.js";import{CORNER_STYLE_TO_PX as se,normalizeCornerRadius as ae,normalizeCornerStyle as ce,normalizeShadowColor as le,selectedThemeColors as he}from"../../format/lib/theme.js";const R="sf-site-styles",de="sf-site-styles-tabpanel",ue=!1,pe="Show hints";function fe({shown:e,onChange:t}){return o("div",{className:"sf-hints",children:_("button",{type:"button","aria-pressed":e,onClick:()=>t(!e),className:`sf-rung sf-hints-toggle${e?" is-active":""}`,children:[o(Z,{size:13}),S(pe)]})})}const gt="text",b=[{id:"basics",label:"Basics",icon:o(D,{})},{id:"theme",label:"Theme",icon:o(V,{})},{id:"text",label:"Text",icon:o(ee,{})}];function ge({themeFromDocument:e,persist:t}){const{appState:i,dispatch:s}=F(d=>d),{theme:l,setTheme:n}=p(),h=i.data,u=h.root?.props??{},a=d=>{if(e){const f={...u,theme:d};s({type:"replaceRoot",root:{...h.root,props:f},recordHistory:!0})}else n(d);t({selected_preset:d.selected,theme_presets:d.themes})};return o(N,{value:e?u.theme:l,onChange:a})}function me({themeFromDocument:e,persist:t}){const[i,s]=P(null),{theme:l,setFonts:n,setSizes:h,setHeadingTypography:u}=p(),a=ie({themeFromDocument:e,persist:t}),{old:d,saved:f,writeRoot:C}=a,w=a.fonts,c=a.sizes,y=a.typography,g=r=>r.values.size??_e(Ce[r.id]??"body")??we[r.kind],T=r=>a.write(r),E=Se(l),I=r=>{const m={...w,accent:r};e?C({fonts:m}):n(m),t({accent_font:r})},L=r=>{h({...c,accent:r}),t({accent_size_px:r})},A=r=>{const m={...y,weightStrong:r};e?C({headingTypography:m}):u(m),t({heading_weight_strong:r})},B=r=>{const m={...y,italicStrong:r};e?C({headingTypography:m}):u(m),t({accent_italic:r})};return _(x,{children:[o(K,{saved:f,old:d,colours:E,sizeOf:g,onChange:T,openId:i===H?null:i,onOpenChange:s,withoutSize:e}),o(q,{font:w.accent,size:c.accent,weight:y.weightStrong,italic:y.italicStrong,headingWeight:y.weight,open:i===H,onOpenChange:r=>s(r?H:null),onChange:r=>{r.key==="font"?I(r.value):r.key==="size"?L(r.value):r.key==="weight"?A(r.value):B(r.value)},withoutSize:e})]})}const H="accent";function Se(e){const t=he(e);return[{key:"accent",name:S("Accent"),value:t.accent},{key:"text",name:S("Text"),value:t.text},{key:"labels",name:S("Labels"),value:t.muted??t.text}]}const Ce={"heading-1":"heading","heading-2":"heading2","heading-3":"heading3","body-1":"body","body-5":"label"},we={heading:32,body:14},ye={heading:"main h1, main h2",heading2:"main h1, main h2",heading3:"main h1, main h2",accent:"main h1 em, main h2 em",body:"main p",label:"main .mono-eyebrow"};function _e(e){if(typeof document>"u")return null;const i=(re()?.contentDocument??document).querySelector(ye[e]);if(!i)return null;const s=parseFloat(getComputedStyle(i).fontSize);return Number.isFinite(s)?s:null}function xe({themeFromDocument:e,persist:t,showHint:i}){const{appState:s,dispatch:l}=F(c=>c),{cornerRadiusPx:n,setCornerRadiusPx:h}=p(),u=s.data,a=u.root?.props??{},d=a.cornerRadiusPx===void 0?se[ce(a.cornerStyle)]:ae(a.cornerRadiusPx),f=e?d:n,C=c=>l({type:"replaceRoot",root:{...u.root,props:{...a,...c}},recordHistory:!0});return o(k,{value:f,onChange:c=>{e?C({cornerRadiusPx:c}):h(c),t({corner_radius_px:c})},showHint:i})}function Te(e){return{site_width:e}}function be({persist:e,showHint:t}){const{siteWidth:i,setSiteWidth:s}=p();return o(U,{value:i,onChange:n=>{s(n),e(Te(n),n===null)},showHint:t})}function Pe(e){return{block_gap:e}}function Re(e){return{site_gutter:e}}function He({persist:e,showHint:t}){const{siteGutter:i,setSiteGutter:s}=p();return o(X,{value:i,onChange:n=>{s(n),e(Re(n),n===null)},showHint:t})}function Fe({persist:e,showHint:t}){const{blockGap:i,setBlockGap:s}=p();return o(W,{value:i,onChange:n=>{s(n),e(Pe(n),n===null)},showHint:t})}function Ee({persist:e,showHint:t}){const{heroBackgroundFollowsWidth:i,setHeroBackgroundFollowsWidth:s}=p();return o(G,{value:i,onChange:n=>{s(n),e({hero_background_follows_width:n},!0)},showHint:t})}function Ie({persist:e,showHint:t=!0}){return _(x,{children:[o(be,{persist:e,showHint:t}),o(He,{persist:e,showHint:t}),o(Fe,{persist:e,showHint:t}),o(Ee,{persist:e,showHint:t})]})}function Le(e){return{card_shadow:e}}function Ae(e){return e===null?{shadow_color:null}:{shadow_color:le(e)}}function Be(e){return{hover_effect:e}}function Ne({persist:e,showHint:t=!0}){const{cardShadow:i,setCardShadow:s,shadowColor:l,setShadowColor:n,hoverEffect:h,setHoverEffect:u}=p();return _(x,{children:[o(z,{value:i,onChange:a=>{s(a),e(Le(a),!0)},showHint:t}),o(O,{value:l,onChange:a=>{n(a),e(Ae(a),a===null)},showHint:t}),o(v,{value:h,onChange:a=>{u(a),e(Be(a),!0)},showHint:t})]})}function ke(e){return{photography_grayscale:e}}function ze({persist:e,showHint:t}){const{photographyGrayscale:i,setPhotographyGrayscale:s}=p();return o(Y,{value:i,onChange:n=>{s(n),e(ke(n),!0)},showHint:t})}function Oe({persist:e,showHint:t=!0}){return o(x,{children:o(ze,{persist:e,showHint:t})})}function We(e){return{share_button_on_posts:e}}function ve({persist:e,showHint:t=!0}){const{shareButtonOnPosts:i,setShareButtonOnPosts:s}=p();return o(j,{value:i,onChange:n=>{s(n),e(We(n),!0)},showHint:t})}function Ge(){const{websiteName:e}=p();return e?.trim()||ne}function mt(){const e=Ge();return o($,{content:S("{name} — renamed in the Console: {place}.",{name:e,place:S("Storefront ▸ Sites ▸ Settings")}),className:"sf-name-tip",children:o("span",{className:"sf-panel-site",children:e})})}function Ye({themeFromDocument:e=!1,tokenRef:t,siteId:i,onNotify:s,tab:l,onTabChange:n}){const{persist:h}=te({themeFromDocument:e,tokenRef:t,siteId:i,onResult:g=>{const T=oe(g);T&&s?.(T.msg,T.tone)}}),[u,a]=P(b[0].id),d=l!==void 0,f=d?l:u,C=d?n??(()=>{}):a,w=b.find(g=>g.id===f)??b[0],[c,y]=P(ue);return _(x,{children:[o(M,{items:b.map(g=>({...g,label:S(g.label)})),activeId:w.id,onSelect:C,ariaLabel:S("Site styles"),idPrefix:R}),_("div",{id:Q(R,w.id),className:de,role:"tabpanel","aria-labelledby":J(R,w.id),children:[f==="basics"&&_(x,{children:[o(xe,{themeFromDocument:e,persist:h,showHint:c}),!e&&o(Ne,{persist:h,showHint:c}),!e&&o(Ie,{persist:h,showHint:c}),!e&&o(Oe,{persist:h,showHint:c}),!e&&o(ve,{persist:h,showHint:c}),o(fe,{shown:c,onChange:y})]}),f==="theme"&&o(ge,{themeFromDocument:e,persist:h}),f==="text"&&o(me,{themeFromDocument:e,persist:h})]})]})}export{Ne as CardLookFields,fe as HintsToggle,Ie as PageGroupFields,Oe as PhotographyGroupFields,ue as SHOW_HINTS_DEFAULT,R as SITE_STYLES_ID_PREFIX,b as SITE_STYLES_TABS,gt as SITE_STYLES_TEXT_TAB,ve as ShareButtonRootField,de as TABPANEL_CLASS,mt as WebsiteNameReadonly,Pe as blockGapPatch,Le as cardShadowPatch,Ye as default,Be as hoverEffectPatch,ke as photographyPatch,Ae as shadowColourPatch,We as shareButtonPatch,Re as siteGutterPatch,Te as siteWidthPatch,Ge as useWebsiteName};
1
+ "use client";import{jsx as o,jsxs as y,Fragment as _}from"react/jsx-runtime";import{useEasel as F}from"efficient-easel/easel";import{useState as P}from"react";import A from"./ThemeField.js";import B from"./CornersField.js";import L from"./CardShadowField.js";import z from"./ShadowColourField.js";import O from"./BlockGapField.js";import W from"./HoverEffectField.js";import G from"./HeroImageField.js";import Y from"./PhotographyField.js";import j from"./ShareButtonField.js";import X from"./SideSpaceField.js";import U from"./SiteWidthField.js";import q from"./SiteAccentField.js";import K from"./SiteTextStylesField.js";import{usePreviewHeader as p}from"../../render/components/PreviewHeaderContext.js";import{Tabs as M,Tooltip as $,tabButtonId as J,tabPanelId as Q}from"efficient-shell/ui";import{ContrastIcon as V,NoteIcon as Z,SettingsIcon as D,TypeIcon as ee}from"efficient-easel/icons";import{useThemeRowPersist as te}from"../lib/theme-row-persist.js";import{themeSaveNotice as oe}from"../../format/lib/theme-save-message.js";import{say as m}from"../../format/lib/editor-words.js";import{NEUTRAL_SITE_NAME as ne}from"../../format/lib/content/site-name.js";import{previewFrame as re}from"../lib/puck/preview-dom.js";import{useSiteTextStylesWriter as ie}from"../lib/site-text-styles-writer.js";import{CORNER_STYLE_TO_PX as se,normalizeCornerRadius as ae,normalizeCornerStyle as ce,normalizeShadowColor as le,selectedThemeColors as he}from"../../format/lib/theme.js";const R="sf-site-styles",de="sf-site-styles-tabpanel",ue=!1,pe="Show hints";function fe({shown:e,onChange:t}){return o("div",{className:"sf-hints",children:y("button",{type:"button","aria-pressed":e,onClick:()=>t(!e),className:`sf-rung sf-hints-toggle${e?" is-active":""}`,children:[o(Z,{size:13}),m(pe)]})})}const gt="text",T=[{id:"basics",label:"Basics",icon:o(D,{})},{id:"theme",label:"Theme",icon:o(V,{})},{id:"text",label:"Text",icon:o(ee,{})}];function ge({themeFromDocument:e,persist:t}){const{appState:n,dispatch:i}=F(d=>d),{theme:l,setTheme:r}=p(),h=n.data,u=h.root?.props??{},a=d=>{if(e){const f={...u,theme:d};i({type:"replaceRoot",root:{...h.root,props:f},recordHistory:!0})}else r(d);t({selected_preset:d.selected,theme_presets:d.themes})};return o(A,{value:e?u.theme:l,onChange:a})}function me({themeFromDocument:e,persist:t}){const[n,i]=P(null),{theme:l,setFonts:r,setSizes:h,setHeadingTypography:u}=p(),a=ie({themeFromDocument:e,persist:t}),{old:d,saved:f,writeRoot:S}=a,C=a.fonts,c=a.sizes,w=a.typography,x=s=>s.values.size??_e(Ce[s.id]??"body")??we[s.kind],b=s=>a.write(s),E=Se(l),I=s=>{const g={...C,accent:s};e?S({fonts:g}):r(g),t({accent_font:s})},N=s=>{h({...c,accent:s}),t({accent_size_px:s})},k=s=>{const g={...w,weightStrong:s};e?S({headingTypography:g}):u(g),t({heading_weight_strong:s})},v=s=>{const g={...w,italicStrong:s};e?S({headingTypography:g}):u(g),t({accent_italic:s})};return y(_,{children:[o(K,{saved:f,old:d,colours:E,sizeOf:x,onChange:b,openId:n===H?null:n,onOpenChange:i,withoutSize:e}),o(q,{font:C.accent,size:c.accent,weight:w.weightStrong,italic:w.italicStrong,headingWeight:w.weight,open:n===H,onOpenChange:s=>i(s?H:null),onChange:s=>{s.key==="font"?I(s.value):s.key==="size"?N(s.value):s.key==="weight"?k(s.value):v(s.value)},withoutSize:e})]})}const H="accent";function Se(e){const t=he(e);return[{key:"accent",name:m("Accent"),value:t.accent},{key:"text",name:m("Text"),value:t.text},{key:"labels",name:m("Labels"),value:t.muted??t.text}]}const Ce={"heading-1":"heading","heading-2":"heading2","heading-3":"heading3","body-1":"body","body-5":"label"},we={heading:32,body:14},ye={heading:"main h1, main h2",heading2:"main h1, main h2",heading3:"main h1, main h2",accent:"main h1 em, main h2 em",body:"main p",label:"main .mono-eyebrow"};function _e(e){if(typeof document>"u")return null;const n=(re()?.contentDocument??document).querySelector(ye[e]);if(!n)return null;const i=parseFloat(getComputedStyle(n).fontSize);return Number.isFinite(i)?i:null}function xe({themeFromDocument:e,persist:t,showHint:n}){const{appState:i,dispatch:l}=F(c=>c),{cornerRadiusPx:r,setCornerRadiusPx:h}=p(),u=i.data,a=u.root?.props??{},d=a.cornerRadiusPx===void 0?se[ce(a.cornerStyle)]:ae(a.cornerRadiusPx),f=e?d:r,S=c=>l({type:"replaceRoot",root:{...u.root,props:{...a,...c}},recordHistory:!0});return o(B,{value:f,onChange:c=>{e?S({cornerRadiusPx:c}):h(c),t({corner_radius_px:c})},showHint:n})}function be(e){return{site_width:e}}function Te({persist:e,showHint:t}){const{siteWidth:n,setSiteWidth:i}=p();return o(U,{value:n,onChange:r=>{i(r),e(be(r),r===null)},showHint:t})}function Pe(e){return{block_gap:e}}function Re(e){return{site_gutter:e}}function He({persist:e,showHint:t}){const{siteGutter:n,setSiteGutter:i}=p();return o(X,{value:n,onChange:r=>{i(r),e(Re(r),r===null)},showHint:t})}function Fe({persist:e,showHint:t}){const{blockGap:n,setBlockGap:i}=p();return o(O,{value:n,onChange:r=>{i(r),e(Pe(r),r===null)},showHint:t})}function Ee({persist:e,showHint:t}){const{heroBackgroundFollowsWidth:n,setHeroBackgroundFollowsWidth:i}=p();return o(G,{value:n,onChange:r=>{i(r),e({hero_background_follows_width:r},!0)},showHint:t})}function Ie({persist:e,showHint:t=!0}){return y(_,{children:[o(Te,{persist:e,showHint:t}),o(He,{persist:e,showHint:t}),o(Fe,{persist:e,showHint:t}),o(Ee,{persist:e,showHint:t})]})}function Ne(e){return{card_shadow:e}}function ke(e){return e===null?{shadow_color:null}:{shadow_color:le(e)}}function ve(e){return{hover_effect:e}}function Ae({persist:e,showHint:t=!0}){const{cardShadow:n,setCardShadow:i,shadowColor:l,setShadowColor:r,hoverEffect:h,setHoverEffect:u}=p();return y(_,{children:[o(L,{value:n,onChange:a=>{i(a),e(Ne(a),!0)},showHint:t}),o(z,{value:l,onChange:a=>{r(a),e(ke(a),a===null)},showHint:t}),o(W,{value:h,onChange:a=>{u(a),e(ve(a),!0)},showHint:t})]})}function Be(e){return{photography_grayscale:e}}function Le({persist:e,showHint:t}){const{photographyGrayscale:n,setPhotographyGrayscale:i}=p();return o(Y,{value:n,onChange:r=>{i(r),e(Be(r),!0)},showHint:t})}function ze({persist:e,showHint:t=!0}){return o(_,{children:o(Le,{persist:e,showHint:t})})}function Oe(e){return{share_button_on_posts:e}}function We({persist:e,showHint:t=!0}){const{shareButtonOnPosts:n,setShareButtonOnPosts:i}=p();return o(j,{value:n,onChange:r=>{i(r),e(Oe(r),!0)},showHint:t})}function Ge(){const{websiteName:e}=p();return e?.trim()||ne}function mt(){const e=Ge();return o($,{content:m("{name} — renamed in the Console: {place}.",{name:e,place:m("Storefront ▸ Sites ▸ Settings")}),className:"sf-name-tip",children:o("span",{className:"sf-panel-site",children:e})})}function Ye({themeFromDocument:e=!1,tokenRef:t,siteId:n,onNotify:i,tab:l,onTabChange:r}){const{persist:h}=te({themeFromDocument:e,tokenRef:t,siteId:n,onResult:x=>{const b=oe(x);b&&i?.(b.msg,b.tone)}}),[u,a]=P(T[0].id),d=l!==void 0,f=d?l:u,S=d?r??(()=>{}):a,C=T.find(x=>x.id===f)??T[0],[c,w]=P(ue);return y(_,{children:[o(je,{activeId:C.id,onSelect:S}),y("div",{id:Q(R,C.id),className:de,role:"tabpanel","aria-labelledby":J(R,C.id),children:[f==="basics"&&y(_,{children:[o(xe,{themeFromDocument:e,persist:h,showHint:c}),!e&&o(Ae,{persist:h,showHint:c}),!e&&o(Ie,{persist:h,showHint:c}),!e&&o(ze,{persist:h,showHint:c}),!e&&o(We,{persist:h,showHint:c}),o(fe,{shown:c,onChange:w})]}),f==="theme"&&o(ge,{themeFromDocument:e,persist:h}),f==="text"&&o(me,{themeFromDocument:e,persist:h})]})]})}function je({activeId:e,onSelect:t}){return o("div",{className:"es-insp-tabs",children:o(M,{variant:"underline",block:!0,labelsFit:!0,"aria-label":m("Site styles"),idPrefix:R,value:e,onChange:t,items:T.map(n=>{const i=m(n.label);return{id:n.id,icon:n.icon,label:i}})})})}export{Ae as CardLookFields,fe as HintsToggle,Ie as PageGroupFields,ze as PhotographyGroupFields,ue as SHOW_HINTS_DEFAULT,R as SITE_STYLES_ID_PREFIX,T as SITE_STYLES_TABS,gt as SITE_STYLES_TEXT_TAB,We as ShareButtonRootField,je as SiteStylesTabStrip,de as TABPANEL_CLASS,mt as WebsiteNameReadonly,Pe as blockGapPatch,Ne as cardShadowPatch,Ye as default,ve as hoverEffectPatch,Be as photographyPatch,ke as shadowColourPatch,Oe as shareButtonPatch,Re as siteGutterPatch,be as siteWidthPatch,Ge as useWebsiteName};
@@ -1,6 +1,6 @@
1
- import{failedChecks as C,ruleChecks as w}from"./rule.js";import{isPanelFile as j,readLabels as H,readPanelLabels as R}from"./support/label-extraction.js";import{registryFiles as $}from"./support/registry-source.js";const g=["kicker","tagline","headline","blurb","description","copy","paragraph","photo","picture","cta","kind","class","grayscale","greyscale","colour","align","align items","text alignment","centre","catalogue","behaviour","labelled","stylised","stack","container","gutter","margin","site width","max width","contained","boxed","header offset","clearance","typeface","font family","leading","character spacing","kerning","text transform"],S=o=>o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),B=g.map(o=>({word:o,pattern:new RegExp(`\\b${S(o)}s?\\b`)}));function P(o){return o.split(/\(| — /)[0].trim()}function F(o){const s=new Set;for(const l of $(o))for(const a of l.text.matchAll(/\{[^{}]*\btype:\s*"slot"[^{}]*\}/g)){const t=/\ballow:\s*\[([^\]]*)\]/.exec(a[0]);for(const r of t?.[1].matchAll(/"([A-Za-z0-9_]+)"/g)??[])s.add(r[1])}return s}const A=o=>/^lib\/puck\/blocks\/[^/]+\/([^/]+)\//.exec(o)?.[1]??null;function m(o,s){const l=P(o).toLowerCase(),a=[];for(const{word:r,pattern:n}of B)n.test(l)&&a.push(`N10.1 "${r}"`);/^title\b/.test(l)&&s==="section"&&a.push("N10.2 Title at section level"),/^heading\b/.test(l)&&s==="item"&&a.push("N10.2 Heading at item level");const t=/\b(button|link)\s+(text|label|href|url)$/.exec(l);return t&&a.push(`N10.3 "${t[1]} ${t[2]}"`),l==="text"&&a.push("N10.4 bare Text"),a}function v(o,s,l){const a=$(o),t=o.filter(j),r=F(o),n=new Map,c=[],f=(e,i)=>{for(const p of e){const k=i(p.text);n.set(p.path,k.length);const T=r.has(A(p.path)??"");for(const x of k){const N=x.item?"item":T?"slot child":"section";c.push({...x,file:p.path,level:N,why:m(x.label,N)})}}};f(a,H),f(t,R);for(const[e,i]of Object.entries(s.floors)){const p=n.get(e);l(`${e} yields >= ${i} labels (found ${p??"none: not read"})`,p!==void 0&&p>=i,p===void 0?"it has a floor but was not read — it dropped out of the panels and the registry":"the reader is broken, not the panel")}const d=a.reduce((e,i)=>e+(n.get(i.path)??0),0);l(`the block registry yields >= ${s.minRegistryLabels} labels across ${a.length} files (found ${d})`,d>=s.minRegistryLabels,"the reader is broken, not the panel");const h=c.filter(e=>e.why.length>0),y=e=>s.parked.some(i=>i.file===e.file&&i.label===e.label),b=h.filter(e=>!y(e)),u=e=>c.filter(i=>i.level===e).length;l(`every field label obeys N10.1–N10.4 (${c.length} read across ${a.length+t.length} files: ${u("section")} section-level, ${u("item")} item-level, ${u("slot child")} in a slot child of ${[...r].sort().join(", ")||"none"})`,b.length===0,`${b.length} break doc/naming.md N10:
1
+ import{failedChecks as C,ruleChecks as w}from"./rule.js";import{isPanelFile as j,readLabels as H,readPanelLabels as S}from"./support/label-extraction.js";import{registryFiles as $}from"./support/registry-source.js";const g=["kicker","tagline","headline","blurb","description","copy","paragraph","photo","picture","cta","kind","class","grayscale","greyscale","colour","align","align items","text alignment","centre","catalogue","behaviour","labelled","stylised","stack","container","gutter","margin","site width","max width","contained","boxed","header offset","clearance","typeface","font family","leading","character spacing","kerning","text transform"],R=o=>o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),B=g.map(o=>({word:o,pattern:new RegExp(`\\b${R(o)}s?\\b`)}));function P(o){return o.split(/\(| — /)[0].trim()}function F(o){const s=new Set;for(const l of $(o))for(const a of l.text.matchAll(/\{[^{}]*\btype:\s*"slot"[^{}]*\}/g)){const t=/\ballow:\s*\[([^\]]*)\]/.exec(a[0]);for(const r of t?.[1].matchAll(/"([A-Za-z0-9_]+)"/g)??[])s.add(r[1])}return s}const A=o=>/^lib\/puck\/blocks\/[^/]+\/([^/]+)\//.exec(o)?.[1]??null;function m(o,s){const l=P(o).toLowerCase(),a=[];for(const{word:r,pattern:n}of B)n.test(l)&&a.push(`N10.1 "${r}"`);/^title\b/.test(l)&&s==="section"&&a.push("N10.2 Title at section level"),/^heading\b/.test(l)&&s==="item"&&a.push("N10.2 Heading at item level");const t=/\b(button|link)\s+(text|label|href|url)$/.exec(l);return t&&a.push(`N10.3 "${t[1]} ${t[2]}"`),l==="text"&&a.push("N10.4 bare Text"),a}function v(o,s,l){const a=$(o),t=o.filter(j),r=F(o),n=new Map,c=[],f=(e,i)=>{for(const p of e){const k=i(p.text);n.set(p.path,k.length);const T=r.has(A(p.path)??"");for(const x of k){const N=x.item?"item":T?"slot child":"section";c.push({...x,file:p.path,level:N,why:m(x.label,N)})}}};f(a,H),f(t,S);for(const[e,i]of Object.entries(s.floors)){const p=n.get(e);l(`${e} yields >= ${i} labels (found ${p??"none: not read"})`,p!==void 0&&p>=i,p===void 0?"it has a floor but was not read — it dropped out of the panels and the registry":"the reader is broken, not the panel")}const d=a.reduce((e,i)=>e+(n.get(i.path)??0),0);l(`the block registry yields >= ${s.minRegistryLabels} labels across ${a.length} files (found ${d})`,d>=s.minRegistryLabels,"the reader is broken, not the panel");const h=c.filter(e=>e.why.length>0),y=e=>s.parked.some(i=>i.file===e.file&&i.label===e.label),b=h.filter(e=>!y(e)),u=e=>c.filter(i=>i.level===e).length;l(`every field label obeys N10.1–N10.4 (${c.length} read across ${a.length+t.length} files: ${u("section")} section-level, ${u("item")} item-level, ${u("slot child")} in a slot child of ${[...r].sort().join(", ")||"none"})`,b.length===0,`${b.length} break doc/naming.md N10:
2
2
  `+b.map(e=>` ${e.file}:${e.line} [${e.level}] ${JSON.stringify(e.label)} — ${e.why.join(", ")}`).join(`
3
3
  `));for(const e of s.parked)l(`PARKED ${e.file} ${JSON.stringify(e.label)} still breaks N10 — ${e.why}`,h.some(i=>i.file===e.file&&i.label===e.label),"it no longer breaks N10 (renamed, or its row deleted) — take it out of the list");return{read:c,live:b,slotChildren:r}}function E(o,s){const{check:l,report:a}=w("label vocabulary");l(`N10.1 forbids ${g.length} words, each written once, lower-case and trimmed: ${[...g].sort().join(", ")}`,g.length>0&&new Set(g).size===g.length&&g.every(t=>t===t.trim().toLowerCase()&&t.length>0),JSON.stringify(g));{const t=(n,c=!1)=>m(n,c?"item":"section"),r=g.filter(n=>{const c=`N10.1 "${n}"`,f=n[0].toUpperCase()+n.slice(1);return!t(f).includes(c)||!t(`Card ${n}s`).includes(c)});l("N10.1 catches every word on the list, alone and as a qualified plural",r.length===0,r.join(", ")),l("N10.1 …but not inside a longer word",t("Copyright").length===0&&t("Classic layout").length===0&&t("Stacking order").length===0,JSON.stringify([t("Copyright"),t("Classic layout"),t("Stacking order")])),l("N10.2 a section's label may not start Title, an item's may not start Heading",t("Title").includes("N10.2 Title at section level")&&t("Heading",!0).includes("N10.2 Heading at item level")),l("N10.2 …and each is right at its own level",t("Heading").length===0&&t("Title",!0).length===0&&t("Card title").length===0&&t("Section heading",!0).length===0),l("N10.2 a slot child's label may start with either word, and N10.1 still holds there",m("Title","slot child").length===0&&m("Heading","slot child").length===0&&m("Headline","slot child").includes('N10.1 "headline"')),l("N10.3 nothing follows `button` or `link`",t("Button text").includes('N10.3 "button text"')&&t("Submit button label").includes('N10.3 "button label"')&&t("Link href").includes('N10.3 "link href"')&&t("Archive link URL").includes('N10.3 "link url"')),l("N10.3 …and the pair itself passes",t("Button").length===0&&t("Button link").length===0&&t("Archive link").length===0),l("N10.4 a bare Text fails; Alt text is a name",t("Text").includes("N10.4 bare Text")&&t("Alt text").length===0),l("the name is cut at a hint tail, so a hint cannot corrupt the verdict",t("Body (blank line = new paragraph)").length===0&&t("Copy — the words under it").includes('N10.1 "copy"'))}{const t=[{path:"lib/puck/config.tsx",text:['heading: plainText("Heading"),','eyebrow: plainText("Kicker"),','title: plainText("Title"),','cards: { type: "array", label: "Cards",'," arrayFields: {",' heading: plainText("Heading"),',' title: plainText("Card title"),'," },","},",'layout: { type: "select", label: "Layout",',' options: [{ label: "Centre", value: "center" }] },'].join(`
4
- `)},{path:"components/FixturePanel.tsx",text:['import { SettingsField } from "efficient-easel/panel";',"const items = [",' { label: "Copy", onClick: () => copy() },',"];","const rows = [",' { key: "photo", label: "Photo", group: "media" },',"];","const tabs: SettingsTabItem[] = [",' { id: "text", label: "Text" },',"];",'<SettingsField label="Colour" />'].join(`
4
+ `)},{path:"components/FixturePanel.tsx",text:['import { SettingsField } from "efficient-easel/panel";',"const items = [",' { label: "Copy", onClick: () => copy() },',"];","const rows = [",' { key: "photo", label: "Photo", group: "media" },',"];","const tabs: SiteStylesTabItem[] = [",' { id: "text", label: "Text" },',"];",'<SettingsField label="Colour" />'].join(`
5
5
  `)},{path:"lib/puck/blocks/commerce/GalleryB/render.tsx",text:'export const GalleryBSlots = { items: { type: "slot", allow: ["GalleryItem"] } };'},{path:"lib/puck/blocks/commerce/GalleryItem/fields.tsx",text:['name: text("Title"),','photo: upload("Photo"),'].join(`
6
6
  `)},{path:"lib/puck/blocks/service/AppointmentBooking/render.tsx",text:'export const Slots = { boxes: { type: "slot", allow: ["BookingBox"] } };'},{path:"lib/puck/blocks/service/BookingBox/fields.tsx",text:'heading: plainTextarea("Heading"),'},{path:"components/HandRolled.tsx",text:'<div className="sf-field"><Row label="Gutter" /></div>'},{path:"components/ShopperForm.tsx",text:'<Field label="Description" />'}],r=w("fixture"),{read:n,live:c,slotChildren:f}=v(t,{floors:{"components/FixturePanel.tsx":5,"components/HandRolled.tsx":1,"components/Moved.tsx":1},minRegistryLabels:11,parked:[{file:"components/FixturePanel.tsx",label:"Colour",why:"fixture: still breaks"},{file:"lib/puck/config.tsx",label:"Headline",why:"fixture: renamed long ago"}]},r.check),d=C(r.report()).map(e=>e.name),h=e=>d.some(i=>i.startsWith(e)),y=n.map(e=>e.label);l("the fixture reads the registry's fields and the panels' rows, and no option, action, tab or shopper's form",y.join(" · ")==="Heading · Kicker · Title · Cards · Heading · Card title · Layout · Title · Photo · Heading · Photo · Colour · Gutter",y.join(" · ")),l("…and the breaches are the ones it wrote, the parked one waived",c.map(e=>`${e.label}=${e.why.join("+")}`).join(" · ")==='Kicker=N10.1 "kicker" · Title=N10.2 Title at section level · Heading=N10.2 Heading at item level · Photo=N10.1 "photo" · Photo=N10.1 "photo" · Gutter=N10.1 "gutter"',JSON.stringify(c.map(e=>[e.label,e.why])));const b=n.filter(e=>e.level==="slot child").map(e=>`${e.file.split("/")[4]} ${e.label}=${e.why.join("+")||"ok"}`),u=n.filter(e=>e.file==="lib/puck/config.tsx"&&e.label==="Title").map(e=>`${e.level}:${e.why.join("+")}`);l("a block in a literal slot `allow` is a slot child: GalleryItem `Title` and BookingBox `Heading` both pass, N10.1 still bites, and a section's own `Title` still fails N10.2",[...f].sort().join()==="BookingBox,GalleryItem"&&b.join(" · ")==='GalleryItem Title=ok · GalleryItem Photo=N10.1 "photo" · BookingBox Heading=ok'&&u.join()==="section:N10.2 Title at section level",JSON.stringify([[...f],b,u])),l("a file under its floor goes red",h("components/FixturePanel.tsx yields")&&!h("components/HandRolled.tsx yields"),d.join(" | ")),l("a floored file that is not read goes red",h("components/Moved.tsx yields"),d.join(" | ")),l("a registry under its floor goes red",h("the block registry yields"),d.join(" | ")),l("a PARKED label that no longer breaks N10 goes red, and one that still does is waived",h('PARKED lib/puck/config.tsx "Headline"')&&!h('PARKED components/FixturePanel.tsx "Colour"'),d.join(" | ")),l("the verdict goes red on a live breach",h("every field label obeys"),d.join(" | ")),l("…and nothing else did",d.length===5,d.join(" | "))}return v(o,s,l),a()}export{g as NEVER_WORDS,E as labelVocabulary,F as slotChildTypes,m as vocabularyBreaches};
@@ -1,5 +1,5 @@
1
1
  const g=["text","textarea","plainText","copyText","plainTextarea","linkField","textList","upload","toggle","checkbox","select","searchSelect","segmented","slider","colorInput","focalPicker","sizeField","backgroundField","multiSelect"];function A(e){const t=e.split(`
2
- `),n=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\("((?:[^"\\\\]|\\\\.)*)"`,"g"),o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\(\\s*$`),l=/^\s*"((?:[^"\\]|\\.)*)"\s*,/,r=[];let c=0,h=0;const f=[];return t.forEach((a,u)=>{const d=u+1,b=h>0;for(const i of a.matchAll(n))r.push({line:d,label:i[2],item:b,builder:i[1]});const m=s.exec(a);if(m){let i=u+1;for(;i<t.length&&t[i].trim()==="";)i+=1;const p=i<t.length?l.exec(t[i]):null;p&&r.push({line:i+1,label:p[1],item:b,builder:m[1]})}for(const i of a.matchAll(o)){const p=a.slice(0,i.index??0),x=u>0?t[u-1].trim():"";(/type:\s*"/.test(p)||/type:\s*"[a-z]+"\s*,?$/.test(x))&&r.push({line:d,label:i[1],item:b})}for(let i=0;i<a.length;i+=1)a[i]==="{"?(/arrayFields:\s*$/.test(a.slice(0,i))&&(f.push(c),h+=1),c+=1):a[i]==="}"&&(c-=1,f.length&&c===f[f.length-1]&&(f.pop(),h-=1))}),r}function L(e,t){let n=0,o=-1;for(let l=t-1;l>=0;l-=1){const r=e[l];if(r==="}")n+=1;else if(r==="{"){if(n===0){o=l;break}n-=1}}if(o<0)return"";let s=0;for(let l=o;l<e.length;l+=1)if(e[l]==="{")s+=1;else if(e[l]==="}"&&(s-=1,s===0))return e.slice(o,l+1);return e.slice(o)}function $(e){let t=0,n="";for(const o of e){if(o==="{"||o==="["){t+=1;continue}if(o==="}"||o==="]"){t-=1;continue}t===1&&(n+=o)}return n}function y(e,t){const n=$(L(e,t));return/(^|[,;])\s*(value|fields|render|resolveFields|panelId|href|amount|meta)\s*:/.test(n)||w(e,t)}function w(e,t){let n=0,o=0;for(let s=t-1;s>=0;s-=1){const l=e[s];if(l==="}"||l==="]"||l===")")n+=1;else if(l==="{"||l==="("){if(n>0){n-=1;continue}if(l==="("||++o>1)return!1}else if(l==="["){if(n>0){n-=1;continue}return/SettingsTabItem\[\]\s*=\s*$/.test(e.slice(Math.max(0,s-80),s))}}return!1}function F(e){const t=e.split(`
3
- `),n=[];for(let l=0,r=0;l<t.length;l+=1)n.push(r),r+=t[l].length+1;const o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=[];return t.forEach((l,r)=>{for(const c of l.matchAll(o))y(e,n[r]+(c.index??0))||s.push({line:r+1,label:c[1],item:!1})}),s}const j=/(?<![-A-Za-z])label=(?:\{say\()?"((?:[^"\\]|\\.)*)"/g;function E(e){const t=[];return e.split(`
4
- `).forEach((n,o)=>{for(const s of n.matchAll(j))t.push({line:o+1,label:s[1],item:!1})}),t}const S=/className="sf-field"|from\s*["']efficient-easel/;function I(e){return e.path.startsWith("components/")&&e.path.endsWith(".tsx")&&S.test(e.text)}const k=6;function O(e,t){for(let n=t;n<Math.min(e.length,t+k);n+=1){if(/^\s*\}[,)]?\s*$/.test(e[n])&&n>t)return!1;if(/\bonClick:/.test(e[n]))return!0}return!1}function N(e){const t=new Set,n=e.split(`
5
- `);return[...A(e),...F(e),...E(e)].filter(o=>{const s=`${o.line}:${o.label}`;return t.has(s)?!1:(t.add(s),!O(n,o.line-1))})}export{g as BUILDERS,j as JSX_LABEL,I as isPanelFile,E as readJsxLabels,A as readLabels,N as readPanelLabels,F as readRowLabels};
2
+ `),n=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\("((?:[^"\\\\]|\\\\.)*)"`,"g"),o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\(\\s*$`),l=/^\s*"((?:[^"\\]|\\.)*)"\s*,/,r=[];let c=0,h=0;const f=[];return t.forEach((a,u)=>{const d=u+1,b=h>0;for(const i of a.matchAll(n))r.push({line:d,label:i[2],item:b,builder:i[1]});const m=s.exec(a);if(m){let i=u+1;for(;i<t.length&&t[i].trim()==="";)i+=1;const p=i<t.length?l.exec(t[i]):null;p&&r.push({line:i+1,label:p[1],item:b,builder:m[1]})}for(const i of a.matchAll(o)){const p=a.slice(0,i.index??0),x=u>0?t[u-1].trim():"";(/type:\s*"/.test(p)||/type:\s*"[a-z]+"\s*,?$/.test(x))&&r.push({line:d,label:i[1],item:b})}for(let i=0;i<a.length;i+=1)a[i]==="{"?(/arrayFields:\s*$/.test(a.slice(0,i))&&(f.push(c),h+=1),c+=1):a[i]==="}"&&(c-=1,f.length&&c===f[f.length-1]&&(f.pop(),h-=1))}),r}function L(e,t){let n=0,o=-1;for(let l=t-1;l>=0;l-=1){const r=e[l];if(r==="}")n+=1;else if(r==="{"){if(n===0){o=l;break}n-=1}}if(o<0)return"";let s=0;for(let l=o;l<e.length;l+=1)if(e[l]==="{")s+=1;else if(e[l]==="}"&&(s-=1,s===0))return e.slice(o,l+1);return e.slice(o)}function $(e){let t=0,n="";for(const o of e){if(o==="{"||o==="["){t+=1;continue}if(o==="}"||o==="]"){t-=1;continue}t===1&&(n+=o)}return n}function w(e,t){const n=$(L(e,t));return/(^|[,;])\s*(value|fields|render|resolveFields|panelId|href|amount|meta)\s*:/.test(n)||y(e,t)}function y(e,t){let n=0,o=0;for(let s=t-1;s>=0;s-=1){const l=e[s];if(l==="}"||l==="]"||l===")")n+=1;else if(l==="{"||l==="("){if(n>0){n-=1;continue}if(l==="("||++o>1)return!1}else if(l==="["){if(n>0){n-=1;continue}return/\w*TabItem\[\]\s*=\s*$/.test(e.slice(Math.max(0,s-80),s))}}return!1}function F(e){const t=e.split(`
3
+ `),n=[];for(let l=0,r=0;l<t.length;l+=1)n.push(r),r+=t[l].length+1;const o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=[];return t.forEach((l,r)=>{for(const c of l.matchAll(o))w(e,n[r]+(c.index??0))||s.push({line:r+1,label:c[1],item:!1})}),s}const j=/(?<![-A-Za-z])label=(?:\{say\()?"((?:[^"\\]|\\.)*)"/g;function E(e){const t=[];return e.split(`
4
+ `).forEach((n,o)=>{for(const s of n.matchAll(j))t.push({line:o+1,label:s[1],item:!1})}),t}const k=/className="sf-field"|from\s*["']efficient-easel/;function I(e){return e.path.startsWith("components/")&&e.path.endsWith(".tsx")&&k.test(e.text)}const O=6;function P(e,t){for(let n=t;n<Math.min(e.length,t+O);n+=1){if(/^\s*\}[,)]?\s*$/.test(e[n])&&n>t)return!1;if(/\bonClick:/.test(e[n]))return!0}return!1}function N(e){const t=new Set,n=e.split(`
5
+ `);return[...A(e),...F(e),...E(e)].filter(o=>{const s=`${o.line}:${o.label}`;return t.has(s)?!1:(t.add(s),!P(n,o.line-1))})}export{g as BUILDERS,j as JSX_LABEL,I as isPanelFile,E as readJsxLabels,A as readLabels,N as readPanelLabels,F as readRowLabels};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as se,Fragment as oe}from"react/jsx-runtime";import re from"./BoxTabs.js";import te from"./SiteGutterFrame.js";import{BoxSurfaceProvider as ne}from"./BoxSurfaceContext.js";import{BoxCellWidthContext as le}from"./BoxCellWidthContext.js";import{useInSiteHeader as ae}from"./PhoneMenuTools.js";import{FRAME_BASE as ie,FRAME_GUTTER as ce}from"./BlockFrame.js";import{containerGapProps as me}from"../../format/lib/content/container-gap.js";import{boxLayoutClasses as fe,boxBlockSpacingClass as be,boxPhoneRowClasses as _,boxShareClasses as O,boxWrapClass as ue}from"../../format/lib/content/box-layout.js";import{BOX_CARD_PAD as s,BOX_OWNS_SIDES_CLASS as de,boxDarkenStyle as xe,boxPlacementClasses as ye,CARD_SHADOW_CLASS as pe,isBackgroundBox as j}from"../../format/lib/content/box-background.js";import{sectionBorderStyle as Se}from"../../format/lib/content/borders.js";import{sectionPadAttrs as $e}from"../../format/lib/content/section-padding.js";import{ON_MEDIA_INK_STYLE as Ce}from"../../format/lib/content/ink.js";import{sizedBackground as h}from"../../format/lib/sized-image.js";const _e="bg-cover bg-center bg-[image:var(--sf-box-bg)] max-[720px]:bg-[image:var(--sf-box-bg-p)]";function he({direction:o,label:H,gap:W,justify:z,align:i,wrap:G,share:v,phoneRow:g,blockSpacing:I,bgImage:c,bgImagePhone:A,darken:L,darkenStyle:M,placement:R,padV2:X=!1,border:U,borderPhone:K,padTop:m,padBottom:f,padTopPhone:b,padBottomPhone:u,padLeft:d,padRight:x,padLeftPhone:y,padRightPhone:p,contained:T=!0,fillHeight:N=!1,content:Y}){const t=j(c),P=ae(),E=[O(v),be(I)].filter(Boolean).join(" "),q=E?` ${E}`:"",k=["flex",o==="row"?`flex-row ${_(g)}`:"flex-col",ue(G),t?ye(R??"center",o):fe(z,i)].join(" ")+q,r=N||t?" h-full":"",S=t||P||X?"":" py-6",J=`${ie}${S} ${ce}${r}`,Q=P?r.trim():`w-full${S}${r}`,n=me("Flex",W,o==="row"?"inline":"block"),B=e(Y,{className:`${k}${n.className}${r}`,style:n.style,minEmptyHeight:120}),$=o==="tabs"?e(re,{className:`${k}${n.className}${r}`,style:n.style,children:B}):B,V=H?.trim()||void 0,Z={values:{top:m,bottom:f,topPhone:b,bottomPhone:u,left:d,right:x,leftPhone:y,rightPhone:p},frame:S?24:0},w=a=>e(te,{contained:T,framedClass:J,fillClass:Q,tabLabel:V,pad:t?void 0:Z,border:Se(U,K),children:a});if(!t){const a=i===void 0||i==="stretch",ee=O(v)!==""&&(a||_(g)!==_(void 0));return w((o==="row"?ee:o==="column"&&a)?e(le.Provider,{value:!0,children:$}):$)}const l=xe(L,M),D=j(A),C=$e(typeof m=="number"?m:s.desktop,typeof f=="number"?f:s.desktop,typeof b=="number"?b:s.phone,typeof u=="number"?u:s.phone,typeof d=="number"?d:s.side,typeof x=="number"?x:s.side,typeof y=="number"?y:s.sidePhone,typeof p=="number"?p:s.sidePhone),F=e("div",{className:`relative z-[1] ${de} ${C?.className??""}${N?" h-full":""}`.trimEnd(),style:l?{...C?.style,...Ce}:C?.style,children:$});return w(e(oe,{children:se("div",{className:`relative isolate overflow-hidden ${pe}${r}${D?` ${_e}`:""}`,style:D?{"--sf-box-bg":h(c??""),"--sf-box-bg-p":h(A??"")}:{backgroundImage:h(c??""),backgroundSize:"cover",backgroundPosition:"center"},children:[l&&e("div",{className:"absolute inset-0 z-0",style:l,"aria-hidden":!0}),l?e(ne,{children:F}):F]})}))}export{he as default};
1
+ import{jsx as e,jsxs as oe,Fragment as re}from"react/jsx-runtime";import te from"./BoxTabs.js";import ne from"./SiteGutterFrame.js";import{BoxSurfaceProvider as le}from"./BoxSurfaceContext.js";import{BoxCellWidthContext as ae}from"./BoxCellWidthContext.js";import{useInSiteHeader as ie}from"./PhoneMenuTools.js";import{FRAME_BASE as ce,FRAME_GUTTER as me}from"./BlockFrame.js";import{containerGapProps as fe}from"../../format/lib/content/container-gap.js";import{boxLayoutClasses as ue,boxBlockSpacingClass as be,boxPhoneRowClasses as _,boxShareClasses as O,boxWrapClass as de}from"../../format/lib/content/box-layout.js";import{BOX_CARD_PAD as s,BOX_OWNS_SIDES_CLASS as xe,boxDarkenStyle as pe,boxPlacementClasses as ye,CARD_SHADOW_CLASS as Se,isBackgroundBox as j}from"../../format/lib/content/box-background.js";import{sectionBorderStyle as Ce}from"../../format/lib/content/borders.js";import{sectionPadAttrs as $e}from"../../format/lib/content/section-padding.js";import{ON_MEDIA_INK_STYLE as _e}from"../../format/lib/content/ink.js";import{sizedBackground as h}from"../../format/lib/sized-image.js";const H={"--sf-site-gutter":"0px"},he="bg-cover bg-center bg-[image:var(--sf-box-bg)] max-[720px]:bg-[image:var(--sf-box-bg-p)]";function ge({direction:o,label:W,gap:R,justify:z,align:i,wrap:G,share:g,phoneRow:v,blockSpacing:I,bgImage:c,bgImagePhone:A,darken:L,darkenStyle:M,placement:T,padV2:U=!1,border:X,borderPhone:K,padTop:m,padBottom:f,padTopPhone:u,padBottomPhone:b,padLeft:d,padRight:x,padLeftPhone:p,padRightPhone:y,contained:Y=!0,fillHeight:E=!1,content:q}){const t=j(c),N=ie(),P=[O(g),be(I)].filter(Boolean).join(" "),J=P?` ${P}`:"",k=["flex",o==="row"?`flex-row ${_(v)}`:"flex-col",de(G),t?ye(T??"center",o):ue(z,i)].join(" ")+J,r=E||t?" h-full":"",S=t||N||U?"":" py-6",Q=`${ce}${S} ${me}${r}`,V=N?r.trim():`w-full${S}${r}`,n=fe("Flex",R,o==="row"?"inline":"block"),B=e(q,{className:`${k}${n.className}${r}`,style:n.style,minEmptyHeight:120}),C=o==="tabs"?e(te,{className:`${k}${n.className}${r}`,style:n.style,children:B}):B,Z=W?.trim()||void 0,ee={values:{top:m,bottom:f,topPhone:u,bottomPhone:b,left:d,right:x,leftPhone:p,rightPhone:y},frame:S?24:0},w=a=>e(ne,{contained:Y,framedClass:Q,fillClass:V,tabLabel:Z,pad:t?void 0:ee,border:Ce(X,K),children:a});if(!t){const a=i===void 0||i==="stretch",se=O(g)!==""&&(a||_(v)!==_(void 0));return w((o==="row"?se:o==="column"&&a)?e(ae.Provider,{value:!0,children:C}):C)}const l=pe(L,M),D=j(A),$=$e(typeof m=="number"?m:s.desktop,typeof f=="number"?f:s.desktop,typeof u=="number"?u:s.phone,typeof b=="number"?b:s.phone,typeof d=="number"?d:s.side,typeof x=="number"?x:s.side,typeof p=="number"?p:s.sidePhone,typeof y=="number"?y:s.sidePhone),F=e("div",{className:`relative z-[1] ${xe} ${$?.className??""}${E?" h-full":""}`.trimEnd(),style:l?{...$?.style,...H,..._e}:{...$?.style,...H},children:C});return w(e(re,{children:oe("div",{className:`relative isolate overflow-hidden ${Se}${r}${D?` ${he}`:""}`,style:D?{"--sf-box-bg":h(c??""),"--sf-box-bg-p":h(A??"")}:{backgroundImage:h(c??""),backgroundSize:"cover",backgroundPosition:"center"},children:[l&&e("div",{className:"absolute inset-0 z-0",style:l,"aria-hidden":!0}),l?e(le,{children:F}):F]})}))}export{ge as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "27.0.0",
3
+ "version": "28.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",
@@ -53,7 +53,7 @@
53
53
  "peerDependencies": {
54
54
  "@tabler/icons-react": "^3.46.0",
55
55
  "efficient-easel": "^14.1.0",
56
- "efficient-shell": "^7.75.0 || ^8.0.0",
56
+ "efficient-shell": "^8.2.0",
57
57
  "isomorphic-dompurify": "^3.18.0",
58
58
  "next": ">=16",
59
59
  "react": ">=19",
@@ -73,7 +73,7 @@
73
73
  "@types/react": "^19",
74
74
  "@types/react-dom": "^19",
75
75
  "efficient-easel": "^14.1.0",
76
- "efficient-shell": "^8.0.0",
76
+ "efficient-shell": "^8.2.0",
77
77
  "esbuild": "^0.28.0",
78
78
  "happy-dom": "^20.14.5",
79
79
  "isomorphic-dompurify": "^3.18.0",