efficient-web-builder 9.0.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +186 -0
  2. package/dist/components/SectionEditor.js +1 -1
  3. package/dist/components/SectionTextEntries.d.ts +3 -1
  4. package/dist/components/SectionTextEntries.js +1 -1
  5. package/dist/components/SiteFields.d.ts +2 -1
  6. package/dist/components/SiteFields.js +1 -1
  7. package/dist/components/SlotChildRows.js +1 -1
  8. package/dist/components/storefront-editor.css +14 -4
  9. package/dist/lib/content/card-corners.d.ts +1 -1
  10. package/dist/lib/content/card-corners.js +1 -1
  11. package/dist/lib/content/section-corners.d.ts +0 -2
  12. package/dist/lib/content/section-corners.js +1 -1
  13. package/dist/lib/editor-words-catalogue.d.ts +15 -7
  14. package/dist/lib/editor-words-catalogue.js +4 -4
  15. package/dist/lib/puck/apply-card-corners.js +1 -1
  16. package/dist/lib/puck/blocks/general/Footprint/fields.js +1 -1
  17. package/dist/lib/puck/blocks/general/Hero/fields.js +1 -1
  18. package/dist/lib/puck/blocks/general/ImageBlock/fields.js +1 -1
  19. package/dist/lib/puck/blocks/general/LongRead/fields.js +1 -1
  20. package/dist/lib/puck/blocks/general/ProcessSteps/fields.js +1 -1
  21. package/dist/lib/puck/blocks/general/Prose/fields.js +1 -1
  22. package/dist/lib/puck/blocks/general/Split/fields.js +1 -1
  23. package/dist/lib/puck/blocks/general/Timeline/fields.js +1 -1
  24. package/dist/lib/puck/blocks/general/TimelineTrack/fields.js +1 -1
  25. package/dist/lib/puck/controls.d.ts +21 -11
  26. package/dist/lib/puck/controls.js +1 -1
  27. package/dist/lib/puck/field-buckets.d.ts +1 -1
  28. package/dist/lib/puck/field-buckets.js +1 -1
  29. package/dist/lib/puck/field-groups.d.ts +19 -8
  30. package/dist/lib/puck/field-groups.js +1 -1
  31. package/dist/lib/puck/panel-bands.d.ts +14 -0
  32. package/dist/lib/puck/panel-bands.js +1 -0
  33. package/dist/lib/puck/panel-drop-empty-headings.js +1 -1
  34. package/dist/lib/puck/passes/settings-groups.js +1 -1
  35. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,191 @@
1
1
  # Changelog
2
2
 
3
+ ## 11.0.0 - 2026-10-14
4
+
5
+ - **Breaking: the settings panel has two tabs, Design and Animation** (owner,
6
+ final 2026-10-10). It had four: Content, Style, Layout and Animation. A
7
+ section, a Box (`Flex`) and a block all get the same two. The tab strip is
8
+ efficient-easel's `Inspector` (icon-only, equal width); this package only
9
+ sorts the fields into it.
10
+ - **Inside Design the groups have one order**: the Content part first (the
11
+ text box, then the rows that were the Content tab), then Size, Design,
12
+ Layout, Position and Anchor, each under its `DESIGN_GROUP_KEY`. A group with
13
+ no rows is not emitted.
14
+ - **Folding groups, one level** (Lewis 2026-10-13: "Or should these fold like
15
+ this? It is getting messy." — one kind of group heading per panel). Every
16
+ group in a tabbed panel is the same grey band that folds (efficient-easel's
17
+ `SettingsGroup`, − / + on its right, open by default), drawn by the
18
+ Inspector from FOLD MARKERS: the text box is a band titled "Text"
19
+ (`leadFold`); each heading of the Content part is a band titled with its
20
+ label; `_dSize` … `_dAnchor` are bands titled Size, Design, Layout,
21
+ Position, Anchor; each heading of the Animation tab is a band. A heading
22
+ INSIDE Size … Anchor (Width, Height, Padding, Shape, Color, Motion …) draws
23
+ nothing: one level only. Every heading keeps its key and its fold payload as
24
+ a marker (`foldMarker`, `quietMarker`, `foldTitleOf` in `lib/puck/controls`),
25
+ so no key is lost. The text box no longer draws its own "TEXT" caption
26
+ (`SectionTextEntries`' new `heading`, false in the panel).
27
+ - **A band of one labelled row draws no band** (editor-panel-design §2b.1, a
28
+ group of one needs no heading): `SiteFields` measures what each band draws
29
+ and, when exactly one row shows and that row has its own label, the band goes
30
+ and the row stands alone at its place (its marker becomes `fold: false`,
31
+ so the row does not join the band above). A band whose one row has no label
32
+ keeps its band (it is the row's only name). The text box gets a band only
33
+ over two or more rows. The rule is `lib/puck/panel-bands` (new).
34
+ - **A block list is named as a row, not a sub-heading.** `SlotChildRows`
35
+ (Blocks, Slides, Groups …) drew its name as an uppercase `GroupLabel` with
36
+ the count ("BLOCKS · 0"), a second kind of heading in the Design tab. It is
37
+ now the list's row label (`SettingsField`, the Layers glyph) with the count on
38
+ the right.
39
+ - **Row names for one-level bands** (Lewis picked option A, 2026-10-14).
40
+ With no sub-head inside a band, a row says its own full name: the height
41
+ strip (`Auto | Fixed | Screen`) shows the label "Height" with its glyph, on
42
+ the shared row (desktop and phone); every padding row says "Padding top",
43
+ "Padding bottom" (a card's "Padding left", "Padding right"), never a bare
44
+ side; Split's overlay pair is "Overlay button" / "Overlay button link", so
45
+ it no longer reads "Button" / "Button link" twice. Labels only: no key
46
+ moves. `scripts/test-band-row-names.tsx` (new) renders every row of every
47
+ tabbed panel and holds all three.
48
+ - **More row names for one-level bands: one label per row in a panel**
49
+ (GG, 2026-10-14). `scripts/test-band-row-names.tsx` §4 fails when two rows
50
+ of one tabbed panel show the same label (a desktop row and its phone twin
51
+ count as one; a pair that must repeat is listed in `MAY_REPEAT` with its
52
+ reason, and none is). It found two panels. Split: the text column's
53
+ background picture says "Background image", not "Image" (the image column
54
+ keeps "Image"). Hero: "Show texture", "Show slide picker", "Show arrows",
55
+ "Slide picker shape", "Arrows shape", "Slide picker placement", "Arrows
56
+ placement" (they were "Show" three times, "Shape" and "Placement" twice;
57
+ the sub-heads that told them apart draw nothing in option A). `Arrows`
58
+ stays plural, the feature's one word (card 66250). Labels only: no key
59
+ moves.
60
+ - **Two more names** (GG, 2026-10-14): Hero's texture colour row says "Texture color", and LongRead's article heading says "Article title", so its text box no longer lists "Heading" twice (N10.1: the section's own heading is `Heading`, an item's is `Title`). Labels only; keys unchanged.
61
+ - **A closed band stays closed** across selections for the editor's life:
62
+ closing Size on one section keeps Size closed on the next one (`SiteFields`,
63
+ keyed by the band's field key).
64
+ The Content part starts with a `_dContent` marker that draws nothing, so
65
+ Copy style (efficient-easel 4.0.0) can tell content from a look.
66
+ - **Where each group went** (GG, 2026-10-13): Content keeps every Content
67
+ label and takes the pictures that were in Style (`Media`, `Image`, `Images`,
68
+ `Image column`, `Gallery`, `Logo`). Size: `Width`, `Height`, `Cell width`.
69
+ Design: the rest of Style. Layout: the rest of Layout, Padding included.
70
+ Position: `Nudge`. Anchor: `Anchor`. The Text and Heading blocks' Padding
71
+ goes in Size, beside Width (`BLOCK_KEY_GROUP`).
72
+ - **No setting is cut.** `scripts/test-no-setting-lost.tsx` checks every field
73
+ key of 6.0.0 against a record made on 6.0.0
74
+ (`scripts/fixtures/settings-before-two-tabs.json`): 871 keys over 54
75
+ components, all still there (still 871 on 10.0.0: main's work since added
76
+ and removed none), Animation unchanged, every key of the old
77
+ Content tab in the Content part, before every other group, every old Style
78
+ key in the Design group or the Content part, and every old Layout key in
79
+ Size, Layout, Position or Anchor.
80
+ - **Countdown has tabs now** (GG, 2026-10-13). It was added after every
81
+ placeable section was grouped, and nobody added it to `GROUPED_SECTIONS`, so
82
+ its 16 settings sat in one list with no tabs. Now its own 4 rows (Heading, At
83
+ zero, Ends, Unit labels) open the Content part of Design, the 11 shared rows
84
+ sit in Size, Design, Layout and Anchor, and its motion row is in Animation.
85
+ - **Breaking: `lib/puck/field-groups` API.** `LABEL_BUCKET` is `LABEL_GROUP`
86
+ and `KEY_BUCKET` is `KEY_GROUP`; their values are a Design group or
87
+ `"Animation"` (`Place`), not a tab. New: `BLOCK_KEY_GROUP`, `placeOf`,
88
+ `bucketOfPlace`, `headerKeysOf`, `headerKeysOfPlace`, `PLACE_WORDS`,
89
+ `INJECTED_RETIRED`, `DESIGN_GROUPS` and `DESIGN_GROUP_KEY` (also from
90
+ `lib/puck/field-buckets`). `bucketOf` still answers the tab.
91
+ `seatContentBucket` is `seatDesignBucket`. `BUCKET_KEY` has `Design` and
92
+ `Animation` only; a section that declares `_sContent`, `_sStyle`, `_sLayout`
93
+ or `_sMedia` now throws. A section opens a Design group itself with its key
94
+ (`_dDesign: section("Design")`, as Prose, ProcessSteps, Footprint, Timeline
95
+ and TimelineTrack now do).
96
+ - **`RETIRED` keeps every heading it retired.** A row now retires a level-2
97
+ heading whose label repeats the word of the PLACE it sits in (`PLACE_WORDS`:
98
+ "Content" in the Content part, "Style" or "Design" in the Design group,
99
+ "Layout" in Layout, …), with the same exact checks. The `Anchor` heading
100
+ every section gets is retired by key (`INJECTED_RETIRED`), because the
101
+ Anchor group heading above it says the same word.
102
+ - **The keep-lists follow the groups.** `LAYOUT_FIELD_KEYS`,
103
+ `SECTION_THEME_FIELD_KEYS`, `SECTION_SHAPE_FIELD_KEYS`,
104
+ `SECTION_ANIM_FIELD_KEYS` and `BOUND_CARD_MEDIA_FIELD_KEYS` carry the new tab
105
+ and group heading keys, read off the builders' own headings.
106
+ - **The text entries open the Design tab.** `SiteFields` hands them to the
107
+ Inspector as `lead` (drawn before the rows), and `entriesHiddenForTab` shows
108
+ them on Design only. `BUCKET_ICONS`: Design is the shell's `adjust`,
109
+ Animation the shell's `animation`.
110
+ - **Breaking: efficient-easel ^6.2.0** (peer and dev; was `^4.0.0`):
111
+ `SETTINGS_BUCKETS` Design/Animation, `DESIGN_GROUPS`, `DESIGN_GROUP_KEY`,
112
+ the panel words' `designGroups`, the Inspector's `lead`, `leadFold`,
113
+ `closedFolds` and `onFold`, and the fold markers are easel 5.0.0's; 6.0.0
114
+ draws the text box's toolbar from the shell (`TextToolbar`), which this
115
+ package does not touch. **Breaking: efficient-shell ^7.22.1** (peer; dev
116
+ `^7.23.1`; was `^7.21.0`): easel 6's own floor, and the first shell with
117
+ the `slide-picker-*` / `slide-arrows-*` glyphs and the seven-character
118
+ `HexInput` the Hero's rows use. `scripts/test-part-final-text-box.tsx` now
119
+ finds the text box's toolbar as the shell's `.rosh-tb` (easel 6 draws
120
+ `TextToolbar`; `.es-tb` is gone).
121
+ - New guard `scripts/test-panel-one-level-bands.tsx`: in every tabbed panel
122
+ (declared and resolved) every heading is a marker, so none is drawn; the
123
+ five groups and every Content and Animation heading are bands, nothing inside
124
+ Size … Anchor is; the bands come in order and every look row sits in its own
125
+ group's band; every branch of §2b.1; and `SiteFields` mounted: the band
126
+ order, the text box's band, a one-labelled-row band dropped, a one-unlabelled
127
+ -row band kept, no other heading kind, and a closed band kept closed on the
128
+ next node.
129
+ - Host follow-ups when taking this release: efficient-storefront-blocks (about
130
+ 15 guards that name the old tabs, `DetailRows`' `_sStyle: section("Style")`,
131
+ two uses of `BUCKET_KEY.Content`) and efficient-storefront (the pin, and about
132
+ 10 guards), each in its own pull request.
133
+ - `editor-words-catalogue` carries the new row and tab words (Design,
134
+ Animation, Arrows placement, Arrows shape, Article title …; `Show` is no
135
+ longer said alone), so a host can translate them.
136
+
137
+ ## 10.0.0 - 2026-10-14
138
+
139
+ - **The `Which corners` cells and the nine-square grid are efficient-shell
140
+ parts**, drawn straight from `efficient-shell/ui`
141
+ (Efficient-Pty-Ltd/efficient-shell#377, harness UI-24: one UI kit). The 2x2
142
+ `CornersInput` is in the shell from 7.16.0 (#452); the peer floor 9.0.0 set,
143
+ `^7.21.0`, already covers it, so the range does not move.
144
+ - **Corners is ONE row: the shell's `CornersInput`, its radius box beside
145
+ the 2x2.** On a section, on a card and on the Image block, the `Corners`
146
+ slider row and the `Which corners` row under it are now one `Corners` row
147
+ (one builder, `cornersRowField` in `lib/puck/controls`): the radius box
148
+ ("R" … "px", 120px) and the four corners as a 2x2 that mirrors the box (TL TR
149
+ over BL BR, 24px buttons). Lewis approved the 2x2 beside the box (GG,
150
+ 2026-10-14). Stored values do not move: no number = following, a number =
151
+ that number, ↺ writes `null`; the corner set stays on its own key
152
+ (`sectionCornerSides`, `cardCornerSides`, `cornerSides`) with the same
153
+ values (nothing stored = all four; all four back on writes `null`). The
154
+ corner-set keys are still declared and draw no row of their own
155
+ (`cornerSidesField`, a no-control field).
156
+ - **Following is shown by the parts that already say it.** An empty box
157
+ shows, as its placeholder, the number the page draws: the site's Corners
158
+ for a section, the section's (or the site's, when the section runs edge to
159
+ edge) for a card, and 0 (square) for a picture; ArrowUp starts from it. The
160
+ ↺ (easel `SettingsDefaultReset`) shows only while a number is set. The hint
161
+ line is unchanged ("Follows Site styles ▸ Basics ▸ Corners until you set a
162
+ number here." on a section). A section that runs edge to edge closes the
163
+ whole row (box and corners) with the same reason.
164
+ - **The radius box draws as the shell draws it** inside the inspector:
165
+ `storefront-editor.css` rolls its old unlayered input rule back for the
166
+ Corners row (`.sf-corners`), as it already did for the slider's number and
167
+ the colour box (without it the number sat on top of "px").
168
+ - "Apply to all cards" now says "Gives the other card(s) this card's
169
+ Corners." (the corner set is on the Corners row).
170
+ - Breaking, removed as dead: `sectionCornerSidesField` and
171
+ `cardCornerSidesField` (one `cornerSidesField`), `pxField`'s `restAtSite`
172
+ option, the corner sliders' resting-track components, and
173
+ `CORNER_SIDES_LABEL` and `cornerSidesSummary` (`lib/content/section-corners`,
174
+ re-exported by `lib/content/card-corners`; the "Which corners" row and its
175
+ summary are gone).
176
+ - **`FocalPicker` draws the shell's `AlignmentGrid`** (was efficient-easel's
177
+ `panel/SettingsPlacement`), so every nine-square row does: `placementField`
178
+ (Placement, Content position, Text position) and `edgePad` (Scroll
179
+ direction, Overlay position). Same nine values, same shut cells, same
180
+ arrows on the marquee's live cells, and the cells' names and reasons are
181
+ still said through `lib/editor-words`. New from the part: one Tab stop for
182
+ the grid, and the arrow keys move and choose (stopping at the edge). The
183
+ look is the one Lewis approved for the part (40px square cells with thin
184
+ lines, the chosen cell light blue with a blue square). `FocalPicker`'s
185
+ `points` take the shell's `AlignmentPoint` type.
186
+ - Nothing in `src/` takes `SettingsCorners` or `SettingsPlacement` from
187
+ efficient-easel any more (`scripts/test-corners-and-grid-from-the-shell.tsx`).
188
+
3
189
  ## 9.0.0 - 2026-10-14
4
190
 
5
191
  - **The Pages panel draws the Layers panel's tree** (Lewis on the Pages panel,
@@ -1 +1 @@
1
- "use client";import{jsx as n,jsxs as d,Fragment as v}from"react/jsx-runtime";import{useState as fe}from"react";import{useEasel as ue}from"efficient-easel/easel";import{InspectorHead as he,InspectorIconButton as x}from"efficient-easel/chrome";import{DuplicateIcon as Se,TrashIcon as we}from"efficient-easel/icons";import{panelFieldsOf as be}from"../lib/puck/panel-fields.js";import{TICKER_PART_LABEL as B}from"./PreviewTickerContext.js";import ge from"./SectionIcon.js";import{PanelHideButton as z}from"./SidePanelHead.js";import{useEditorSession as ke}from"../lib/editor-session-context.js";import{say as i}from"../lib/editor-words.js";import ve,{HintsToggle as Pe,SHOW_HINTS_DEFAULT as ye}from"./WebsiteSettingsPanel.js";import Ee from"./ChatSettingsPanel.js";import Ie from"./SocialLinksPanel.js";import Le from"./TickerSettingsPanel.js";import Ne,{PartSourceNote as Oe,partStyleName as Te}from"./PartSettingsPanel.js";import He from"./DuplicateToPageMenu.js";import{useStorefrontDocument as _e}from"./StorefrontDocumentContext.js";import{usePreviewHeader as Re}from"./PreviewHeaderContext.js";import{usePartStyle as Ae}from"./PreviewPartStyleContext.js";import{useSectionOps as Ce}from"../lib/puck/use-section-ops.js";import{SELECTION_MODE as De}from"../lib/editor-screen.js";import{usePreviewParts as Fe}from"./PreviewPartsContext.js";import{SectionTextEntries as xe}from"./SectionTextEntries.js";import{SectionTextSuppressProvider as Be}from"../lib/puck/section-text-suppress.js";import{HEADER_TYPE as ze,ROOT_ZONE as K}from"../lib/puck/content-tree.js";import{duplicateBlocked as Ke}from"../lib/hero-group-placement.js";import{FOOTER_TYPE as P}from"../lib/puck/footer-blocks.js";import Me from"./SwitchToBoxFooter.js";import{SiteFields as M}from"./SiteFields.js";import{SITE_FOOTER_SLUG as We}from"../lib/content/footer.js";import{SettingsSwitch as je}from"efficient-easel/panel";import{foldTopTier as Ue}from"../lib/puck/field-groups.js";import{FoldHeadingScope as Ye}from"../lib/puck/panel-heading-scope.js";import{partRowField as Ge}from"../lib/puck/part-row-field.js";import{decodePartKey as Ze,partRowHeadLabel as $e}from"../lib/puck/part-rows.js";import{encodePartId as W,partHeadLabel as qe,partLabel as Je,sectionTextParts as Qe}from"../lib/puck/text-parts.js";import{partSourceOf as Ve,sourceSlugOf as Xe}from"../lib/puck/source-bound-parts.js";const Yt=De,Gt={kind:"header"},Zt={kind:"website"},$t={kind:"chat"},qt={kind:"social"},g="Part";function j(e){return i("Part of {name}",{name:i(e)})}function et(e,o,r){const c=e.describeNode(o);return{name:r,kindLabel:c?j(c.label):i(g)}}function tt(e){switch(e){case"Header":return{title:i("Header settings belong to a website."),own:i("Each website created from this template sets its own header afterwards.")};case"Appearance":return{title:i("Appearance settings belong to a website."),own:i("Each website created from this template sets its own appearance afterwards.")};case"Live chat":return{title:i("Live chat settings belong to a website."),own:i("Each website created from this template sets its own live chat afterwards.")};case"Social link":return{title:i("Social link settings belong to a website."),own:i("Each website created from this template sets its own social link afterwards.")};default:return{title:i("{what} settings belong to a website.",{what:e}),own:i("Each website created from this template sets its own {what} afterwards.",{what:e.toLowerCase()})}}}function U({what:e}){const o=tt(e);return d("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:o.title})}),d("p",{children:[i("A template is a blueprint — it has no website of its own, so there is nothing here to change.")," ",o.own]})]})}const nt={header:{name:"Header",kindLabel:"Site settings",icon:"header",render:(e,o)=>{const r=o.hostPanels?.header;return r?n(r,{placeholderMode:o.capabilities.placeholderFrames,tokenRef:o.tokenRef,siteId:o.siteId,websiteName:o.websiteName,onOpenWebsiteSettings:o.onOpenWebsiteSettings,onAuthExpired:()=>o.notifyParent("storefront-editor:auth-expired")}):null}},website:{name:"Appearance",kindLabel:"Site settings",icon:"website",render:(e,o)=>n(ve,{themeFromDocument:!o.capabilities.hasSiteTheme,tokenRef:o.tokenRef,siteId:o.siteId,onNotify:o.onNotify})},chat:{name:"Live chat",kindLabel:"Site settings",icon:"chat",render:()=>n(Ee,{})},social:{name:"Social links",kindLabel:"Site settings",icon:"social",render:()=>n(Ie,{unavailable:n(U,{what:"Social link"})})},ticker:{name:B,kindLabel:g,icon:"ticker",head:(e,o)=>e.kind==="ticker"?et(o,e.heroId,i(B)):null,render:e=>n(Le,{heroId:e.kind==="ticker"?e.heroId:""})},part:{name:g,kindLabel:g,icon:"Text",head:(e,o)=>{if(e.kind!=="part")return null;const r=o.describeNode(e.nodeId);if(!r)return null;const{key:c,row:h}=Ze(e.propKey),w=h?Ge(r.fields[c],h):r.fields[c],u=$e(i(qe(Je(w??{},c))),h),p=o.styleNameOfPart(e.nodeId,e.propKey);return{name:p!==null?i(p):u,kindLabel:j(r.label)}},render:(e,o)=>e.kind==="part"?n(Ne,{nodeId:e.nodeId,propKey:e.propKey,onBack:()=>o.onSelectNode(e.nodeId),onEditStyle:o.onOpenSiteStyles}):null}},ot=new Set(["header","website","chat"]);function it(e,o){if(e==="puck")return null;const r=nt[e];return ot.has(e)&&!o.hasSiteSettings?{...r,kindLabel:"Not part of a template",render:()=>n(U,{what:r.name})}:r}function rt({mode:e,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c,hideNodeActions:h=!1,onNotify:w,onHidePanel:u}){const{capabilities:p,tokenRef:y,notifyParent:Y,currentSlug:E,siteId:I,runAuthed:G,readOnly:Z}=_e(),{websiteName:$,fonts:q}=Re(),{partStyle:L}=Ae(),b=Ce({readOnly:Z}),{select:J}=Fe(),{selectedItem:t,getItemById:N,getSelectorForId:Q,config:m,appState:V}=ue(l=>l),X=be(m,t?{type:t.type,props:t.props}:null),ee=l=>m.components[l]?.label??l,s=t?Q(t.props.id):void 0,a=it(e.kind,p),O=ke(),T=O.chrome?.panels?.chromePage,H={capabilities:p,tokenRef:y,hostPanels:O.chrome?.panels,describeNode:l=>{const f=N(l);if(!f)return null;const S=m.components[f.type];return{type:f.type,label:S?.label??f.type,fields:S?.fields??{}}},styleNameOfPart:(l,f)=>{const S=N(l);if(!S)return null;const de=W(l,f),me=L?.partId===de?L:null;return Te(S.props,f,me,q)},siteId:I,websiteName:$??null,notifyParent:Y,onNotify:w,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c},_=a?.head?.(e,H)??null,te=_?.name??(a?i(a.name):t?i(ee(t.type)):i("Page settings")),ne=_?.kindLabel??(a?i(a.kindLabel):t?s&&s.zone!==K?i("Block"):i("Section"):i("Page")),oe=a?a.icon:t?t.type:"page",R=a?null:t?m.components[t.type]?.fields??null:m.root?.fields??null,ie=R?Ue(R):2,A=e.kind==="puck"&&t?Ve(t.type):null,re=!!t&&!!s&&s.zone===K&&t.type!==P&&t.type!==ze,k=Ke(V?.data,t),se=()=>{k||s&&b.duplicateComponent(s.zone,s.index)},ae=()=>{s&&(b.removeComponent(s.zone,s.index),b.select(null))},le=t?m.components[t.type]?.defaultProps?.previewHover:void 0,C=e.kind==="puck"&&!!t&&!!s&&le!==void 0,D=C&&t.props.previewHover===!0,ce=()=>{!t||!s||b.replaceComponent(s.zone,s.index,{...t,props:{...t.props,previewHover:!D}})},[F,pe]=fe(ye);return d("div",{className:`es-sidepanel es-sidepanel--right sf-panel sf-panel--right${F||!(!a&&!!t)?"":" sf-hints-folded"}`,children:[n(he,{icon:n(ge,{type:oe,size:15}),name:te,kind:ne,actions:!h&&e.kind==="puck"&&t&&t.type!==P?d(v,{children:[n(x,{label:i("Duplicate section"),title:k??void 0,disabled:k!==null,onClick:se,children:n(Se,{size:15})}),re&&p.hasSiteSettings&&n(He,{node:t,currentSlug:E,siteId:I??void 0,tokenRef:y,runAuthed:G,onNotify:w}),n(x,{label:i("Remove section"),danger:!0,onClick:ae,children:n(we,{size:15})}),u?n(z,{side:"right",onHide:u,divider:!0}):null]}):u?n(z,{side:"right",onHide:u}):void 0}),C&&d("div",{className:"sf-preview-pin",children:[d("div",{className:"sf-preview-pin-text",children:[n("span",{className:"sf-preview-pin-label",children:i("Preview hover state")}),n("span",{className:"sf-preview-pin-hint",children:i("not shown live")})]}),n(je,{checked:D,onChange:ce,ariaLabel:i("Preview hover state")})]}),n(Ye,{tier:ie,children:n("div",{className:"sf-insp-body sf-scroll",children:a?a.render(e,H):t?d(v,{children:[n(Be,{children:n(M,{entries:n(xe,{parts:Qe(X??m.components[t.type]?.fields,t.props),onOpen:l=>J(W(t.props.id,l))})})}),t.type===P&&p.hasSiteSettings&&n(Me,{}),A&&n(Oe,{source:A,slug:Xe(t?.props)}),n(Pe,{shown:F,onChange:pe})]}):d(v,{children:[n(M,{}),E===We&&p.hasSiteSettings&&T&&n(T,{})]})})})]})}export{$t as CHAT_MODE,Gt as HEADER_MODE,Yt as PUCK_MODE,qt as SOCIAL_MODE,Zt as WEBSITE_MODE,rt as default,it as resolvePanel};
1
+ "use client";import{jsx as n,jsxs as d,Fragment as v}from"react/jsx-runtime";import{useState as ue}from"react";import{useEasel as he}from"efficient-easel/easel";import{InspectorHead as Se,InspectorIconButton as B}from"efficient-easel/chrome";import{DuplicateIcon as we,TrashIcon as be}from"efficient-easel/icons";import{panelFieldsOf as ge}from"../lib/puck/panel-fields.js";import{TICKER_PART_LABEL as z}from"./PreviewTickerContext.js";import ke from"./SectionIcon.js";import{PanelHideButton as K}from"./SidePanelHead.js";import{useEditorSession as ve}from"../lib/editor-session-context.js";import{say as i}from"../lib/editor-words.js";import Pe,{HintsToggle as ye,SHOW_HINTS_DEFAULT as Ee}from"./WebsiteSettingsPanel.js";import Ie from"./ChatSettingsPanel.js";import Le from"./SocialLinksPanel.js";import Ne from"./TickerSettingsPanel.js";import Oe,{PartSourceNote as Te,partStyleName as He}from"./PartSettingsPanel.js";import _e from"./DuplicateToPageMenu.js";import{useStorefrontDocument as Ce}from"./StorefrontDocumentContext.js";import{usePreviewHeader as Re}from"./PreviewHeaderContext.js";import{usePartStyle as Ae}from"./PreviewPartStyleContext.js";import{useSectionOps as De}from"../lib/puck/use-section-ops.js";import{SELECTION_MODE as Fe}from"../lib/editor-screen.js";import{usePreviewParts as xe}from"./PreviewPartsContext.js";import{entryPartsOf as Be,SectionTextEntries as ze}from"./SectionTextEntries.js";import{SectionTextSuppressProvider as Ke}from"../lib/puck/section-text-suppress.js";import{HEADER_TYPE as Me,ROOT_ZONE as M}from"../lib/puck/content-tree.js";import{duplicateBlocked as We}from"../lib/hero-group-placement.js";import{FOOTER_TYPE as P}from"../lib/puck/footer-blocks.js";import je from"./SwitchToBoxFooter.js";import{SiteFields as W}from"./SiteFields.js";import{SITE_FOOTER_SLUG as Ue}from"../lib/content/footer.js";import{SettingsSwitch as Ye}from"efficient-easel/panel";import{foldTopTier as Ge}from"../lib/puck/field-groups.js";import{FoldHeadingScope as Ze}from"../lib/puck/panel-heading-scope.js";import{partRowField as $e}from"../lib/puck/part-row-field.js";import{decodePartKey as qe,partRowHeadLabel as Je}from"../lib/puck/part-rows.js";import{encodePartId as j,partHeadLabel as Qe,partLabel as Ve,sectionTextParts as Xe}from"../lib/puck/text-parts.js";import{partSourceOf as et,sourceSlugOf as tt}from"../lib/puck/source-bound-parts.js";const Zt=Fe,$t={kind:"header"},qt={kind:"website"},Jt={kind:"chat"},Qt={kind:"social"},g="Part";function U(e){return i("Part of {name}",{name:i(e)})}function nt(e,o,r){const c=e.describeNode(o);return{name:r,kindLabel:c?U(c.label):i(g)}}function ot(e){switch(e){case"Header":return{title:i("Header settings belong to a website."),own:i("Each website created from this template sets its own header afterwards.")};case"Appearance":return{title:i("Appearance settings belong to a website."),own:i("Each website created from this template sets its own appearance afterwards.")};case"Live chat":return{title:i("Live chat settings belong to a website."),own:i("Each website created from this template sets its own live chat afterwards.")};case"Social link":return{title:i("Social link settings belong to a website."),own:i("Each website created from this template sets its own social link afterwards.")};default:return{title:i("{what} settings belong to a website.",{what:e}),own:i("Each website created from this template sets its own {what} afterwards.",{what:e.toLowerCase()})}}}function Y({what:e}){const o=ot(e);return d("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:o.title})}),d("p",{children:[i("A template is a blueprint — it has no website of its own, so there is nothing here to change.")," ",o.own]})]})}const it={header:{name:"Header",kindLabel:"Site settings",icon:"header",render:(e,o)=>{const r=o.hostPanels?.header;return r?n(r,{placeholderMode:o.capabilities.placeholderFrames,tokenRef:o.tokenRef,siteId:o.siteId,websiteName:o.websiteName,onOpenWebsiteSettings:o.onOpenWebsiteSettings,onAuthExpired:()=>o.notifyParent("storefront-editor:auth-expired")}):null}},website:{name:"Appearance",kindLabel:"Site settings",icon:"website",render:(e,o)=>n(Pe,{themeFromDocument:!o.capabilities.hasSiteTheme,tokenRef:o.tokenRef,siteId:o.siteId,onNotify:o.onNotify})},chat:{name:"Live chat",kindLabel:"Site settings",icon:"chat",render:()=>n(Ie,{})},social:{name:"Social links",kindLabel:"Site settings",icon:"social",render:()=>n(Le,{unavailable:n(Y,{what:"Social link"})})},ticker:{name:z,kindLabel:g,icon:"ticker",head:(e,o)=>e.kind==="ticker"?nt(o,e.heroId,i(z)):null,render:e=>n(Ne,{heroId:e.kind==="ticker"?e.heroId:""})},part:{name:g,kindLabel:g,icon:"Text",head:(e,o)=>{if(e.kind!=="part")return null;const r=o.describeNode(e.nodeId);if(!r)return null;const{key:c,row:h}=qe(e.propKey),w=h?$e(r.fields[c],h):r.fields[c],u=Je(i(Qe(Ve(w??{},c))),h),p=o.styleNameOfPart(e.nodeId,e.propKey);return{name:p!==null?i(p):u,kindLabel:U(r.label)}},render:(e,o)=>e.kind==="part"?n(Oe,{nodeId:e.nodeId,propKey:e.propKey,onBack:()=>o.onSelectNode(e.nodeId),onEditStyle:o.onOpenSiteStyles}):null}},rt=new Set(["header","website","chat"]);function st(e,o){if(e==="puck")return null;const r=it[e];return rt.has(e)&&!o.hasSiteSettings?{...r,kindLabel:"Not part of a template",render:()=>n(Y,{what:r.name})}:r}function at({mode:e,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c,hideNodeActions:h=!1,onNotify:w,onHidePanel:u}){const{capabilities:p,tokenRef:y,notifyParent:G,currentSlug:E,siteId:I,runAuthed:Z,readOnly:$}=Ce(),{websiteName:q,fonts:J}=Re(),{partStyle:L}=Ae(),b=De({readOnly:$}),{select:Q}=xe(),{selectedItem:t,getItemById:N,getSelectorForId:V,config:m,appState:X}=he(l=>l),ee=ge(m,t?{type:t.type,props:t.props}:null),O=t?Xe(ee??m.components[t.type]?.fields,t.props):[],te=l=>m.components[l]?.label??l,s=t?V(t.props.id):void 0,a=st(e.kind,p),T=ve(),H=T.chrome?.panels?.chromePage,_={capabilities:p,tokenRef:y,hostPanels:T.chrome?.panels,describeNode:l=>{const f=N(l);if(!f)return null;const S=m.components[f.type];return{type:f.type,label:S?.label??f.type,fields:S?.fields??{}}},styleNameOfPart:(l,f)=>{const S=N(l);if(!S)return null;const me=j(l,f),fe=L?.partId===me?L:null;return He(S.props,f,fe,J)},siteId:I,websiteName:q??null,notifyParent:G,onNotify:w,onOpenWebsiteSettings:o,onOpenSiteStyles:r,onSelectNode:c},C=a?.head?.(e,_)??null,ne=C?.name??(a?i(a.name):t?i(te(t.type)):i("Page settings")),oe=C?.kindLabel??(a?i(a.kindLabel):t?s&&s.zone!==M?i("Block"):i("Section"):i("Page")),ie=a?a.icon:t?t.type:"page",R=a?null:t?m.components[t.type]?.fields??null:m.root?.fields??null,re=R?Ge(R):2,A=e.kind==="puck"&&t?et(t.type):null,se=!!t&&!!s&&s.zone===M&&t.type!==P&&t.type!==Me,k=We(X?.data,t),ae=()=>{k||s&&b.duplicateComponent(s.zone,s.index)},le=()=>{s&&(b.removeComponent(s.zone,s.index),b.select(null))},ce=t?m.components[t.type]?.defaultProps?.previewHover:void 0,D=e.kind==="puck"&&!!t&&!!s&&ce!==void 0,F=D&&t.props.previewHover===!0,pe=()=>{!t||!s||b.replaceComponent(s.zone,s.index,{...t,props:{...t.props,previewHover:!F}})},[x,de]=ue(Ee);return d("div",{className:`es-sidepanel es-sidepanel--right sf-panel sf-panel--right${x||!(!a&&!!t)?"":" sf-hints-folded"}`,children:[n(Se,{icon:n(ke,{type:ie,size:15}),name:ne,kind:oe,actions:!h&&e.kind==="puck"&&t&&t.type!==P?d(v,{children:[n(B,{label:i("Duplicate section"),title:k??void 0,disabled:k!==null,onClick:ae,children:n(we,{size:15})}),se&&p.hasSiteSettings&&n(_e,{node:t,currentSlug:E,siteId:I??void 0,tokenRef:y,runAuthed:Z,onNotify:w}),n(B,{label:i("Remove section"),danger:!0,onClick:le,children:n(be,{size:15})}),u?n(K,{side:"right",onHide:u,divider:!0}):null]}):u?n(K,{side:"right",onHide:u}):void 0}),D&&d("div",{className:"sf-preview-pin",children:[d("div",{className:"sf-preview-pin-text",children:[n("span",{className:"sf-preview-pin-label",children:i("Preview hover state")}),n("span",{className:"sf-preview-pin-hint",children:i("not shown live")})]}),n(Ye,{checked:F,onChange:pe,ariaLabel:i("Preview hover state")})]}),n(Ze,{tier:re,children:n("div",{className:"sf-insp-body sf-scroll",children:a?a.render(e,_):t?d(v,{children:[n(Ke,{children:n(W,{entries:n(ze,{parts:O,heading:!1,onOpen:l=>Q(j(t.props.id,l))}),entryCount:Be(O).length})}),t.type===P&&p.hasSiteSettings&&n(je,{}),A&&n(Te,{source:A,slug:tt(t?.props)}),n(ye,{shown:x,onChange:de})]}):d(v,{children:[n(W,{}),E===Ue&&p.hasSiteSettings&&H&&n(H,{})]})})})]})}export{Jt as CHAT_MODE,$t as HEADER_MODE,Zt as PUCK_MODE,Qt as SOCIAL_MODE,qt as WEBSITE_MODE,at as default,st as resolvePanel};
@@ -1,5 +1,7 @@
1
1
  import type { SectionTextPart } from "../lib/puck/text-parts.js";
2
- export declare function SectionTextEntries({ parts, onOpen, }: {
2
+ export declare function entryPartsOf(parts: SectionTextPart[]): SectionTextPart[];
3
+ export declare function SectionTextEntries({ parts, onOpen, heading, }: {
3
4
  parts: SectionTextPart[];
4
5
  onOpen: (key: string) => void;
6
+ heading?: boolean;
5
7
  }): import("react").JSX.Element | null;
@@ -1 +1 @@
1
- "use client";import{jsx as n,jsxs as r}from"react/jsx-runtime";import{SettingsDrill as f}from"efficient-easel/panel";import a from"./UiIcon.js";import{say as i}from"../lib/editor-words.js";const l="Not shown on the page";function m({part:e,onOpen:o}){return n(f,{name:i(e.label),preview:e.offPage?i(l):e.preview||i("Empty"),offPage:e.offPage,status:e.hidden?n("span",{className:"sf-entry-eye",role:"img","aria-label":i("Hidden on the page"),children:n(a,{name:"eye-off",size:14})}):void 0,onOpen:()=>o(e.key)})}function u({parts:e,onOpen:o}){const t=e.filter(s=>!s.identifier);return t.length?r("div",{className:"sf-entries",children:[n("h3",{className:"sf-entries-head",children:i("Text")}),t.map(s=>n(m,{part:s,onOpen:o},s.key))]}):null}export{u as SectionTextEntries};
1
+ "use client";import{jsx as t,jsxs as f}from"react/jsx-runtime";import{SettingsDrill as a}from"efficient-easel/panel";import l from"./UiIcon.js";import{say as i}from"../lib/editor-words.js";const m="Not shown on the page";function c({part:e,onOpen:n}){return t(a,{name:i(e.label),preview:e.offPage?i(m):e.preview||i("Empty"),offPage:e.offPage,status:e.hidden?t("span",{className:"sf-entry-eye",role:"img","aria-label":i("Hidden on the page"),children:t(l,{name:"eye-off",size:14})}):void 0,onOpen:()=>n(e.key)})}function u(e){return e.filter(n=>!n.identifier)}function g({parts:e,onOpen:n,heading:o=!0}){const r=u(e);return r.length?f("div",{className:"sf-entries",children:[o?t("h3",{className:"sf-entries-head",children:i("Text")}):null,r.map(s=>t(c,{part:s,onOpen:n},s.key))]}):null}export{g as SectionTextEntries,u as entryPartsOf};
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type SettingsBucket } from "efficient-easel/fields";
3
3
  export declare const TAB_ICONS: Record<SettingsBucket, ReactNode>;
4
- export declare function SiteFields({ entries }: {
4
+ export declare function SiteFields({ entries, entryCount }: {
5
5
  entries?: ReactNode;
6
+ entryCount?: number;
6
7
  }): import("react").JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as l}from"react/jsx-runtime";import{useState as b}from"react";import{useSelectedFields as S}from"efficient-easel/easel";import{Inspector as C,planFields as T}from"efficient-easel/fields";import{BUCKET_ICONS as g,entriesHiddenForTab as h}from"../lib/puck/controls.js";import{BUCKETS as x}from"../lib/puck/field-groups.js";import{say as y}from"../lib/editor-words.js";const i=new Map,O=Object.fromEntries(x.map(t=>{const e=g[t];return[t,l(e,{},t)]}));function w({entries:t}){const{id:e,fields:a,values:m,readOnly:d,onChange:p}=S(),[s,f]=b(()=>i.get(e)),o=i.get(e),n=T(a).buckets,r=o&&n.includes(o)?o:s&&n.includes(s)?s:n[0],u=r===void 0||h(n,r)!==!0;return l(C,{fields:a,values:m,onChange:p,readOnly:d,tab:r,onTab:c=>{i.set(e,c),f(c)},tabIcons:O,idPrefix:e,ariaLabel:y("Section settings"),children:u?t:null})}export{w as SiteFields,O as TAB_ICONS};
1
+ "use client";import{jsx as S}from"react/jsx-runtime";import{useLayoutEffect as O,useMemo as B,useRef as k,useState as T}from"react";import{useSelectedFields as D}from"efficient-easel/easel";import{Inspector as K,planFields as x}from"efficient-easel/fields";import{BUCKET_ICONS as j,entriesHiddenForTab as v}from"../lib/puck/controls.js";import{BUCKETS as L}from"../lib/puck/field-groups.js";import{say as q}from"../lib/editor-words.js";import{bandIsDropped as R,droppedBands as U,sameKeys as X,TEXT_BAND_KEY as F,TEXT_BAND_TITLE as G,withoutBands as H}from"../lib/puck/panel-bands.js";const E=new Map,f=new Set;function P(n,r){const s=new Map;for(const l of n.querySelectorAll(".es-insp-row[data-field]"))s.set(l.getAttribute("data-field")??"",l);const o=[];for(const[l,m]of r)o.push({key:l,rows:m.map(p=>{const d=s.get(p),c=!!d&&[...d.children].some(w=>!w.hidden),i=d?.querySelector(".es-field-label, .es-list-label")?.textContent?.trim();return{shown:c,labelled:c&&!!i}})});return o}const Y=Object.fromEntries(L.map(n=>{const r=j[n];return[n,S(r,{},n)]}));function te({entries:n,entryCount:r=0}){const{id:s,fields:o,values:l,readOnly:m,onChange:p}=D(),[d,c]=T(()=>new Set(f)),[i,w]=T(()=>new Set),g=k(null),C=B(()=>{const e=new Map;for(const t of x(o).rows){if(!t.fold)continue;const a=e.get(t.fold.key)??[];a.push(t.name),e.set(t.fold.key,a)}return e},[o]);O(()=>{const e=g.current?.parentElement;if(!e)return;const t=new Set(U(P(e,C)));w(a=>X(a,t)?a:t)});const _=B(()=>H(o,i),[o,i]),A={key:F,rows:Array.from({length:r},()=>({shown:!0,labelled:!0}))},I=r>0&&!R(A)?{key:F,title:G}:void 0,[b,M]=T(()=>E.get(s)),h=E.get(s),u=x(o).buckets,y=h&&u.includes(h)?h:b&&u.includes(b)?b:u[0],N=y===void 0||v(u,y)!==!0;return S(K,{fields:_,values:l,onChange:p,readOnly:m,tab:y,onTab:e=>{E.set(s,e),M(e)},tabIcons:Y,idPrefix:s,ariaLabel:q("Section settings"),lead:N?n:null,leadFold:I,closedFolds:d,onFold:(e,t)=>{t?f.delete(e):f.add(e),c(new Set(f))},children:S("span",{ref:g,hidden:!0})})}export{te as SiteFields,Y as TAB_ICONS};
@@ -1 +1 @@
1
- "use client";import{jsx as s,jsxs as b}from"react/jsx-runtime";import{useEasel as x}from"efficient-easel/easel";import{SettingsDrill as A}from"efficient-easel/panel";import C from"./AddBlockRow.js";import N from"./AddChildRow.js";import{useSlotChildActions as k}from"./SlotChildActionsContext.js";import{HERO_GROUP_TYPE as $,heroGroupNestDepth as j}from"../lib/hero-group-placement.js";import{canAddTo as w}from"../lib/puck/add-target.js";import{GroupLabel as D}from"../lib/puck/controls.js";import{say as _}from"../lib/editor-words.js";function E({parent:o,parentType:t,label:d,rowName:r,onSelectChild:e,onAddChild:m,nestDepth:p=0}){const u=w(t,p);if(!u)return null;const{slot:n,choices:f,spec:i}=u,a=String(o.props.id),h=`${a}:${n}`,l=Array.isArray(o.props[n])?o.props[n]:[],R=i?.addBlocked?.(l)??null,S=i?.notice?.(l)??null;return b("div",{className:"sf-slot-rows",children:[d?s(D,{label:`${_(d)} · ${l.length}`}):null,S?s("p",{className:"sf-note",children:S}):null,l.map((c,g)=>s(A,{name:r(c),onOpen:()=>e(h,g,String(c.props.id),t)},String(c.props.id??`${h}-${g}`))),f?s(C,{choices:f,onPick:c=>m(a,n,c,l.length,t)}):i.fixed?null:s(N,{label:i.addLabel,blocked:R,onAdd:()=>m(a,n,i.childType,l.length,t)})]})}function G(o,t){return w(t)?.source==="footer"?o.blockRowName:o.childRowName}function O({parentType:o,label:t}){const{appState:d,selectedItem:r}=x(p=>p),e=k();if(!e||!r||r.type!==o)return null;const m=o===$?j(d?.data,String(r.props.id)):0;return s(E,{parent:r,parentType:o,label:t,rowName:G(e,o),onSelectChild:e.selectChild,onAddChild:e.addChild,nestDepth:m})}export{E as SlotChildRows,O as default,G as rowNamerFor};
1
+ "use client";import{jsx as e,Fragment as A,jsxs as C}from"react/jsx-runtime";import{useEasel as N}from"efficient-easel/easel";import{LayersIcon as b}from"efficient-easel/icons";import{SettingsDrill as k,SettingsField as F}from"efficient-easel/panel";import _ from"./AddBlockRow.js";import j from"./AddChildRow.js";import{useSlotChildActions as D}from"./SlotChildActionsContext.js";import{HERO_GROUP_TYPE as $,heroGroupNestDepth as E}from"../lib/hero-group-placement.js";import{canAddTo as R}from"../lib/puck/add-target.js";import{say as I}from"../lib/editor-words.js";function O({parent:o,parentType:t,label:d,rowName:r,onSelectChild:s,onAddChild:m,nestDepth:a=0}){const h=R(t,a);if(!h)return null;const{slot:n,choices:u,spec:i}=h,p=String(o.props.id),f=`${p}:${n}`,l=Array.isArray(o.props[n])?o.props[n]:[],x=i?.addBlocked?.(l)??null,g=i?.notice?.(l)??null,S=C(A,{children:[g?e("p",{className:"sf-note",children:g}):null,l.map((c,w)=>e(k,{name:r(c),onOpen:()=>s(f,w,String(c.props.id),t)},String(c.props.id??`${f}-${w}`))),u?e(_,{choices:u,onPick:c=>m(p,n,c,l.length,t)}):i.fixed?null:e(j,{label:i.addLabel,blocked:x,onAdd:()=>m(p,n,i.childType,l.length,t)})]});return e("div",{className:"sf-slot-rows",children:d?e(F,{label:I(d),icon:e(b,{}),value:String(l.length),children:S}):S})}function P(o,t){return R(t)?.source==="footer"?o.blockRowName:o.childRowName}function v({parentType:o,label:t}){const{appState:d,selectedItem:r}=N(a=>a),s=D();if(!s||!r||r.type!==o)return null;const m=o===$?E(d?.data,String(r.props.id)):0;return e(O,{parent:r,parentType:o,label:t,rowName:P(s,o),onSelectChild:s.selectChild,onAddChild:s.addChild,nestDepth:m})}export{O as SlotChildRows,v as default,P as rowNamerFor};
@@ -2238,11 +2238,12 @@
2238
2238
  .es-field-head > .sf-colour {
2239
2239
  margin-left: auto;
2240
2240
  }
2241
- /* Seven monospaced characters and the box's padding — no wider, so a two-word
2242
- label keeps its line beside the swatch. */
2241
+ /* The hex box's width is the SHELL's: `HexInput` is never narrower than its
2242
+ seven characters and its padding. This sheet held it at 4.75rem, which cut
2243
+ "#0A0A0A" to "#0A0A0" in the Hero's Texture color row (Lewis, 2026-10-14). */
2243
2244
  .sf-colour-hexwrap {
2244
2245
  flex: none;
2245
- width: 4.75rem;
2246
+ display: flex;
2246
2247
  }
2247
2248
  .sf-colour-caption {
2248
2249
  font-size: var(--text-xs);
@@ -2262,6 +2263,14 @@
2262
2263
  .sf-editor .sf-insp-body :is(.sf-slider, .sf-colour) input::placeholder {
2263
2264
  all: revert-layer;
2264
2265
  }
2266
+ /* The same roll-back for the Corners row's radius box (`.sf-corners`, the
2267
+ shell's CornersInput, plan W2): without it the old rule's padding put the
2268
+ number on top of "px". */
2269
+ .sf-editor .sf-insp-body .sf-corners input[type="text"],
2270
+ .sf-editor .sf-insp-body .sf-corners input[type="text"]:focus,
2271
+ .sf-editor .sf-insp-body .sf-corners input::placeholder {
2272
+ all: revert-layer;
2273
+ }
2265
2274
  /* The colour a row FOLLOWS, shown in its box in grey (option E): the grey is
2266
2275
  what says the setting has no colour of its own. After the roll-back above,
2267
2276
  and more specific than it, so the roll-back does not take the grey away. */
@@ -3032,7 +3041,8 @@
3032
3041
  }
3033
3042
 
3034
3043
  /* The nine-square grid moved into `efficient-easel/panel` as `SettingsPlacement`
3035
- (0.35.0), so the `.sf-focal*` rules that lived here are gone rather than left
3044
+ (0.35.0), and from there into efficient-shell as `AlignmentGrid` (#377, which
3045
+ web-builder 10.0.0 draws directly), so the `.sf-focal*` rules that lived here are gone rather than left
3036
3046
  as a second copy nobody would remember to update. The chosen cell also stopped
3037
3047
  being card 8811's tint on the way: the shell tells the chosen thing apart by
3038
3048
  being the darkest in the row on a grey track (66138 / 66302), and its suite
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from "react";
2
- export { CORNER_SIDES, CORNER_SIDE_POINTS, CORNER_SIDES_LABEL, cornerSidesShorthand, cornerSidesSummary, hasCornerSubset, normalizeCornerSides, type CornerSide, } from "./section-corners.js";
2
+ export { CORNER_SIDES, CORNER_SIDE_POINTS, cornerSidesShorthand, hasCornerSubset, normalizeCornerSides, type CornerSide, } from "./section-corners.js";
3
3
  export declare const CARD_BOX_RADIUS_PROP = "--sf-card-box-radius";
4
4
  export declare const SITE_CARD_RADIUS_PROP = "--sf-site-card-radius";
5
5
  export declare const CARD_FOLLOWS_SITE_CLASS = "sf-section-bleeds";
@@ -1 +1 @@
1
- import{cornerRadiusTokens as d,normalizeCornerRadius as S}from"../theme.js";import{CARD_RADIUS_PROP as t,cornerSidesShorthand as p,hasCornerSubset as u,normalizeCornerSides as c}from"./section-corners.js";import{CORNER_SIDES as E,CORNER_SIDE_POINTS as I,CORNER_SIDES_LABEL as b,cornerSidesShorthand as P,cornerSidesSummary as y,hasCornerSubset as L,normalizeCornerSides as N}from"./section-corners.js";const C="--sf-card-box-radius",a="--sf-site-card-radius",m="sf-section-bleeds";function f(r){return typeof r=="number"&&Number.isFinite(r)}function O(r,o){if(!f(r))return;const e=d(S(r))[t];if(typeof e!="string")return;const s=u(o)?p(e,c(o)??[]):e;return{[C]:s}}function x(r){const o=r[t];return typeof o=="string"?{[a]:o}:{}}function D(r,o){const e=r.find(n=>n?.props?.id===o);if(!e)return[...r];const s=e.props?.cardCorners,i=e.props?.cardCornerSides;return r.map(n=>n?.props?.id===o?n:{...n,props:{...n.props,cardCorners:s,cardCornerSides:i}})}export{C as CARD_BOX_RADIUS_PROP,m as CARD_FOLLOWS_SITE_CLASS,E as CORNER_SIDES,b as CORNER_SIDES_LABEL,I as CORNER_SIDE_POINTS,a as SITE_CARD_RADIUS_PROP,O as cardCornerStyle,D as cardsWithSharedCorners,P as cornerSidesShorthand,y as cornerSidesSummary,L as hasCornerSubset,f as hasOwnCardCorners,N as normalizeCornerSides,x as siteCardRadiusTokens};
1
+ import{cornerRadiusTokens as d,normalizeCornerRadius as p}from"../theme.js";import{CARD_RADIUS_PROP as t,cornerSidesShorthand as S,hasCornerSubset as u,normalizeCornerSides as c}from"./section-corners.js";import{CORNER_SIDES as b,CORNER_SIDE_POINTS as I,cornerSidesShorthand as P,hasCornerSubset as E,normalizeCornerSides as T}from"./section-corners.js";const C="--sf-card-box-radius",a="--sf-site-card-radius",m="sf-section-bleeds";function f(r){return typeof r=="number"&&Number.isFinite(r)}function x(r,o){if(!f(r))return;const e=d(p(r))[t];if(typeof e!="string")return;const s=u(o)?S(e,c(o)??[]):e;return{[C]:s}}function O(r){const o=r[t];return typeof o=="string"?{[a]:o}:{}}function h(r,o){const e=r.find(n=>n?.props?.id===o);if(!e)return[...r];const s=e.props?.cardCorners,i=e.props?.cardCornerSides;return r.map(n=>n?.props?.id===o?n:{...n,props:{...n.props,cardCorners:s,cardCornerSides:i}})}export{C as CARD_BOX_RADIUS_PROP,m as CARD_FOLLOWS_SITE_CLASS,b as CORNER_SIDES,I as CORNER_SIDE_POINTS,a as SITE_CARD_RADIUS_PROP,x as cardCornerStyle,h as cardsWithSharedCorners,P as cornerSidesShorthand,E as hasCornerSubset,f as hasOwnCardCorners,T as normalizeCornerSides,O as siteCardRadiusTokens};
@@ -8,9 +8,7 @@ export type CornerSide = (typeof CORNER_SIDES)[number];
8
8
  export declare function normalizeCornerSides(value: unknown): CornerSide[] | null;
9
9
  export declare function hasCornerSubset(value: unknown): boolean;
10
10
  export declare function cornerSidesShorthand(radius: string, sides: CornerSide[]): string;
11
- export declare const CORNER_SIDES_LABEL = "Which corners";
12
11
  export declare const CORNER_SIDE_POINTS: readonly {
13
12
  value: CornerSide;
14
13
  label: string;
15
14
  }[];
16
- export declare function cornerSidesSummary(sides: readonly CornerSide[]): string;
@@ -1 +1 @@
1
- import{cornerRadiusTokens as u,normalizeCornerRadius as c}from"../theme.js";function f(r){return typeof r=="number"&&Number.isFinite(r)}function R(r,t){if(!f(r))return;const n=u(c(r));if(Object.keys(n).length===0)return;const o=n[a];if(typeof o!="string")return n;const i=h(t)?b(o,l(t)??[]):o;return{...n,[s]:i}}const s="--sf-section-radius",a="--sf-card-radius",e=["tl","tr","br","bl"];function l(r){if(!Array.isArray(r))return null;const t=r.filter(n=>e.includes(n));return e.filter(n=>t.includes(n))}function h(r){const t=l(r);return t!==null&&t.length<e.length}function b(r,t){return e.map(n=>t.includes(n)?r:"0").join(" ")}const d="Which corners",p=[{value:"tl",label:"Top left"},{value:"tr",label:"Top right"},{value:"bl",label:"Bottom left"},{value:"br",label:"Bottom right"}];function g(r){const t=n=>r.includes(n);if(r.length===e.length)return"All four";if(r.length===0)return"None";if(r.length===1)return p.find(n=>n.value===r[0])?.label??"1 corner";if(r.length===2){if(t("tl")&&t("tr"))return"Top two";if(t("bl")&&t("br"))return"Bottom two";if(t("tl")&&t("bl"))return"Left two";if(t("tr")&&t("br"))return"Right two"}return`${r.length} corners`}export{a as CARD_RADIUS_PROP,e as CORNER_SIDES,d as CORNER_SIDES_LABEL,p as CORNER_SIDE_POINTS,s as SECTION_RADIUS_PROP,b as cornerSidesShorthand,g as cornerSidesSummary,h as hasCornerSubset,f as hasOwnSectionCorners,l as normalizeCornerSides,R as sectionCornerStyle};
1
+ import{cornerRadiusTokens as l,normalizeCornerRadius as u}from"../theme.js";function c(r){return typeof r=="number"&&Number.isFinite(r)}function S(r,t){if(!c(r))return;const e=l(u(r));if(Object.keys(e).length===0)return;const o=e[a];if(typeof o!="string")return e;const s=d(t)?p(o,i(t)??[]):o;return{...e,[f]:s}}const f="--sf-section-radius",a="--sf-card-radius",n=["tl","tr","br","bl"];function i(r){if(!Array.isArray(r))return null;const t=r.filter(e=>n.includes(e));return n.filter(e=>t.includes(e))}function d(r){const t=i(r);return t!==null&&t.length<n.length}function p(r,t){return n.map(e=>t.includes(e)?r:"0").join(" ")}const R=[{value:"tl",label:"Top left"},{value:"tr",label:"Top right"},{value:"bl",label:"Bottom left"},{value:"br",label:"Bottom right"}];export{a as CARD_RADIUS_PROP,n as CORNER_SIDES,R as CORNER_SIDE_POINTS,f as SECTION_RADIUS_PROP,p as cornerSidesShorthand,d as hasCornerSubset,c as hasOwnSectionCorners,i as normalizeCornerSides,S as sectionCornerStyle};
@@ -114,6 +114,7 @@ export declare const WEB_BUILDER_WORDS: {
114
114
  readonly "An empty section. Add whatever you want inside.": "An empty section. Add whatever you want inside.";
115
115
  readonly Anchor: "Anchor";
116
116
  readonly "Anchor name": "Anchor name";
117
+ readonly Animation: "Animation";
117
118
  readonly "Another group already uses this heading \u2014 pick a different one.": "Another group already uses this heading — pick a different one.";
118
119
  readonly Answer: "Answer";
119
120
  readonly "Any color": "Any color";
@@ -128,10 +129,13 @@ export declare const WEB_BUILDER_WORDS: {
128
129
  readonly "Approved customer reviews in a star-rated card grid, pulled live.": "Approved customer reviews in a star-rated card grid, pulled live.";
129
130
  readonly Arrow: "Arrow";
130
131
  readonly Arrows: "Arrows";
132
+ readonly "Arrows placement": "Arrows placement";
133
+ readonly "Arrows shape": "Arrows shape";
131
134
  readonly Article: "Article";
132
135
  readonly "Article *headline* goes here.": "Article *headline* goes here.";
133
136
  readonly "Article Text": "Article Text";
134
137
  readonly "Article headline": "Article headline";
138
+ readonly "Article title": "Article title";
135
139
  readonly "As designed": "As designed";
136
140
  readonly "As shot": "As shot";
137
141
  readonly "As typed": "As typed";
@@ -297,7 +301,6 @@ export declare const WEB_BUILDER_WORDS: {
297
301
  readonly "Copy over image": "Copy over image";
298
302
  readonly "Copying\u2026": "Copying…";
299
303
  readonly Corners: "Corners";
300
- readonly "Corners left off stay square. The row above sets how round the others are.": "Corners left off stay square. The row above sets how round the others are.";
301
304
  readonly "Couldn\u2019t add the page \u2014 please retry.": "Couldn’t add the page — please retry.";
302
305
  readonly "Couldn\u2019t delete the page \u2014 please retry.": "Couldn’t delete the page — please retry.";
303
306
  readonly "Couldn\u2019t duplicate the section \u2014 please retry": "Couldn’t duplicate the section — please retry";
@@ -343,6 +346,7 @@ export declare const WEB_BUILDER_WORDS: {
343
346
  readonly "Describe this section in a sentence or two.": "Describe this section in a sentence or two.";
344
347
  readonly "Describe this step in a sentence or two.": "Describe this step in a sentence or two.";
345
348
  readonly "Describe what happened, in a sentence or two.": "Describe what happened, in a sentence or two.";
349
+ readonly Design: "Design";
346
350
  readonly Detail: "Detail";
347
351
  readonly "Detail line": "Detail line";
348
352
  readonly Direction: "Direction";
@@ -441,7 +445,6 @@ export declare const WEB_BUILDER_WORDS: {
441
445
  readonly "Follow the slideshow": "Follow the slideshow";
442
446
  readonly "Follows Desktop": "Follows Desktop";
443
447
  readonly "Follows no style \u2014 change": "Follows no style — change";
444
- readonly "Follows the section": "Follows the section";
445
448
  readonly "Follows the section's Corners until you set a number here.": "Follows the section's Corners until you set a number here.";
446
449
  readonly "Follows the site": "Follows the site";
447
450
  readonly "Follows the style": "Follows the style";
@@ -472,8 +475,8 @@ export declare const WEB_BUILDER_WORDS: {
472
475
  readonly "Gap only": "Gap only";
473
476
  readonly Ghost: "Ghost";
474
477
  readonly "Give the new template page a name. It starts blank \u2014 add sections once it opens.": "Give the new template page a name. It starts blank — add sections once it opens.";
475
- readonly "Gives the other card this card's Corners and Which corners.": "Gives the other card this card's Corners and Which corners.";
476
- readonly "Gives the other {n} cards this card's Corners and Which corners.": "Gives the other {n} cards this card's Corners and Which corners.";
478
+ readonly "Gives the other card this card's Corners.": "Gives the other card this card's Corners.";
479
+ readonly "Gives the other {n} cards this card's Corners.": "Gives the other {n} cards this card's Corners.";
477
480
  readonly Good: "Good";
478
481
  readonly "Greeting message": "Greeting message";
479
482
  readonly Grid: "Grid";
@@ -723,6 +726,7 @@ export declare const WEB_BUILDER_WORDS: {
723
726
  readonly Overlay: "Overlay";
724
727
  readonly "Overlay - CartDrawer": "Overlay - CartDrawer";
725
728
  readonly "Overlay button": "Overlay button";
729
+ readonly "Overlay button link": "Overlay button link";
726
730
  readonly "Overlay color": "Overlay color";
727
731
  readonly "Overlay position": "Overlay position";
728
732
  readonly Padding: "Padding";
@@ -758,6 +762,7 @@ export declare const WEB_BUILDER_WORDS: {
758
762
  readonly "Plays well with\n*your favourite apps.*": "Plays well with\n*your favourite apps.*";
759
763
  readonly "Pop up - SubscribePopup": "Pop up - SubscribePopup";
760
764
  readonly "Portal card (stock + button + orders)": "Portal card (stock + button + orders)";
765
+ readonly Position: "Position";
761
766
  readonly Positions: "Positions";
762
767
  readonly "Post Card": "Post Card";
763
768
  readonly Prefix: "Prefix";
@@ -867,7 +872,6 @@ export declare const WEB_BUILDER_WORDS: {
867
872
  readonly Separator: "Separator";
868
873
  readonly "Series title": "Series title";
869
874
  readonly Serif: "Serif";
870
- readonly "Set a number above first \u2014 there is nothing to shape yet.": "Set a number above first — there is nothing to shape yet.";
871
875
  readonly "Set this card's corners first.": "Set this card's corners first.";
872
876
  readonly "Shadow color": "Shadow color";
873
877
  readonly Shape: "Shape";
@@ -876,10 +880,12 @@ export declare const WEB_BUILDER_WORDS: {
876
880
  readonly "Short description of this figure.": "Short description of this figure.";
877
881
  readonly "Short detail line": "Short detail line";
878
882
  readonly "Short supporting line": "Short supporting line";
879
- readonly Show: "Show";
883
+ readonly "Show arrows": "Show arrows";
880
884
  readonly "Show cover image": "Show cover image";
881
885
  readonly "Show hints": "Show hints";
882
886
  readonly "Show on a card": "Show on a card";
887
+ readonly "Show slide picker": "Show slide picker";
888
+ readonly "Show texture": "Show texture";
883
889
  readonly "Show the chat bubble": "Show the chat bubble";
884
890
  readonly "Show the chat bubble on the whole site": "Show the chat bubble on the whole site";
885
891
  readonly "Show ticker": "Show ticker";
@@ -900,6 +906,8 @@ export declare const WEB_BUILDER_WORDS: {
900
906
  readonly "Slash /": "Slash /";
901
907
  readonly "Slide name": "Slide name";
902
908
  readonly "Slide picker": "Slide picker";
909
+ readonly "Slide picker placement": "Slide picker placement";
910
+ readonly "Slide picker shape": "Slide picker shape";
903
911
  readonly Small: "Small";
904
912
  readonly "Social Logos": "Social Logos";
905
913
  readonly "Social link settings belong to a website.": "Social link settings belong to a website.";
@@ -994,6 +1002,7 @@ export declare const WEB_BUILDER_WORDS: {
994
1002
  readonly "Text style": "Text style";
995
1003
  readonly Texts: "Texts";
996
1004
  readonly Texture: "Texture";
1005
+ readonly "Texture color": "Texture color";
997
1006
  readonly "Texture opacity": "Texture opacity";
998
1007
  readonly "Thanks \u2014 we'll email you to confirm.": "Thanks — we'll email you to confirm.";
999
1008
  readonly "The built-in spacing.": "The built-in spacing.";
@@ -1090,7 +1099,6 @@ export declare const WEB_BUILDER_WORDS: {
1090
1099
  readonly "What people *say.*": "What people *say.*";
1091
1100
  readonly WhatsApp: "WhatsApp";
1092
1101
  readonly "Whether this page sits on the site's content column, or runs edge to edge.": "Whether this page sits on the site's content column, or runs edge to edge.";
1093
- readonly "Which corners": "Which corners";
1094
1102
  readonly "Whole number Theme Color": "Whole number Theme Color";
1095
1103
  readonly "Wide (2:1)": "Wide (2:1)";
1096
1104
  readonly "Wide promo strip with background image.": "Wide promo strip with background image.";