efficient-storefront-blocks 0.74.0 → 0.76.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 +48 -0
- package/dist/chunks/EditorPreviewCheckout-ANI7HUYX.js +4 -0
- package/dist/chunks/{SiteEditorProvider-Z33JB5BA.js → SiteEditorProvider-AJUWZYHT.js} +1 -1
- package/dist/chunks/chunk-3IQQNZIM.js +311 -0
- package/dist/chunks/chunk-4F5CAFXO.js +1 -0
- package/dist/chunks/{chunk-5OFEWRWI.js → chunk-5NXOTPHK.js} +1 -1
- package/dist/chunks/chunk-YAYHH5GY.js +1 -0
- package/dist/chunks/{chunk-QJDTP7K6.js → chunk-YFPWVNDB.js} +1 -1
- package/dist/chunks/{fitment-data-DHKRLKNI.js → fitment-data-IZYCNTET.js} +1 -1
- package/dist/contract.js +2 -2
- package/dist/editor/components/BlogSource.js +1 -1
- package/dist/editor/components/CategoryProductFields.d.ts +22 -0
- package/dist/editor/components/CategoryProductFields.js +1 -0
- package/dist/editor/components/CategorySource.d.ts +12 -0
- package/dist/editor/components/CategorySource.js +1 -1
- package/dist/editor/components/CollectionPicker.js +1 -1
- package/dist/editor/components/CountryShowAsTiles.js +1 -1
- package/dist/editor/components/EditorPreviewChat.js +1 -11
- package/dist/editor/components/EditorPreviewSurface.js +1 -1
- package/dist/editor/components/GalleryProductBinding.js +1 -1
- package/dist/editor/components/GalleryShowcaseSource.js +1 -1
- package/dist/editor/components/HeaderSettingsPanel.d.ts +8 -4
- package/dist/editor/components/HeaderSettingsPanel.js +1 -1
- package/dist/editor/components/MenuPicker.js +1 -1
- package/dist/editor/components/PreviewProductPicker.js +1 -1
- package/dist/editor/components/ProductHeroSource.js +1 -1
- package/dist/editor/components/ProductPicker.js +1 -1
- package/dist/editor/components/SocialLinksDoor.js +1 -1
- package/dist/editor/components/SpecTableSource.js +1 -1
- package/dist/editor/lib/document/block-align-row.d.ts +2 -0
- package/dist/editor/lib/document/block-align-row.js +1 -0
- package/dist/editor/lib/document/blocks/commerce/AccountBlock/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/AlloyWheelsListing/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/BundleOffer/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CartBlock/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CatalogFilterBar/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CheckoutCTA/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CollectionCard/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/Collections/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CompatibleTyres/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/CountrySwitchBlock/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/DeliveryOptions/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/DetailRows/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/EuTyreLabel/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/FitmentFinder/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/FitmentTable/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/Gallery/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/GalleryB/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/GalleryItem/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/ProductGallery/fields.d.ts +2 -2
- package/dist/editor/lib/document/blocks/commerce/ProductGallery/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/ProductGrid/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/ProductHero/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/RelatedProducts/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/SearchBlock/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/SpecTable/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/TyreFitment/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/TyreSizes/fields.js +1 -1
- package/dist/editor/lib/document/blocks/commerce/shared-fields.d.ts +1 -0
- package/dist/editor/lib/document/blocks/commerce/shared-fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/AppointmentBooking/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/BookingBox/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/ContactCards/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/ContactRouting/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/Events/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/Footer/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterDivider/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterEmailSignup/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterGroup/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterLogo/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterMenu/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterMessaging/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterPayment/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterSocial/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterText/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/Form/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/MessagingCards/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/OpeningHours/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/RateTable/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/RatingBlock/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/ReviewForm/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/Reviews/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/SiteHeader/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/SubmitBox/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/SubmitBuild/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/Subscribe/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/SubscribeBlogs/fields.js +1 -1
- package/dist/editor/lib/document/box-header.js +1 -1
- package/dist/editor/lib/document/config.d.ts +16 -16
- package/dist/editor/lib/document/config.js +1 -1
- package/dist/editor/lib/editor-currency-source.js +1 -1
- package/dist/editor/lib/efficient-backend.js +1 -1
- package/dist/editor/lib/storefront-editor-words.d.ts +12 -16
- package/dist/editor/lib/storefront-editor-words.js +1 -1
- package/dist/editor.css +1 -1
- package/dist/index.js +413 -724
- package/dist/links.js +1 -1
- package/dist/render/app/globals.css +32 -79
- package/dist/render/built-with.json +1 -1
- package/dist/render/components/BoxHeaderBar.js +1 -1
- package/dist/render/components/CartContext.d.ts +4 -0
- package/dist/render/components/CartContext.js +1 -1
- package/dist/render/components/CartDrawer.js +2 -2
- package/dist/render/components/CatalogFilterBarSection.d.ts +1 -1
- package/dist/render/components/CatalogFilterBarSection.js +1 -1
- package/dist/render/components/Collections.js +1 -1
- package/dist/render/components/CompatibleTyres.js +1 -1
- package/dist/render/components/ConsentPanel.js +1 -1
- package/dist/render/components/ContactRouting.js +1 -1
- package/dist/render/components/CouponField.js +1 -1
- package/dist/render/components/CurrencyContext.js +1 -1
- package/dist/render/components/Events.js +1 -1
- package/dist/render/components/FitmentTable.js +1 -1
- package/dist/render/components/FooterGroup.d.ts +1 -1
- package/dist/render/components/FooterGroup.js +1 -1
- package/dist/render/components/FooterLogo.d.ts +2 -1
- package/dist/render/components/FooterMenu.js +1 -1
- package/dist/render/components/FooterPayment.d.ts +1 -2
- package/dist/render/components/FooterPayment.js +1 -1
- package/dist/render/components/FooterSocial.d.ts +1 -2
- package/dist/render/components/FooterSocial.js +1 -1
- package/dist/render/components/FormBlock.js +1 -1
- package/dist/render/components/GalleryItem.js +1 -1
- package/dist/render/components/GalleryShowcase.js +1 -1
- package/dist/render/components/Header.js +1 -1
- package/dist/render/components/HeaderToolBlocks.d.ts +1 -2
- package/dist/render/components/HeaderToolBlocks.js +1 -1
- package/dist/render/components/HeaderTools.js +1 -1
- package/dist/render/components/Lightbox.d.ts +2 -2
- package/dist/render/components/Lightbox.js +1 -1
- package/dist/render/components/LinkedProductHero.d.ts +2 -0
- package/dist/render/components/PopupFrame.d.ts +17 -4
- package/dist/render/components/PopupFrame.js +1 -1
- package/dist/render/components/ProductGallery.js +1 -1
- package/dist/render/components/ProductGridSection.js +1 -1
- package/dist/render/components/ProductHeroPanel.d.ts +3 -1
- package/dist/render/components/ProductHeroPanel.js +1 -1
- package/dist/render/components/ProductLightbox.js +1 -1
- package/dist/render/components/ReviewForm.js +1 -1
- package/dist/render/components/SectionGroupBody.js +1 -1
- package/dist/render/components/SpecTable.d.ts +2 -1
- package/dist/render/components/SpecTable.js +1 -1
- package/dist/render/components/SubscribePopup.js +2 -2
- package/dist/render/components/TyreRenderSvg.js +1 -1
- package/dist/render/components/booking/BookingRegions.js +1 -1
- package/dist/render/components/catalog/CatalogFilterBar.d.ts +4 -4
- package/dist/render/components/catalog/CatalogFilterBar.js +1 -1
- package/dist/render/components/catalog/CatalogFilterContext.d.ts +5 -3
- package/dist/render/components/catalog/CatalogFilterContext.js +1 -1
- package/dist/render/components/catalog/FilterPill.d.ts +3 -1
- package/dist/render/components/catalog/FilterPill.js +1 -1
- package/dist/render/components/checkout/CheckoutPageClient.js +1 -1
- package/dist/render/components/checkout/checkout-parts.js +1 -1
- package/dist/render/components/checkout/checkout-state.d.ts +19 -2
- package/dist/render/components/checkout/checkout-state.js +3 -3
- package/dist/render/components/fitment/StockFitmentCard.js +1 -1
- package/dist/render/components/pdp-dynamic/DynamicProductGallery.js +1 -1
- package/dist/render/components/pdp-dynamic/DynamicProductHero.d.ts +2 -0
- package/dist/render/components/pdp-dynamic/DynamicRelatedProducts.js +1 -1
- package/dist/render/components/pdp-dynamic/DynamicSpecTable.js +1 -1
- package/dist/render/components/pdp-dynamic/RecordPhotoGallery.js +1 -1
- package/dist/render/components/product-hero/TyreHeroFitment.js +1 -1
- package/dist/render/components/product-hero/VehicleQuestion.d.ts +1 -2
- package/dist/render/components/product-hero/VehicleQuestion.js +1 -1
- package/dist/render/components/product-hero/WheelHeroFitment.js +1 -1
- package/dist/render/components/product-hero/trust-bullets.d.ts +5 -0
- package/dist/render/components/product-hero/trust-bullets.js +1 -0
- package/dist/render/components/useModalDismiss.d.ts +2 -1
- package/dist/render/components/useModalDismiss.js +1 -1
- package/dist/render/components/wheels-plp/AlloyWheelsListing.js +1 -1
- package/dist/render/components/wheels-plp/PlpNotifyMeDialog.js +1 -1
- package/dist/render/lib/api/index.d.ts +0 -8
- package/dist/render/lib/api/index.js +1 -1
- package/dist/render/lib/api/types.d.ts +7 -3
- package/dist/render/lib/booking/appointment-time.d.ts +2 -0
- package/dist/render/lib/booking/appointment-time.js +1 -0
- package/dist/render/lib/catalog/from-wheel.js +1 -1
- package/dist/render/lib/catalog/plp-item.js +1 -1
- package/dist/render/lib/checkout/stripe-appearance.d.ts +10 -0
- package/dist/render/lib/checkout/stripe-appearance.js +1 -0
- package/dist/render/lib/checkout/wallet-return.d.ts +1 -1
- package/dist/render/lib/commerce.d.ts +1 -0
- package/dist/render/lib/commerce.js +1 -1
- package/dist/render/lib/content/legacy-block-align.d.ts +2 -0
- package/dist/render/lib/content/legacy-block-align.js +1 -0
- package/dist/render/lib/content/menu-row.d.ts +0 -3
- package/dist/render/lib/content/menu-row.js +1 -1
- package/dist/render/lib/content/site.d.ts +1 -1
- package/dist/render/lib/document/blocks/commerce/AlloyWheelsListing/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/BundleOffer/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/CheckoutCTA/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/Collections/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/CompatibleTyres/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/CountrySwitchBlock/render.js +1 -1
- package/dist/render/lib/document/blocks/commerce/DeliveryOptions/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/DetailRows/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/EuTyreLabel/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/FitmentFinder/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/FitmentTable/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/ProductGrid/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/ProductHero/meta.d.ts +6 -0
- package/dist/render/lib/document/blocks/commerce/ProductHero/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/ProductHero/render.js +1 -1
- package/dist/render/lib/document/blocks/commerce/RelatedProducts/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/SpecTable/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/SpecTable/render.js +1 -1
- package/dist/render/lib/document/blocks/commerce/TyreFitment/meta.js +1 -1
- package/dist/render/lib/document/blocks/commerce/TyreSizes/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/ContactCards/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/ContactRouting/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/FooterPayment/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/FooterSocial/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/MessagingCards/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/OpeningHours/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/RateTable/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/SubmitBuild/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/Subscribe/meta.js +1 -1
- package/dist/render/lib/document/blocks/service/SubscribeBlogs/meta.js +1 -1
- package/dist/render/lib/document/lazy-draws.js +1 -1
- package/dist/render/lib/document/render-client.d.ts +8 -3
- package/dist/render/lib/document/render-client.js +1 -1
- package/dist/render/lib/document/section-to-box-rows-reviews.js +1 -1
- package/dist/render/lib/document/storefront-root.d.ts +0 -2
- package/dist/render/lib/document/storefront-root.js +1 -1
- package/dist/render/lib/field-input.d.ts +1 -0
- package/dist/render/lib/field-input.js +1 -0
- package/dist/render/lib/sections/content-cap-gutter.d.ts +1 -0
- package/dist/render/lib/sections/content-cap-gutter.js +1 -0
- package/dist/render/lib/sections/hero-trust-bullets.d.ts +2 -0
- package/dist/render/lib/sections/hero-trust-bullets.js +1 -0
- package/dist/render/lib/tyres/spec-sheet.d.ts +17 -0
- package/dist/render/lib/tyres/spec-sheet.js +1 -1
- package/dist/render/lib/use-scope-class.d.ts +1 -0
- package/dist/render/lib/use-scope-class.js +1 -0
- package/dist/render/lib/wheels/catalog-default-layout.d.ts +3 -3
- package/dist/render/lib/wheels/catalog-default-layout.js +1 -1
- package/dist/render/lib/wheels/catalog-filters.d.ts +2 -2
- package/dist/render/lib/wheels/catalog-filters.js +1 -1
- package/dist/render/lib/wheels/grid-source.d.ts +7 -1
- package/dist/render/lib/wheels/grid-source.js +1 -1
- package/dist/render/lib/wheels/plp-hydrate.js +1 -1
- package/dist/words.d.ts +48 -48
- package/dist/words.js +6 -6
- package/package.json +7 -4
- package/dist/chunks/EditorPreviewCheckout-YQ3F5MSG.js +0 -4
- package/dist/chunks/chunk-BZDVZUF4.js +0 -1
- package/dist/chunks/chunk-UGXNUQRA.js +0 -246
- package/dist/chunks/chunk-UJW4B64R.js +0 -1
- package/dist/render/components/product-hero/hero-content.d.ts +0 -7
- package/dist/render/components/product-hero/hero-content.js +0 -1
- package/dist/render/components/useIsLightTheme.d.ts +0 -1
- package/dist/render/components/useIsLightTheme.js +0 -1
- package/dist/render/lib/content/product-hero.d.ts +0 -14
- package/dist/render/lib/content/product-hero.js +0 -1
- package/dist/render/lib/wheels/collections.d.ts +0 -22
- package/dist/render/lib/wheels/collections.js +0 -1
- /package/dist/chunks/{chunk-UGXNUQRA.js.LEGAL.txt → chunk-3IQQNZIM.js.LEGAL.txt} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.76.0 - 2026-10-31
|
|
4
|
+
|
|
5
|
+
**A major for hosts (major version zero, so a minor number):** the peers move to `efficient-web-builder` `^46.0.0` (was `^44.0.0`), `efficient-easel` `^26.1.0` (was `^23.1.0`) and `efficient-shell` `^11.8.0` (was `^10.13.0`), published names and paths go, and stored pages need data moves. A host must: install the three new peers (its Tailwind must resolve `efficient-shell/motion.css`); follow the page theme with `!useRootIsDark({ whenUnset: true })` from `efficient-shell/theme` in place of `render/components/useIsLightTheme`; stop importing `lib/wheels/collections` and call `scopeCatalogSections(data)` with the page only; pass the theme row's `theme` to `RenderClient`; stop using the removed names listed below; and delete the removed words from its editor catalogue. For efficient-storefront: do not take this release until the US-site width data move M1 (114 rows / 22 pages, by CLI) and the #392 data move (maxWidth on 3 Text blocks, inovit_us) have run; in the sync PR that takes it, change `app/wheels/[slug]/PDPClient.tsx`, `app/wheels/CatalogPageClient.tsx`, `components/CollectionHeader.tsx`, `lib/wheels/range-collections.ts` and `app/wheels/page.tsx`, delete `scripts/harness/panel-row-wrap.tsx` and `probe-panel-row-wrap.mjs`, and update the old `data-menu-align` start / end CSS in `scripts/harness/box-panels-converge.html`. After the storefront sync: the admin-portal bump, then the CLI moves of the Product Hero trust bullets (1 page), the hartesmetal.com `/wheels` Product Grid source (4 cells) and the footer Menu's `linkAlign` (4 copies).
|
|
6
|
+
|
|
7
|
+
- **BREAKING: web-builder 46, easel 26, shell 11** (#284). Peer and dev, here and in `package/`: `efficient-web-builder` `^46.0.0`, `efficient-easel` `^26.1.0`, `efficient-shell` `^11.8.0` (in `package/package.json` the peers were `^44.0.0`, `^23.1.0`, `^10.13.0`; #275 below moved shell to `^10.23.0` on the way). The Box rows come from easel's box-fields through the builder's one binding (`editor/lib/document/box-fields`); the container gap row is `containerGapField`. The Reviews section-to-box row drops `on: false` (the builder's one list, `SECTION_TO_BOX_ON`). 15 `fields.tsx` files drop `widthFieldsForParent`: sections follow the site's Background and Content width, and the old width keys (`widthMode`, `fullWidth`, `pageWidth`) are not read; `StorefrontRootProps` loses `fullWidth` and `pageWidth`. The chat bubble in the editor uses the canvas frame. The content-cap side padding is one constant, `CONTENT_CAP_GUTTER` (`render/lib/sections/content-cap-gutter`), same markup. **efficient-storefront must not take this release until the width data move M1 is done**, or live sections change look.
|
|
8
|
+
- **Entrance is efficient-shell's** (#298, merged into #284). The site sheet loads `efficient-shell/motion.css`; the `data-sf-anim` rules and the sheet's own section keyframes are gone. Old Fade / Rise / Scale values still play, with the same distances, time and curve. A Gap only Box zeroes its blocks' frame padding through their Entrance wrapper too. 15 blocks have the Entrance rows and no Design / Animation tab strip yet (a web-builder follow-up).
|
|
9
|
+
- **BREAKING: which products a Product Grid shows is one setting, "Product content"** (#249). Manual, All products, or one storefront Category; only the chosen answer's rows are drawn, on every page. "Product types" is one row (`productKindsField`) for the Product Grid and the Alloy Wheels Listing; unset reads as what the section draws. The Catalog Filter Bar follows Category grids. An empty `/wheels` page is seeded with one Category grid per category the site's catalog holds, its links `/wheels?collection=<name>`. **Removed:** `lib/wheels/collections` (`COLLECTIONS`, `COLLECTION_ANCHORS`, `PROCESS_ORDER`, `siteProcesses`, `siteCollections`, `slugifyProcess`, `collectionsForCatalog`, `CollectionMeta`, `SiteCollectionMeta`); `scopeCatalogSections` takes the page only; `GridSource.process` is no longer read; `CatalogFilterBar`'s `processOptions` is a list of category names with no default. A stored `collection:` value reads as the category of that name; nothing is written until the merchant picks.
|
|
10
|
+
- **BREAKING: the page theme is read with efficient-shell's hook** (#275). `render/components/useIsLightTheme` is deleted; the blocks call `useRootIsDark`, `rootIsDark` and `watchRootTheme` from efficient-shell and keep no reader or watcher of their own. A page with the `dark` class is now dark here too, as the stylesheet reads it.
|
|
11
|
+
- **BREAKING for stored pages: the Product Hero's trust bullets are a Box of Text blocks in the hero** (#279, C10). The Product Hero has a `trustBullets` slot that holds a Box (`allow: ["Flex"]`, `lib/sections/hero-trust-bullets`), one plain Text block per bullet, each with its own Layers row and panel. **The shop no longer reads `root.props.heroBullets`**: a page that set bullets shows none until a CLI move puts them in the slot (inovit_us: 1 page). The right panel of a dynamic page keeps Product type and Record type only. An empty slot draws no row on the published page. A migrated bullet keeps the old row's size, weight and spacing; two or more bullets stack one per line. **Removed:** `lib/content/product-hero` (`PRODUCT_HERO_BULLETS_PROP`, `resolveProductHeroContent`, `parseHeroBullet`, `heroBulletLine`, `HERO_BULLET_EXAMPLE`, `HERO_BULLET_SEPARATOR`, `PRODUCT_HERO_DEFAULTS`) and `components/product-hero/hero-content` (`ProductHeroContentProvider`, `useProductHeroContent`).
|
|
12
|
+
- **BREAKING: `editor/components/HeaderSettingsPanel` no longer exports `Field`** (#287). The header panel's rows are easel's `SettingsField` and `SettingsDefaultReset`, its groups the builder's `PanelBand`; `BlogSource` and `SocialLinksDoor` use `PanelBand` too, and no blocks file imports `GroupLabel`. Amber, radius and border literals read shell tokens (`--warning-text`, `--radius-control`, `--radius-card`, `--line`). Not pixel identical: the groups are grey bands, every row has a glyph, the "Open live" link is a control-radius button.
|
|
13
|
+
- **BREAKING: every photo view takes the site scrim** (#299, #297). The `Lightbox` frame draws the scrim (`SITE_TINT`, `SITE_BLUR[8]` from `PopupFrame`) for every photo view, and its `style` prop is removed; new export `LIGHTBOX_CLOSE_TINT`. Seen by a shopper: the /gallery photo view goes from black 92% to the site background 78%, the wheel-page hero image view from black 90% to 78%, the photos-only record gallery from 86% to 78%; the blur stays 8px.
|
|
14
|
+
- **BREAKING: the alignment strips are efficient-easel's rows** (#306). `render/*` drops `MenuLinkAlign`, `MENU_LINK_ALIGNS`, `resolveMenuLinkAlign` (`render/lib/content/menu-row`), `FooterPaymentAlign` (`render/components/FooterPayment`) and `SocialAlign` (`render/components/FooterSocial`): use web-builder's `BlockAlign` / `BLOCK_ALIGN_JUSTIFY` (`efficient-web-builder/format/lib/content/block-align`); the start / end reader is `legacyBlockAlignOf` (`render/lib/content/legacy-block-align`). Footer Logo, Payment logos, Social logos and the Menu's Link alignment draw easel's Block alignment row and store left / center / right (start / end still read, on the page and in the panel); the Product Hero's words draw Text alignment; the Footer box draws Item alignment with Stretch (an unset value lights Start). The storefront takes this release before the `linkAlign` data move: its current blocks code does not read left / right.
|
|
15
|
+
- **The published page converts with the site theme** (#304). `RenderClient` takes the theme row's `theme`; `renderMetadata(...)` builds the metadata (the site widths plus the builder's `siteThemeMetadata`). A host that passes nothing hands no theme. No page changes today: no conversion row is on in builder 46.
|
|
16
|
+
- **Checkout: a placed order is handled once and shown** (#290, #291, #292, #300, #280, #303).
|
|
17
|
+
- Once an order is placed, the basket and the coupon are emptied (#290). They are kept when the order is refused or a card payment step fails to start.
|
|
18
|
+
- When the payment step fails to start after the order is saved, the shopper reads "Your order N is saved, but the payment did not start", and the button becomes "Try payment again · N", which starts the payment for the same order (#292). A new address ticked "Save this address to my account" is saved once per order, and a failed save is tried again (#291).
|
|
19
|
+
- When a coupon check fails on a network or server error, the code is not struck through and a "Try again" button checks it again (#300). A refused code looks as before.
|
|
20
|
+
- "Not you? Sign out" also empties the email, name, address, phone and state, and resets the country to the header region (#280). The cart is kept.
|
|
21
|
+
- The order confirmation shows a short receipt under the order number: delivery method and charge, discount and coupon code, and "Total paid" or "Order total" (#303). Every amount is the order's own; a missing row is left out, and a wallet return with nothing parked shows the order number only.
|
|
22
|
+
- **Screen readers and keyboards on the shop** (#285, #302, #281, #296, #308). The checkout Email, Country and State captions name their controls (#285). The catalog sort control is named "Sort results" (#302). A filter pill carries `aria-haspopup`, `aria-expanded` and `aria-controls`, and closes on Escape (focus back on the pill) or a press outside (#281). The chosen finish, size and gallery photo on a product page set `aria-pressed` (#296). The cart drawer and the "Notify me when available" dialog keep Tab inside while open and give focus back on close (`useModalDismiss` takes an optional `trapRef`; `PopupFrame`'s site scrim gains `trapRef`) (#308).
|
|
23
|
+
- **Catalog and cart** (#286, #289). In the pill filter bar on a phone, the results link, Clear All and sort wrap onto a second row under the pills; before, they were hidden below 720px (#286). The cart drawer closes when the route changes, so every link in it closes it (#289).
|
|
24
|
+
- **The fitment car card shows the factory tyre sizes** (#301): "OEM front tyres" and "OEM rear tyres", or "—". The desktop grid goes from 6 to 4 columns.
|
|
25
|
+
- **Spec rows and fitment headers follow the site English** (#276). `SpecTable` gets `builtInLabels`; built rows and the `FitmentTable` headers go through `useEnglish()` ("Center Bore" on a US site). Merchant-typed rows stay as typed.
|
|
26
|
+
- **Shopper text removed** (#277, #278). The Contact channel rail drops "→ Message routes here" and "Other inboxes filter as spam"; the routed row keeps its accent left line (#277). The wheel page drops "Asked once. Every wheel after this one is already filled in.", "Wheels · Not handed" and "Only one of each is left, so there is nothing to choose here."; the tyre page drops its "Asked once" line; `VehicleQuestion` loses `askNote` (#278).
|
|
27
|
+
- **A Box's own phone Gap draws below 800px** (#283). `.sf-gap-zone` reads `--sf-gap-len-phone`, which web-builder writes only for a Box with a stored phone Gap (efficient-web-builder #390); without it the gap is half, as before.
|
|
28
|
+
- **One home for duplicated parts, no look change** (#288, #293, #295). New render entries: `lib/booking/appointment-time` (`formatAppointment`, `formatAppointmentTime`), `lib/commerce` `currencyFormat`, `lib/use-scope-class` (`useScopeClass`), `lib/checkout/stripe-appearance` (`stripeAppearance`, `StripeAppearance`), `lib/tyres/spec-sheet` (`TYRE_SPEC_KEYS`, `TYRE_SPEC_FIELD_KEYS`), `lib/field-input` (`FIELD_INPUT_CLASS`). The header cart badge asks the builder's `prefersReducedMotion` (#288). The Spec Table, Product, Gallery A and Product Hero panels draw one "category, then product" part (`CategoryProductFields`) (#293). The lightbox dismisses through `useModalDismiss`, so the chat bubble hides while it is open (#293). The consent panel, Notify me and the subscribe popup sit in `PopupFrame`'s new `site` scrim (`SITE_TINT`) (#295).
|
|
29
|
+
- New editor words to translate: "Product content", "Pick the products yourself below, or choose “All products” or a category from {place}.", "Shows this source’s products as they are now, here and on the live page. Set how many appear with “Items to display”.", "Disabled because this grid’s {source} is set to “{name}”. The grid fills itself from that source automatically. To pick wheels here, set {source} back to “Manual”.", "{n} {one}", "{n} {many}", "OEM front tyres", "OEM rear tyres", and from web-builder 46: "Effect", "Duration", "Delay", "Loop", "Reveal", "Glide", "Bounce", "Flip", "Spin", "Desktop", "Box shape", "Square (1:1)", "Gutter", "Layouts", "Link to", "Shrink to fit", "When the text does not fit", "Highlight when a link jumps here", "When a link lands on this Box's anchor, the Box gets an accent outline and its first block turns accent.", "Follows Styles ▸ Basics ▸ Corners until you set a number here.", "The width of every section's background.", "The width of every section's content.", "Enter by hand", "Find from the address", "Find from the address (OpenStreetMap)", "Latitude, longitude", "City maps", "City pictures", "A card per city, grouped by region: address, phone, hours and a map.", "A wall of city photos, grouped by region. Each photo links to its city's card.", "A line across the blocks, with a dot on each.", "Still to come: a hollow dot, and the gold line stops before it.", "none", "upper". Gone: "Products source", "Categories", "Linked to “{name}” · {n} product", "Linked to “{name}” · {n} products", the old "None" versions of the three Product content hints, "Product hero", "Trust bullets", "The promises under Add to Cart. Text before the · is bold. Leave the list empty to show no promises at all.", "Start" (#306), and from web-builder 46: "Motion", "Scroll duration", "Clear change", "Clear change: {label}", "Clear override", "Clear override: {label}", "Clear {what}", "Clear {what}: {label}", "Contained", "Content cannot be wider than the background.", "On phones, content always fills the screen.", "The width of every section's background, until the section sets its own.", "The width of every section's content, until the section sets its own.", "The section is full width, so this card follows Styles ▸ Basics ▸ Corners.", "This section runs edge to edge, so its corners sit off the page. Set Width to Content width to use them.", "Coordinates from OpenStreetMap", "Enter coordinates manually", "Find coordinates", "Hide manual coordinates", "Image width", "Item alignment", "Justify", "Stretch", "Left and right", "Top and bottom", "No wrap", "Space between", "e.g. {example}", "from Styles".
|
|
30
|
+
- Guards: new `scripts/test-product-content.tsx` (#249), `scripts/test-page-theme-hook.tsx` (#275), `scripts/test-contact-routing-no-marker.tsx` (#277), `scripts/test-wheel-page-has-no-scaffold-text.tsx` (#278), `scripts/test-checkout-sign-out-clears-details.tsx` (#280), `scripts/test-filter-pill-dismiss.tsx` (#281), `scripts/test-one-page-theme-reader.ts` and `scripts/test-content-cap-gutter-one-home.ts` (#284), `scripts/test-checkout-field-names.tsx` (#285), `scripts/test-catalog-filter-bar-phone.tsx` (#286), `scripts/test-editor-duplicates-b1.ts` (#287), `scripts/test-render-helpers-b2.ts` and the shared `scripts/happy-dom-globals.ts` (#288; #294 moves the cart-close guard onto it), `scripts/test-cart-close-on-navigate.tsx` (#289), `scripts/test-checkout-empties-the-cart.tsx` (#290), `scripts/test-checkout-retry-saves-address-once.tsx` (#291), `scripts/test-checkout-payment-start-failure.tsx` (#292), `scripts/test-one-category-product-picker.ts` and `scripts/test-one-field-input-class.ts` (#293), `scripts/test-site-dialogs-one-frame.tsx` (#295; §5 from #297, widened by #299), `scripts/test-product-hero-choice-pressed.ts` (#296), `scripts/test-stock-fitment-card-tyres.tsx` (#301), `scripts/test-catalog-sort-name.tsx` (#302), `scripts/test-checkout-confirmation-receipt.tsx` (#303), `scripts/test-render-client-site-theme.tsx` (#304), `scripts/test-block-align-one-alphabet.tsx` (#306). Changed: `scripts/test-shell-peer-range.ts` reads the builder's own peer range (#284); `scripts/test-section-animation.tsx` is rewritten for the Entrance module and `scripts/test-gap-only-one-rule.tsx` gains §4 (#298); `scripts/test-product-hero-bullets.tsx` is rewritten for the slot (#279); `scripts/test-english-variant.tsx` gains test 5 (#276); `scripts/test-container-gap.tsx` expects the phone Gap rule (#283); `scripts/test-coupon-preview-shopper-token.tsx` gains a retry section (#300); `scripts/test-overlays-dismiss-in-one-place.tsx` checks the lightbox (#293) and the Tab trap (#308); `scripts/test-content-cap-gutter-one-home.ts` pins the wheels listing's own 2.5rem gutter (#305). Removed: `scripts/test-catalog-site-processes.ts` (#249), `scripts/test-panel-row-wraps.tsx` (#287).
|
|
31
|
+
|
|
32
|
+
## 0.75.0 - 2026-10-29
|
|
33
|
+
|
|
34
|
+
**A major for hosts (major version zero, so a minor number):** three editor phrases leave `words`, and the `render/lib/api` entry loses `AdminStorefrontSitePatch`, `storefrontAdmin.updateSite` and the site's Maps fields. The peer ranges do not move. A host must: delete "No regions yet", "Site header — above every page" and "Site footer — below every page" from its editor catalogue; stop calling `storefrontAdmin.updateSite`; deploy efficient-backend #3774 before this release reaches a shop that takes bank transfer; and, for efficient-storefront, carry the `openapi.yml` change (`bank` in `paymentMethods`, the quote's `postcode` and `courier`, the Maps fields removed) in the sync PR that takes this release.
|
|
35
|
+
|
|
36
|
+
- **BREAKING: the editor canvas draws no site header caption and no empty region label** (#270). "Site header — above every page" and "Site footer — below every page" (`SectionGroupBody`) and the "No regions yet" box in a Country Switch block of a site with no regions (`CountrySwitchTool`, with its dashed placeholder) are gone. The live site never drew them; with no regions the canvas now draws nothing for that block, as the live site does. `CountrySwitchTool` loses its `editing` prop. The three phrases leave `efficient-storefront-blocks/words` (`WebsiteEditorCatalogue`, `STOREFRONT_BLOCKS_WORDS`): a host that lists them must delete them (found in foyerboard-venue-portal `src/locales/*/editor.ts`).
|
|
37
|
+
- **BREAKING: the editor no longer reads or saves the site record's Maps key** (#271). The EFFICIENT backend site record is `{ name, slug }`: `maps_api_key` / `maps_map_id` are no longer mapped (backend 98.32.0 does not send them), and `site.update` is removed, so `canEditSiteRecord` is now false. `render/lib/api`: `AdminStorefrontSite` loses `maps_api_key` / `maps_map_id`; `AdminStorefrontSitePatch` and `storefrontAdmin.updateSite` are removed. `render/lib/api/types` is regenerated: `Site` loses `mapsApiKey` / `mapsMapId`, and the quote's `courier` is the named `CartQuoteCourier` (same fields). Not changed: `package/src/public.d.ts` keeps `SiteRecord.mapsApiKey` / `mapsMapId`, `SiteRecordPatch` and `WebsiteSite.update`, as efficient-easel's contract, until easel's next major.
|
|
38
|
+
- **The checkout offers bank transfer only when the merchant switched it on** (#209; owner ruling 2026-10-23). `buildPayOptions` pushed "Bank transfer · Invoiced" for every tenant. Now it reads `bank` from `site.paymentMethods` like every other method, last in the list; efficient-backend #3774 adds the switch (`bank_transfer_enabled`, default off). `PaymentMethod` and the `/site` contract type gain `"bank"`.
|
|
39
|
+
- A tenant with no method switched on: the Payment card says `NO_PAYMENT_METHOD_NOTE` ("This shop does not take payment online yet. Please contact the shop to order."), the button reads "No online payment" and is off, and `placeOrder` places nothing.
|
|
40
|
+
- **For hosts: deploy efficient-backend #3774 first.** A backend without it never lists `bank`, so its tenants would lose bank transfer.
|
|
41
|
+
- **The checkout sends the postcode with its quote, once the address is complete** (#253). `QuoteDestination` gains `postcode` (`useCart().setQuoteDestination`); `products.quoteCart` sends it as `postcode` (efficient-backend #3918: with it, the tenant's connected courier is one more delivery option). The checkout sets it only when line 1, city, postcode, country and, where the country has a list, the state are filled; away from checkout none is sent. Without the backend change the field is ignored and nothing changes. `render/lib/api/types` gains `postcode` on `CartQuoteRequest`.
|
|
42
|
+
- **When the connected courier cannot be priced, the checkout asks the shopper to try again** (Lewis 2026-10-27). The quote's `courier` answer (`{status, reason}` or null) is on `useCart().courier`, and `useCart().requote()` asks again for the same cart and address. On `status: "unavailable"` the courier is not offered and the Shipping card says `SHIPPING_RETRY_NOTE` ("Shipping cannot be calculated right now. Please try again.") with a Try again control. No second message, no retry counter.
|
|
43
|
+
- **The checkout's Phone field has no example number** (#273). It showed "+44 7700 900000", a UK number, on every site. The field keeps its visible "Phone" label; no other example is put in.
|
|
44
|
+
- **A website map draws on the editor's canvas** (#269, C24). The Locations Map and every Contact / Locations card drew an empty grey box in the editor, because the map's sheets landed in the host head, which the canvas frame does not mirror. `package/build.mjs` adds `maplibre-gl.css` and `efficient-shell/map-site.css` to the canvas sheet (`MAP_SHEETS`). Published pages are unchanged.
|
|
45
|
+
- **The Products source select uses the full row again** (#272). In the Product Grid and Product Hero panels the select was squeezed to one letter; `CategorySource` now draws the link status, "Refresh now" and the help line under the field, as the other source rows do.
|
|
46
|
+
- **The package declares `qrcode`** (#268). `dist/render/lib/qr.js` imports `qrcode`, and the published manifest did not declare it, so a host that imported `ContactCards`, `FooterMessaging` or `MessagingCards` from `render/*` without its own `qrcode` failed to build. `package/package.json` now has `"dependencies": { "qrcode": "^1.5.4" }` (a dependency, not a peer).
|
|
47
|
+
- **Checked against web-builder 44.0.1** (#267). The dev builder moves to `^44.0.1` (its media manifest names the Hero slide's `videoFrame` again); the peer stays `^44.0.0`.
|
|
48
|
+
- New editor words to translate: "Shipping cannot be calculated right now. Please try again.", "This shop does not take payment online yet. Please contact the shop to order.". Gone: "No regions yet", "Site header — above every page", "Site footer — below every page".
|
|
49
|
+
- Guards: new `scripts/test-group-no-caption-on-canvas.tsx` (#270), `scripts/test-site-record-has-no-maps-key.ts` (#271), `scripts/test-checkout-offers-only-switched-on-methods.tsx` (#209), `scripts/test-checkout-phone-has-no-country-example.tsx` (#273), `scripts/test-products-source-row.tsx` (#272); `scripts/test-checkout-quote-destination.tsx` gains §7 and §8 (#253); `scripts/test-editor-canvas-live-head.tsx` gains section 4 (#269); `scripts/test-web-package.mjs` checks that every import in `package/dist` is declared in `package/package.json` (#268); `scripts/test-shell-peer-range.ts` pins the dev builder `^44.0.1` (#267).
|
|
50
|
+
|
|
3
51
|
## 0.74.0 - 2026-10-28
|
|
4
52
|
|
|
5
53
|
**A major for hosts (major version zero, so a minor number):** the peers move to `efficient-web-builder` `^44.0.0` (was `^42.0.0`), `efficient-easel` `^23.1.0` (was `^22.0.0`) and `efficient-shell` `^10.13.0` (was `^10.0.0`), three published names and one published row key go, and the Reviews props narrow. **0.71.0, 0.72.0 and 0.73.0 were written but never published:** npm goes from 0.70.0 to this release, which carries their sections below.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use client";import{$ as un,L as en,M as tn,N as nn,O as rn,P as an,Q,S as qe,T as on,U as sn,V as Ke,W as cn,Y as st,_ as ln,aa as pn,b as Jt,c as Xt,d as Zt,e as Qt,fa as dn,ka as mn,la as fn,oa as ct,qa as G,ra as z,x as We}from"./chunk-4F5CAFXO.js";import{i as Se,o as Pe,v as j}from"./chunk-YFPWVNDB.js";import{Ca as Gt,wa as Ht,ya as ne}from"./chunk-YAYHH5GY.js";import{k as Vt,l as Te,m as Z}from"./chunk-5NXOTPHK.js";import{a as it,b as Br}from"./chunk-Y6SLVHK3.js";var hn=it((Qa,yn)=>{"use strict";var Gr="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";yn.exports=Gr});var Cn=it((eo,xn)=>{"use strict";var Vr=hn();function vn(){}function bn(){}bn.resetWarningCache=vn;xn.exports=function(){function e(r,a,i,s,p,d){if(d!==Vr){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}e.isRequired=e;function t(){return e}var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:bn,resetWarningCache:vn};return n.PropTypes=n,n}});var Sn=it((ro,kn)=>{"use strict";kn.exports=Cn()();var to,no});import{useEffect as xr,useMemo as hr,useRef as Me,useState as ve}from"react";import{rootIsDark as Hr}from"efficient-shell/format";function gn(){if(typeof document>"u")return;let e=getComputedStyle(document.documentElement),t=(r,a)=>e.getPropertyValue(r).trim()||a,n=Hr({whenUnset:!0});return{theme:n?"night":"stripe",variables:{colorPrimary:t("--accent",n?"#c9a461":"#8a6a2a"),colorBackground:t("--site-surface",n?"#131313":"#ffffff"),colorText:t("--fg",n?"#f5f1e8":"#0a0a0a"),borderRadius:"0px"}}}var A=Br(Sn(),1);import N from"react";function Pn(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function Jr(e){if(Array.isArray(e))return e}function In(e,t,n){return(t=na(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Xr(e,t){var n=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(n!=null){var r,a,i,s,p=[],d=!0,l=!1;try{if(i=(n=n.call(e)).next,t!==0)for(;!(d=(r=i.call(n)).done)&&(p.push(r.value),p.length!==t);d=!0);}catch(b){l=!0,a=b}finally{try{if(!d&&n.return!=null&&(s=n.return(),Object(s)!==s))return}finally{if(l)throw a}}return p}}function Zr(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
2
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Nn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable})),n.push.apply(n,r)}return n}function wn(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?Nn(Object(n),!0).forEach(function(r){In(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Nn(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function Qr(e,t){if(e==null)return{};var n,r,a=ea(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}function ea(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function An(e,t){return Jr(e)||Xr(e,t)||ra(e,t)||Zr()}function ta(e,t){if(typeof e!="object"||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t);if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}function na(e){var t=ta(e,"string");return typeof t=="symbol"?t:t+""}function lt(e){"@babel/helpers - typeof";return lt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},lt(e)}function ra(e,t){if(e){if(typeof e=="string")return Pn(e,t);var n={}.toString.call(e).slice(8,-1);return n==="Object"&&e.constructor&&(n=e.constructor.name),n==="Map"||n==="Set"?Array.from(e):n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Pn(e,t):void 0}}var F=function(t,n,r){var a=!!r,i=N.useRef(r);N.useEffect(function(){i.current=r},[r]),N.useEffect(function(){if(!a||!t)return function(){};var s=function(){if(i.current)return i.current.apply(i,arguments)};return t.on(n,s),function(){t.off(n,s)}},[a,n,t,i])},ut=function(t){var n=N.useRef(t);return N.useEffect(function(){n.current=t},[t]),n.current},Ne=function(t){return t!==null&<(t)==="object"},aa=function(t){return Ne(t)&&typeof t.then=="function"},oa=function(t){return Ne(t)&&typeof t.elements=="function"&&typeof t.createToken=="function"&&typeof t.createPaymentMethod=="function"&&typeof t.confirmCardPayment=="function"},En="[object Object]",ia=function e(t,n){if(t===n)return!0;if(!Ne(t)||!Ne(n))return t===n;var r=Array.isArray(t),a=Array.isArray(n);if(r!==a)return!1;var i=Object.prototype.toString.call(t)===En,s=Object.prototype.toString.call(n)===En;if(i!==s)return!1;if(!i&&!r)return t===n;var p=Object.keys(t),d=Object.keys(n);if(p.length!==d.length)return!1;for(var l={},b=0;b<p.length;b+=1)l[p[b]]=!0;for(var m=0;m<d.length;m+=1)l[d[m]]=!0;var h=Object.keys(l);if(h.length!==p.length)return!1;var u=t,P=n,S=function(V){return e(u[V],P[V])};return h.every(S)},On=function(t,n,r){return Ne(t)?Object.keys(t).reduce(function(a,i){var s=!Ne(n)||!ia(t[i],n[i]);return r.includes(i)?(s&&console.warn("Unsupported prop change: options.".concat(i," is not a mutable property.")),a):s?wn(wn({},a||{}),{},In({},i,t[i])):a},null):null},Ln="Invalid prop `stripe` supplied to `Elements`. We recommend using the `loadStripe` utility from `@stripe/stripe-js`. See https://stripe.com/docs/stripe-js/react#elements-props-stripe for details.",Rn=function(t){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Ln;if(t===null||oa(t))return t;throw new Error(n)},sa=function(t){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Ln;if(aa(t))return{tag:"async",stripePromise:Promise.resolve(t).then(function(a){return Rn(a,n)})};var r=Rn(t,n);return r===null?{tag:"empty"}:{tag:"sync",stripe:r}},ca=function(t){!t||!t._registerWrapper||!t.registerAppInfo||(t._registerWrapper({name:"react-stripe-js",version:"6.12.0"}),t.registerAppInfo({name:"react-stripe-js",version:"6.12.0",url:"https://stripe.com/docs/stripe-js/react"}))},Ye=N.createContext(null);Ye.displayName="ElementsContext";var Tn=function(t,n){if(!t)throw new Error("Could not find Elements context; You need to wrap the part of your app that ".concat(n," in an <Elements> provider."));return t},dt=function(t){var n=t.stripe,r=t.options,a=t.children,i=N.useMemo(function(){return sa(n)},[n]),s=N.useState(function(){return{stripe:i.tag==="sync"?i.stripe:null,elements:i.tag==="sync"?i.stripe.elements(r):null}}),p=An(s,2),d=p[0],l=p[1];N.useEffect(function(){var h=!0,u=function(S){l(function(w){return w.stripe?w:{stripe:S,elements:S.elements(r)}})};return i.tag==="async"&&!d.stripe?i.stripePromise.then(function(P){P&&h&&u(P)}):i.tag==="sync"&&!d.stripe&&u(i.stripe),function(){h=!1}},[i,d,r]);var b=ut(n);N.useEffect(function(){b!==null&&b!==n&&console.warn("Unsupported prop change on Elements: You cannot change the `stripe` prop after setting it.")},[b,n]);var m=ut(r);return N.useEffect(function(){if(d.elements){var h=On(r,m,["clientSecret","fonts"]);h&&d.elements.update(h)}},[r,m,d.elements]),N.useEffect(function(){ca(d.stripe)},[d.stripe]),N.createElement(Ye.Provider,{value:d},a)};dt.propTypes={stripe:A.default.any,options:A.default.object};var qn=function(t){var n=N.useContext(Ye);return Tn(n,t)},_n=function(){var t=qn("calls useElements()"),n=t.elements;return n},la=function(t){var n=t.children,r=qn("mounts <ElementsConsumer>");return n(r)};la.propTypes={children:A.default.func.isRequired};var ua=N.createContext(null);ua.displayName="CheckoutContext";var jn=N.createContext(null);jn.displayName="CheckoutSdkContext";var pt=function(t){var n=N.useContext(jn),r=N.useContext(Ye);if(n){if(r)throw new Error("You cannot wrap the part of your app that ".concat(t," in both a checkout provider and <Elements> provider."));return n}else return Tn(r,t)},pa=["mode"],da=function(t){return t.charAt(0).toUpperCase()+t.slice(1)},O=function(t,n,r){var a="".concat(da(t),"Element"),i=function(l){var b=l.id,m=l.className,h=l.options,u=h===void 0?{}:h,P=l.onBlur,S=l.onFocus,w=l.onReady,V=l.onChange,M=l.onEscape,E=l.onClick,D=l.onLoadError,B=l.onLoaderStart,_=l.onNetworksChange,U=l.onConfirm,de=l.onCancel,we=l.onShippingAddressChange,be=l.onShippingRateChange,ae=l.onSavedPaymentMethodRemove,oe=l.onSavedPaymentMethodUpdate,ie=l.onAvailablePaymentMethodsChange,$=pt("mounts <".concat(a,">")),y="elements"in $?$.elements:null,H="checkoutSdk"in $?$.checkoutSdk:null,Ee=N.useState(null),me=An(Ee,2),T=me[0],Re=me[1],W=N.useRef(null),se=N.useRef(null);F(T,"blur",P),F(T,"focus",S),F(T,"escape",M),F(T,"click",E),F(T,"loaderror",D),F(T,"loaderstart",B),F(T,"networkschange",_),F(T,"confirm",U),F(T,"cancel",de),F(T,"shippingaddresschange",we),F(T,"shippingratechange",be),F(T,"savedpaymentmethodremove",ae),F(T,"savedpaymentmethodupdate",oe),F(T,"availablepaymentmethodschange",ie),F(T,"change",V);var ce;w&&(t==="expressCheckout"?ce=w:ce=function(){w(T)}),F(T,"ready",ce),N.useLayoutEffect(function(){if(W.current===null&&se.current!==null&&(y||H)){var R=null;if(H){var J=H,xe=H;switch(t){case"paymentForm":R=xe.createForm(u);break;case"payment":R=J.createPaymentElement(u);break;case"address":if("mode"in u){var q=u.mode,fe=Qr(u,pa);if(q==="shipping")R=J.createShippingAddressElement(fe);else if(q==="billing")R=J.createBillingAddressElement(fe);else throw new Error("Invalid options.mode. mode must be 'billing' or 'shipping'.")}else throw new Error("You must supply options.mode. mode must be 'billing' or 'shipping'.");break;case"expressCheckout":R=J.createExpressCheckoutElement(u);break;case"currencySelector":R=H.createCurrencySelectorElement();break;case"taxId":R=J.createTaxIdElement(u);break;case"contactDetails":R=J.createContactDetailsElement();break;case"linkSignup":if("createLinkSignupElement"in H)R=H.createLinkSignupElement(u);else throw new Error("<LinkSignupElement> requires <CheckoutElementsProvider> and is not supported inside <CheckoutFormProvider>.");break;case"terms":R=J.createTermsElement(u);break;default:throw new Error("<".concat(a,"> is not supported inside a checkout provider. Use an <Elements> provider instead."))}}else y&&(R=y.create(t,u));W.current=R,Re(R),R&&R.mount(se.current)}},[y,H,u]);var le=ut(u);return N.useEffect(function(){if(W.current){var R=On(u,le,["paymentRequest"]);R&&"update"in W.current&&W.current.update(R)}},[u,le]),N.useLayoutEffect(function(){return function(){if(W.current&&typeof W.current.destroy=="function")try{W.current.destroy(),W.current=null}catch{}}},[]),N.createElement("div",{id:b,className:m,ref:se})},s=function(l){pt("mounts <".concat(a,">"));var b=l.id,m=l.className;return N.createElement("div",{id:b,className:m})},p=n?s:i;return p.propTypes={id:A.default.string,className:A.default.string,onChange:A.default.func,onBlur:A.default.func,onFocus:A.default.func,onReady:A.default.func,onEscape:A.default.func,onClick:A.default.func,onLoadError:A.default.func,onLoaderStart:A.default.func,onNetworksChange:A.default.func,onConfirm:A.default.func,onCancel:A.default.func,onShippingAddressChange:A.default.func,onShippingRateChange:A.default.func,onSavedPaymentMethodRemove:A.default.func,onSavedPaymentMethodUpdate:A.default.func,onAvailablePaymentMethodsChange:A.default.func,options:A.default.object},p.displayName=a,p.__elementType=t,p},L=typeof window>"u",ma=N.createContext(null);ma.displayName="EmbeddedCheckoutProviderContext";var Mn=function(){var t=pt("calls useStripe()"),n=t.stripe;return n},oo=O("auBankAccount",L),io=O("card",L),so=O("cardNumber",L),co=O("cardExpiry",L),lo=O("cardCvc",L),uo=O("currencySelector",L),po=O("iban",L),Fn=O("payment",L),mo=O("expressCheckout",L),fo=O("paymentRequestButton",L),go=O("linkAuthentication",L),yo=O("linkSignup",L),ho=O("contactDetails",L),vo=O("address",L),bo=O("shippingAddress",L),xo=O("paymentMethodMessaging",L),Co=O("taxId",L),ko=O("issuingCardNumberDisplay",L),So=O("issuingCardCvcDisplay",L),Po=O("issuingCardExpiryDisplay",L),No=O("issuingCardPinDisplay",L),wo=O("issuingCardCopyButton",L),Eo=O("terms",L);function He(e){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?He=function(t){return typeof t}:He=function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},He(e)}var $n="dahlia",fa=function(t){return t===3?"v3":t},Wn="https://js.stripe.com",ga="".concat(Wn,"/").concat($n,"/stripe.js"),ya=/^https:\/\/js\.stripe\.com\/v3\/?(\?.*)?$/,ha=/^https:\/\/js\.stripe\.com\/(v3|[a-z]+)\/stripe\.js(\?.*)?$/,Dn="loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used",va=function(t){return ya.test(t)||ha.test(t)},ba=function(){for(var t=document.querySelectorAll('script[src^="'.concat(Wn,'"]')),n=0;n<t.length;n++){var r=t[n];if(va(r.src))return r}return null},Un=function(t){var n=t&&!t.advancedFraudSignals?"?advancedFraudSignals=false":"",r=document.createElement("script");r.src="".concat(ga).concat(n);var a=document.head||document.body;if(!a)throw new Error("Expected document.body not to be null. Stripe.js requires a <body> element.");return a.appendChild(r),r},xa=function(t,n){!t||!t._registerWrapper||t._registerWrapper({name:"stripe-js",version:"9.17.0",startTime:n})},_e=null,ze=null,Be=null,Ca=function(t){return function(n){t(new Error("Failed to load Stripe.js",{cause:n}))}},ka=function(t,n){return function(){window.Stripe?t(window.Stripe):n(new Error("Stripe.js not available"))}},Sa=function(t){return _e!==null?_e:(_e=new Promise(function(n,r){if(typeof window>"u"||typeof document>"u"){n(null);return}if(window.Stripe&&t&&console.warn(Dn),window.Stripe){n(window.Stripe);return}try{var a=ba();if(a&&t)console.warn(Dn);else if(!a)a=Un(t);else if(a&&Be!==null&&ze!==null){var i;a.removeEventListener("load",Be),a.removeEventListener("error",ze),(i=a.parentNode)===null||i===void 0||i.removeChild(a),a=Un(t)}Be=ka(n,r),ze=Ca(r),a.addEventListener("load",Be),a.addEventListener("error",ze)}catch(s){r(s);return}}),_e.catch(function(n){return _e=null,Promise.reject(n)}))},Pa=function(t,n,r){if(t===null)return null;var a=n[0];if(typeof a!="string")throw new Error("Expected publishable key to be of type string, got type ".concat(He(a)," instead."));var i=a.match(/^pk_test/),s=fa(t.version),p=$n;i&&s!==p&&console.warn("Stripe.js@".concat(s," was loaded on the page, but @stripe/stripe-js@").concat("9.17.0"," expected Stripe.js@").concat(p,". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning"));var d=t.apply(void 0,n);return xa(d,r),d},je,Kn=!1,Yn=function(){return je||(je=Sa(null).catch(function(t){return je=null,Promise.reject(t)}),je)};Promise.resolve().then(function(){return Yn()}).catch(function(e){Kn||console.warn(e)});var zn=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];Kn=!0;var a=Date.now();return Yn().then(function(i){return Pa(i,n,a)})};import{createContext as qa,useContext as _a,useEffect as K,useMemo as rr,useRef as yt,useState as k}from"react";var Na="sf:gclid",wa="sf:fbclid",Ea=2160*60*60*1e3;function Gn(){return typeof window<"u"}function Bn(e){let t=Te.getItem(e);if(!t)return"";try{let{v:n,t:r}=JSON.parse(t);return!n||typeof r!="number"||Date.now()-r>Ea?"":n}catch{return""}}function Hn(e){if(!Gn())return"";let t=e.replace(/([.$?*|{}()[\]\\/+^])/g,"\\$1"),n=document.cookie.match(new RegExp(`(?:^|; )${t}=([^;]*)`));return n?decodeURIComponent(n[1]):""}function Vn(){if(!Gn())return{};let e=Bn(Na),t=Bn(wa),n=Hn("_fbp"),r=Hn("_fbc");!r&&t&&(r=`fb.1.${Date.now()}.${t}`);let a={};return e&&(a.gclid=e),t&&(a.fbclid=t),n&&(a.fbp=n),r&&(a.fbc=r),a}var Jn="sf:meta-purchases",Ra=20;function Zn(){return typeof window>"u"||window.parent!==window}function Ia(...e){try{if(Zn()||typeof window.fbq!="function")return;window.fbq(...e)}catch{}}var Xn=new Set;function Aa(e){if(Xn.has(e))return!1;Xn.add(e);try{let t=JSON.parse(Te.getItem(Jn)??"[]");if(t.includes(e))return!1;Te.setItem(Jn,JSON.stringify([...t,e].slice(-Ra)))}catch{}return!0}function Oa(e){return[...new Set(e.filter(qe).flatMap(t=>t.components.map(n=>n.partNumber)))]}function Qn(e){let t=e.confirmation;Zn()||!Aa(t.orderNumber)||Ia("track","Purchase",{value:Number(t.grandTotal),currency:t.currency,content_type:"product",content_ids:Oa(e.lines)},{eventID:t.orderNumber})}var mt="checkout-afterpay-context",Ge="checkout-gocardless-context",ft="checkout-zip-context",Ve="checkout-klarna-context";function La({evidence:e,parked:t}){return e?{action:"capture",evidence:e,parked:t}:t?{action:"settle",parked:t}:{action:"ignore"}}function Ta(e,t){let n=e.getItem(t);if(e.removeItem(t),!n)return null;try{return JSON.parse(n)}catch{return null}}var er={name:"Afterpay",legParam:"afterpay",legValues:["confirm","cancel"],storageKey:mt,evidenceFrom(e,t){return t==="cancel"||(e.get("status")??"").toUpperCase()==="CANCELLED"?null:e.get("orderToken")},requestFrom:e=>({token:e})},tr={name:"Zip",legParam:"zip",legValues:["return"],storageKey:ft,evidenceFrom(e){let t=(e.get("result")??"").toLowerCase();return t==="cancelled"||t==="declined"?null:e.get("checkoutId")},requestFrom:e=>({checkoutId:e})};async function gt(e,t){let n=new URLSearchParams(t.search),r=n.get(e.legParam);if(!r||!e.legValues.includes(r))return;let a=Ta(t.storage,e.storageKey),i=e.evidenceFrom(n,r);t.scrubQuery();let s=La({evidence:i,parked:a});if(s.action!=="ignore"){if(t.page.clearCart(),s.action==="settle"){t.page.note(`The ${e.name} payment was not completed \u2014 our team will follow up on payment.`),t.page.land(s.parked.confirmation);return}t.page.setConfirming(!0);try{let p=await t.capture(e.requestFrom(s.evidence));p.status==="paid"?t.page.markPaid():t.page.note(`${e.name} declined the payment \u2014 our team will follow up on payment.`),t.page.land(s.parked?.confirmation??p)}catch{s.parked?(t.page.note(`We could not confirm the ${e.name} payment \u2014 our team will follow up on payment.`),t.page.land(s.parked.confirmation)):t.page.fail(`We could not confirm your ${e.name} payment. Please contact us before trying again \u2014 your payment may already have been taken.`)}finally{t.page.setConfirming(!1)}}}function nr(e,t,n){let r=(t??"").trim();if(!r)return"";if(n.length===0)return r;let a=r.toUpperCase(),i=`${e.toUpperCase()}-${a}`,s=n.find(p=>p.code&&p.code.toUpperCase()===a)??n.find(p=>p.code&&p.code.toUpperCase()===i)??n.find(p=>p.name.toUpperCase()===a);return s?s.code||s.name:""}import{jsx as re}from"react/jsx-runtime";function ar(e){let t=e.indexOf(`
|
|
3
|
+
`);return t===-1?[e,""]:[e.slice(0,t),e.slice(t+1)]}function or(e,{canParkContext:t}={canParkContext:!0}){let n=e.paymentMethods,r=[];return n.includes("card")&&r.push({key:"card",title:"Card",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA \xB7 MC \xB7 AMEX"})}),n.includes("paypal")&&e.paypalClientId&&r.push({key:"paypal",title:"PayPal",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAYPAL \xB7 CARDS"})}),n.includes("afterpay")&&r.push({key:"afterpay",title:"Afterpay",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"4 \xD7 INTEREST-FREE"})}),n.includes("square")&&e.squareApplicationId&&e.squareLocationId&&r.push({key:"square",title:"Card (Square)",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA \xB7 MC \xB7 AMEX"})}),n.includes("gocardless")&&t&&r.push({key:"gocardless",title:"Bank Direct Debit",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY BY BANK"})}),n.includes("zip")&&r.push({key:"zip",title:"Zip",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY IN 4"})}),n.includes("klarna")&&t&&r.push({key:"klarna",title:"Klarna",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY LATER"})}),n.includes("bank")&&r.push({key:"bank",title:"Bank transfer",body:null,price:re("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Invoiced"})}),r}var ir="This shop does not take payment online yet. Please contact the shop to order.";function ja(e,t){let n=t instanceof Se?` (${t.message})`:"";return`Your order ${e} is saved, but the payment did not start${n}. Try the payment again \u2014 your order will not be placed twice.`}var sr="Shipping cannot be calculated right now. Please try again.";function Ma({site:e,logo:t,preview:n=!1}){let{items:r,totals:a,coupon:i,refuseCoupon:s,deliveryOptions:p,shippingMethodId:d,setShippingMethodId:l,setQuoteDestination:b,courier:m,requote:h,identify:u,clearCapturedCart:P,replaceItems:S,removeCoupon:w}=Ke(),V=p.find(f=>f.id===d)?.pickupLocation??null,{country:M,countries:E,activeCountry:D,formatMoney:B}=Q(),[_,U]=k(()=>or(e)[0]?.key??null),[de,we]=k(!0);K(()=>{we(Vt(Z))},[]);let[be,ae]=k(!1),[oe,ie]=k(""),[$,y]=k(""),[H,Ee]=k(""),[me,T]=k(""),[Re,W]=k(""),[se,ce]=k(""),[le,R]=k(""),[J,xe]=k(""),[q,fe]=k(()=>M||E[0]?.code||""),[Ce,Fe]=k(""),[Ie,Ct]=k([]),[Qe,et]=k(null),[De,Ae]=k(null),kt=rr(()=>E.find(f=>f.code===q)??D,[E,q,D]),Cr=kt?.postalLabel||"Postal Code",kr=Ie[0]?.divisionType||"State / Province";K(()=>{if(!q){Ct([]),et(q);return}et(null);let f=!1;return j.listCountrySubdivisions(q).then(g=>{f||(Ct(g),et(q),Fe(""))}),()=>{f=!0}},[q]);let St=me.trim()!==""&&se.trim()!==""&&le.trim()!==""&&Qe===q&&(Ie.length===0||Ce!=="")?le.trim():"";K(()=>{b(q?{country:q,subdivision:Ce,postcode:St}:null)},[q,Ce,St,b]),K(()=>()=>b(null),[b]);let Sr=m?.status==="unavailable",Pr=h,[tt,Pt]=k(null),[Nr,Nt]=k([]),[wt,nt]=k("new"),[Et,Rt]=k(!1),[It,wr]=k("Home"),[Er,At]=k(null),[Y]=k(()=>fn()),Ot=yt(null),[Lt,ge]=k(null),[Rr,ye]=k(null),[Tt,Ir]=k(null),[qt,Ar]=k(!1),[_t,Or]=k(!1),[Lr,rt]=k(null),[Tr,Ue]=k(!1),[at,jt]=k(null),[qr,te]=k(null),[_r,jr]=k(!1),[Mr,Mt]=k(!1),[Fr,Dr]=k(!1),[Ur,Ft]=k(!1),Dt=!!(Lt||Tt||qt||_t);K(()=>{Dt&&(S([]),w())},[Dt,S,w]);let Ut=yt(!1);K(()=>{n||Ut.current||!r.some(qe)||(Ut.current=!0,en({lines:r,currency:a.currency,value:a.subtotal-a.discount,coupon:i?.valid?i.code:void 0}))},[r,a,i,n]),K(()=>{u(oe,$.trim()||void 0)},[oe,$,u]);let $t=yt(null),[$e,$r]=k(null);K(()=>{let f=$t.current;if(!$e||!f)return;let g=()=>f.style.setProperty("--sf-checkout-header-h",`${$e.offsetHeight}px`);g();let v=new ResizeObserver(g);return v.observe($e),()=>v.disconnect()},[$e]),K(()=>{let f=v=>({setConfirming:v,land:ge,markPaid:()=>Ue(!0),note:te,fail:ye,clearCart:P}),g={search:window.location.search,storage:Z,scrubQuery:()=>window.history.replaceState(null,"",window.location.pathname)};gt(er,{...g,capture:j.captureAfterpayPayment,page:f(jr)}),gt(tr,{...g,capture:j.captureZipPayment,page:f(Dr)})},[]),K(()=>{let g=new URLSearchParams(window.location.search).get("gocardless");if(g!=="confirm"&&g!=="cancel")return;let v=Z.getItem(Ge);if(Z.removeItem(Ge),window.history.replaceState(null,"",window.location.pathname),!v)return;let I;try{I=JSON.parse(v)}catch{return}if(P(),g==="cancel"){te("The direct debit was not set up \u2014 our team will follow up on payment."),ge(I.confirmation);return}Mt(!0),j.completeGocardlessPayment({idempotencyKey:I.idempotencyKey}).then(X=>{X.status==="paid"?Ue(!0):X.status==="declined"?te("The direct debit was declined \u2014 our team will follow up on payment."):te("Your direct debit is set up \u2014 the payment is collecting and will clear in a few days.")}).catch(()=>{te("We could not confirm the direct debit \u2014 our team will follow up on payment.")}).finally(()=>{ge(I.confirmation),Mt(!1)})},[]),K(()=>{let f=new URLSearchParams(window.location.search),g=f.get("klarna");if(g!=="confirm"&&g!=="cancel")return;let v=Z.getItem(Ve);Z.removeItem(Ve);let I=f.get("authorization_token");if(window.history.replaceState(null,"",window.location.pathname),!v)return;let X;try{X=JSON.parse(v)}catch{return}if(P(),g==="cancel"||!I){te("The Klarna payment was not completed \u2014 our team will follow up on payment."),ge(X.confirmation);return}Ft(!0),j.captureKlarnaPayment({idempotencyKey:X.idempotencyKey,authorizationToken:I}).then(Oe=>{Oe.status==="paid"?Ue(!0):Oe.status==="declined"?te("Klarna declined the payment \u2014 our team will follow up on payment."):te("Your Klarna payment is being reviewed \u2014 we'll confirm the outcome shortly.")}).catch(()=>{te("We could not confirm the Klarna payment \u2014 our team will follow up on payment.")}).finally(()=>{ge(X.confirmation),Ft(!1)})},[]);function Wt(f){let[g,v]=ar(f.address);T(g),W(v),ce(f.city),R(f.zip_code),f.country&&fe(f.country),f.phone&&xe(f.phone),Ae({country:f.country||null,state:f.state??""})}K(()=>{if(De){if((De.country||q)!==q){Ae(null);return}Qe===q&&(Fe(nr(q,De.state,Ie)),Ae(null))}},[De,q,Qe,Ie]),K(()=>{let f=!1;return(async()=>{try{let[g,v,I]=await Promise.all([Pe.me(),Pe.myProfile().catch(()=>null),Pe.myAddresses().catch(()=>[])]);if(f)return;Pt(g);let X=I.filter(Le=>Le.is_active);Nt(X),ie(g.email);let Oe=(v?.contact_name??"").split(/\s+/);y(g.first_name||Oe[0]||""),Ee(g.last_name||Oe.slice(1).join(" "));let Bt=g.phone||v?.phone;Bt&&xe(Bt);let ot=X.find(Le=>Le.id===g.default_delivery_location)??X[0];if(ot)nt(ot.id),Wt(ot);else if(v){let[Le,zr]=ar(v.address??"");T(Le),W(zr),ce(v.city??""),R(v.zip_code??""),v.country&&fe(v.country),Ae({country:v.country||null,state:v.state??""})}}catch{}})(),()=>{f=!0}},[]);function Wr(){Pe.logout(),Pt(null),Nt([]),nt("new"),Rt(!1),ie(""),y(""),Ee(""),T(""),W(""),ce(""),R(""),xe(""),fe(M||E[0]?.code||""),Fe(""),Ae(null)}let ke=rr(()=>or(e,{canParkContext:de}),[e,de]);K(()=>{ke.some(f=>f.key===_)||U(ke[0]?.key??null)},[ke,_]);let Kr=ke.length===0,Kt=Re.trim()?`${me}
|
|
4
|
+
${Re.trim()}`:me;async function Yr(){if(n||be)return;if(at){ae(!0),ye(null),await Yt(),await zt(at);return}if(r.length===0||a.repricing||!_||!ke.some(v=>v.key===_))return;let f=r.filter(qe).flatMap(v=>Qt(v.components,v.qty));if(f.length===0){ye("Pick a size on each wheel's product page before checking out.");return}ae(!0),ye(null);let g;try{let v=tt?j.createOrderAuthed:j.createOrder,I=mn();g=await v({customer:{email:oe,name:`${$} ${H}`.trim(),phone:J.trim()||void 0,address:Kt,city:se,state:Ce||void 0,zipCode:le,country:q},items:f,currency:a.currency,idempotencyKey:Y,shippingMethodId:d??void 0,couponCode:Xt(i),...I==="denied"?{}:Vn(),...I?{adConsent:I}:{}}),tn({confirmation:g,lines:r,adsSendTo:e.googleAdsId&&e.googleAdsConversionLabel?`${e.googleAdsId}/${e.googleAdsConversionLabel}`:null}),Qn({confirmation:g,lines:r}),P(),await Yt()}catch(v){let I=Zt(v);I?(s(I),ye(`${I} Your order has not been placed. Place it again to continue without the code.`)):ye(v instanceof Se?v.message:"Could not place the order. Please try again."),ae(!1);return}await zt(g)}async function Yt(){if(!(!tt||!Et||wt!=="new"||Ot.current===Y))try{await Pe.createAddress({label:It.trim()||"Home",contact_name:`${$} ${H}`.trim(),phone:J.trim(),address:Kt,city:se,zip_code:le,state:Ce,country:q}),Ot.current=Y,At("Address saved to your account.")}catch{At("We couldn't save the address to your account \u2014 you can add it under Account \u2192 Addresses.")}}async function zt(f){jt(null);try{if(_==="card"&&e.paymentMethods.includes("card")){let g=await j.createPaymentIntent({idempotencyKey:Y});rt(f),Ir(g)}else if(_==="paypal"&&e.paymentMethods.includes("paypal"))rt(f),Ar(!0);else if(_==="afterpay"&&e.paymentMethods.includes("afterpay")){let g=window.location.origin,v=await j.createAfterpayCheckout({idempotencyKey:Y,confirmUrl:`${g}/checkout?afterpay=confirm`,cancelUrl:`${g}/checkout?afterpay=cancel`}),I={idempotencyKey:Y,confirmation:f};Z.setItem(mt,JSON.stringify(I)),window.location.assign(v.redirectCheckoutUrl);return}else if(_==="square"&&e.paymentMethods.includes("square"))rt(f),Or(!0);else if(_==="gocardless"&&e.paymentMethods.includes("gocardless")){let g=window.location.origin,v=await j.createGocardlessBillingRequest({idempotencyKey:Y,confirmUrl:`${g}/checkout?gocardless=confirm`,cancelUrl:`${g}/checkout?gocardless=cancel`}),I={idempotencyKey:Y,confirmation:f};Z.setItem(Ge,JSON.stringify(I)),window.location.assign(v.authorisationUrl);return}else if(_==="zip"&&e.paymentMethods.includes("zip")){let g=window.location.origin,v=await j.createZipCheckout({idempotencyKey:Y,redirectUrl:`${g}/checkout?zip=return`}),I={idempotencyKey:Y,confirmation:f};Z.setItem(ft,JSON.stringify(I)),window.location.assign(v.redirectUrl);return}else if(_==="klarna"&&e.paymentMethods.includes("klarna")){let g=window.location.origin,v=await j.createKlarnaCheckout({idempotencyKey:Y,confirmUrl:`${g}/checkout?klarna=confirm`,cancelUrl:`${g}/checkout?klarna=cancel`}),I={idempotencyKey:Y,confirmation:f};Z.setItem(Ve,JSON.stringify(I)),window.location.assign(v.redirectUrl);return}else ge(f)}catch(g){jt(f),ye(ja(f.orderNumber,g)),ae(!1)}}return{site:e,logo:t,items:r,totals:a,coupon:i,deliveryOptions:p,courierUnavailable:Sr,retryCourier:Pr,shippingMethodId:d,setShippingMethodId:l,pickupLocation:V,servedCountries:E,formatMoney:B,payChoice:_,setPayChoice:U,placing:be,email:oe,setEmail:ie,firstName:$,setFirstName:y,lastName:H,setLastName:Ee,address1:me,setAddress1:T,address2:Re,setAddress2:W,city:se,setCity:ce,postcode:le,setPostcode:R,phone:J,setPhone:xe,country:q,setCountry:fe,subdivision:Ce,setSubdivision:Fe,subdivisions:Ie,destination:kt,postcodeLabel:Cr,subdivisionLabel:kr,me:tt,savedAddresses:Nr,selectedAddressId:wt,setSelectedAddressId:nt,saveAddress:Et,setSaveAddress:Rt,saveLabel:It,setSaveLabel:wr,addressSaveNote:Er,idemKey:Y,confirmation:Lt,setConfirmation:ge,orderError:Rr,payment:Tt,paypalStep:qt,squareStep:_t,pendingConf:Lr,paid:Tr,setPaid:Ue,unpaidOrder:at,payNote:qr,afterpayConfirming:_r,gocardlessConfirming:Mr,zipConfirming:Fr,klarnaConfirming:Ur,checkoutRootRef:$t,setCheckoutHeaderEl:$r,fillFromAddress:Wt,checkoutSignOut:Wr,payOptions:ke,noPaymentMethod:Kr,placeOrder:Yr}}var cr=qa(null);function lr({children:e,...t}){let n=Ma(t);return re(cr.Provider,{value:n,children:e})}function ue(){let e=_a(cr);if(!e)throw new Error("useCheckout must be used inside CheckoutStateProvider");return e}import{useId as ht}from"react";import{Fragment as pe,jsx as o,jsxs as C}from"react/jsx-runtime";function pr(){let{email:e,setEmail:t,firstName:n,setFirstName:r,lastName:a,setLastName:i,me:s,checkoutSignOut:p}=ue(),d=ht();return C(Xe,{num:"N\xB0 01",title:"Contact",children:[o(G,{label:"Email",htmlFor:d,hint:s?C(pe,{children:["Signed in \xB7"," ",o("button",{type:"button",onClick:p,className:"underline transition-colors hover:text-accent",children:"Not you? Sign out"})]}):void 0,children:o("input",{id:d,type:"email",value:e,onChange:l=>t(l.target.value),placeholder:"you@example.com",readOnly:s!==null,className:z+(s?" opacity-70":"")})}),C(yr,{children:[o(G,{label:"First name",children:o("input",{type:"text",value:n,onChange:l=>r(l.target.value),className:z})}),o(G,{label:"Last name",children:o("input",{type:"text",value:a,onChange:l=>i(l.target.value),className:z})})]})]})}function dr(){let{pickupLocation:e,servedCountries:t,address1:n,setAddress1:r,address2:a,setAddress2:i,city:s,setCity:p,postcode:d,setPostcode:l,phone:b,setPhone:m,country:h,setCountry:u,subdivision:P,setSubdivision:S,subdivisions:w,destination:V,postcodeLabel:M,subdivisionLabel:E,me:D,savedAddresses:B,selectedAddressId:_,setSelectedAddressId:U,saveAddress:de,setSaveAddress:we,saveLabel:be,setSaveLabel:ae,fillFromAddress:oe}=ue(),ie=ht(),$=ht();return C(Xe,{num:"N\xB0 02",title:e?"Collection":"Shipping address",children:[e?C("div",{className:"grid gap-2 text-[14px] leading-[1.6]",children:[o("span",{className:"font-medium",children:e.name}),[e.address,e.city,e.state,e.zipCode,e.country].filter(Boolean).length>0&&o("span",{className:"opacity-80",children:[e.address,e.city,e.state,e.zipCode,e.country].filter(Boolean).join(", ")}),e.openingHours&&o("span",{className:"opacity-80",children:e.openingHours}),e.instructions&&o("span",{className:"opacity-80",children:e.instructions}),o("span",{className:"mt-1 font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"No delivery address needed"})]}):C(pe,{children:[D!==null&&B.length>0&&C("div",{className:"grid gap-3",children:[B.map(y=>o(Je,{active:_===y.id,onClick:()=>{U(y.id),oe(y)},title:y.label,body:y.formatted_address,price:null},y.id)),o(Je,{active:_==="new",onClick:()=>U("new"),title:"New address",body:null,price:null})]}),o(G,{label:"Address line 1",children:o("input",{type:"text",value:n,onChange:y=>r(y.target.value),className:z})}),o(G,{label:"Address line 2",children:o("input",{type:"text",value:a,onChange:y=>i(y.target.value),placeholder:"Apartment, unit, garage bay\u2026",className:z})}),C(yr,{cols:"three",children:[o(G,{label:"City",children:o("input",{type:"text",value:s,onChange:y=>p(y.target.value),className:z})}),o(G,{label:M,children:o("input",{type:"text",value:d,onChange:y=>l(y.target.value),className:z})}),o(G,{label:"Country",separate:!0,htmlFor:ie,children:o(ct,{id:ie,value:h,onChange:y=>u(y.target.value),className:z+" pr-10",style:ur,children:t.map(y=>o("option",{value:y.code,children:y.name},y.code))})})]}),o(G,{label:E,separate:!0,htmlFor:$,children:w.length>0?C(ct,{id:$,value:P,onChange:y=>S(y.target.value),className:z+" pr-10",style:ur,children:[o("option",{value:"",children:"Select\u2026"}),w.map(y=>o("option",{value:y.code||y.name,children:y.name},y.code||y.name))]}):o("input",{id:$,type:"text",value:P,onChange:y=>S(y.target.value),className:z})})]}),o(G,{label:"Phone",children:o("input",{type:"tel",value:b,onChange:y=>m(y.target.value),className:z})}),!e&&D!==null&&_==="new"&&C(pe,{children:[o(Fa,{checked:de,onChange:we,label:"Save this address to my account"}),de&&o(G,{label:"Address label",children:o("input",{type:"text",value:be,onChange:y=>ae(y.target.value),placeholder:"Home",className:z})})]})]})}function mr(){let{totals:e,coupon:t,deliveryOptions:n,shippingMethodId:r,setShippingMethodId:a,pickupLocation:i,formatMoney:s,city:p,destination:d,courierUnavailable:l,retryCourier:b}=ue();return o(Xe,{num:"N\xB0 03",title:"Shipping",children:C("div",{className:"grid gap-3",children:[n.map(m=>{let h=m.pickupLocation,u=h?[h.address,h.city,h.state,h.zipCode].filter(Boolean).join(", "):null;return o(Je,{active:r===m.id,onClick:()=>a(m.id),title:h?`${m.name} \u2014 ${h.name}`:m.name,body:h?[u,h.openingHours,h.instructions,m.description].filter(Boolean).join(" \xB7 "):m.description||null,price:e.freeShipping||m.amount===0?We:s(m.amount,e.currency),tag:m.tag||void 0},m.id)}),l?C("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:[sr," ",o("button",{type:"button",onClick:b,className:"underline transition-colors hover:text-accent",children:"Try again"})]}):n.length===0&&o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"Shipping is arranged after your order is reviewed."})]})})}function fr(){let{payChoice:e,setPayChoice:t,placing:n,payment:r,payOptions:a,noPaymentMethod:i}=ue();return C(Xe,{num:"N\xB0 04",title:"Payment",children:[i&&o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:ir}),o("div",{className:"grid gap-3",children:a.map(s=>o(Je,{active:e===s.key,onClick:()=>t(s.key),title:s.title,body:s.body,price:s.price,tag:s.tag},s.key))}),e==="card"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll enter card details on the secure payment step after placing the order."}):e==="paypal"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll approve the payment with PayPal on the payment step after placing the order."}):e==="afterpay"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll be taken to Afterpay to approve four interest-free payments, then brought straight back."}):e==="square"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll enter card details on the secure payment step after placing the order."}):e==="gocardless"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll set up a bank direct debit with GoCardless, then be brought straight back. Direct debits clear in a few days."}):e==="zip"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll be taken to Zip to approve four instalments, then brought straight back."}):e==="klarna"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"You\u2019ll be taken to Klarna to choose how to pay, then brought straight back."}):e==="bank"?o("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"Our team emails you the invoice and bank details after review."}):null]})}function gr(){let{site:e,items:t,totals:n,coupon:r,formatMoney:a,payChoice:i,placing:s,email:p,orderError:d,payment:l,noPaymentMethod:b,unpaidOrder:m,placeOrder:h}=ue();return C("aside",{className:"sticky top-[var(--sf-checkout-header-h,88px)] border border-line max-[1100px]:static",style:{background:"linear-gradient(180deg, color-mix(in oklab, var(--site-surface) 70%, var(--bg)) 0%, var(--bg) 100%)"},children:[C("header",{className:"flex items-center justify-between border-b border-accent bg-accent px-6 py-4 font-mono text-[13px] font-bold uppercase tracking-[0.28em] text-bg",children:[o("span",{children:"Your order"}),o(ne,{href:"/wheels",className:"text-bg/80 transition-colors hover:text-bg",children:"Edit \u2197"})]}),o("div",{className:"flex flex-col px-6 py-2",children:t.length===0?C("div",{className:"py-8 text-center font-serif text-[16px] italic leading-[1.5] text-fg-dim",children:["Your cart is empty. ",o(ne,{href:"/wheels",className:"text-accent underline-offset-4 hover:underline",children:"Browse the catalog \u2192"})]}):t.map(u=>o(Da,{slug:u.slug,name:u.name,qty:u.qty,config:u.config,configSummary:Ua(u.config),price:on(u,n.currency)??0,currency:n.currency},u.id))}),o("div",{className:"border-t border-line px-6 pt-5",children:o(dn,{customerEmail:p})}),C("div",{className:"flex flex-col gap-2 border-t border-line mt-5 px-6 pt-5",children:[o(he,{label:"Subtotal",value:a(n.subtotal,n.currency)}),n.discount>0&&r?.valid&&o(he,{label:`Coupon \xB7 ${r.code}`,value:C("span",{className:"font-semibold text-green",children:["\u2212 ",a(n.discount,n.currency)]})}),r?.deferred&&o(he,{label:`Coupon \xB7 ${r.code}`,value:Jt}),r?.valid&&r.effects?.gift&&o(he,{label:`Free gift \xB7 ${r.effects.gift.partNumber}${r.effects.gift.quantity>1?` \xD7${r.effects.gift.quantity}`:""}`,value:o("span",{className:"font-semibold text-green",children:We})}),o(he,{label:"Shipping",value:n.shippingStatus==="free"?o("span",{className:"font-semibold text-green",children:We}):rn(n.shippingStatus)??a(n.shipping,n.currency)}),n.tax&&(n.tax.charged?o(he,{label:n.tax.inclusive?`${n.tax.name} included \xB7 ${n.tax.rate}%`:n.tax.name,value:a(n.tax.amount,n.currency)}):n.tax.name?o(he,{label:n.tax.name,value:nn}):null)]}),C("div",{className:"mt-4 flex items-end justify-between border-y-2 border-accent px-6 py-4",style:{background:"color-mix(in oklab, var(--accent) 10%, var(--bg))"},children:[o("span",{className:"font-display text-[20px] font-bold uppercase tracking-[0.04em] text-fg",children:"Total"}),o("span",{className:"text-right font-display text-[34px] font-bold leading-none tracking-[-0.025em] text-fg",children:n.repricing?"\u2026":a(n.grand,n.currency)})]}),C("div",{className:"flex flex-col gap-3 px-6 pt-5 pb-6",children:[d&&o("p",{className:"border border-red-300 bg-red-50 px-3 py-2 text-[13px] text-red-700",children:d}),n.hasUnpricedLine&&C("p",{className:"border border-amber-300 bg-amber-50 px-3 py-2 text-[13px] text-amber-800",children:["One or more items have no price in ",n.currency,". Remove them, or switch region, to continue."]}),o("button",{type:"button",onClick:h,disabled:s||!m&&(b||t.length===0||n.hasUnpricedLine||n.repricing),className:["group flex items-center justify-between border px-5 py-5 font-mono text-[14px] font-medium uppercase tracking-[0.3em] transition-all",s||!m&&(t.length===0||b||n.hasUnpricedLine||n.repricing)?"cursor-not-allowed border-line bg-surface text-fg-dim":"border-btn bg-btn text-btn-ink hover:border-fg hover:bg-fg"].join(" "),children:s?C(pe,{children:["Building order\u2026 ",o("span",{children:"\xB7"})]}):b?C(pe,{children:["No online payment ",o("span",{children:"\xB7"})]}):m?C(pe,{children:["Try payment again \xB7 ",m.orderNumber,o("span",{className:"transition-transform group-hover:translate-x-1",children:"\u2192"})]}):n.repricing?C(pe,{children:["Updating total\u2026 ",o("span",{children:"\xB7"})]}):C(pe,{children:[i==="bank"?"Place order":"Continue to payment"," \xB7"," ",a(n.grand,n.currency),o("span",{className:"transition-transform group-hover:translate-x-1",children:"\u2192"})]})})]})]})}var ur={backgroundImage:"linear-gradient(45deg, transparent 50%, var(--accent) 50%), linear-gradient(135deg, var(--accent) 50%, transparent 50%)",backgroundPosition:"calc(100% - 18px) 50%, calc(100% - 12px) 50%",backgroundSize:"6px 6px",backgroundRepeat:"no-repeat"};function Xe({num:e,title:t,children:n}){return C("section",{className:"mb-6 border border-line bg-bg",children:[C("header",{className:"flex items-center gap-4 border-b border-line bg-surface px-6 py-4",children:[o("span",{className:"inline-flex items-center justify-center bg-accent px-3 py-1 font-mono text-[11px] font-bold uppercase tracking-[0.24em] text-bg",children:e}),o("h2",{className:"font-display text-[26px] font-medium uppercase leading-none tracking-[-0.02em] text-fg",children:t})]}),o("div",{className:"flex flex-col gap-4 px-6 py-6",children:n})]})}function yr({cols:e="two",children:t}){return o("div",{className:["grid gap-3 max-[640px]:grid-cols-1",e==="two"?"grid-cols-2":"grid-cols-[1.2fr_1fr_1fr]"].join(" "),children:t})}function Je({active:e,onClick:t,title:n,body:r,price:a,tag:i}){return C("button",{type:"button",onClick:t,"aria-pressed":e,className:["relative grid grid-cols-[auto_1fr_auto] items-center gap-5 border bg-bg px-6 py-5 text-left transition-colors",e?"border-accent outline outline-1 outline-accent -outline-offset-1":"border-line hover:border-[color-mix(in_oklab,var(--accent)_50%,var(--site-line))]"].join(" "),style:e?{background:"color-mix(in oklab, var(--accent) 14%, var(--bg))"}:void 0,children:[e&&o("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),o("span",{className:["flex h-[18px] w-[18px] items-center justify-center rounded-full border-2",e?"border-accent":"border-fg-dim"].join(" "),children:e&&o("span",{className:"block h-2.5 w-2.5 rounded-full bg-accent"})}),C("span",{className:"flex min-w-0 flex-col gap-1",children:[C("span",{className:"flex flex-wrap items-baseline gap-3 font-display text-[18px] font-medium tracking-[-0.01em] text-fg",children:[n,i&&o("span",{className:"border px-2 py-0.5 font-mono text-[11px] font-normal uppercase tracking-[0.24em] text-accent",style:{background:"color-mix(in oklab, var(--accent) 14%, transparent)",borderColor:"color-mix(in oklab, var(--accent) 45%, var(--site-line))"},children:i})]}),r&&o("span",{className:"font-mono text-[12px] uppercase tracking-[0.22em] text-fg-dim",children:r})]}),o("span",{className:"whitespace-nowrap font-display text-[18px] font-medium tracking-[-0.01em] text-fg",children:a})]})}function Fa({checked:e,onChange:t,label:n,sub:r}){return C("div",{className:"flex items-start gap-3 border-t border-line py-4 first:border-t-0 first:pt-0",children:[o("button",{type:"button",onClick:()=>t(!e),"aria-pressed":e,"aria-label":n,className:["mt-px flex h-5 w-5 flex-shrink-0 items-center justify-center border transition-colors",e?"border-accent":"border-line"].join(" "),style:e?{background:"color-mix(in oklab, var(--accent) 18%, transparent)"}:void 0,children:e&&o("span",{className:"text-[13px] text-accent",children:"\u2713"})}),C("span",{className:"flex-1 font-display text-[16px] leading-[1.5] text-fg",children:[n,r&&o("small",{className:"mt-1 block font-mono text-[12px] uppercase tracking-[0.18em] text-fg-dim",children:r})]})]})}function Da({slug:e,name:t,qty:n,config:r,configSummary:a,price:i,currency:s}){let{catalog:p}=Ke(),{formatMoney:d}=Q(),l=p.find(S=>S.slug===e),b=l?.spokes??5,m=l?.mesh??!1,h=r.find(S=>S.gold)?.label,u=l?.finishes.find(S=>S.name===h&&S.src)??l?.finishes.find(S=>S.src),P=l?.finishes[0]?.color??pn;return C("div",{className:"grid grid-cols-[60px_1fr_auto] items-center gap-4 border-b border-line py-4 last:border-b-0",children:[C("div",{className:"relative flex aspect-square items-center justify-center overflow-hidden border border-line bg-surface",children:[o("span",{className:"absolute -right-1.5 -top-1.5 z-[2] flex h-[18px] w-[18px] items-center justify-center rounded-full bg-accent font-mono text-[11px] font-bold text-bg",children:n}),u?.src?o(Ht,{src:u.src,alt:`${t.lead}${t.accent} \u2014 ${u.name}`,width:120,height:120,sizes:"60px",className:"relative block h-full w-full object-contain p-2"}):o("div",{className:"block w-[78%]",style:{color:P},children:o(un,{spokes:b,mesh:m,className:"block w-full"})})]}),C("div",{className:"flex min-w-0 flex-col gap-0.5",children:[C("span",{className:"font-display text-[17px] font-bold uppercase leading-none tracking-[-0.005em] text-fg",children:[t.lead,o("em",{className:"font-serif font-normal italic text-accent tracking-[-0.005em] normal-case",children:t.accent})]}),o("span",{className:"font-mono text-[12px] uppercase leading-[1.5] tracking-[0.18em] text-fg-dim",children:a})]}),o("span",{className:"text-right font-display text-[17px] font-bold tracking-[-0.005em] text-fg",children:d(i,s)})]})}function he({label:e,value:t}){return C("div",{className:"flex items-center justify-between font-mono text-[13px] font-medium uppercase tracking-[0.18em] text-fg",children:[o("span",{children:e}),o("strong",{className:"font-display text-[16px] font-medium tracking-[-0.005em] normal-case text-fg",children:t})]})}function Ua(e){return e.map(t=>t.label).join(" \xB7 ")}import{Fragment as ee,jsx as c,jsxs as x}from"react/jsx-runtime";function xt(e){return c(lr,{...e,children:c(Wa,{})})}function $a({order:e,paid:t}){let{formatMoney:n}=Q();if(!e.grandTotal||!e.currency)return null;let r=s=>n(Number(s),e.currency),a=Number(e.freightCharge??0),i=Number(e.discountAmount??0);return x("dl",{className:"grid w-full max-w-sm grid-cols-[1fr_auto] gap-x-6 gap-y-1 border-y border-line py-3 text-left text-sm",children:[(e.shippingMethod||a>0)&&x(ee,{children:[x("dt",{className:"text-fg-dim",children:["Delivery",e.shippingMethod?` \xB7 ${e.shippingMethod}`:""]}),c("dd",{className:"text-right font-mono",children:r(e.freightCharge??"0")})]}),i>0&&x(ee,{children:[x("dt",{className:"text-fg-dim",children:["Discount",e.couponCode?` \xB7 ${e.couponCode}`:""]}),x("dd",{className:"text-right font-mono",children:["\u2212",r(e.discountAmount??"0")]})]}),c("dt",{className:"text-fg",children:t?"Total paid":"Order total"}),c("dd",{className:"text-right font-mono text-fg",children:r(e.grandTotal)})]})}function Wa(){let{site:e,logo:t,items:n,placing:r,email:a,me:i,addressSaveNote:s,idemKey:p,confirmation:d,setConfirmation:l,payment:b,paypalStep:m,squareStep:h,pendingConf:u,paid:P,setPaid:S,payNote:w,afterpayConfirming:V,gocardlessConfirming:M,zipConfirming:E,klarnaConfirming:D,checkoutRootRef:B,setCheckoutHeaderEl:_}=ue();return d?x("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-bg px-6 text-center text-fg",children:[c("h1",{className:"font-display text-3xl",children:P?"Payment received":"Order received"}),x("p",{className:"text-fg-dim",children:[P?x(ee,{children:["Thank you \u2014 your payment for order"," ",c("span",{className:"font-mono text-fg",children:d.orderNumber})," has gone through."," "]}):x(ee,{children:["Thank you \u2014 your order ",c("span",{className:"font-mono text-fg",children:d.orderNumber})," is being reviewed by our team."," "]}),i?x(ee,{children:["Track it under"," ",c(ne,{href:"/account/orders",className:"text-accent underline",children:"your orders"}),"."]}):c(ee,{children:"We\u2019ve emailed you a link to set a password and track it."})]}),c($a,{order:d,paid:P}),w&&c("p",{className:"text-sm text-fg-dim",children:w}),s&&c("p",{className:"text-sm text-fg-dim",children:s}),!i&&x("p",{className:"text-sm text-fg-dim",children:["You can also"," ",c(ne,{href:`/track?order=${encodeURIComponent(d.orderNumber)}`,className:"text-accent underline",children:"track this order"})," ","anytime with just your order number and email \u2014 no password needed."]}),c(ne,{href:"/wheels",className:"mt-2 border-2 border-line px-6 py-3 font-mono text-[12px] uppercase tracking-[0.24em] hover:border-accent",children:"Continue browsing"})]}):V?x("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-bg px-6 text-center text-fg",children:[c("h1",{className:"font-display text-3xl",children:"Confirming your payment\u2026"}),c("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Checking with Afterpay \u2014 one moment."})]}):M?x("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-bg px-6 text-center text-fg",children:[c("h1",{className:"font-display text-3xl",children:"Setting up your direct debit\u2026"}),c("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Confirming with GoCardless \u2014 one moment."})]}):E?x("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-bg px-6 text-center text-fg",children:[c("h1",{className:"font-display text-3xl",children:"Confirming your payment\u2026"}),c("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Checking with Zip \u2014 one moment."})]}):D?x("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-bg px-6 text-center text-fg",children:[c("h1",{className:"font-display text-3xl",children:"Confirming your payment\u2026"}),c("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Checking with Klarna \u2014 one moment."})]}):b?c(Ka,{payment:b,onPaid:()=>{S(!0),l(u)},onSkip:()=>l(u)}):m&&u?c(Ba,{confirmation:u,clientId:e.paypalClientId??"",idemKey:p,onPaid:()=>{S(!0),l(u)},onSkip:()=>l(u)}):h&&u?c(Ga,{confirmation:u,applicationId:e.squareApplicationId??"",locationId:e.squareLocationId??"",environment:e.squareEnvironment??"production",idemKey:p,onPaid:()=>{S(!0),l(u)},onSkip:()=>l(u)}):x("div",{ref:B,className:"bg-bg text-fg",children:[x("header",{ref:_,className:"sticky top-0 z-30 grid grid-cols-[1fr_auto_1fr] items-center gap-8 border-b border-line px-[var(--sf-site-gutter,40px)] py-6 backdrop-blur-md max-[640px]:px-[min(20px,var(--sf-site-gutter,40px))] max-[640px]:py-4",style:{background:"color-mix(in oklab, var(--bg) 92%, transparent)"},children:[x(ne,{href:"/",className:"inline-flex items-center gap-3 font-mono text-[13px] uppercase tracking-[0.26em] text-fg-dim transition-colors hover:text-accent",children:["\u2190",c("span",{className:"max-[640px]:hidden",children:"Back to shop"})]}),c(ne,{href:"/","aria-label":`${e.name} home`,className:"inline-flex items-center justify-center",children:c(ln,{variant:"header",scrolled:!0,src:t?.url??null,reverse:t?.reverse??!1,reversedSrc:t?.reversed??null,inkIsDark:t?.inkIsDark??null,size:t?.size??"medium",sizePx:t?.sizePx??null,siteName:e.name})}),e.cardPayments?x("span",{className:"flex items-center justify-end gap-3 font-mono text-[12px] uppercase tracking-[0.26em] text-fg-dim",children:[c("span",{className:"text-green",children:"\u25CF"}),c("span",{className:"max-[640px]:hidden",children:"Encrypted \xB7"})," Stripe"]}):c("span",{})]}),x("section",{className:"mx-auto flex max-w-[var(--sf-site-width,1600px)] flex-wrap items-center justify-between gap-x-8 gap-y-3 border-b border-line bg-surface px-[var(--sf-site-gutter,40px)] py-4 font-mono text-[13px] font-medium uppercase tracking-[0.24em] text-fg max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))]",children:[c("span",{className:"inline-flex items-center bg-accent px-3 py-1 font-bold text-bg",children:"Checkout"}),c("nav",{"aria-label":"Checkout steps",className:"flex flex-wrap items-center gap-5",children:[{n:"01",label:"Cart",state:"done"},{n:"02",label:"Ship & pay",state:"active"},{n:"03",label:"Confirmed",state:"pending"}].map(U=>x("span",{className:["relative flex items-center gap-2 transition-colors",U.state==="pending"?"text-fg-dim":"text-fg",U.state==="active"?"font-bold after:absolute after:inset-x-0 after:-bottom-1 after:h-[2px] after:bg-accent":""].join(" "),children:[c("span",{className:U.state==="done"?"text-accent font-bold":"",children:U.n}),c("span",{children:U.label})]},U.n))})]}),x("main",{className:"mx-auto grid max-w-[var(--sf-site-width,1600px)] grid-cols-[1fr_420px] items-start gap-16 px-[var(--sf-site-gutter,40px)] pt-10 pb-[100px] max-[1100px]:grid-cols-1 max-[1100px]:gap-10 max-[1100px]:px-[min(24px,var(--sf-site-gutter,40px))] max-[1100px]:pt-8 max-[1100px]:pb-20",children:[x("div",{children:[c(pr,{}),c(dr,{}),c(mr,{}),c(fr,{})]}),c(gr,{})]}),c("footer",{className:"flex flex-wrap items-center justify-between gap-4 border-t border-line px-[var(--sf-site-gutter,40px)] py-6 font-mono text-[12px] uppercase tracking-[0.22em] text-fg-dim max-[640px]:px-[min(20px,var(--sf-site-gutter,40px))]",children:c("span",{children:cn({legalName:e.legalName,foundedYear:e.foundedYear,siteName:e.name})})})]})}function Ka({payment:e,onPaid:t,onSkip:n}){let{formatMoney:r}=Q(),a=hr(()=>zn(e.publishableKey),[e.publishableKey]),i=hr(()=>gn(),[]);return c("div",{className:"flex min-h-screen flex-col items-center justify-center gap-6 bg-bg px-6 py-16 text-fg",children:x("div",{className:"w-full max-w-xl border border-line bg-bg",children:[x("header",{className:"flex items-center justify-between gap-4 border-b border-line bg-surface px-6 py-4",children:[c("span",{className:"inline-flex items-center justify-center bg-accent px-3 py-1 font-mono text-[11px] font-bold uppercase tracking-[0.24em] text-bg",children:e.orderNumber}),c("h1",{className:"font-display text-[26px] font-medium uppercase leading-none tracking-[-0.02em] text-fg",children:"Payment"})]}),x("div",{className:"flex flex-col gap-4 px-6 py-6",children:[x("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:["Your order is placed. Pay"," ",c("span",{className:"text-fg",children:r(Number(e.amount),e.currency)})," ","by card to confirm it now."]}),c(dt,{stripe:a,options:{clientSecret:e.clientSecret,appearance:i},children:c(Ya,{payment:e,onPaid:t,onSkip:n})})]})]})})}function Ya({payment:e,onPaid:t,onSkip:n}){let{formatMoney:r}=Q(),a=Mn(),i=_n(),[s,p]=ve(!1),[d,l]=ve(null);async function b(){if(!a||!i||s)return;p(!0),l(null);let m=await a.confirmPayment({elements:i,redirect:"if_required"});if(m.error){l(m.error.message??"Payment failed. Please try again."),p(!1);return}let h=m.paymentIntent?.status;if(h==="succeeded"||h==="processing"){t();return}l("Payment did not complete. Please try again."),p(!1)}return x("div",{className:"flex flex-col gap-4",children:[c(Fn,{}),d&&c("p",{className:"border border-red-300 bg-red-50 px-3 py-2 text-[13px] text-red-700",children:d}),c("button",{type:"button",onClick:b,disabled:!a||!i||s,className:["group flex items-center justify-between border px-5 py-5 font-mono text-[14px] font-medium uppercase tracking-[0.3em] transition-all",!a||!i||s?"cursor-not-allowed border-line bg-surface text-fg-dim":"border-btn bg-btn text-btn-ink hover:border-fg hover:bg-fg"].join(" "),children:s?x(ee,{children:["Processing\u2026 ",c("span",{children:"\xB7"})]}):x(ee,{children:["Pay ",r(Number(e.amount),e.currency),c("span",{className:"transition-transform group-hover:translate-x-1",children:"\u2192"})]})}),c("button",{type:"button",onClick:n,disabled:s,className:"self-center font-mono text-[11px] uppercase tracking-[0.24em] text-fg-dim underline-offset-4 transition-colors hover:text-accent hover:underline",children:"Pay later \u2014 our team will be in touch"})]})}var vr="paypal-sdk-js",vt=null;function za(e,t){let n=`${e}|${t}`;if(vt?.key===n)return vt.promise;let r=new Promise((a,i)=>{document.getElementById(vr)?.remove();let s=document.createElement("script");s.id=vr;let p=new URLSearchParams({"client-id":e,currency:t,intent:"capture"});s.src=`https://www.paypal.com/sdk/js?${p}`,s.onload=()=>{let d=window.paypal;d?a(d):i(new Error("PayPal SDK loaded without its namespace"))},s.onerror=()=>i(new Error("PayPal SDK failed to load")),document.head.appendChild(s)});return vt={key:n,promise:r},r}function Ba({confirmation:e,clientId:t,idemKey:n,onPaid:r,onSkip:a}){let{formatMoney:i}=Q(),s=Me(null),[p,d]=ve(!1),[l,b]=ve(null),m=Me(r);return m.current=r,xr(()=>{let h=!1,u=null;return za(t,e.currency).then(P=>{if(!(h||!s.current))return u=P.Buttons({style:{layout:"vertical",color:"gold",shape:"rect",label:"paypal"},createOrder:async()=>(await j.createPaypalOrder({idempotencyKey:n})).paypalOrderId,onApprove:async S=>{try{if((await j.capturePaypalOrder({idempotencyKey:n,paypalOrderId:S.orderID})).status==="paid"){m.current();return}b("PayPal did not complete the payment. Please try again.")}catch(w){b(w instanceof Se?w.message:"PayPal payment failed. Please try again.")}},onError:()=>{b("PayPal could not process the payment. Please try again.")}}),u.render(s.current).then(()=>{h||d(!0)})}).catch(()=>{h||b("PayPal could not be loaded. You can pay later \u2014 your order stands either way.")}),()=>{h=!0,u?.close?.()}},[t,e.currency,n]),c("div",{className:"flex min-h-screen flex-col items-center justify-center gap-6 bg-bg px-6 py-16 text-fg",children:x("div",{className:"w-full max-w-xl border border-line bg-bg",children:[x("header",{className:"flex items-center justify-between gap-4 border-b border-line bg-surface px-6 py-4",children:[c("span",{className:"inline-flex items-center justify-center bg-accent px-3 py-1 font-mono text-[11px] font-bold uppercase tracking-[0.24em] text-bg",children:e.orderNumber}),c("h1",{className:"font-display text-[26px] font-medium uppercase leading-none tracking-[-0.02em] text-fg",children:"PayPal"})]}),x("div",{className:"flex flex-col gap-4 px-6 py-6",children:[x("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:["Your order is placed. Pay"," ",c("span",{className:"text-fg",children:i(Number(e.grandTotal),e.currency)})," ","with PayPal to confirm it now."]}),!p&&!l&&c("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"Loading PayPal\u2026"}),c("div",{ref:s}),l&&c("p",{className:"border border-red-300 bg-red-50 px-3 py-2 text-[13px] text-red-700",children:l}),c("button",{type:"button",onClick:a,className:"self-center font-mono text-[11px] uppercase tracking-[0.24em] text-fg-dim underline-offset-4 transition-colors hover:text-accent hover:underline",children:"Pay later \u2014 our team will be in touch"})]})]})})}var br="square-web-sdk",bt=null;function Ha(e){let t=e==="sandbox"?"sandbox":"production";if(bt?.key===t)return bt.promise;let n=new Promise((r,a)=>{document.getElementById(br)?.remove();let i=document.createElement("script");i.id=br,i.src=t==="sandbox"?"https://sandbox.web.squarecdn.com/v1/square.js":"https://web.squarecdn.com/v1/square.js",i.onload=()=>{let s=window.Square;s?r(s):a(new Error("Square SDK loaded without its namespace"))},i.onerror=()=>a(new Error("Square SDK failed to load")),document.head.appendChild(i)});return bt={key:t,promise:n},n}function Ga({confirmation:e,applicationId:t,locationId:n,environment:r,idemKey:a,onPaid:i,onSkip:s}){let{formatMoney:p}=Q(),d=Me(null),l=Me(null),b=Me(null),[m,h]=ve(!1),[u,P]=ve(!1),[S,w]=ve(null);xr(()=>{let M=!1,E=null;return Ha(r).then(async D=>{if(M||!d.current)return;let B=D.payments(t,n);b.current=B,E=await B.card(),await E.attach(d.current),l.current=E,M||h(!0)}).catch(()=>{M||w("Square could not be loaded. You can pay later \u2014 your order stands either way.")}),()=>{M=!0,E?.destroy?.()}},[t,n,r]);async function V(){let M=l.current;if(!(!M||u)){P(!0),w(null);try{let E=await M.tokenize();if(E.status!=="OK"||!E.token){w(E.errors?.[0]?.message??"Please check the card details and try again."),P(!1);return}let D;try{D=(await b.current?.verifyBuyer?.(E.token,{amount:String(e.grandTotal),currencyCode:e.currency,intent:"CHARGE"}))?.token}catch{}if((await j.chargeSquare({idempotencyKey:a,sourceId:E.token,...D?{verificationToken:D}:{}})).status==="paid"){i();return}w("Square did not complete the payment. Please try again.")}catch(E){w(E instanceof Se?E.message:"Square payment failed. Please try again.")}P(!1)}}return c("div",{className:"flex min-h-screen flex-col items-center justify-center gap-6 bg-bg px-6 py-16 text-fg",children:x("div",{className:"w-full max-w-xl border border-line bg-bg",children:[x("header",{className:"flex items-center justify-between gap-4 border-b border-line bg-surface px-6 py-4",children:[c("span",{className:"inline-flex items-center justify-center bg-accent px-3 py-1 font-mono text-[11px] font-bold uppercase tracking-[0.24em] text-bg",children:e.orderNumber}),c("h1",{className:"font-display text-[26px] font-medium uppercase leading-none tracking-[-0.02em] text-fg",children:"Card"})]}),x("div",{className:"flex flex-col gap-4 px-6 py-6",children:[x("p",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:["Your order is placed. Pay"," ",c("span",{className:"text-fg",children:p(Number(e.grandTotal),e.currency)})," ","by card to confirm it now."]}),!m&&!S&&c("p",{className:"font-mono text-[11px] uppercase tracking-[0.2em] text-fg-dim",children:"Loading card form\u2026"}),c("div",{ref:d}),S&&c("p",{className:"border border-red-300 bg-red-50 px-3 py-2 text-[13px] text-red-700",children:S}),c("button",{type:"button",onClick:V,disabled:!m||u,className:["group flex items-center justify-between border px-5 py-5 font-mono text-[14px] font-medium uppercase tracking-[0.3em] transition-all",!m||u?"cursor-not-allowed border-line bg-surface text-fg-dim":"border-btn bg-btn text-btn-ink hover:border-fg hover:bg-fg"].join(" "),children:u?x(ee,{children:["Processing\u2026 ",c("span",{children:"\xB7"})]}):x(ee,{children:["Pay ",p(Number(e.grandTotal),e.currency),c("span",{className:"transition-transform group-hover:translate-x-1",children:"\u2192"})]})}),c("button",{type:"button",onClick:s,disabled:u,className:"self-center font-mono text-[11px] uppercase tracking-[0.24em] text-fg-dim underline-offset-4 transition-colors hover:text-accent hover:underline",children:"Pay later \u2014 our team will be in touch"})]})]})})}import{jsx as Ze}from"react/jsx-runtime";function Va(){let{settings:e,websiteName:t}=Gt(),n=t?{...st,name:t}:st,r=e?{url:e.logoUrl,reversed:e.logoReversed??null,inkIsDark:e.logoInkIsDark??null,reverse:e.reverseLogo,size:e.logoSize,sizePx:e.logoSizePx}:null;return Ze("div",{style:{position:"fixed",inset:0,zIndex:2147482e3,overflowY:"auto",background:"var(--bg)",color:"var(--fg)"},children:Ze(an,{children:Ze(sn,{preview:!0,children:Ze(xt,{site:n,logo:r,preview:!0})})})})}export{Va as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{
|
|
1
|
+
"use client";import{Sk as r}from"./chunk-3IQQNZIM.js";import"./chunk-YAYHH5GY.js";import"./chunk-5NXOTPHK.js";import"./chunk-Y6SLVHK3.js";import{jsx as o}from"react/jsx-runtime";import e from"efficient-easel/screen/components/ScreenStoreProvider";function a(t){return o(e,{...t,parts:r})}export{a as default};
|