efficient-web-builder 16.0.2 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/dist/components/HeroGroup.d.ts +5 -1
- package/dist/components/HeroGroup.js +1 -1
- package/dist/components/PartSettingsPanel.d.ts +0 -20
- package/dist/components/PartSettingsPanel.js +1 -1
- package/dist/components/PartTextBox.d.ts +2 -1
- package/dist/components/PartTextBox.js +1 -1
- package/dist/components/SectionEditor.d.ts +0 -1
- package/dist/components/SectionEditor.js +1 -1
- package/dist/components/storefront-editor.css +9 -9
- package/dist/lib/content/borders.d.ts +21 -0
- package/dist/lib/content/borders.js +1 -0
- package/dist/lib/editor-words-catalogue.d.ts +14 -12
- package/dist/lib/editor-words-catalogue.js +5 -5
- package/dist/lib/puck/blocks/general/CategoryBar/fields.js +1 -1
- package/dist/lib/puck/blocks/general/Chart/fields.js +1 -1
- package/dist/lib/puck/blocks/general/Countdown/fields.js +1 -1
- package/dist/lib/puck/blocks/general/Flex/fields.js +1 -1
- package/dist/lib/puck/blocks/general/HeroGroup/fields.js +1 -1
- package/dist/lib/puck/blocks/general/HeroGroup/render.js +1 -1
- package/dist/lib/puck/blocks/general/HeroSlide/fields.js +1 -1
- package/dist/lib/puck/blocks/general/ImageBlock/fields.js +1 -1
- package/dist/lib/puck/blocks/general/LogoBlock/fields.js +1 -1
- package/dist/lib/puck/blocks/general/Logos/fields.js +1 -1
- package/dist/lib/puck/blocks/general/SectionHeader/fields.js +1 -1
- package/dist/lib/puck/controls.d.ts +17 -0
- package/dist/lib/puck/controls.js +1 -1
- package/dist/lib/puck/field-groups.js +1 -1
- package/dist/lib/puck/part-styles.d.ts +2 -1
- package/dist/lib/puck/part-styles.js +2 -2
- package/dist/lib/puck/passes/borders.d.ts +2 -0
- package/dist/lib/puck/passes/borders.js +1 -0
- package/dist/lib/puck/passes/index.js +1 -1
- package/dist/lib/puck/passes/inspector.js +1 -1
- package/dist/lib/puck/passes/section-padding.js +1 -1
- package/dist/lib/puck/passes/types.d.ts +5 -0
- package/dist/lib/source-rules/label-vocabulary.js +3 -3
- package/dist/lib/source-rules/one-border-resolver.d.ts +4 -0
- package/dist/lib/source-rules/one-border-resolver.js +1 -0
- package/dist/lib/source-rules/support/part-slider-call-sites.js +3 -3
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 17.0.0 - 2026-10-16
|
|
4
|
+
|
|
5
|
+
Two builds in one release (GG cuts one 17.0.0, as easel cut one 10.0.0). A major: the efficient-easel peer range narrows to `^10.1.0` (10.0.0 for the text panel and the Border and Padding parts, 10.1.0 for `onChangeMany`, which the four-side Padding row writes with) and the efficient-shell range to `^7.47.0` (7.44.0 for the Border row and the No list glyph, 7.47.0 for the Style list that shows every style whole, scrolls with no cut row, opens small in a small field and is solid: shell#507, Lewis's review 2026-10-16).
|
|
6
|
+
|
|
7
|
+
**A text part draws the one text panel** (card [MERGE] Settings Tabs Into Design And Animation; text panel v3, Lewis final 2026-10-15; wave 3 · W1 of `_desk/plans/2026-10-15-text-panel-build.md`; Italic, Lewis 2026-10-16 via GG). The part panel draws easel 10's `TextPartPanel`, the same panel the email designer draws.
|
|
8
|
+
|
|
9
|
+
### Changed for merchants
|
|
10
|
+
|
|
11
|
+
- **A text part's words are typed where they are, on the page; the panel draws no text box for them.** Its rows are, in this order: Style (with "*" when the text has its own changes, and Clear changes · Edit styles in the list), Font with an **Italic** button at its end, the number cells (Font size · Line spacing · Letter spacing · Paragraph spacing · Padding · Width), Alignment, and Capitalization.
|
|
12
|
+
- **A text box stays only for words the canvas cannot take**: an image's alt text, a logo's alt text, a slide's name and its reel label, a Box name, a tab name, a category bar's active tab, a countdown's At zero line and a chart's value suffix (each field says so with the new `withPanelOnly` marker), words that never reach the page, and words hidden with the eye. The eye stays where it was.
|
|
13
|
+
- **Italic** (new): the whole text leans; pressing it again follows the style; over an italic site style it shows pressed and turns the text upright. Stored as `_partStyles[part].italic`, painted as `font-style`.
|
|
14
|
+
- **Capitalized** (new): a fourth letter case, beside As typed, Uppercase and Lowercase.
|
|
15
|
+
- **The head names the part**: line 1 is the part's own name, line 2 "Part of ‹section›" (easel's `headWords`). It no longer shows the style's name (gate 4 of the text panel plan; it replaces the 2026-09-07 ruling, with Lewis's "v3 is final").
|
|
16
|
+
- **Link and word colour are not cut**: a part whose words carry marks keeps its panel text box (toolbar only, no cells), because easel's canvas typing bar has no Link and no colour window yet. It goes when easel adds both to the canvas bar (`scripts/test-part-link-colour-kept.tsx`, red before the fix).
|
|
17
|
+
- **A whole text list keeps its style rows** (GG 2026-10-16): a ticker's items, a masthead's issues, an integrations list, a mockup's cards and its terminal lines are one part with no type-in-place kind. They draw the one text panel's rows under the list's own control, as they had the style card in 16.0.2 (`scripts/test-text-lists-keep-style-rows.tsx`, red before the fix).
|
|
18
|
+
- **No Color row and no style card of its own** (v3: a colour is put on selected words from the canvas toolbar). A colour a part already stores still draws, and Clear changes takes it away. "No style" is still the first answer in the Style list; Clear changes keeps the style the part follows.
|
|
19
|
+
|
|
20
|
+
### Changed for hosts
|
|
21
|
+
|
|
22
|
+
- The settings body wears easel's row inset (`es-insp-body`: 16px, 8px under a 284px panel), and `.sf-insp-body` no longer sets its own side padding; `--sf-insp-pad-x` follows `--es-insp-pad-x`.
|
|
23
|
+
- `controls`: `withPanelOnly(field)` and `textFieldPanelOnly(field)`. `PartTextBox` exports `partTextCells` (the one list of a part's cells).
|
|
24
|
+
- `label-vocabulary`: six more N10.1 Never words — typeface, font family, leading, character spacing, kerning, text transform (the storefront's `doc/naming.md` Never column takes them in the pin PR, as `test-label-vocabulary` there compares the two).
|
|
25
|
+
|
|
26
|
+
### Guards
|
|
27
|
+
|
|
28
|
+
- New `scripts/test-one-text-panel.tsx` (31 checks: italic stored and painted, Capitalized, the ten marked fields, the panel drawing `TextPartPanel` and no card or Color row, the head, the inset); all failed on 16.0.2.
|
|
29
|
+
- Retired `scripts/test-part-field-icons.tsx` (the rows it checked are easel's `TextPartPanel` now, tested there). `test-part-colour` §7, `test-part-follows-style` §6, `test-part-final-text-box` §5, `test-panel-padding-narrows`, `test-panel-strip-width-stable`, `test-editor-type-steps`, `test-one-dropdown`, `test-one-editor-list` read the new panel.
|
|
30
|
+
|
|
31
|
+
**A section and a Box take a Border** (card [DESIGN] The Hartes Name Block; Box Border approved by Lewis 2026-10-15, GG's order 2026-10-16: the section and Box tier first).
|
|
32
|
+
|
|
33
|
+
### Added for merchants
|
|
34
|
+
|
|
35
|
+
- **A Border row in every section's Shape group, after Corners** (a Box is a section, so this is the Box's Border too): the shell's `BorderInput` through easel 10's `SettingsBorder`, glyph `border-all`, with the shared `Each side` toggle in its head. One width box, or four (left · top / right · bottom); Solid / Dashed / Dotted; a colour. 0–20px (answer 4). The phone's own value is a second row shown in phone view only (`sectionBorderPhone`); an empty part shows the desktop value in grey there, and the site's Borders colour on desktop.
|
|
36
|
+
- An empty Border is stored as nothing, and a section without a border of its own draws byte for byte as before.
|
|
37
|
+
- **Heading and Text take their own left and right padding** (card [ADD] INOVIT And Hartes Metal US Websites; Lewis 2026-10-16, option A: the Hartes US footer tagline needs 20px more on the right). Their two Padding sliders become ONE `Padding` row: the shell's `SidesInput` through easel `SettingsSides`, glyph `padding-all`, with the `Each side` toggle in its head. Two boxes (left and right · top and bottom), or four. 0–200px, step 4; an empty side adds nothing. The phone's own value is the same row in phone view, its empty sides showing the desktop value in grey. The stored keys do not change (`sectionPaddingTop` / `Bottom` keep their data; `sectionPaddingLeft` / `Right` and the phone twins are new), and a Heading or Text with no padding draws byte for byte as before.
|
|
38
|
+
|
|
39
|
+
- **Every section and every Box take left and right padding, in one four-side Padding row** (four-side Padding v2, Lewis 2026-10-15; GG 2026-10-16, step W-P1). The shared row (`sidesPaddingFields`, the shell's `SidesInput` through easel) replaces the section's two Top/Bottom sliders: two boxes (left and right · top and bottom), or four with `Each side` on, desktop and phone. New stored keys `sectionPaddingLeft` / `sectionPaddingRight` and their phone twins; an empty side draws nothing, so every stored page draws as before. A section draws its left/right on its outer padding wrapper; a Box on a picture still draws all four sides inside the card (its resting figures show grey in the row). The Box's hidden `py-6` is unchanged here (W-P2).
|
|
40
|
+
|
|
41
|
+
- **The Box inside a Hero (HeroGroup) shows the same four-side Padding row** (one grammar, GG 2026-10-16) instead of its Top/Bottom sliders, and draws left/right (and their phone values) on its own root, never a wrapper (the slide's grid placement, card 66290). Nothing set draws what it drew before.
|
|
42
|
+
- **Every phone twin of the Padding row is a phone-only field**: the Left/Right/Bottom phone twins the row keeps were not marked, so copy / paste style counted them as settings of their own ("Pasted N settings").
|
|
43
|
+
|
|
44
|
+
### Added for hosts
|
|
45
|
+
|
|
46
|
+
- `lib/content/borders.ts`, THE one border resolver: a stored value becomes `--sf-border-{top,right,bottom,left}-width`, `--sf-border-style`, `--sf-border-color` (each again with `-phone`). Only what is set is published, so an unset side or colour follows the tier above. The `sectionBorder` pass puts them on a `display: contents` carrier, `.sf-section-border`, right after the corners carrier. **The host's stylesheet draws the line** from them on `.sf-section-border > *`, as it draws `--sf-section-radius` (the storefront's next pin carries that rule).
|
|
47
|
+
- `sidesPaddingFields(opts)` in `lib/puck/controls`: THE one four-side Padding row builder (keys, phone twin, empty-side value, grid), for every padding place; it writes every side it changes in one write, easel's `onChangeMany` (efficient-easel 10.1.0), never one `onChange` per side. The Heading/Text wrapper (`blockPadding`) draws left and right through `sectionPadAttrs`; a section's outer wrapper still does not.
|
|
48
|
+
|
|
49
|
+
### Guards
|
|
50
|
+
|
|
51
|
+
- New `scripts/test-section-border.tsx` (8): the resolver (nothing set, width vs side, the Hartes value, clamps, a bad style or colour dropped, the phone suffix), the pass (byte-identical without a border, the carrier with one, phone only), its place after `sectionCorners`, the Shape group's keys, and `source-rules/one-border-resolver` (a second file writing `--sf-border-` fails). Failed before the modules existed.
|
|
52
|
+
- `test-shell-peer-range` and `test-publish-main-action` read the new ranges.
|
|
53
|
+
- New `scripts/test-block-side-padding.tsx`: the draw (left/right and their phone values on Heading and Text, no wrapper when nothing is set, no left/right on a section's outer wrapper), the panel (eight keys on the Design tab, one edit = one patch, the row writes through `onChangeMany` only, the shell's sides group and toggle drawn) and the builder over other keys. Failed before the change. `test-band-row-names` reads the four-side row: it says `Padding`, its boxes name the sides.
|
|
54
|
+
|
|
55
|
+
- New `scripts/test-section-side-padding.tsx` (27): a section and a plain Box draw left/right (desktop and phone), nothing set is not wrapped, a card Box draws none outside, every section's panel declares the eight keys and shows the shared row, and a Box's Border wraps its padding wrapper (the Hartes 20px sits inside the red line). Failed before the change.
|
|
56
|
+
- `test-block-side-padding` §4 and `test-box-card-padding-in-design` §2 read the new rule (a section draws left/right; only the card Box keeps them inside).
|
|
57
|
+
|
|
58
|
+
- New `scripts/test-padding-phone-twins-and-hero-group.tsx` (20): every phone twin is tier mobile, HeroGroup declares the eight keys and shows the shared row, and draws left/right on its root (desktop and phone; nothing set, no padding). Failed before the change (10 of 20).
|
|
59
|
+
|
|
3
60
|
## 16.0.2 - 2026-10-16
|
|
4
61
|
|
|
5
62
|
**On a phone, a hero with a set height grows to fit its words** (card [ADD] INOVIT And Hartes Metal US Websites, GG 2026-10-15). hartesmetal.com/dealers: the heading "Become a Hartes Metal dealer" is five lines on a phone, and the hero's set phone height (60vh) was a fixed height, so the bottom-aligned words overflowed upward and the heading ran under the logo (181px above the top of the page at 390x844, 267px at 375x667).
|
|
@@ -14,7 +14,11 @@ export interface HeroGroupProps {
|
|
|
14
14
|
sectionPaddingBottom?: unknown;
|
|
15
15
|
sectionPaddingTopPhone?: unknown;
|
|
16
16
|
sectionPaddingBottomPhone?: unknown;
|
|
17
|
+
sectionPaddingLeft?: unknown;
|
|
18
|
+
sectionPaddingRight?: unknown;
|
|
19
|
+
sectionPaddingLeftPhone?: unknown;
|
|
20
|
+
sectionPaddingRightPhone?: unknown;
|
|
17
21
|
content?: SlotComponent;
|
|
18
22
|
dragRef?: ((element: Element | null) => void) | null;
|
|
19
23
|
}
|
|
20
|
-
export default function HeroGroup({ placement, nudgeX, nudgeY, width, gap, direction, justify, align, wrap, sectionPaddingTop, sectionPaddingBottom, sectionPaddingTopPhone, sectionPaddingBottomPhone, content: Content, dragRef, }: HeroGroupProps): import("react").JSX.Element;
|
|
24
|
+
export default function HeroGroup({ placement, nudgeX, nudgeY, width, gap, direction, justify, align, wrap, sectionPaddingTop, sectionPaddingBottom, sectionPaddingTopPhone, sectionPaddingBottomPhone, sectionPaddingLeft, sectionPaddingRight, sectionPaddingLeftPhone, sectionPaddingRightPhone, content: Content, dragRef, }: HeroGroupProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as m}from"react/jsx-runtime";import{containerDirectionClass as
|
|
1
|
+
import{jsx as m}from"react/jsx-runtime";import{containerDirectionClass as k,resolveContainerDirection as v}from"../lib/content/container-direction.js";import{containerGapProps as D}from"../lib/content/container-gap.js";import{boxLayoutClasses as W,boxWrapClass as w}from"../lib/content/box-layout.js";import{sectionPadAttrs as A}from"../lib/content/section-padding.js";import{clampNudge as p,clampWidth as B,normalisePlacement as E,placementParts as F,placementRow as L}from"../lib/hero-group-placement.js";function R({placement:c,nudgeX:f,nudgeY:u,width:r,gap:g,direction:t,justify:y,align:h,wrap:x,sectionPaddingTop:d,sectionPaddingBottom:b,sectionPaddingTopPhone:N,sectionPaddingBottomPhone:G,sectionPaddingLeft:H,sectionPaddingRight:P,sectionPaddingLeftPhone:j,sectionPaddingRightPhone:$,content:n,dragRef:C}){const s=E(c),a=p(f),l=p(u),i=D("HeroGroup",g,v("HeroGroup",t)==="column"?"block":"inline"),o={"--sf-hg-row":L(s),justifySelf:F(s).column};typeof r=="number"&&Number.isFinite(r)&&(o["--sf-hg-w"]=`${B(r)}%`),(a!==0||l!==0)&&(o["--sf-hg-nudge"]=`${a}px ${l}px`);const e=A(d,b,N,G,H,P,j,$);return m("div",{className:e?`sf-hero-group ${e.className}`:"sf-hero-group","data-hg":s,style:e?{...o,...e.style}:o,ref:C??void 0,children:n?m(n,{className:["sf-hero-group-blocks flex",k("HeroGroup",t),W(y,h),w(x)].filter(Boolean).join(" ")+i.className,style:i.style,minEmptyHeight:40}):null})}export{R as default};
|
|
@@ -4,15 +4,6 @@ import { type FontRole, type FontsValue } from "../lib/fonts.js";
|
|
|
4
4
|
import { type TypeGroup } from "../lib/theme.js";
|
|
5
5
|
import { type PartStyle, type PartStyleBase } from "../lib/puck/part-styles.js";
|
|
6
6
|
import { type PartSource } from "../lib/puck/source-bound-parts.js";
|
|
7
|
-
export declare const PART_FIELDS: readonly [{
|
|
8
|
-
readonly key: "font";
|
|
9
|
-
readonly label: "Font";
|
|
10
|
-
readonly group: "Style";
|
|
11
|
-
}, {
|
|
12
|
-
readonly key: "color";
|
|
13
|
-
readonly label: "Color";
|
|
14
|
-
readonly group: "Style";
|
|
15
|
-
}];
|
|
16
7
|
export type PartFace = {
|
|
17
8
|
kind: "role";
|
|
18
9
|
role: FontRole;
|
|
@@ -32,22 +23,11 @@ export declare function partFace(props: Record<string, unknown>, propKey: string
|
|
|
32
23
|
faceRole: FontRole;
|
|
33
24
|
base: PartStyleBase;
|
|
34
25
|
} | null, fonts: FontsValue): PartFace;
|
|
35
|
-
export declare function partStyleName(props: Record<string, unknown>, propKey: string, reading: {
|
|
36
|
-
faceRole: FontRole;
|
|
37
|
-
base: PartStyleBase;
|
|
38
|
-
} | null, fonts: FontsValue): string | null;
|
|
39
26
|
export declare function PartStyleSelect({ face, base, onPick, }: {
|
|
40
27
|
face: PartFace;
|
|
41
28
|
base: PartStyleBase | null;
|
|
42
29
|
onPick: (role: FontRole | null) => void;
|
|
43
30
|
}): import("react").JSX.Element;
|
|
44
|
-
export declare function PartStyleCard({ parts, onEditStyle, onClearAll, onFollowStyle, kindLabel, }: {
|
|
45
|
-
parts: readonly PanelPart[];
|
|
46
|
-
onEditStyle?: () => void;
|
|
47
|
-
onClearAll: () => void;
|
|
48
|
-
onFollowStyle?: (role: FontRole | null) => void;
|
|
49
|
-
kindLabel?: string;
|
|
50
|
-
}): import("react").JSX.Element;
|
|
51
31
|
export { PartResetDot };
|
|
52
32
|
export declare function PartPanelBody({ sectionName, onBack, textEditor, styleRow, children, }: {
|
|
53
33
|
sectionName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as t,jsxs as u,Fragment as _}from"react/jsx-runtime";import{useEffect as W,useId as $e,useRef as Z,useState as ee}from"react";import{PartResetDot as ye}from"./PartResetDot.js";import{FieldSelect as ge,InspectorField as De}from"efficient-easel/fields";import{SettingsField as be,SettingsGroup as Ve}from"efficient-easel/panel";import{InspectorUpLevel as G}from"efficient-easel/chrome";import{StylesIcon as Be,TextColorIcon as Me,TypeIcon as Se}from"efficient-easel/icons";import{useEasel as We}from"efficient-easel/easel";import{Tooltip as Ge}from"efficient-shell/ui";import{PartInkControl as je}from"./PartInkControl.js";import{PartTextBox as Ue}from"./PartTextBox.js";import xe from"./UiIcon.js";import{usePreviewHeader as He}from"./PreviewHeaderContext.js";import{usePartStyle as Ke}from"./PreviewPartStyleContext.js";import{say as o}from"../lib/editor-words.js";import{readHidable as j,textFieldOffPage as Xe}from"../lib/puck/controls.js";import{TEXT_FIELD_MARKER as Ye}from"../lib/puck/field-markers.js";import{useSectionOps as qe}from"../lib/puck/use-section-ops.js";import{FONT_OPTIONS as Je,FONT_ROLES as te,FONT_ROLE_LABELS as ne,fontOption as L}from"../lib/fonts.js";import{isMultilineKind as Qe,partPlaceholder as Ze,typeInPlaceKind as et}from"../lib/puck/part-text.js";import{partRowField as tt}from"../lib/puck/part-row-field.js";import{decodePartKey as nt,partPropsWithRowValue as ot,partRowValue as st}from"../lib/puck/part-rows.js";import{PART_WIDTH_MAX as lt,propsWithPartStyleValue as oe,propsWithoutPartStyle as rt,readPartStyle as ve}from"../lib/puck/part-styles.js";import{partInks as at}from"../lib/puck/part-inks.js";import{styleKeyForPart as it,TEXT_KIND_LABELS as ct}from"../lib/sections/section-text-kinds.js";import{commitPartText as dt}from"../lib/puck/part-typing.js";import{keysOnCanvas as ut,useCanvasTypingPart as ft}from"../lib/puck/canvas-typing.js";import{useEditorHost as pt}from"../lib/editor-host.js";import{SOURCE_LINES as mt,SOURCE_ACTIONS as ht,SOURCE_ACTION_LABEL as yt,partSourceOf as gt,sourceSlugOf as Ne}from"../lib/puck/source-bound-parts.js";import{encodePartId as bt,holdsAuthoredText as St}from"../lib/puck/text-parts.js";import{regionsForSection as xt}from"../lib/sections/section-text-regions.js";import{textRegionOfPartKey as vt}from"../lib/sections/text-regions.js";const Nt={400:"Regular",500:"Medium",600:"Semibold",700:"Bold"},ke=[{key:"font",label:"Font",group:"Style"},{key:"color",label:"Color",group:"Style"}],kt=[...new Set(ke.map(e=>e.group))],Pt={font:t(Se,{}),color:t(Me,{})};function A(e){return e?o(e):null}function R(e){return e.kind==="role"?ne[e.role]:e.kind==="custom"?"Custom":null}const wt=e=>e.kind==="role"?`role:${e.role}`:e.kind;function Tt(e){const n=e.role;return n&&te.includes(n)?{kind:"role",role:n}:null}function Et(e,n){if(!e)return{kind:"unread"};const{faceRole:l,base:r}=e;if(n[l]===r.fontKey)return{kind:"role",role:l};const c=Object.keys(n).filter(i=>n[i]===r.fontKey);return c.length===1?{kind:"role",role:c[0]}:{kind:"custom"}}function se(e,n,l,r){return Tt(ve(e,n))??Et(l,r)}function Sn(e,n,l,r){return R(se(e,n,l,r))}function le(e,n){if(!e.length)return null;const l=n(e[0]);return e.every(r=>n(r)===l)?l:null}function Ct(e){return Object.values(e).filter(n=>n!==void 0).length}function Rt(e,n){const l=e.style[n];return n==="color"?l??"":l!==void 0?String(l):e.base.fontKey}function Ft({face:e,base:n,onPick:l}){const[r,c]=ee(!1),i=Z(null),y=Z(null),g=$e();W(()=>{if(!r)return;const a=E=>{i.current&&!i.current.contains(E.target)&&c(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[r]);const f=e.kind==="role"?e.role:null,x=a=>{l(a),c(!1),y.current?.focus()};return u("div",{className:"sf-part-style-pick",ref:i,children:[u("button",{ref:y,type:"button",className:"sf-part-style-trigger","aria-expanded":r,"aria-controls":g,"aria-label":R(e)?o("Follows {name} — change",{name:A(R(e))}):o("Follows no style — change"),onClick:()=>c(a=>!a),onKeyDown:a=>{a.key==="Escape"&&r&&(a.preventDefault(),c(!1))},children:[t("span",{className:"sf-part-style-name",style:{fontFamily:n?.fontKey?`var(${L(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:A(R(e))}),t("span",{className:"sf-part-style-sign","aria-hidden":"true"})]}),r&&u("div",{className:"sf-multi-menu sf-part-style-menu",id:g,role:"listbox",onKeyDown:a=>{a.key==="Escape"&&(a.preventDefault(),c(!1),y.current?.focus())},children:[u("button",{type:"button",role:"option","aria-selected":f===null,className:`sf-part-style-option${f===null?" is-on":""}`,onClick:()=>x(null),children:[t("span",{className:"sf-part-style-option-name",children:o("No style")}),t("span",{className:"sf-note",children:o("Section’s own")})]}),te.map(a=>t("button",{type:"button",role:"option","aria-selected":f===a,className:`sf-part-style-option${f===a?" is-on":""}`,onClick:()=>x(a),children:t("span",{className:"sf-part-style-option-name",style:{fontFamily:`var(--font-role-${a})`},children:o(ne[a])})},a))]})]})}const U="";function Ot({face:e,base:n,onPick:l}){const r=e.kind==="role"?e.role:U,c=[{label:o("No style"),value:U},...te.map(i=>({label:o(ne[i]),value:i}))];return t(ge,{ariaLabel:o("Style"),value:r,options:c,inline:!0,onChange:i=>l(i===U?null:i),renderOption:i=>i.value===U?u(_,{children:[t("span",{className:"es-fsel-label sf-part-style-keep",children:i.label}),t("span",{className:"sf-part-style-aside","aria-hidden":"true",children:o("Section’s own")})]}):t("span",{className:"es-fsel-label",style:{fontFamily:`var(--font-role-${i.value})`},children:i.label}),renderValue:()=>t("span",{style:{fontFamily:n?.fontKey?`var(${L(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:A(R(e))}),valueText:i=>A(R(e))??i?.label??""})}function It({parts:e,onEditStyle:n,onClearAll:l,onFollowStyle:r,kindLabel:c}){const y=le(e,E=>wt(E.face))?e[0].face:null,g=y?R(y):null,f=y&&y.kind!=="unread"?e[0].base:null,x=e.reduce((E,H)=>E+Ct(H.style),0),a=f?L(f.fontKey)?.label:void 0;return u("div",{className:`sf-part-style${x?" has-overrides":""}`,children:[t("div",{className:"sf-part-style-caption",children:o("Style")}),e.length>1&&t("div",{className:"sf-part-style-count",children:o("{n} selected",{n:e.length})}),e.length===1&&c&&t("div",{className:"sf-part-style-count",children:o("{kind} · every row",{kind:o(c)})}),g&&f?u(_,{children:[r&&y?t(Ft,{face:y,base:f,onPick:r}):t("div",{className:"sf-part-style-name",style:{fontFamily:a?`var(${L(f.fontKey)?.cssVar})`:void 0,fontWeight:f.weight},children:o(g)}),t("div",{className:"sf-part-style-meta",children:[a,`${Math.round(f.sizePx)} px`,o(Nt[f.weight])].filter(Boolean).join(" · ")})]}):t("div",{className:"sf-part-style-name",children:o("Mixed styles")}),u("div",{className:"sf-part-style-top",children:[g?x?u(_,{children:[t("span",{className:"sf-part-chip",children:o("{n} changed",{n:x})}),t("button",{type:"button",className:"sf-part-link",onClick:l,children:o("Clear")})]}):t("span",{className:"sf-part-style-state",children:o("This text follows the site style.")}):t("span",{className:"sf-part-style-state",children:o("Changes apply to all selected.")}),t("span",{className:"sf-part-style-gap"}),g&&n&&t("button",{type:"button",className:"sf-part-link",onClick:n,children:o("Edit")})]})]})}function _t({sectionName:e,onBack:n,textEditor:l,styleRow:r,children:c}){return u("div",{className:"sf-part-panel",children:[t(G,{inline:!0,name:o(e),onSelect:n}),l,r,c]})}function Pe({source:e,slug:n}){const l=pt(),r=ht[e],c=!r.needsSlug||!!n;return t("div",{className:"sf-note sf-note--source",children:u("p",{className:"es-field-hint sf-hint-keep",children:[o(mt[e]),c?u(_,{children:[" ",t("button",{type:"button",className:"sf-source-open",onClick:()=>{r.type==="storefront-editor:open-menus"?l.send(r.type):n&&l.send(r.type,{slug:n})},children:o(yt)})]}):null]})})}const we=4,Lt=120;function At({region:e,sizePx:n,face:l,base:r,onFollowStyle:c,source:i,slug:y,onBack:g}){const f=e.follows;return u("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:o(e.label)})}),t("p",{children:n?o("Its size follows Site styles ▸ {follows} — {px}px right now.",{follows:o(f),px:Math.round(n)}):o("Its size follows Site styles ▸ {follows}.",{follows:o(f)})}),c?t(_,{children:t(be,{label:o("Style"),icon:t(Be,{}),hint:o("Every {part} in this section follows it. The face and the size change; the letter case is the section’s own and stays as it is.",{part:o(e.label).toLowerCase()}),children:t(Ot,{face:l,base:r,onPick:c})})}):t("p",{className:"es-field-hint sf-hint-keep",children:o("Only the size follows a site style. This section sets its own font, weight and letter case.")}),i?t(Pe,{source:i,slug:y}):null,t(G,{inline:!0,name:o("Page"),onSelect:g})]})}function zt({onBack:e}){return u("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:o("This part is no longer here.")})}),t("p",{children:o("The section it belonged to has been changed or removed.")}),t(G,{inline:!0,name:o("Page"),onSelect:e})]})}function $t({onBack:e,partId:n,why:l}){return u("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:o("This part's settings did not open.")})}),t("p",{children:o("The words are still on your page and nothing has been lost. The editor could not work out which control belongs to them, which is a fault on our side. Go back and click the section to open its settings instead.")}),t("p",{className:"sf-note-detail",children:u("code",{children:[n," — ",l]})}),t(G,{inline:!0,name:o("Page"),onSelect:e})]})}function Dt({nodeId:e,propKey:n,onBack:l,onEditStyle:r}){const{getItemById:c,getSelectorForId:i,config:y}=We(s=>s),g=qe(),f=ft(),{partStyle:x}=Ke(),{fonts:a}=He(),[E,H]=ee({}),re=Z(null),b=c(e),v=i(e),ae=b?y.components[b.type]:void 0,{key:C,row:P}=nt(n),ie=ae?.fields?.[C],w=P?tt(ie,P):ie,F=bt(e,n),m=b?.props??{},T=et(w),Te=Xe(w),Ee=St(w),K=b?gt(b.type):null,X=P?st(m[C],P):m[C],ce=!!P&&!(Array.isArray(m[C])&&P.index<m[C].length);W(()=>{if(ut(document))return;re.current?.querySelector(".es-copy [contenteditable='true'], .es-copy textarea, .sf-copybox textarea, .sf-copybox input")?.focus()},[F]);const[Y,de]=ee(0);W(()=>de(0),[F]);const q=!!b&&!ce&&(!v||!w);W(()=>{if(!q||Y>=we)return;const s=setTimeout(()=>de(d=>d+1),Lt);return()=>clearTimeout(s)},[q,Y]);const Ce=q&&Y<we;if(!b||ce)return t(zt,{onBack:l});const z=xt(b.type),ue=z?vt(z,n):null;if(z&&ue){const s=x?.partId===F?x:null,d=z[ue],h=d.writable===!0&&!!v,S=p=>{v&&g.replaceComponent(v.zone,v.index,{...b,props:oe(m,n,"role",p)})};return t(At,{region:d,sizePx:s?.base.sizePx??null,face:se(m,n,s,a),base:s?.base??null,onFollowStyle:h?S:void 0,source:K,slug:Ne(m),onBack:l})}if(!v||!w)return Ce?t("div",{className:"sf-note","aria-busy":"true"}):t($t,{onBack:l,partId:F,why:v?"no field":"no selector"});const $=s=>{g.replaceComponent(v.zone,v.index,{...b,props:s})},J=s=>{if(j(s).hidden!==j(X).hidden||!T){const h=P?ot(m,C,P,s):{...m,[C]:s};h&&$(h);return}dt({node:b,propKey:n,kind:T,zone:v.zone,index:v.index},j(s).text,g.replaceComponent)},Re=X,D=it(b?.type,n),Fe=ve(m,D),V=x?.partId===F?x:null,N=[{partKey:D,face:se(m,D,V,a),sizeGroup:V?.sizeGroup??null,base:V?.base??Vt,style:Fe}],Oe=le(N,s=>s.sizeGroup),fe=at(V?.inks),B=(s,d)=>{let h=m;for(const S of N)h=oe(h,S.partKey,s,d);$(h)},Ie=s=>B("role",s),_e=()=>{let s=m;for(const d of N)s=rt(s,d.partKey);$(s)},Le=s=>{let d=m;for(const h of N)for(const[S,p]of Object.entries(s))d=oe(d,h.partKey,S,p??null);$(d)},Ae=(s,d)=>{const h=N.some(k=>k.style[s]!==void 0),S=le(N,k=>Rt(k,s)),p=S===null,O=`sf-part-${e}-${n}-${s}`;return s==="color"?t(je,{value:p?null:String(S),label:d,colors:fe,onChange:k=>B("color",k)},s):t(be,{label:o(d),icon:Pt[s],className:"sf-part-field",changed:h,htmlFor:O,action:h?t(ye,{label:d,onClear:()=>B(s,null)}):void 0,children:s==="font"?t(ge,{id:O,ariaLabel:o(d),value:!p&&L(String(S))?String(S):void 0,placeholder:p?o("Mixed"):o("Site style"),options:Je.map(k=>({label:k.label,value:k.key})),onChange:k=>B("font",k||null)}):null},s)},pe=T==="text"||T==="textarea",{text:me,hidden:I}=j(X),M=w?.[Ye]?.label??n,he=I?o("Show {label} on the slide",{label:o(M)}):o("Hide {label} on the slide",{label:o(M)}),ze=u("div",{className:"sf-field-head",children:[t(Se,{}),t("span",{className:"sf-field-label sf-field-label--inline",children:o(M)}),pe&&t(Ge,{content:he,children:t("button",{type:"button",className:"sf-field-eye","aria-pressed":I,"aria-label":he,onClick:()=>J({text:me,hidden:!I}),children:I?t(xe,{name:"eye-off",size:14}):t(xe,{name:"eye",size:14})})})]}),Q=!Te&&Ee;return u(_t,{sectionName:ae?.label??b.type,onBack:l,textEditor:u("div",{ref:re,className:"sf-part-text",children:[T?t(Ue,{text:me,onTextChange:s=>J(pe?{text:s,hidden:I}:s),multiline:Qe(T),markup:T!=="plainText",styled:Q,style:N[0].style,base:N[0].base,setValue:Le,colors:fe.map(s=>({name:s.key,label:o(s.name),value:s.value})),placeholder:A(Ze(w))??void 0,ariaLabel:o(M),head:ze,typedOnCanvas:f===F}):t(De,{field:w,name:n,value:Re,onChange:J,id:`sf-part-${e}-${n}`}),Q&&T&&Oe===null&&t("p",{className:"es-field-hint sf-hint-keep",children:o("Fixed size — the site’s Text setting doesn’t resize this.")})]}),children:[K&&t(Pe,{source:K,slug:Ne(m)}),Q&&kt.map(s=>{const d=ke.filter(p=>p.group===s),h=d.filter(p=>N.some(O=>O.style[p.key]!==void 0)).length,S=`sf-part-g-${e}-${n}-${s.replace(/\W+/g,"-")}`;return u(Ve,{id:S,title:o(s),open:E[s]!==!0,onToggle:p=>H(O=>({...O,[s]:!p})),count:h,children:[t(It,{parts:N,onEditStyle:r,onClearAll:_e,onFollowStyle:Ie,kindLabel:ct[D]}),d.map(p=>Ae(p.key,p.label))]},s)})]})}const Vt={fontKey:"",sizePx:16,weight:400,lineRatio:1.4,letterEm:0,align:"left",case:"none",paddingPx:0,widthPx:lt};export{ke as PART_FIELDS,_t as PartPanelBody,ye as PartResetDot,Pe as PartSourceNote,It as PartStyleCard,Ot as PartStyleSelect,Dt as default,se as partFace,Sn as partStyleName};
|
|
1
|
+
"use client";import{jsx as n,Fragment as D,jsxs as h}from"react/jsx-runtime";import{useEffect as $,useRef as Re,useState as Ce}from"react";import{PartResetDot as _e}from"./PartResetDot.js";import{FieldSelect as Fe,InspectorField as Ie}from"efficient-easel/fields";import{SettingsField as ze}from"efficient-easel/panel";import{InspectorUpLevel as z}from"efficient-easel/chrome";import{StylesIcon as Ae,TypeIcon as Le}from"efficient-easel/icons";import{useEasel as Ve}from"efficient-easel/easel";import{TextPartPanel as Be}from"efficient-easel/copy";import{Tooltip as Ke}from"efficient-shell/ui";import{PartTextBox as je,partTextCells as Ge}from"./PartTextBox.js";import he from"./UiIcon.js";import{usePreviewHeader as Me}from"./PreviewHeaderContext.js";import{usePartStyle as Ue}from"./PreviewPartStyleContext.js";import{say as l}from"../lib/editor-words.js";import{readHidable as A,textFieldOffPage as We,textFieldPanelOnly as He}from"../lib/puck/controls.js";import{TEXT_FIELD_MARKER as De}from"../lib/puck/field-markers.js";import{useSectionOps as $e}from"../lib/puck/use-section-ops.js";import{FONT_OPTIONS as Ye,FONT_ROLES as Y,FONT_ROLE_LABELS as X,fontOption as q}from"../lib/fonts.js";import{isMultilineKind as Xe,partPlaceholder as qe,typeInPlaceKind as Je}from"../lib/puck/part-text.js";import{partRowField as Qe}from"../lib/puck/part-row-field.js";import{decodePartKey as Ze,partPropsWithRowValue as et,partRowValue as tt}from"../lib/puck/part-rows.js";import{PART_WIDTH_MAX as nt,propsWithPartStyleValue as L,propsWithoutPartStyle as ot,readPartStyle as ye}from"../lib/puck/part-styles.js";import{partInks as lt}from"../lib/puck/part-inks.js";import{styleKeyForPart as st}from"../lib/sections/section-text-kinds.js";import{commitPartText as rt}from"../lib/puck/part-typing.js";import{keysOnCanvas as it,useCanvasTypingPart as at}from"../lib/puck/canvas-typing.js";import{useEditorHost as ct}from"../lib/editor-host.js";import{SOURCE_LINES as dt,SOURCE_ACTIONS as ut,SOURCE_ACTION_LABEL as ft,partSourceOf as pt,sourceSlugOf as ge}from"../lib/puck/source-bound-parts.js";import{encodePartId as mt,holdsAuthoredText as ht}from"../lib/puck/text-parts.js";import{regionsForSection as yt}from"../lib/sections/section-text-regions.js";import{textRegionOfPartKey as gt}from"../lib/sections/text-regions.js";function J(t){return t?l(t):null}function be(t){return t.kind==="role"?X[t.role]:t.kind==="custom"?"Custom":null}function bt(t){const o=t.role;return o&&Y.includes(o)?{kind:"role",role:o}:null}function xt(t,o){if(!t)return{kind:"unread"};const{faceRole:s,base:r}=t;if(o[s]===r.fontKey)return{kind:"role",role:s};const d=Object.keys(o).filter(i=>o[i]===r.fontKey);return d.length===1?{kind:"role",role:d[0]}:{kind:"custom"}}function Q(t,o,s,r){return bt(ye(t,o))??xt(s,r)}function St(t,o){if(!t.length)return null;const s=o(t[0]);return t.every(r=>o(r)===s)?s:null}const V="";function Pt({face:t,base:o,onPick:s}){const r=t.kind==="role"?t.role:V,d=[{label:l("No style"),value:V},...Y.map(i=>({label:l(X[i]),value:i}))];return n(Fe,{ariaLabel:l("Style"),value:r,options:d,inline:!0,onChange:i=>s(i===V?null:i),renderOption:i=>i.value===V?h(D,{children:[n("span",{className:"es-fsel-label sf-part-style-keep",children:i.label}),n("span",{className:"sf-part-style-aside","aria-hidden":"true",children:l("Section’s own")})]}):n("span",{className:"es-fsel-label",style:{fontFamily:`var(--font-role-${i.value})`},children:i.label}),renderValue:()=>n("span",{style:{fontFamily:o?.fontKey?`var(${q(o.fontKey)?.cssVar})`:void 0,fontWeight:o?.weight},children:J(be(t))}),valueText:i=>J(be(t))??i?.label??""})}function vt({sectionName:t,onBack:o,textEditor:s,styleRow:r,children:d}){return h("div",{className:"sf-part-panel",children:[n(z,{inline:!0,name:l(t),onSelect:o}),s,r,d]})}function xe({source:t,slug:o}){const s=ct(),r=ut[t],d=!r.needsSlug||!!o;return n("div",{className:"sf-note sf-note--source",children:h("p",{className:"es-field-hint sf-hint-keep",children:[l(dt[t]),d?h(D,{children:[" ",n("button",{type:"button",className:"sf-source-open",onClick:()=>{r.type==="storefront-editor:open-menus"?s.send(r.type):o&&s.send(r.type,{slug:o})},children:l(ft)})]}):null]})})}const Se=4,Tt=120;function wt({region:t,sizePx:o,face:s,base:r,onFollowStyle:d,source:i,slug:B,onBack:T}){const O=t.follows;return h("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:l(t.label)})}),n("p",{children:o?l("Its size follows Site styles ▸ {follows} — {px}px right now.",{follows:l(O),px:Math.round(o)}):l("Its size follows Site styles ▸ {follows}.",{follows:l(O)})}),d?n(D,{children:n(ze,{label:l("Style"),icon:n(Ae,{}),hint:l("Every {part} in this section follows it. The face and the size change; the letter case is the section’s own and stays as it is.",{part:l(t.label).toLowerCase()}),children:n(Pt,{face:s,base:r,onPick:d})})}):n("p",{className:"es-field-hint sf-hint-keep",children:l("Only the size follows a site style. This section sets its own font, weight and letter case.")}),i?n(xe,{source:i,slug:B}):null,n(z,{inline:!0,name:l("Page"),onSelect:T})]})}function kt({onBack:t}){return h("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:l("This part is no longer here.")})}),n("p",{children:l("The section it belonged to has been changed or removed.")}),n(z,{inline:!0,name:l("Page"),onSelect:t})]})}function Nt({onBack:t,partId:o,why:s}){return h("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:l("This part's settings did not open.")})}),n("p",{children:l("The words are still on your page and nothing has been lost. The editor could not work out which control belongs to them, which is a fault on our side. Go back and click the section to open its settings instead.")}),n("p",{className:"sf-note-detail",children:h("code",{children:[o," — ",s]})}),n(z,{inline:!0,name:l("Page"),onSelect:t})]})}function Ot({nodeId:t,propKey:o,onBack:s,onEditStyle:r}){const{getItemById:d,getSelectorForId:i,config:B}=Ve(e=>e),T=$e(),O=at(),{partStyle:E}=Ue(),{fonts:R,textStyles:Pe}=Me(),Z=Re(null),u=d(t),p=i(t),ee=u?B.components[u.type]:void 0,{key:x,row:b}=Ze(o),te=ee?.fields?.[x],y=b?Qe(te,b):te,S=mt(t,o),c=u?.props??{},g=Je(y),ne=We(y),oe=ht(y),K=u?pt(u.type):null,j=b?tt(c[x],b):c[x],le=!!b&&!(Array.isArray(c[x])&&b.index<c[x].length);$(()=>{if(it(document))return;Z.current?.querySelector(".es-copy [contenteditable='true'], .es-copy textarea, .sf-copybox textarea, .sf-copybox input")?.focus()},[S]);const[G,se]=Ce(0);$(()=>se(0),[S]);const M=!!u&&!le&&(!p||!y);$(()=>{if(!M||G>=Se)return;const e=setTimeout(()=>se(a=>a+1),Tt);return()=>clearTimeout(e)},[M,G]);const ve=M&&G<Se;if(!u||le)return n(kt,{onBack:s});const C=yt(u.type),re=C?gt(C,o):null;if(C&&re){const e=E?.partId===S?E:null,a=C[re],f=a.writable===!0&&!!p,N=H=>{p&&T.replaceComponent(p.zone,p.index,{...u,props:L(c,o,"role",H)})};return n(wt,{region:a,sizePx:e?.base.sizePx??null,face:Q(c,o,e,R),base:e?.base??null,onFollowStyle:f?N:void 0,source:K,slug:ge(c),onBack:s})}if(!p||!y)return ve?n("div",{className:"sf-note","aria-busy":"true"}):n(Nt,{onBack:s,partId:S,why:p?"no field":"no selector"});const _=e=>{T.replaceComponent(p.zone,p.index,{...u,props:e})},U=e=>{if(A(e).hidden!==A(j).hidden||!g){const f=b?et(c,x,b,e):{...c,[x]:e};f&&_(f);return}rt({node:u,propKey:o,kind:g,zone:p.zone,index:p.index},A(e).text,T.replaceComponent)},Te=j,F=st(u?.type,o),P=ye(c,F),w=E?.partId===S?E:null,m=[{partKey:F,face:Q(c,F,w,R),sizeGroup:w?.sizeGroup??null,base:w?.base??Ct,style:P}],we=St(m,e=>e.sizeGroup),ke=lt(w?.inks),k=(e,a)=>{let f=c;for(const N of m)f=L(f,N.partKey,e,a);_(f)},Ne=e=>k("role",e),ie=e=>{let a=c;for(const f of m)for(const[N,H]of Object.entries(e))a=L(a,f.partKey,N,H??null);_(a)},W=g==="text"||g==="textarea",{text:ae,hidden:v}=A(j),I=y?.[De]?.label??o,ce=v?l("Show {label} on the slide",{label:l(I)}):l("Hide {label} on the slide",{label:l(I)}),de=h("div",{className:"sf-field-head",children:[n(Le,{}),n("span",{className:"sf-field-label sf-field-label--inline",children:l(I)}),W&&n(Ke,{content:ce,children:n("button",{type:"button",className:"sf-field-eye","aria-pressed":v,"aria-label":ce,onClick:()=>U({text:ae,hidden:!v}),children:v?n(he,{name:"eye-off",size:14}):n(he,{name:"eye",size:14})})})]}),ue=!ne&&oe,Oe=!!g&&(He(y)||ne||v||!oe||g!=="plainText"),fe=Q(c,F,w,R),pe=fe.kind==="role"?fe.role:null,me=Object.entries(P).filter(([e,a])=>e!=="role"&&a!==void 0).length,Ee=()=>{let e=c;for(const a of m){const f=a.style.role;e=ot(e,a.partKey),f&&(e=L(e,a.partKey,"role",f))}_(e)};return h(vt,{sectionName:ee?.label??u.type,onBack:s,textEditor:n("div",{ref:Z,className:"sf-part-text",children:Oe?n(je,{text:ae,onTextChange:e=>U(W?{text:e,hidden:v}:e),multiline:Xe(g),markup:g!=="plainText",styled:!1,style:m[0].style,base:m[0].base,setValue:ie,colors:ke.map(e=>({name:e.key,label:l(e.name),value:e.value})),placeholder:J(qe(y))??void 0,ariaLabel:l(I),head:de,typedOnCanvas:O===S}):g?W?de:null:n(Ie,{field:y,name:o,value:Te,onChange:U,id:`sf-part-${t}-${o}`})}),children:[K&&n(xe,{source:K,slug:ge(c)}),ue&&n(Be,{style:{value:pe??"",options:[{value:"",label:l("No style"),description:l("Section’s own")},...Y.map(e=>({value:e,label:l(X[e]),description:q(R[e])?.label}))],onChange:e=>Ne(e||null),changed:me>0,onClearChanges:me>0?Ee:void 0,onEditStyles:r},font:{value:P.font??"",styleValue:q(m[0].base.fontKey)?.label,options:Ye.map(e=>({label:e.label,value:e.key})),onChange:e=>k("font",e||null)},italic:{value:P.italic,styleValue:Rt(Pe,pe),onChange:e=>k("italic",e??null)},cells:Ge(m[0].style,m[0].base,ie),align:{value:P.align??"",styleValue:m[0].base.align,onChange:e=>k("align",e||null)},letterCase:{value:P.case??"",styleValue:m[0].base.case,onChange:e=>k("case",e||null)}}),ue&&we===null&&n("p",{className:"es-field-hint sf-hint-keep",children:l("Fixed size — the site’s Text setting doesn’t resize this.")})]})}const Et={heading:"heading-1",heading2:"heading-2",heading3:"heading-3",body:"body-1",label:"body-5"};function Rt(t,o){const s=o?Et[o]:void 0;return!s||!Array.isArray(t)?!1:t.find(d=>d?.id===s)?.values?.italic===!0}const Ct={fontKey:"",sizePx:16,weight:400,lineRatio:1.4,letterEm:0,align:"left",case:"none",paddingPx:0,widthPx:nt};export{vt as PartPanelBody,_e as PartResetDot,xe as PartSourceNote,Pt as PartStyleSelect,Ot as default,Q as partFace};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import { type CopyThemeColor } from "efficient-easel/copy";
|
|
2
|
+
import { type CopyCell, type CopyThemeColor } from "efficient-easel/copy";
|
|
3
3
|
import { type PartStyle, type PartStyleBase } from "../lib/puck/part-styles.js";
|
|
4
4
|
export type PartStylePatch = {
|
|
5
5
|
[K in keyof PartStyle]?: PartStyle[K] | null;
|
|
6
6
|
};
|
|
7
|
+
export declare function partTextCells(style: PartStyle, base: PartStyleBase, setValue: (patch: PartStylePatch) => void): CopyCell[];
|
|
7
8
|
export declare function PartTextBox({ text, onTextChange, multiline, markup, styled, style, base, setValue, colors, placeholder, ariaLabel, head, typedOnCanvas, }: {
|
|
8
9
|
text: string;
|
|
9
10
|
onTextChange: (next: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as g,jsxs as _}from"react/jsx-runtime";import{COPY_CELLS as r,CopyBox as T}from"efficient-easel/copy";import{PaddingYIcon as S,WidthIcon as A}from"efficient-easel/icons";import{say as u}from"../lib/editor-words.js";import{SHOP_MARKUP as C}from"../lib/markup.js";import{partTextTools as I}from"../lib/puck/canvas-typing.js";import{PART_PADDING_MAX as R,PART_PADDING_MIN as D,PART_PADDING_STEP as v,PART_WIDTH_MAX as z,PART_WIDTH_MIN as H,PART_WIDTH_STEP as w,partSpacingOf as N}from"../lib/puck/part-styles.js";const M=["left","center","right","justify"];function j(i,a,e){const l=N(i),t=i.size??a.sizePx;return[{...r.fontSize,value:i.size,styleValue:Math.round(a.sizePx),onChange:n=>e({size:n??null})},{...r.lineHeight,value:l.lineHeight,styleValue:a.lineRatio,onChange:n=>e(n===void 0?{lineHeight:null,line:null}:{lineHeight:n})},{...r.letterSpacing,scale:t,value:l.letterSpacingEm,styleValue:a.letterEm,onChange:n=>e(n===void 0?{letterSpacing:null,letter:null}:{letterSpacing:n})},{...r.paragraphSpacing,value:i.paragraphSpacing,styleValue:0,onChange:n=>e({paragraphSpacing:n??null})},{key:"padding",name:u("Padding"),icon:g(S,{}),unit:"px",step:v,shiftStep:10,min:D,max:R,value:i.padding,styleValue:a.paddingPx,onChange:n=>e({padding:n??null})},{key:"width",name:u("Width"),icon:g(A,{}),unit:"px",step:w,shiftStep:100,min:H,max:z,value:i.width,styleValue:a.widthPx,onChange:n=>e({width:n??null})}]}function X({text:i,onTextChange:a,multiline:e,markup:l=!0,styled:t=!0,style:n,base:c,setValue:p,colors:d,placeholder:s,ariaLabel:h,head:f,typedOnCanvas:P=!1}){const m=j(n,c,p),x=I(l,e);return _("div",{className:"sf-part-textbox",children:[f,g(T,{value:i,onChange:a,multiline:e,placeholder:s,ariaLabel:h,rules:C,tools:x,barShows:P?"focus":"always",colors:l?d:[],align:t?{value:n.align??c.align,allow:M,onChange:o=>p({align:o})}:void 0,letterCase:t?{value:n.case==="capitalize"?"":n.case??"",onChange:o=>p({case:o||null})}:void 0,cells:t?m:void 0})]})}export{X as PartTextBox,j as partTextCells};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as n,jsxs as
|
|
1
|
+
"use client";import{jsx as n,jsxs as m,Fragment as v}from"react/jsx-runtime";import{useState as ae}from"react";import{useEasel as le}from"efficient-easel/easel";import{headWords as ce,InspectorHead as pe,InspectorIconButton as A}from"efficient-easel/chrome";import{DuplicateIcon as de,TrashIcon as me}from"efficient-easel/icons";import{panelFieldsOf as fe}from"../lib/puck/panel-fields.js";import{TICKER_PART_LABEL as C}from"./PreviewTickerContext.js";import ue from"./SectionIcon.js";import{PanelHideButton as R}from"./SidePanelHead.js";import{useEditorSession as he}from"../lib/editor-session-context.js";import{say as o}from"../lib/editor-words.js";import we,{HintsToggle as Se,SHOW_HINTS_DEFAULT as be}from"./WebsiteSettingsPanel.js";import ge from"./ChatSettingsPanel.js";import ke from"./SocialLinksPanel.js";import ve from"./TickerSettingsPanel.js";import Pe,{PartSourceNote as Ee}from"./PartSettingsPanel.js";import ye from"./DuplicateToPageMenu.js";import{useStorefrontDocument as Ie}from"./StorefrontDocumentContext.js";import{usePreviewHeader as Le}from"./PreviewHeaderContext.js";import{useSectionOps as Oe}from"../lib/puck/use-section-ops.js";import{SELECTION_MODE as Te}from"../lib/editor-screen.js";import{usePreviewParts as Ne}from"./PreviewPartsContext.js";import{entryPartsOf as He,SectionTextEntries as _e}from"./SectionTextEntries.js";import{SectionTextSuppressProvider as De}from"../lib/puck/section-text-suppress.js";import{HEADER_TYPE as Ae,ROOT_ZONE as x}from"../lib/puck/content-tree.js";import{websiteDuplicateBlocked as Ce}from"../lib/puck/every-page.js";import{FOOTER_TYPE as P}from"../lib/puck/footer-blocks.js";import Re from"./SwitchToBoxFooter.js";import{SiteFields as F}from"./SiteFields.js";import{SettingsSwitch as xe}from"efficient-easel/panel";import{foldTopTier as Fe}from"../lib/puck/field-groups.js";import{FoldHeadingScope as Be}from"../lib/puck/panel-heading-scope.js";import{partRowField as ze}from"../lib/puck/part-row-field.js";import{decodePartKey as Ke,partRowHeadLabel as Me}from"../lib/puck/part-rows.js";import{encodePartId as We,partHeadLabel as je,partLabel as Ue,sectionTextParts as Ye}from"../lib/puck/text-parts.js";import{partSourceOf as Ze,sourceSlugOf as $e}from"../lib/puck/source-bound-parts.js";const Bt=Te,zt={kind:"header"},Kt={kind:"website"},Mt={kind:"chat"},Wt={kind:"social"},g="Part";function qe(e){return o("Part of {name}",{name:o(e)})}function Ge(e,i,r){const l=e.describeNode(i);return{name:r,kindLabel:l?qe(l.label):o(g)}}function Je(e){switch(e){case"Header":return{title:o("Header settings belong to a website."),own:o("Each website created from this template sets its own header afterwards.")};case"Appearance":return{title:o("Appearance settings belong to a website."),own:o("Each website created from this template sets its own appearance afterwards.")};case"Live chat":return{title:o("Live chat settings belong to a website."),own:o("Each website created from this template sets its own live chat afterwards.")};case"Social link":return{title:o("Social link settings belong to a website."),own:o("Each website created from this template sets its own social link afterwards.")};default:return{title:o("{what} settings belong to a website.",{what:e}),own:o("Each website created from this template sets its own {what} afterwards.",{what:e.toLowerCase()})}}}function B({what:e}){const i=Je(e);return m("div",{className:"sf-note",children:[n("p",{children:n("strong",{children:i.title})}),m("p",{children:[o("A template is a blueprint — it has no website of its own, so there is nothing here to change.")," ",i.own]})]})}const Qe={header:{name:"Header",kindLabel:"Site settings",icon:"header",render:(e,i)=>{const r=i.hostPanels?.header;return r?n(r,{placeholderMode:i.capabilities.placeholderFrames,tokenRef:i.tokenRef,siteId:i.siteId,websiteName:i.websiteName,onOpenWebsiteSettings:i.onOpenWebsiteSettings,onAuthExpired:()=>i.notifyParent("storefront-editor:auth-expired")}):null}},website:{name:"Appearance",kindLabel:"Site settings",icon:"website",render:(e,i)=>n(we,{themeFromDocument:!i.capabilities.hasSiteTheme,tokenRef:i.tokenRef,siteId:i.siteId,onNotify:i.onNotify})},chat:{name:"Live chat",kindLabel:"Site settings",icon:"chat",render:()=>n(ge,{})},social:{name:"Social links",kindLabel:"Site settings",icon:"social",render:()=>n(ke,{unavailable:n(B,{what:"Social link"})})},ticker:{name:C,kindLabel:g,icon:"ticker",head:(e,i)=>e.kind==="ticker"?Ge(i,e.heroId,o(C)):null,render:e=>n(ve,{heroId:e.kind==="ticker"?e.heroId:""})},part:{name:g,kindLabel:g,icon:"Text",head:(e,i)=>{if(e.kind!=="part")return null;const r=i.describeNode(e.nodeId);if(!r)return null;const{key:l,row:u}=Ke(e.propKey),h=u?ze(r.fields[l],u):r.fields[l],f=Me(o(je(Ue(h??{},l))),u),p=ce({name:f,tier:"part",of:o(r.label)},{partOf:({name:w})=>o("Part of {name}",{name:w})});return{name:p.name,kindLabel:p.kind}},render:(e,i)=>e.kind==="part"?n(Pe,{nodeId:e.nodeId,propKey:e.propKey,onBack:()=>i.onSelectNode(e.nodeId),onEditStyle:i.onOpenSiteStyles}):null}},Ve=new Set(["header","website","chat"]);function Xe(e,i){if(e==="puck")return null;const r=Qe[e];return Ve.has(e)&&!i.hasSiteSettings?{...r,kindLabel:"Not part of a template",render:()=>n(B,{what:r.name})}:r}function et({mode:e,onOpenWebsiteSettings:i,onOpenSiteStyles:r,onSelectNode:l,hideNodeActions:u=!1,onNotify:h,onHidePanel:f}){const{capabilities:p,tokenRef:w,notifyParent:z,currentSlug:K,siteId:E,runAuthed:M,readOnly:W}=Ie(),{websiteName:j}=Le(),S=Oe({readOnly:W}),{select:U}=Ne(),{selectedItem:t,getItemById:Y,getSelectorForId:Z,config:d,appState:$}=le(c=>c),q=fe(d,t?{type:t.type,props:t.props}:null),y=t?Ye(q??d.components[t.type]?.fields,t.props):[],G=c=>d.components[c]?.label??c,s=t?Z(t.props.id):void 0,a=Xe(e.kind,p),J=he(),I={capabilities:p,tokenRef:w,hostPanels:J.chrome?.panels,describeNode:c=>{const b=Y(c);if(!b)return null;const D=d.components[b.type];return{type:b.type,label:D?.label??b.type,fields:D?.fields??{}}},siteId:E,websiteName:j??null,notifyParent:z,onNotify:h,onOpenWebsiteSettings:i,onOpenSiteStyles:r,onSelectNode:l},L=a?.head?.(e,I)??null,Q=L?.name??(a?o(a.name):t?o(G(t.type)):o("Page settings")),V=L?.kindLabel??(a?o(a.kindLabel):t?s&&s.zone!==x?o("Block"):o("Section"):o("Page")),X=a?a.icon:t?t.type:"page",O=a?null:t?d.components[t.type]?.fields??null:d.root?.fields??null,ee=O?Fe(O):2,T=e.kind==="puck"&&t?Ze(t.type):null,te=!!t&&!!s&&s.zone===x&&t.type!==P&&t.type!==Ae,k=Ce($?.data,t),ne=()=>{k||s&&S.duplicateComponent(s.zone,s.index)},oe=()=>{s&&(S.removeComponent(s.zone,s.index),S.select(null))},ie=t?d.components[t.type]?.defaultProps?.previewHover:void 0,N=e.kind==="puck"&&!!t&&!!s&&ie!==void 0,H=N&&t.props.previewHover===!0,re=()=>{!t||!s||S.replaceComponent(s.zone,s.index,{...t,props:{...t.props,previewHover:!H}})},[_,se]=ae(be);return m("div",{className:`es-sidepanel es-sidepanel--right sf-panel sf-panel--right${_||!(!a&&!!t)?"":" sf-hints-folded"}`,children:[n(pe,{icon:n(ue,{type:X,size:15}),name:Q,kind:V,actions:!u&&e.kind==="puck"&&t&&t.type!==P?m(v,{children:[n(A,{label:o("Duplicate section"),title:k??void 0,disabled:k!==null,onClick:ne,children:n(de,{size:15})}),te&&p.hasSiteSettings&&n(ye,{node:t,currentSlug:K,siteId:E??void 0,tokenRef:w,runAuthed:M,onNotify:h}),n(A,{label:o("Remove section"),danger:!0,onClick:oe,children:n(me,{size:15})}),f?n(R,{side:"right",onHide:f,divider:!0}):null]}):f?n(R,{side:"right",onHide:f}):void 0}),N&&m("div",{className:"sf-preview-pin",children:[m("div",{className:"sf-preview-pin-text",children:[n("span",{className:"sf-preview-pin-label",children:o("Preview hover state")}),n("span",{className:"sf-preview-pin-hint",children:o("not shown live")})]}),n(xe,{checked:H,onChange:re,ariaLabel:o("Preview hover state")})]}),n(Be,{tier:ee,children:n("div",{className:"sf-insp-body es-insp-body sf-scroll",children:a?a.render(e,I):t?m(v,{children:[t.type===P&&p.hasSiteSettings&&n(Re,{}),n(De,{children:n(F,{entries:n(_e,{parts:y,heading:!1,onOpen:c=>U(We(t.props.id,c))}),entryCount:He(y).length})}),T&&n(Ee,{source:T,slug:$e(t?.props)}),n(Se,{shown:_,onChange:se})]}):n(v,{children:n(F,{})})})})]})}export{Mt as CHAT_MODE,zt as HEADER_MODE,Bt as PUCK_MODE,Wt as SOCIAL_MODE,Kt as WEBSITE_MODE,et as default,Xe as resolvePanel};
|
|
@@ -846,8 +846,13 @@
|
|
|
846
846
|
came to hang 6px OUTSIDE the panel at every width under 280 (measured: gap
|
|
847
847
|
-6.0px at 260 and at 220, against 0.0 at the default 320). One name, read
|
|
848
848
|
by the padding, by the narrow override, and by anything that undoes it. */
|
|
849
|
-
|
|
850
|
-
|
|
849
|
+
/* THE SIDES ARE EASEL'S NOW (one text panel W1): the body wears
|
|
850
|
+
`es-insp-body` (efficient-easel 9.0.0 chrome.css), the one row inset both
|
|
851
|
+
editors share — 16px, 8px under a 284px panel, the numbers this sheet
|
|
852
|
+
measured and set (card 66212, 2026-10-13). The token stays, as a name for
|
|
853
|
+
that inset, because rules below read it to reach the panel's edge. */
|
|
854
|
+
--sf-insp-pad-x: var(--es-insp-pad-x, var(--space-16));
|
|
855
|
+
padding-block: 4px 18px;
|
|
851
856
|
|
|
852
857
|
/* THE DROPDOWN ARROW, WRITTEN ONCE — card 66399.c.
|
|
853
858
|
Read by `.sf-insp-body select` at rest AND by the hover rule beside it. The
|
|
@@ -912,13 +917,8 @@
|
|
|
912
917
|
and 10 has nothing to spare, and type is paid vertically as well — card 66206
|
|
913
918
|
has just set the row rhythm to 16px, which shrinking type would hand straight
|
|
914
919
|
back. The padding was the horizontal cost, so the padding is what moved. */
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
/* The TOKEN, not `padding-inline` — so everything that reads the padding
|
|
918
|
-
narrows with it, instead of only the padding itself. */
|
|
919
|
-
--sf-insp-pad-x: var(--space-8);
|
|
920
|
-
}
|
|
921
|
-
}
|
|
920
|
+
/* The narrow inset (8px under a 284px panel) is easel's `.es-insp-body` rule
|
|
921
|
+
now; `--sf-insp-pad-x` follows it, so every reader narrows with it. */
|
|
922
922
|
|
|
923
923
|
/* Floating-styled form controls for Puck's native fields — and ONLY those.
|
|
924
924
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
export declare const BORDER_MAX = 20;
|
|
3
|
+
export declare const BORDER_STYLES: readonly ["solid", "dashed", "dotted"];
|
|
4
|
+
export type BorderStyle = (typeof BORDER_STYLES)[number];
|
|
5
|
+
export declare const BORDER_SIDES: readonly ["top", "right", "bottom", "left"];
|
|
6
|
+
export type BorderSide = (typeof BORDER_SIDES)[number];
|
|
7
|
+
export type BorderValue = {
|
|
8
|
+
width?: number | null;
|
|
9
|
+
top?: number | null;
|
|
10
|
+
right?: number | null;
|
|
11
|
+
bottom?: number | null;
|
|
12
|
+
left?: number | null;
|
|
13
|
+
style?: BorderStyle | string | null;
|
|
14
|
+
color?: string | null;
|
|
15
|
+
};
|
|
16
|
+
export declare const SECTION_BORDER_CLASS = "sf-section-border";
|
|
17
|
+
export declare function hasOwnBorder(value: BorderValue | null | undefined): boolean;
|
|
18
|
+
export declare function borderVars(value: BorderValue | null | undefined, { phone }?: {
|
|
19
|
+
phone?: boolean;
|
|
20
|
+
}): Record<string, string> | undefined;
|
|
21
|
+
export declare function sectionBorderStyle(desktop: BorderValue | null | undefined, phone: BorderValue | null | undefined): CSSProperties | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const h=20,i=["solid","dashed","dotted"],c=["top","right","bottom","left"],b="sf-section-border",p=/^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i,f=t=>typeof t=="number"&&Number.isFinite(t)?`${Math.min(20,Math.max(0,Math.round(t)))}px`:void 0;function u(t){return r(t)!==void 0}function r(t,{phone:n=!1}={}){if(!t||typeof t!="object")return;const e=n?"-phone":"",o={};for(const s of c){const d=f(t[s])??f(t.width);d!==void 0&&(o[`--sf-border-${s}-width${e}`]=d)}return typeof t.style=="string"&&i.includes(t.style)&&(o[`--sf-border-style${e}`]=t.style),typeof t.color=="string"&&p.test(t.color)&&(o[`--sf-border-color${e}`]=t.color.toLowerCase()),Object.keys(o).length?o:void 0}function x(t,n){const e=r(t),o=r(n,{phone:!0});return e||o?{...e,...o}:void 0}export{h as BORDER_MAX,c as BORDER_SIDES,i as BORDER_STYLES,b as SECTION_BORDER_CLASS,r as borderVars,u as hasOwnBorder,x as sectionBorderStyle};
|
|
@@ -186,6 +186,14 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
186
186
|
readonly "Bold is the weight above \u2014 one value, two ways to set it.": "Bold is the weight above — one value, two ways to set it.";
|
|
187
187
|
readonly "Bold word": "Bold word";
|
|
188
188
|
readonly "Booking Form": "Booking Form";
|
|
189
|
+
readonly Border: "Border";
|
|
190
|
+
readonly "Border bottom": "Border bottom";
|
|
191
|
+
readonly "Border color": "Border color";
|
|
192
|
+
readonly "Border left": "Border left";
|
|
193
|
+
readonly "Border right": "Border right";
|
|
194
|
+
readonly "Border style": "Border style";
|
|
195
|
+
readonly "Border top": "Border top";
|
|
196
|
+
readonly "Border width": "Border width";
|
|
189
197
|
readonly Borders: "Borders";
|
|
190
198
|
readonly Bottom: "Bottom";
|
|
191
199
|
readonly "Bottom center": "Bottom center";
|
|
@@ -243,7 +251,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
243
251
|
readonly "Cell width": "Cell width";
|
|
244
252
|
readonly Center: "Center";
|
|
245
253
|
readonly "Changed on every page": "Changed on every page";
|
|
246
|
-
readonly "Changes apply to all selected.": "Changes apply to all selected.";
|
|
247
254
|
readonly "Changes not live yet": "Changes not live yet";
|
|
248
255
|
readonly Chart: "Chart";
|
|
249
256
|
readonly "Chart style": "Chart style";
|
|
@@ -260,7 +267,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
260
267
|
readonly "City strip": "City strip";
|
|
261
268
|
readonly "Claims bars": "Claims bars";
|
|
262
269
|
readonly "Claims panel (rows + defect bars)": "Claims panel (rows + defect bars)";
|
|
263
|
-
readonly Clear: "Clear";
|
|
264
270
|
readonly "Clear change": "Clear change";
|
|
265
271
|
readonly "Clear change: {label}": "Clear change: {label}";
|
|
266
272
|
readonly "Clear colors": "Clear colors";
|
|
@@ -328,6 +334,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
328
334
|
readonly "Dark band": "Dark band";
|
|
329
335
|
readonly Darken: "Darken";
|
|
330
336
|
readonly "Darken style": "Darken style";
|
|
337
|
+
readonly Dashed: "Dashed";
|
|
331
338
|
readonly "Data points": "Data points";
|
|
332
339
|
readonly Date: "Date";
|
|
333
340
|
readonly "Deck / standfirst": "Deck / standfirst";
|
|
@@ -368,6 +375,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
368
375
|
readonly "Donut (split of a whole)": "Donut (split of a whole)";
|
|
369
376
|
readonly "Dot \u25CF": "Dot ●";
|
|
370
377
|
readonly Dots: "Dots";
|
|
378
|
+
readonly Dotted: "Dotted";
|
|
371
379
|
readonly Down: "Down";
|
|
372
380
|
readonly "Drop in your own sanitized HTML.": "Drop in your own sanitized HTML.";
|
|
373
381
|
readonly "Duplicate section": "Duplicate section";
|
|
@@ -378,6 +386,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
378
386
|
readonly "Dynamic Pages": "Dynamic Pages";
|
|
379
387
|
readonly "EU Tyre Label": "EU Tyre Label";
|
|
380
388
|
readonly "Each block": "Each block";
|
|
389
|
+
readonly "Each side": "Each side";
|
|
381
390
|
readonly "Each website created from this template sets its own appearance afterwards.": "Each website created from this template sets its own appearance afterwards.";
|
|
382
391
|
readonly "Each website created from this template sets its own header afterwards.": "Each website created from this template sets its own header afterwards.";
|
|
383
392
|
readonly "Each website created from this template sets its own live chat afterwards.": "Each website created from this template sets its own live chat afterwards.";
|
|
@@ -449,11 +458,9 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
449
458
|
readonly "Follow the page": "Follow the page";
|
|
450
459
|
readonly "Follow the slideshow": "Follow the slideshow";
|
|
451
460
|
readonly "Follows Desktop": "Follows Desktop";
|
|
452
|
-
readonly "Follows no style \u2014 change": "Follows no style — change";
|
|
453
461
|
readonly "Follows the section's Corners until you set a number here.": "Follows the section's Corners until you set a number here.";
|
|
454
462
|
readonly "Follows the site": "Follows the site";
|
|
455
463
|
readonly "Follows the style": "Follows the style";
|
|
456
|
-
readonly "Follows {name} \u2014 change": "Follows {name} — change";
|
|
457
464
|
readonly Font: "Font";
|
|
458
465
|
readonly "Footer Box": "Footer Box";
|
|
459
466
|
readonly "Footer \u00B7 on every page": "Footer · on every page";
|
|
@@ -608,6 +615,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
608
615
|
readonly "Leave a blank line between paragraphs to start a new one.": "Leave a blank line between paragraphs to start a new one.";
|
|
609
616
|
readonly "Leave a field blank to use the built-in wording.": "Leave a field blank to use the built-in wording.";
|
|
610
617
|
readonly Left: "Left";
|
|
618
|
+
readonly "Left and right": "Left and right";
|
|
611
619
|
readonly "Left of the copy": "Left of the copy";
|
|
612
620
|
readonly "Legal & documents": "Legal & documents";
|
|
613
621
|
readonly "Legal Line": "Legal Line";
|
|
@@ -673,7 +681,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
673
681
|
readonly "Milestone title.": "Milestone title.";
|
|
674
682
|
readonly Milestones: "Milestones";
|
|
675
683
|
readonly Mixed: "Mixed";
|
|
676
|
-
readonly "Mixed styles": "Mixed styles";
|
|
677
684
|
readonly "Mockup Card": "Mockup Card";
|
|
678
685
|
readonly "Mockup card": "Mockup card";
|
|
679
686
|
readonly "Mockup position": "Mockup position";
|
|
@@ -822,7 +829,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
822
829
|
readonly "Reel label": "Reel label";
|
|
823
830
|
readonly "Refresh now": "Refresh now";
|
|
824
831
|
readonly "Region \u00B7 country": "Region · country";
|
|
825
|
-
readonly Regular: "Regular";
|
|
826
832
|
readonly "Related Products": "Related Products";
|
|
827
833
|
readonly "Remove section": "Remove section";
|
|
828
834
|
readonly "Repeating full-width rows \u2014 eyebrow, title and copy beside a numbered close-up image, alternating sides each row.": "Repeating full-width rows — eyebrow, title and copy beside a numbered close-up image, alternating sides each row.";
|
|
@@ -885,7 +891,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
885
891
|
readonly "Select a word, then press the highlighter.": "Select a word, then press the highlighter.";
|
|
886
892
|
readonly "Selector guide (pills + results)": "Selector guide (pills + results)";
|
|
887
893
|
readonly "Selector pills": "Selector pills";
|
|
888
|
-
readonly Semibold: "Semibold";
|
|
889
894
|
readonly Separator: "Separator";
|
|
890
895
|
readonly "Series title": "Series title";
|
|
891
896
|
readonly Serif: "Serif";
|
|
@@ -914,7 +919,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
914
919
|
readonly "Signup Form": "Signup Form";
|
|
915
920
|
readonly Simple: "Simple";
|
|
916
921
|
readonly "Site settings": "Site settings";
|
|
917
|
-
readonly "Site style": "Site style";
|
|
918
922
|
readonly "Site styles": "Site styles";
|
|
919
923
|
readonly "Six across": "Six across";
|
|
920
924
|
readonly "Six stagger": "Six stagger";
|
|
@@ -1058,7 +1062,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
1058
1062
|
readonly "This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.": "This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.";
|
|
1059
1063
|
readonly "This site has {n} color theme of its own. Clearing takes them away and puts back the four the shop supplies.": "This site has {n} color theme of its own. Clearing takes them away and puts back the four the shop supplies.";
|
|
1060
1064
|
readonly "This site has {n} color themes of its own. Clearing takes them away and puts back the four the shop supplies.": "This site has {n} color themes of its own. Clearing takes them away and puts back the four the shop supplies.";
|
|
1061
|
-
readonly "This text follows the site style.": "This text follows the site style.";
|
|
1062
1065
|
readonly "This ticker\u2019s hero is no longer on the page.": "This ticker’s hero is no longer on the page.";
|
|
1063
1066
|
readonly "Three across": "Three across";
|
|
1064
1067
|
readonly "Three ladder": "Three ladder";
|
|
@@ -1074,6 +1077,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
1074
1077
|
readonly Title: "Title";
|
|
1075
1078
|
readonly Tone: "Tone";
|
|
1076
1079
|
readonly Top: "Top";
|
|
1080
|
+
readonly "Top and bottom": "Top and bottom";
|
|
1077
1081
|
readonly "Top border": "Top border";
|
|
1078
1082
|
readonly "Top center": "Top center";
|
|
1079
1083
|
readonly "Top left": "Top left";
|
|
@@ -1173,6 +1177,7 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
1173
1177
|
readonly manifesto: "manifesto";
|
|
1174
1178
|
readonly "not set": "not set";
|
|
1175
1179
|
readonly "not shown live": "not shown live";
|
|
1180
|
+
readonly part: "part";
|
|
1176
1181
|
readonly px: "px";
|
|
1177
1182
|
readonly "the Text style in Site styles": "the Text style in Site styles";
|
|
1178
1183
|
readonly "the admin": "the admin";
|
|
@@ -1185,7 +1190,6 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
1185
1190
|
readonly "videos only": "videos only";
|
|
1186
1191
|
readonly "{face} is loaded without an italic, so it cannot be set in italic. Slanting it would deform the letters rather than style them.": "{face} is loaded without an italic, so it cannot be set in italic. Slanting it would deform the letters rather than style them.";
|
|
1187
1192
|
readonly "{grade} on the button": "{grade} on the button";
|
|
1188
|
-
readonly "{kind} \u00B7 every row": "{kind} · every row";
|
|
1189
1193
|
readonly "{label} hex code": "{label} hex code";
|
|
1190
1194
|
readonly "{label} {n}": "{label} {n}";
|
|
1191
1195
|
readonly "{label} \u2014 row {n}": "{label} — row {n}";
|
|
@@ -1193,11 +1197,9 @@ export declare const WEB_BUILDER_WORDS: {
|
|
|
1193
1197
|
readonly "{name} (unavailable)": "{name} (unavailable)";
|
|
1194
1198
|
readonly "{name} is on this section": "{name} is on this section";
|
|
1195
1199
|
readonly "{name} \u2014 renamed in the Console: {place}.": "{name} — renamed in the Console: {place}.";
|
|
1196
|
-
readonly "{n} changed": "{n} changed";
|
|
1197
1200
|
readonly "{n} cities": "{n} cities";
|
|
1198
1201
|
readonly "{n} city": "{n} city";
|
|
1199
1202
|
readonly "{n} of {total} layouts": "{n} of {total} layouts";
|
|
1200
|
-
readonly "{n} selected": "{n} selected";
|
|
1201
1203
|
readonly "{value} from {from}": "{value} from {from}";
|
|
1202
1204
|
readonly "{value} on desktop": "{value} on desktop";
|
|
1203
1205
|
readonly "{what} settings belong to a website.": "{what} settings belong to a website.";
|