efficient-web-builder 5.3.0 → 6.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +2 -0
  3. package/dist/components/Countdown.d.ts +9 -0
  4. package/dist/components/Countdown.js +1 -0
  5. package/dist/components/ImageFocusRow.js +1 -1
  6. package/dist/components/PartStyledKind.d.ts +5 -0
  7. package/dist/components/PartStyledKind.js +1 -0
  8. package/dist/components/SectionThumbnail.js +1 -1
  9. package/dist/components/SocialLinksPanel.js +1 -1
  10. package/dist/components/StorefrontLinkField.js +1 -1
  11. package/dist/components/socialIcons.js +1 -1
  12. package/dist/components/storefront-editor.css +18 -120
  13. package/dist/components/useSocialSettings.d.ts +2 -2
  14. package/dist/lib/content/block-sources.d.ts +20 -0
  15. package/dist/lib/content/block-sources.js +1 -0
  16. package/dist/lib/content/product-page.js +1 -1
  17. package/dist/lib/content/record-types.d.ts +21 -0
  18. package/dist/lib/content/record-types.js +1 -0
  19. package/dist/lib/content/social-links.d.ts +1 -1
  20. package/dist/lib/content/social-links.js +1 -1
  21. package/dist/lib/links/link-picker-setup.d.ts +1 -1
  22. package/dist/lib/links/link-picker-setup.js +1 -1
  23. package/dist/lib/links/page-link-rules.d.ts +0 -1
  24. package/dist/lib/links/page-link-rules.js +1 -1
  25. package/dist/lib/puck/block-source-fields.d.ts +5 -0
  26. package/dist/lib/puck/block-source-fields.js +1 -0
  27. package/dist/lib/puck/blocks/general/Countdown/fields.d.ts +2 -0
  28. package/dist/lib/puck/blocks/general/Countdown/fields.js +1 -0
  29. package/dist/lib/puck/blocks/general/Countdown/render.d.ts +6 -0
  30. package/dist/lib/puck/blocks/general/Countdown/render.js +1 -0
  31. package/dist/lib/puck/blocks/general/HeroSingle/render.js +1 -1
  32. package/dist/lib/puck/blocks/general/HeroSlide/render.js +1 -1
  33. package/dist/lib/puck/blocks/general/OrderSummary/fields.js +1 -1
  34. package/dist/lib/puck/blocks/general/OrderSummary/render.js +1 -1
  35. package/dist/lib/puck/blocks/general/index.d.ts +2 -2
  36. package/dist/lib/puck/blocks/general/index.js +1 -1
  37. package/dist/lib/puck/blocks/general/renders.d.ts +1 -0
  38. package/dist/lib/puck/blocks/general/renders.js +1 -1
  39. package/dist/lib/puck/controls.d.ts +2 -1
  40. package/dist/lib/puck/controls.js +1 -1
  41. package/dist/lib/puck/editor-page-context.d.ts +1 -0
  42. package/dist/lib/puck/editor-page-context.js +1 -1
  43. package/dist/lib/puck/general-registry.d.ts +1 -1
  44. package/dist/lib/puck/general-registry.js +1 -1
  45. package/dist/lib/puck/page-root-fields.d.ts +4 -1
  46. package/dist/lib/puck/page-root-fields.js +1 -1
  47. package/dist/lib/puck/registry.js +1 -1
  48. package/dist/lib/puck/section-catalog.js +1 -1
  49. package/dist/lib/puck/section-descriptions.js +1 -1
  50. package/dist/lib/source-rules/editor-chrome-note.js +1 -1
  51. package/dist/lib/source-rules/social-icons-import.js +4 -4
  52. package/package.json +4 -4
  53. package/dist/lib/image-focus.d.ts +0 -16
  54. package/dist/lib/image-focus.js +0 -1
@@ -1 +1 @@
1
- "use client";import{jsx as r,jsxs as y,Fragment as E}from"react/jsx-runtime";import{cloneElement as qe,useId as Je,useRef as q,useState as ue}from"react";import{useEasel as N}from"efficient-easel/easel";import{readHidable as de,hidableText as pe}from"./hidable.js";import{FOCAL_DEFAULT as fe}from"../image-focus.js";import{FOLD_FIELD_MARKER as J,LINK_FIELD_MARKER as he,MEDIA_FIELD_MARKER as me,SCAFFOLD_FIELD_MARKER as ge,TEXT_FIELD_MARKER as T,foldMetaOf as Z,textFieldIdentifier as Ze}from"./field-markers.js";import Qe from"../../components/ApplyCornersToSiblings.js";import{CARD_IMAGE_RADIUS_STEP as et,CORNER_RADIUS_MAX as W,CORNER_RADIUS_MIN as B}from"../content/card-image-shape.js";import{IMAGE_CORNER_STEP as tt,IMAGE_CORNERS_LABEL as nt}from"../content/image-corners.js";import{GRID_MAX_COLUMNS as ot}from"../content/grid-span.js";import{GALLERY_ACROSS_BUCKETS as rt,GALLERY_LAYOUTS as A,GALLERY_LAYOUT_KEYS as be}from"../content/gallery-layout.js";import{anchorSiblingsOf as it,HERO_GROUP_PLACEMENTS as lt,HERO_GROUP_PLACEMENT_DEFAULT as at,normalisePlacement as st,placementPoints as xe}from"../hero-group-placement.js";import ct from"../../components/KeepHint.js";import{AlignLeftIcon as ut,AlignSeparateIcon as dt,AnimationIcon as Ce,BackgroundIcon as pt,BlockSectionIcon as ft,CartIcon as ht,ColumnWidthsIcon as Se,ColumnsIcon as mt,CornerIcon as Ie,DirectionDownIcon as gt,DirectionLeftIcon as bt,DirectionRightIcon as xt,DirectionUpIcon as Ct,DollarIcon as St,FinishIcon as It,GapIcon as _e,GridIcon as _t,GroundIcon as yt,HashIcon as ye,ImageIcon as Et,LayoutIcon as Tt,ListIcon as Rt,LocationIcon as Q,PaddingBottomIcon as Lt,PaddingLeftIcon as vt,PaddingRightIcon as Ot,PaddingTopIcon as Nt,PageIcon as Ee,PhoneIcon as At,PlacementIcon as Ft,ProductSizeIcon as Pt,RotateIcon as wt,SquareIcon as kt,StylesIcon as Dt,TextLinesIcon as Ht,TypeIcon as Bt,WidthIcon as Gt,WrapIcon as Mt}from"efficient-easel/icons";import{FieldGlyph as Te}from"../../components/FieldGlyph.js";import{resolvePageBackground as $t}from"../content/page-background.js";import{CORNER_SIDES as F,CORNER_SIDE_POINTS as ee,CORNER_SIDES_LABEL as P,cornerSidesSummary as Re,hasOwnSectionCorners as Wt,normalizeCornerSides as U}from"../content/section-corners.js";import{hasOwnCardCorners as Ut}from"../content/card-corners.js";import{SECTION_MOTION_NONE as Kt,SECTION_MOTION_OPTIONS as Xt}from"../content/section-animation.js";import{enclosingSectionProps as Le}from"./enclosing-section.js";import{SettingsCorners as ve,SettingsDefaultReset as g,SettingsField as h,SettingsGroupHead as zt,SettingsGroupSub as Vt,SettingsPlacement as Yt,SettingsSegmented as jt,SettingsSwitch as qt}from"efficient-easel/panel";import{FieldSelect as Jt,ListField as Zt}from"efficient-easel/fields";import{Checkbox as Qt,Slider as en,Tooltip as K}from"efficient-shell/ui";import{ColourControl as Oe}from"./ColourControl.js";import Ne from"./MarkupToolbar.js";import{deviceField as R}from"./device-fields.js";import{noControlField as tn}from"./panel-no-control-mark.js";import{phoneKey as X,resolvePhoneValue as te}from"./phone-override.js";import{SuppressibleText as nn}from"./section-text-suppress.js";import{CARD_INDEX_OPTIONS as on,CARD_OUTLINE_OPTIONS as rn,DEFAULT_CARD_INDEX_FORMAT as ln,DEFAULT_CARD_OUTLINE as an}from"../sections/product-card-style.js";import{COVER_INDEX_OPTIONS as sn,DEFAULT_COVER_INDEX as cn}from"../sections/card-cover-index.js";import{SCALAR_TEXT_CONTROLS as un}from"./text-control-kinds.js";import dn from"../../components/ImageFocusRow.js";import pn from"../../components/MediaUploadField.js";import fn from"../../components/MultiSelectField.js";import hn from"../../components/SectionThemePicker.js";import mn from"../../components/SearchSelectField.js";import gn from"../../components/StorefrontLinkField.js";import Ae from"../../components/UiIcon.js";import{SECTION_PADDING as S}from"../content/section-padding.js";import{hasPhoneHeight as bn,resolveSectionMinHeight as xn}from"../content/section-min-height.js";import{VIEW_TIER_LABEL as ne}from"../content/view-tiers.js";import{SECTION_MIN_HEIGHT as Cn,SECTION_MIN_HEIGHT_GROUP_LABEL as G,SECTION_SCREEN_PCT as Sn}from"../content/section-min-height.js";import{CONTAINER_DIRECTION_LABEL as In,containerDirectionPoints as _n,resolveContainerDirection as Fe}from"../content/container-direction.js";import{BOX_ALIGN_POINTS as yn,BOX_BLOCK_SPACING_LABEL as En,BOX_BLOCK_SPACING_POINTS as Pe,BOX_JUSTIFY_POINTS as we,BOX_PHONE_ROW_LABEL as Tn,BOX_PHONE_ROW_MAX as Rn,BOX_PHONE_ROW_MIN as ke,BOX_SHARE_LABEL as De,BOX_SHARE_POINTS as oe,BOX_WRAP_LABEL as Ln,BOX_WRAP_POINTS as He}from"../content/box-layout.js";import{usePreviewHeader as z}from"../../components/PreviewHeaderContext.js";import{CONTAINER_GAP as re,CONTAINER_GAP_BUILT_IN as vn,GAP_FIELD_CONTAINER as On,hasOwnContainerGap as Nn,resolveContainerGap as An}from"../content/container-gap.js";import{CARD_IMAGE_BG_INHERIT as Fn,CARD_IMAGE_BG_OFF as Pn,CARD_IMAGE_BG_SWATCH_NAMES as wn,CARD_IMAGE_BG_SWATCHES as kn,isCardImageBackgroundInheriting as Dn,cardImageBackgroundChoice as Hn,THEME_CARD_IMAGE_BG as Bn}from"../content/card-image-background.js";import{SECTION_BG_INHERIT as Gn,SECTION_BG_SWATCHES as Mn,SECTION_BG_SWATCH_NAMES as $n,THEME_SECTION_BG as Wn,isSectionBackgroundInheriting as Un}from"../content/section-background.js";import{SECTION_THEME_GROUP_LABEL as Kn}from"../content/section-surface.js";import{TYPE_SIZE_FIXED as Xn,TYPE_SIZE_INHERIT as zn,isTypeSizeInheriting as Vn}from"../content/section-type-size.js";import{SECTION_WIDTH_CHOICES as Yn,WIDTH_CHOICE_LABEL as jn,WIDTH_INHERIT as qn,resolveWidth as Jn,sectionRunsFullWidth as Be}from"../content/section-width.js";import{useFoldHeadingLevel as Ge}from"./panel-heading-scope.js";import{withStyleKind as Zn}from"efficient-easel/style-clipboard";function M(e){for(const[t,n]of Object.entries(e))n&&typeof n=="object"&&!Z(n)&&Zn(n,`section:${t}`);return e}function Yr({children:e}){return r("div",{className:"sf-field-label",children:e})}function Me(){return null}function Qn(e){if(!e.trim())throw new Error("noGlyph() needs a reason naming the ruling that decided it.");return r(Me,{},e)}function eo(e){return e.type===Me}function V(e){return eo(e)?void 0:e}function w(e,t){return`${e} from ${t}`}function to(){const{appState:e}=N(i=>i),t=e.data.root?.props??{},{mode:n,pageWidth:o}=Jn(t,"full");return w(n==="page"?`${o}px`:n==="contained"?"Contained":"Full","the page")}function no(){const{blockGap:e}=z();return e===null?"this container's own spacing":w(`${e}px`,"Site styles")}function oo({inherited:e,onReset:t,label:n}){return r(g,{label:n,changed:!e,detail:no(),onReset:t})}function ro({inherited:e,onReset:t,label:n}){return r(g,{label:n,changed:!e,detail:to(),onReset:t})}function k({value:e,onChange:t,label:n,placeholder:o,hint:i,multiline:l,hideable:a=!0,markup:s=!0}){const{text:c,hidden:d}=de(e),f=q(null),u=q(null),p=_=>t(a?{text:_,hidden:d}:_),m=()=>t({text:c,hidden:!d}),b=a&&d,I=Je(),x=i?co(i)?r("span",{className:"sf-hint-keep sf-hint-while-typing",children:i}):r(ct,{children:i}):void 0;return r(h,{label:n,icon:r(Bt,{}),htmlFor:I,className:b?"is-hidden":void 0,hint:x,action:a?r(K,{content:d?`Show ${n} on the slide`:`Hide ${n} on the slide`,children:r("button",{type:"button",className:"sf-field-eye","aria-pressed":d,"aria-label":d?`Show ${n} on the slide`:`Hide ${n} on the slide`,onClick:m,children:d?r(Ae,{name:"eye-off",size:14}):r(Ae,{name:"eye",size:14})})}):void 0,children:y("div",{className:"sf-copybox",children:[s&&r(Ne,{target:l?u:f,value:c,onChange:p}),l?r("textarea",{id:I,ref:u,value:c,placeholder:o,onChange:_=>p(_.target.value)}):r("input",{id:I,ref:f,type:"text",value:c,placeholder:o,onChange:_=>p(_.target.value)})]})})}function jr(e,t){return{...e,[ge]:t}}function qr(e){const t=e[T];if(!t)throw new Error("withOffPage: the field holds no authored text");return{...e,[T]:{...t,offPage:!0}}}function Jr(e){return!e||typeof e!="object"?!1:e[T]?.offPage===!0}function Zr(e){const t=e[T];if(!t)throw new Error("withIdentifier: the field holds no authored text");return{...e,[T]:{...t,identifier:!0}}}import{TEXT_CONTROL_KINDS as tl,SCALAR_TEXT_CONTROLS as nl}from"./text-control-kinds.js";const io=new Set(un),D=(e,t)=>{const n={...t,[T]:e};if(!io.has(e.control))return n;const o=t.render;return{...tn(n,"authored-copy"),render:i=>r(nn,{name:i.name,children:o(i)})}},Qr="Everything else on this block comes from the linked post. Unlink it to edit by hand.",lo="Select a word, then press the highlighter.",ao="A short name so a link can jump straight to this section, like yoursite.com/page#about.",so=new Set([lo]),co=e=>so.has(e);function ei(e,t,n){return D({control:"text",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n})})}function ti(e,t,n){return D({control:"textarea",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,multiline:!0})})}function uo(e,t,n){return D({control:"plainText",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,hideable:!1,markup:!1})})}function ni(e,t,n){return D({control:"copyText",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,hideable:!1})})}function oi(e){return{type:"custom",[he]:{label:e},render:({value:t,onChange:n})=>r(gn,{value:pe(t),onChange:n,label:e})}}function ri(e,t,n){return D({control:"plainTextarea",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,multiline:!0,hideable:!1})})}const ii={Content:Ht,Style:Dt,Layout:Tt,Animation:Ce};function li(e,t){return e.includes("Content")?t!=="Content":null}function po({label:e}){return r(zt,{title:e,level:Ge(1)})}function fo({level:e,label:t}){return e===1?r(po,{label:t}):r(mo,{label:t})}function $e(e,t){return{type:"custom",[J]:{label:e,level:t},render:()=>r(fo,{level:t,label:e})}}function C(e){return $e(e,2)}function ai(e){return{type:"custom",render:()=>r(ho,{text:e})}}function ho({text:e}){return r("p",{className:"sf-note",children:e})}function si(e){return $e(e,1)}function ci(e){return Z(e)!==null&&e?.tabs!==void 0}const We=new Map;function ui(e,t){const n=`${e}\0${t?t.join(""):""}`,o=We.get(n)??{type:"custom",tabs:t,[J]:{label:e,level:1},bucket:e,marker:!0,render:()=>r(E,{})};return We.set(n,o),o}function mo({label:e}){return r(Vt,{title:e,level:Ge(2)})}function Ue({swatches:e,current:t,onPick:n,names:o}){const i=e.find(a=>a.toLowerCase()===t.toLowerCase()),l=(i?o?.[i]:void 0)??t;return y("div",{className:"sf-swatches",children:[e.map(a=>{const s=o?.[a]??a;return r(K,{content:s,children:r("button",{type:"button","aria-pressed":t.toLowerCase()===a.toLowerCase(),className:`sf-swatch ${t.toLowerCase()===a.toLowerCase()?"is-active":""}`,style:{background:a},onClick:()=>n(a),"aria-label":s})},a)}),r("span",{className:"sf-swatch-hex",children:l})]})}function di(e,t){return{type:"custom",render:({value:n,onChange:o})=>{const i=Un(n,t);return r(h,{label:e,icon:r(pt,{}),changed:!i,action:r(g,{label:e,changed:!i,detail:"the theme's section background",onReset:()=>o(Gn)}),children:Ue({swatches:Mn,current:i?Wn:n??t??"",onPick:o,names:$n})})}}}function go(e,t){return{type:"custom",render:({value:n,onChange:o})=>{const i=n,l=Dn(i,t);return r(h,{label:e,icon:r(yt,{}),changed:!l,action:r(g,{label:e,changed:!l,detail:"the theme's image stage",onReset:()=>o(Fn)}),children:Ue({swatches:kn,current:l?Bn:Hn(i,t),onPick:o,names:wn})})}}}function pi(e=n=>n,t){return M({_gSectionTheme:C(Kn),sectionAccent:{type:"custom",render:({value:n,onChange:o})=>r(hn,{value:e(n),onChange:o,followLabel:t})}})}function v({min:e,max:t,step:n,value:o,onChange:i,suffix:l="",readout:a=!0,notch:s,ariaLabel:c,disabled:d=!1}){const f=s!==void 0&&Number.isFinite(s)&&s>=e&&s<=t;return r("div",{className:f?"sf-slider has-notch":"sf-slider",style:f?{"--sf-notch":(s-e)/(t-e)}:void 0,children:r(en,{min:e,max:t,step:n,value:o,suffix:l||void 0,showInput:a,label:c,disabled:d,size:"sm",className:"sf-slider-track",onChange:u=>{u!==null&&u!==o&&i(u)}})})}function H(e,t,n,o,i,l,a="",s){return{type:"custom",render:c=>r(h,{label:e,icon:V(t),action:s?s("storedValue"in c?c.storedValue:c.value,c.onChange):void 0,children:v({min:n,max:o,step:i,value:typeof c.value=="number"?c.value:l,suffix:a,ariaLabel:e,onChange:c.onChange})})}}function Ke({min:e,max:t,step:n,px:o,label:i,onChange:l,disabled:a=!1}){const{cornerRadiusPx:s}=z();return r(E,{children:v({min:e,max:t,step:n,value:o??(typeof s=="number"?s:e),readout:!1,ariaLabel:i,disabled:a,onChange:l})})}function $(e,t){const{min:n,max:o,step:i=1,unsetLabel:l,hint:a,restAtSite:s=!1,restTrack:c,unsetMark:d}=t;return{type:"custom",render:({value:f,onChange:u})=>{const p=typeof f=="number"?f:null,m=p===null;return r(h,{label:e,value:m?d?void 0:l:`${p}px`,changed:!m,action:d?qe(d,{changed:!m,onReset:()=>u(null)}):r(g,{label:e,changed:!m,onReset:()=>u(null)}),hint:a,children:c?c({min:n,max:o,step:i,px:p,label:e,onChange:u}):s?r(Ke,{min:n,max:o,step:i,px:p,label:e,onChange:u}):v({min:n,max:o,step:i,value:p??n,readout:!1,ariaLabel:e,onChange:u})})}}}function fi(e){const t=H("Gap",r(_e,{}),re.min,re.max,re.step,vn[e],"px",(n,o)=>r(oo,{inherited:!Nn(e,n),onReset:()=>o(void 0),label:"Gap"}));return{type:"custom",[On]:e,render:n=>t.render({...n,value:An(e,n.value,n.field?.siteGap),storedValue:n.value,onChange:o=>n.onChange(o)})}}function bo(){return{type:"custom",render:({value:e,onChange:t})=>{const o=U(e)??[...F],i=o.length===F.length;return r(h,{label:P,icon:r(Ie,{}),value:Re(o),changed:!i,action:r(g,{label:P,changed:!i,onReset:()=>t(null)}),hint:"Corners left off stay square. The row above sets how round the others are.",children:r(_o,{value:o,onChange:l=>{const a=U(l)??[];t(a.length===F.length?null:a)}})})}}}function xo({label:e,changed:t=!1,onReset:n=()=>{}}){const{cornerRadiusPx:o}=z(),i=typeof o=="number"?`${o}px`:"not set";return r(g,{label:e,changed:t,detail:o==null?"the built-in corners":w(i,"Site styles"),onReset:n})}function Co(){return $("Corners",{min:B,max:W,unsetLabel:"Follows the site",unsetMark:r(xo,{label:"Corners"}),restTrack:e=>r(So,{...e}),hint:r(Io,{})})}const Xe="This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.";function ie(){return Be(Y())}function So(e){return r(Ke,{...e,disabled:ie()})}function Io(){return r(E,{children:ie()?Xe:"Follows Site styles ▸ Basics ▸ Corners until you set a number here."})}function _o({value:e,onChange:t}){const n=ie();return r(ve,{label:P,value:e,corners:n?ee.map(o=>({...o,disabled:!0,title:Xe})):ee,onChange:t})}function hi(){return M({_gShape:C("Shape"),sectionCorners:Co(),sectionCornerSides:bo()})}function mi(){return{_gMotion:C("Motion"),sectionAnimation:ce("Entrance",r(Ce,{}),[...Xt],Kt)}}function le(){let e=null;try{const{appState:t,selectedItem:n}=N(i=>i),o=n?.props?.id?String(n.props.id):void 0;e=o?Le(t?.data,o):null}catch{e=null}return e!==null&&Be(e)}function ze(e){const{cornerRadiusPx:t}=z(),n=le(),o=typeof t=="number"?t:e;let i=null;try{const{appState:a,selectedItem:s}=N(d=>d),c=s?.props?.id?String(s.props.id):void 0;i=c?Le(a?.data,c):null}catch{i=null}if(n||!i)return o;const l=i.sectionCorners;return Wt(l)?l:o}function yo({min:e,max:t,step:n,px:o,label:i,onChange:l}){const a=ze(e);return r(E,{children:v({min:e,max:t,step:n,value:o??a,readout:!1,ariaLabel:i,onChange:l})})}function Eo({label:e,changed:t=!1,onReset:n=()=>{}}){const o=le(),i=ze(B),l=o?"Site":"Section";return r(g,{label:e,changed:t,detail:w(`${i}px`,o?"Site styles":"the section"),onReset:n})}function To(){return r(E,{children:le()?"The section is full width, so this card follows Site styles ▸ Basics ▸ Corners.":"Follows the section's Corners until you set a number here."})}function Ro(){return $("Corners",{min:B,max:W,unsetLabel:"Follows the section",unsetMark:r(Eo,{label:"Corners"}),restTrack:e=>r(yo,{...e}),hint:r(To,{})})}function Lo({value:e,onChange:t}){return r(ve,{label:P,value:e,corners:ee,onChange:t})}function vo({unset:e}){return r(E,{children:e?"Set a number above first — there is nothing to shape yet.":"Corners left off stay square. The row above sets how round the others are."})}function Oo(){return{type:"custom",render:({value:e,onChange:t})=>{const o=U(e)??[...F],i=o.length===F.length;return r(h,{label:P,icon:r(Ie,{}),value:Re(o),changed:!i,action:r(g,{label:P,changed:!i,onReset:()=>t(null)}),hint:r(vo,{unset:!Ut(e)}),children:r(Lo,{value:o,onChange:l=>{const a=U(l)??[];t(a.length===F.length?null:a)}})})}}}function No(){return{type:"custom",render:()=>r(Qe,{})}}function gi(){return{_gShape:C("Shape"),cardCorners:Ro(),cardCornerSides:Oo(),cardCornersApplyAll:No()}}function bi(){return L("Justify",r(dt,{}),we,we[0].value)}function xi(){return L("Item alignment",r(ut,{}),yn,"stretch")}function Ci(){return L(Ln,r(Mt,{}),He,He[0].value)}function Si(){return{type:"custom",render:({value:e,onChange:t})=>{const n=oe.find(o=>o.value===e)??oe[0];return r(h,{label:De,icon:r(Se,{}),value:n.label,children:r("div",{className:"sf-gallery-layouts",role:"group","aria-label":De,children:oe.map(o=>r(K,{content:o.label,className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":n.value===o.value,"aria-label":o.label,onClick:()=>t(o.value),children:r("span",{className:"sf-gallery-pic",children:Ao(o.weights).map((i,l)=>r("i",{style:{gridColumn:`span ${i}`}},l))})})},o.value))})})}}}function Ao(e){if(!e)return[3,4];const t=e.reduce((n,o)=>n+o,0);return e.map(n=>Math.round(n/t*12))}function Ii(){return L(En,r(_e,{}),Pe,Pe[0].value)}function _i(){return H(Tn,r(At,{}),ke,Rn,1,ke)}function yi(e){const t=ce(In,Qn("`Direction` names how a container's children run — a MODIFIER, not a thing. doc/naming.md N10.1 gives the idea a dash in its Glyph column; editor-shell's own `direction` meaning says the bare row is CORRECT and not an omission (SS seat, 2026-09-11)."),_n(e),Fe(e,void 0));return{type:"custom",render:n=>t.render({...n,value:Fe(e,n.value),onChange:o=>n.onChange(o)})}}function Ei(e,t,n,o,i,l){return{type:"custom",render:({value:a,onChange:s})=>r(h,{label:e,icon:r(Te,{noun:l}),action:r(g,{label:e,changed:!Vn(a),detail:"the Text style in Site styles",onReset:()=>s(zn),defaultAction:{onPress:()=>s(Xn),title:"Keep this section's own built-in size",icon:r(ft,{})}}),children:v({min:t,max:n,step:o,value:typeof a=="number"?a:i,suffix:"px",ariaLabel:e,onChange:s})})}}function Ti(){return{_gCellWidth:C("Cell width"),gridSpan:L("Positions",r(Se,{}),[{label:"Auto",value:""},...Array.from({length:ot},(e,t)=>({label:t===0?"1 position":`${t+1} positions`,value:String(t+1)}))],"")}}function Y(){let e=null;try{e=N(t=>t).selectedItem}catch{e=null}return e?.props??{}}function Fo({min:e,max:t,step:n,px:o,label:i,onChange:l,desktopKey:a,fallback:s}){const c=Y()[a],d=te(void 0,c,s);return r(E,{children:v({min:e,max:t,step:n,value:te(o,c,s),readout:!1,ariaLabel:i,notch:d,onChange:l})})}function Po({label:e,desktopKey:t,fallback:n,changed:o=!1,onReset:i=()=>{}}){const l=Y()[t],a=te(void 0,l,n);return r(g,{label:e,changed:o,detail:`${a}px on ${ne.desktop.toLowerCase()}`,onReset:i})}function wo(e){return $(e.label,{min:e.min,max:e.max,step:e.step,unsetLabel:`Follows ${ne.desktop}`,unsetMark:r(Po,{label:e.label,desktopKey:e.desktopKey,fallback:e.fallback}),restTrack:t=>r(Fo,{...t,desktopKey:e.desktopKey,fallback:e.fallback})})}function Ri(e={}){const t=e.keys?.top??"sectionPaddingTop",n=e.keys?.bottom??"sectionPaddingBottom",o=e.group!==!1,i=x=>o?x:`Padding ${x.toLowerCase()}`,l=x=>H(i("Top"),r(Nt,{}),S.min,S.max,S.step,x,"px"),a=(x,_,je,j=S)=>R("mobile",wo({label:i(x),desktopKey:_,min:j.min,max:j.max,step:j.step,fallback:je})),s=e.top??S.min,c=e.bottom??S.min,d="sectionPaddingLeft",f="sectionPaddingRight",u=e.sideBounds??S,p=e.side??u.min,m=e.sidePhone??p,b=e.phone===!0,I=x=>b?R("desktop",x):x;return M({...o?{_gSpacing:C("Padding")}:{},[t]:I(l(s)),...b?{[X(t)]:a("Top",t,s)}:{},...e.only==="top"?{}:{[n]:I(H(i("Bottom"),r(Lt,{}),S.min,S.max,S.step,c,"px")),...b?{[X(n)]:a("Bottom",n,c)}:{}},...e.sides?{[d]:I(H(i("Left"),r(vt,{}),u.min,u.max,u.step,p,"px")),...b?{[X(d)]:a("Left",d,m,u)}:{},[f]:I(H(i("Right"),r(Ot,{}),u.min,u.max,u.step,p,"px")),...b?{[X(f)]:a("Right",f,m,u)}:{}}:{}})}const ko={contained:"Contained",page:"Page",full:"Full"},ae="Width";function Li(e,t=Yn,n=!0){const o=t.map(i=>({label:jn[i]??ko[i],value:i}));return M({...n?{_gWidth:C(ae)}:{},widthMode:{type:"custom",render:({onChange:i,field:l})=>r(h,{label:"Width",icon:r(Gt,{}),action:n?r(ro,{inherited:l?.inherited??!1,onReset:()=>i(qn),label:ae}):void 0,children:se({options:o,value:l?.currentValue||e,onChange:i,ariaLabel:ae})})}})}function vi(){const e=o=>({type:"custom",render:({value:i,onChange:l})=>y("div",{className:"sf-field",children:[o?y("div",{className:"sf-field-head",children:[r("span",{className:"sf-field-label sf-field-label--inline",children:G}),o(l)]}):null,r("div",{children:se({options:[{label:"Auto",value:"auto"},{label:"Fixed",value:"fixed"},{label:"Screen",value:"screen"}],value:["auto","fixed","screen"].includes(i)?i:"auto",onChange:l,ariaLabel:G})})]})}),t=()=>({type:"custom",render:({value:o,onChange:i,field:l})=>{const a=l?.unit==="%"?"%":"px",s=a==="%"?Sn:Cn;return r("div",{className:"sf-field",children:v({min:s.min,max:s.max,step:s.step,value:typeof o=="number"?o:s.fallback,suffix:a,ariaLabel:G,onChange:i})})}}),n=()=>ce("Unit",r(ye,{}),[{label:"px",value:"px"},{label:"%",value:"%"}],"px");return M({_gHeight:C(G),sectionHeightMode:R("desktop",e()),sectionHeightValue:R("desktop",t()),sectionHeightUnit:R("desktop",n()),sectionHeightModePhone:R("mobile",e(o=>r(Do,{onClear:()=>o(void 0)}))),sectionHeightValuePhone:R("mobile",t()),sectionHeightUnitPhone:R("mobile",n())})}function Do({onClear:e}){const t=Y(),n=bn(t),o=xn(t),i=`${o.mode==="auto"?"Auto":`${o.value}${o.unit}`} on ${ne.desktop.toLowerCase()}`;return r(g,{label:G,changed:n,detail:i,onReset:e})}function Oi(){return{_gAnchor:C("Anchor"),anchor:uo("Anchor name","e.g. about",ao)}}function O(e,t,n){return{type:"custom",render:({value:o,onChange:i,id:l,name:a})=>{const s=typeof o=="boolean"?o:t,c=`${l??a??e}-label`;return r(h,{label:e,labelId:c,icon:n,action:r(qt,{checked:s,onChange:i,ariaLabelledBy:c})})}}}function Ni(){return{type:"custom",render:({value:e,onChange:t,id:n,name:o})=>{const i=`${String(n??o??"pageBackground")}-colour`;return r(h,{label:"Background",icon:r(Ee,{}),htmlFor:i,action:r(Oe,{id:i,label:"Background",value:$t(e),onChange:t})})}}}function Ai(e,t){return{type:"custom",render:({value:n,onChange:o,id:i})=>{const l=typeof n=="boolean"?n:t,a=`${i??e}-checkbox`;return r(h,{label:e,htmlFor:a,className:"sf-checkbox",action:r(Qt,{id:a,checked:l,onChange:o})})}}}function Fi(e,t){return{type:"custom",render:({value:n,onChange:o})=>r(h,{label:e,action:Oe({value:n||t,onChange:o,label:e})})}}const Ho=[{value:"0% 0%",label:"Top left"},{value:"50% 0%",label:"Top"},{value:"100% 0%",label:"Top right"},{value:"0% 50%",label:"Left"},{value:"50% 50%",label:"Center"},{value:"100% 50%",label:"Right"},{value:"0% 100%",label:"Bottom left"},{value:"50% 100%",label:"Bottom"},{value:"100% 100%",label:"Bottom right"}];function Ve({label:e,value:t,onChange:n,points:o=Ho}){return r(Yt,{label:e,value:t,points:o,onChange:n})}function Pi(e,t=fe,n="mediaImage"){return{type:"custom",render:({value:o,onChange:i})=>r("div",{className:"sf-focal-row",children:r(Bo,{label:e,value:o||t,onChange:i,imageProp:n})})}}function Bo({label:e,value:t,onChange:n,imageProp:o}){const{selectedItem:i}=N(a=>a),l=i?.props?.[o];return r(dn,{label:e,value:t,onChange:n,image:typeof l=="string"?l:void 0})}const Go=xe([]);function wi(e,{stacking:t,fallback:n=at}){return{type:"custom",render:({value:o,onChange:i})=>{const l=lt.includes(o)?o:n;return t?r(Mo,{label:e,value:l,onChange:i}):Ye({label:e,value:l,onChange:i,points:Go})}}}function Mo({label:e,value:t,onChange:n}){const{appState:o,selectedItem:i}=N(s=>s),l=i?.props?.id?String(i.props.id):void 0,a=l?it(o?.data,l):[];return Ye({label:e,value:t,onChange:n,points:xe(a,l)})}function Ye({label:e,value:t,onChange:n,points:o}){const i=o.find(l=>l.disabled);return r(h,{label:e,icon:r(Ft,{}),hint:i?i.title:void 0,children:Ve({label:e,value:st(t),onChange:n,points:o})})}const ki={top:r(Ct,{}),right:r(xt,{}),bottom:r(gt,{}),left:r(bt,{})};function Di(e,t,n,o,i,l){const a=f=>t.find(u=>u.value===f),s=f=>({value:f,label:"",disabled:!0,title:o}),c=f=>{const u=t.find(m=>m.cell===f);if(!u)return s(`missing-${f}`);const p=l?.[f];return p?{value:u.value,label:u.label,icon:p}:{value:u.value,label:u.label}},d=[s("corner-top-left"),c("top"),s("corner-top-right"),c("left"),s("centre"),c("right"),s("corner-bottom-left"),c("bottom"),s("corner-bottom-right")];return{type:"custom",render:({value:f,onChange:u})=>{const p=t.some(m=>m.value===f)?f:n;return r(h,{label:e,icon:i,value:a(p)?.label??"",children:Ve({label:e,value:p,onChange:u,points:d})})}}}const $o="\0note";function L(e,t,n,o,i){return{type:"custom",options:n,fallback:o,...i?{note:i}:{},render:({value:l,onChange:a,field:s})=>{const c=s.options??n,d=s.fallback??o,f=c.some(u=>u.value===l)?l:d;return r(h,{label:e,icon:V(t),children:r(Jt,{value:f,ariaLabel:e,onChange:a,options:[...i?[{label:i,value:$o,disabled:!0}]:[],...c.map(u=>({label:u.label,value:u.value}))]})})}}}function Hi(e,t,n){return{type:"custom",options:t,render:({value:o,onChange:i,field:l})=>r(fn,{label:e,options:l.options??t,value:Array.isArray(o)?o:[],onChange:i,...n?{emptyLabel:n}:{}})}}function Bi(e,t,n,o){return{type:"custom",options:t,fallback:n,render:({value:i,onChange:l,field:a})=>r(mn,{label:e,options:a.options??t,fallback:a.fallback??n,value:i,onChange:l,placeholder:o})}}function Gi(e,t={}){return{type:"custom",render:({value:n,onChange:o})=>{const i={value:n,onChange:o,...t};return r(e,{...i})}}}function se({options:e,value:t,onChange:n,ariaLabel:o,disabled:i=!1}){return r(jt,{options:e.map(l=>({id:l.value,label:l.label,title:l.title})),value:t,onChange:n,ariaLabel:o,disabled:i})}const Mi=[{label:"Image",value:"image"},{label:"Video",value:"video"}];function ce(e,t,n,o){const i=n.map(l=>typeof l=="string"?{label:l,value:l}:l);return{type:"custom",render:({value:l,onChange:a,field:s})=>r(h,{label:e,icon:V(t),children:se({options:i,value:i.some(c=>c.value===l)?l:l||s?.currentValue||o,onChange:a,ariaLabel:e})})}}function $i(e,t,n){return{type:"custom",[me]:!0,render:({value:o,onChange:i})=>r(pn,{value:o||"",onChange:i,label:e,accept:t,placeholder:n})}}const Wi={HeroSingle:["imageFocal"],ContactLocations:["locations[].photo"],ProcessSteps:["steps[].image"]};function Ui({value:e,onChange:t,label:n}){const o=e||{},i=!!o.pending,l=i?"var(--fg-dim, #888)":o.ok?"#1d9e75":"#d85a30",a=(s,c)=>t({...o,[s]:c===""?void 0:Number(c)});return y(h,{label:n,icon:r(Q,{}),children:[r("button",{type:"button",disabled:i,onClick:()=>t({...o,pending:!0,ok:!1,status:"Finding…"}),style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"center",gap:6,padding:"8px 10px",fontSize:13,cursor:i?"default":"pointer",opacity:i?.6:1,border:"1px solid var(--border-strong, #ccc)",borderRadius:6,background:"transparent",color:"inherit"},children:i?"Finding…":"Find coordinates"}),o.status&&r("div",{style:{marginTop:6,fontSize:12,lineHeight:1.4,color:l},children:o.status}),r("div",{style:{marginTop:6,fontSize:11,color:"var(--fg-dim, #999)"},children:"Coordinates from OpenStreetMap"}),r("button",{type:"button",onClick:()=>t({...o,manual:!o.manual}),style:{marginTop:8,padding:0,border:"none",background:"none",font:"inherit",fontSize:12,color:"var(--sf-accent, #2563eb)",cursor:"pointer",textDecoration:"underline"},children:o.manual?"Hide manual coordinates":"Enter coordinates manually"}),o.manual&&y("div",{style:{marginTop:8,display:"grid",gap:8},children:[r(h,{label:"Latitude",icon:r(Q,{}),children:r("input",{type:"number",step:"any",placeholder:"e.g. 34.0990198",value:typeof o.lat=="number"?o.lat:"",onChange:s=>a("lat",s.target.value)})}),r(h,{label:"Longitude",icon:r(Q,{}),children:r("input",{type:"number",step:"any",placeholder:"e.g. -117.9842833",value:typeof o.lng=="number"?o.lng:"",onChange:s=>a("lng",s.target.value)})})]})]})}function Wo(e,t){return t===null||t<0||t>=e.length?"":e[t]?.text??""}function Uo(e,t,n){const o=e.map(i=>({text:i?.text??""}));return t===null||t<0||t>=e.length?o:o.map((i,l)=>l===t?{text:n}:i)}function Ki(e,t){return e===null?null:t>e?e:null}function Ko(e,t,n){if(n===null||n>=t.length)return null;for(let o=0;o<n;o+=1)if(e[o]!==t[o])return null;return e[n]!==t[n]&&t.includes(e[n])||e[n]!==t[n]&&t.length!==e.length?null:n}const Xi={label:"Ticker items",icon:r(Rt,{})};function zi(e,t,n,o){return{type:"custom",[T]:{control:"textList",label:e,placeholder:n,itemKey:"text",rendering:o},render:({value:i,onChange:l})=>r(Xo,{label:e,icon:V(t),items:Array.isArray(i)?i:[],placeholder:n,onChange:l,markup:o==="markup"})}}function Xo({label:e,icon:t,items:n,placeholder:o,onChange:i,markup:l=!1}){const a=q(null),[s,c]=ue(null),d=u=>u.map(p=>({text:p?.text??""}));return r(Zt,{label:e,icon:t,noun:"item",items:n,onChange:u=>{const p=Ko(n,u,s);p===null&&(a.current=null),c(p),i(d(u))},newItem:()=>({text:""}),open:null,onOpen:()=>{},renderItem:()=>null,above:l?r(Ne,{target:a,value:Wo(n,s),onChange:u=>i(Uo(n,s??-1,u)),disabled:s===null,label:s===null?"Formatting — click a row first":`Formatting — row ${s+1}`}):void 0,renderRow:(u,p,m)=>r("input",{type:"text",className:l&&s===p?"sf-list-marking":void 0,value:u?.text??"",placeholder:o,"aria-label":`${e} ${p+1}`,onChange:b=>m({text:b.target.value}),onFocus:b=>{a.current=b.currentTarget,c(p)}})})}function Vi(e,t){const n=`${e.label} — row ${t+1}`;return D({control:"plainText",label:n,placeholder:e.placeholder,offPage:e.offPage},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:n,placeholder:e.placeholder,hideable:!1,markup:e.rendering==="markup"})})}function Yi(e){return{_gCards:C("Cards"),coverIndex:L("Cover image",r(Et,{}),sn,String(cn),e?.coverHint??"A card's opening picture — a card pinned to a finish keeps its own."),imageBackground:go("Image background",Pn),cardImage:zo(),spinOnHover:O("Rotate on hover",e?.spinDefault??!0,r(wt,{}))}}function ji(){return{outline:L("Card outline",r(kt,{}),rn,an),indexBadge:L("Card number",r(ye,{}),on,ln),showBadge:O("Product badge",!0,r(Te,{noun:"tag"}))}}function qi(e){const t=e?.bottomDefault??!0;return{_gShowOnCard:C("Show on a card"),showCardPrice:O("Price",!0,r(St,{})),showCardFinishes:O("Finish swatches",!0,r(It,{})),showCardSizes:O("Sizes",t,r(Pt,{})),showCardBuy:O("Buy button",t,r(ht,{})),showCardPage:O("Page button",t,r(Ee,{}))}}function zo(){return $("Card image",{min:B,max:W,step:et,hint:"Rounds the picture. The card's own corner is in Site styles."})}function Ji(){return $(nt,{min:B,max:W,step:tt,unsetLabel:"Square",hint:"Rounds the picture. Left alone it stays square."})}function Zi(){return{type:"custom",render:({value:e,onChange:t})=>r(Vo,{value:typeof e=="string"?e:"",onChange:t})}}function Vo({value:e,onChange:t}){const[n,o]=ue(null),i=be.filter(a=>n===null||A[a].across===n),l=e&&e in A?A[e]:null;return y(E,{children:[r(h,{label:"Photos in a row",icon:r(mt,{}),children:y("div",{className:"sf-gallery-filter",children:[r("button",{type:"button","aria-pressed":n===null,onClick:()=>o(null),children:"All"}),rt.map(a=>r("button",{type:"button","aria-pressed":n===a,onClick:()=>o(a),children:a},a))]})}),r(h,{label:"Layout",icon:r(_t,{}),value:l?l.label:"Not chosen",hint:`${i.length} of ${be.length} layouts`,children:r("div",{className:"sf-gallery-layouts",children:i.map(a=>r(K,{content:A[a].label,className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":e===a,"aria-label":A[a].label,onClick:()=>t(e===a?"":a),children:r("span",{className:"sf-gallery-pic",children:A[a].desktop.map(([s,c],d)=>r("i",{style:{gridColumn:`span ${s}`,gridRow:`span ${c}`}},d))})})},a))})})]})}export{ao as ANCHOR_HINT,Qr as BOUND_TO_POST_NOTE,ii as BUCKET_ICONS,Wi as CUSTOM_FIELD_MEDIA,Ui as CoordsField,ki as EDGE_ARROWS,fe as FOCAL_DEFAULT,Ho as FOCAL_POINTS,J as FOLD_FIELD_MARKER,Ve as FocalPicker,mo as GroupLabel,lo as HIGHLIGHT_HINT,k as HidableTextField,he as LINK_FIELD_MARKER,Yr as Label,me as MEDIA_FIELD_MARKER,Mi as MEDIA_TYPE_OPTIONS,ho as PanelNoteLine,Ye as PlacementGridView,ge as SCAFFOLD_FIELD_MARKER,nl as SCALAR_TEXT_CONTROLS,Xe as SECTION_BLEEDS_HINT,po as SectionHeading,se as Segmented,oo as SiteGapDefaultReset,v as Slider,Ue as Swatches,tl as TEXT_CONTROL_KINDS,T as TEXT_FIELD_MARKER,Xi as TICKER_ITEMS_ROW,Xo as TextListField,ro as WidthDefaultReset,Ko as aimAfterListChange,Oi as anchorFields,w as backTo,di as backgroundField,xi as boxAlignField,Ii as boxBlockSpacingField,bi as boxJustifyField,_i as boxPhoneRowField,Si as boxShareField,Ci as boxWrapField,ui as bucketHeader,Oo as cardCornerSidesField,Ro as cardCornersField,go as cardImageBackgroundField,zo as cardImageField,Yi as cardMediaFields,gi as cardShapeFields,qi as cardShowFields,ji as cardStyleFields,Ti as cellWidthFields,Ai as checkbox,Fi as colorInput,ni as copyText,yi as directionField,Di as edgePad,li as entriesHiddenForTab,Pi as focalPicker,Ki as focusAfterRemove,Z as foldMetaOf,Zi as galleryLayoutField,fi as gapField,C as group,vi as heightFields,pe as hidableText,co as hintIsWhileTyping,V as iconOf,Ji as imageCornersField,ci as isBucketHeader,eo as isNoGlyph,oi as linkField,Hi as multiSelect,Qn as noGlyph,Ni as pageBackgroundField,ai as panelNote,wo as phoneOverrideField,wi as placementField,uo as plainText,ri as plainTextarea,$ as pxField,de as readHidable,Wo as rowText,Bi as searchSelect,si as section,mi as sectionAnimationFields,bo as sectionCornerSidesField,Co as sectionCornersField,hi as sectionShapeFields,pi as sectionThemeFields,ce as segmented,L as select,Uo as setRowText,Ei as sizeField,H as slider,Gi as sourceField,Ri as spacingFields,ei as text,Ze as textFieldIdentifier,Jr as textFieldOffPage,zi as textList,Vi as textListRowField,ti as textarea,O as toggle,$i as upload,to as usePageWidthDetail,no as useSiteGapDetail,Li as widthField,Zr as withIdentifier,qr as withOffPage,jr as withScaffold};
1
+ "use client";import{jsx as r,jsxs as y,Fragment as E}from"react/jsx-runtime";import{cloneElement as qe,useId as Je,useRef as q,useState as ue}from"react";import{useEasel as N}from"efficient-easel/easel";import{readHidable as de,hidableText as pe}from"./hidable.js";import{FOLD_FIELD_MARKER as J,LINK_FIELD_MARKER as me,MEDIA_FIELD_MARKER as fe,SCAFFOLD_FIELD_MARKER as he,TEXT_FIELD_MARKER as T,foldMetaOf as Z,textFieldIdentifier as Ze}from"./field-markers.js";import Qe from"../../components/ApplyCornersToSiblings.js";import{CARD_IMAGE_RADIUS_STEP as et,CORNER_RADIUS_MAX as W,CORNER_RADIUS_MIN as B}from"../content/card-image-shape.js";import{IMAGE_CORNER_STEP as tt,IMAGE_CORNERS_LABEL as nt}from"../content/image-corners.js";import{GRID_MAX_COLUMNS as ot}from"../content/grid-span.js";import{GALLERY_ACROSS_BUCKETS as rt,GALLERY_LAYOUTS as A,GALLERY_LAYOUT_KEYS as ge}from"../content/gallery-layout.js";import{anchorSiblingsOf as it,HERO_GROUP_PLACEMENTS as lt,HERO_GROUP_PLACEMENT_DEFAULT as at,normalisePlacement as st,placementPoints as be}from"../hero-group-placement.js";import ct from"../../components/KeepHint.js";import{AlignLeftIcon as ut,AlignSeparateIcon as dt,AnimationIcon as xe,BackgroundIcon as pt,BlockSectionIcon as mt,CartIcon as ft,ColumnWidthsIcon as Ce,ColumnsIcon as ht,CornerIcon as Se,DirectionDownIcon as gt,DirectionLeftIcon as bt,DirectionRightIcon as xt,DirectionUpIcon as Ct,DollarIcon as St,FinishIcon as It,GapIcon as Ie,GridIcon as _t,GroundIcon as yt,HashIcon as _e,ImageIcon as Et,LayoutIcon as Tt,ListIcon as Rt,LocationIcon as Q,PaddingBottomIcon as Lt,PaddingLeftIcon as vt,PaddingRightIcon as Ot,PaddingTopIcon as Nt,PageIcon as ye,PhoneIcon as At,PlacementIcon as Ft,ProductSizeIcon as Pt,RotateIcon as wt,SquareIcon as kt,StylesIcon as Dt,TextLinesIcon as Ht,TypeIcon as Bt,WidthIcon as Gt,WrapIcon as Mt}from"efficient-easel/icons";import{FieldGlyph as Ee}from"../../components/FieldGlyph.js";import{resolvePageBackground as $t}from"../content/page-background.js";import{CORNER_SIDES as F,CORNER_SIDE_POINTS as ee,CORNER_SIDES_LABEL as P,cornerSidesSummary as Te,hasOwnSectionCorners as Wt,normalizeCornerSides as U}from"../content/section-corners.js";import{hasOwnCardCorners as Ut}from"../content/card-corners.js";import{SECTION_MOTION_NONE as Kt,SECTION_MOTION_OPTIONS as Xt}from"../content/section-animation.js";import{enclosingSectionProps as Re}from"./enclosing-section.js";import{SettingsCorners as Le,SettingsDefaultReset as g,SettingsField as f,SettingsGroupHead as zt,SettingsGroupSub as Vt,SettingsPlacement as Yt,SettingsSegmented as jt,SettingsSwitch as qt}from"efficient-easel/panel";import{FieldSelect as Jt,ListField as Zt}from"efficient-easel/fields";import{Checkbox as Qt,DateTimePicker as en,FOCAL_DEFAULT as ve,Slider as tn,Tooltip as K}from"efficient-shell/ui";import{ColourControl as Oe}from"./ColourControl.js";import Ne from"./MarkupToolbar.js";import{deviceField as R}from"./device-fields.js";import{noControlField as nn}from"./panel-no-control-mark.js";import{phoneKey as X,resolvePhoneValue as te}from"./phone-override.js";import{SuppressibleText as on}from"./section-text-suppress.js";import{CARD_INDEX_OPTIONS as rn,CARD_OUTLINE_OPTIONS as ln,DEFAULT_CARD_INDEX_FORMAT as an,DEFAULT_CARD_OUTLINE as sn}from"../sections/product-card-style.js";import{COVER_INDEX_OPTIONS as cn,DEFAULT_COVER_INDEX as un}from"../sections/card-cover-index.js";import{SCALAR_TEXT_CONTROLS as dn}from"./text-control-kinds.js";import pn from"../../components/ImageFocusRow.js";import mn from"../../components/MediaUploadField.js";import fn from"../../components/MultiSelectField.js";import hn from"../../components/SectionThemePicker.js";import gn from"../../components/SearchSelectField.js";import bn from"../../components/StorefrontLinkField.js";import Ae from"../../components/UiIcon.js";import{SECTION_PADDING as S}from"../content/section-padding.js";import{hasPhoneHeight as xn,resolveSectionMinHeight as Cn}from"../content/section-min-height.js";import{VIEW_TIER_LABEL as ne}from"../content/view-tiers.js";import{SECTION_MIN_HEIGHT as Sn,SECTION_MIN_HEIGHT_GROUP_LABEL as G,SECTION_SCREEN_PCT as In}from"../content/section-min-height.js";import{CONTAINER_DIRECTION_LABEL as _n,containerDirectionPoints as yn,resolveContainerDirection as Fe}from"../content/container-direction.js";import{BOX_ALIGN_POINTS as En,BOX_BLOCK_SPACING_LABEL as Tn,BOX_BLOCK_SPACING_POINTS as Pe,BOX_JUSTIFY_POINTS as we,BOX_PHONE_ROW_LABEL as Rn,BOX_PHONE_ROW_MAX as Ln,BOX_PHONE_ROW_MIN as ke,BOX_SHARE_LABEL as De,BOX_SHARE_POINTS as oe,BOX_WRAP_LABEL as vn,BOX_WRAP_POINTS as He}from"../content/box-layout.js";import{usePreviewHeader as z}from"../../components/PreviewHeaderContext.js";import{CONTAINER_GAP as re,CONTAINER_GAP_BUILT_IN as On,GAP_FIELD_CONTAINER as Nn,hasOwnContainerGap as An,resolveContainerGap as Fn}from"../content/container-gap.js";import{CARD_IMAGE_BG_INHERIT as Pn,CARD_IMAGE_BG_OFF as wn,CARD_IMAGE_BG_SWATCH_NAMES as kn,CARD_IMAGE_BG_SWATCHES as Dn,isCardImageBackgroundInheriting as Hn,cardImageBackgroundChoice as Bn,THEME_CARD_IMAGE_BG as Gn}from"../content/card-image-background.js";import{SECTION_BG_INHERIT as Mn,SECTION_BG_SWATCHES as $n,SECTION_BG_SWATCH_NAMES as Wn,THEME_SECTION_BG as Un,isSectionBackgroundInheriting as Kn}from"../content/section-background.js";import{SECTION_THEME_GROUP_LABEL as Xn}from"../content/section-surface.js";import{TYPE_SIZE_FIXED as zn,TYPE_SIZE_INHERIT as Vn,isTypeSizeInheriting as Yn}from"../content/section-type-size.js";import{SECTION_WIDTH_CHOICES as jn,WIDTH_CHOICE_LABEL as qn,WIDTH_INHERIT as Jn,resolveWidth as Zn,sectionRunsFullWidth as Be}from"../content/section-width.js";import{useFoldHeadingLevel as Ge}from"./panel-heading-scope.js";import{withStyleKind as Qn}from"efficient-easel/style-clipboard";function M(e){for(const[t,n]of Object.entries(e))n&&typeof n=="object"&&!Z(n)&&Qn(n,`section:${t}`);return e}function Yr({children:e}){return r("div",{className:"sf-field-label",children:e})}function Me(){return null}function eo(e){if(!e.trim())throw new Error("noGlyph() needs a reason naming the ruling that decided it.");return r(Me,{},e)}function to(e){return e.type===Me}function V(e){return to(e)?void 0:e}function w(e,t){return`${e} from ${t}`}function no(){const{appState:e}=N(i=>i),t=e.data.root?.props??{},{mode:n,pageWidth:o}=Zn(t,"full");return w(n==="page"?`${o}px`:n==="contained"?"Contained":"Full","the page")}function oo(){const{blockGap:e}=z();return e===null?"this container's own spacing":w(`${e}px`,"Site styles")}function ro({inherited:e,onReset:t,label:n}){return r(g,{label:n,changed:!e,detail:oo(),onReset:t})}function io({inherited:e,onReset:t,label:n}){return r(g,{label:n,changed:!e,detail:no(),onReset:t})}function k({value:e,onChange:t,label:n,placeholder:o,hint:i,multiline:l,hideable:a=!0,markup:s=!0}){const{text:c,hidden:d}=de(e),m=q(null),u=q(null),p=_=>t(a?{text:_,hidden:d}:_),h=()=>t({text:c,hidden:!d}),b=a&&d,I=Je(),x=i?uo(i)?r("span",{className:"sf-hint-keep sf-hint-while-typing",children:i}):r(ct,{children:i}):void 0;return r(f,{label:n,icon:r(Bt,{}),htmlFor:I,className:b?"is-hidden":void 0,hint:x,action:a?r(K,{content:d?`Show ${n} on the slide`:`Hide ${n} on the slide`,children:r("button",{type:"button",className:"sf-field-eye","aria-pressed":d,"aria-label":d?`Show ${n} on the slide`:`Hide ${n} on the slide`,onClick:h,children:d?r(Ae,{name:"eye-off",size:14}):r(Ae,{name:"eye",size:14})})}):void 0,children:y("div",{className:"sf-copybox",children:[s&&r(Ne,{target:l?u:m,value:c,onChange:p}),l?r("textarea",{id:I,ref:u,value:c,placeholder:o,onChange:_=>p(_.target.value)}):r("input",{id:I,ref:m,type:"text",value:c,placeholder:o,onChange:_=>p(_.target.value)})]})})}function jr(e,t){return{...e,[he]:t}}function qr(e){const t=e[T];if(!t)throw new Error("withOffPage: the field holds no authored text");return{...e,[T]:{...t,offPage:!0}}}function Jr(e){return!e||typeof e!="object"?!1:e[T]?.offPage===!0}function Zr(e){const t=e[T];if(!t)throw new Error("withIdentifier: the field holds no authored text");return{...e,[T]:{...t,identifier:!0}}}import{TEXT_CONTROL_KINDS as nl,SCALAR_TEXT_CONTROLS as ol}from"./text-control-kinds.js";const lo=new Set(dn),D=(e,t)=>{const n={...t,[T]:e};if(!lo.has(e.control))return n;const o=t.render;return{...nn(n,"authored-copy"),render:i=>r(on,{name:i.name,children:o(i)})}},Qr="Everything else on this block comes from the linked post. Unlink it to edit by hand.",ao="Select a word, then press the highlighter.",so="A short name so a link can jump straight to this section, like yoursite.com/page#about.",co=new Set([ao]),uo=e=>co.has(e);function ei(e,t,n){return D({control:"text",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n})})}function ti(e,t,n){return D({control:"textarea",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,multiline:!0})})}function po(e,t,n){return D({control:"plainText",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,hideable:!1,markup:!1})})}function ni(e,t,n){return D({control:"copyText",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,hideable:!1})})}function oi(e){return{type:"custom",[me]:{label:e},render:({value:t,onChange:n})=>r(bn,{value:pe(t),onChange:n,label:e})}}function ri(e,t,n){return D({control:"plainTextarea",label:e,placeholder:t,hint:n},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:e,placeholder:t,hint:n,multiline:!0,hideable:!1})})}const ii={Content:Ht,Style:Dt,Layout:Tt,Animation:xe};function li(e,t){return e.includes("Content")?t!=="Content":null}function mo({label:e}){return r(zt,{title:e,level:Ge(1)})}function fo({level:e,label:t}){return e===1?r(mo,{label:t}):r(go,{label:t})}function $e(e,t){return{type:"custom",[J]:{label:e,level:t},render:()=>r(fo,{level:t,label:e})}}function C(e){return $e(e,2)}function ai(e){return{type:"custom",render:()=>r(ho,{text:e})}}function ho({text:e}){return r("p",{className:"sf-note",children:e})}function si(e){return $e(e,1)}function ci(e){return Z(e)!==null&&e?.tabs!==void 0}const We=new Map;function ui(e,t){const n=`${e}\0${t?t.join(""):""}`,o=We.get(n)??{type:"custom",tabs:t,[J]:{label:e,level:1},bucket:e,marker:!0,render:()=>r(E,{})};return We.set(n,o),o}function go({label:e}){return r(Vt,{title:e,level:Ge(2)})}function Ue({swatches:e,current:t,onPick:n,names:o}){const i=e.find(a=>a.toLowerCase()===t.toLowerCase()),l=(i?o?.[i]:void 0)??t;return y("div",{className:"sf-swatches",children:[e.map(a=>{const s=o?.[a]??a;return r(K,{content:s,children:r("button",{type:"button","aria-pressed":t.toLowerCase()===a.toLowerCase(),className:`sf-swatch ${t.toLowerCase()===a.toLowerCase()?"is-active":""}`,style:{background:a},onClick:()=>n(a),"aria-label":s})},a)}),r("span",{className:"sf-swatch-hex",children:l})]})}function di(e,t){return{type:"custom",render:({value:n,onChange:o})=>{const i=Kn(n,t);return r(f,{label:e,icon:r(pt,{}),changed:!i,action:r(g,{label:e,changed:!i,detail:"the theme's section background",onReset:()=>o(Mn)}),children:Ue({swatches:$n,current:i?Un:n??t??"",onPick:o,names:Wn})})}}}function bo(e,t){return{type:"custom",render:({value:n,onChange:o})=>{const i=n,l=Hn(i,t);return r(f,{label:e,icon:r(yt,{}),changed:!l,action:r(g,{label:e,changed:!l,detail:"the theme's image stage",onReset:()=>o(Pn)}),children:Ue({swatches:Dn,current:l?Gn:Bn(i,t),onPick:o,names:kn})})}}}function pi(e=n=>n,t){return M({_gSectionTheme:C(Xn),sectionAccent:{type:"custom",render:({value:n,onChange:o})=>r(hn,{value:e(n),onChange:o,followLabel:t})}})}function v({min:e,max:t,step:n,value:o,onChange:i,suffix:l="",readout:a=!0,notch:s,ariaLabel:c,disabled:d=!1}){const m=s!==void 0&&Number.isFinite(s)&&s>=e&&s<=t;return r("div",{className:m?"sf-slider has-notch":"sf-slider",style:m?{"--sf-notch":(s-e)/(t-e)}:void 0,children:r(tn,{min:e,max:t,step:n,value:o,suffix:l||void 0,showInput:a,label:c,disabled:d,size:"sm",className:"sf-slider-track",onChange:u=>{u!==null&&u!==o&&i(u)}})})}function H(e,t,n,o,i,l,a="",s){return{type:"custom",render:c=>r(f,{label:e,icon:V(t),action:s?s("storedValue"in c?c.storedValue:c.value,c.onChange):void 0,children:v({min:n,max:o,step:i,value:typeof c.value=="number"?c.value:l,suffix:a,ariaLabel:e,onChange:c.onChange})})}}function Ke({min:e,max:t,step:n,px:o,label:i,onChange:l,disabled:a=!1}){const{cornerRadiusPx:s}=z();return r(E,{children:v({min:e,max:t,step:n,value:o??(typeof s=="number"?s:e),readout:!1,ariaLabel:i,disabled:a,onChange:l})})}function $(e,t){const{min:n,max:o,step:i=1,unsetLabel:l,hint:a,restAtSite:s=!1,restTrack:c,unsetMark:d}=t;return{type:"custom",render:({value:m,onChange:u})=>{const p=typeof m=="number"?m:null,h=p===null;return r(f,{label:e,value:h?d?void 0:l:`${p}px`,changed:!h,action:d?qe(d,{changed:!h,onReset:()=>u(null)}):r(g,{label:e,changed:!h,onReset:()=>u(null)}),hint:a,children:c?c({min:n,max:o,step:i,px:p,label:e,onChange:u}):s?r(Ke,{min:n,max:o,step:i,px:p,label:e,onChange:u}):v({min:n,max:o,step:i,value:p??n,readout:!1,ariaLabel:e,onChange:u})})}}}function mi(e){const t=H("Gap",r(Ie,{}),re.min,re.max,re.step,On[e],"px",(n,o)=>r(ro,{inherited:!An(e,n),onReset:()=>o(void 0),label:"Gap"}));return{type:"custom",[Nn]:e,render:n=>t.render({...n,value:Fn(e,n.value,n.field?.siteGap),storedValue:n.value,onChange:o=>n.onChange(o)})}}function xo(){return{type:"custom",render:({value:e,onChange:t})=>{const o=U(e)??[...F],i=o.length===F.length;return r(f,{label:P,icon:r(Se,{}),value:Te(o),changed:!i,action:r(g,{label:P,changed:!i,onReset:()=>t(null)}),hint:"Corners left off stay square. The row above sets how round the others are.",children:r(yo,{value:o,onChange:l=>{const a=U(l)??[];t(a.length===F.length?null:a)}})})}}}function Co({label:e,changed:t=!1,onReset:n=()=>{}}){const{cornerRadiusPx:o}=z(),i=typeof o=="number"?`${o}px`:"not set";return r(g,{label:e,changed:t,detail:o==null?"the built-in corners":w(i,"Site styles"),onReset:n})}function So(){return $("Corners",{min:B,max:W,unsetLabel:"Follows the site",unsetMark:r(Co,{label:"Corners"}),restTrack:e=>r(Io,{...e}),hint:r(_o,{})})}const Xe="This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.";function ie(){return Be(Y())}function Io(e){return r(Ke,{...e,disabled:ie()})}function _o(){return r(E,{children:ie()?Xe:"Follows Site styles ▸ Basics ▸ Corners until you set a number here."})}function yo({value:e,onChange:t}){const n=ie();return r(Le,{label:P,value:e,corners:n?ee.map(o=>({...o,disabled:!0,title:Xe})):ee,onChange:t})}function fi(){return M({_gShape:C("Shape"),sectionCorners:So(),sectionCornerSides:xo()})}function hi(){return{_gMotion:C("Motion"),sectionAnimation:ce("Entrance",r(xe,{}),[...Xt],Kt)}}function le(){let e=null;try{const{appState:t,selectedItem:n}=N(i=>i),o=n?.props?.id?String(n.props.id):void 0;e=o?Re(t?.data,o):null}catch{e=null}return e!==null&&Be(e)}function ze(e){const{cornerRadiusPx:t}=z(),n=le(),o=typeof t=="number"?t:e;let i=null;try{const{appState:a,selectedItem:s}=N(d=>d),c=s?.props?.id?String(s.props.id):void 0;i=c?Re(a?.data,c):null}catch{i=null}if(n||!i)return o;const l=i.sectionCorners;return Wt(l)?l:o}function Eo({min:e,max:t,step:n,px:o,label:i,onChange:l}){const a=ze(e);return r(E,{children:v({min:e,max:t,step:n,value:o??a,readout:!1,ariaLabel:i,onChange:l})})}function To({label:e,changed:t=!1,onReset:n=()=>{}}){const o=le(),i=ze(B),l=o?"Site":"Section";return r(g,{label:e,changed:t,detail:w(`${i}px`,o?"Site styles":"the section"),onReset:n})}function Ro(){return r(E,{children:le()?"The section is full width, so this card follows Site styles ▸ Basics ▸ Corners.":"Follows the section's Corners until you set a number here."})}function Lo(){return $("Corners",{min:B,max:W,unsetLabel:"Follows the section",unsetMark:r(To,{label:"Corners"}),restTrack:e=>r(Eo,{...e}),hint:r(Ro,{})})}function vo({value:e,onChange:t}){return r(Le,{label:P,value:e,corners:ee,onChange:t})}function Oo({unset:e}){return r(E,{children:e?"Set a number above first — there is nothing to shape yet.":"Corners left off stay square. The row above sets how round the others are."})}function No(){return{type:"custom",render:({value:e,onChange:t})=>{const o=U(e)??[...F],i=o.length===F.length;return r(f,{label:P,icon:r(Se,{}),value:Te(o),changed:!i,action:r(g,{label:P,changed:!i,onReset:()=>t(null)}),hint:r(Oo,{unset:!Ut(e)}),children:r(vo,{value:o,onChange:l=>{const a=U(l)??[];t(a.length===F.length?null:a)}})})}}}function Ao(){return{type:"custom",render:()=>r(Qe,{})}}function gi(){return{_gShape:C("Shape"),cardCorners:Lo(),cardCornerSides:No(),cardCornersApplyAll:Ao()}}function bi(){return L("Justify",r(dt,{}),we,we[0].value)}function xi(){return L("Item alignment",r(ut,{}),En,"stretch")}function Ci(){return L(vn,r(Mt,{}),He,He[0].value)}function Si(){return{type:"custom",render:({value:e,onChange:t})=>{const n=oe.find(o=>o.value===e)??oe[0];return r(f,{label:De,icon:r(Ce,{}),value:n.label,children:r("div",{className:"sf-gallery-layouts",role:"group","aria-label":De,children:oe.map(o=>r(K,{content:o.label,className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":n.value===o.value,"aria-label":o.label,onClick:()=>t(o.value),children:r("span",{className:"sf-gallery-pic",children:Fo(o.weights).map((i,l)=>r("i",{style:{gridColumn:`span ${i}`}},l))})})},o.value))})})}}}function Fo(e){if(!e)return[3,4];const t=e.reduce((n,o)=>n+o,0);return e.map(n=>Math.round(n/t*12))}function Ii(){return L(Tn,r(Ie,{}),Pe,Pe[0].value)}function _i(){return H(Rn,r(At,{}),ke,Ln,1,ke)}function yi(e){const t=ce(_n,eo("`Direction` names how a container's children run — a MODIFIER, not a thing. doc/naming.md N10.1 gives the idea a dash in its Glyph column; editor-shell's own `direction` meaning says the bare row is CORRECT and not an omission (SS seat, 2026-09-11)."),yn(e),Fe(e,void 0));return{type:"custom",render:n=>t.render({...n,value:Fe(e,n.value),onChange:o=>n.onChange(o)})}}function Ei(e,t,n,o,i,l){return{type:"custom",render:({value:a,onChange:s})=>r(f,{label:e,icon:r(Ee,{noun:l}),action:r(g,{label:e,changed:!Yn(a),detail:"the Text style in Site styles",onReset:()=>s(Vn),defaultAction:{onPress:()=>s(zn),title:"Keep this section's own built-in size",icon:r(mt,{})}}),children:v({min:t,max:n,step:o,value:typeof a=="number"?a:i,suffix:"px",ariaLabel:e,onChange:s})})}}function Ti(){return{_gCellWidth:C("Cell width"),gridSpan:L("Positions",r(Ce,{}),[{label:"Auto",value:""},...Array.from({length:ot},(e,t)=>({label:t===0?"1 position":`${t+1} positions`,value:String(t+1)}))],"")}}function Y(){let e=null;try{e=N(t=>t).selectedItem}catch{e=null}return e?.props??{}}function Po({min:e,max:t,step:n,px:o,label:i,onChange:l,desktopKey:a,fallback:s}){const c=Y()[a],d=te(void 0,c,s);return r(E,{children:v({min:e,max:t,step:n,value:te(o,c,s),readout:!1,ariaLabel:i,notch:d,onChange:l})})}function wo({label:e,desktopKey:t,fallback:n,changed:o=!1,onReset:i=()=>{}}){const l=Y()[t],a=te(void 0,l,n);return r(g,{label:e,changed:o,detail:`${a}px on ${ne.desktop.toLowerCase()}`,onReset:i})}function ko(e){return $(e.label,{min:e.min,max:e.max,step:e.step,unsetLabel:`Follows ${ne.desktop}`,unsetMark:r(wo,{label:e.label,desktopKey:e.desktopKey,fallback:e.fallback}),restTrack:t=>r(Po,{...t,desktopKey:e.desktopKey,fallback:e.fallback})})}function Ri(e={}){const t=e.keys?.top??"sectionPaddingTop",n=e.keys?.bottom??"sectionPaddingBottom",o=e.group!==!1,i=x=>o?x:`Padding ${x.toLowerCase()}`,l=x=>H(i("Top"),r(Nt,{}),S.min,S.max,S.step,x,"px"),a=(x,_,je,j=S)=>R("mobile",ko({label:i(x),desktopKey:_,min:j.min,max:j.max,step:j.step,fallback:je})),s=e.top??S.min,c=e.bottom??S.min,d="sectionPaddingLeft",m="sectionPaddingRight",u=e.sideBounds??S,p=e.side??u.min,h=e.sidePhone??p,b=e.phone===!0,I=x=>b?R("desktop",x):x;return M({...o?{_gSpacing:C("Padding")}:{},[t]:I(l(s)),...b?{[X(t)]:a("Top",t,s)}:{},...e.only==="top"?{}:{[n]:I(H(i("Bottom"),r(Lt,{}),S.min,S.max,S.step,c,"px")),...b?{[X(n)]:a("Bottom",n,c)}:{}},...e.sides?{[d]:I(H(i("Left"),r(vt,{}),u.min,u.max,u.step,p,"px")),...b?{[X(d)]:a("Left",d,h,u)}:{},[m]:I(H(i("Right"),r(Ot,{}),u.min,u.max,u.step,p,"px")),...b?{[X(m)]:a("Right",m,h,u)}:{}}:{}})}const Do={contained:"Contained",page:"Page",full:"Full"},ae="Width";function Li(e,t=jn,n=!0){const o=t.map(i=>({label:qn[i]??Do[i],value:i}));return M({...n?{_gWidth:C(ae)}:{},widthMode:{type:"custom",render:({onChange:i,field:l})=>r(f,{label:"Width",icon:r(Gt,{}),action:n?r(io,{inherited:l?.inherited??!1,onReset:()=>i(Jn),label:ae}):void 0,children:se({options:o,value:l?.currentValue||e,onChange:i,ariaLabel:ae})})}})}function vi(){const e=o=>({type:"custom",render:({value:i,onChange:l})=>y("div",{className:"sf-field",children:[o?y("div",{className:"sf-field-head",children:[r("span",{className:"sf-field-label sf-field-label--inline",children:G}),o(l)]}):null,r("div",{children:se({options:[{label:"Auto",value:"auto"},{label:"Fixed",value:"fixed"},{label:"Screen",value:"screen"}],value:["auto","fixed","screen"].includes(i)?i:"auto",onChange:l,ariaLabel:G})})]})}),t=()=>({type:"custom",render:({value:o,onChange:i,field:l})=>{const a=l?.unit==="%"?"%":"px",s=a==="%"?In:Sn;return r("div",{className:"sf-field",children:v({min:s.min,max:s.max,step:s.step,value:typeof o=="number"?o:s.fallback,suffix:a,ariaLabel:G,onChange:i})})}}),n=()=>ce("Unit",r(_e,{}),[{label:"px",value:"px"},{label:"%",value:"%"}],"px");return M({_gHeight:C(G),sectionHeightMode:R("desktop",e()),sectionHeightValue:R("desktop",t()),sectionHeightUnit:R("desktop",n()),sectionHeightModePhone:R("mobile",e(o=>r(Ho,{onClear:()=>o(void 0)}))),sectionHeightValuePhone:R("mobile",t()),sectionHeightUnitPhone:R("mobile",n())})}function Ho({onClear:e}){const t=Y(),n=xn(t),o=Cn(t),i=`${o.mode==="auto"?"Auto":`${o.value}${o.unit}`} on ${ne.desktop.toLowerCase()}`;return r(g,{label:G,changed:n,detail:i,onReset:e})}function Oi(){return{_gAnchor:C("Anchor"),anchor:po("Anchor name","e.g. about",so)}}function Ni(e,t,n){return{type:"custom",render:({value:o,onChange:i,id:l,name:a})=>{const s=`${l??a??e}-datetime`,c=Date.parse(typeof o=="string"?o:"");return r(f,{label:e,icon:t,htmlFor:s,hint:n,children:r(en,{id:s,value:Number.isFinite(c)?new Date(c):null,onChange:d=>i(d?d.toISOString():"")})})}}}function O(e,t,n){return{type:"custom",render:({value:o,onChange:i,id:l,name:a})=>{const s=typeof o=="boolean"?o:t,c=`${l??a??e}-label`;return r(f,{label:e,labelId:c,icon:n,action:r(qt,{checked:s,onChange:i,ariaLabelledBy:c})})}}}function Ai(){return{type:"custom",render:({value:e,onChange:t,id:n,name:o})=>{const i=`${String(n??o??"pageBackground")}-colour`;return r(f,{label:"Background",icon:r(ye,{}),htmlFor:i,action:r(Oe,{id:i,label:"Background",value:$t(e),onChange:t})})}}}function Fi(e,t){return{type:"custom",render:({value:n,onChange:o,id:i})=>{const l=typeof n=="boolean"?n:t,a=`${i??e}-checkbox`;return r(f,{label:e,htmlFor:a,className:"sf-checkbox",action:r(Qt,{id:a,checked:l,onChange:o})})}}}function Pi(e,t){return{type:"custom",render:({value:n,onChange:o})=>r(f,{label:e,action:Oe({value:n||t,onChange:o,label:e})})}}const Bo=[{value:"0% 0%",label:"Top left"},{value:"50% 0%",label:"Top"},{value:"100% 0%",label:"Top right"},{value:"0% 50%",label:"Left"},{value:"50% 50%",label:"Center"},{value:"100% 50%",label:"Right"},{value:"0% 100%",label:"Bottom left"},{value:"50% 100%",label:"Bottom"},{value:"100% 100%",label:"Bottom right"}];function Ve({label:e,value:t,onChange:n,points:o=Bo}){return r(Yt,{label:e,value:t,points:o,onChange:n})}function wi(e,t=ve,n="mediaImage"){return{type:"custom",render:({value:o,onChange:i})=>r("div",{className:"sf-focal-row",children:r(Go,{label:e,value:o||t,onChange:i,imageProp:n})})}}function Go({label:e,value:t,onChange:n,imageProp:o}){const{selectedItem:i}=N(a=>a),l=i?.props?.[o];return r(pn,{label:e,value:t,onChange:n,image:typeof l=="string"?l:void 0})}const Mo=be([]);function ki(e,{stacking:t,fallback:n=at}){return{type:"custom",render:({value:o,onChange:i})=>{const l=lt.includes(o)?o:n;return t?r($o,{label:e,value:l,onChange:i}):Ye({label:e,value:l,onChange:i,points:Mo})}}}function $o({label:e,value:t,onChange:n}){const{appState:o,selectedItem:i}=N(s=>s),l=i?.props?.id?String(i.props.id):void 0,a=l?it(o?.data,l):[];return Ye({label:e,value:t,onChange:n,points:be(a,l)})}function Ye({label:e,value:t,onChange:n,points:o}){const i=o.find(l=>l.disabled);return r(f,{label:e,icon:r(Ft,{}),hint:i?i.title:void 0,children:Ve({label:e,value:st(t),onChange:n,points:o})})}const Di={top:r(Ct,{}),right:r(xt,{}),bottom:r(gt,{}),left:r(bt,{})};function Hi(e,t,n,o,i,l){const a=m=>t.find(u=>u.value===m),s=m=>({value:m,label:"",disabled:!0,title:o}),c=m=>{const u=t.find(h=>h.cell===m);if(!u)return s(`missing-${m}`);const p=l?.[m];return p?{value:u.value,label:u.label,icon:p}:{value:u.value,label:u.label}},d=[s("corner-top-left"),c("top"),s("corner-top-right"),c("left"),s("centre"),c("right"),s("corner-bottom-left"),c("bottom"),s("corner-bottom-right")];return{type:"custom",render:({value:m,onChange:u})=>{const p=t.some(h=>h.value===m)?m:n;return r(f,{label:e,icon:i,value:a(p)?.label??"",children:Ve({label:e,value:p,onChange:u,points:d})})}}}const Wo="\0note";function L(e,t,n,o,i){return{type:"custom",options:n,fallback:o,...i?{note:i}:{},render:({value:l,onChange:a,field:s})=>{const c=s.options??n,d=s.fallback??o,m=c.some(u=>u.value===l)?l:d;return r(f,{label:e,icon:V(t),children:r(Jt,{value:m,ariaLabel:e,onChange:a,options:[...i?[{label:i,value:Wo,disabled:!0}]:[],...c.map(u=>({label:u.label,value:u.value}))]})})}}}function Bi(e,t,n){return{type:"custom",options:t,render:({value:o,onChange:i,field:l})=>r(fn,{label:e,options:l.options??t,value:Array.isArray(o)?o:[],onChange:i,...n?{emptyLabel:n}:{}})}}function Gi(e,t,n,o){return{type:"custom",options:t,fallback:n,render:({value:i,onChange:l,field:a})=>r(gn,{label:e,options:a.options??t,fallback:a.fallback??n,value:i,onChange:l,placeholder:o})}}function Mi(e,t={}){return{type:"custom",render:({value:n,onChange:o})=>{const i={value:n,onChange:o,...t};return r(e,{...i})}}}function se({options:e,value:t,onChange:n,ariaLabel:o,disabled:i=!1}){return r(jt,{options:e.map(l=>({id:l.value,label:l.label,title:l.title})),value:t,onChange:n,ariaLabel:o,disabled:i})}const $i=[{label:"Image",value:"image"},{label:"Video",value:"video"}];function ce(e,t,n,o){const i=n.map(l=>typeof l=="string"?{label:l,value:l}:l);return{type:"custom",render:({value:l,onChange:a,field:s})=>r(f,{label:e,icon:V(t),children:se({options:i,value:i.some(c=>c.value===l)?l:l||s?.currentValue||o,onChange:a,ariaLabel:e})})}}function Wi(e,t,n){return{type:"custom",[fe]:!0,render:({value:o,onChange:i})=>r(mn,{value:o||"",onChange:i,label:e,accept:t,placeholder:n})}}const Ui={HeroSingle:["imageFocal"],ContactLocations:["locations[].photo"],ProcessSteps:["steps[].image"]};function Ki({value:e,onChange:t,label:n}){const o=e||{},i=!!o.pending,l=i?"var(--fg-dim, #888)":o.ok?"#1d9e75":"#d85a30",a=(s,c)=>t({...o,[s]:c===""?void 0:Number(c)});return y(f,{label:n,icon:r(Q,{}),children:[r("button",{type:"button",disabled:i,onClick:()=>t({...o,pending:!0,ok:!1,status:"Finding…"}),style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"center",gap:6,padding:"8px 10px",fontSize:13,cursor:i?"default":"pointer",opacity:i?.6:1,border:"1px solid var(--border-strong, #ccc)",borderRadius:6,background:"transparent",color:"inherit"},children:i?"Finding…":"Find coordinates"}),o.status&&r("div",{style:{marginTop:6,fontSize:12,lineHeight:1.4,color:l},children:o.status}),r("div",{style:{marginTop:6,fontSize:11,color:"var(--fg-dim, #999)"},children:"Coordinates from OpenStreetMap"}),r("button",{type:"button",onClick:()=>t({...o,manual:!o.manual}),style:{marginTop:8,padding:0,border:"none",background:"none",font:"inherit",fontSize:12,color:"var(--sf-accent, #2563eb)",cursor:"pointer",textDecoration:"underline"},children:o.manual?"Hide manual coordinates":"Enter coordinates manually"}),o.manual&&y("div",{style:{marginTop:8,display:"grid",gap:8},children:[r(f,{label:"Latitude",icon:r(Q,{}),children:r("input",{type:"number",step:"any",placeholder:"e.g. 34.0990198",value:typeof o.lat=="number"?o.lat:"",onChange:s=>a("lat",s.target.value)})}),r(f,{label:"Longitude",icon:r(Q,{}),children:r("input",{type:"number",step:"any",placeholder:"e.g. -117.9842833",value:typeof o.lng=="number"?o.lng:"",onChange:s=>a("lng",s.target.value)})})]})]})}function Uo(e,t){return t===null||t<0||t>=e.length?"":e[t]?.text??""}function Ko(e,t,n){const o=e.map(i=>({text:i?.text??""}));return t===null||t<0||t>=e.length?o:o.map((i,l)=>l===t?{text:n}:i)}function Xi(e,t){return e===null?null:t>e?e:null}function Xo(e,t,n){if(n===null||n>=t.length)return null;for(let o=0;o<n;o+=1)if(e[o]!==t[o])return null;return e[n]!==t[n]&&t.includes(e[n])||e[n]!==t[n]&&t.length!==e.length?null:n}const zi={label:"Ticker items",icon:r(Rt,{})};function Vi(e,t,n,o){return{type:"custom",[T]:{control:"textList",label:e,placeholder:n,itemKey:"text",rendering:o},render:({value:i,onChange:l})=>r(zo,{label:e,icon:V(t),items:Array.isArray(i)?i:[],placeholder:n,onChange:l,markup:o==="markup"})}}function zo({label:e,icon:t,items:n,placeholder:o,onChange:i,markup:l=!1}){const a=q(null),[s,c]=ue(null),d=u=>u.map(p=>({text:p?.text??""}));return r(Zt,{label:e,icon:t,noun:"item",items:n,onChange:u=>{const p=Xo(n,u,s);p===null&&(a.current=null),c(p),i(d(u))},newItem:()=>({text:""}),open:null,onOpen:()=>{},renderItem:()=>null,above:l?r(Ne,{target:a,value:Uo(n,s),onChange:u=>i(Ko(n,s??-1,u)),disabled:s===null,label:s===null?"Formatting — click a row first":`Formatting — row ${s+1}`}):void 0,renderRow:(u,p,h)=>r("input",{type:"text",className:l&&s===p?"sf-list-marking":void 0,value:u?.text??"",placeholder:o,"aria-label":`${e} ${p+1}`,onChange:b=>h({text:b.target.value}),onFocus:b=>{a.current=b.currentTarget,c(p)}})})}function Yi(e,t){const n=`${e.label} — row ${t+1}`;return D({control:"plainText",label:n,placeholder:e.placeholder,offPage:e.offPage},{type:"custom",render:({value:o,onChange:i})=>r(k,{value:o,onChange:i,label:n,placeholder:e.placeholder,hideable:!1,markup:e.rendering==="markup"})})}function ji(e){return{_gCards:C("Cards"),coverIndex:L("Cover image",r(Et,{}),cn,String(un),e?.coverHint??"A card's opening picture — a card pinned to a finish keeps its own."),imageBackground:bo("Image background",wn),cardImage:Vo(),spinOnHover:O("Rotate on hover",e?.spinDefault??!0,r(wt,{}))}}function qi(){return{outline:L("Card outline",r(kt,{}),ln,sn),indexBadge:L("Card number",r(_e,{}),rn,an),showBadge:O("Product badge",!0,r(Ee,{noun:"tag"}))}}function Ji(e){const t=e?.bottomDefault??!0;return{_gShowOnCard:C("Show on a card"),showCardPrice:O("Price",!0,r(St,{})),showCardFinishes:O("Finish swatches",!0,r(It,{})),showCardSizes:O("Sizes",t,r(Pt,{})),showCardBuy:O("Buy button",t,r(ft,{})),showCardPage:O("Page button",t,r(ye,{}))}}function Vo(){return $("Card image",{min:B,max:W,step:et,hint:"Rounds the picture. The card's own corner is in Site styles."})}function Zi(){return $(nt,{min:B,max:W,step:tt,unsetLabel:"Square",hint:"Rounds the picture. Left alone it stays square."})}function Qi(){return{type:"custom",render:({value:e,onChange:t})=>r(Yo,{value:typeof e=="string"?e:"",onChange:t})}}function Yo({value:e,onChange:t}){const[n,o]=ue(null),i=ge.filter(a=>n===null||A[a].across===n),l=e&&e in A?A[e]:null;return y(E,{children:[r(f,{label:"Photos in a row",icon:r(ht,{}),children:y("div",{className:"sf-gallery-filter",children:[r("button",{type:"button","aria-pressed":n===null,onClick:()=>o(null),children:"All"}),rt.map(a=>r("button",{type:"button","aria-pressed":n===a,onClick:()=>o(a),children:a},a))]})}),r(f,{label:"Layout",icon:r(_t,{}),value:l?l.label:"Not chosen",hint:`${i.length} of ${ge.length} layouts`,children:r("div",{className:"sf-gallery-layouts",children:i.map(a=>r(K,{content:A[a].label,className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":e===a,"aria-label":A[a].label,onClick:()=>t(e===a?"":a),children:r("span",{className:"sf-gallery-pic",children:A[a].desktop.map(([s,c],d)=>r("i",{style:{gridColumn:`span ${s}`,gridRow:`span ${c}`}},d))})})},a))})})]})}export{so as ANCHOR_HINT,Qr as BOUND_TO_POST_NOTE,ii as BUCKET_ICONS,Ui as CUSTOM_FIELD_MEDIA,Ki as CoordsField,Di as EDGE_ARROWS,ve as FOCAL_DEFAULT,Bo as FOCAL_POINTS,J as FOLD_FIELD_MARKER,Ve as FocalPicker,go as GroupLabel,ao as HIGHLIGHT_HINT,k as HidableTextField,me as LINK_FIELD_MARKER,Yr as Label,fe as MEDIA_FIELD_MARKER,$i as MEDIA_TYPE_OPTIONS,ho as PanelNoteLine,Ye as PlacementGridView,he as SCAFFOLD_FIELD_MARKER,ol as SCALAR_TEXT_CONTROLS,Xe as SECTION_BLEEDS_HINT,mo as SectionHeading,se as Segmented,ro as SiteGapDefaultReset,v as Slider,Ue as Swatches,nl as TEXT_CONTROL_KINDS,T as TEXT_FIELD_MARKER,zi as TICKER_ITEMS_ROW,zo as TextListField,io as WidthDefaultReset,Xo as aimAfterListChange,Oi as anchorFields,w as backTo,di as backgroundField,xi as boxAlignField,Ii as boxBlockSpacingField,bi as boxJustifyField,_i as boxPhoneRowField,Si as boxShareField,Ci as boxWrapField,ui as bucketHeader,No as cardCornerSidesField,Lo as cardCornersField,bo as cardImageBackgroundField,Vo as cardImageField,ji as cardMediaFields,gi as cardShapeFields,Ji as cardShowFields,qi as cardStyleFields,Ti as cellWidthFields,Fi as checkbox,Pi as colorInput,ni as copyText,Ni as dateTime,yi as directionField,Hi as edgePad,li as entriesHiddenForTab,wi as focalPicker,Xi as focusAfterRemove,Z as foldMetaOf,Qi as galleryLayoutField,mi as gapField,C as group,vi as heightFields,pe as hidableText,uo as hintIsWhileTyping,V as iconOf,Zi as imageCornersField,ci as isBucketHeader,to as isNoGlyph,oi as linkField,Bi as multiSelect,eo as noGlyph,Ai as pageBackgroundField,ai as panelNote,ko as phoneOverrideField,ki as placementField,po as plainText,ri as plainTextarea,$ as pxField,de as readHidable,Uo as rowText,Gi as searchSelect,si as section,hi as sectionAnimationFields,xo as sectionCornerSidesField,So as sectionCornersField,fi as sectionShapeFields,pi as sectionThemeFields,ce as segmented,L as select,Ko as setRowText,Ei as sizeField,H as slider,Mi as sourceField,Ri as spacingFields,ei as text,Ze as textFieldIdentifier,Jr as textFieldOffPage,Vi as textList,Yi as textListRowField,ti as textarea,O as toggle,Wi as upload,no as usePageWidthDetail,oo as useSiteGapDetail,Li as widthField,Zr as withIdentifier,qr as withOffPage,jr as withScaffold};
@@ -4,3 +4,4 @@ export declare function setEditorPageSlug(slug: string | null): void;
4
4
  export declare function getEditorPageSlug(): string | null;
5
5
  export declare function isEditorOnDynamicPage(): boolean;
6
6
  export declare function editorTemplateProductKind(rootProps?: Record<string, unknown> | null): TemplateProductKind;
7
+ export declare function editorRecordType(rootProps?: Record<string, unknown> | null): string | null;
@@ -1 +1 @@
1
- import{PRODUCT_PAGE_SLUG as r,templateProductKind as i}from"../content/product-page.js";let e=null,n=null;function l(t,o){e=t,n=o}function d(t){l(t,null)}function a(){return e}function g(){return n==="dynamic"||e===r}function P(t){return i(e??"",t)??"alloy-wheel"}export{P as editorTemplateProductKind,a as getEditorPageSlug,g as isEditorOnDynamicPage,l as setEditorPage,d as setEditorPageSlug};
1
+ import{PRODUCT_PAGE_SLUG as n,templateProductKind as i}from"../content/product-page.js";import{declaredRecordType as l}from"../content/record-types.js";let t=null,r=null;function u(e,o){t=e,r=o}function p(e){u(e,null)}function g(){return t}function d(){return r==="dynamic"||t===n}function P(e){return i(t??"",e)??"alloy-wheel"}function f(e){return d()?l(e):null}export{f as editorRecordType,P as editorTemplateProductKind,g as getEditorPageSlug,d as isEditorOnDynamicPage,u as setEditorPage,p as setEditorPageSlug};
@@ -1,4 +1,4 @@
1
1
  import type { Config } from "efficient-easel/blocks";
2
- export declare const GENERAL_REGISTRATION_ORDER: readonly ["Heading", "Text", "Eyebrow", "ImageBlock", "LogoBlock", "ButtonBlock", "Spacer", "Divider", "Grid", "Flex", "Breadcrumb", "Masthead", "CategoryBar", "FeaturedCover", "LongRead", "Series", "Banner", "ParagraphsA", "StatsParagraph", "Timeline", "Footprint", "TimelineTrack", "TitleWithButtons", "Stats", "Integrations", "Mockup", "Chart", "KeyFeatures", "Testimonials", "Prose", "Cards", "Logos", "Ticker", "ContactLocations", "HeroSingle", "Hero", "HeroSlide", "HeroGroup", "PostCard", "DocMetaCards", "DocTabs", "DocMasthead", "DocBody", "FAQ", "SpecStrip", "Manifesto", "SectionHeader", "IntroBleed", "Split", "ProcessSteps", "OrderSummary", "PaymentBadges", "CustomHTML"];
2
+ export declare const GENERAL_REGISTRATION_ORDER: readonly ["Heading", "Text", "Eyebrow", "ImageBlock", "LogoBlock", "ButtonBlock", "Spacer", "Divider", "Grid", "Flex", "Breadcrumb", "Masthead", "CategoryBar", "FeaturedCover", "LongRead", "Series", "Banner", "ParagraphsA", "StatsParagraph", "Timeline", "Footprint", "TimelineTrack", "TitleWithButtons", "Stats", "Integrations", "Mockup", "Chart", "KeyFeatures", "Testimonials", "Prose", "Cards", "Logos", "Ticker", "Countdown", "ContactLocations", "HeroSingle", "Hero", "HeroSlide", "HeroGroup", "PostCard", "DocMetaCards", "DocTabs", "DocMasthead", "DocBody", "FAQ", "SpecStrip", "Manifesto", "SectionHeader", "IntroBleed", "Split", "ProcessSteps", "OrderSummary", "PaymentBadges", "CustomHTML"];
3
3
  export declare const generalRegistry: Config;
4
4
  export default generalRegistry;
@@ -1 +1 @@
1
- import{jsx as a}from"react/jsx-runtime";import{assembleGeneralBlocks as l}from"./blocks/general/index.js";import{EditorThemedBody as m,PublishedPageFrame as u,suppressPreviewNav as g}from"./page-root.js";import{GENERAL_ROOT_FIELDS as f}from"./page-root-fields.js";import{finishRegistry as h}from"./registry.js";import{blockSetOf as B,buildPuckCategories as S}from"./section-catalog.js";const k=["Heading","Text","Eyebrow","ImageBlock","LogoBlock","ButtonBlock","Spacer","Divider","Grid","Flex","Breadcrumb","Masthead","CategoryBar","FeaturedCover","LongRead","Series","Banner","ParagraphsA","StatsParagraph","Timeline","Footprint","TimelineTrack","TitleWithButtons","Stats","Integrations","Mockup","Chart","KeyFeatures","Testimonials","Prose","Cards","Logos","Ticker","ContactLocations","HeroSingle","Hero","HeroSlide","HeroGroup","PostCard","DocMetaCards","DocTabs","DocMasthead","DocBody","FAQ","SpecStrip","Manifesto","SectionHeader","IntroBleed","Split","ProcessSteps","OrderSummary","PaymentBadges","CustomHTML"];function T(e){const o=Object.fromEntries(Object.entries(e.fields??{}).map(([t,r])=>[t,r&&typeof r=="object"&&r.type==="slot"?{...r}:r]));return{...e,...e.fields?{fields:o}:null}}function y(){const e={};for(const[o,t]of Object.entries(S())){const r=t.components.filter(s=>B(s)==="general");(r.length>0||o==="structure")&&(e[o]={...t,components:r})}return e}const E=l(),c={root:{fields:{...f},render:e=>{const{children:o,puck:t,widthMode:r,fullWidth:s,pageWidth:i,pageBackground:n,theme:d,fonts:p}=e;return t?.isEditing?a(m,{propsTheme:d,propsFonts:p,widthMode:r,fullWidth:s,pageWidth:i,pageBackground:typeof n=="string"?n:void 0,suppressPreviewNav:g,children:o}):a(u,{pageBackground:n,w:{widthMode:r,fullWidth:s,pageWidth:i},children:o})}},categories:y(),components:Object.fromEntries(k.map(e=>[e,T(E[e])]))};h(c);var L=c;export{k as GENERAL_REGISTRATION_ORDER,L as default,c as generalRegistry};
1
+ import{jsx as a}from"react/jsx-runtime";import{assembleGeneralBlocks as l}from"./blocks/general/index.js";import{EditorThemedBody as u,PublishedPageFrame as m,suppressPreviewNav as g}from"./page-root.js";import{GENERAL_ROOT_FIELDS as f}from"./page-root-fields.js";import{finishRegistry as h}from"./registry.js";import{blockSetOf as B,buildPuckCategories as S}from"./section-catalog.js";const k=["Heading","Text","Eyebrow","ImageBlock","LogoBlock","ButtonBlock","Spacer","Divider","Grid","Flex","Breadcrumb","Masthead","CategoryBar","FeaturedCover","LongRead","Series","Banner","ParagraphsA","StatsParagraph","Timeline","Footprint","TimelineTrack","TitleWithButtons","Stats","Integrations","Mockup","Chart","KeyFeatures","Testimonials","Prose","Cards","Logos","Ticker","Countdown","ContactLocations","HeroSingle","Hero","HeroSlide","HeroGroup","PostCard","DocMetaCards","DocTabs","DocMasthead","DocBody","FAQ","SpecStrip","Manifesto","SectionHeader","IntroBleed","Split","ProcessSteps","OrderSummary","PaymentBadges","CustomHTML"];function T(e){const r=Object.fromEntries(Object.entries(e.fields??{}).map(([t,o])=>[t,o&&typeof o=="object"&&o.type==="slot"?{...o}:o]));return{...e,...e.fields?{fields:r}:null}}function y(){const e={};for(const[r,t]of Object.entries(S())){const o=t.components.filter(s=>B(s)==="general");(o.length>0||r==="structure")&&(e[r]={...t,components:o})}return e}const E=l(),c={root:{fields:{...f},render:e=>{const{children:r,puck:t,widthMode:o,fullWidth:s,pageWidth:i,pageBackground:n,theme:d,fonts:p}=e;return t?.isEditing?a(u,{propsTheme:d,propsFonts:p,widthMode:o,fullWidth:s,pageWidth:i,pageBackground:typeof n=="string"?n:void 0,suppressPreviewNav:g,children:r}):a(m,{pageBackground:n,w:{widthMode:o,fullWidth:s,pageWidth:i},children:r})}},categories:y(),components:Object.fromEntries(k.map(e=>[e,T(E[e])]))};h(c);var F=c;export{k as GENERAL_REGISTRATION_ORDER,F as default,c as generalRegistry};
@@ -1,3 +1,4 @@
1
+ import { type SelectField } from "./controls.js";
1
2
  export declare function pageWidthField(): {
2
3
  type: "custom";
3
4
  render: ({ value, onChange }: {
@@ -18,7 +19,7 @@ export declare const TOP_SPACE_OPTIONS: readonly [{
18
19
  export declare const GENERAL_ROOT_FIELDS: {
19
20
  title: import("./controls.js").CustomField<import("./controls.js").HidableValue>;
20
21
  pageBackground: import("./controls.js").CustomField<string>;
21
- topSpace: import("./controls.js").SelectField;
22
+ topSpace: SelectField;
22
23
  widthChoice: {
23
24
  type: "custom";
24
25
  render: ({ value, onChange }: {
@@ -27,3 +28,5 @@ export declare const GENERAL_ROOT_FIELDS: {
27
28
  }) => import("react").JSX.Element;
28
29
  };
29
30
  };
31
+ export declare const RECORD_TYPE_LABEL = "Record type";
32
+ export declare function withRecordTypeRow(fields: Record<string, unknown>, rootProps?: Record<string, unknown> | null): Record<string, unknown>;
@@ -1 +1 @@
1
- import{jsx as o}from"react/jsx-runtime";import{PaddingTopIcon as n}from"efficient-easel/icons";import r from"../../components/WidthFollowField.js";import{pageBackgroundField as a,plainText as i,select as s}from"./controls.js";import{DEFAULT_TOP_SPACE as p}from"./header-clearance.js";function d(){return{type:"custom",render:({value:e,onChange:t})=>o(r,{value:e==="full"?"full":e==="content"?"content":void 0,resolved:"content",followsLabel:"Follows the site",hint:"Whether this page sits on the site's content column, or runs edge to edge.",onChange:l=>t(l)})}}const c=[{label:"Auto",value:"auto"},{label:"Shared",value:"shared"},{label:"Its own",value:"own"}],T={title:i("Page Title"),pageBackground:a(),topSpace:s("Top space",o(n,{}),c,p),widthChoice:d()};export{T as GENERAL_ROOT_FIELDS,c as TOP_SPACE_OPTIONS,d as pageWidthField};
1
+ import{jsx as i}from"react/jsx-runtime";import{ListIcon as T,PaddingTopIcon as m}from"efficient-easel/icons";import w from"../../components/WidthFollowField.js";import{PRODUCT_RECORD_TYPE as R,TEMPLATE_RECORD_TYPE_PROP as c,declaredRecordType as f,recordTypes as s,recordTypesRevision as a}from"../content/record-types.js";import{pageBackgroundField as h,plainText as E,select as p}from"./controls.js";import{isEditorOnDynamicPage as g}from"./editor-page-context.js";import{DEFAULT_TOP_SPACE as P}from"./header-clearance.js";function _(){return{type:"custom",render:({value:e,onChange:r})=>i(w,{value:e==="full"?"full":e==="content"?"content":void 0,resolved:"content",followsLabel:"Follows the site",hint:"Whether this page sits on the site's content column, or runs edge to edge.",onChange:o=>r(o)})}}const O=[{label:"Auto",value:"auto"},{label:"Shared",value:"shared"},{label:"Its own",value:"own"}],F={title:E("Page Title"),pageBackground:h(),topSpace:p("Top space",i(m,{}),O,P),widthChoice:_()},y="Record type",l=new Map;let u=-1;function x(e){u!==a()&&(l.clear(),u=a());const r=s(),o=r.some(n=>n.key===e)?"":e;let t=l.get(o);return t||(t=p(y,i(T,{}),[...r.map(n=>({label:n.label,value:n.key})),...o?[{label:o,value:o}]:[]],R),l.set(o,t)),t}const d=new WeakMap;function S(e,r){if(!g()||s().length<2||c in e)return e;const o=x(f(r)),t=d.get(e);if(t&&t.row===o)return t.fields;const n={[c]:o,...e};return d.set(e,{row:o,fields:n}),n}export{F as GENERAL_ROOT_FIELDS,y as RECORD_TYPE_LABEL,O as TOP_SPACE_OPTIONS,_ as pageWidthField,S as withRecordTypeRow};
@@ -1 +1 @@
1
- import{dropEmptyHeadings as r}from"./panel-drop-empty-headings.js";import{applyBlockPasses as l,registryPassContext as d}from"./passes/index.js";import{PASS_INSPECTOR as m}from"./passes/inspector.js";function u(o){const n={...d(Object.keys(o.components),o.categories?.structure?.components??[]),inspector:m};for(const[t,e]of Object.entries(o.components))l(t,e,n);const i=o.root,c=i.resolveFields;return i.resolveFields=c?(t,e)=>{const s=c(t,e);return s instanceof Promise?s.then(p=>r(p??e.fields,"page")):r(s??e.fields,"page")}:(t,e)=>r(e.fields,"page"),n}export{u as finishRegistry};
1
+ import{withRecordTypeRow as l}from"./page-root-fields.js";import{dropEmptyHeadings as m}from"./panel-drop-empty-headings.js";import{applyBlockPasses as f,registryPassContext as d}from"./passes/index.js";import{PASS_INSPECTOR as y}from"./passes/inspector.js";function R(t){const n={...d(Object.keys(t.components),t.categories?.structure?.components??[]),inspector:y};for(const[e,o]of Object.entries(t.components))f(e,o,n);const i=t.root,c=i.resolveFields,s=(e,o)=>m(l(e,o?.props),"page");return i.resolveFields=c?(e,o)=>{const r=c(e,o);return r instanceof Promise?r.then(p=>s(p??o.fields,e)):s(r??o.fields,e)}:(e,o)=>s(o.fields,e),n}export{R as finishRegistry};
@@ -1 +1 @@
1
- const p=["general","commerce","service"],o=[{key:"openers",title:"Hero & intros",defaultExpanded:!0,templateable:!0,sections:[{type:"Hero",label:"Hero Slideshow",set:"general"},{type:"HeroSingle",label:"Hero",set:"general"},{type:"IntroBleed",label:"Scroll-Over Text",set:"general"}]},{key:"shop",title:"Shop & galleries",templateable:!0,sections:[{type:"Collections",label:"Collections",set:"commerce"},{type:"BrandStrip",label:"Brand Strip",set:"commerce"},{type:"AlloyWheelsListing",label:"List",set:"commerce"},{type:"CatalogFilterBar",label:"Catalog Filter Bar",set:"commerce"},{type:"ProductGrid",label:"Product Grid",set:"commerce"},{type:"FitmentFinder",label:"Fitment Form",set:"commerce"},{type:"Gallery",label:"Tabbed Gallery",set:"commerce"},{type:"GalleryB",label:"Customer Photo Grid",set:"commerce"},{type:"SpecStrip",label:"Spec Strip",set:"general"}]},{key:"product",title:"Product page",templateable:!0,sections:[{type:"ProductHero",label:"Product Hero",set:"commerce"},{type:"SpecTable",label:"Spec Table",set:"commerce"},{type:"ProcessSteps",label:"Image & Text Columns",set:"general"},{type:"DetailRows",label:"Feature Rows",set:"commerce"},{type:"FitmentTable",label:"Fitment Table",set:"commerce"},{type:"TyreSizes",label:"Tyre Sizes",set:"commerce"},{type:"TyreFitment",label:"Tyre Fitment Form",set:"commerce"},{type:"EuTyreLabel",label:"EU Tyre Label",set:"commerce"},{type:"RelatedProducts",label:"Related Products",set:"commerce"},{type:"BundleOffer",label:"Bundle Products",set:"commerce"}]},{key:"checkout",title:"Checkout & ordering",templateable:!0,sections:[{type:"OrderSummary",label:"Order Table",set:"general"},{type:"DeliveryOptions",label:"Delivery Options",set:"commerce"},{type:"PaymentBadges",label:"Payment Methods",set:"general"},{type:"CheckoutCTA",label:"Ready-to-Order Banner",set:"commerce"}]},{key:"about",title:"About & brand story",templateable:!0,sections:[{type:"Manifesto",label:"Brand Text",set:"general"},{type:"Timeline",label:"Story Timeline",set:"general"},{type:"TimelineTrack",label:"Milestone Timeline",set:"general"},{type:"Footprint",label:"Locations Map",set:"general"}]},{key:"content",title:"Text & content",templateable:!0,sections:[{type:"Prose",label:"Editorial Text",set:"general"},{type:"ParagraphsA",label:"Lead Text",set:"general"},{type:"Split",label:"Image & Text Split",set:"general"},{type:"Cards",label:"Cards",set:"general"},{type:"KeyFeatures",label:"Key Features",set:"general"}]},{key:"proof",title:"Stats & social proof",templateable:!0,sections:[{type:"Stats",label:"Stats",set:"general"},{type:"StatsParagraph",label:"Stats with Text",set:"general"},{type:"Chart",label:"Chart",set:"general"},{type:"Mockup",label:"Mockup Card",set:"general"},{type:"Testimonials",label:"Testimonials",set:"general"},{type:"Reviews",label:"Reviews",set:"service"},{type:"Logos",label:"Logos",set:"general"}]},{key:"promo",title:"Promotions & sign-ups",templateable:!0,sections:[{type:"Banner",label:"Banner",set:"general"},{type:"TitleWithButtons",label:"Call-to-Action Heading",set:"general"},{type:"Ticker",label:"Scrolling Bar",set:"general"},{type:"Subscribe",label:"Signup Form",set:"service"}]},{key:"blog",title:"Blog & journal",templateable:!0,sections:[{type:"Masthead",label:"Issue Header",set:"general"},{type:"FeaturedCover",label:"Feature Banner",set:"general"},{type:"LongRead",label:"Article Text",set:"general"},{type:"Series",label:"Recurring Columns",set:"general"},{type:"Events",label:"Latest Posts",set:"service"}]},{key:"navigation",title:"Navigation & wayfinding",templateable:!0,sections:[{type:"Breadcrumb",label:"Breadcrumb",set:"general"},{type:"CategoryBar",label:"Category Bar",set:"general"},{type:"DocTabs",label:"Document Tabs",set:"general"}]},{key:"legal",title:"Legal & documents",templateable:!0,sections:[{type:"DocMasthead",label:"Document Header",set:"general"},{type:"DocBody",label:"Document Text",set:"general"},{type:"DocMetaCards",label:"Document Detail Cards",set:"general"}]},{key:"contact",title:"Contact, FAQ & forms",templateable:!0,sections:[{type:"FAQ",label:"Q&A",set:"general"},{type:"ContactRouting",label:"Contact Form",set:"service"},{type:"ContactLocations",label:"Contact / Locations",set:"general"},{type:"SubmitBuild",label:"Photo Submission Form",set:"service"},{type:"ReviewForm",label:"Review Form",set:"service"},{type:"Form",label:"Form",set:"service"},{type:"AppointmentBooking",label:"Booking Form",set:"service"}]},{key:"structure",title:"Layout, structure & embeds",templateable:!1,sections:[{type:"SectionHeader",label:"Section Header",set:"general"},{type:"Flex",label:"Box",set:"general"},{type:"Spacer",label:"Spacer",set:"general"},{type:"Divider",label:"Divider",set:"general"},{type:"CustomHTML",label:"Custom HTML",set:"general"}]}];function h(){return Object.fromEntries(o.map(e=>[e.key,{title:e.title,components:e.sections.map(t=>t.type),...e.defaultExpanded?{defaultExpanded:!0}:{}}]))}const l={Grid:'Lewis, 2026-09-14: Box and Grid duplicate each other and it feels confusing. 2026-09-15 he chose the order: give Box uneven widths FIRST, then merge Grid into Box. Shown three ways to pick the widths (mockup "Uneven Box Widths"), he chose A — shape pictures on the Box\'s `Block widths` row, the same "a row is a shape, pick a picture of it" rule he set for the photo wall on 2026-09-07.\n\nWHAT REPLACES IT: a Box set to One row, with `Block widths` at Equal or a shape (Big left, Big right, Bigger left, Bigger right) and its own `Columns on phone`. Measured on PRODUCTION 2026-09-16 ~09:28 AEST (database `efficient-system`, all 10 tenant schemas, 128 storefront pages, both `layout` and `published_layout` — 256 documents): 2 Grid nodes, and they are ONE Grid counted twice — the 9DIEM homepage on 9diem.com (`xtreme_mudder` schema), once as draft and once as published. It is top-level, holds three `ImageBlock`s at `columns` 3 — equal thirds — and NO block sets `Positions`. A Box draws that with `Block widths` at Equal.\n\n⚠️ THE COUNT MOVES; THE RULE MUST NOT DEPEND ON IT. This entry has already carried three different readings. A local-clone snapshot said no Grid used `Positions`. A PRODUCTION reading on 2026-09-15 ~13:15 AEST found 6 nodes on two sites, 4 of them spanned — hartesmetal.com.au homepage and about, 4 columns, spans 1 + 3. That one was TRUE when it was taken and stopped being true the same day: those two pages were rebuilt on Box (`Block widths: Bigger right`), and on 2026-09-16 they hold zero Grid nodes and are built from `Flex`. ⛔ So the rule is NOT "there are still N spanned Grids". NEVER delete the Grid component or its `gridSpan` handling, whatever a census says — Grid still renders, still edits, still drags, and a merchant may rebuild a page either way on any day. Re-run the census on production before anyone PROPOSES deleting either, and read any number written here as the reading of its own day, not as the state of the world.\n\nWHAT A MERCHANT LOSES: a new Grid, and with it a fixed "N per row" that wraps by itself past three across, and the per-block `Positions` number. Box wraps with `Wrap`, but by content width, not by a fixed count.\n\nTHE TYPE KEY STAYS AND SO DOES THE COMPONENT. Every page holding a Grid still renders through it and can still be edited, dragged and added to; no document is rewritten and NO MIGRATION RUNS — the owner redoes live sections himself.\n\n⚠️ AND IT STAYS DROPPABLE WHERE IT LIVES. The drop rule in lib/puck/config.tsx read the nestable containers off the catalogue\'s `structure` row, so leaving the catalogue would have made every open slot — a Box included — refuse a Grid already stored inside one. `scripts/test-retired-grid-stays-editable.tsx` §3 pins it.',CompatibleTyres:'Lewis, 2026-09-09: "Do not bother counting. Delete Compatible Tyres and use the new one. The new one needs complete settings — it must have every setting our cards have." Shown three ways to finish it, he chose C: retire from the menu now, and take styling the card text as its own card.\n\nWHAT REPLACES IT: `RelatedProducts` with its `Show` dropdown set to "Tyres that fit this product". That block is the GENERIC relationship section from card 1128 — it knows nothing about wheels or tyres, it asks the registry for a relationship by name. The two have rendered through the SAME renderer (`DynamicRelatedProducts`) since that card; this one is the pre-registry one-off that was never removed.\n\n⚠️ THE SWAP WAS NOT SAFE UNTIL #1305, AND SAYING SO IS THE POINT. The first old-versus-new table put in front of the owner was WRONG. `DynamicRelatedProducts` returns EARLY on a tyre answer and draws this component, so the seven card settings, the head split and the Width control all stopped at that call — nine settings, measured NO EFFECT, on precisely the relationship that replaces this block. #1283 gave the new block the card settings, #1299 the head split and its own Width, #1305 carried all of it onto the tyre branch. Only then was the claim true.\n\nWHAT WAS MEASURED BEFORE RETIRING, four ways, because the premise decides the card:\n • settable text kinds (SECTION_TEXT_KINDS): both blocks ABSENT — the map holds only TimelineTrack and Footprint, both AUTHORED lists\n • read-only text regions: neither `components/CompatibleTyres` nor `components/TyreCard` stamps one\n • panel rows through resolveFields: this block 31, `RelatedProducts` 42. This block\'s only style-ish key is `_sStyle`, the bucket HEADER, not a control\n • head text (num/title/description) is authored on both, so `_partStyles` reaches it identically\nSo on the CARD runs the two are zero against zero — neither can style them — and everywhere else the new block is ahead. Styling those runs needs a section-level prop family and a paint path for DERIVED text, which no section has yet: a part is anchored by matching an AUTHORED prop\'s string against the DOM, and `lib/puck/source-bound-parts` keeps hydrated copy unreachable on purpose so a merchant cannot type into a copy of a product name and lose it at the next sync. That is its own card, and `lib/sections/text-regions` is the read-only half that already ships.\n\nTHE TYPE KEY STAYS AND SO DOES THE COMPONENT, the same contract Subscribe, Split and SubscribeBlogs have. Every page holding a `CompatibleTyres` still renders through it, no published document is rewritten, and NO MIGRATION RUNS — the owner\'s standing ruling of 2026-09-05: he redoes live sections himself and deletes the old ones when he does. He also said explicitly not to count them first.\n\n⚠️ AND THIS COMPONENT IS LOAD-BEARING FOR ITS OWN REPLACEMENT: `DynamicRelatedProducts` draws it for EVERY tyre answer. Deleting it would blank the block that replaces it, not just the pages still holding this one.',SubscribeBlogs:"card 66396 — folded into `Subscribe`, which now chooses its rail's content with a `Type` control (the newsletter's own issues, or live blog posts). The two shared 21 of their fields and rendered THE SAME BYTES from equivalent rows, so offering both asked a merchant to choose between two names for one section. The type key stays because it is stored on published pages, and the component stays because those pages still render through it."},m=["Grid"],y=Array.from(new Set([...o.flatMap(e=>e.sections.map(t=>t.type)),...Object.keys(l)])),u=Object.fromEntries(o.flatMap(e=>e.sections.map(t=>[t.type,t.label]))),i={Heading:"general",Text:"general",Eyebrow:"general",ImageBlock:"general",LogoBlock:"general",ButtonBlock:"general",PostCard:"general",HeroSlide:"general",HeroGroup:"general",Integrations:"general",Grid:"general",CollectionCard:"commerce",GalleryItem:"commerce",ProductRef:"commerce",CompatibleTyres:"commerce",Header:"commerce",SearchBlock:"commerce",CartBlock:"commerce",CountrySwitchBlock:"commerce",AccountBlock:"commerce",ThemeSwitchBlock:"commerce",SubmitBox:"service",BookingBox:"service",SubscribeBlogs:"service",Footer:"service",FooterLogo:"service",FooterMenu:"service",FooterDivider:"service",FooterGroup:"service",FooterText:"service",FooterEmailSignup:"service",FooterSocial:"service",MenuBlock:"service",EmailFormBlock:"service",SocialLogosBlock:"service",LegalLineBlock:"service",SiteHeader:"service",SiteFooter:"service"},a={...i,...Object.fromEntries(o.flatMap(e=>e.sections.map(t=>[t.type,t.set])))};function b(e){return Object.prototype.hasOwnProperty.call(a,e)?a[e]:void 0}function r(e){return Object.keys(a).filter(t=>a[t]===e).sort()}const g=r("general"),T=r("commerce"),S=r("service"),c="Flex",s="Box",E=`${s}es`;function d(e){return e==="section"?"Blank section":s}function w(e,t,n){return e===c?d(t):n}export{y as ALL_SECTION_TYPES,p as BLOCK_SETS,s as BOX_LABEL,E as BOX_LABEL_PLURAL,T as COMMERCE_BLOCKS,g as GENERAL_BLOCKS,c as LEVEL_NAMED_TYPE,m as RETIRED_NESTABLE_SECTIONS,l as RETIRED_SECTIONS,o as SECTION_CATALOG,u as SECTION_LABELS,S as SERVICE_BLOCKS,i as UNLISTED_BLOCK_SETS,b as blockSetOf,r as blocksInSet,h as buildPuckCategories,w as labelAtLevel,d as labelForFlex};
1
+ const p=["general","commerce","service"],o=[{key:"openers",title:"Hero & intros",defaultExpanded:!0,templateable:!0,sections:[{type:"Hero",label:"Hero Slideshow",set:"general"},{type:"HeroSingle",label:"Hero",set:"general"},{type:"IntroBleed",label:"Scroll-Over Text",set:"general"}]},{key:"shop",title:"Shop & galleries",templateable:!0,sections:[{type:"Collections",label:"Collections",set:"commerce"},{type:"BrandStrip",label:"Brand Strip",set:"commerce"},{type:"AlloyWheelsListing",label:"List",set:"commerce"},{type:"CatalogFilterBar",label:"Catalog Filter Bar",set:"commerce"},{type:"ProductGrid",label:"Product Grid",set:"commerce"},{type:"FitmentFinder",label:"Fitment Form",set:"commerce"},{type:"Gallery",label:"Tabbed Gallery",set:"commerce"},{type:"GalleryB",label:"Customer Photo Grid",set:"commerce"},{type:"SpecStrip",label:"Spec Strip",set:"general"}]},{key:"product",title:"Product page",templateable:!0,sections:[{type:"ProductHero",label:"Product Hero",set:"commerce"},{type:"SpecTable",label:"Spec Table",set:"commerce"},{type:"ProcessSteps",label:"Image & Text Columns",set:"general"},{type:"DetailRows",label:"Feature Rows",set:"commerce"},{type:"FitmentTable",label:"Fitment Table",set:"commerce"},{type:"TyreSizes",label:"Tyre Sizes",set:"commerce"},{type:"TyreFitment",label:"Tyre Fitment Form",set:"commerce"},{type:"EuTyreLabel",label:"EU Tyre Label",set:"commerce"},{type:"RelatedProducts",label:"Related Products",set:"commerce"},{type:"BundleOffer",label:"Bundle Products",set:"commerce"}]},{key:"checkout",title:"Checkout & ordering",templateable:!0,sections:[{type:"OrderSummary",label:"Order Table",set:"general"},{type:"DeliveryOptions",label:"Delivery Options",set:"commerce"},{type:"PaymentBadges",label:"Payment Methods",set:"general"},{type:"CheckoutCTA",label:"Ready-to-Order Banner",set:"commerce"}]},{key:"about",title:"About & brand story",templateable:!0,sections:[{type:"Manifesto",label:"Brand Text",set:"general"},{type:"Timeline",label:"Story Timeline",set:"general"},{type:"TimelineTrack",label:"Milestone Timeline",set:"general"},{type:"Footprint",label:"Locations Map",set:"general"}]},{key:"content",title:"Text & content",templateable:!0,sections:[{type:"Prose",label:"Editorial Text",set:"general"},{type:"ParagraphsA",label:"Lead Text",set:"general"},{type:"Split",label:"Image & Text Split",set:"general"},{type:"Cards",label:"Cards",set:"general"},{type:"KeyFeatures",label:"Key Features",set:"general"}]},{key:"proof",title:"Stats & social proof",templateable:!0,sections:[{type:"Stats",label:"Stats",set:"general"},{type:"StatsParagraph",label:"Stats with Text",set:"general"},{type:"Chart",label:"Chart",set:"general"},{type:"Mockup",label:"Mockup Card",set:"general"},{type:"Testimonials",label:"Testimonials",set:"general"},{type:"Reviews",label:"Reviews",set:"service"},{type:"Logos",label:"Logos",set:"general"}]},{key:"promo",title:"Promotions & sign-ups",templateable:!0,sections:[{type:"Banner",label:"Banner",set:"general"},{type:"TitleWithButtons",label:"Call-to-Action Heading",set:"general"},{type:"Ticker",label:"Scrolling Bar",set:"general"},{type:"Countdown",label:"Countdown",set:"general"},{type:"Subscribe",label:"Signup Form",set:"service"}]},{key:"blog",title:"Blog & journal",templateable:!0,sections:[{type:"Masthead",label:"Issue Header",set:"general"},{type:"FeaturedCover",label:"Feature Banner",set:"general"},{type:"LongRead",label:"Article Text",set:"general"},{type:"Series",label:"Recurring Columns",set:"general"},{type:"Events",label:"Latest Posts",set:"service"}]},{key:"navigation",title:"Navigation & wayfinding",templateable:!0,sections:[{type:"Breadcrumb",label:"Breadcrumb",set:"general"},{type:"CategoryBar",label:"Category Bar",set:"general"},{type:"DocTabs",label:"Document Tabs",set:"general"}]},{key:"legal",title:"Legal & documents",templateable:!0,sections:[{type:"DocMasthead",label:"Document Header",set:"general"},{type:"DocBody",label:"Document Text",set:"general"},{type:"DocMetaCards",label:"Document Detail Cards",set:"general"}]},{key:"contact",title:"Contact, FAQ & forms",templateable:!0,sections:[{type:"FAQ",label:"Q&A",set:"general"},{type:"ContactRouting",label:"Contact Form",set:"service"},{type:"ContactLocations",label:"Contact / Locations",set:"general"},{type:"SubmitBuild",label:"Photo Submission Form",set:"service"},{type:"ReviewForm",label:"Review Form",set:"service"},{type:"Form",label:"Form",set:"service"},{type:"AppointmentBooking",label:"Booking Form",set:"service"}]},{key:"structure",title:"Layout, structure & embeds",templateable:!1,sections:[{type:"SectionHeader",label:"Section Header",set:"general"},{type:"Flex",label:"Box",set:"general"},{type:"Spacer",label:"Spacer",set:"general"},{type:"Divider",label:"Divider",set:"general"},{type:"CustomHTML",label:"Custom HTML",set:"general"}]}];function h(){return Object.fromEntries(o.map(e=>[e.key,{title:e.title,components:e.sections.map(t=>t.type),...e.defaultExpanded?{defaultExpanded:!0}:{}}]))}const l={Grid:'Lewis, 2026-09-14: Box and Grid duplicate each other and it feels confusing. 2026-09-15 he chose the order: give Box uneven widths FIRST, then merge Grid into Box. Shown three ways to pick the widths (mockup "Uneven Box Widths"), he chose A — shape pictures on the Box\'s `Block widths` row, the same "a row is a shape, pick a picture of it" rule he set for the photo wall on 2026-09-07.\n\nWHAT REPLACES IT: a Box set to One row, with `Block widths` at Equal or a shape (Big left, Big right, Bigger left, Bigger right) and its own `Columns on phone`. Measured on PRODUCTION 2026-09-16 ~09:28 AEST (database `efficient-system`, all 10 tenant schemas, 128 storefront pages, both `layout` and `published_layout` — 256 documents): 2 Grid nodes, and they are ONE Grid counted twice — the 9DIEM homepage on 9diem.com (`xtreme_mudder` schema), once as draft and once as published. It is top-level, holds three `ImageBlock`s at `columns` 3 — equal thirds — and NO block sets `Positions`. A Box draws that with `Block widths` at Equal.\n\n⚠️ THE COUNT MOVES; THE RULE MUST NOT DEPEND ON IT. This entry has already carried three different readings. A local-clone snapshot said no Grid used `Positions`. A PRODUCTION reading on 2026-09-15 ~13:15 AEST found 6 nodes on two sites, 4 of them spanned — hartesmetal.com.au homepage and about, 4 columns, spans 1 + 3. That one was TRUE when it was taken and stopped being true the same day: those two pages were rebuilt on Box (`Block widths: Bigger right`), and on 2026-09-16 they hold zero Grid nodes and are built from `Flex`. ⛔ So the rule is NOT "there are still N spanned Grids". NEVER delete the Grid component or its `gridSpan` handling, whatever a census says — Grid still renders, still edits, still drags, and a merchant may rebuild a page either way on any day. Re-run the census on production before anyone PROPOSES deleting either, and read any number written here as the reading of its own day, not as the state of the world.\n\nWHAT A MERCHANT LOSES: a new Grid, and with it a fixed "N per row" that wraps by itself past three across, and the per-block `Positions` number. Box wraps with `Wrap`, but by content width, not by a fixed count.\n\nTHE TYPE KEY STAYS AND SO DOES THE COMPONENT. Every page holding a Grid still renders through it and can still be edited, dragged and added to; no document is rewritten and NO MIGRATION RUNS — the owner redoes live sections himself.\n\n⚠️ AND IT STAYS DROPPABLE WHERE IT LIVES. The drop rule in lib/puck/config.tsx read the nestable containers off the catalogue\'s `structure` row, so leaving the catalogue would have made every open slot — a Box included — refuse a Grid already stored inside one. `scripts/test-retired-grid-stays-editable.tsx` §3 pins it.',CompatibleTyres:'Lewis, 2026-09-09: "Do not bother counting. Delete Compatible Tyres and use the new one. The new one needs complete settings — it must have every setting our cards have." Shown three ways to finish it, he chose C: retire from the menu now, and take styling the card text as its own card.\n\nWHAT REPLACES IT: `RelatedProducts` with its `Show` dropdown set to "Tyres that fit this product". That block is the GENERIC relationship section from card 1128 — it knows nothing about wheels or tyres, it asks the registry for a relationship by name. The two have rendered through the SAME renderer (`DynamicRelatedProducts`) since that card; this one is the pre-registry one-off that was never removed.\n\n⚠️ THE SWAP WAS NOT SAFE UNTIL #1305, AND SAYING SO IS THE POINT. The first old-versus-new table put in front of the owner was WRONG. `DynamicRelatedProducts` returns EARLY on a tyre answer and draws this component, so the seven card settings, the head split and the Width control all stopped at that call — nine settings, measured NO EFFECT, on precisely the relationship that replaces this block. #1283 gave the new block the card settings, #1299 the head split and its own Width, #1305 carried all of it onto the tyre branch. Only then was the claim true.\n\nWHAT WAS MEASURED BEFORE RETIRING, four ways, because the premise decides the card:\n • settable text kinds (SECTION_TEXT_KINDS): both blocks ABSENT — the map holds only TimelineTrack and Footprint, both AUTHORED lists\n • read-only text regions: neither `components/CompatibleTyres` nor `components/TyreCard` stamps one\n • panel rows through resolveFields: this block 31, `RelatedProducts` 42. This block\'s only style-ish key is `_sStyle`, the bucket HEADER, not a control\n • head text (num/title/description) is authored on both, so `_partStyles` reaches it identically\nSo on the CARD runs the two are zero against zero — neither can style them — and everywhere else the new block is ahead. Styling those runs needs a section-level prop family and a paint path for DERIVED text, which no section has yet: a part is anchored by matching an AUTHORED prop\'s string against the DOM, and `lib/puck/source-bound-parts` keeps hydrated copy unreachable on purpose so a merchant cannot type into a copy of a product name and lose it at the next sync. That is its own card, and `lib/sections/text-regions` is the read-only half that already ships.\n\nTHE TYPE KEY STAYS AND SO DOES THE COMPONENT, the same contract Subscribe, Split and SubscribeBlogs have. Every page holding a `CompatibleTyres` still renders through it, no published document is rewritten, and NO MIGRATION RUNS — the owner\'s standing ruling of 2026-09-05: he redoes live sections himself and deletes the old ones when he does. He also said explicitly not to count them first.\n\n⚠️ AND THIS COMPONENT IS LOAD-BEARING FOR ITS OWN REPLACEMENT: `DynamicRelatedProducts` draws it for EVERY tyre answer. Deleting it would blank the block that replaces it, not just the pages still holding this one.',SubscribeBlogs:"card 66396 — folded into `Subscribe`, which now chooses its rail's content with a `Type` control (the newsletter's own issues, or live blog posts). The two shared 21 of their fields and rendered THE SAME BYTES from equivalent rows, so offering both asked a merchant to choose between two names for one section. The type key stays because it is stored on published pages, and the component stays because those pages still render through it."},m=["Grid"],y=Array.from(new Set([...o.flatMap(e=>e.sections.map(t=>t.type)),...Object.keys(l)])),u=Object.fromEntries(o.flatMap(e=>e.sections.map(t=>[t.type,t.label]))),i={Heading:"general",Text:"general",Eyebrow:"general",ImageBlock:"general",LogoBlock:"general",ButtonBlock:"general",PostCard:"general",HeroSlide:"general",HeroGroup:"general",Integrations:"general",Grid:"general",CollectionCard:"commerce",GalleryItem:"commerce",ProductRef:"commerce",CompatibleTyres:"commerce",Header:"commerce",SearchBlock:"commerce",CartBlock:"commerce",CountrySwitchBlock:"commerce",AccountBlock:"commerce",ThemeSwitchBlock:"commerce",SubmitBox:"service",BookingBox:"service",SubscribeBlogs:"service",Footer:"service",FooterLogo:"service",FooterMenu:"service",FooterDivider:"service",FooterGroup:"service",FooterText:"service",FooterEmailSignup:"service",FooterSocial:"service",MenuBlock:"service",EmailFormBlock:"service",SocialLogosBlock:"service",LegalLineBlock:"service",SiteHeader:"service",SiteFooter:"service"},a={...i,...Object.fromEntries(o.flatMap(e=>e.sections.map(t=>[t.type,t.set])))};function b(e){return Object.prototype.hasOwnProperty.call(a,e)?a[e]:void 0}function r(e){return Object.keys(a).filter(t=>a[t]===e).sort()}const g=r("general"),T=r("commerce"),S=r("service"),c="Flex",s="Box",E=`${s}es`;function d(e){return e==="section"?"Blank section":s}function w(e,t,n){return e===c?d(t):n}export{y as ALL_SECTION_TYPES,p as BLOCK_SETS,s as BOX_LABEL,E as BOX_LABEL_PLURAL,T as COMMERCE_BLOCKS,g as GENERAL_BLOCKS,c as LEVEL_NAMED_TYPE,m as RETIRED_NESTABLE_SECTIONS,l as RETIRED_SECTIONS,o as SECTION_CATALOG,u as SECTION_LABELS,S as SERVICE_BLOCKS,i as UNLISTED_BLOCK_SETS,b as blockSetOf,r as blocksInSet,h as buildPuckCategories,w as labelAtLevel,d as labelForFlex};
@@ -1 +1 @@
1
- const e={Hero:"Full-screen opener with rotating slides.",HeroSingle:"Full-screen image or video with a headline.",IntroBleed:"Full-bleed intro image the next section scrolls over.",Collections:"Product collections in a tidy grid.",AlloyWheelsListing:"A full product-listing page: filter rail, sortable card grid and pagination, from the live catalog. Choose which product types it shows.",CatalogFilterBar:"Filters the collection grids below it — a sticky row of Pills (the default), or Columns, one per filter you switch on.",ProductGrid:"Hand-picked products in a tidy grid.",FitmentFinder:"A vehicle picker — make, model, year and trim resolve the OEM stock fitment live.",Gallery:"Two image galleries with tabs and filters.",GalleryB:"Customer photos in a card grid with a click-to-open lightbox.",SpecStrip:"A thin one-line spec strip — small-caps items spread across the width, as a dark band or a bare hairline row.",ProductHero:"A product hero — image beside price, bullets and a buy button.",SpecTable:"A spec sheet — labeled rows of product specifications.",ProcessSteps:"A heading over columns of image, title, blurb and specs.",DetailRows:"Repeating full-width rows — eyebrow, title and copy beside a numbered close-up image, alternating sides each row.",FitmentTable:"A fitment table — per-size bolt patterns, offsets and load ratings, filterable by diameter.",CompatibleTyres:"The current product's compatible tyres — image, size, key specs and price per tyre, with an inquiry link. Display only.",RelatedProducts:"The current product's related items in a tidy row — the product page's built-in 'Pair with' cross-sell.",OrderSummary:"A display order-summary panel — items, totals and a note.",DeliveryOptions:"Delivery tiers as cards — name, window and price, one highlighted.",PaymentBadges:"A payment-methods trust strip with reassurance lines.",CheckoutCTA:"A centered 'ready to order?' headline with the checkout button.",Manifesto:"A bold brand statement beside a full-height image, with a stat strip.",ParagraphsA:"An editorial text panel with a stat strip and founders' note.",StatsParagraph:"An editorial heading and paragraph over a row of theme-color-accented stat cards.",Chart:"A titled chart — bars, line or donut — drawn from your own labeled data points.",Mockup:"A headline beside a stylized product-UI mockup card — spec sheet, fitment, portal, kanban and more.",Prose:"A plain editorial text section — eyebrow, heading and body copy.",Timeline:"An editorial aside beside a rail-marked timeline of dated entries.",TimelineTrack:"A horizontal year track of milestones — company history or roadmap.",Footprint:"A world map of your locations with a legend — designed here, sold worldwide.",TitleWithButtons:"A big headline beside a stack of call-to-action buttons.",Split:"Side-by-side image and text in two columns.",Cards:"A heading over a grid of free-text title-and-blurb cards.",FAQ:"A frequently-asked-questions accordion with a header.",Testimonials:"Customer quotes in a grid — the quote, a name and a role.",Masthead:"A journal issue header with a lead statement and contents.",Breadcrumb:"A slim trail showing where the reader is (Home / Journal…).",CategoryBar:"A sticky row of category tabs with counts and links.",FeaturedCover:"A featured article — big cover image beside a headline and dek.",LongRead:"A long-form article spread with a pull-quote and cover image.",Series:"A section heading over a grid of column cards.",Subscribe:"A newsletter signup beside a list of recent issues.",SubscribeBlogs:"A newsletter signup beside your latest blog posts, pulled live.",Events:"Latest journal posts in a three-card row.",DocMasthead:"A document header — headline, metadata and standfirst.",DocTabs:"A sticky tab bar to switch between documents.",DocBody:"Long-form document body with an 'On this page' contents list.",DocMetaCards:"A three-up meta strip for the foot of a document.",Banner:"Wide promo strip with background image.",Stats:"Highlight key numbers — years, designs.",KeyFeatures:"A theme-color chip and heading over a grid of short feature labels.",Logos:"A row of partner or brand logos.",Ticker:"A scrolling marquee of short phrases, full width.",Reviews:"Approved customer reviews in a star-rated card grid, pulled live.",SubmitBuild:"A 'Show us yours.' headline with a photo-submission form.",ReviewForm:"A write-a-review form — submissions wait for your approval before they show.",ContactRouting:"Pick who to reach, then a form that routes the message.",ContactLocations:"Your locations as a city gallery plus address and map cards.",SectionHeader:"A numbered section title with optional link.",Grid:"Multi-column container for blocks.",Flex:"An empty section. Add whatever you want inside.",Spacer:"Vertical breathing room between sections.",Divider:"A thin horizontal rule between sections.",CustomHTML:"Drop in your own sanitized HTML.",Heading:"A single heading line.",Text:"A paragraph of body copy.",ImageBlock:"A standalone image, at the width you set.",ButtonBlock:"A call-to-action button."};export{e as SECTION_DESCRIPTIONS};
1
+ const e={Hero:"Full-screen opener with rotating slides.",HeroSingle:"Full-screen image or video with a headline.",IntroBleed:"Full-bleed intro image the next section scrolls over.",Collections:"Product collections in a tidy grid.",AlloyWheelsListing:"A full product-listing page: filter rail, sortable card grid and pagination, from the live catalog. Choose which product types it shows.",CatalogFilterBar:"Filters the collection grids below it — a sticky row of Pills (the default), or Columns, one per filter you switch on.",ProductGrid:"Hand-picked products in a tidy grid.",FitmentFinder:"A vehicle picker — make, model, year and trim resolve the OEM stock fitment live.",Gallery:"Two image galleries with tabs and filters.",GalleryB:"Customer photos in a card grid with a click-to-open lightbox.",SpecStrip:"A thin one-line spec strip — small-caps items spread across the width, as a dark band or a bare hairline row.",ProductHero:"A product hero — image beside price, bullets and a buy button.",SpecTable:"A spec sheet — labeled rows of product specifications.",ProcessSteps:"A heading over columns of image, title, blurb and specs.",DetailRows:"Repeating full-width rows — eyebrow, title and copy beside a numbered close-up image, alternating sides each row.",FitmentTable:"A fitment table — per-size bolt patterns, offsets and load ratings, filterable by diameter.",CompatibleTyres:"The current product's compatible tyres — image, size, key specs and price per tyre, with an inquiry link. Display only.",RelatedProducts:"The current product's related items in a tidy row — the product page's built-in 'Pair with' cross-sell.",OrderSummary:"A display order-summary panel — items, totals and a note.",DeliveryOptions:"Delivery tiers as cards — name, window and price, one highlighted.",PaymentBadges:"A payment-methods trust strip with reassurance lines.",CheckoutCTA:"A centered 'ready to order?' headline with the checkout button.",Manifesto:"A bold brand statement beside a full-height image, with a stat strip.",ParagraphsA:"An editorial text panel with a stat strip and founders' note.",StatsParagraph:"An editorial heading and paragraph over a row of theme-color-accented stat cards.",Chart:"A titled chart — bars, line or donut — drawn from your own labeled data points.",Mockup:"A headline beside a stylized product-UI mockup card — spec sheet, fitment, portal, kanban and more.",Prose:"A plain editorial text section — eyebrow, heading and body copy.",Timeline:"An editorial aside beside a rail-marked timeline of dated entries.",TimelineTrack:"A horizontal year track of milestones — company history or roadmap.",Footprint:"A world map of your locations with a legend — designed here, sold worldwide.",TitleWithButtons:"A big headline beside a stack of call-to-action buttons.",Split:"Side-by-side image and text in two columns.",Cards:"A heading over a grid of free-text title-and-blurb cards.",FAQ:"A frequently-asked-questions accordion with a header.",Testimonials:"Customer quotes in a grid — the quote, a name and a role.",Masthead:"A journal issue header with a lead statement and contents.",Breadcrumb:"A slim trail showing where the reader is (Home / Journal…).",CategoryBar:"A sticky row of category tabs with counts and links.",FeaturedCover:"A featured article — big cover image beside a headline and dek.",LongRead:"A long-form article spread with a pull-quote and cover image.",Series:"A section heading over a grid of column cards.",Subscribe:"A newsletter signup beside a list of recent issues.",SubscribeBlogs:"A newsletter signup beside your latest blog posts, pulled live.",Events:"Latest journal posts in a three-card row.",DocMasthead:"A document header — headline, metadata and standfirst.",DocTabs:"A sticky tab bar to switch between documents.",DocBody:"Long-form document body with an 'On this page' contents list.",DocMetaCards:"A three-up meta strip for the foot of a document.",Banner:"Wide promo strip with background image.",Stats:"Highlight key numbers — years, designs.",Countdown:"Hours, minutes and seconds to a set date and time, then one line.",KeyFeatures:"A theme-color chip and heading over a grid of short feature labels.",Logos:"A row of partner or brand logos.",Ticker:"A scrolling marquee of short phrases, full width.",Reviews:"Approved customer reviews in a star-rated card grid, pulled live.",SubmitBuild:"A 'Show us yours.' headline with a photo-submission form.",ReviewForm:"A write-a-review form — submissions wait for your approval before they show.",ContactRouting:"Pick who to reach, then a form that routes the message.",ContactLocations:"Your locations as a city gallery plus address and map cards.",SectionHeader:"A numbered section title with optional link.",Grid:"Multi-column container for blocks.",Flex:"An empty section. Add whatever you want inside.",Spacer:"Vertical breathing room between sections.",Divider:"A thin horizontal rule between sections.",CustomHTML:"Drop in your own sanitized HTML.",Heading:"A single heading line.",Text:"A paragraph of body copy.",ImageBlock:"A standalone image, at the width you set.",ButtonBlock:"A call-to-action button."};export{e as SECTION_DESCRIPTIONS};
@@ -8,6 +8,6 @@ import{ruleChecks as z}from"./rule.js";const g="sf-note";function y(o){const i=[
8
8
  font-size: 12px;
9
9
  `,"font-size")==="12px"&&m(` font-size-adjust: 0.5;
10
10
  `,"font-size")===null),t("a grouping block reports its children, not itself",p(y("@keyframes sf-x { from { opacity: 0; } to { opacity: 1; } }").map(h=>h.selector),["from","to"])),t("braces in comments and strings do not shift nesting",p(y('/* .a { x } */ .b { content: "}"; } .c { color: red; }').map(h=>h.selector),[".b",".c"])),t("modifiers and descendants report the base note class",p([...u(".sf-note--error")],["sf-note"])&&p([...u(".sf-note p + p")],["sf-note"])&&p([...u(`.${e("pages")}, .${e("sm")}`)],[e("pages"),e("sm")])&&u(".sf-notebook").size===0);const f=[`/* Two homes were rejected: \`.${e("pages")}\` belongs to the chrome. */`,`// …and .${e("sm")} is the sitemap's own.`,'const url = "https://x/y";','export const Note = () => <div className="sf-note">hi</div>;'].join(`
11
- `);t("a class a file only TALKS about is not a class it renders, and a `//` in a URL is not a comment",p([...u(b(f))],["sf-note"])&&/https:\/\/x\/y/.test(b(f)))}let r=new Set([g]);if(i.stylesheet){const e=o.find(s=>s.path===i.stylesheet);if(t(`read the stylesheet ${i.stylesheet}`,!!e)&&e){const s=y(e.text);r=new Set;for(const l of s)for(const d of u(l.selector))r.add(d);t(`the stylesheet parses (${s.length} rules, more than 400)`,s.length>400,"the walker looks broken"),t(`the scan is not vacuous: it finds a note class (${r.size})`,r.size>0,"the selector scan looks broken"),t(`the chrome declares exactly ONE note class, .${g}`,p([...r].sort(),[g]),`it declares ${[...r].sort().map(l=>`.${l}`).join(", ")}. One quiet sentence, one class: a note that needs a different INSET takes it from the block it sits in (\`.sf-pages-list > .sf-note\`), never from a new class`);const f=new Map;for(const l of r){const d=s.find(x=>x.selector===`.${l}`),w=d?m(d.body,"font-size"):null;t(`.${l} has a type rule of its own`,!!d,"it is a modifier without a base"),t(`.${l} states its own font-size`,w!==null,"it inherits one — that is a size nobody chose"),f.set(l,w)}const h=new Set(f.values());t("every note class states the same size",h.size<=1,`the chrome's notes are set at ${h.size} sizes: ${[...f].map(([l,d])=>`.${l} ${d}`).join(", ")}`);const $=s.find(l=>l.selector===`.${g}`);t(`the note still reads as a note: .${g} is var(--sf-muted)`,!!$&&m($.body,"color")==="var(--sf-muted)",$?`color: ${m($.body,"color")}`:"the chrome no longer declares it")}}const n=o.filter(e=>/\.(tsx?|jsx?|mjs)$/.test(e.path));t(`read the source (${n.length} JS/TS files, at least ${i.minFiles})`,n.length>=i.minFiles,"fewer means the walk broke, and the check below is vacuous");const a=[];for(const e of n)for(const s of u(b(e.text)))r.has(s)||a.push(`${e.path} ${s}`);return t(`no source file names a note class the chrome does not declare (${[...r].map(e=>`.${e}`).join(", ")})`,a.length===0,`a \`.sf-*\` class is scoped under \`.sf-editor\` in the PARENT document, so a missing rule is not a compile error — the text simply renders at whatever it inherits:
11
+ `);t("a class a file only TALKS about is not a class it renders, and a `//` in a URL is not a comment",p([...u(b(f))],["sf-note"])&&/https:\/\/x\/y/.test(b(f)))}let r=new Set([g]);if(i.stylesheet){const e=o.find(s=>s.path===i.stylesheet);if(t(`read the stylesheet ${i.stylesheet}`,!!e)&&e){const s=y(e.text);r=new Set;for(const l of s)for(const d of u(l.selector))r.add(d);t(`the stylesheet parses (${s.length} rules, more than 300)`,s.length>300,"the walker looks broken"),t(`the scan is not vacuous: it finds a note class (${r.size})`,r.size>0,"the selector scan looks broken"),t(`the chrome declares exactly ONE note class, .${g}`,p([...r].sort(),[g]),`it declares ${[...r].sort().map(l=>`.${l}`).join(", ")}. One quiet sentence, one class: a note that needs a different INSET takes it from the block it sits in (\`.sf-pages-list > .sf-note\`), never from a new class`);const f=new Map;for(const l of r){const d=s.find(x=>x.selector===`.${l}`),w=d?m(d.body,"font-size"):null;t(`.${l} has a type rule of its own`,!!d,"it is a modifier without a base"),t(`.${l} states its own font-size`,w!==null,"it inherits one — that is a size nobody chose"),f.set(l,w)}const h=new Set(f.values());t("every note class states the same size",h.size<=1,`the chrome's notes are set at ${h.size} sizes: ${[...f].map(([l,d])=>`.${l} ${d}`).join(", ")}`);const $=s.find(l=>l.selector===`.${g}`);t(`the note still reads as a note: .${g} is var(--sf-muted)`,!!$&&m($.body,"color")==="var(--sf-muted)",$?`color: ${m($.body,"color")}`:"the chrome no longer declares it")}}const n=o.filter(e=>/\.(tsx?|jsx?|mjs)$/.test(e.path));t(`read the source (${n.length} JS/TS files, at least ${i.minFiles})`,n.length>=i.minFiles,"fewer means the walk broke, and the check below is vacuous");const a=[];for(const e of n)for(const s of u(b(e.text)))r.has(s)||a.push(`${e.path} ${s}`);return t(`no source file names a note class the chrome does not declare (${[...r].map(e=>`.${e}`).join(", ")})`,a.length===0,`a \`.sf-*\` class is scoped under \`.sf-editor\` in the PARENT document, so a missing rule is not a compile error — the text simply renders at whatever it inherits:
12
12
  ${a.join(`
13
13
  `)}`),c()}export{g as CHROME_NOTE_CLASS,m as declaration,S as editorChromeNote,y as leafRules,u as noteClasses,b as withoutComments};
@@ -1,6 +1,6 @@
1
- import{ruleChecks as d}from"./rule.js";const a=n=>JSON.stringify(n),g="the website builder's components/socialIcons.tsx (`<SocialMark>`)",$=/\.(ts|tsx|js|jsx|mjs|cjs)$/,u=/(?:from\s*|import\s*\(\s*|require\s*\(\s*|import\s+)["'](@tabler\/[^"']+)["']/g,f=/(?:import\s*\*\s*as\s+\w+\s*from|export\s*\*\s*(?:as\s+\w+\s*)?from)\s*["']@tabler\/[^"']+["']/,x=["Instagram","Facebook","Tiktok","Youtube","X","Linkedin","Pinterest","Whatsapp"],c=n=>[...n.matchAll(u)].map(t=>t[1]);function k(n,t){const{check:r,report:b}=d("social icons import");{const e=["@tabler","icons-react"].join("/"),s=[["a named import",`import { IconBrandX } from ${a(e)};`,!1],["a dynamic import()",`const m = await import(${a(e)});`,!1],["a require()",`const t = require(${a(e)});`,!1],["a side-effect import",`import ${a(e)};`,!1],["a namespace import",`import * as Tabler from ${a(e)};`,!0],["a star re-export",`export * from ${a(e)};`,!0],["a named star re-export",`export * as T from ${a(e)};`,!0]];for(const[l,o,p]of s)r(`the reader finds ${l}`,c(o).length===1),r(`…and ${p?"flags":"does not flag"} it as the whole set`,f.test(o)===p);r("a package that is not Tabler is not Tabler",c('import x from "@tablerish/x";').length===0)}const i=n.filter(e=>$.test(e.path));r(`read the source (${i.length} JS/TS files, at least ${t.minFiles})`,i.length>=t.minFiles,"fewer means the walk broke, and every check below is vacuous");const m=i.filter(e=>c(e.text).length>0&&e.path!==t.helper).map(e=>e.path);r(t.helper?`only ${t.helper} imports Tabler`:"no file here imports Tabler",m.length===0,`Tabler is imported outside its one home:
1
+ import{ruleChecks as $}from"./rule.js";const a=n=>JSON.stringify(n),w="the website builder's components/socialIcons.tsx (`<SocialMark>`)",u=/\.(ts|tsx|js|jsx|mjs|cjs)$/,x=/(?:from\s*|import\s*\(\s*|require\s*\(\s*|import\s+)["'](@tabler\/[^"']+)["']/g,d=/(?:import\s*\*\s*as\s+\w+\s*from|export\s*\*\s*(?:as\s+\w+\s*)?from)\s*["']@tabler\/[^"']+["']/,k=["Instagram","Facebook","Tiktok","Youtube","X","Linkedin","Pinterest","Whatsapp"],b=["Telegram","Line","Wechat"],h=n=>[...n.matchAll(x)].map(t=>t[1]);function S(n,t){const{check:r,report:g}=$("social icons import");{const e=["@tabler","icons-react"].join("/"),o=[["a named import",`import { IconBrandX } from ${a(e)};`,!1],["a dynamic import()",`const m = await import(${a(e)});`,!1],["a require()",`const t = require(${a(e)});`,!1],["a side-effect import",`import ${a(e)};`,!1],["a namespace import",`import * as Tabler from ${a(e)};`,!0],["a star re-export",`export * from ${a(e)};`,!0],["a named star re-export",`export * as T from ${a(e)};`,!0]];for(const[f,l,c]of o)r(`the reader finds ${f}`,h(l).length===1),r(`…and ${c?"flags":"does not flag"} it as the whole set`,d.test(l)===c);r("a package that is not Tabler is not Tabler",h('import x from "@tablerish/x";').length===0)}const i=n.filter(e=>u.test(e.path));r(`read the source (${i.length} JS/TS files, at least ${t.minFiles})`,i.length>=t.minFiles,"fewer means the walk broke, and every check below is vacuous");const m=i.filter(e=>h(e.text).length>0&&e.path!==t.helper).map(e=>e.path);r(t.helper?`only ${t.helper} imports Tabler`:"no file here imports Tabler",m.length===0,`Tabler is imported outside its one home:
2
2
  ${m.join(`
3
3
  `)}
4
- Draw social marks through ${g} instead.`);const h=i.filter(e=>f.test(e.text)).map(e=>e.path);if(r("nothing imports the whole Tabler set",h.length===0,`a namespace or star import from Tabler ships all ~6,000 icons (552 KB gzip):
5
- ${h.join(`
6
- `)}`),t.helper){const e=i.find(s=>s.path===t.helper);if(r(`read the helper ${t.helper}`,!!e,"the social marks have lost their one home")&&e){const s=[...new Set(c(e.text))];r("the helper imports from @tabler/icons-react only (the React build, per-icon rewritable)",s.length===1&&s[0]==="@tabler/icons-react",JSON.stringify(s));const l=x.flatMap(o=>[`IconBrand${o}`,`IconBrand${o}Filled`]).filter(o=>!new RegExp(`\\b${o},`).test(e.text));r("the helper imports the sixteen marks by name",l.length===0,`no longer imports ${l.join(", ")}`)}}return b()}export{k as socialIconsImport};
4
+ Draw social marks through ${w} instead.`);const p=i.filter(e=>d.test(e.text)).map(e=>e.path);if(r("nothing imports the whole Tabler set",p.length===0,`a namespace or star import from Tabler ships all ~6,000 icons (552 KB gzip):
5
+ ${p.join(`
6
+ `)}`),t.helper){const e=i.find(o=>o.path===t.helper);if(r(`read the helper ${t.helper}`,!!e,"the social marks have lost their one home")&&e){const o=[...new Set(h(e.text))];r("the helper imports from @tabler/icons-react only (the React build, per-icon rewritable)",o.length===1&&o[0]==="@tabler/icons-react",JSON.stringify(o));const l=[...k.flatMap(s=>[`IconBrand${s}`,`IconBrand${s}Filled`]),...b.map(s=>`IconBrand${s}`)].filter(s=>!new RegExp(`\\b${s},`).test(e.text));r("the helper imports the nineteen marks by name",l.length===0,`no longer imports ${l.join(", ")}`);const c=b.filter(s=>!new RegExp(`createReactComponent\\(\\s*"filled",\\s*"brand-${s.toLowerCase()}-filled"`).test(e.text));r("the helper draws the three Solid marks Tabler does not ship",/\bcreateReactComponent,/.test(e.text)&&c.length===0,`no Solid mark for ${c.join(", ")||"any of them: the factory is not imported"}`)}}return g()}export{S as socialIconsImport};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "5.3.0",
3
+ "version": "6.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",
@@ -40,7 +40,7 @@
40
40
  "peerDependencies": {
41
41
  "@tabler/icons-react": "^3.46.0",
42
42
  "efficient-easel": "^2.0.0",
43
- "efficient-shell": "^4.171.0 || ^5.0.0",
43
+ "efficient-shell": "^5.6.0",
44
44
  "isomorphic-dompurify": "^3.18.0",
45
45
  "next": ">=16",
46
46
  "react": ">=19",
@@ -58,8 +58,8 @@
58
58
  "@types/node": "^20",
59
59
  "@types/react": "^19",
60
60
  "@types/react-dom": "^19",
61
- "efficient-easel": "^2.1.0",
62
- "efficient-shell": "^4.180.0",
61
+ "efficient-easel": "^2.2.0",
62
+ "efficient-shell": "^5.6.0",
63
63
  "esbuild": "^0.28.0",
64
64
  "happy-dom": "^20.14.5",
65
65
  "isomorphic-dompurify": "^3.18.0",
@@ -1,16 +0,0 @@
1
- export declare const FOCAL_DEFAULT = "50% 50%";
2
- export declare const FOCAL_NUDGE_STEP = 1;
3
- export declare const FOCAL_NUDGE_COARSE = 10;
4
- export interface FocalPoint {
5
- x: number;
6
- y: number;
7
- }
8
- export declare function parseFocal(value?: string | null): FocalPoint;
9
- export declare function formatFocal(x: number, y: number): string;
10
- export declare function nudgeFocal(value: string | undefined | null, key: string, coarse?: boolean): string | null;
11
- export declare function focalFromRect(rect: {
12
- left: number;
13
- top: number;
14
- width: number;
15
- height: number;
16
- }, clientX: number, clientY: number): FocalPoint;
@@ -1 +0,0 @@
1
- const i="50% 50%",x=1,p=10,c=t=>t<0?0:t>100?100:Math.round(t);function a(t){const r=String(t??"").trim().split(/\s+/);if(r.length!==2)return{x:50,y:50};const e=u=>{const l=/^(-?\d+(?:\.\d+)?)%$/.exec(u);return l?Number(l[1]):null},n=e(r[0]),o=e(r[1]);return n===null||o===null?{x:50,y:50}:{x:c(n),y:c(o)}}function s(t,r){return`${c(t)}% ${c(r)}%`}function f(t,r,e=!1){const n=e?10:1,{x:o,y:u}=a(t);switch(r){case"ArrowLeft":return s(o-n,u);case"ArrowRight":return s(o+n,u);case"ArrowUp":return s(o,u-n);case"ArrowDown":return s(o,u+n);default:return null}}function A(t,r,e){return!(t.width>0)||!(t.height>0)?{x:50,y:50}:{x:c((r-t.left)/t.width*100),y:c((e-t.top)/t.height*100)}}export{i as FOCAL_DEFAULT,p as FOCAL_NUDGE_COARSE,x as FOCAL_NUDGE_STEP,A as focalFromRect,s as formatFocal,f as nudgeFocal,a as parseFocal};