efficient-web-builder 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +42 -0
  3. package/dist/components/ApplyCornersToSiblings.js +1 -1
  4. package/dist/components/Banner.js +1 -1
  5. package/dist/components/BlockGapField.js +1 -1
  6. package/dist/components/BlogPostSource.js +1 -1
  7. package/dist/components/Breadcrumb.js +1 -1
  8. package/dist/components/CardShadowField.js +1 -1
  9. package/dist/components/CategoryBar.js +1 -1
  10. package/dist/components/ChatSettingsPanel.js +1 -1
  11. package/dist/components/ClearColoursDialog.js +1 -1
  12. package/dist/components/CornersField.js +1 -1
  13. package/dist/components/DocBody.js +5 -5
  14. package/dist/components/DuplicateToPageMenu.js +1 -1
  15. package/dist/components/FAQ.js +1 -1
  16. package/dist/components/Flex.js +1 -1
  17. package/dist/components/Footprint.js +3 -3
  18. package/dist/components/HeadingAudit.js +1 -1
  19. package/dist/components/HeroImageField.js +1 -1
  20. package/dist/components/HeroSection.js +2 -2
  21. package/dist/components/HeroSingle.js +1 -1
  22. package/dist/components/HeroSlide.js +1 -1
  23. package/dist/components/HoverEffectField.js +1 -1
  24. package/dist/components/ImageFocusRow.js +1 -1
  25. package/dist/components/IntegrationsSection.js +1 -1
  26. package/dist/components/IntroBleed.js +1 -1
  27. package/dist/components/KeyFeatures.js +1 -1
  28. package/dist/components/LocationsGroupedField.js +1 -1
  29. package/dist/components/MediaUploadField.js +1 -1
  30. package/dist/components/MultiSelectField.js +1 -1
  31. package/dist/components/PagesPanel.js +1 -1
  32. package/dist/components/PartInkControl.js +1 -1
  33. package/dist/components/PartResetDot.js +1 -1
  34. package/dist/components/PartSettingsPanel.js +1 -1
  35. package/dist/components/PartTextBox.js +1 -1
  36. package/dist/components/PhotographyField.js +1 -1
  37. package/dist/components/ProcessSteps.js +1 -1
  38. package/dist/components/SearchSelectField.d.ts +1 -1
  39. package/dist/components/SearchSelectField.js +1 -1
  40. package/dist/components/SectionEditor.js +1 -1
  41. package/dist/components/SectionTextEntries.js +1 -1
  42. package/dist/components/SectionThemePicker.js +1 -1
  43. package/dist/components/Series.js +1 -1
  44. package/dist/components/ShadowColourField.js +1 -1
  45. package/dist/components/SideSpaceField.js +1 -1
  46. package/dist/components/SiteFields.js +1 -1
  47. package/dist/components/SiteWidthField.js +1 -1
  48. package/dist/components/SlotChildRows.js +1 -1
  49. package/dist/components/SocialLinksPanel.js +1 -1
  50. package/dist/components/SourceStatus.js +1 -1
  51. package/dist/components/SpecStrip.js +1 -1
  52. package/dist/components/Split.js +1 -1
  53. package/dist/components/StandaloneSectionEditor.js +1 -1
  54. package/dist/components/StatsParagraph.js +1 -1
  55. package/dist/components/StorefrontLinkField.js +1 -1
  56. package/dist/components/StylesPanel.js +1 -1
  57. package/dist/components/SwitchToBoxFooter.js +1 -1
  58. package/dist/components/Testimonials.js +1 -1
  59. package/dist/components/TextStyleRow.js +1 -1
  60. package/dist/components/TextStylesField.js +1 -1
  61. package/dist/components/ThemeCard.js +1 -1
  62. package/dist/components/ThemeColourField.js +1 -1
  63. package/dist/components/ThemeField.js +1 -1
  64. package/dist/components/TickerSection.js +1 -1
  65. package/dist/components/TickerSettingsPanel.js +1 -1
  66. package/dist/components/TitleWithButtons.js +1 -1
  67. package/dist/components/WebsiteScreenParts.js +1 -1
  68. package/dist/components/WebsiteSettingsPanel.js +1 -1
  69. package/dist/components/WidthFollowField.js +1 -1
  70. package/dist/components/preview-devices.js +1 -1
  71. package/dist/components/storefront-editor.css +43 -37
  72. package/dist/components/useLocationsTree.js +1 -1
  73. package/dist/lib/content/ink.d.ts +36 -0
  74. package/dist/lib/content/ink.js +1 -0
  75. package/dist/lib/content/section-surface.js +1 -1
  76. package/dist/lib/editor-words-catalogue.d.ts +1184 -0
  77. package/dist/lib/editor-words-catalogue.js +11 -0
  78. package/dist/lib/editor-words.d.ts +15 -0
  79. package/dist/lib/editor-words.js +1 -0
  80. package/dist/lib/links/link-picker-setup.js +1 -1
  81. package/dist/lib/puck/ColourControl.js +1 -1
  82. package/dist/lib/puck/MarkupToolbar.js +1 -1
  83. package/dist/lib/puck/apply-card-corners.js +1 -1
  84. package/dist/lib/puck/blocks/general/Breadcrumb/render.js +1 -1
  85. package/dist/lib/puck/blocks/general/Cards/render.js +1 -1
  86. package/dist/lib/puck/blocks/general/CategoryBar/render.js +1 -1
  87. package/dist/lib/puck/blocks/general/Chart/render.js +2 -2
  88. package/dist/lib/puck/blocks/general/DocBody/render.js +1 -1
  89. package/dist/lib/puck/blocks/general/DocMasthead/render.js +1 -1
  90. package/dist/lib/puck/blocks/general/DocTabs/render.js +1 -1
  91. package/dist/lib/puck/blocks/general/FAQ/render.js +1 -1
  92. package/dist/lib/puck/blocks/general/Footprint/render.js +2 -2
  93. package/dist/lib/puck/blocks/general/KeyFeatures/render.js +1 -1
  94. package/dist/lib/puck/blocks/general/Logos/render.js +1 -1
  95. package/dist/lib/puck/blocks/general/Masthead/render.js +1 -1
  96. package/dist/lib/puck/blocks/general/OrderSummary/render.js +1 -1
  97. package/dist/lib/puck/blocks/general/PaymentBadges/render.js +1 -1
  98. package/dist/lib/puck/blocks/general/ProcessSteps/render.js +1 -1
  99. package/dist/lib/puck/blocks/general/Series/render.js +1 -1
  100. package/dist/lib/puck/blocks/general/StatsParagraph/render.js +1 -1
  101. package/dist/lib/puck/blocks/general/Testimonials/render.js +1 -1
  102. package/dist/lib/puck/blocks/general/Timeline/render.js +2 -2
  103. package/dist/lib/puck/blocks/general/TimelineTrack/render.js +1 -1
  104. package/dist/lib/puck/blocks/scaffold.js +1 -1
  105. package/dist/lib/puck/controls.js +1 -1
  106. package/dist/lib/puck/footer-block-row-name.js +1 -1
  107. package/dist/lib/puck/page-root-fields.js +1 -1
  108. package/dist/lib/puck/theme-swatches.js +1 -1
  109. package/dist/lib/source-rules/editor-words.d.ts +26 -0
  110. package/dist/lib/source-rules/editor-words.js +3 -0
  111. package/dist/lib/source-rules/mirrored-rows-agree.js +1 -1
  112. package/dist/lib/source-rules/part-style-naming.js +1 -1
  113. package/dist/lib/source-rules/support/label-extraction.js +2 -2
  114. package/dist/lib/theme-save-message.js +1 -1
  115. package/package.json +6 -5
@@ -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{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};
1
+ "use client";import{jsx as r,jsxs as T,Fragment as R}from"react/jsx-runtime";import{cloneElement as Je,useId as Ze,useRef as ee,useState as pe}from"react";import{useEasel as F}from"efficient-easel/easel";import{say as l,editorEaselWords as b}from"../editor-words.js";import{readHidable as fe,hidableText as me}from"./hidable.js";import{FOLD_FIELD_MARKER as te,LINK_FIELD_MARKER as he,MEDIA_FIELD_MARKER as ge,SCAFFOLD_FIELD_MARKER as be,TEXT_FIELD_MARKER as v,foldMetaOf as ne,textFieldIdentifier as Qe}from"./field-markers.js";import et from"../../components/ApplyCornersToSiblings.js";import{CARD_IMAGE_RADIUS_STEP as tt,CORNER_RADIUS_MAX as $,CORNER_RADIUS_MIN as M}from"../content/card-image-shape.js";import{IMAGE_CORNER_STEP as nt,IMAGE_CORNERS_LABEL as ot}from"../content/image-corners.js";import{GRID_MAX_COLUMNS as rt}from"../content/grid-span.js";import{GALLERY_ACROSS_BUCKETS as it,GALLERY_LAYOUTS as w,GALLERY_LAYOUT_KEYS as xe}from"../content/gallery-layout.js";import{anchorSiblingsOf as lt,HERO_GROUP_PLACEMENTS as at,HERO_GROUP_PLACEMENT_DEFAULT as st,normalisePlacement as ct,placementPoints as Ce}from"../hero-group-placement.js";import ut from"../../components/KeepHint.js";import{AlignLeftIcon as dt,AlignSeparateIcon as pt,AnimationIcon as Se,BackgroundIcon as ft,BlockSectionIcon as mt,CartIcon as ht,ColumnWidthsIcon as Ie,ColumnsIcon as gt,CornerIcon as _e,DirectionDownIcon as bt,DirectionLeftIcon as xt,DirectionRightIcon as Ct,DirectionUpIcon as St,DollarIcon as It,FinishIcon as _t,GapIcon as ye,GridIcon as yt,GroundIcon as Et,HashIcon as Ee,ImageIcon as Tt,LayoutIcon as Rt,ListIcon as vt,LocationIcon as oe,PaddingBottomIcon as Lt,PaddingLeftIcon as Nt,PaddingRightIcon as Ot,PaddingTopIcon as At,PageIcon as Te,PhoneIcon as Ft,PlacementIcon as wt,ProductSizeIcon as Pt,RotateIcon as kt,SquareIcon as Dt,StylesIcon as Bt,TextLinesIcon as Ht,TypeIcon as Gt,WidthIcon as Mt,WrapIcon as Wt}from"efficient-easel/icons";import{FieldGlyph as Re}from"../../components/FieldGlyph.js";import{resolvePageBackground as Ut}from"../content/page-background.js";import{CORNER_SIDES as P,CORNER_SIDE_POINTS as re,CORNER_SIDES_LABEL as k,cornerSidesSummary as ve,hasOwnSectionCorners as Kt,normalizeCornerSides as z}from"../content/section-corners.js";import{hasOwnCardCorners as Xt}from"../content/card-corners.js";import{SECTION_MOTION_NONE as $t,SECTION_MOTION_OPTIONS as zt}from"../content/section-animation.js";import{enclosingSectionProps as Le}from"./enclosing-section.js";import{SettingsCorners as Ne,SettingsDefaultReset as x,SettingsField as h,SettingsGroupHead as Vt,SettingsGroupSub as Yt,SettingsPlacement as jt,SettingsSegmented as qt,SettingsSwitch as Jt}from"efficient-easel/panel";import{FieldSelect as Zt,ListField as Qt}from"efficient-easel/fields";import{Checkbox as en,DateTimePicker as tn,FOCAL_DEFAULT as Oe,Slider as nn,Tooltip as V}from"efficient-shell/ui";import{ColourControl as Ae}from"./ColourControl.js";import Fe from"./MarkupToolbar.js";import{deviceField as L}from"./device-fields.js";import{noControlField as on}from"./panel-no-control-mark.js";import{phoneKey as Y,resolvePhoneValue as ie}from"./phone-override.js";import{SuppressibleText as rn}from"./section-text-suppress.js";import{CARD_INDEX_OPTIONS as ln,CARD_OUTLINE_OPTIONS as an,DEFAULT_CARD_INDEX_FORMAT as sn,DEFAULT_CARD_OUTLINE as cn}from"../sections/product-card-style.js";import{COVER_INDEX_OPTIONS as un,DEFAULT_COVER_INDEX as dn}from"../sections/card-cover-index.js";import{SCALAR_TEXT_CONTROLS as pn}from"./text-control-kinds.js";import fn from"../../components/ImageFocusRow.js";import mn from"../../components/MediaUploadField.js";import hn from"../../components/MultiSelectField.js";import gn from"../../components/SectionThemePicker.js";import bn from"../../components/SearchSelectField.js";import xn from"../../components/StorefrontLinkField.js";import we from"../../components/UiIcon.js";import{SECTION_PADDING as _}from"../content/section-padding.js";import{hasPhoneHeight as Cn,resolveSectionMinHeight as Sn}from"../content/section-min-height.js";import{SECTION_MIN_HEIGHT as In,SECTION_MIN_HEIGHT_GROUP_LABEL as W,SECTION_SCREEN_PCT as _n}from"../content/section-min-height.js";import{CONTAINER_DIRECTION_LABEL as yn,containerDirectionPoints as En,resolveContainerDirection as Pe}from"../content/container-direction.js";import{BOX_ALIGN_POINTS as Tn,BOX_BLOCK_SPACING_LABEL as Rn,BOX_BLOCK_SPACING_POINTS as ke,BOX_JUSTIFY_POINTS as De,BOX_PHONE_ROW_LABEL as vn,BOX_PHONE_ROW_MAX as Ln,BOX_PHONE_ROW_MIN as Be,BOX_SHARE_LABEL as He,BOX_SHARE_POINTS as le,BOX_WRAP_LABEL as Nn,BOX_WRAP_POINTS as Ge}from"../content/box-layout.js";import{usePreviewHeader as j}from"../../components/PreviewHeaderContext.js";import{CONTAINER_GAP as ae,CONTAINER_GAP_BUILT_IN as On,GAP_FIELD_CONTAINER as An,hasOwnContainerGap as Fn,resolveContainerGap as wn}from"../content/container-gap.js";import{CARD_IMAGE_BG_INHERIT as Pn,CARD_IMAGE_BG_OFF as kn,CARD_IMAGE_BG_SWATCH_NAMES as Dn,CARD_IMAGE_BG_SWATCHES as Bn,isCardImageBackgroundInheriting as Hn,cardImageBackgroundChoice as Gn,THEME_CARD_IMAGE_BG as Mn}from"../content/card-image-background.js";import{SECTION_BG_INHERIT as Wn,SECTION_BG_SWATCHES as Un,SECTION_BG_SWATCH_NAMES as Kn,THEME_SECTION_BG as Xn,isSectionBackgroundInheriting as $n}from"../content/section-background.js";import{SECTION_THEME_GROUP_LABEL as zn}from"../content/section-surface.js";import{TYPE_SIZE_FIXED as Vn,TYPE_SIZE_INHERIT as Yn,isTypeSizeInheriting as jn}from"../content/section-type-size.js";import{SECTION_WIDTH_CHOICES as qn,WIDTH_CHOICE_LABEL as Jn,WIDTH_INHERIT as Zn,resolveWidth as Qn,sectionRunsFullWidth as Me}from"../content/section-width.js";import{useFoldHeadingLevel as We}from"./panel-heading-scope.js";import{withStyleKind as eo}from"efficient-easel/style-clipboard";function U(e){for(const[t,o]of Object.entries(e))o&&typeof o=="object"&&!ne(o)&&eo(o,`section:${t}`);return e}function qr({children:e}){return r("div",{className:"sf-field-label",children:typeof e=="string"?l(e):e})}function Ue(){return null}function to(e){if(!e.trim())throw new Error("noGlyph() needs a reason naming the ruling that decided it.");return r(Ue,{},e)}function no(e){return e.type===Ue}function q(e){return no(e)?void 0:e}function D(e,t){return l("{value} from {from}",{value:e,from:t})}function oo(){const{appState:e}=F(i=>i),t=e.data.root?.props??{},{mode:o,pageWidth:n}=Qn(t,"full");return o==="page"?D(`${n}px`,l("the page")):o==="contained"?D(l("Contained"),l("the page")):D(l("Full"),l("the page"))}function ro(){const{blockGap:e}=j();return e===null?l("this container's own spacing"):D(`${e}px`,l("Site styles"))}function io({inherited:e,onReset:t,label:o}){return r(x,{words:b()?.panel,label:l(o),changed:!e,detail:ro(),onReset:t})}function lo({inherited:e,onReset:t,label:o}){return r(x,{words:b()?.panel,label:l(o),changed:!e,detail:oo(),onReset:t})}function B({value:e,onChange:t,label:o,placeholder:n,hint:i,multiline:a,hideable:s=!0,markup:c=!0}){const{text:u,hidden:p}=fe(e),m=ee(null),d=ee(null),f=E=>t(s?{text:E,hidden:p}:E),g=()=>t({text:u,hidden:!p}),C=s&&p,y=Ze(),S=i?po(i)?r("span",{className:"sf-hint-keep sf-hint-while-typing",children:l(i)}):r(ut,{children:l(i)}):void 0,X=p?l("Show {label} on the slide",{label:l(o)}):l("Hide {label} on the slide",{label:l(o)});return r(h,{label:l(o),icon:r(Gt,{}),htmlFor:y,className:C?"is-hidden":void 0,hint:S,action:s?r(V,{content:X,children:r("button",{type:"button",className:"sf-field-eye","aria-pressed":p,"aria-label":X,onClick:g,children:p?r(we,{name:"eye-off",size:14}):r(we,{name:"eye",size:14})})}):void 0,children:T("div",{className:"sf-copybox",children:[c&&r(Fe,{target:a?d:m,value:u,onChange:f}),a?r("textarea",{id:y,ref:d,value:u,placeholder:n===void 0?void 0:l(n),onChange:E=>f(E.target.value)}):r("input",{id:y,ref:m,type:"text",value:u,placeholder:n===void 0?void 0:l(n),onChange:E=>f(E.target.value)})]})})}function Jr(e,t){return{...e,[be]:t}}function Zr(e){const t=e[v];if(!t)throw new Error("withOffPage: the field holds no authored text");return{...e,[v]:{...t,offPage:!0}}}function Qr(e){return!e||typeof e!="object"?!1:e[v]?.offPage===!0}function ei(e){const t=e[v];if(!t)throw new Error("withIdentifier: the field holds no authored text");return{...e,[v]:{...t,identifier:!0}}}import{TEXT_CONTROL_KINDS as rl,SCALAR_TEXT_CONTROLS as il}from"./text-control-kinds.js";const ao=new Set(pn),H=(e,t)=>{const o={...t,[v]:e};if(!ao.has(e.control))return o;const n=t.render;return{...on(o,"authored-copy"),render:i=>r(rn,{name:i.name,children:n(i)})}},ti="Everything else on this block comes from the linked post. Unlink it to edit by hand.",so="Select a word, then press the highlighter.",co="A short name so a link can jump straight to this section, like yoursite.com/page#about.",uo=new Set([so]),po=e=>uo.has(e);function ni(e,t,o){return H({control:"text",label:e,placeholder:t,hint:o},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:e,placeholder:t,hint:o})})}function oi(e,t,o){return H({control:"textarea",label:e,placeholder:t,hint:o},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:e,placeholder:t,hint:o,multiline:!0})})}function fo(e,t,o){return H({control:"plainText",label:e,placeholder:t,hint:o},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:e,placeholder:t,hint:o,hideable:!1,markup:!1})})}function ri(e,t,o){return H({control:"copyText",label:e,placeholder:t,hint:o},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:e,placeholder:t,hint:o,hideable:!1})})}function ii(e){return{type:"custom",[he]:{label:e},render:({value:t,onChange:o})=>r(xn,{value:me(t),onChange:o,label:e})}}function li(e,t,o){return H({control:"plainTextarea",label:e,placeholder:t,hint:o},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:e,placeholder:t,hint:o,multiline:!0,hideable:!1})})}const ai={Content:Ht,Style:Bt,Layout:Rt,Animation:Se};function si(e,t){return e.includes("Content")?t!=="Content":null}function mo({label:e}){return r(Vt,{title:l(e),level:We(1)})}function ho({level:e,label:t}){return e===1?r(mo,{label:t}):r(bo,{label:t})}function Ke(e,t){return{type:"custom",[te]:{label:e,level:t},render:()=>r(ho,{level:t,label:e})}}function I(e){return Ke(e,2)}function ci(e){return{type:"custom",render:()=>r(go,{text:e})}}function go({text:e}){return r("p",{className:"sf-note",children:l(e)})}function ui(e){return Ke(e,1)}function di(e){return ne(e)!==null&&e?.tabs!==void 0}const Xe=new Map;function pi(e,t){const o=`${e}\0${t?t.join(""):""}`,n=Xe.get(o)??{type:"custom",tabs:t,[te]:{label:e,level:1},bucket:e,marker:!0,render:()=>r(R,{})};return Xe.set(o,n),n}function bo({label:e}){return r(Yt,{title:l(e),level:We(2)})}function $e({swatches:e,current:t,onPick:o,names:n}){const i=e.find(c=>c.toLowerCase()===t.toLowerCase()),a=i?n?.[i]:void 0,s=a?l(a):t;return T("div",{className:"sf-swatches",children:[e.map(c=>{const u=n?.[c]?l(n[c]):c;return r(V,{content:u,children:r("button",{type:"button","aria-pressed":t.toLowerCase()===c.toLowerCase(),className:`sf-swatch ${t.toLowerCase()===c.toLowerCase()?"is-active":""}`,style:{background:c},onClick:()=>o(c),"aria-label":u})},c)}),r("span",{className:"sf-swatch-hex",children:s})]})}function fi(e,t){return{type:"custom",render:({value:o,onChange:n})=>{const i=$n(o,t);return r(h,{label:l(e),icon:r(ft,{}),changed:!i,action:r(x,{words:b()?.panel,label:l(e),changed:!i,detail:l("the theme's section background"),onReset:()=>n(Wn)}),children:$e({swatches:Un,current:i?Xn:o??t??"",onPick:n,names:Kn})})}}}function xo(e,t){return{type:"custom",render:({value:o,onChange:n})=>{const i=o,a=Hn(i,t);return r(h,{label:l(e),icon:r(Et,{}),changed:!a,action:r(x,{words:b()?.panel,label:l(e),changed:!a,detail:l("the theme's image stage"),onReset:()=>n(Pn)}),children:$e({swatches:Bn,current:a?Mn:Gn(i,t),onPick:n,names:Dn})})}}}function mi(e=o=>o,t){return U({_gSectionTheme:I(zn),sectionAccent:{type:"custom",render:({value:o,onChange:n})=>r(gn,{value:e(o),onChange:n,followLabel:t})}})}function O({min:e,max:t,step:o,value:n,onChange:i,suffix:a="",readout:s=!0,notch:c,ariaLabel:u,disabled:p=!1}){const m=c!==void 0&&Number.isFinite(c)&&c>=e&&c<=t;return r("div",{className:m?"sf-slider has-notch":"sf-slider",style:m?{"--sf-notch":(c-e)/(t-e)}:void 0,children:r(nn,{min:e,max:t,step:o,value:n,suffix:a||void 0,showInput:s,label:u===void 0?void 0:l(u),disabled:p,size:"sm",className:"sf-slider-track",onChange:d=>{d!==null&&d!==n&&i(d)}})})}function G(e,t,o,n,i,a,s="",c){return{type:"custom",render:u=>r(h,{label:l(e),icon:q(t),action:c?c("storedValue"in u?u.storedValue:u.value,u.onChange):void 0,children:O({min:o,max:n,step:i,value:typeof u.value=="number"?u.value:a,suffix:s,ariaLabel:e,onChange:u.onChange})})}}function ze({min:e,max:t,step:o,px:n,label:i,onChange:a,disabled:s=!1}){const{cornerRadiusPx:c}=j();return r(R,{children:O({min:e,max:t,step:o,value:n??(typeof c=="number"?c:e),readout:!1,ariaLabel:i,disabled:s,onChange:a})})}function K(e,t){const{min:o,max:n,step:i=1,unsetLabel:a,hint:s,restAtSite:c=!1,restTrack:u,unsetMark:p}=t;return{type:"custom",render:({value:m,onChange:d})=>{const f=typeof m=="number"?m:null,g=f===null;return r(h,{label:l(e),value:g?p||a===void 0?void 0:l(a):`${f}px`,changed:!g,action:p?Je(p,{changed:!g,onReset:()=>d(null)}):r(x,{words:b()?.panel,label:l(e),changed:!g,onReset:()=>d(null)}),hint:typeof s=="string"?l(s):s,children:u?u({min:o,max:n,step:i,px:f,label:e,onChange:d}):c?r(ze,{min:o,max:n,step:i,px:f,label:e,onChange:d}):O({min:o,max:n,step:i,value:f??o,readout:!1,ariaLabel:e,onChange:d})})}}}function hi(e){const t=G("Gap",r(ye,{}),ae.min,ae.max,ae.step,On[e],"px",(o,n)=>r(io,{inherited:!Fn(e,o),onReset:()=>n(void 0),label:"Gap"}));return{type:"custom",[An]:e,render:o=>t.render({...o,value:wn(e,o.value,o.field?.siteGap),storedValue:o.value,onChange:n=>o.onChange(n)})}}function Co(){return{type:"custom",render:({value:e,onChange:t})=>{const n=z(e)??[...P],i=n.length===P.length;return r(h,{label:l(k),icon:r(_e,{}),value:ve(n),changed:!i,action:r(x,{words:b()?.panel,label:l(k),changed:!i,onReset:()=>t(null)}),hint:"Corners left off stay square. The row above sets how round the others are.",children:r(Eo,{value:n,onChange:a=>{const s=z(a)??[];t(s.length===P.length?null:s)}})})}}}function So({label:e,changed:t=!1,onReset:o=()=>{}}){const{cornerRadiusPx:n}=j(),i=typeof n=="number"?`${n}px`:l("not set");return r(x,{words:b()?.panel,label:l(e),changed:t,detail:n==null?l("the built-in corners"):D(i,l("Site styles")),onReset:o})}function Io(){return K("Corners",{min:M,max:$,unsetLabel:"Follows the site",unsetMark:r(So,{label:"Corners"}),restTrack:e=>r(_o,{...e}),hint:r(yo,{})})}const Ve="This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.";function se(){return Me(J())}function _o(e){return r(ze,{...e,disabled:se()})}function yo(){return r(R,{children:se()?Ve:"Follows Site styles ▸ Basics ▸ Corners until you set a number here."})}function Eo({value:e,onChange:t}){const o=se();return r(Ne,{label:l(k),value:e,corners:o?re.map(n=>({...n,disabled:!0,title:Ve})):re,onChange:t})}function gi(){return U({_gShape:I("Shape"),sectionCorners:Io(),sectionCornerSides:Co()})}function bi(){return{_gMotion:I("Motion"),sectionAnimation:de("Entrance",r(Se,{}),[...zt],$t)}}function ce(){let e=null;try{const{appState:t,selectedItem:o}=F(i=>i),n=o?.props?.id?String(o.props.id):void 0;e=n?Le(t?.data,n):null}catch{e=null}return e!==null&&Me(e)}function Ye(e){const{cornerRadiusPx:t}=j(),o=ce(),n=typeof t=="number"?t:e;let i=null;try{const{appState:s,selectedItem:c}=F(p=>p),u=c?.props?.id?String(c.props.id):void 0;i=u?Le(s?.data,u):null}catch{i=null}if(o||!i)return n;const a=i.sectionCorners;return Kt(a)?a:n}function To({min:e,max:t,step:o,px:n,label:i,onChange:a}){const s=Ye(e);return r(R,{children:O({min:e,max:t,step:o,value:n??s,readout:!1,ariaLabel:i,onChange:a})})}function Ro({label:e,changed:t=!1,onReset:o=()=>{}}){const n=ce(),i=Ye(M),a=n?"Site":"Section";return r(x,{words:b()?.panel,label:l(e),changed:t,detail:D(`${i}px`,n?l("Site styles"):l("the section")),onReset:o})}function vo(){return r(R,{children:ce()?l("The section is full width, so this card follows Site styles ▸ Basics ▸ Corners."):l("Follows the section's Corners until you set a number here.")})}function Lo(){return K("Corners",{min:M,max:$,unsetLabel:"Follows the section",unsetMark:r(Ro,{label:"Corners"}),restTrack:e=>r(To,{...e}),hint:r(vo,{})})}function No({value:e,onChange:t}){return r(Ne,{label:l(k),value:e,corners:re,onChange:t})}function Oo({unset:e}){return r(R,{children:e?l("Set a number above first — there is nothing to shape yet."):l("Corners left off stay square. The row above sets how round the others are.")})}function Ao(){return{type:"custom",render:({value:e,onChange:t})=>{const n=z(e)??[...P],i=n.length===P.length;return r(h,{label:l(k),icon:r(_e,{}),value:ve(n),changed:!i,action:r(x,{words:b()?.panel,label:l(k),changed:!i,onReset:()=>t(null)}),hint:r(Oo,{unset:!Xt(e)}),children:r(No,{value:n,onChange:a=>{const s=z(a)??[];t(s.length===P.length?null:s)}})})}}}function Fo(){return{type:"custom",render:()=>r(et,{})}}function xi(){return{_gShape:I("Shape"),cardCorners:Lo(),cardCornerSides:Ao(),cardCornersApplyAll:Fo()}}function Ci(){return N("Justify",r(pt,{}),De,De[0].value)}function Si(){return N("Item alignment",r(dt,{}),Tn,"stretch")}function Ii(){return N(Nn,r(Wt,{}),Ge,Ge[0].value)}function _i(){return{type:"custom",render:({value:e,onChange:t})=>{const o=le.find(n=>n.value===e)??le[0];return r(h,{label:l(He),icon:r(Ie,{}),value:l(o.label),children:r("div",{className:"sf-gallery-layouts",role:"group","aria-label":l(He),children:le.map(n=>r(V,{content:l(n.label),className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":o.value===n.value,"aria-label":l(n.label),onClick:()=>t(n.value),children:r("span",{className:"sf-gallery-pic",children:wo(n.weights).map((i,a)=>r("i",{style:{gridColumn:`span ${i}`}},a))})})},n.value))})})}}}function wo(e){if(!e)return[3,4];const t=e.reduce((o,n)=>o+n,0);return e.map(o=>Math.round(o/t*12))}function yi(){return N(Rn,r(ye,{}),ke,ke[0].value)}function Ei(){return G(vn,r(Ft,{}),Be,Ln,1,Be)}function Ti(e){const t=de(yn,to("`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)."),En(e),Pe(e,void 0));return{type:"custom",render:o=>t.render({...o,value:Pe(e,o.value),onChange:n=>o.onChange(n)})}}function Ri(e,t,o,n,i,a){return{type:"custom",render:({value:s,onChange:c})=>r(h,{label:l(e),icon:r(Re,{noun:a}),action:r(x,{words:b()?.panel,label:l(e),changed:!jn(s),detail:l("the Text style in Site styles"),onReset:()=>c(Yn),defaultAction:{onPress:()=>c(Vn),title:l("Keep this section's own built-in size"),icon:r(mt,{})}}),children:O({min:t,max:o,step:n,value:typeof s=="number"?s:i,suffix:"px",ariaLabel:e,onChange:c})})}}function vi(){return{_gCellWidth:I("Cell width"),gridSpan:N("Positions",r(Ie,{}),[{label:"Auto",value:""},...Array.from({length:rt},(e,t)=>({label:t===0?"1 position":`${t+1} positions`,value:String(t+1)}))],"")}}function J(){let e=null;try{e=F(t=>t).selectedItem}catch{e=null}return e?.props??{}}function Po({min:e,max:t,step:o,px:n,label:i,onChange:a,desktopKey:s,fallback:c}){const u=J()[s],p=ie(void 0,u,c);return r(R,{children:O({min:e,max:t,step:o,value:ie(n,u,c),readout:!1,ariaLabel:i,notch:p,onChange:a})})}function ko({label:e,desktopKey:t,fallback:o,changed:n=!1,onReset:i=()=>{}}){const a=J()[t],s=ie(void 0,a,o);return r(x,{words:b()?.panel,label:l(e),changed:n,detail:l("{value} on desktop",{value:`${s}px`}),onReset:i})}function Do(e){return K(e.label,{min:e.min,max:e.max,step:e.step,unsetLabel:"Follows Desktop",unsetMark:r(ko,{label:e.label,desktopKey:e.desktopKey,fallback:e.fallback}),restTrack:t=>r(Po,{...t,desktopKey:e.desktopKey,fallback:e.fallback})})}const Bo={Top:"Padding top",Bottom:"Padding bottom",Left:"Padding left",Right:"Padding right"};function Li(e={}){const t=e.keys?.top??"sectionPaddingTop",o=e.keys?.bottom??"sectionPaddingBottom",n=e.group!==!1,i=S=>n?S:Bo[S],a=S=>G(i("Top"),r(At,{}),_.min,_.max,_.step,S,"px"),s=(S,X,E,Q=_)=>L("mobile",Do({label:i(S),desktopKey:X,min:Q.min,max:Q.max,step:Q.step,fallback:E})),c=e.top??_.min,u=e.bottom??_.min,p="sectionPaddingLeft",m="sectionPaddingRight",d=e.sideBounds??_,f=e.side??d.min,g=e.sidePhone??f,C=e.phone===!0,y=S=>C?L("desktop",S):S;return U({...n?{_gSpacing:I("Padding")}:{},[t]:y(a(c)),...C?{[Y(t)]:s("Top",t,c)}:{},...e.only==="top"?{}:{[o]:y(G(i("Bottom"),r(Lt,{}),_.min,_.max,_.step,u,"px")),...C?{[Y(o)]:s("Bottom",o,u)}:{}},...e.sides?{[p]:y(G(i("Left"),r(Nt,{}),d.min,d.max,d.step,f,"px")),...C?{[Y(p)]:s("Left",p,g,d)}:{},[m]:y(G(i("Right"),r(Ot,{}),d.min,d.max,d.step,f,"px")),...C?{[Y(m)]:s("Right",m,g,d)}:{}}:{}})}const Ho={contained:"Contained",page:"Page",full:"Full"},Z="Width";function Ni(e,t=qn,o=!0){const n=t.map(i=>({label:Jn[i]??Ho[i],value:i}));return U({...o?{_gWidth:I(Z)}:{},widthMode:{type:"custom",render:({onChange:i,field:a})=>r(h,{label:l(Z),icon:r(Mt,{}),action:o?r(lo,{inherited:a?.inherited??!1,onReset:()=>i(Zn),label:Z}):void 0,children:ue({options:n,value:a?.currentValue||e,onChange:i,ariaLabel:Z})})}})}function Oi(){const e=n=>({type:"custom",render:({value:i,onChange:a})=>T("div",{className:"sf-field",children:[n?T("div",{className:"sf-field-head",children:[r("span",{className:"sf-field-label sf-field-label--inline",children:W}),n(a)]}):null,r("div",{children:ue({options:[{label:"Auto",value:"auto"},{label:"Fixed",value:"fixed"},{label:"Screen",value:"screen"}],value:["auto","fixed","screen"].includes(i)?i:"auto",onChange:a,ariaLabel:W})})]})}),t=()=>({type:"custom",render:({value:n,onChange:i,field:a})=>{const s=a?.unit==="%"?"%":"px",c=s==="%"?_n:In;return r("div",{className:"sf-field",children:O({min:c.min,max:c.max,step:c.step,value:typeof n=="number"?n:c.fallback,suffix:s,ariaLabel:W,onChange:i})})}}),o=()=>de("Unit",r(Ee,{}),[{label:"px",value:"px"},{label:"%",value:"%"}],"px");return U({_gHeight:I(W),sectionHeightMode:L("desktop",e()),sectionHeightValue:L("desktop",t()),sectionHeightUnit:L("desktop",o()),sectionHeightModePhone:L("mobile",e(n=>r(Go,{onClear:()=>n(void 0)}))),sectionHeightValuePhone:L("mobile",t()),sectionHeightUnitPhone:L("mobile",o())})}function Go({onClear:e}){const t=J(),o=Cn(t),n=Sn(t),i=l("{value} on desktop",{value:n.mode==="auto"?l("Auto"):`${n.value}${n.unit}`});return r(x,{words:b()?.panel,label:l(W),changed:o,detail:i,onReset:e})}function Ai(){return{_gAnchor:I("Anchor"),anchor:fo("Anchor name","e.g. about",co)}}function Fi(e,t,o){return{type:"custom",render:({value:n,onChange:i,id:a,name:s})=>{const c=`${a??s??e}-datetime`,u=Date.parse(typeof n=="string"?n:"");return r(h,{label:l(e),icon:t,htmlFor:c,hint:o===void 0?void 0:l(o),children:r(tn,{id:c,value:Number.isFinite(u)?new Date(u):null,onChange:p=>i(p?p.toISOString():"")})})}}}function A(e,t,o){return{type:"custom",render:({value:n,onChange:i,id:a,name:s})=>{const c=typeof n=="boolean"?n:t,u=`${a??s??e}-label`;return r(h,{label:l(e),labelId:u,icon:o,action:r(Jt,{checked:c,onChange:i,ariaLabelledBy:u})})}}}function wi(){return{type:"custom",render:({value:e,onChange:t,id:o,name:n})=>{const i=`${String(o??n??"pageBackground")}-colour`;return r(h,{label:l("Background"),icon:r(Te,{}),htmlFor:i,action:r(Ae,{id:i,label:"Background",value:Ut(e),onChange:t})})}}}function Pi(e,t){return{type:"custom",render:({value:o,onChange:n,id:i})=>{const a=typeof o=="boolean"?o:t,s=`${i??e}-checkbox`;return r(h,{label:l(e),htmlFor:s,className:"sf-checkbox",action:r(en,{id:s,checked:a,onChange:n})})}}}function ki(e,t){return{type:"custom",render:({value:o,onChange:n})=>r(h,{label:l(e),action:Ae({value:o||t,onChange:n,label:e})})}}const Mo=[{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 je({label:e,value:t,onChange:o,points:n=Mo}){const i=n.map(a=>({...a,label:l(a.label),...a.title?{title:l(a.title)}:null}));return r(jt,{label:l(e),value:t,points:i,onChange:o})}function Di(e,t=Oe,o="mediaImage"){return{type:"custom",render:({value:n,onChange:i})=>r("div",{className:"sf-focal-row",children:r(Wo,{label:e,value:n||t,onChange:i,imageProp:o})})}}function Wo({label:e,value:t,onChange:o,imageProp:n}){const{selectedItem:i}=F(s=>s),a=i?.props?.[n];return r(fn,{label:e,value:t,onChange:o,image:typeof a=="string"?a:void 0})}const Uo=Ce([]);function Bi(e,{stacking:t,fallback:o=st}){return{type:"custom",render:({value:n,onChange:i})=>{const a=at.includes(n)?n:o;return t?r(Ko,{label:e,value:a,onChange:i}):qe({label:e,value:a,onChange:i,points:Uo})}}}function Ko({label:e,value:t,onChange:o}){const{appState:n,selectedItem:i}=F(c=>c),a=i?.props?.id?String(i.props.id):void 0,s=a?lt(n?.data,a):[];return qe({label:e,value:t,onChange:o,points:Ce(s,a)})}function qe({label:e,value:t,onChange:o,points:n}){const i=n.find(a=>a.disabled);return r(h,{label:l(e),icon:r(wt,{}),hint:i?.title?l(i.title):void 0,children:je({label:e,value:ct(t),onChange:o,points:n})})}const Hi={top:r(St,{}),right:r(Ct,{}),bottom:r(bt,{}),left:r(xt,{})};function Gi(e,t,o,n,i,a){const s=m=>t.find(d=>d.value===m),c=m=>({value:m,label:"",disabled:!0,title:n}),u=m=>{const d=t.find(g=>g.cell===m);if(!d)return c(`missing-${m}`);const f=a?.[m];return f?{value:d.value,label:d.label,icon:f}:{value:d.value,label:d.label}},p=[c("corner-top-left"),u("top"),c("corner-top-right"),u("left"),c("centre"),u("right"),c("corner-bottom-left"),u("bottom"),c("corner-bottom-right")];return{type:"custom",render:({value:m,onChange:d})=>{const f=t.some(g=>g.value===m)?m:o;return r(h,{label:l(e),icon:i,value:s(f)?.label?l(s(f).label):"",children:je({label:e,value:f,onChange:d,points:p})})}}}const Xo="\0note";function N(e,t,o,n,i){return{type:"custom",options:o,fallback:n,...i?{note:i}:{},render:({value:a,onChange:s,field:c})=>{const u=c.options??o,p=c.fallback??n,m=u.some(d=>d.value===a)?a:p;return r(h,{label:l(e),icon:q(t),children:r(Zt,{value:m,ariaLabel:l(e),onChange:s,options:[...i?[{label:l(i),value:Xo,disabled:!0}]:[],...u.map(d=>({label:l(d.label),value:d.value}))]})})}}}function Mi(e,t,o){return{type:"custom",options:t,render:({value:n,onChange:i,field:a})=>r(hn,{label:e,options:(a.options??t).map(s=>({...s,label:l(s.label)})),value:Array.isArray(n)?n:[],onChange:i,...o?{emptyLabel:l(o)}:{}})}}function Wi(e,t,o,n){return{type:"custom",options:t,fallback:o,render:({value:i,onChange:a,field:s})=>r(bn,{label:e,options:(s.options??t).map(c=>({...c,label:l(c.label)})),fallback:s.fallback??o,value:i,onChange:a,placeholder:n===void 0?void 0:l(n)})}}function Ui(e,t={}){return{type:"custom",render:({value:o,onChange:n})=>{const i={value:o,onChange:n,...t};return r(e,{...i})}}}function ue({options:e,value:t,onChange:o,ariaLabel:n,disabled:i=!1}){return r(qt,{options:e.map(a=>({id:a.value,label:l(a.label),title:a.title===void 0?void 0:l(a.title)})),value:t,onChange:o,ariaLabel:l(n),disabled:i})}const Ki=[{label:"Image",value:"image"},{label:"Video",value:"video"}];function de(e,t,o,n){const i=o.map(a=>typeof a=="string"?{label:a,value:a}:a);return{type:"custom",render:({value:a,onChange:s,field:c})=>r(h,{label:l(e),icon:q(t),children:ue({options:i,value:i.some(u=>u.value===a)?a:a||c?.currentValue||n,onChange:s,ariaLabel:e})})}}function Xi(e,t,o){return{type:"custom",[ge]:!0,render:({value:n,onChange:i})=>r(mn,{value:n||"",onChange:i,label:e,accept:t,placeholder:o})}}const $i={HeroSingle:["imageFocal"],ContactLocations:["locations[].photo"],ProcessSteps:["steps[].image"]};function zi({value:e,onChange:t,label:o}){const n=e||{},i=!!n.pending,a=i?"var(--fg-dim, #888)":n.ok?"#1d9e75":"#d85a30",s=(c,u)=>t({...n,[c]:u===""?void 0:Number(u)});return T(h,{label:l(o),icon:r(oe,{}),children:[r("button",{type:"button",disabled:i,onClick:()=>t({...n,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?l("Finding…"):l("Find coordinates")}),n.status&&r("div",{style:{marginTop:6,fontSize:12,lineHeight:1.4,color:a},children:l(n.status)}),r("div",{style:{marginTop:6,fontSize:11,color:"var(--fg-dim, #999)"},children:l("Coordinates from OpenStreetMap")}),r("button",{type:"button",onClick:()=>t({...n,manual:!n.manual}),style:{marginTop:8,padding:0,border:"none",background:"none",font:"inherit",fontSize:12,color:"var(--sf-accent, #2563eb)",cursor:"pointer",textDecoration:"underline"},children:n.manual?l("Hide manual coordinates"):l("Enter coordinates manually")}),n.manual&&T("div",{style:{marginTop:8,display:"grid",gap:8},children:[r(h,{label:l("Latitude"),icon:r(oe,{}),children:r("input",{type:"number",step:"any",placeholder:l("e.g. {example}",{example:"34.0990198"}),value:typeof n.lat=="number"?n.lat:"",onChange:c=>s("lat",c.target.value)})}),r(h,{label:l("Longitude"),icon:r(oe,{}),children:r("input",{type:"number",step:"any",placeholder:l("e.g. {example}",{example:"-117.9842833"}),value:typeof n.lng=="number"?n.lng:"",onChange:c=>s("lng",c.target.value)})})]})]})}function $o(e,t){return t===null||t<0||t>=e.length?"":e[t]?.text??""}function zo(e,t,o){const n=e.map(i=>({text:i?.text??""}));return t===null||t<0||t>=e.length?n:n.map((i,a)=>a===t?{text:o}:i)}function Vi(e,t){return e===null?null:t>e?e:null}function Vo(e,t,o){if(o===null||o>=t.length)return null;for(let n=0;n<o;n+=1)if(e[n]!==t[n])return null;return e[o]!==t[o]&&t.includes(e[o])||e[o]!==t[o]&&t.length!==e.length?null:o}const Yi={label:"Ticker items",icon:r(vt,{})};function ji(e,t,o,n){return{type:"custom",[v]:{control:"textList",label:e,placeholder:o,itemKey:"text",rendering:n},render:({value:i,onChange:a})=>r(Yo,{label:e,icon:q(t),items:Array.isArray(i)?i:[],placeholder:o,onChange:a,markup:n==="markup"})}}function Yo({label:e,icon:t,items:o,placeholder:n,onChange:i,markup:a=!1}){const s=ee(null),[c,u]=pe(null),p=d=>d.map(f=>({text:f?.text??""})),m=d=>{const f=Vo(o,d,c);f===null&&(s.current=null),u(f),i(p(d))};return r(Qt,{label:l(e),icon:t,noun:l("item"),items:o,onChange:m,newItem:()=>({text:""}),open:null,onOpen:()=>{},renderItem:()=>null,above:a?r(Fe,{target:s,value:$o(o,c),onChange:d=>i(zo(o,c??-1,d)),disabled:c===null,label:c===null?l("Formatting — click a row first"):l("Formatting — row {n}",{n:c+1})}):void 0,renderRow:(d,f,g)=>r("input",{type:"text",className:a&&c===f?"sf-list-marking":void 0,value:d?.text??"",placeholder:l(n),"aria-label":l("{label} {n}",{label:l(e),n:f+1}),onChange:C=>g({text:C.target.value}),onFocus:C=>{s.current=C.currentTarget,u(f)}})})}function qi(e,t){const o=`${e.label} — row ${t+1}`;return H({control:"plainText",label:o,placeholder:e.placeholder,offPage:e.offPage},{type:"custom",render:({value:n,onChange:i})=>r(B,{value:n,onChange:i,label:l("{label} — row {n}",{label:l(e.label),n:t+1}),placeholder:e.placeholder,hideable:!1,markup:e.rendering==="markup"})})}function Ji(e){return{_gCards:I("Cards"),coverIndex:N("Cover image",r(Tt,{}),un,String(dn),e?.coverHint??"A card's opening picture — a card pinned to a finish keeps its own."),imageBackground:xo("Image background",kn),cardImage:jo(),spinOnHover:A("Rotate on hover",e?.spinDefault??!0,r(kt,{}))}}function Zi(){return{outline:N("Card outline",r(Dt,{}),an,cn),indexBadge:N("Card number",r(Ee,{}),ln,sn),showBadge:A("Product badge",!0,r(Re,{noun:"tag"}))}}function Qi(e){const t=e?.bottomDefault??!0;return{_gShowOnCard:I("Show on a card"),showCardPrice:A("Price",!0,r(It,{})),showCardFinishes:A("Finish swatches",!0,r(_t,{})),showCardSizes:A("Sizes",t,r(Pt,{})),showCardBuy:A("Buy button",t,r(ht,{})),showCardPage:A("Page button",t,r(Te,{}))}}function jo(){return K("Card image",{min:M,max:$,step:tt,hint:"Rounds the picture. The card's own corner is in Site styles."})}function el(){return K(ot,{min:M,max:$,step:nt,unsetLabel:"Square",hint:"Rounds the picture. Left alone it stays square."})}function tl(){return{type:"custom",render:({value:e,onChange:t})=>r(qo,{value:typeof e=="string"?e:"",onChange:t})}}function qo({value:e,onChange:t}){const[o,n]=pe(null),i=xe.filter(s=>o===null||w[s].across===o),a=e&&e in w?w[e]:null;return T(R,{children:[r(h,{label:l("Photos in a row"),icon:r(gt,{}),children:T("div",{className:"sf-gallery-filter",children:[r("button",{type:"button","aria-pressed":o===null,onClick:()=>n(null),children:l("All")}),it.map(s=>r("button",{type:"button","aria-pressed":o===s,onClick:()=>n(s),children:s},s))]})}),r(h,{label:l("Layout"),icon:r(yt,{}),value:a?l(a.label):l("Not chosen"),hint:l("{n} of {total} layouts",{n:i.length,total:xe.length}),children:r("div",{className:"sf-gallery-layouts",children:i.map(s=>r(V,{content:l(w[s].label),className:"sf-tile-tip",children:r("button",{type:"button","aria-pressed":e===s,"aria-label":l(w[s].label),onClick:()=>t(e===s?"":s),children:r("span",{className:"sf-gallery-pic",children:w[s].desktop.map(([c,u],p)=>r("i",{style:{gridColumn:`span ${c}`,gridRow:`span ${u}`}},p))})})},s))})})]})}export{co as ANCHOR_HINT,ti as BOUND_TO_POST_NOTE,ai as BUCKET_ICONS,$i as CUSTOM_FIELD_MEDIA,zi as CoordsField,Hi as EDGE_ARROWS,Oe as FOCAL_DEFAULT,Mo as FOCAL_POINTS,te as FOLD_FIELD_MARKER,je as FocalPicker,bo as GroupLabel,so as HIGHLIGHT_HINT,B as HidableTextField,he as LINK_FIELD_MARKER,qr as Label,ge as MEDIA_FIELD_MARKER,Ki as MEDIA_TYPE_OPTIONS,go as PanelNoteLine,qe as PlacementGridView,be as SCAFFOLD_FIELD_MARKER,il as SCALAR_TEXT_CONTROLS,Ve as SECTION_BLEEDS_HINT,mo as SectionHeading,ue as Segmented,io as SiteGapDefaultReset,O as Slider,$e as Swatches,rl as TEXT_CONTROL_KINDS,v as TEXT_FIELD_MARKER,Yi as TICKER_ITEMS_ROW,Yo as TextListField,lo as WidthDefaultReset,Vo as aimAfterListChange,Ai as anchorFields,D as backTo,fi as backgroundField,Si as boxAlignField,yi as boxBlockSpacingField,Ci as boxJustifyField,Ei as boxPhoneRowField,_i as boxShareField,Ii as boxWrapField,pi as bucketHeader,Ao as cardCornerSidesField,Lo as cardCornersField,xo as cardImageBackgroundField,jo as cardImageField,Ji as cardMediaFields,xi as cardShapeFields,Qi as cardShowFields,Zi as cardStyleFields,vi as cellWidthFields,Pi as checkbox,ki as colorInput,ri as copyText,Fi as dateTime,Ti as directionField,Gi as edgePad,si as entriesHiddenForTab,Di as focalPicker,Vi as focusAfterRemove,ne as foldMetaOf,tl as galleryLayoutField,hi as gapField,I as group,Oi as heightFields,me as hidableText,po as hintIsWhileTyping,q as iconOf,el as imageCornersField,di as isBucketHeader,no as isNoGlyph,ii as linkField,Mi as multiSelect,to as noGlyph,wi as pageBackgroundField,ci as panelNote,Do as phoneOverrideField,Bi as placementField,fo as plainText,li as plainTextarea,K as pxField,fe as readHidable,$o as rowText,Wi as searchSelect,ui as section,bi as sectionAnimationFields,Co as sectionCornerSidesField,Io as sectionCornersField,gi as sectionShapeFields,mi as sectionThemeFields,de as segmented,N as select,zo as setRowText,Ri as sizeField,G as slider,Ui as sourceField,Li as spacingFields,ni as text,Qe as textFieldIdentifier,Qr as textFieldOffPage,ji as textList,qi as textListRowField,oi as textarea,A as toggle,Xi as upload,oo as usePageWidthDetail,ro as useSiteGapDetail,Ni as widthField,ei as withIdentifier,Zr as withOffPage,Jr as withScaffold};
@@ -1 +1 @@
1
- function r(t,o){const n=t.props;if(t.type==="FooterMenu"){const e=n.menu;return n.heading||e?.name||"Menu"}if(t.type==="FooterText"){const e=typeof n.text=="string"?n.text.trim():"";return e?e.length>28?`${e.slice(0,28)}…`:e:"Text"}return t.type==="FooterEmailSignup"?n.heading||"Email signup":o(t.type)}export{r as footerBlockRowName};
1
+ import{say as o}from"../editor-words.js";function u(e,r){const n=e.props;if(e.type==="FooterMenu"){const t=n.menu;return n.heading||t?.name||o("Menu")}if(e.type==="FooterText"){const t=typeof n.text=="string"?n.text.trim():"";return t?t.length>28?`${t.slice(0,28)}…`:t:o("Text")}return e.type==="FooterEmailSignup"?n.heading||o("Email signup"):r(e.type)}export{u as footerBlockRowName};
@@ -1 +1 @@
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
+ import{jsx as i}from"react/jsx-runtime";import{ListIcon as T,PaddingTopIcon as w}from"efficient-easel/icons";import R from"../../components/WidthFollowField.js";import{say as s}from"../editor-words.js";import{PRODUCT_RECORD_TYPE as f,TEMPLATE_RECORD_TYPE_PROP as a,declaredRecordType as h,recordTypes as c,recordTypesRevision as p}from"../content/record-types.js";import{pageBackgroundField as E,plainText as g,select as u}from"./controls.js";import{isEditorOnDynamicPage as P}from"./editor-page-context.js";import{DEFAULT_TOP_SPACE as _}from"./header-clearance.js";function y(){return{type:"custom",render:({value:e,onChange:n})=>i(R,{value:e==="full"?"full":e==="content"?"content":void 0,resolved:"content",followsLabel:s("Follows the site"),hint:s("Whether this page sits on the site's content column, or runs edge to edge."),onChange:o=>n(o)})}}const O=[{label:"Auto",value:"auto"},{label:"Shared",value:"shared"},{label:"Its own",value:"own"}],I={title:g("Page Title"),pageBackground:E(),topSpace:u("Top space",i(w,{}),O,_),widthChoice:y()},x="Record type",l=new Map;let d=-1;function v(e){d!==p()&&(l.clear(),d=p());const n=c(),o=n.some(r=>r.key===e)?"":e;let t=l.get(o);return t||(t=u(x,i(T,{}),[...n.map(r=>({label:r.label,value:r.key})),...o?[{label:o,value:o}]:[]],f),l.set(o,t)),t}const m=new WeakMap;function W(e,n){if(!P()||c().length<2||a in e)return e;const o=v(h(n)),t=m.get(e);if(t&&t.row===o)return t.fields;const r={[a]:o,...e};return m.set(e,{row:o,fields:r}),r}export{I as GENERAL_ROOT_FIELDS,x as RECORD_TYPE_LABEL,O as TOP_SPACE_OPTIONS,y as pageWidthField,W as withRecordTypeRow};
@@ -1 +1 @@
1
- import{typedHex as f}from"efficient-easel/pick";import{normalizeTheme as h}from"../theme.js";function l(a){const n=new Set,r=[];return h(a).themes.forEach((o,t)=>{const m=[[`Theme ${t+1} main color`,o.accent],[`Theme ${t+1} text color`,o.text],[`Theme ${t+1} background`,o.background]];for(const[s,c]of m){const e=c?f(c):null;!e||n.has(e)||(n.add(e),r.push({name:s,value:e}))}}),r}export{l as themeSwatches};
1
+ import{say as t}from"../editor-words.js";import{typedHex as h}from"efficient-easel/pick";import{normalizeTheme as u}from"../theme.js";function p(m){const r=new Set,c=[];return u(m).themes.forEach((o,n)=>{const s=[[t("Theme {n} main color",{n:n+1}),o.accent],[t("Theme {n} text color",{n:n+1}),o.text],[t("Theme {n} background",{n:n+1}),o.background]];for(const[f,a]of s){const e=a?h(a):null;!e||r.has(e)||(r.add(e),c.push({name:f,value:e}))}}),c}export{p as themeSwatches};
@@ -0,0 +1,26 @@
1
+ import type * as TS from "typescript";
2
+ import { type RuleReport, type SourceFile } from "./rule.js";
3
+ export declare const BUILDER_WORDS: Readonly<Record<string, readonly number[]>>;
4
+ export type EditorWordsDataFile = {
5
+ readonly path: string;
6
+ readonly keys: readonly string[] | "*";
7
+ };
8
+ export type EditorWordsOptions = {
9
+ readonly dataFiles?: readonly EditorWordsDataFile[];
10
+ readonly skip?: readonly string[];
11
+ readonly known?: ReadonlySet<string>;
12
+ };
13
+ export declare function isPhrase(text: string): boolean;
14
+ export declare function editorPhrases(ts: typeof TS, files: readonly SourceFile[], options?: EditorWordsOptions): Map<string, string[]>;
15
+ export type EditorWordsCatalogueShape = {
16
+ readonly constant: string;
17
+ readonly phraseType: string;
18
+ readonly header: readonly string[];
19
+ };
20
+ export declare function editorWordsCatalogueText(phrases: Iterable<string>, shape: EditorWordsCatalogueShape): string;
21
+ export declare function editorWordsCatalogue(ts: typeof TS, files: readonly SourceFile[], options: EditorWordsOptions & {
22
+ readonly catalogue: SourceFile | null;
23
+ readonly shape: EditorWordsCatalogueShape;
24
+ readonly floor: number;
25
+ readonly write: string;
26
+ }): RuleReport;
@@ -0,0 +1,3 @@
1
+ import{ruleChecks as A}from"./rule.js";const E={text:[0,1,2],textarea:[0,1,2],plainText:[0,1,2],copyText:[0,1,2],plainTextarea:[0,1,2],linkField:[0],textList:[0,2],upload:[0,2],toggle:[0],checkbox:[0],select:[0,4],searchSelect:[0,3],segmented:[0],multiSelect:[0,2],slider:[0],colorInput:[0],focalPicker:[0],sizeField:[0],backgroundField:[0],cardImageBackgroundField:[0],placementField:[0],pxField:[0],dateTime:[0,2],edgePad:[0,3],blockSourceField:[0,1],phPrev:[1],phHide:[1],phHideDefault:[1],group:[0],section:[0],panelNote:[0]},b=new Set(["value","render","fields","type","arrayFields","icon"]),N=/(^|_)(PH|LABELS?|HINTS?|NOTES?|TITLES?|SWATCH_NAMES|GROUP|REASON|ROWS|PANELS|TABS|LINES)$/,O=new Set(["key","value","id","type","href","slug","kind","cell","set","icon","token","unit","path","url","src","className","variant","mode","side","align","role"]),$=new Set(["hint","coverHint","unsetLabel","emptyLabel","addLabel"]),_=new Set(["say","sayCount"]);function C(t){return/\p{L}/u.test(t)&&t.trim()===t&&t.length>0&&!/^[a-z0-9]+(?:-[a-z0-9]+)+$/.test(t)}const z=/(?:Key|Id|Slug|Href|Url|ClassName)$/;function L(t,p,s={}){const a=new Map,k=new Set(s.skip??[]),S=new Map((s.dataFiles??[]).map(e=>[e.path,e.keys])),u=(e,l)=>{if(!C(e))return;let d=a.get(e);d||a.set(e,d=new Set),d.add(l)},f=e=>e&&(t.isStringLiteral(e)||t.isNoSubstitutionTemplateLiteral(e))?e.text:null,o=e=>{if(!e)return[];const l=f(e);return l!==null?[l]:t.isParenthesizedExpression(e)?o(e.expression):t.isConditionalExpression(e)?[...o(e.whenTrue),...o(e.whenFalse)]:t.isBinaryExpression(e)&&(e.operatorToken.kind===t.SyntaxKind.QuestionQuestionToken||e.operatorToken.kind===t.SyntaxKind.BarBarToken)?[...o(e.left),...o(e.right)]:[]},y=e=>{const l=e.expression;return t.isIdentifier(l)?l.text:t.isPropertyAccessExpression(l)?l.name.text:null},g=e=>e.name&&(t.isIdentifier(e.name)||t.isStringLiteral(e.name))?e.name.text:null;for(const e of p){if(!/\.tsx?$/.test(e.path)||k.has(e.path))continue;const l=S.get(e.path),d=t.createSourceFile(e.path,e.text,t.ScriptTarget.Latest,!0,e.path.endsWith(".tsx")?t.ScriptKind.TSX:t.ScriptKind.TS),T=n=>{if(t.isCallExpression(n)){const r=y(n);if(r&&_.has(r))for(const c of n.arguments){const i=f(c);i!==null&&u(i,e.path)}else if(r&&t.isIdentifier(n.expression)&&Object.prototype.hasOwnProperty.call(E,r)){for(const c of E[r])for(const i of o(n.arguments[c]))u(i,e.path);if(r==="segmented"){const c=n.arguments[2];if(c&&t.isArrayLiteralExpression(c))for(const i of c.elements){const h=f(i);h!==null&&u(h,e.path)}}}}else if(t.isJsxAttribute(n)&&n.name.getText(d)==="label"&&n.initializer&&t.isStringLiteral(n.initializer)&&/^[A-Z]/.test(n.parent.parent.tagName.getText(d).split(".").pop()??""))u(n.initializer.text,e.path);else if(t.isObjectLiteralExpression(n)){const r=n.properties.filter(t.isPropertyAssignment),c=r.find(i=>g(i)==="label");if(c&&r.some(i=>b.has(g(i)??""))){const i=f(c.initializer);i!==null&&u(i,e.path)}for(const i of r){const h=g(i);if(h!==null&&$.has(h))for(const x of o(i.initializer))u(x,e.path)}if(l)for(const i of r){const h=g(i);if(h!==null&&(l==="*"||l.includes(h))){const x=f(i.initializer);x!==null&&u(x,e.path)}}}else if(t.isVariableDeclaration(n)&&t.isIdentifier(n.name)&&N.test(n.name.text)&&n.initializer&&!/CSSProperties|Style\b/.test(n.type?.getText(d)??"")){const r=f(n.initializer);r!==null&&!/^[a-z0-9_]+$/.test(r)&&u(r,e.path);const c=i=>{const h=t.isPropertyAssignment(i)?g(i)??"":"";if(t.isPropertyAssignment(i)&&!O.has(h)&&!z.test(h)){const x=f(i.initializer);x!==null&&u(x,e.path)}t.forEachChild(i,c)};c(n.initializer)}t.forEachChild(n,T)};T(d)}const m=new Map;for(const e of[...a.keys()].sort(w))s.known?.has(e)||m.set(e,[...a.get(e)].sort());return m}function w(t,p){return t<p?-1:t>p?1:0}function P(t,p){return["/**",...p.header.map(a=>a?` * ${a}`:" *")," */",`export const ${p.constant} = {`,...[...t].map(a=>` ${JSON.stringify(a)}: ${JSON.stringify(a)},`),"} as const;","",`/** Every phrase of {@link ${p.constant}}: what a host's words are keyed by. */`,`export type ${p.phraseType} = keyof typeof ${p.constant};`,""].join(`
2
+ `)}function I(t,p,s){const{check:a,report:k}=A("editor words");{const f=[{path:"fixture.tsx",text:['const a = say("Delete {name}", { name });','const b = sayCount("{n} page", "{n} pages", n);','const c = text("Heading", "Main heading", "A hint");','const d = select("Align", icon, [{ label: "Left", value: "left" }], "left", "A note");','const e = segmented("Size", icon, ["Small", "Large"], "Small");','const SERIES_PH = { headTitle: "Section heading", link: "#" };','export const CORNER_SIDES_LABEL = "Corner sides";','const VIEW_TIER_LABEL = { desktop: "Desktop" };',"const DEFAULT_LABEL_KEY = 12;",'const FOCUS_HINT: CSSProperties = { display: "flex" };','const LAYOUT_TABS = "tabs";','const TEMPLATE_GROUP = { group: "Template pages", groupKey: "template" };','const a4 = <MenuLink label="text-fg" />;','const THEME_COLOUR_ROWS = [{ key: "fg", label: "Text color" }, { group: "Borders" }];','const a1 = <GroupLabel label="Wording" />;','const a2 = <input label="raw" />;','const a3 = say("Already listed");','const f = toggle("Show", false, "not-a-word");','const i = pxField("Corners", { min: 0, unsetLabel: on ? "Square" : "Round", hint: opts?.hint ?? "Rounds it." });','const g = { label: "Content", href: "/" };',"const h = say(`${x} colour`);"].join(`
3
+ `)},{path:"names.ts",text:'export const N = [{ key: "openers", title: "Hero & intros", sections: [{ type: "Hero", label: "Hero Slideshow" }] }];'},{path:"block.tsx",text:'export const B = { label: "Banner", fields: {}, defaultProps: { cta: { label: "Shop now", href: "/" } } };'}],o=[...L(t,f,{dataFiles:[{path:"names.ts",keys:["title"]}],known:new Set(["Already listed"])}).keys()],y=["A hint","A note","Align","Banner","Borders","Corner sides","Corners","Round","Rounds it.","Square","Template pages","Text color","Wording","Desktop","Delete {name}","Heading","Hero & intros","Hero Slideshow","Large","Left","Main heading","Section heading","Show","Size","Small","{n} page","{n} pages"].sort(w);a("the reader reads every shape on a fixture, and no value, link or built phrase",JSON.stringify(o)===JSON.stringify(y),`read ${JSON.stringify(o)}`)}const S=L(t,p,s);a(`the source says at least ${s.floor} phrases`,S.size>=s.floor,`read ${S.size}: the reader broke, or the editor stopped saying its words through it`);const u=P(S.keys(),s.shape);if(!s.catalogue)a("the catalogue exists",!1,`run ${s.write}`);else{const f=s.catalogue.text===u;let o;if(!f){const y=new Set([...s.catalogue.text.matchAll(/^ {2}("(?:[^"\\]|\\.)*"): /gm)].map(e=>JSON.parse(e[1]))),g=[...S.keys()].filter(e=>!y.has(e)),m=[...y].filter(e=>!S.has(e));o=`${s.catalogue.path} is not what the source says — run ${s.write}. Missing ${g.length}${g.length?` (${g.slice(0,5).map(e=>JSON.stringify(e)).join(", ")}…)`:""}; no longer said ${m.length}${m.length?` (${m.slice(0,5).map(e=>JSON.stringify(e)).join(", ")}…)`:""}.`}a(`${s.catalogue.path} lists exactly the ${S.size} phrases the source says`,f,o)}return k()}export{E as BUILDER_WORDS,L as editorPhrases,I as editorWordsCatalogue,P as editorWordsCatalogueText,C as isPhrase};
@@ -1,6 +1,6 @@
1
1
  import{ruleChecks as k}from"./rule.js";import{blockSource as E,registryFiles as S}from"./support/registry-source.js";const x="lib/puck/controls.tsx",j=["slider","select","segmented","textList"];function y(c){return/icon=\{<([A-Z][A-Za-z0-9]*Icon)\s*\/>\}/.exec(c)?.[1]??/<([A-Z][A-Za-z0-9]*Icon)\s*\/>/.exec(c)?.[1]??/<FieldGlyph noun="([a-z]+)"/.exec(c)?.[1]??"none"}function I(c){const s=new Map;for(const l of c)l.text.split(`
2
2
  `).forEach((t,p)=>{const a=t.trim();if(!(a.startsWith("//")||a.startsWith("*")||a.startsWith("/*")))for(const h of j){if(new RegExp(`^(export )?function ${h}\\(`).test(a))continue;const d=t.match(new RegExp(`(^|[^.\\w])${h}\\(\\s*"([^"]+)"`));d&&s.set(d[2],[...s.get(d[2])??[],{file:l,line:p+1,builder:h}])}});return s}function R(c){const s=[];for(const l of c)l.text.split(`
3
- `).forEach((t,p)=>{const a=t.match(/<SettingsField\s+label="([^"]+)"/);a&&s.push({file:l.path,line:p+1,label:a[1].trim(),glyph:y(t)})});return s}function W(c,s,l){const{check:t,report:p}=k("mirrored rows agree"),a=l.mirrored??[],h=l.sameWord??[];{const e={path:"fixture.tsx",text:["export function select(label: string) {}",'const a = select("Product", <BoxIcon />, options);','// select("In a comment", <BoxIcon />)','const b = usePreviewParts().select("Not a row");','const c = <SettingsField label="Product" icon={<BoxIcon />}>{x}</SettingsField>;'].join(`
3
+ `).forEach((t,p)=>{const a=t.match(/<SettingsField\s+label=(?:\{say\()?"([^"]+)"/);a&&s.push({file:l.path,line:p+1,label:a[1].trim(),glyph:y(t)})});return s}function W(c,s,l){const{check:t,report:p}=k("mirrored rows agree"),a=l.mirrored??[],h=l.sameWord??[];{const e={path:"fixture.tsx",text:["export function select(label: string) {}",'const a = select("Product", <BoxIcon />, options);','// select("In a comment", <BoxIcon />)','const b = usePreviewParts().select("Not a row");','const c = <SettingsField label="Product" icon={<BoxIcon />}>{x}</SettingsField>;'].join(`
4
4
  `)},o=I([e]),n=R([e]);t("the builder-label reader finds a call, and not its declaration, a comment or another object's method",[...o.keys()].join()==="Product"&&o.get("Product")?.[0].line===2,JSON.stringify([...o.keys()])),t("the row reader finds a hand-drawn row and the glyph it wears",n.length===1&&n[0].label==="Product"&&n[0].glyph==="BoxIcon",JSON.stringify(n))}const d=s.find(e=>e.path===x);for(const e of a){const o=d?new RegExp(`export const ${e.constant} = \\{[\\s\\S]*?\\} as const;`).exec(d.text):null;t(`${e.constant} is declared in ${x}`,o!==null),o&&(t("…and carries the label",/label:\s*"/.test(o[0]),o[0].slice(0,120)),t("…and carries the glyph",/icon:\s*</.test(o[0]),o[0].slice(0,120)));let n=null;try{n=E(c,s,e.declaredIn)}catch{n=null}t(`read the ${e.declaredIn} block`,n!==null,`no block "${e.declaredIn}" among the files handed in`);const r=s.find(i=>i.path===e.drawnIn)?.text??null;t(`read ${e.drawnIn}`,r!==null);for(const[i,$]of[[`the ${e.declaredIn} block`,n],[e.drawnIn,r]])$!==null&&(t(`${i} spreads ${e.constant}`,new RegExp(`${e.constant}\\.(label|icon)`).test($)),t(`…and no longer hard-codes "${e.row}"`,!new RegExp(`"${e.row}"`).test($),`${i} still contains the literal`))}t(`the mirrored pairs were checked (${a.length}, at least ${l.floors.pairs}; an empty sweep proves nothing)`,a.length>=l.floors.pairs);const f=I([...S(s),...d?[d]:[]]),w=s.filter(e=>/^components\/[^/]+\.tsx$/.test(e.path)),u=R(w),g=[],m=[];for(const e of u){if(!f.has(e.label))continue;if(h.includes(e.label)){m.push({at:`${e.file}:${e.line}`,label:e.label,glyph:e.glyph});continue}const o=(f.get(e.label)??[]).map(n=>`${n.builder} @ ${n.file.path}:${n.line}`).join(" · ");g.push(`${e.file}:${e.line} "${e.label}" — also ${o}`)}t(`the builder-label scan read something (${f.size} labels, at least ${l.floors.labels})`,f.size>=l.floors.labels),t(`the component scan read something (${u.length} hand-drawn rows in ${w.length} component files, at least ${l.floors.panelRows})`,u.length>=l.floors.panelRows),t("no NEW hard-coded mirror",g.length===0,`
5
5
  ${g.join(`
6
6
  `)}`);const b=h.filter(e=>!f.has(e));t("no same-word entry has outlived its subject",b.length===0,b.join(" · "));for(const e of h){const o=new Set,n=[];for(const r of m.filter(i=>i.label===e))o.add(r.glyph),n.push(`${r.at} → ${r.glyph}`);for(const r of f.get(e)??[]){const i=y(r.file.text.split(`
@@ -1,2 +1,2 @@
1
1
  import{fontRoleOfClassName as y,FONT_ROLE_LABELS as x}from"../fonts.js";import{isRuleSource as w,ruleChecks as E}from"./rule.js";import{enclosingLiteral as N}from"./heading-ceiling-sweep.js";import{stripComments as b}from"./support/ts-source.js";import{typeScaleGroupOfClassName as u}from"../theme.js";const R=["app/","components/","lib/"],p={"font-display":"heading","font-heading2":"heading2","font-heading3":"heading3","font-body":"body","font-serif":"accent","font-mono":"label"},k={heading:"--font-role-heading",heading2:"--font-role-heading2",heading3:"--font-role-heading3",body:"--font-role-body",accent:"--font-role-accent",label:"--font-role-label"},$=[];function L(m){const n=[],t=new Set;for(const d of m){const c=b(d.text),l=/\bfont-(?:display|body|serif|mono)\b/g;let r;for(;r=l.exec(c);){const i=N(c,r.index);if(!i)continue;const o=c.slice(0,r.index).split(`
2
- `).length,h=`${d.path}:${o}:${i}`;if(t.has(h))continue;t.add(h);const g=i.split(/\s+/).filter(a=>!a.slice(0,a.lastIndexOf(":")+1).includes("&")).map(a=>a.slice(a.lastIndexOf(":")+1)),f=Object.keys(p).filter(a=>g.includes(a));f.length!==0&&n.push({file:d.path,line:o,className:i,utilities:f})}}return n}function I(m,n){const{check:t,report:d}=E("part style naming"),c=m.filter(e=>/\.tsx?$/.test(e.path)&&!w(e.path)&&R.some(s=>e.path.startsWith(s))),l=L(c),r=new Map(m.map(e=>[e.path,e]));t(`read the source (${c.length} .ts/.tsx files)`,c.length>0,"found no source to sweep — this rule is not measuring anything"),t(`the scanner finds face-tagged class lists at all (${l.length}, at least ${n.minSites})`,l.length>=n.minSites);const i=l.filter(e=>u(e.className)!==null),o=l.filter(e=>u(e.className)===null);t(`…both taggings are represented, so neither branch below is untested (${i.length} with a scale token, at least ${n.minWithScale})`,i.length>=n.minWithScale&&i.length>0),t(`…and the face-without-a-size-knob population is real, not an artefact (${o.length}, at least ${n.minWithoutScale})`,o.length>=n.minWithoutScale&&o.length>0,`${o.length} class lists carry a face utility and no matching scale token`);const h=l.filter(e=>y(e.className)!==p[e.utilities[0]]);if(t("every class list in the census reads back as its own utility's role",h.length===0,h.slice(0,5).map(e=>`${e.file}:${e.line} has ${e.utilities[0]} but reads ${y(e.className)}`).join("; ")),n.roleSheet!==void 0){const e=r.get(n.roleSheet),s=Object.values(k).filter(O=>!e||!e.text.includes(O));t(`…and every role named here is a custom property ${n.roleSheet} defines`,!!e&&s.length===0,e?s.join(", "):"the sheet was not read")}const g=Object.values(p).filter(e=>!(e in x));t("every face utility names a role the panel offers",g.length===0,g.join(", "));const f=Object.keys(x).filter(e=>!Object.values(p).includes(e));t("…and the roles no utility can name are exactly the ones decided to have none",f.join()===$.join(),`no utility reaches: [${f}] — expected [${$}]`);const a=o.filter(e=>u(e.className)!==null);t("no class list without a scale token claims a size group",a.length===0,a.slice(0,5).map(e=>`${e.file}:${e.line}`).join("; ")),t("the reported case: a `font-display text-[22px]` heading is Headings, size group none",y("font-display text-[22px] font-medium")==="heading"&&u("font-display text-[22px] font-medium")===null),t("…and genuinely body-tagged copy still reads as the body size group",u("text-[var(--size-body,16px)]")==="body");const S=l.filter(e=>e.utilities.length>1);if(t("every class list names at most one face",S.length===0,S.slice(0,5).map(e=>`${e.file}:${e.line} — ${e.utilities.join(" + ")}`).join("; ")),n.panel!==void 0){const e=r.get(n.panel),s=e?b(e.text):"";t(`read the part panel ${n.panel}`,!!e),t("the box's name comes from the FACE, not from a size group",s.includes("FONT_ROLE_LABELS[face.role]")&&!s.includes("TYPE_GROUP_LABELS[")),t("…a face the page does not draw as its declared role is called Custom",/return\s*"Custom"/.test(s)&&s.includes('kind: "custom"')),t("…and a part no size knob reaches says so under the text box",/sizeGroup === null && \(\s*<p className="es-field-hint sf-hint-keep">Fixed size/.test(s))}if(n.bridge!==void 0){const e=r.get(n.bridge),s=e?b(e.text):"";t(`read the preview's part bridge ${n.bridge}`,!!e),t("the preview publishes BOTH tags, each walked up to its own nearest declarer",s.includes("fontRoleOfClassName")&&s.includes("typeScaleGroupOfClassName")&&s.includes("el.parentElement")),t("…and the element it reads from is one that declares EITHER tag",/partStyleSource\([\s\S]{0,200}fontRoleOfClassName[\s\S]{0,120}typeScaleGroupOfClassName/.test(s))}return d()}export{I as partStyleNaming};
2
+ `).length,h=`${d.path}:${o}:${i}`;if(t.has(h))continue;t.add(h);const g=i.split(/\s+/).filter(a=>!a.slice(0,a.lastIndexOf(":")+1).includes("&")).map(a=>a.slice(a.lastIndexOf(":")+1)),f=Object.keys(p).filter(a=>g.includes(a));f.length!==0&&n.push({file:d.path,line:o,className:i,utilities:f})}}return n}function I(m,n){const{check:t,report:d}=E("part style naming"),c=m.filter(e=>/\.tsx?$/.test(e.path)&&!w(e.path)&&R.some(s=>e.path.startsWith(s))),l=L(c),r=new Map(m.map(e=>[e.path,e]));t(`read the source (${c.length} .ts/.tsx files)`,c.length>0,"found no source to sweep — this rule is not measuring anything"),t(`the scanner finds face-tagged class lists at all (${l.length}, at least ${n.minSites})`,l.length>=n.minSites);const i=l.filter(e=>u(e.className)!==null),o=l.filter(e=>u(e.className)===null);t(`…both taggings are represented, so neither branch below is untested (${i.length} with a scale token, at least ${n.minWithScale})`,i.length>=n.minWithScale&&i.length>0),t(`…and the face-without-a-size-knob population is real, not an artefact (${o.length}, at least ${n.minWithoutScale})`,o.length>=n.minWithoutScale&&o.length>0,`${o.length} class lists carry a face utility and no matching scale token`);const h=l.filter(e=>y(e.className)!==p[e.utilities[0]]);if(t("every class list in the census reads back as its own utility's role",h.length===0,h.slice(0,5).map(e=>`${e.file}:${e.line} has ${e.utilities[0]} but reads ${y(e.className)}`).join("; ")),n.roleSheet!==void 0){const e=r.get(n.roleSheet),s=Object.values(k).filter(O=>!e||!e.text.includes(O));t(`…and every role named here is a custom property ${n.roleSheet} defines`,!!e&&s.length===0,e?s.join(", "):"the sheet was not read")}const g=Object.values(p).filter(e=>!(e in x));t("every face utility names a role the panel offers",g.length===0,g.join(", "));const f=Object.keys(x).filter(e=>!Object.values(p).includes(e));t("…and the roles no utility can name are exactly the ones decided to have none",f.join()===$.join(),`no utility reaches: [${f}] — expected [${$}]`);const a=o.filter(e=>u(e.className)!==null);t("no class list without a scale token claims a size group",a.length===0,a.slice(0,5).map(e=>`${e.file}:${e.line}`).join("; ")),t("the reported case: a `font-display text-[22px]` heading is Headings, size group none",y("font-display text-[22px] font-medium")==="heading"&&u("font-display text-[22px] font-medium")===null),t("…and genuinely body-tagged copy still reads as the body size group",u("text-[var(--size-body,16px)]")==="body");const S=l.filter(e=>e.utilities.length>1);if(t("every class list names at most one face",S.length===0,S.slice(0,5).map(e=>`${e.file}:${e.line} — ${e.utilities.join(" + ")}`).join("; ")),n.panel!==void 0){const e=r.get(n.panel),s=e?b(e.text):"";t(`read the part panel ${n.panel}`,!!e),t("the box's name comes from the FACE, not from a size group",s.includes("FONT_ROLE_LABELS[face.role]")&&!s.includes("TYPE_GROUP_LABELS[")),t("…a face the page does not draw as its declared role is called Custom",/return\s*"Custom"/.test(s)&&s.includes('kind: "custom"')),t("…and a part no size knob reaches says so under the text box",/sizeGroup === null && \(\s*<p className="es-field-hint sf-hint-keep">(?:\{say\(")?Fixed size/.test(s))}if(n.bridge!==void 0){const e=r.get(n.bridge),s=e?b(e.text):"";t(`read the preview's part bridge ${n.bridge}`,!!e),t("the preview publishes BOTH tags, each walked up to its own nearest declarer",s.includes("fontRoleOfClassName")&&s.includes("typeScaleGroupOfClassName")&&s.includes("el.parentElement")),t("…and the element it reads from is one that declares EITHER tag",/partStyleSource\([\s\S]{0,200}fontRoleOfClassName[\s\S]{0,120}typeScaleGroupOfClassName/.test(s))}return d()}export{I as partStyleNaming};
@@ -1,5 +1,5 @@
1
1
  const g=["text","textarea","plainText","copyText","plainTextarea","linkField","textList","upload","toggle","checkbox","select","searchSelect","segmented","slider","colorInput","focalPicker","sizeField","backgroundField","multiSelect"];function A(e){const t=e.split(`
2
- `),n=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\("((?:[^"\\\\]|\\\\.)*)"`,"g"),o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\(\\s*$`),l=/^\s*"((?:[^"\\]|\\.)*)"\s*,/,r=[];let c=0,h=0;const f=[];return t.forEach((a,u)=>{const d=u+1,b=h>0;for(const i of a.matchAll(n))r.push({line:d,label:i[2],item:b,builder:i[1]});const m=s.exec(a);if(m){let i=u+1;for(;i<t.length&&t[i].trim()==="";)i+=1;const p=i<t.length?l.exec(t[i]):null;p&&r.push({line:i+1,label:p[1],item:b,builder:m[1]})}for(const i of a.matchAll(o)){const p=a.slice(0,i.index??0),x=u>0?t[u-1].trim():"";(/type:\s*"/.test(p)||/type:\s*"[a-z]+"\s*,?$/.test(x))&&r.push({line:d,label:i[1],item:b})}for(let i=0;i<a.length;i+=1)a[i]==="{"?(/arrayFields:\s*$/.test(a.slice(0,i))&&(f.push(c),h+=1),c+=1):a[i]==="}"&&(c-=1,f.length&&c===f[f.length-1]&&(f.pop(),h-=1))}),r}function L(e,t){let n=0,o=-1;for(let l=t-1;l>=0;l-=1){const r=e[l];if(r==="}")n+=1;else if(r==="{"){if(n===0){o=l;break}n-=1}}if(o<0)return"";let s=0;for(let l=o;l<e.length;l+=1)if(e[l]==="{")s+=1;else if(e[l]==="}"&&(s-=1,s===0))return e.slice(o,l+1);return e.slice(o)}function $(e){let t=0,n="";for(const o of e){if(o==="{"||o==="["){t+=1;continue}if(o==="}"||o==="]"){t-=1;continue}t===1&&(n+=o)}return n}function w(e,t){const n=$(L(e,t));return/(^|[,;])\s*(value|fields|render|resolveFields|panelId|href|amount|meta)\s*:/.test(n)||y(e,t)}function y(e,t){let n=0,o=0;for(let s=t-1;s>=0;s-=1){const l=e[s];if(l==="}"||l==="]"||l===")")n+=1;else if(l==="{"||l==="("){if(n>0){n-=1;continue}if(l==="("||++o>1)return!1}else if(l==="["){if(n>0){n-=1;continue}return/SettingsTabItem\[\]\s*=\s*$/.test(e.slice(Math.max(0,s-80),s))}}return!1}function F(e){const t=e.split(`
3
- `),n=[];for(let l=0,r=0;l<t.length;l+=1)n.push(r),r+=t[l].length+1;const o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=[];return t.forEach((l,r)=>{for(const c of l.matchAll(o))w(e,n[r]+(c.index??0))||s.push({line:r+1,label:c[1],item:!1})}),s}const j=/(?<![-A-Za-z])label="((?:[^"\\]|\\.)*)"/g;function E(e){const t=[];return e.split(`
2
+ `),n=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\("((?:[^"\\\\]|\\\\.)*)"`,"g"),o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=new RegExp(`(?<![A-Za-z0-9_.$])(${g.join("|")})\\(\\s*$`),l=/^\s*"((?:[^"\\]|\\.)*)"\s*,/,r=[];let c=0,h=0;const f=[];return t.forEach((a,u)=>{const d=u+1,b=h>0;for(const i of a.matchAll(n))r.push({line:d,label:i[2],item:b,builder:i[1]});const m=s.exec(a);if(m){let i=u+1;for(;i<t.length&&t[i].trim()==="";)i+=1;const p=i<t.length?l.exec(t[i]):null;p&&r.push({line:i+1,label:p[1],item:b,builder:m[1]})}for(const i of a.matchAll(o)){const p=a.slice(0,i.index??0),x=u>0?t[u-1].trim():"";(/type:\s*"/.test(p)||/type:\s*"[a-z]+"\s*,?$/.test(x))&&r.push({line:d,label:i[1],item:b})}for(let i=0;i<a.length;i+=1)a[i]==="{"?(/arrayFields:\s*$/.test(a.slice(0,i))&&(f.push(c),h+=1),c+=1):a[i]==="}"&&(c-=1,f.length&&c===f[f.length-1]&&(f.pop(),h-=1))}),r}function L(e,t){let n=0,o=-1;for(let l=t-1;l>=0;l-=1){const r=e[l];if(r==="}")n+=1;else if(r==="{"){if(n===0){o=l;break}n-=1}}if(o<0)return"";let s=0;for(let l=o;l<e.length;l+=1)if(e[l]==="{")s+=1;else if(e[l]==="}"&&(s-=1,s===0))return e.slice(o,l+1);return e.slice(o)}function $(e){let t=0,n="";for(const o of e){if(o==="{"||o==="["){t+=1;continue}if(o==="}"||o==="]"){t-=1;continue}t===1&&(n+=o)}return n}function y(e,t){const n=$(L(e,t));return/(^|[,;])\s*(value|fields|render|resolveFields|panelId|href|amount|meta)\s*:/.test(n)||w(e,t)}function w(e,t){let n=0,o=0;for(let s=t-1;s>=0;s-=1){const l=e[s];if(l==="}"||l==="]"||l===")")n+=1;else if(l==="{"||l==="("){if(n>0){n-=1;continue}if(l==="("||++o>1)return!1}else if(l==="["){if(n>0){n-=1;continue}return/SettingsTabItem\[\]\s*=\s*$/.test(e.slice(Math.max(0,s-80),s))}}return!1}function F(e){const t=e.split(`
3
+ `),n=[];for(let l=0,r=0;l<t.length;l+=1)n.push(r),r+=t[l].length+1;const o=/label:\s*"((?:[^"\\]|\\.)*)"/g,s=[];return t.forEach((l,r)=>{for(const c of l.matchAll(o))y(e,n[r]+(c.index??0))||s.push({line:r+1,label:c[1],item:!1})}),s}const j=/(?<![-A-Za-z])label=(?:\{say\()?"((?:[^"\\]|\\.)*)"/g;function E(e){const t=[];return e.split(`
4
4
  `).forEach((n,o)=>{for(const s of n.matchAll(j))t.push({line:o+1,label:s[1],item:!1})}),t}const S=/className="sf-field"|from\s*["']efficient-easel/;function I(e){return e.path.startsWith("components/")&&e.path.endsWith(".tsx")&&S.test(e.text)}const k=6;function O(e,t){for(let n=t;n<Math.min(e.length,t+k);n+=1){if(/^\s*\}[,)]?\s*$/.test(e[n])&&n>t)return!1;if(/\bonClick:/.test(e[n]))return!0}return!1}function N(e){const t=new Set,n=e.split(`
5
5
  `);return[...A(e),...F(e),...E(e)].filter(o=>{const s=`${o.line}:${o.label}`;return t.has(s)?!1:(t.add(s),!O(n,o.line-1))})}export{g as BUILDERS,j as JSX_LABEL,I as isPanelFile,E as readJsxLabels,A as readLabels,N as readPanelLabels,F as readRowLabels};
@@ -1 +1 @@
1
- function t(e){switch(e.status){case"saved":return null;case"failed":return{msg:"Not saved. Try again.",tone:"error"};case"skipped":switch(e.reason){case"empty":return null;case"no-token":return{msg:"Not saved. Reload the page.",tone:"error"};case"template":return{msg:"Templates keep their look. Press Done.",tone:"success"}}}}export{t as themeSaveNotice};
1
+ import{say as e}from"./editor-words.js";function r(t){switch(t.status){case"saved":return null;case"failed":return{msg:e("Not saved. Try again."),tone:"error"};case"skipped":switch(t.reason){case"empty":return null;case"no-token":return{msg:e("Not saved. Reload the page."),tone:"error"};case"template":return{msg:e("Templates keep their look. Press Done."),tone:"success"}}}}export{r as themeSaveNotice};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "description": "The EFFICIENT website builder: the website editor, the general sections and the renderer that draws them, compiled. Hostable by any EFFICIENT product; nothing here imports a host.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Efficient Pty Ltd",
@@ -35,12 +35,13 @@
35
35
  "build": "node scripts/build.mjs",
36
36
  "verify:dist": "node scripts/verify-dist.mjs",
37
37
  "verify": "pnpm run typecheck && pnpm run test:boundary && pnpm run test:screen && pnpm run test:own-ui && pnpm run test:guards && pnpm run build && pnpm run verify:dist",
38
- "test:guards": "tsc --noEmit -p scripts/tsconfig.json && node scripts/run-guards.mjs"
38
+ "test:guards": "tsc --noEmit -p scripts/tsconfig.json && node scripts/run-guards.mjs",
39
+ "words": "TSX_TSCONFIG_PATH=scripts/tsconfig.json tsx scripts/write-editor-words.ts"
39
40
  },
40
41
  "peerDependencies": {
41
42
  "@tabler/icons-react": "^3.46.0",
42
- "efficient-easel": "^2.0.0",
43
- "efficient-shell": "^5.6.0",
43
+ "efficient-easel": "^2.0.0 || ^3.1.0",
44
+ "efficient-shell": "^5.6.0 || ^6.4.0 || ^7.7.0",
44
45
  "isomorphic-dompurify": "^3.18.0",
45
46
  "next": ">=16",
46
47
  "react": ">=19",
@@ -59,7 +60,7 @@
59
60
  "@types/react": "^19",
60
61
  "@types/react-dom": "^19",
61
62
  "efficient-easel": "^2.2.0",
62
- "efficient-shell": "^5.6.0",
63
+ "efficient-shell": "^7.7.0",
63
64
  "esbuild": "^0.28.0",
64
65
  "happy-dom": "^20.14.5",
65
66
  "isomorphic-dompurify": "^3.18.0",