efficient-web-builder 21.0.0 → 22.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +196 -0
- package/dist/components/AnimatedStat.js +1 -1
- package/dist/components/Banner.js +1 -1
- package/dist/components/Cards.js +1 -1
- package/dist/components/CategoryBar.js +1 -1
- package/dist/components/ChartSection.js +1 -1
- package/dist/components/Countdown.js +1 -1
- package/dist/components/DealerFinder.d.ts +12 -0
- package/dist/components/DealerFinder.js +1 -0
- package/dist/components/DocMasthead.js +1 -1
- package/dist/components/DocMetaCards.js +1 -1
- package/dist/components/DocTabs.js +1 -1
- package/dist/components/FeaturedCover.js +1 -1
- package/dist/components/Footprint.d.ts +8 -1
- package/dist/components/Footprint.js +5 -5
- package/dist/components/HeroPoster.d.ts +2 -1
- package/dist/components/HeroPoster.js +1 -1
- package/dist/components/HeroSingle.d.ts +3 -1
- package/dist/components/HeroSingle.js +4 -4
- package/dist/components/HeroSlide.d.ts +2 -1
- package/dist/components/HeroSlide.js +1 -1
- package/dist/components/ImageBlock.d.ts +2 -1
- package/dist/components/ImageBlock.js +1 -1
- package/dist/components/KeyFeatures.js +1 -1
- package/dist/components/LocationGroupHeader.js +1 -1
- package/dist/components/Logos.js +1 -1
- package/dist/components/LongRead.js +1 -1
- package/dist/components/Manifesto.js +1 -1
- package/dist/components/Masthead.js +1 -1
- package/dist/components/MediaUploadField.d.ts +3 -1
- package/dist/components/MediaUploadField.js +1 -1
- package/dist/components/MockupSection.js +1 -1
- package/dist/components/OrderSummary.js +1 -1
- package/dist/components/PagesPanel.js +1 -1
- package/dist/components/ParagraphsA.js +1 -1
- package/dist/components/PartSettingsPanel.d.ts +2 -1
- package/dist/components/PartSettingsPanel.js +1 -1
- package/dist/components/PinnedChromeLoadNotice.d.ts +12 -2
- package/dist/components/PinnedChromeLoadNotice.js +1 -1
- package/dist/components/PostCard.js +1 -1
- package/dist/components/ProcessSteps.js +1 -1
- package/dist/components/Prose.js +1 -1
- package/dist/components/SectionEditor.js +1 -1
- package/dist/components/SectionEyebrow.js +1 -1
- package/dist/components/SectionHeader.js +1 -1
- package/dist/components/Series.js +1 -1
- package/dist/components/SiteTextStylesField.js +1 -1
- package/dist/components/Split.js +1 -1
- package/dist/components/Stats.js +1 -1
- package/dist/components/StatsParagraph.js +1 -1
- package/dist/components/Testimonials.js +1 -1
- package/dist/components/Text.js +1 -1
- package/dist/components/ThemeField.js +1 -1
- package/dist/components/Timeline.js +1 -1
- package/dist/components/TimelineTrack.js +1 -1
- package/dist/components/WebsiteScreenParts.js +1 -1
- package/dist/components/storefront-editor.css +96 -271
- package/dist/components/useLocationsTree.js +1 -1
- package/dist/components/usePinnedChromeState.d.ts +3 -0
- package/dist/components/usePinnedChromeState.js +1 -0
- package/dist/components/useWebsiteMainAction.js +1 -1
- package/dist/lib/content/phone-focus.d.ts +7 -0
- package/dist/lib/content/phone-focus.js +1 -0
- package/dist/lib/dealer-source.d.ts +34 -0
- package/dist/lib/dealer-source.js +1 -0
- package/dist/lib/editor-words-catalogue.d.ts +14 -5
- package/dist/lib/editor-words-catalogue.js +4 -4
- package/dist/lib/page-live-state.d.ts +2 -1
- package/dist/lib/page-live-state.js +1 -1
- package/dist/lib/puck/MarkupToolbar.d.ts +1 -1
- package/dist/lib/puck/MarkupToolbar.js +1 -1
- package/dist/lib/puck/blocks/general/Footprint/fields.js +1 -1
- package/dist/lib/puck/blocks/general/Footprint/render.js +2 -2
- package/dist/lib/puck/blocks/general/HeroSingle/fields.js +1 -1
- package/dist/lib/puck/blocks/general/HeroSingle/render.js +1 -1
- package/dist/lib/puck/blocks/general/HeroSlide/fields.js +1 -1
- package/dist/lib/puck/blocks/general/HeroSlide/render.js +1 -1
- package/dist/lib/puck/blocks/general/ImageBlock/fields.js +1 -1
- package/dist/lib/puck/blocks/general/ImageBlock/render.js +1 -1
- package/dist/lib/puck/blocks/general/text-part-shapes.json +2162 -0
- package/dist/lib/puck/controls.d.ts +5 -2
- package/dist/lib/puck/controls.js +1 -1
- package/dist/lib/puck/field-groups.js +1 -1
- package/dist/lib/puck/media-manifest.json +7 -2
- package/dist/lib/puck/passes/clickable-parts.js +1 -1
- package/dist/lib/puck/passes/inspector.js +1 -1
- package/dist/lib/puck/passes/section-width.js +1 -1
- package/dist/lib/puck/passes/types.d.ts +3 -1
- package/dist/lib/puck/registry.d.ts +1 -1
- package/dist/lib/puck/registry.js +1 -1
- package/dist/lib/puck/render-registry.d.ts +3 -0
- package/dist/lib/puck/render-registry.js +1 -0
- package/dist/lib/puck/source-bound-parts.d.ts +2 -0
- package/dist/lib/puck/source-bound-parts.js +1 -1
- package/dist/lib/puck/text-part-shape.d.ts +18 -0
- package/dist/lib/puck/text-part-shape.js +2 -0
- package/dist/lib/sections/collection-card-text-regions.d.ts +9 -1
- package/dist/lib/sections/collection-card-text-regions.js +1 -1
- package/dist/lib/sections/text-regions.d.ts +1 -0
- package/dist/lib/sections/text-regions.js +1 -1
- package/dist/lib/site-text-styles.d.ts +1 -0
- package/dist/lib/site-text-styles.js +2 -2
- package/dist/lib/source-rules/heading-ceiling-sweep.js +3 -3
- package/dist/lib/source-rules/part-style-naming.js +2 -2
- package/dist/lib/source-rules/rule.d.ts +1 -0
- package/dist/lib/source-rules/rule.js +3 -1
- package/dist/lib/source-rules/size-token-paints.js +4 -4
- package/dist/lib/source-rules/style-face-matches-size.js +3 -3
- package/dist/lib/source-rules/support/registry-source.d.ts +1 -1
- package/dist/lib/source-rules/support/registry-source.js +3 -3
- package/package.json +9 -6
- package/dist/components/ImageFocusRow.d.ts +0 -7
- package/dist/components/ImageFocusRow.js +0 -1
- package/dist/components/TemplateGlyph.d.ts +0 -6
- package/dist/components/TemplateGlyph.js +0 -1
- package/dist/components/TextStyleRow.d.ts +0 -13
- package/dist/components/TextStyleRow.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,201 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 22.1.0 - 2026-10-19
|
|
4
|
+
|
|
5
|
+
**A template no longer carries a picture's focus point, on any picture or in either view** (phone focus plan, step 7; Lewis 2026-10-19: "one picture, one dot"). A patch: no stored value moves.
|
|
6
|
+
|
|
7
|
+
### Fixed for merchants
|
|
8
|
+
|
|
9
|
+
- Save as template cleared only the single Hero's first focus point (`imageFocal`). The second picture's (`imageFocal2`), the Image block's (`focal`) and the phone points 22.0.0 added (`imageFocalPhone`, `imageFocal2Phone`, `focalPhone`) went into the template, so a site made from it opened with another merchant's points on its own pictures.
|
|
10
|
+
|
|
11
|
+
### Changed for hosts
|
|
12
|
+
|
|
13
|
+
- `lib/puck/media-manifest.json`: `technicalStateKeys` lists all six, and `contentHash` moves (`d674ba52a1cf8456` → `bff238ceb7836a0a`). The backend sanitizer refuses a template write whose hash differs from its copy, so the backend's vendored manifest moves with this release. The storefront's `scripts/gen-media-manifest.ts` writes the list and checks each key against the config.
|
|
14
|
+
|
|
15
|
+
**Publish counts the header and footer, the canvas says when they are not saved, and the menu note says only what is synced** (hartesmetal.com.au, 2026-10-19: a footer edit stayed off the live site while the bar said "Published", and a footer column's typed heading was labelled "Synced from the site menu"). A patch: no stored value moves.
|
|
16
|
+
|
|
17
|
+
### Fixed for merchants
|
|
18
|
+
|
|
19
|
+
- **The bar's Publish reads the header and footer too.** They are edited in place on every page but stored in their own document (the site-footer page). A footer-only change used to leave the page live, and the bar said "Published · Everything is live" over a change that was not live. Now the bar shows **Publish** with **"Header and footer not live yet"** until that document is live. The press already published both.
|
|
20
|
+
- **The canvas says when the header and footer are not saved**, in the same notice place as "could not load", one sentence at a time:
|
|
21
|
+
- "{name} is editing the header and footer. Nothing you change in them here is saved." (somebody else holds them; "Somebody else" when the name is unknown)
|
|
22
|
+
- "The header and footer were changed somewhere else. Nothing you change in them here is saved. Reload to get the latest."
|
|
23
|
+
- "The header and footer did not save. They are sent again with your next change."
|
|
24
|
+
Before, the edit showed on the canvas and was never stored, with nothing on screen to say so.
|
|
25
|
+
- **"Synced from the site menu." only where the words are synced.** A Footer menu column's own Heading is typed, and it wins over the menu's name. The part panel said "Synced from the site menu. Open" over it, because it chose the note by block type, so the heading looked as if it came from Storefront › Menus. The note now shows only for a prop that holds hydrated words. The column's block panel still says it, for the links.
|
|
26
|
+
- **Open goes to that menu.** Open on a menu column's note sends the column's menu id with `storefront-editor:open-menus`, so the console opens that menu, not only the Menus list (the admin already reads `menuId`, as for the Header panel's "Edit menu"). With no linked menu, it opens the list, as before.
|
|
27
|
+
|
|
28
|
+
### For hosts
|
|
29
|
+
|
|
30
|
+
- `mainActionFor` takes `pinnedUnpublished` (optional, default false: the page alone, as before).
|
|
31
|
+
- New `components/usePinnedChromeState`: the one reader of `PinnedChromeReport`, used by the bar and by the notice.
|
|
32
|
+
- `PinnedChromeLoadNotice` keeps its name and its load notice; `PINNED_CHROME_NOTES` holds its four sentences.
|
|
33
|
+
- `lib/puck/source-bound-parts`: new `partSourceNoteFor(nodeType, propKey)` (the note for one prop) and `sourceMenuIdOf(props)`. `PartSourceNote` takes an optional `menuId`.
|
|
34
|
+
- `storefront-editor:open-menus` from the source note now carries `{ menuId }` (a string, or null).
|
|
35
|
+
|
|
36
|
+
### Keep editor code off shopper pages
|
|
37
|
+
|
|
38
|
+
- **A registry that is only drawn can be finished without the settings panel**
|
|
39
|
+
(keep editor code off shopper pages, W1, 2026-10-19). New
|
|
40
|
+
`lib/puck/render-registry`: `finishRenderRegistry(config)` runs every pass's
|
|
41
|
+
draw half over the blocks and imports none of the panel's builders.
|
|
42
|
+
`finishRegistry` is now that same loop handed the inspector, so the editor
|
|
43
|
+
and a shopper's page are wrapped by one list of passes. The Image width
|
|
44
|
+
slider's icon is handed in on the inspector (`PassInspector.WidthIcon`)
|
|
45
|
+
instead of imported by `passes/section-width`, so the passes folder imports
|
|
46
|
+
no icon set. Nothing a merchant sees changes.
|
|
47
|
+
|
|
48
|
+
- **A block that is only drawn can carry its text parts without its fields**
|
|
49
|
+
(keep editor code off shopper pages, W2a, 2026-10-19). New
|
|
50
|
+
`lib/puck/text-part-shape`: `textPartShape(fields)` cuts a field list down to
|
|
51
|
+
what the part walk (`partNeedles`) reads, as plain data, and
|
|
52
|
+
`textPartShapesText(blocks)` writes a set of them as JSON. The general
|
|
53
|
+
blocks' file is `lib/puck/blocks/general/text-part-shapes.json`, written by
|
|
54
|
+
`pnpm run text-parts`. The part-style wrapper (`passes/clickable-parts`)
|
|
55
|
+
reads a block's `textParts` before its `fields` (a render half's `fields`
|
|
56
|
+
are its slots alone), so a published page can draw a merchant's part styles
|
|
57
|
+
without loading the settings panel. An editor's block has no `textParts`.
|
|
58
|
+
Nothing a merchant sees changes. For hosts: run the same function over your
|
|
59
|
+
own blocks to write your file.
|
|
60
|
+
|
|
61
|
+
## 22.0.0 - 2026-10-19
|
|
62
|
+
|
|
63
|
+
**A site text style's phone size** (Lewis 2026-10-19: the Hartes hero's Heading 1 draws 106px on a 390px phone; the site's style gets a phone size first, one place for every page; a single heading keeps its own phone Font size in the part text panel, which already exists).
|
|
64
|
+
|
|
65
|
+
### Changed for merchants
|
|
66
|
+
|
|
67
|
+
- **Site styles › Text, in the phone view:** each style's Size row edits its PHONE size (efficient-easel 12's `device`). The desktop size shows grey behind it; an emptied box follows the desktop size again.
|
|
68
|
+
- On the page, below the phone breakpoint, the style's face takes its phone size, and so does the size token it feeds (`--size-headingLarge` for Heading 1, `headingMedium`, `headingSmall`, `body`, `label`), so a section that reads the token (a Hero's Heading 1) follows too.
|
|
69
|
+
|
|
70
|
+
### Added for hosts
|
|
71
|
+
|
|
72
|
+
- `StoredTextStyleValues.sizePhone` (px; efficient-backend #3388 stores it). `textStylesCss` writes it under `PART_PHONE_MAX_CSS`, the token `!important` because it sits inline on `.sf-themed-content`. No phone size, no phone rule: every saved list draws what it drew.
|
|
73
|
+
|
|
74
|
+
### Guards
|
|
75
|
+
|
|
76
|
+
- New `scripts/test-text-style-phone-size.tsx`: stored and passed through in px, drawn under the one phone breakpoint (face and token), absent draws nothing, and Site styles hands easel the view.
|
|
77
|
+
|
|
78
|
+
**A picture's phone focus, set by the dot on the picture** (Lewis 2026-10-19, the Hartes hero: on a 390px phone the Ranger II truck was cut on the right; "one picture, one dot"). Published pages with no phone point draw the bytes they drew.
|
|
79
|
+
|
|
80
|
+
### Changed for merchants
|
|
81
|
+
|
|
82
|
+
- The single Hero (both pictures), the Hero slide and the Image block set their focus with the dot ON the picture row, not in an **Image focus** row of its own with a second copy of the photograph. The view you drag in sets that view's point: the desktop's, or in the **phone** view the phone's, with ↺ back to the desktop point (empty = the phone draws the desktop point). The Image block shows the dot only while its picture is cropped, as the row did.
|
|
83
|
+
- Fixed on the way: Image 2's focus row previewed the FIRST picture; its dot is on its own picture now.
|
|
84
|
+
|
|
85
|
+
### Added for hosts
|
|
86
|
+
|
|
87
|
+
- `upload(label, accept, placeholder, { focus, focusWhen })`: the picture row's focus key and when it can move anything. `focusKeptField()`: a focus key declared with no control, so it is saved.
|
|
88
|
+
- New keys, each `<key>Phone` (`phoneKey`): `imageFocalPhone`, `imageFocal2Phone` (single Hero), `imageFocalPhone` (Hero slide), `focalPhone` (Image block).
|
|
89
|
+
- `lib/content/phone-focus`: `phoneFocus(point)`, `PHONE_FOCUS_CLASS` (`sf-focus-phone`), `PHONE_FOCUS_VAR` (`--sf-focus-phone`). A phone point reaches the picture as that class and variable beside the inline desktop point; **the host's site stylesheet must draw it under the phone breakpoint** (storefront-blocks' `globals.css`, beside `.sf-pad-top-phone`). `HeroPoster`, `HeroSingle`, `HeroSlide` take `objectPositionPhone` (`objectPosition2Phone`); `ImageBlock` takes `focalPhone`.
|
|
90
|
+
|
|
91
|
+
### Removed for hosts
|
|
92
|
+
|
|
93
|
+
- `focalPicker` (no caller: the dot is on the picture) and the editor CSS that hid the second photograph (`.es-insp-rows:has([data-image-focus])`, `.sf-focal-row`). `components/ImageFocusRow.tsx` (no caller: the dot is on the picture). `components/TextStyleRow.tsx` (its last caller was `ImageFocusRow`).
|
|
94
|
+
|
|
95
|
+
### Guards
|
|
96
|
+
|
|
97
|
+
- New `scripts/test-phone-focus.tsx`: the helper, the render (with and without a phone point, the Image block only while cropped) and the fields (every focus key declared with its phone twin; each picture row names its own key).
|
|
98
|
+
- `scripts/test-panel-parts-from-the-shell.ts` §2-3: one picture, one dot; no focus row and no crop-hiding rule. `scripts/test-hero-media-show-when.tsx`: the phone keys hide with their picture for a video.
|
|
99
|
+
|
|
100
|
+
**Every picture row is the shell's media field, with a Change image bar** (Lewis 2026-10-19: "how do I change the picture?"; one picture, one dot). A MAJOR: the efficient-shell peer narrows to `^7.69.1` and the efficient-easel peer moves to `^12.0.0`.
|
|
101
|
+
|
|
102
|
+
### Breaking for hosts
|
|
103
|
+
|
|
104
|
+
- **efficient-easel 12.0.0 or later and efficient-shell 7.69.1 or later are required.** Every `upload()` row draws easel's `ImageBox`, which since easel 12 IS the shell's `MediaUploadField` (efficient-shell #528). A host moves easel, the shell and this package in one pull request; its Tailwind must scan the shell for the bar's classes (admin-portal does).
|
|
105
|
+
|
|
106
|
+
### Changed for merchants
|
|
107
|
+
|
|
108
|
+
- Every picture and video row (the 31 `upload()` rows and the chrome media panels) shows the shell's field: the picture with its file name on it, and along its bottom a **Change image** bar and a bin (on hover and keyboard focus; always on a screen with no hover). Empty, the shell's drop zone.
|
|
109
|
+
|
|
110
|
+
### Changed for hosts
|
|
111
|
+
|
|
112
|
+
- `components/MediaUploadField` no longer runs a drop intake of its own: the shell field's intake holds a dropped file to the slot's kind and to `backendOf(session).media.maxUploadBytes` and announces a refused one, and a file that passes goes to the admin through `openLibrary(file)` → `requestMediaPick(host, { file })`, as before. Its own busy and error lines and their CSS (`.sf-image-drop`, `.sf-image-status`) are gone.
|
|
113
|
+
|
|
114
|
+
### Guards
|
|
115
|
+
|
|
116
|
+
- `scripts/test-shell-peer-range.ts` records the 7.69.1 floor; `scripts/test-two-ways-to-add.ts` the easel `^12.0.0` range.
|
|
117
|
+
- `scripts/test-upload-intake-guard.ts`: no migrated surface of its own any more (the media slot's intake is the shell field's); the markers still hold that no file here reads a drop itself.
|
|
118
|
+
|
|
119
|
+
- **Every margin, padding and gap in the editor's stylesheet sits on the
|
|
120
|
+
shell's spacing scale** (SSOT cleanup batch 4, Lewis approved 2026-10-17).
|
|
121
|
+
On main of 2026-10-19, 83 declarations in `storefront-editor.css` were off the
|
|
122
|
+
scale; 75 now read `var(--space-*)`, each snapped UP (3 -> 4, 5/6/7 -> 8, 9/10/11
|
|
123
|
+
-> 12, 13/14 -> 16, 18 -> 20, 28/30 -> 32, the Pages pin's 1px line gap -> 2).
|
|
124
|
+
Eight stay as named geometry in the new guard
|
|
125
|
+
`scripts/test-editor-css-spacing-on-scale.ts` (hairline and baseline
|
|
126
|
+
nudges, the slider notch, the visually-hidden box, and the empty page's 64px
|
|
127
|
+
space, which is empty canvas space, not a panel gap). Editor chrome only;
|
|
128
|
+
no live-site section changes.
|
|
129
|
+
|
|
130
|
+
- **Each section's own text sizes are written once** (SSOT cleanup batch 4,
|
|
131
|
+
GG ruling B, 2026-10-17). While a site has not set a text style, a part keeps
|
|
132
|
+
its section's own size ("unset = the section keeping its own size",
|
|
133
|
+
`DEFAULT_SIZES`). Those sizes now live in one `TEXT_SIZE` table per section,
|
|
134
|
+
and the parts read it: 161 uses are 128 entries in 33 sections. Nothing on
|
|
135
|
+
screen changes. Every section render (through the storefront-blocks sweep,
|
|
136
|
+
with this build and main's) and the compiled CSS are byte-identical, and each
|
|
137
|
+
file's table, put back inline, gives the old source exactly.
|
|
138
|
+
- **`builtInOf()`** (`lib/sections/text-regions`): a text region reads its
|
|
139
|
+
built-in size from its section's table instead of typing it again. The
|
|
140
|
+
Collections card does this first: `COLLECTION_CARD_TEXT_SIZE` holds the five
|
|
141
|
+
runs' classes, and each `builtIn` is read from it. storefront-blocks'
|
|
142
|
+
`CollectionCard` imports the table in a follow-up after this release.
|
|
143
|
+
- **`inlineTextSizes()`** (`lib/source-rules/rule`): the source rules that
|
|
144
|
+
read class lists (style face beside its size, heading ceiling, part-style
|
|
145
|
+
naming, size-token paints) put a file's table back in place first, line for
|
|
146
|
+
line, so they check exactly what the page draws.
|
|
147
|
+
- New guard `scripts/test-text-size-tables.ts`: a file with a table writes no
|
|
148
|
+
size fallback outside it, and no entry twice.
|
|
149
|
+
- **The Pages panel's last own numbers sit on the shell's spacing scale**
|
|
150
|
+
(Lewis's scale of 2026-10-12, snapped up). The type pills (Dynamic,
|
|
151
|
+
Lightbox, Preview) pad `var(--space-2) var(--space-8)` (was 2px 7px). The
|
|
152
|
+
note that stands where the tree would (Loading, nothing found, an error) pads
|
|
153
|
+
`var(--space-12)` (was 10px 12px). The "draft" tag has no spacing of its own,
|
|
154
|
+
so it does not move. The new guard `scripts/test-pages-pills-on-scale.ts`
|
|
155
|
+
holds both. A patch.
|
|
156
|
+
|
|
157
|
+
**The copy field's formatting bar is the shell's text toolbar** (efficient-easel ^11.8.0). A minor: no stored value moves.
|
|
158
|
+
|
|
159
|
+
**The Locations Map can show the website's dealers: Source = Typed in · Dealers** (Lewis approved 2026-10-17, card [ADD] Dealer Finder, Panthera "Where to buy"). A minor: a section saved before this setting draws exactly what it drew.
|
|
160
|
+
|
|
161
|
+
### Added for merchants
|
|
162
|
+
|
|
163
|
+
- **Source** (in the Offices band): Typed in (the default, today's section) or Dealers. Dealers lists the dealers ticked "Show" in the website's Dealers list (admin), read from the ERP; the section stores nothing about a dealer.
|
|
164
|
+
- In Dealers mode the map is efficient-shell's `EntityMap` in its site look: pins in the site's own colours, light or dark by the section's Map theme, crowded pins grouped into numbered circles that zoom open, two fingers to move it on a phone. A list sits left, right or below it (one column on a phone). A list row flies the map to its pin; a pin brings its row into view.
|
|
165
|
+
- **Search** band (Dealers only): **Show** switch, **Hint** and **No match**. A search puts the nearest dealers first, with km, and frames the five nearest on the map.
|
|
166
|
+
- **List** band (Dealers only): **Position** (Left · Right · Below) and **Distance**.
|
|
167
|
+
- The rows hide by the shell's one show-when rule (`withShowWhen`).
|
|
168
|
+
|
|
169
|
+
### Added for hosts
|
|
170
|
+
|
|
171
|
+
- `lib/dealer-source`: the host hands the dealer read over through `DealerSourceProvider` (`GET /api/v1/dealers`). Without it the editor says so and a live page draws nothing.
|
|
172
|
+
- `efficient-shell` peer: see above (`^7.69.1` in this release). `maplibre-gl` and `@tanstack/react-query` are devDependencies only; the shell's map declares them as its own peers, and the host serves the MapLibre worker (`efficient-shell/map/worker-route`) and loads `efficient-shell/map-site.css`.
|
|
173
|
+
|
|
174
|
+
### Changed for merchants
|
|
175
|
+
|
|
176
|
+
- **The bar above a copy field is the shell `TextToolbar`**, the one text toolbar every editor draws (efficient-easel 11.5.0 made `MarkBar` a wrapper over it). Bold, Italic and Strikethrough wear the shell's own glyphs, names and 32px-high buttons where the 14px hand-drawn glyphs and the 22px row were; Clear formatting sits in the toolbar's last cell, right after the marks, with no divider of the inspector's. The bar is still inside the copy box's frame and still hidden until the caret is in the words.
|
|
177
|
+
|
|
178
|
+
### Changed for hosts
|
|
179
|
+
|
|
180
|
+
- **`efficient-easel` peer and dev range `^11.8.0`** (was `^11.2.0`; `^12.0.0` in this release, above).
|
|
181
|
+
- `MarkupToolbar` draws `efficient-shell/ui`'s `TextToolbar` directly, not easel's deprecated `MarkBar` (removed in easel 12.0.0); it puts `sf-markup-bar` on the toolbar's wrapper. `storefront-editor.css` places the bar by that class only and dresses no shell toolbar class: the old `.es-copy-bar` / `.es-copy-mark` / `.es-copy-bar-split` rules are gone with the bar that drew them.
|
|
182
|
+
|
|
183
|
+
### Guards
|
|
184
|
+
|
|
185
|
+
- `test-markup-toolbar`, `test-clear-formatting`, `test-shop-text-box` read the shell toolbar: its `rosh-tb-btn` marks, its words from `DEFAULT_SHELL_STRINGS.textToolbar` (Bold, Italic, Strikethrough), Clear in the toolbar's own row, the bar hidden at rest by `.sf-markup-bar`, and the marks' mousedown guard in the shell's toolbar. `test-two-ways-to-add` checks `^11.8.0`. All four failed on the bump alone.
|
|
186
|
+
|
|
187
|
+
**Seven editor glyphs come from the shell's one icon set** (SSOT cleanup, Lewis approved 2026-10-17; harness UI-24). A patch: the drawings change a little, nothing else.
|
|
188
|
+
|
|
189
|
+
### Changed
|
|
190
|
+
|
|
191
|
+
- Site styles > Theme > Add new theme: the shell's `add` (was a local plus).
|
|
192
|
+
- Pages panel, each page row: the shell's `page` (was a local document).
|
|
193
|
+
- Text styles, the saved tick: the shell's `check` (was a local tick, stroke 3; the shell's is lighter).
|
|
194
|
+
- Contact locations tree: a region group is `globe`, a city `location`, a city's map `map` (were three local drawings; the note that the shell had no `map` is out of date).
|
|
195
|
+
- The toolbar's Save as Template button: the shell's `template` glyph (`components/TemplateGlyph` was a local copy of the same bookmark; deleted). Lewis approved 2026-10-19.
|
|
196
|
+
|
|
197
|
+
Before/after sheet: GG's notes folder, `ssot-batch2-wb-icons-before-after.png`.
|
|
198
|
+
|
|
3
199
|
## 21.0.0 - 2026-10-19
|
|
4
200
|
|
|
5
201
|
**The picture strip is efficient-shell's `PictureTiles`** (Lewis 2026-10-17 chose picture tiles for the header country picker's "Show as"; GG: one copy, in the shell). The Photo Grid's "Layout" and the Box's "Block widths" drew one local strip; the header picker is its third row, so the strip moved into efficient-shell 7.53.0 (Efficient-Pty-Ltd/efficient-shell#518) and both rows draw their pictures into it. Release it as a **major**: the shell peer range narrows to `^7.53.0`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as n,jsxs as
|
|
1
|
+
"use client";import{jsx as n,jsxs as o}from"react/jsx-runtime";import{useCountUp as r}from"./useCountUp.js";const t={headingMedium:"text-[length:var(--size-headingMedium,40px)]",label:"text-[length:var(--size-label,13px)]"};function u({target:a,label:i}){const e=a.match(/^(\d+)(.*)$/),s=e?parseInt(e[1],10):0,m=e?e[2]:"",{ref:l,value:d}=r(s),c=e?d+m:a;return o("div",{ref:l,className:"min-w-0",children:[n("div",{className:`font-heading2 ${t.headingMedium} font-medium leading-none tracking-[-0.02em] tabular-nums`,"aria-label":a,children:c}),n("div",{className:`mt-1 font-mono ${t.label} uppercase tracking-[0.2em] text-fg-dim`,children:i})]})}export{u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as s}from"react/jsx-runtime";import f from"./BlockFrame.js";import
|
|
1
|
+
import{jsx as e,jsxs as s}from"react/jsx-runtime";import f from"./BlockFrame.js";import g from"./Btn.js";import{media as u}from"../lib/media.js";import{CONTENT_SIZES as v,sizedImage as N}from"../lib/sized-image.js";import b from"./SectionEyebrow.js";import{renderGold as m,renderHeadline as y,splitParagraphs as M}from"./goldPhrases.js";import{ON_MEDIA_INK_STYLE as z}from"../lib/content/ink.js";const n={headingMediumUpTo800:"max-[800px]:text-[length:min(var(--size-headingMedium,32px),var(--sf-heading-max,9999px))]",headingMedium:"text-[length:min(var(--size-headingMedium,44px),var(--sf-heading-max,9999px))]",body:"text-[length:var(--size-body,16px)]"};function E({eyebrow:r,title:a,body:d,ctaText:t,ctaHref:l,imageSrc:i,contained:o,overlay:c=60}){const p=Math.min(Math.max(c,0),100)/100;return e(f,{contained:o,className:"py-6",children:s("div",{className:"sf-card relative overflow-hidden border border-line bg-surface px-10 py-16 max-[800px]:px-6 max-[800px]:py-10",children:[i&&s("div",{className:"absolute inset-0","aria-hidden":!0,children:[e(_,{src:u(i)}),e("div",{className:"absolute inset-0",style:{background:`rgba(0,0,0,${p})`}})]}),s("div",{className:"relative z-[1] flex max-w-[680px] flex-col gap-5",style:i?z:void 0,children:[r&&e(b,{text:r}),a&&e("h2",{className:`font-heading2 ${n.headingMedium} font-medium leading-[1.05] tracking-[-0.03em] ${n.headingMediumUpTo800}`,children:y(a,!1)}),d&&M(d).map((h,x)=>e("p",{className:`${n.body} leading-[1.6] opacity-85`,children:m(h)},x)),t&&e("div",{className:"mt-2 self-start",children:e(g,{href:l||"#",variant:"primary",children:m(t)})})]})]})})}function _({src:r}){const a=N(r);return e("img",{src:a.src,...a.srcSet?{srcSet:a.srcSet,sizes:v}:{},alt:"",className:"h-full w-full object-cover"})}export{E as default};
|
package/dist/components/Cards.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,Fragment as
|
|
1
|
+
import{jsx as e,Fragment as f,jsxs as n}from"react/jsx-runtime";import u from"./SectionEyebrow.js";import{renderGold as l,renderHeadline as v}from"./goldPhrases.js";const t={headingMediumUpTo800:"max-[800px]:text-[length:min(var(--size-headingMedium,32px),var(--sf-heading-max,9999px))]",headingMedium:"text-[length:min(var(--size-headingMedium,44px),var(--sf-heading-max,9999px))]",body:"text-[length:var(--size-body,15px)]",headingSmall:"text-[length:var(--size-headingSmall,20px)]"},b="mx-auto max-w-[var(--sf-site-width,1600px)] px-[var(--sf-site-gutter,40px)] py-[72px] max-[960px]:px-[min(24px,var(--sf-site-gutter,40px))]",N="mx-auto max-w-[var(--sf-site-width,1600px)] px-[var(--sf-site-gutter,40px)] pt-0 pb-[72px] max-[960px]:px-[min(24px,var(--sf-site-gutter,40px))]";function M({look:x,eyebrow:i,title:r,items:p,columns:o,omitHead:m=!1,editing:d=!1}={}){const g=Math.min(4,Math.max(2,o??3)),s=(p??[]).filter(a=>d||(a.title??"").trim()||(a.body??"").trim()),c=!!(i??"").trim()||!!(r??"").trim();return!d&&!c&&s.length===0?null:e("section",{className:"relative z-[2] bg-surface",children:n("div",{className:m?N:b,children:[m?null:n(f,{children:[(i??"").trim()&&e(u,{text:i??"",look:x,className:"mb-4 block"}),(r??"").trim()&&e("h2",{className:`mb-9 font-heading2 ${t.headingMedium} font-medium uppercase leading-none tracking-[-0.02em] text-fg max-[800px]:mb-7 ${t.headingMediumUpTo800}`,children:v(r??"",!1)})]}),s.length>0&&e("div",{className:"sf-card grid grid-cols-1 gap-px border border-line bg-line min-[700px]:[grid-template-columns:repeat(var(--cd-cols),minmax(0,1fr))]",style:{"--cd-cols":String(g)},children:s.map((a,h)=>n("div",{className:"bg-bg p-8 max-[800px]:p-7",children:[e("div",{className:`mb-3 font-heading3 ${t.headingSmall} font-medium uppercase tracking-[0.02em] text-fg`,children:l((a.title??"").trim()||"Card title")}),e("p",{className:`${t.body} leading-[1.6] text-fg-dim`,children:l((a.body??"").trim()||"A short line about this card.")})]},h))})]})})}export{M as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as r,jsxs as
|
|
1
|
+
import{jsx as r,jsxs as s}from"react/jsx-runtime";import{SiteLink as u}from"../lib/site-runtime.js";import{renderChrome as l}from"./goldPhrases.js";import{STICKY_UNDERHEADER_CLASS as v}from"../lib/puck/header-clearance.js";import{say as k}from"../lib/editor-words.js";const n={body:"text-[length:var(--size-body,12px)]",label:"text-[length:var(--size-label,13px)]"};function w({tabs:d,activeTab:i,links:b,sticky:f=!0,editing:h=!1}){const c=(d??[]).filter(e=>e?.label?.trim()),a=c.length>0?c:h?[{label:k("Tab")}]:[],o=(b??[]).filter(e=>e?.label?.trim());if(a.length===0&&o.length===0)return null;const p=i?a.findIndex(e=>e.label.toLowerCase()===i.toLowerCase()):-1,g=p===-1?0:p;return r("nav",{className:`${f?`${v} sticky top-[var(--sf-header-h,88px)] z-40 `:""}border-b border-line px-[var(--sf-site-gutter,40px)] backdrop-blur-md max-[1100px]:px-[min(16px,var(--sf-site-gutter,40px))]`,style:{background:"color-mix(in oklab, var(--bg) 92%, transparent)"},children:s("div",{className:"mx-auto flex max-w-[calc(var(--sf-site-width,1600px)_-_var(--sf-site-gutter,40px)*2)] items-stretch gap-0 overflow-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:[a.map((e,t)=>{const m=t===g,x=e.count?.trim()?e.count:"";return s("span",{className:[`relative whitespace-nowrap border-r border-line px-[22px] py-[18px] font-mono ${n.label} uppercase tracking-[0.22em] transition-colors`,t===0?"border-l border-line":"",m?"text-fg":"text-fg-dim hover:text-fg"].join(" "),children:[l(e.label),x&&r("span",{className:`ml-2 ${n.body} text-accent opacity-70`,children:l(x)}),m&&r("span",{className:"absolute inset-x-0 -bottom-px h-[2px] bg-accent"})]},t)}),o.length>0&&r("div",{className:"ml-auto flex border-l border-line",children:o.map((e,t)=>s(u,{href:e.href||"#",className:`flex items-center gap-2.5 px-[22px] py-[18px] font-mono ${n.label} uppercase tracking-[0.22em] text-fg-dim hover:text-fg`,children:[l(e.label)," ",r("span",{className:"text-accent",children:"↗"})]},t))})]})})}export{w as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as t,jsxs as o}from"react/jsx-runtime";import{renderGold as g,renderHeadline as N}from"./goldPhrases.js";const d={headingMediumUpTo800:"max-[800px]:text-[length:min(var(--size-headingMedium,32px),var(--sf-heading-max,9999px))]",headingMedium:"text-[length:min(var(--size-headingMedium,44px),var(--sf-heading-max,9999px))]",bodySmall:"text-[length:var(--size-body,15px)]",bodyLarge:"text-[length:var(--size-body,16px)]",labelSmall:"text-[length:var(--size-label,10px)]",label:"text-[length:var(--size-label,11px)]",labelLarge:"text-[length:var(--size-label,12px)]"};function v(e){return Number.isInteger(e)?String(e):String(Math.round(e*10)/10)}const b=[100,70,46,30,19,12];function y(e){return`color-mix(in srgb, var(--accent) ${b[e%b.length]}%, var(--bg))`}function $({data:e,suffix:x}){const h=Math.max(...e.map(m=>m.value),0)||1;return t("div",{className:"flex w-full flex-col gap-6",children:e.map((m,a)=>o("div",{children:[o("div",{className:"mb-2 flex items-baseline justify-between gap-4",children:[t("span",{className:`font-mono ${d.label} uppercase tracking-[0.14em] text-fg/60`,children:g(m.label)}),o("span",{className:`font-display ${d.bodyLarge} font-medium text-fg`,children:[v(m.value),x]})]}),t("div",{className:"h-[10px] border border-line bg-bg",children:t("div",{className:"h-full bg-accent",style:{width:`${Math.max(m.value/h*100,m.value===0?0:2)}%`}})})]},a))})}function k({data:e,suffix:x}){const a={l:42,r:42,t:36,b:38},f=640-a.l-a.r,c=300-a.t-a.b,n=Math.max(...e.map(l=>l.value),0)||1,s=e.length>1?f/(e.length-1):0,i=e.map((l,r)=>({x:a.l+(e.length>1?r*s:f/2),y:a.t+c-l.value/n*c})),p=i.map((l,r)=>`${r===0?"M":"L"}${l.x},${l.y}`).join(" "),u=`${p} L${i[i.length-1].x},${a.t+c} L${i[0].x},${a.t+c} Z`;return o("svg",{viewBox:"0 0 640 300",className:"w-full",role:"img","aria-hidden":!0,children:[[.25,.5,.75,1].map(l=>t("line",{x1:a.l,x2:640-a.r,y1:a.t+c*(1-l),y2:a.t+c*(1-l),stroke:"var(--site-line)",strokeWidth:"1"},l)),t("line",{x1:a.l,x2:640-a.r,y1:a.t+c,y2:a.t+c,stroke:"var(--site-line)",strokeWidth:"1.5"}),t("path",{d:u,fill:"var(--accent)",opacity:"0.13"}),t("path",{d:p,fill:"none",stroke:"var(--accent)",strokeWidth:"2.5"}),i.map((l,r)=>o("g",{children:[t("circle",{cx:l.x,cy:l.y,r:"4",fill:"var(--accent)"}),o("text",{x:l.x,y:l.y-12,textAnchor:"middle",className:"font-display",fontSize:"14",fill:"var(--fg)",children:[v(e[r].value),x]}),t("text",{x:l.x,y:288,textAnchor:"middle",className:"font-mono",fontSize:"10",letterSpacing:"0.1em",fill:"var(--fg)",opacity:"0.55",children:e[r].label.toUpperCase()})]},r))]})}function M({data:e,suffix:x}){const h=e.reduce((n,s)=>n+s.value,0)||1,m=80,a=2*Math.PI*m;let f=0;const c=e.map((n,s)=>{const i=n.value/h,p={frac:i,dash:Math.max(i*a-3,0),off:f,ink:y(s)};return f+=i*a,p});return o("div",{className:"flex w-full flex-wrap items-center justify-center gap-10",children:[t("svg",{viewBox:"0 0 200 200",className:"w-[220px] max-w-full -rotate-90",role:"img","aria-hidden":!0,children:c.map((n,s)=>t("circle",{cx:"100",cy:"100",r:m,fill:"none",stroke:n.ink,strokeWidth:"34",strokeDasharray:`${n.dash} ${a-n.dash}`,strokeDashoffset:-n.off},s))}),t("ul",{className:"flex min-w-[200px] flex-1 flex-col gap-3",children:e.map((n,s)=>o("li",{className:"flex items-baseline gap-3",children:[t("span",{"aria-hidden":!0,className:"h-[10px] w-[10px] flex-shrink-0 rotate-45",style:{background:y(s)}}),t("span",{className:`flex-1 font-mono ${d.label} uppercase tracking-[0.12em] text-fg/60`,children:g(n.label)}),t("span",{className:`font-display ${d.bodySmall} font-medium text-fg`,children:x?`${v(n.value)}${x}`:`${Math.round(n.value/h*100)}%`})]},s))})]})}function w({eyebrow:e,title:x,body:h,chartStyle:m,items:a,valueSuffix:f,caption:c,editing:n=!1}={}){const s=(f??"").trim()===""?"":f??"",i=(a??[]).map(r=>({label:(r.label??"").trim(),value:parseFloat(r.value??"")})).filter(r=>n?!0:r.label&&Number.isFinite(r.value)).map(r=>({label:r.label||"—",value:Number.isFinite(r.value)?r.value:0})),p=!!(e??"").trim()||!!(x??"").trim();if(!n&&!p&&i.length===0)return null;const u=m??"bars",l=i.length===0?null:u==="line"&&i.length>1?t(k,{data:i,suffix:s}):u==="donut"?t(M,{data:i,suffix:s}):t($,{data:i,suffix:s});return t("section",{className:"relative z-[2] border-y border-line bg-surface",children:o("div",{className:"mx-auto grid max-w-[var(--sf-site-width,1600px)] items-center gap-14 px-[var(--sf-site-gutter,40px)] py-[76px] min-[960px]:[grid-template-columns:minmax(0,5fr)_minmax(0,7fr)] max-[960px]:px-[min(24px,var(--sf-site-gutter,40px))]",children:[o("div",{children:[(e??"").trim()&&t("span",{className:`inline-block bg-accent px-3.5 py-1.5 font-mono ${d.labelLarge} font-semibold uppercase tracking-[0.16em] text-bg`,children:g(e??"")}),(x??"").trim()&&t("h2",{className:`mt-5 font-heading2 ${d.headingMedium} font-medium uppercase leading-[1.04] tracking-[-0.02em] text-fg ${d.headingMediumUpTo800}`,children:N(x??"",!1)}),(h??"").trim()&&t("p",{className:`mt-5 max-w-[46ch] ${d.bodySmall} leading-relaxed text-fg/65`,children:h})]}),o("div",{children:[l,(c??"").trim()&&t("p",{className:`mt-4 font-mono ${d.labelSmall} uppercase tracking-[0.14em] text-fg/40`,children:c})]})]})})}export{w as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as o,Fragment as
|
|
1
|
+
"use client";import{jsx as e,jsxs as o,Fragment as E}from"react/jsx-runtime";import{useEffect as T,useState as f}from"react";import u from"./PartStyledKind.js";import{renderGold as y,renderHeadline as M}from"./goldPhrases.js";import{PART_KIND_ATTR as h}from"../lib/puck/text-parts.js";import{TEXT_KIND_NAME as g,TEXT_KIND_VALUE as v}from"../lib/sections/section-text-kinds.js";const c={headingSmall:"text-[length:min(var(--size-headingSmall,32px),var(--sf-heading-max,9999px))]",labelSmall:"text-[length:var(--size-label,11px)]",labelLarge:"text-[length:var(--size-label,12px)]"},D=24*3600*1e3,I=[{key:"hours",label:"Hours"},{key:"minutes",label:"Minutes"},{key:"seconds",label:"Seconds"}];function L(t,n){return Math.max(0,Math.ceil((t-n)/1e3))}function $(t){const n=Date.parse((t??"").trim());return Number.isFinite(n)?n:null}const z=t=>String(t).padStart(2,"0");function A({title:t,zeroText:n,endsAt:w,showUnits:N=!0,editing:i=!1}={}){const b=$(w),[S]=f(()=>Date.now()+D),l=b??(i?S:null),[_,m]=f(()=>Date.now());if(T(()=>{if(l===null)return;m(Date.now());const a=window.setInterval(()=>m(Date.now()),1e3);return()=>window.clearInterval(a)},[l]),l===null)return null;const s=L(l,_),r=[Math.floor(s/3600),Math.floor(s%3600/60),s%60],d=(t??"").trim(),p=(n??"").trim(),k=`${r[0]} hours, ${r[1]} minutes and ${r[2]} seconds left`;return e("section",{className:"relative z-[2] bg-bg",role:"timer","aria-live":"off",children:o("div",{className:"mx-auto flex max-w-[var(--sf-site-width,1600px)] flex-col items-center gap-4 px-[var(--sf-site-gutter,40px)] py-12 text-center max-[960px]:px-[min(24px,var(--sf-site-gutter,40px))]",children:[d&&e("p",{className:`font-mono ${c.labelLarge} uppercase tracking-[0.2em] text-fg-dim`,children:y(d)}),s===0?p&&e("p",{className:`font-heading3 ${c.headingSmall} font-medium leading-tight text-fg`,children:M(p,!1)}):o(E,{children:[e("span",{className:"sr-only",children:k}),e("div",{"aria-hidden":!0,className:"flex items-start gap-[clamp(8px,2vw,24px)]",children:I.map((a,x)=>o("div",{className:"contents",children:[x>0&&e("span",{className:"font-mono text-[length:clamp(32px,7vw,80px)] leading-none text-accent",children:":"}),o("div",{className:"flex min-w-0 flex-col items-center gap-2",children:[e(u,{kind:v,children:e("span",{"data-countdown-unit":a.key,...i?{[h]:v}:{},suppressHydrationWarning:!0,className:"font-mono text-[length:clamp(40px,8vw,96px)] font-medium leading-none tabular-nums text-fg",children:z(r[x])})}),N&&e(u,{kind:g,children:e("span",{...i?{[h]:g}:{},className:`font-mono ${c.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:a.label})})]})]},a.key))})]})]})})}export{A as default,L as secondsLeft};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type MapThemeMode } from "../lib/map-styles.js";
|
|
2
|
+
import { type DealerListPosition } from "../lib/dealer-source.js";
|
|
3
|
+
export default function DealerFinder({ mapLabel, mapTheme, search, searchHint, noMatchText, listPosition, showDistance, editing, }: {
|
|
4
|
+
mapLabel: string;
|
|
5
|
+
mapTheme: MapThemeMode;
|
|
6
|
+
search: boolean;
|
|
7
|
+
searchHint: string;
|
|
8
|
+
noMatchText: string;
|
|
9
|
+
listPosition: DealerListPosition;
|
|
10
|
+
showDistance: boolean;
|
|
11
|
+
editing?: boolean;
|
|
12
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as n,jsxs as a}from"react/jsx-runtime";import{useEffect as C,useMemo as y,useRef as V,useState as c}from"react";import{EntityMap as W}from"efficient-shell/map";import{mapModeIsLight as N,watchMapTheme as G}from"../lib/map-styles.js";import{dealerDistanceLabel as Q,dealerPins as Y,parseDealerListPosition as J,useDealerSource as U}from"../lib/dealer-source.js";import{groupColsClass as X}from"../lib/locations-grid.js";import{say as Z}from"../lib/editor-words.js";const D={near:null,dealers:[]},H="max-h-[480px] overflow-y-auto overscroll-contain",ee=5,te="h-[480px] max-[800px]:h-[320px]",ne={"--rosh-map-pin":"var(--accent)","--rosh-map-pin-text":"var(--bg)","--rosh-map-pin-edge":"var(--bg)","--rosh-map-ring":"var(--fg)","--rosh-map-radius":"0px","--rosh-map-font":"var(--font-role-label)"};function ae(t){const[s,o]=c(()=>N(t));return C(()=>(o(N(t)),G(()=>o(N(t)))),[t]),s?"light":"dark"}function re({mapLabel:t,mapTheme:s,search:o,searchHint:l,noMatchText:f,listPosition:u,showDistance:E,editing:I}){const d=U(),[r,x]=c(D),[w,z]=c(""),[T,S]=c(!1),[k,g]=c(null),[A,B]=c(null),b=V(null),P=ae(s);C(()=>{if(!d)return;let e=!0;return d({}).then(i=>e&&x(i)).catch(()=>e&&x(D)),()=>{e=!1}},[d]);const p=y(()=>Y(r.dealers),[r.dealers]),R=y(()=>new Set(p.map(e=>e.key)),[p]),K=y(()=>r.near==="found"?p.slice(0,ee).map(e=>e.key):null,[r.near,p]),O=e=>{g(e),R.has(e)&&B(i=>({key:e,n:(i?.n??0)+1}))},$=e=>{g(e),b.current?.querySelector(`[data-dealer="${CSS.escape(e)}"]`)?.scrollIntoView({block:"nearest"})};if(!d)return I?n("p",{"data-dealers-unavailable":!0,className:"font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.24em] text-fg-dim",children:Z("Dealers are not available on this website")}):null;const q=e=>{e.preventDefault();const i=w.trim();S(!0),g(null),d(i?{near:i}:{}).then(x).catch(()=>x(F=>({...F,near:"try_again"}))).finally(()=>S(!1))},m=J(u),_=m!=="below",v=r.near==="not_found"||r.near==="try_again",j=o?a("form",{role:"search",onSubmit:q,className:"mb-4 flex gap-2",children:[n("input",{type:"search",value:w,onChange:e=>z(e.target.value),placeholder:l,"aria-label":l,"aria-invalid":v||void 0,className:["min-w-0 flex-1 border bg-bg px-3 py-2 text-[length:var(--size-body,14px)] text-fg outline-none",v?"border-accent":"border-line focus:border-fg"].join(" ")}),n("button",{type:"submit","aria-label":l,disabled:T,className:"grid w-10 shrink-0 place-items-center bg-fg text-bg disabled:opacity-50",children:a("svg",{"aria-hidden":!0,width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("circle",{cx:"11",cy:"11",r:"7"}),n("path",{d:"M20 20l-3.5-3.5"})]})})]}):null,L=v&&f?n("p",{role:"status",className:"mb-3 text-[length:var(--size-body,14px)] text-fg-dim",children:f}):null,h=r.dealers.map(e=>n(se,{dealer:e,active:k===e.id,onSelect:()=>O(e.id),distance:E?Q(e.distanceKm):"",tile:!_},e.id)),M=n("div",{style:ne,children:n(W,{pins:p,selectedKey:k,focus:A,onSelect:$,ariaLabel:t,className:te,groupCrowded:!0,fitTo:K,look:"site",theme:P,cooperativeGestures:"coarse"})});return _?a("div",{"data-dealer-finder":m,className:["grid items-start gap-6 max-[800px]:grid-cols-1",m==="left"?"grid-cols-[minmax(260px,360px)_1fr]":"grid-cols-[1fr_minmax(260px,360px)]"].join(" "),children:[a("div",{className:["min-w-0",m==="right"?"order-2":"","max-[800px]:order-2"].join(" "),children:[j,L,n("div",{ref:b,className:[H,"max-[800px]:max-h-none"].join(" "),children:h})]}),n("div",{className:["min-w-0",m==="right"?"order-1":"","max-[800px]:order-1"].join(" "),children:M})]}):a("div",{"data-dealer-finder":"below",children:[j,L,M,h.length>0&&n("div",{ref:b,className:["mt-12 grid gap-[2px] bg-bg",X(h.length),h.length>2?"max-[1100px]:grid-cols-2 max-[700px]:grid-cols-1":"max-[700px]:grid-cols-1"].join(" "),children:h})]})}function se({dealer:t,active:s,onSelect:o,distance:l,tile:f}){const u=[t.city,[t.state,t.postcode].filter(Boolean).join(" ")].filter(Boolean).join(" ");return a("div",{"data-dealer":t.id,className:["flex gap-3 bg-bg text-left outline outline-1 -outline-offset-1",f?"px-6 py-5":"border-b border-line px-1 py-4",s?"outline-accent":"outline-transparent hover:outline-line"].join(" "),children:[a("button",{type:"button",onClick:o,"aria-pressed":s,className:"min-w-0 flex-1 text-left",children:[n("span",{className:"block font-display text-[length:var(--size-body,16px)] font-medium leading-[1.25] text-fg",children:t.name}),t.address&&n("span",{className:"mt-1 block text-[length:var(--size-body,14px)] text-fg-dim",children:t.address}),u&&n("span",{className:"block text-[length:var(--size-body,14px)] text-fg-dim",children:u})]}),a("span",{className:"flex shrink-0 flex-col items-end gap-1 text-[length:var(--size-body,14px)]",children:[l&&n("span",{className:"text-fg-dim",children:l}),t.phone&&n("a",{href:`tel:${t.phone.replace(/[^\d+]/g,"")}`,className:"text-fg underline underline-offset-2",children:t.phone}),t.website&&n("a",{href:t.website,target:"_blank",rel:"noopener noreferrer",className:"text-fg underline underline-offset-2",children:t.website.replace(/^https?:\/\//,"").replace(/\/$/,"")})]})]})}export{re as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as a,jsxs as
|
|
1
|
+
import{jsx as a,jsxs as s}from"react/jsx-runtime";import c from"./SectionEyebrow.js";import{renderGold as i,renderHeadline as g}from"./goldPhrases.js";const x={bodyUpTo900:"max-[900px]:text-[length:var(--size-body,19px)]",body:"text-[length:var(--size-body,22px)]",label:"text-[length:var(--size-label,13px)]"};function b({level:t,className:l,children:r}){return a(t===2?"h2":"h1",{className:l,children:r})}function f({eyebrow:t,title:l,deck:r,meta:p,editing:o=!1,titleLevel:d}){const n=(p??[]).filter(e=>(e.label??"").trim()!==""||(e.value??"").trim()!=="");return!!!(t||l||r||n.length>0)&&!o?null:a("section",{className:"relative z-[2] bg-bg",children:s("div",{className:"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] pt-[100px] pb-[60px] max-[900px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[900px]:pt-[60px] max-[900px]:pb-10",children:[s("div",{className:"grid grid-cols-[auto_1fr_auto] items-end gap-10 pb-8 max-[900px]:grid-cols-1 max-[900px]:gap-4",children:[t&&a(c,{text:t,className:"pb-3",classNameAfter:"max-[900px]:pb-0"}),l&&a(b,{level:d,className:"font-display text-[length:min(var(--size-headingLarge,clamp(56px,8vw,128px)),var(--sf-heading-max,9999px))] font-medium uppercase leading-[0.88] tracking-[-0.04em]",children:g(l,!0)}),n.length>0&&a("div",{className:`pb-3 text-right font-mono ${x.label} uppercase leading-[1.8] tracking-[0.22em] text-fg-dim max-[900px]:pb-0 max-[900px]:text-left`,children:n.map((e,m)=>s("div",{children:[e.label&&a("strong",{className:"font-normal text-fg",children:i(e.label)}),e.label&&e.value?" ":null,e.value?i(e.value):null]},m))})]}),r&&a("p",{className:`max-w-[760px] border-t border-line pt-8 font-serif ${x.body} italic leading-[1.5] text-fg-dim ${x.bodyUpTo900}`,children:i(r,!0)})]})})}export{f as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as a,jsxs as
|
|
1
|
+
import{jsx as a,jsxs as n}from"react/jsx-runtime";import x from"./SectionEyebrow.js";import{renderGold as t}from"./goldPhrases.js";const l={body:"text-[length:var(--size-body,14px)]",headingSmall:"text-[length:var(--size-headingSmall,20px)]"};function m({cards:i,editing:s=!1}){const r=(i??[]).filter(e=>(e.label??"").trim()!==""||(e.value??"").trim()!==""||(e.desc??"").trim()!=="");return r.length===0&&!s?null:a("section",{className:"relative z-[2] bg-bg",children:a("div",{className:"mx-auto grid max-w-[var(--sf-site-width,1600px)] grid-cols-3 gap-10 border-b border-line px-[var(--sf-site-gutter,40px)] py-[60px] max-[900px]:grid-cols-1 max-[900px]:gap-4 max-[900px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[900px]:py-10",children:r.map((e,d)=>n("div",{className:"flex flex-col gap-2 border border-line bg-surface p-6",children:[e.label&&a(x,{text:e.label,size:12}),e.value&&a("span",{className:`font-heading3 ${l.headingSmall} font-medium tracking-[-0.015em] text-fg`,children:t(e.value)}),e.desc&&a("span",{className:`mt-1.5 font-serif ${l.body} italic leading-[1.5] text-fg-dim`,children:t(e.desc)})]},d))})})}export{m as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as n,jsxs as o}from"react/jsx-runtime";import{SiteLink as m}from"../lib/site-runtime.js";import{renderChrome as b,renderGold as i}from"./goldPhrases.js";import{STICKY_UNDERHEADER_CLASS as f}from"../lib/puck/header-clearance.js";const c={labelSmall:"text-[length:var(--size-label,12px)]",labelLarge:"text-[length:var(--size-label,13px)]"};function h({tabs:p,metaLabel:r,metaValue:t,editing:x=!1}){const a=(p??[]).filter(e=>(e.label??"").trim()!=="");if(a.length===0&&!x)return null;const d=a.findIndex(e=>e.current);return n("nav",{className:`${f} sticky top-[var(--sf-header-h,88px)] z-40 border-b border-line px-[var(--sf-site-gutter,40px)] backdrop-blur-md max-[900px]:px-4`,style:{background:"color-mix(in oklab, var(--bg) 92%, transparent)"},children:o("div",{className:"mx-auto flex max-w-[calc(var(--sf-site-width,1600px)_-_var(--sf-site-gutter,40px)*2)] items-stretch gap-0 overflow-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:[a.map((e,l)=>{const s=l===d;return o(m,{href:e.href||"#",className:[`relative whitespace-nowrap border-r border-line px-[26px] py-[18px] font-mono ${c.labelLarge} uppercase tracking-[0.22em] transition-colors`,l===0?"border-l border-line":"",s?"text-fg":"text-fg-dim hover:text-fg"].join(" "),children:[b(e.label),s&&n("span",{className:"absolute inset-x-0 -bottom-px h-[2px] bg-accent"})]},l)}),(r||t)&&o("span",{className:`ml-auto flex items-center whitespace-nowrap border-l border-line py-[18px] pl-[26px] font-mono ${c.labelSmall} uppercase tracking-[0.24em] text-fg-dim max-[900px]:hidden`,children:[r&&i(r),t&&n("strong",{className:"ml-2 font-normal text-accent",children:i(t)})]})]})})}export{h as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as a}from"react/jsx-runtime";import{sectionRunsFullWidth as
|
|
1
|
+
import{jsx as e,jsxs as a}from"react/jsx-runtime";import{sectionRunsFullWidth as h}from"../lib/content/section-width.js";import{Fragment as v}from"react";import{SiteLink as y}from"../lib/site-runtime.js";import{stripMarkup as N}from"../lib/markup.js";import w from"./Placeholder.js";import{renderGold as r,renderHeadline as k,splitParagraphs as z}from"./goldPhrases.js";const t={body:"text-[length:var(--size-body,20px)]",labelSmall:"text-[length:var(--size-label,12px)]",labelLarge:"text-[length:var(--size-label,13px)]"};function S({image:g,badge:i,imageDate:p,category:o,readLabel:m,date:c,title:n,dek:x,ctaText:d,ctaHref:b,...u}){const f=[o?e("span",{className:"text-accent",children:r(o)}):null,m?e("span",{children:r(m)}):null,c?e("span",{children:r(c)}):null].filter(Boolean);return e("section",{className:h(u)?"border-b border-line px-[var(--sf-site-gutter,40px)] py-20 max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[1100px]:py-[60px]":"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] py-20 max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[1100px]:py-[60px]",children:a("article",{className:"sf-card relative grid grid-cols-[1.3fr_1fr] border border-line bg-[var(--card-bg)] max-[1100px]:grid-cols-1",children:[a("div",{className:"relative aspect-[5/4] overflow-hidden border-r border-line bg-surface-2 max-[1100px]:border-r-0 max-[1100px]:border-b",children:[e(w,{label:"featured-cover",src:g||void 0,alt:N(n||"Cover"),sizes:"(max-width: 1100px) 100vw, 56vw"}),e("div",{className:"pointer-events-none absolute inset-0 z-[1]",style:{background:"linear-gradient(180deg, rgba(10,10,10,0.45) 0%, transparent 30%, transparent 70%, rgba(10,10,10,0.55) 100%)"}}),i&&e("span",{className:`absolute left-6 top-6 z-[2] bg-accent px-3 py-2 font-mono ${t.labelSmall} uppercase tracking-[0.3em] text-bg`,children:r(i)}),p&&e("span",{className:`absolute right-6 bottom-6 z-[2] font-mono ${t.labelSmall} uppercase tracking-[0.24em] text-overlay-fg`,children:r(p)})]}),a("div",{className:"flex flex-col justify-between gap-6 px-12 py-14 max-[1100px]:px-7 max-[1100px]:py-9",children:[f.length>0&&e("div",{className:`flex items-center gap-4 font-mono ${t.labelSmall} uppercase tracking-[0.28em] text-fg-dim`,children:f.map((s,l)=>a(v,{children:[l>0&&e("span",{className:"opacity-40",children:"·"}),s]},l))}),n&&e("h2",{className:"font-heading2 text-[length:min(var(--size-headingMedium,clamp(34px,3.5vw,58px)),var(--sf-heading-max,9999px))] font-medium uppercase leading-none tracking-[-0.03em]",children:k(n,!0)}),x&&z(x).map((s,l)=>e("p",{className:`max-w-[520px] font-serif ${t.body} italic leading-[1.5] text-fg-dim`,children:r(s,!0)},l)),d&&e("div",{children:a(y,{href:b||"#",className:`group inline-flex items-center gap-3.5 py-3.5 font-mono ${t.labelLarge} uppercase tracking-[0.3em] text-accent`,children:[r(d)," ",e("span",{className:"transition-transform group-hover:translate-x-[6px]",children:"→"})]})})]})]})})}export{S as default};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MapThemeMode } from "../lib/map-styles.js";
|
|
2
2
|
import { type FootprintOffice } from "../lib/content/footprint.js";
|
|
3
|
+
import { type DealerListPosition, type FootprintSource } from "../lib/dealer-source.js";
|
|
3
4
|
export interface FootprintProps {
|
|
4
5
|
sectionNumber?: string;
|
|
5
6
|
heading?: string;
|
|
@@ -12,5 +13,11 @@ export interface FootprintProps {
|
|
|
12
13
|
padBottom?: number;
|
|
13
14
|
editing?: boolean;
|
|
14
15
|
omitHead?: boolean;
|
|
16
|
+
source?: FootprintSource;
|
|
17
|
+
search?: boolean;
|
|
18
|
+
searchHint?: string;
|
|
19
|
+
noMatchText?: string;
|
|
20
|
+
listPosition?: DealerListPosition;
|
|
21
|
+
showDistance?: boolean;
|
|
15
22
|
}
|
|
16
|
-
export default function Footprint({ sectionNumber, heading, tagline, offices, apiKey, mapId, mapTheme, padTop, padBottom, editing, omitHead, }: FootprintProps): import("react").JSX.Element | null;
|
|
23
|
+
export default function Footprint({ sectionNumber, heading, tagline, offices, apiKey, mapId, mapTheme, padTop, padBottom, editing, omitHead, source, search, searchHint, noMatchText, listPosition, showDistance, }: FootprintProps): import("react").JSX.Element | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{jsx as n,Fragment as
|
|
1
|
+
"use client";import{jsx as n,Fragment as ct,jsxs as I}from"react/jsx-runtime";import{useEffect as B,useRef as g,useState as H}from"react";import{MAP_PALETTE as tt,mapBackgroundFor as K,mapMarkerColorFor as et,mapPaletteFor as Q,mapStylesFor as nt,watchMapTheme as pt}from"../lib/map-styles.js";import{hasMapCoords as rt,loadGoogleMaps as dt,watchMapLoad as ut}from"../lib/maps-loader.js";import{resolveMapId as mt,resolveMapsKey as ft,useSiteMapId as gt,useSiteMapsKey as bt}from"../lib/maps-config.js";import{bucketByGroup as xt,groupColsClass as yt}from"../lib/locations-grid.js";import ht from"./EditorialSectionHead.js";import{LocationGroupHeader as vt}from"./LocationGroupHeader.js";import{renderGold as kt,renderHeadline as $t}from"./goldPhrases.js";import wt from"./PartStyledText.js";import{say as Mt}from"../lib/editor-words.js";import{parseFootprintSource as St}from"../lib/dealer-source.js";import Lt from"./DealerFinder.js";const S={bodySmall:"text-[length:var(--size-body,10px)]",bodyLarge:"text-[length:var(--size-body,18px)]",labelSmall:"text-[length:var(--size-label,11px)]",labelLarge:"text-[length:var(--size-label,12px)]"},Ct=11,It=6,X=60;function U(t){return t.replace(/[&<>"']/g,r=>r==="&"?"&":r==="<"?"<":r===">"?">":r==='"'?""":"'")}function ot(t,r,p){return{path:r.SymbolPath.CIRCLE,scale:t.hq?Ct:It,fillColor:et(p),fillOpacity:1,strokeColor:et(p),strokeOpacity:t.hq?.3:.25,strokeWeight:t.hq?14:9}}function at(t,r,p,e,l,N){l.forEach(o=>o.setMap(null)),l.clear();const L=new r.LatLngBounds;return e.forEach((o,m)=>{if(!rt(o.lat,o.lng))return;L.extend({lat:o.lat,lng:o.lng});const f=new r.Marker({map:t,position:{lat:o.lat,lng:o.lng},icon:ot(o,r,p),title:o.city,zIndex:o.hq?100:10,cursor:"pointer"});f.addListener("click",()=>N(m)),l.set(m,f)}),L}function Nt(t){return`
|
|
2
2
|
.footprint-map .gm-style { font-family: var(--font-role-label), var(--font-mono-fallback) !important; }
|
|
3
3
|
.footprint-map .gm-style .gm-style-iw-c {
|
|
4
4
|
background: ${t.bg} !important;
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
.footprint-map .gm-style button[aria-label="Close"] > span {
|
|
17
17
|
background-color: ${t.closeX} !important;
|
|
18
18
|
}
|
|
19
|
-
`}function
|
|
19
|
+
`}function lt({pal:t}){const r=t?t.marker:"var(--accent)",p=t?t.info.bg:"var(--site-surface)",e=t?t.background:"var(--bg)",l=t?`color-mix(in oklab, ${t.info.fgDim} 12%, transparent)`:"color-mix(in oklab, var(--fg) 3%, transparent)";return I(ct,{children:[n("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`radial-gradient(60% 70% at 50% 50%, color-mix(in oklab, ${r} 8%, ${p}) 0%, ${p} 60%, ${e} 100%)`}}),n("div",{className:"pointer-events-none absolute inset-0",style:{backgroundImage:`repeating-linear-gradient(0deg, transparent 0 22px, ${l} 22px 23px), repeating-linear-gradient(90deg, transparent 0 22px, ${l} 22px 23px)`}})]})}function Et({sectionNumber:t="",heading:r="",tagline:p="",offices:e=[],apiKey:l="",mapId:N="",mapTheme:L="auto",padTop:o,padBottom:m,editing:f,omitHead:v=!1,source:E,search:D=!1,searchHint:P="",noMatchText:k="",listPosition:_="below",showDistance:$=!0}){const x=St(E)==="dealers",w=typeof o=="number"?o:120,A=typeof m=="number"?m:120,[M,C]=H(null),G=e.length===0&&!x&&!t&&!r&&!p;if(B(()=>{C(a=>a!==null&&a>=e.length?null:a)},[e]),G&&!f)return null;const z=xt(e,a=>String(a.group??""),()=>"");return n("section",{className:"relative z-[2] bg-bg",children:I("div",{className:"mx-auto max-w-[var(--sf-site-width,1600px)] border-b border-line px-[var(--sf-site-gutter,40px)] max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[800px]:px-[min(20px,var(--sf-site-gutter,40px))]",style:{paddingTop:w,paddingBottom:A},children:[!v&&(t||r||p)&&n(ht,{num:t,title:r?$t(r):void 0,desc:p||void 0,spaceBelow:"mb-12"}),x?n(Lt,{mapLabel:r.replace(/[=*]/g,"").replace(/\s+/g," ").trim(),mapTheme:L,search:D,searchHint:P,noMatchText:k,listPosition:_,showDistance:$,editing:f}):n(At,{offices:e,apiKey:l,mapId:N,mapTheme:L,activeIndex:M,onSelect:C,editing:f}),!x&&e.length>0&&n("div",{className:"mt-12 flex flex-col gap-8",children:z.map((a,F)=>I("div",{children:[a.key&&n(vt,{groupKey:a.key,count:a.items.length}),n("div",{className:["grid gap-[2px] bg-bg",yt(a.items.length),a.items.length>2?"max-[1100px]:grid-cols-2 max-[700px]:grid-cols-1":a.items.length===2?"max-[700px]:grid-cols-1":""].join(" "),children:a.items.map(({item:u,index:R})=>{const j=M===R;return I("button",{type:"button",onClick:()=>C(R),"aria-pressed":j,className:["flex flex-col gap-1.5 bg-bg px-6 py-5 text-left transition-colors outline outline-1 -outline-offset-1",j?"outline-accent":"outline-transparent hover:outline-line"].join(" "),children:[I("span",{className:`flex items-center gap-2.5 font-mono ${S.labelSmall} uppercase tracking-[0.28em]`,children:[u.hq&&n("span",{className:`border border-accent bg-accent px-1.5 py-0.5 ${S.bodySmall} text-bg`,children:"HQ"}),u.role&&n("span",{className:"text-accent",children:u.role})]}),u.city&&n("span",{className:`font-display ${S.bodyLarge} font-medium leading-[1.2] tracking-[-0.01em] text-fg`,children:n(wt,{value:u.city,children:u.city})}),u.country&&n("span",{className:`font-mono ${S.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:u.country}),u.address&&n("span",{className:`font-mono ${S.labelSmall} uppercase tracking-[0.2em] text-fg-dim`,children:kt(u.address)})]},R)})})]},a.key?`g:${a.key}`:`ungrouped:${F}`))}),!x&&e.length===0&&f&&n("p",{className:`mt-8 font-mono ${S.labelLarge} uppercase tracking-[0.24em] text-fg-dim`,children:Mt("Add an office in the inspector")})]})})}function At({offices:t,apiKey:r,mapId:p,mapTheme:e,activeIndex:l,onSelect:N,editing:L}){const o=ft(r,bt()),m=mt(p,gt()),f=!!o&&t.some(s=>rt(s.lat,s.lng)),v=e!=="auto",E=Q(e),D=g(null),P=g(null),k=g(null),_=g(null),$=g(new Map),x=g(null),w=g(null),A=g(null),M=g(N);M.current=N;const C=g(t);C.current=t;const G=g(l);G.current=l;const[z,a]=H(!1),F=`${o}|${m}|${e}`,[u,R]=H(null),j=u===F,[W,J]=H(tt.dark),[st,V]=H(tt.dark.background);return B(()=>{J(Q(e)),V(K(e))},[e]),B(()=>{if(!f)return;const s=D.current;if(!s)return;let i=!1,c=null,y=null;const q=async()=>{y=ut(()=>{i||R(F)});try{const d=await dt(o);if(i||!P.current)return;const h=new d.Map(P.current,{center:{lat:25,lng:0},zoom:2,minZoom:1,maxZoom:5,disableDefaultUI:!0,gestureHandling:"cooperative",keyboardShortcuts:!1,clickableIcons:!1,backgroundColor:K(e),...m?{mapId:m}:{styles:nt(e)}});k.current=h,_.current=d;const O=at(h,d,e,C.current,$.current,Z=>M.current(Z));w.current=O,O.isEmpty()||h.fitBounds(O,X);const Y=new d.InfoWindow({disableAutoPan:!0});Y.addListener("closeclick",()=>M.current(null)),x.current=Y,h.addListener("click",()=>M.current(null)),h.addListener("tilesloaded",()=>{y?.ready(),i||a(!0)}),e==="auto"&&!m&&(c=pt(()=>{i||!k.current||(k.current.setOptions({styles:nt(e),backgroundColor:K(e)}),$.current.forEach((Z,it)=>{const T=C.current[it];T&&Z.setIcon(ot(T,d,e))}),J(Q(e)),V(K(e)))}))}catch(d){console.error("[FootprintMap] Maps SDK failed:",d),y?.stop(),i||R(F)}},b=new IntersectionObserver(d=>{for(const h of d)if(h.isIntersecting){b.disconnect(),q();break}},{rootMargin:"200px"});return b.observe(s),()=>{i=!0,b.disconnect(),y?.stop(),c?.(),x.current?.close(),x.current=null,k.current=null,_.current=null,$.current.forEach(d=>d.setMap(null)),$.current.clear(),w.current=null,a(!1)}},[f,o,m,e,F]),B(()=>{const s=k.current,i=_.current;if(!s||!i)return;const c=at(s,i,e,t,$.current,y=>M.current(y));w.current=c,G.current===null&&!c.isEmpty()&&s.fitBounds(c,X)},[t,e]),B(()=>{const s=k.current,i=x.current;if(!s||!i)return;if(l===null){i.close(),A.current!==null&&w.current&&!w.current.isEmpty()&&s.fitBounds(w.current,X),A.current=null;return}const c=t[l],y=$.current.get(l);if(!c||!y){i.close(),A.current=l;return}s.panTo({lat:c.lat,lng:c.lng});const q=s.getZoom();q!=null&&q<4&&s.setZoom(4);const b=W.info,d=c.hq?`<span style="background:${b.accent};color:${b.bg};padding:1px 6px;font-size:10px;letter-spacing:0.18em;">HQ</span>`:"",h=c.role?`<span style="color:${b.accent};">${U(c.role)}</span>`:"";i.setContent(`
|
|
20
20
|
<div style="padding:10px 14px 12px;min-width:180px;color:${b.fg};">
|
|
21
21
|
<div style="display:flex;align-items:center;gap:8px;font-family:var(--font-role-label),var(--font-mono-fallback);font-size:11px;letter-spacing:0.28em;text-transform:uppercase;">
|
|
22
22
|
${d}${h}
|
|
23
23
|
</div>
|
|
24
|
-
<div style="font-family:var(--font-display),Georgia,serif;font-size:20px;font-weight:500;line-height:1.2;margin-top:6px;color:${b.fg};">${
|
|
25
|
-
<div style="font-family:var(--font-role-label),var(--font-mono-fallback);font-size:11px;letter-spacing:0.2em;text-transform:uppercase;color:${b.fgDim};margin-top:4px;">${
|
|
24
|
+
<div style="font-family:var(--font-display),Georgia,serif;font-size:20px;font-weight:500;line-height:1.2;margin-top:6px;color:${b.fg};">${U(c.city)}</div>
|
|
25
|
+
<div style="font-family:var(--font-role-label),var(--font-mono-fallback);font-size:11px;letter-spacing:0.2em;text-transform:uppercase;color:${b.fgDim};margin-top:4px;">${U(c.country)}</div>
|
|
26
26
|
</div>
|
|
27
|
-
`),
|
|
27
|
+
`),i.open({map:s,anchor:y}),A.current=l},[l,z,W,t]),!f||j?L?I("div",{className:["relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",v?"":"bg-bg"].join(" "),style:v?{backgroundColor:E.background}:void 0,children:[n(lt,{pal:v?E:void 0}),n("div",{className:[`absolute inset-0 flex items-center justify-center px-6 text-center font-mono ${S.labelLarge} uppercase tracking-[0.24em]`,v?"":"text-fg-dim"].join(" "),style:v?{color:E.info.fgDim}:void 0,children:o?j?"The map could not load. Check the Google Maps key":"Add office coordinates to plot the map":"Add a Google Maps API key to show the map"})]}):null:I("div",{ref:D,className:"sf-card footprint-map relative aspect-[16/9] w-full overflow-hidden border border-line max-[720px]:aspect-[4/5]",style:{backgroundColor:st},children:[n("style",{dangerouslySetInnerHTML:{__html:Nt(W.info)}}),n(lt,{pal:v?E:void 0}),n("div",{ref:P,className:"gmap-canvas absolute inset-0 transition-opacity duration-500",style:{opacity:z?1:0}}),n("div",{className:[`pointer-events-none absolute inset-0 flex items-center justify-center font-mono ${S.labelLarge} uppercase tracking-[0.24em] text-fg-dim transition-opacity duration-500`,z?"opacity-0":"opacity-100"].join(" "),children:"Loading map…"})]})}export{Et as default};
|
|
@@ -4,7 +4,8 @@ interface HeroPosterProps {
|
|
|
4
4
|
showVideo?: boolean;
|
|
5
5
|
playbackRate?: number;
|
|
6
6
|
objectPosition?: string;
|
|
7
|
+
objectPositionPhone?: string;
|
|
7
8
|
quiet?: boolean;
|
|
8
9
|
}
|
|
9
|
-
export default function HeroPoster({ videoSrc, posterSrc, showVideo, playbackRate, objectPosition, quiet, }: HeroPosterProps): import("react").JSX.Element;
|
|
10
|
+
export default function HeroPoster({ videoSrc, posterSrc, showVideo, playbackRate, objectPosition, objectPositionPhone, quiet, }: HeroPosterProps): import("react").JSX.Element;
|
|
10
11
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as o,jsxs as N}from"react/jsx-runtime";import{useEffect as m,useRef as C,useState as a}from"react";import{SiteImage as L}from"../lib/site-runtime.js";import P from"./HeroHeldFrame.js";import{hasAv1Variant as R,isExternalMediaUrl as A}from"../lib/media.js";import{sizedImage as H}from"../lib/sized-image.js";import{phoneFocus as S}from"../lib/content/phone-focus.js";const _=.5;function $({videoSrc:d,posterSrc:f,showVideo:p=!0,playbackRate:v=_,objectPosition:l="50% 50%",objectPositionPhone:I,quiet:y=!1}){const n=S(I),e=f||"",t=d||"",[c,u]=a(!1),[g,w]=a(!1),[j,F]=a(!1),[k,E]=a(!1),[b,h]=a(!1),z=C(null);m(()=>{u(!1),w(!1),F(!1),E(!1)},[d,f]),m(()=>{if(typeof window>"u")return;const s=()=>{const r=window;r.requestIdleCallback?r.requestIdleCallback(()=>h(!0),{timeout:2e3}):setTimeout(()=>h(!0),800)};if(document.readyState==="complete"){s();return}return window.addEventListener("load",s,{once:!0}),()=>window.removeEventListener("load",s)},[]),m(()=>{const s=z.current;if(!s)return;const r=()=>{s.playbackRate=v};return r(),s.addEventListener("loadedmetadata",r),()=>s.removeEventListener("loadedmetadata",r)},[d,v]);const x=A(e),i=e&&x&&!g?H(e):{src:e};return N("div",{className:"absolute inset-0 z-[1]",children:[o("div",{className:"absolute inset-0",style:{background:"var(--site-surface)"}}),e&&(x?o("img",{src:i.src,...i.srcSet?{srcSet:i.srcSet,sizes:"100vw"}:{},alt:"",className:`absolute inset-0 z-[2] h-full w-full object-cover ${n.className}`.trim(),style:{display:c?"none":"block",objectPosition:l,...n.style},onError:()=>i.srcSet?w(!0):u(!0)},e):o(L,{src:e,alt:"",fill:!0,priority:!0,sizes:"100vw",className:`z-[2] object-cover ${n.className}`.trim(),style:{display:c?"none":"block",objectPosition:l,...n.style},onError:()=>u(!0)},e)),p&&!y&&t&&b&&!j&&N("video",{ref:z,autoPlay:!0,loop:!0,muted:!0,playsInline:!0,preload:"metadata",className:"absolute inset-0 z-[3] h-full w-full object-cover",style:{objectPosition:l},onError:()=>F(!0),children:[R(t)&&o("source",{src:t.replace(/\.mp4$/,".av1.mp4"),type:'video/mp4; codecs="av01.0.08M.10"'}),o("source",{src:t,type:"video/mp4"})]},t),p&&y&&t&&b&&!k&&(!e||c)&&o(P,{src:t,objectPosition:l,onError:()=>E(!0)},t)]})}export{$ as default};
|
|
@@ -7,6 +7,7 @@ export interface HeroSingleProps {
|
|
|
7
7
|
mediaSrc?: string;
|
|
8
8
|
poster?: string;
|
|
9
9
|
objectPosition?: string;
|
|
10
|
+
objectPositionPhone?: string;
|
|
10
11
|
tintColor?: string;
|
|
11
12
|
tintOpacity?: number;
|
|
12
13
|
heightDesktop?: number;
|
|
@@ -16,6 +17,7 @@ export interface HeroSingleProps {
|
|
|
16
17
|
mediaLayoutPhone?: string;
|
|
17
18
|
mediaImage2?: string;
|
|
18
19
|
objectPosition2?: string;
|
|
20
|
+
objectPosition2Phone?: string;
|
|
19
21
|
tintColor2?: string;
|
|
20
22
|
tintOpacity2?: number;
|
|
21
23
|
videoSource?: string;
|
|
@@ -23,4 +25,4 @@ export interface HeroSingleProps {
|
|
|
23
25
|
videoPlayback?: string;
|
|
24
26
|
editing?: boolean;
|
|
25
27
|
}
|
|
26
|
-
export default function HeroSingle({ overlay, overlayColor, overlayPosition, mediaType, mediaSrc, poster, objectPosition, tintColor, tintOpacity, heightDesktop, heightMobile, boxes: Boxes, videoSource, youtubeUrl, videoPlayback, mediaLayout, mediaLayoutPhone, mediaImage2, objectPosition2, tintColor2, tintOpacity2, editing, }: HeroSingleProps): import("react").JSX.Element;
|
|
28
|
+
export default function HeroSingle({ overlay, overlayColor, overlayPosition, mediaType, mediaSrc, poster, objectPosition, objectPositionPhone, tintColor, tintOpacity, heightDesktop, heightMobile, boxes: Boxes, videoSource, youtubeUrl, videoPlayback, mediaLayout, mediaLayoutPhone, mediaImage2, objectPosition2, objectPosition2Phone, tintColor2, tintOpacity2, editing, }: HeroSingleProps): import("react").JSX.Element;
|