efficient-storefront-blocks 0.83.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/chunks/{EditorPreviewCheckout-RI5SBSCE.js → EditorPreviewCheckout-3NVDTH56.js} +1 -1
  3. package/dist/chunks/{SiteEditorProvider-OQXY7YGK.js → SiteEditorProvider-77K7CGYZ.js} +1 -1
  4. package/dist/chunks/chunk-5EQD5D3L.js +340 -0
  5. package/dist/chunks/{chunk-QOM2OL54.js → chunk-DQFD2BJD.js} +1 -1
  6. package/dist/chunks/{chunk-AUYTGAOU.js → chunk-VJLQXB7I.js} +1 -1
  7. package/dist/chunks/chunk-VYOK2XBF.js +1 -0
  8. package/dist/chunks/{fitment-data-64LXUHOU.js → fitment-data-PWXEDMOA.js} +1 -1
  9. package/dist/editor/lib/document/blocks/commerce/ProductHero/fields.js +1 -1
  10. package/dist/editor/lib/document/blocks/commerce/index.d.ts +1 -1
  11. package/dist/editor/lib/document/section-text-regions.js +1 -1
  12. package/dist/editor.css +1 -1
  13. package/dist/index.js +43 -72
  14. package/dist/render/built-with.json +1 -1
  15. package/dist/render/components/FinishSwatches.js +2 -1
  16. package/dist/render/components/LinkedProductHero.d.ts +2 -2
  17. package/dist/render/components/ProductCard.js +1 -1
  18. package/dist/render/components/ProductHeroPanel.d.ts +5 -5
  19. package/dist/render/components/ProductHeroPanel.js +1 -1
  20. package/dist/render/components/ProductRef.js +1 -1
  21. package/dist/render/components/card-pieces/CardPrice.d.ts +9 -1
  22. package/dist/render/components/card-pieces/CardPrice.js +1 -1
  23. package/dist/render/components/card-pieces/ClippedPictures.d.ts +10 -0
  24. package/dist/render/components/card-pieces/ClippedPictures.js +1 -0
  25. package/dist/render/components/card-pieces/HostPart.d.ts +2 -1
  26. package/dist/render/components/card-pieces/HostPart.js +1 -1
  27. package/dist/render/components/card-pieces/ProductCardState.d.ts +12 -0
  28. package/dist/render/components/card-pieces/ProductCardState.js +1 -1
  29. package/dist/render/components/card-pieces/useHeldCardPicture.d.ts +16 -0
  30. package/dist/render/components/card-pieces/useHeldCardPicture.js +1 -0
  31. package/dist/render/components/pdp-dynamic/DynamicProductHero.d.ts +2 -2
  32. package/dist/render/components/product-hero/stage-photo.d.ts +6 -0
  33. package/dist/render/components/product-hero/stage-photo.js +3 -3
  34. package/dist/render/components/useFinishSelection.d.ts +3 -0
  35. package/dist/render/components/useFinishSelection.js +3 -1
  36. package/dist/render/components/useProductCatalog.d.ts +2 -0
  37. package/dist/render/components/wheels-plp/PlpCard.js +1 -1
  38. package/dist/render/lib/api/types.d.ts +15 -2
  39. package/dist/render/lib/content/hero-price-seed.d.ts +4 -0
  40. package/dist/render/lib/content/hero-price-seed.js +1 -0
  41. package/dist/render/lib/document/blocks/commerce/ProductHero/meta.d.ts +4 -0
  42. package/dist/render/lib/document/blocks/commerce/ProductHero/meta.js +1 -1
  43. package/dist/render/lib/document/blocks/commerce/ProductHero/render.js +1 -1
  44. package/dist/render/lib/document/blocks/commerce/ProductPrice/render.js +1 -1
  45. package/dist/render/lib/document/card-templates.js +1 -1
  46. package/dist/render/lib/sections/product-price-text-regions.d.ts +4 -0
  47. package/dist/render/lib/sections/product-price-text-regions.js +1 -0
  48. package/dist/render/lib/wheels/signed-url.d.ts +3 -0
  49. package/dist/render/lib/wheels/signed-url.js +1 -0
  50. package/dist/words.d.ts +0 -3
  51. package/dist/words.js +2 -2
  52. package/package.json +3 -3
  53. package/dist/chunks/chunk-CRXKVHUQ.js +0 -1
  54. package/dist/chunks/chunk-LMOEQBT7.js +0 -340
  55. package/dist/render/lib/sections/product-hero-text-regions.d.ts +0 -3
  56. package/dist/render/lib/sections/product-hero-text-regions.js +0 -1
  57. /package/dist/chunks/{chunk-LMOEQBT7.js.LEGAL.txt → chunk-5EQD5D3L.js.LEGAL.txt} +0 -0
  58. /package/dist/chunks/{chunk-DX6JADLE.js → chunk-F3MB7QCR.js} +0 -0
@@ -1,3 +1,3 @@
1
1
  {
2
- "efficient-web-builder": "51.0.0"
2
+ "efficient-web-builder": "52.0.0"
3
3
  }
@@ -1 +1,2 @@
1
- "use client";import{jsx as t,jsxs as d}from"react/jsx-runtime";function x({finishes:c,availability:f,selectedIdx:a,hoverIdx:s,activeFinish:i,onSelect:u,onHover:r,showLabel:g=!0,className:m}){return d("div",{className:["mt-4",m].filter(Boolean).join(" "),children:[t("div",{className:"flex flex-wrap items-center gap-2",onMouseLeave:()=>r(null),onClick:e=>e.preventDefault(),children:c.map((e,n)=>{if(!f[n])return null;const l=n===a,p=s===n&&s!==a;return t("button",{type:"button",title:e.name,"aria-label":e.name,"aria-pressed":l,onMouseEnter:()=>r(n),onFocus:()=>r(n),onBlur:()=>r(null),onClick:o=>{o.preventDefault(),o.stopPropagation(),u(n)},className:["h-4 w-4 shrink-0 rounded-full transition-all",l?"ring-2 ring-accent ring-offset-2 ring-offset-surface":p?"ring-1 ring-fg ring-offset-2 ring-offset-surface":"ring-1 ring-fg/30 ring-offset-1 ring-offset-surface"].join(" "),style:{background:e.color,border:"1px solid var(--swatch-border)"}},e.name)})}),g&&i&&t("div",{className:"mt-2 truncate font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em] text-fg-dim",children:i.name})]})}export{x as default};
1
+ "use client";import{jsx as t,jsxs as d}from"react/jsx-runtime";function x({finishes:c,availability:u,selectedIdx:a,hoverIdx:s,activeFinish:i,onSelect:f,onHover:r,showLabel:g=!0,className:m}){return d("div",{className:["mt-4",m].filter(Boolean).join(" "),children:[t("div",{className:"flex flex-wrap items-center gap-2",onMouseLeave:()=>r(null),onClick:e=>e.preventDefault(),children:c.map((e,n)=>{if(!u[n])return null;const l=n===a,p=s===n&&s!==a;return t("button",{type:"button",title:e.name,"aria-label":e.name,"aria-pressed":l,onMouseEnter:()=>r(n),onFocus:()=>r(n),onBlur:()=>r(null),onClick:o=>{o.preventDefault(),o.stopPropagation(),f(n)},className:["h-4 w-4 shrink-0 rounded-full transition-all",l?"ring-2 ring-accent ring-offset-2 ring-offset-surface":p?"ring-1 ring-fg ring-offset-2 ring-offset-surface":"ring-1 ring-fg/30 ring-offset-1 ring-offset-surface"].join(" "),style:{background:e.color,border:"1px solid var(--swatch-border)"}},`${e.name}
2
+ ${e.src}`)})}),g&&i&&t("div",{className:"mt-2 truncate font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em] text-fg-dim",children:i.name})]})}export{x as default};
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
- import { type HeroTextRegionProps } from "./ProductHeroPanel.js";
2
+ import { type HeroPriceTemplateProps } from "./ProductHeroPanel.js";
3
3
  import type { HeroPricePlacement } from "../lib/sections/hero-price-placement.js";
4
4
  import type { HeroLayout, HeroTextAlign } from "../lib/sections/hero-arrangement.js";
5
5
  import type { HeroGalleryMode, HeroImageFit } from "../lib/sections/hero-gallery.js";
@@ -11,7 +11,7 @@ export type LinkedHeroRecord = {
11
11
  kind: "tyre";
12
12
  tyre: Tyre;
13
13
  };
14
- interface HeroArrangement extends HeroTextRegionProps {
14
+ interface HeroArrangement extends HeroPriceTemplateProps {
15
15
  heroLayout?: HeroLayout;
16
16
  imageRatio?: number;
17
17
  textAlign?: HeroTextAlign;
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as W,jsxs as R}from"react/jsx-runtime";import U from"next/image";import{useState as X}from"react";import{setSecondSrc as q}from"../lib/wheels/set-mode.js";import{CARD_INDEX_BADGE_CLASS as G,CARD_INDEX_CLASS as M}from"efficient-web-builder/format/lib/sections/product-card-style";import{coverSrcForWheel as O,resolvePaintedSrc as T}from"../lib/wheels/cover-rendering.js";import{wheelCardEyebrow as H,withSetChip as J}from"./ProductCardEyebrow.js";import{withRMark as K}from"efficient-web-builder/render/components/RMark";import Q from"./WheelPlaceholder.js";import{useProductCardChrome as V}from"./ProductCardChrome.js";import Y,{CardBuyDialog as Z}from"./card-pieces/CardBuyButton.js";import ee from"./card-pieces/CardFinishSwatches.js";import re from"./card-pieces/CardPrice.js";import oe from"./card-pieces/CardProductBadge.js";import{useWheelCardState as se,WheelCardStateProvider as ae}from"./card-pieces/ProductCardState.js";import{CardSpecFacts as te}from"./card-pieces/CardSpecs.js";import ie from"./WheelCardFrame.js";import{cardTurnFor as ne}from"efficient-web-builder/format/lib/animation/hover";import{cardSpinOf as de}from"./card-spin.js";function ce({wheel:i,variant:a="compact",defaultFinish:r}){return e(ae,{wheel:i,defaultFinish:r,children:e(le,{variant:a})})}function le({variant:i}){const a=i==="catalog",{wheel:r,sel:s,isSet:n}=se(),{imageBackgroundFill:b,hover:y,coverIndex:B,indexBadge:h,outline:F,showBadge:k,fieldUsage:f,reserveEyebrow:x,showCardPrice:E,showCardFinishes:P,showCardSizes:_,showCardBuy:u,showCardPage:p,imageSizes:$}=V(),d=a&&(u||p),v=O(r,B,s.finish?.name,s.shownSrc),A="h-full w-full",c=de(ne(y,r.spokes)),[w,D]=X(()=>new Set),I=o=>D(t=>t.has(o)?t:new Set(t).add(o)),l=T({overrideSrc:v,hookSrc:s.shownSrc,failed:w}),g=(o,t)=>e(U,{src:o,alt:t,width:1e3,height:1e3,sizes:$,className:`block object-contain ${c.className} ${A}`,style:c.style,draggable:!1,onError:()=>I(o)},o),S=s.finish?`${r.name} — ${s.finish.name}`:r.name,L=l?g(l,S):e(Q,{imageLabel:r.name,spin:c}),m=n?q(r.finishes?.find(o=>o.name===s.finish?.name),l):null,j=m&&!w.has(m)?g(m,`${S} — right`):void 0,C=H({kindLabel:null,brand:null,process:r.process?K(r.process):null},f),z=n&&!a?J(C):C,N=h!=="off"?e("span",{"aria-hidden":!0,className:`${M} ${G}`}):null;return R(W,{children:[e(ie,{variant:i,wide:n&&a,href:`/wheels/${r.slug}`,outline:F,imageBackgroundFill:b,probes:s.probes,reserveEyebrow:x,indexBadge:N,badges:e(oe,{show:k,numbered:h!=="off",axleSets:!0}),image:L,imageSecond:j,eyebrow:z,spec:e(te,{sizes:_,fieldUsage:f}),price:e(re,{show:E,quoteSets:!0}),swatches:e(ee,{show:P}),identityLink:d,wholeCardLink:!0,buy:e(Y,{buy:d&&u,page:d&&p})}),e(Z,{})]})}export{ce as default};
1
+ "use client";import{jsx as e,Fragment as y,jsxs as F}from"react/jsx-runtime";import X from"next/image";import{useState as q}from"react";import{setSecondSrc as G}from"../lib/wheels/set-mode.js";import{CARD_INDEX_BADGE_CLASS as H,CARD_INDEX_CLASS as M}from"efficient-web-builder/format/lib/sections/product-card-style";import{coverSrcForWheel as O,resolvePaintedSrc as J}from"../lib/wheels/cover-rendering.js";import{wheelCardEyebrow as K,withSetChip as Q}from"./ProductCardEyebrow.js";import{withRMark as T}from"efficient-web-builder/render/components/RMark";import V from"./WheelPlaceholder.js";import{useProductCardChrome as Y}from"./ProductCardChrome.js";import Z,{CardBuyDialog as ee}from"./card-pieces/CardBuyButton.js";import re from"./card-pieces/CardFinishSwatches.js";import oe from"./card-pieces/CardPrice.js";import se from"./card-pieces/CardProductBadge.js";import{useHeldCardPicture as ae}from"./card-pieces/useHeldCardPicture.js";import{useWheelCardState as te,WheelCardStateProvider as ie}from"./card-pieces/ProductCardState.js";import{CardSpecFacts as ne}from"./card-pieces/CardSpecs.js";import de from"./WheelCardFrame.js";import{cardSpinOf as ce}from"./card-spin.js";function le({wheel:n,variant:t="compact",defaultFinish:r}){return e(ie,{wheel:n,defaultFinish:r,children:e(me,{variant:t})})}function me({variant:n}){const t=n==="catalog",{wheel:r,sel:o,isSet:d}=te(),{imageBackgroundFill:B,hover:P,coverIndex:E,indexBadge:m,outline:x,showBadge:k,fieldUsage:h,reserveEyebrow:_,showCardPrice:$,showCardFinishes:v,showCardSizes:z,showCardBuy:f,showCardPage:u,imageSizes:p}=Y(),c=t&&(f||u),A=O(r,E,o.finish?.name,o.shownSrc),D="h-full w-full",l=ce(P),[w,I]=q(()=>new Set),g=s=>{o.pictureFailed(s),I(i=>i.has(s)?i:new Set(i).add(s))},S=J({overrideSrc:A,hookSrc:o.shownSrc,failed:w}),C=(s,i)=>e(X,{alt:i,src:s,width:1e3,height:1e3,sizes:p,className:`block object-contain ${l.className} ${D}`,style:l.style,draggable:!1,onError:()=>g(s)},s),L=o.finish?`${r.name} — ${o.finish.name}`:r.name,j=d?G(r.finishes?.find(s=>s.name===o.finish?.name),S):null,a=ae({src:S,second:j,alt:L,sizes:p,failed:w,onFailed:g,near:o.nearScreen,holdEmpty:o.awaitingProbe}),N=F(y,{children:[a.src?C(a.src,a.alt):e(V,{imageLabel:r.name,spin:l}),a.trial]}),W=a.second?C(a.second,`${a.alt} — right`):void 0,b=K({kindLabel:null,brand:null,process:r.process?T(r.process):null},h),R=d&&!t?Q(b):b,U=m!=="off"?e("span",{"aria-hidden":!0,className:`${M} ${H}`}):null;return F(y,{children:[e(de,{variant:n,wide:d&&t,href:`/wheels/${r.slug}`,outline:x,imageBackgroundFill:B,probes:o.probes,reserveEyebrow:_,indexBadge:U,badges:e(se,{show:k,numbered:m!=="off",axleSets:!0}),image:N,imageSecond:W,eyebrow:R,spec:e(ne,{sizes:z,fieldUsage:h}),price:e(oe,{show:$,quoteSets:!0}),swatches:e(re,{show:v}),identityLink:c,wholeCardLink:!0,buy:e(Z,{buy:c&&f,page:c&&u})}),e(ee,{})]})}export{le as default};
@@ -4,12 +4,12 @@ import { type StoreProduct } from "../lib/catalog/store-product.js";
4
4
  import type { HeroPricePlacement } from "../lib/sections/hero-price-placement.js";
5
5
  import { type HeroLayout, type HeroTextAlign } from "../lib/sections/hero-arrangement.js";
6
6
  import { type HeroGalleryMode, type HeroImageFit } from "../lib/sections/hero-gallery.js";
7
- import type { PartStyles } from "efficient-web-builder/render/lib/document/part-styles";
8
- export interface HeroTextRegionProps {
7
+ import type { SlotComponent } from "efficient-easel/blocks";
8
+ export interface HeroPriceTemplateProps {
9
9
  nodeId?: string;
10
- partStyles?: PartStyles;
10
+ priceTemplate?: SlotComponent;
11
11
  }
12
- interface Props extends HeroTextRegionProps {
12
+ interface Props extends HeroPriceTemplateProps {
13
13
  product: StoreProduct;
14
14
  selection: ProductSelection;
15
15
  onLightbox: (src: string, alt: string) => void;
@@ -25,5 +25,5 @@ interface Props extends HeroTextRegionProps {
25
25
  imageFit?: HeroImageFit;
26
26
  trustBullets?: ReactNode;
27
27
  }
28
- export default function ProductHeroPanel({ product, selection, onLightbox, editing, pricePlacement, showVehicleFitment, heroLayout, imageRatio, textAlign, showSpecTable, showPriceQuote, galleryMode, imageFit, trustBullets, nodeId, partStyles, }: Props): import("react").JSX.Element;
28
+ export default function ProductHeroPanel({ product, selection, onLightbox, editing, pricePlacement, showVehicleFitment, heroLayout, imageRatio, textAlign, showSpecTable, showPriceQuote, galleryMode, imageFit, trustBullets, nodeId, priceTemplate, }: Props): import("react").JSX.Element;
29
29
  export {};
@@ -1 +1 @@
1
- "use client";import{Fragment as b,jsx as a,jsxs as n}from"react/jsx-runtime";import Q from"next/link";import{BUY_ROW_CLASS as Ne}from"./buy-row.js";import{useEffect as J,useRef as Se,useState as Te}from"react";import{useCart as we}from"./CartContext.js";import Re from"./QuoteLink.js";import{useSiteTakesOrders as _e}from"./SiteRecordContext.js";import Ee from"./EmailCaptureForm.js";import{useEnglish as I}from"./EnglishVariant.js";import Ae from"./QuantityStepper.js";import{MarkedLabel as $,heroView as Ce}from"./product-hero/hero-view.js";import Oe from"./ProductGallery.js";import{useRootIsDark as Le}from"efficient-shell/theme";import{useWishlist as ze}from"./WishlistContext.js";import{useStockAlertSignup as Ie}from"./useStockAlertSignup.js";import{SPARE_WORDS as $e,productCartLine as je}from"../lib/catalog/purchase.js";import{OPTION_ROW_ATTR as Me}from"../lib/catalog/store-product.js";import{resolvingRowsAnswered as De}from"../lib/catalog/product-options.js";import{STOCK_WORDS as Pe}from"../lib/content/stock-words.js";import{trackViewItem as Fe}from"../lib/google-tag.js";import{DEFAULT_HERO_LAYOUT as He,DEFAULT_HERO_RATIO as Ue,DEFAULT_HERO_TEXT_ALIGN as Be,parseHeroLayout as Ve,parseHeroRatio as Ge,parseHeroTextAlign as We}from"../lib/sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as Ke,DEFAULT_HERO_IMAGE_FIT as qe}from"../lib/sections/hero-gallery.js";import{ADD_TO_BASKET_ATTR as Xe,MAX_SPARES as Ye,UNITS_PER_SET as Qe,formatPrice as Z}from"../lib/commerce.js";import{UNPRICED_LABEL as Je,formatSelectionPrice as Ze,setPriceLabel as et}from"../lib/wheels/price-display.js";import{productIsDually as tt,productIsTwoObjects as at,setSuppressesRow as nt}from"../lib/wheels/set-mode.js";import{CONTENT_CAP_GUTTER as ee}from"../lib/sections/content-cap-gutter.js";import rt from"efficient-web-builder/render/components/TextRegionRun";import{SectionTextParts as lt}from"efficient-web-builder/render/lib/document/editing-bridges";import{TEXT_REGION_ATTR as it}from"efficient-web-builder/format/lib/sections/text-regions";const ot=4e3;function st(e){return e?[e.year,e.make,e.model,e.modification].join("-"):""}const ct=.72;function dt(e){const r=e.trim().split(/\s+/).filter(Boolean);if(r.length===0)return;const s=r.map((l,d)=>l.length+(r.length>1&&d===r.length-1?1:0));return`calc(100cqi / ${(Math.max(...s)*ct).toFixed(2)})`}function mt(e,r){return e?{[it]:r}:{}}function pt({editing:e,nodeId:r,partStyles:s,children:l}){return!e||!r?a(b,{children:l}):a(lt,{nodeId:r,sectionType:"ProductHero",partStyles:s,children:l})}function ft({product:e,selection:r,onLightbox:s,editing:l=!1,pricePlacement:d="top",showVehicleFitment:i=!0,heroLayout:p=He,imageRatio:T=Ue,textAlign:ae=Be,showSpecTable:ne=!0,showPriceQuote:w=!0,galleryMode:re=Ke,imageFit:le=qe,trustBullets:ie,nodeId:oe,partStyles:j}){const se=I(),v=Ve(p),M=We(ae),y=Ge(T),ce=v==="imageRight"?`${100-y}fr ${y}fr`:`${y}fr ${100-y}fr`,{picked:de,pick:D,qty:P,setQty:me,choice:g,setChoice:N,angleIdx:pe,setAngleIdx:fe,showValidation:ue,setShowValidation:R,manualMode:F,vehicle:_,rows:H,facts:be,part:x,outOfStock:U,offer:m,preOrder:E,canAddToCart:S,currency:k,price:u,set:B,msrpLabel:V}=r,c=Ce(e,r,l),A=tt(e),ge=at(e),C=i?c.vehicle:null,he=i?c.vehicleMemory:null,O=!Le({whenUnset:!0}),{addAndOpen:xe,warmCatalog:G}=we(),h=_e();J(()=>{!l&&h&&G(e.kind)},[l,h,e.kind,G]);const W=H.filter(t=>!E||t.values.length>0),K=W.filter(t=>t.role==="resolves"),L=W.filter(t=>t.role==="describes"&&!nt(ge,t.key)),q=L.findIndex(t=>t.chosen===null),X=(!C||!c.vehicleAnswersSpecs||r.fitmentSet)&&De(H,E)?q===-1?L:L.slice(0,q+1):[],ve=[...K,...X],ke=mt(l,"price"),z=a(pt,{editing:l,nodeId:oe,partStyles:j,children:n("div",{className:"flex items-baseline gap-5 border-t border-line pt-[18px]",children:[V&&a("div",{className:"font-mono text-[length:var(--size-label,15px)] text-fg-dim line-through",children:V}),a("div",{className:"font-heading2 text-[length:min(var(--size-headingMedium,36px),var(--sf-heading-max,9999px))] font-bold leading-none tracking-[-0.01em] text-fg",...ke,children:a(rt,{region:"price",partStyles:j,children:A?et(u,k):Ze(u,k)})}),u.priced&&a("div",{className:"font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:c.unitLabel}),u.setTotal!=null&&n("div",{className:"ml-auto border border-accent px-3 py-2 font-mono text-[length:var(--size-label,13px)] font-bold uppercase tracking-[0.18em] text-accent",style:{background:"color-mix(in oklab, var(--accent) 14%, transparent)"},children:[m.quantityLabel,": ",Z(B,k)]})]})}),Y=Se(null);return J(()=>{l||Y.current===e.slug||(Y.current=e.slug,Fe({itemId:x?`${e.slug}|${x.id}`:e.slug,itemName:e.name,variant:c.metaValue,pricePerSet:u.setTotal??u.fromSetTotal??0,currency:k}))},[l,e.slug,e.name,c.metaValue,x,u,k]),n(b,{children:[a("nav",{className:`border-b border-line ${ee} pt-4 pb-4 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.2em] text-fg-dim max-view-tablet:px-[min(20px,var(--sf-site-gutter,40px))]`,style:O?void 0:{background:"var(--section-bg)"},children:e.crumbs.map((t,o)=>n("span",{children:[o>0&&n(b,{children:[a("span",{className:"mx-3 text-accent",children:"/"}),a("wbr",{})]}),t.href?a(Q,{href:t.href,className:"hover:text-fg",children:a($,{text:t.label})}):a("span",{className:"text-fg",children:a($,{text:t.label})})]},`${t.label}-${o}`))}),n("section",{"data-hero-layout":v,"data-hero-align":M,className:[`grid gap-10 ${ee} py-14 max-view-tablet:px-[min(20px,var(--sf-site-gutter,40px))] max-view-tablet:py-8`,v==="stacked"?"grid-cols-1":"[grid-template-columns:var(--hero-cols)] max-view-desktop:[grid-template-columns:minmax(0,1fr)]"].join(" "),style:{...O?{}:{background:"var(--section-bg)"},...v==="stacked"?{}:{"--hero-cols":ce}},children:[a(Oe,{product:e,view:c,angleIdx:pe,onSelect:fe,isLight:O,onLightbox:s,galleryMode:re,imageFit:le,style:v==="imageRight"?{order:2}:void 0}),n("div",{className:["flex flex-col gap-7",M==="center"?"items-center text-center":""].filter(Boolean).join(" "),style:v==="imageRight"?{order:1}:void 0,children:[n("div",{className:"w-full [container-type:inline-size]",children:[n("div",{className:"mb-2.5 flex items-center gap-2.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.2em] text-accent",children:[a("span",{children:a($,{text:e.eyebrow})}),e.badge&&n(b,{children:[a("span",{children:"·"}),a("span",{children:e.badge})]})]}),a("h1",{className:"font-heading2 text-[length:min(min(var(--size-headingMedium,clamp(48px,5.5vw,84px)),var(--hero-name-fit,9999px)),var(--sf-heading-max,9999px))] [font-weight:var(--sf-heading-weight,500)] [text-transform:var(--sf-heading-case,uppercase)] leading-[0.92] tracking-[-0.035em]",style:{"--hero-name-fit":dt(c.heading)},children:(()=>{const t=c.heading.lastIndexOf(" ");if(t===-1)return c.heading;const o=c.heading.slice(0,t),f=c.heading.slice(t+1);return n(b,{children:[o," ",n("em",{className:"font-normal italic text-accent",children:[f,"."]})]})})()})]}),d!=="belowSpecs"&&w&&z,he,K.map(t=>a(te,{row:t,onPick:D},t.key)),E&&c.preOrder?n(b,{children:[d==="belowSpecs"&&w&&z,c.preOrder]}):n(b,{children:[C,X.map(t=>a(te,{row:t,onPick:D},t.key)),ne&&a(ut,{facts:be}),(m.packs.length>0||h&&(m.extra||m.spareCounts.length>0))&&n("div",{className:"border-b border-line pb-[26px]",children:[m.packs.length>0&&n(b,{children:[a("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:"How many"}),a("div",{className:"flex flex-wrap gap-1.5",children:m.packs.map(t=>n("button",{type:"button",onClick:()=>N(o=>({...o,unit:t.value})),"aria-pressed":g.unit===t.value,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",g.unit===t.value?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:g.unit===t.value?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[g.unit===t.value&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:t.label})]},t.value))})]}),h&&m.extra&&n("label",{className:`${m.packs.length>0?"mt-3.5 ":""}flex cursor-pointer items-center gap-3 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.16em] text-fg`,children:[a("input",{type:"checkbox",checked:g.spares>0,onChange:t=>N(o=>({...o,spares:t.target.checked?Ye:0})),className:"h-4 w-4 cursor-pointer accent-[var(--accent)]"}),m.extra.label]}),h&&m.spareCounts.length>0&&n(b,{children:[a("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:$e.howMany}),a("div",{className:"flex flex-col gap-1.5 sm:flex-row sm:flex-wrap",children:m.spareCounts.map(t=>{const o=t.value-Qe,f=g.spares===o;return n("button",{type:"button",onClick:()=>N(ye=>({...ye,spares:o})),"aria-pressed":f,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",f?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:f?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[f&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),n("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:[t.value," · ",t.label]})]},t.value)})})]}),h&&m.spareSide&&n(b,{children:[a("div",{className:"mb-3.5 mt-[26px] font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:m.spareSide.label}),a("div",{className:"flex flex-wrap gap-1.5",children:m.spareSide.options.map(t=>{const o=g.spareSide===t.value;return n("button",{type:"button",onClick:()=>N(f=>({...f,spareSide:t.value})),"aria-pressed":o,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",o?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:o?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[o&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:t.label})]},t.value)})})]})]}),d==="belowSpecs"&&w&&z,n("div",{className:Ne,children:[h&&!(A&&!u.priced)&&a(Ae,{value:P,onChange:me,size:"large"}),!h||A&&!u.priced?a(Re,{className:"flex-1 cursor-pointer bg-btn px-6 py-4 text-center font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-btn-ink transition-colors hover:bg-fg"}):u.priced?U?a("button",{type:"button",disabled:!0,"aria-disabled":!0,className:"flex-1 cursor-not-allowed border-2 border-dashed border-fg-dim/20 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-fg-dim/40",children:Pe.outOfStock}):n("button",{type:"button",[Xe]:"",onClick:()=>{if(!S){R(!0),window.setTimeout(()=>R(!1),ot);return}if(R(!1),l)return;const t=je(e,x,de,{choice:g,qty:P},{fitmentLabel:F?c.specCaption:_.appliedName?`For ${_.appliedName}`:"",fitmentKey:F?`manual|${c.specCaption}`:`vehicle|${st(_.applied?.vehicle)}`});t&&xe(t)},"aria-disabled":!S,className:["flex-1 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] transition-colors",S?"cursor-pointer bg-btn text-btn-ink hover:bg-fg hover:text-bg":"cursor-pointer border-2 border-dashed border-accent/50 text-accent/80 hover:border-accent hover:text-accent"].join(" "),style:S?void 0:{background:"color-mix(in oklab, var(--accent) 6%, transparent)"},children:["Add to Cart",u.setTotal!=null?` · ${Z(B,k)}`:""]}):a("button",{type:"button",disabled:!0,"aria-disabled":!0,className:"flex-1 cursor-not-allowed border-2 border-dashed border-fg-dim/20 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-fg-dim/40",children:Je}),a(bt,{slug:e.slug,name:e.name})]}),U&&x&&a(gt,{partNumbers:x.components.map(t=>t.partNumber),productSlug:e.slug},x.id),ue&&(()=>{const t=ve.filter(f=>f.chosen===null).map(f=>se(f.prompt).replace(/^Select\s+/i,""));if(C&&c.vehicleAnswersSpecs&&!r.fitmentSet&&t.push("vehicle fitment"),t.length===0)return null;const o=t.length===1?t[0]:t.length===2?`${t[0]} and ${t[1]}`:`${t.slice(0,-1).join(", ")}, and ${t.at(-1)}`;return n("p",{role:"alert",className:"-mt-1 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em]",style:{color:"var(--alert)"},children:["Please select ",o," first."]})})()]}),ie]})]})]})}function ut({facts:e}){const r=I();return e.length===0?null:a("div",{className:"border-b border-line pb-[26px]",children:a("dl",{className:"flex flex-col gap-2",children:e.map(s=>n("div",{className:"flex flex-wrap items-baseline gap-x-2 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em]",children:[n("dt",{className:"text-fg-dim",children:[r(s.label)," ·"]}),a("dd",{className:"font-semibold text-fg",children:s.value.label})]},s.key))})})}function te({row:e,onPick:r}){const s=I();if(e.values.length===0&&!e.empty)return null;const l=e.values.find(i=>i.value===e.chosen),d=l&&[l.label,l.note].filter(Boolean).join(" · ");return n("div",{className:"border-b border-line pb-[26px]",[Me]:e.key,children:[n("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:[s(e.label)," · ",a("span",{className:"text-accent",children:d??s(e.prompt)})]}),e.values.length===0?n("p",{className:"font-mono text-[length:var(--size-body,12px)] leading-relaxed tracking-[0.1em] text-fg-dim",children:[e.empty.text," ",a(Q,{href:e.empty.href,className:"text-accent hover:underline",children:e.empty.linkText})]}):e.display==="swatch"?a("div",{className:"flex flex-wrap gap-2",children:e.values.map(i=>{const p=i.value===e.chosen;return n("button",{type:"button",onClick:()=>r(e.key,i.value),"aria-pressed":p,className:["relative flex max-w-full items-center gap-3 border-2 px-3 py-3 text-left transition-colors",p?"border-accent outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 hover:border-accent"].join(" "),style:p?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[p&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block h-5 w-5 shrink-0 rounded-full border border-fg-dim",style:{background:i.swatch}}),a("span",{className:"block min-w-0 break-words font-mono text-[length:var(--size-label,12px)] font-bold uppercase tracking-[0.18em] text-fg",children:i.label})]},i.value)})}):a("div",{className:"flex flex-wrap gap-1.5",children:e.values.map(i=>{const p=i.value===e.chosen;return n("button",{type:"button",onClick:()=>r(e.key,i.value),"aria-pressed":p,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",p?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:p?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[p&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:i.label}),i.note&&a("span",{className:"mt-1 block text-[length:var(--size-label,11px)] tracking-[0.12em] text-fg-dim",children:i.note})]},i.value)})})]})}function bt({slug:e,name:r}){const{has:s,toggle:l}=ze(),d=s(e);return a("button",{type:"button",title:d?"Saved":"Save","aria-label":d?`Remove ${r} from wishlist`:`Save ${r} to wishlist`,"aria-pressed":d,onClick:()=>l(e),className:["h-12 w-12 cursor-pointer border-2 bg-transparent transition-colors",d?"border-accent text-accent":"border-fg-dim/50 text-fg hover:border-accent hover:text-accent"].join(" "),children:d?"♥":"♡"})}function gt({partNumbers:e,productSlug:r}){const[s,l]=Te(""),{status:d,submit:i,reset:p}=Ie();function T(){i({partNumbers:e,email:s,productSlug:r})}return d==="sent"?a("p",{className:"-mt-1 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em] text-accent",children:"We'll email you when it's back."}):a(Ee,{className:"-mt-1",email:s,onEmailChange:l,status:d,onResetVerdict:p,onSubmit:T,inputAriaLabel:"Email for the back-in-stock alert",submitLabel:"Notify me when back",buttonClassName:"cursor-pointer whitespace-nowrap border-2 border-btn px-4 font-mono text-[length:var(--size-label,11px)] font-bold uppercase tracking-[0.22em] text-btn transition-colors hover:bg-btn hover:text-btn-ink disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-btn",errorMessage:"Couldn't save that — please try again."})}export{ft as default};
1
+ "use client";import{jsx as a,Fragment as b,jsxs as n}from"react/jsx-runtime";import Q from"next/link";import{BUY_ROW_CLASS as ye}from"./buy-row.js";import{useEffect as X,useRef as Ne,useState as Se}from"react";import{useCart as we}from"./CartContext.js";import Te from"./QuoteLink.js";import{useSiteTakesOrders as _e}from"./SiteRecordContext.js";import Re from"./EmailCaptureForm.js";import{useEnglish as I}from"./EnglishVariant.js";import Ee from"./QuantityStepper.js";import{MarkedLabel as $,heroView as Ce}from"./product-hero/hero-view.js";import Ae from"./ProductGallery.js";import{useRootIsDark as Le}from"efficient-shell/theme";import{useWishlist as Oe}from"./WishlistContext.js";import{useStockAlertSignup as ze}from"./useStockAlertSignup.js";import{SPARE_WORDS as Ie,productCartLine as $e}from"../lib/catalog/purchase.js";import{OPTION_ROW_ATTR as je}from"../lib/catalog/store-product.js";import{resolvingRowsAnswered as Me}from"../lib/catalog/product-options.js";import{STOCK_WORDS as Pe}from"../lib/content/stock-words.js";import{trackViewItem as De}from"../lib/google-tag.js";import{DEFAULT_HERO_LAYOUT as Fe,DEFAULT_HERO_RATIO as He,DEFAULT_HERO_TEXT_ALIGN as Be,parseHeroLayout as Ue,parseHeroRatio as Ve,parseHeroTextAlign as We}from"../lib/sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as Ge,DEFAULT_HERO_IMAGE_FIT as Ke}from"../lib/sections/hero-gallery.js";import{ADD_TO_BASKET_ATTR as qe,MAX_SPARES as Ye,UNITS_PER_SET as Qe,formatPrice as J}from"../lib/commerce.js";import{UNPRICED_LABEL as Xe,formatSelectionPrice as Je,setPriceLabel as Ze}from"../lib/wheels/price-display.js";import{productIsDually as et,productIsTwoObjects as tt,setSuppressesRow as at}from"../lib/wheels/set-mode.js";import{CONTENT_CAP_GUTTER as Z}from"../lib/sections/content-cap-gutter.js";import{CardTemplateRows as nt}from"efficient-web-builder/render/components/CardRowContext";import rt from"./card-pieces/CardPrice.js";import{HeroPriceStateProvider as lt}from"./card-pieces/ProductCardState.js";const ot=4e3;function it(t){return t?[t.year,t.make,t.model,t.modification].join("-"):""}const st=[{}],ct=.72;function dt(t){const r=t.trim().split(/\s+/).filter(Boolean);if(r.length===0)return;const d=r.map((s,c)=>s.length+(r.length>1&&c===r.length-1?1:0));return`calc(100cqi / ${(Math.max(...d)*ct).toFixed(2)})`}function mt({product:t,selection:r,onLightbox:d,editing:s=!1,pricePlacement:c="top",showVehicleFitment:l=!0,heroLayout:p=Fe,imageRatio:w=He,textAlign:te=Be,showSpecTable:ae=!0,showPriceQuote:T=!0,galleryMode:ne=Ge,imageFit:re=Ke,trustBullets:le,nodeId:oe,priceTemplate:j}){const ie=I(),v=Ue(p),M=We(te),y=Ve(w),se=v==="imageRight"?`${100-y}fr ${y}fr`:`${y}fr ${100-y}fr`,{picked:ce,pick:P,qty:D,setQty:de,choice:h,setChoice:N,angleIdx:me,setAngleIdx:pe,showValidation:ue,setShowValidation:_,manualMode:F,vehicle:R,rows:H,facts:fe,part:x,outOfStock:B,offer:m,preOrder:E,canAddToCart:S,currency:k,price:f,set:U,msrpLabel:be}=r,i=Ce(t,r,s),C=et(t),he=tt(t),A=l?i.vehicle:null,ge=l?i.vehicleMemory:null,L=!Le({whenUnset:!0}),{addAndOpen:xe,warmCatalog:V}=we(),g=_e();X(()=>{!s&&g&&V(t.kind)},[s,g,t.kind,V]);const W=H.filter(e=>!E||e.values.length>0),G=W.filter(e=>e.role==="resolves"),O=W.filter(e=>e.role==="describes"&&!at(he,e.key)),K=O.findIndex(e=>e.chosen===null),q=(!A||!i.vehicleAnswersSpecs||r.fitmentSet)&&Me(H,E)?K===-1?O:O.slice(0,K+1):[],ve=[...G,...q],z=a(lt,{value:{kind:"hero",msrpLabel:be||null,amount:C?Ze(f,k):Je(f,k),unitLabel:f.priced?i.unitLabel:null,packBadge:f.setTotal!=null?`${m.quantityLabel}: ${J(U,k)}`:null},children:j?a(nt,{ownerId:oe??"",ownerType:"ProductHero",Template:j,rows:st,fallback:null,children:e=>e}):a(rt,{})}),Y=Ne(null);return X(()=>{s||Y.current===t.slug||(Y.current=t.slug,De({itemId:x?`${t.slug}|${x.id}`:t.slug,itemName:t.name,variant:i.metaValue,pricePerSet:f.setTotal??f.fromSetTotal??0,currency:k}))},[s,t.slug,t.name,i.metaValue,x,f,k]),n(b,{children:[a("nav",{className:`border-b border-line ${Z} pt-4 pb-4 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.2em] text-fg-dim max-view-tablet:px-[min(20px,var(--sf-site-gutter,40px))]`,style:L?void 0:{background:"var(--section-bg)"},children:t.crumbs.map((e,o)=>n("span",{children:[o>0&&n(b,{children:[a("span",{className:"mx-3 text-accent",children:"/"}),a("wbr",{})]}),e.href?a(Q,{href:e.href,className:"hover:text-fg",children:a($,{text:e.label})}):a("span",{className:"text-fg",children:a($,{text:e.label})})]},`${e.label}-${o}`))}),n("section",{"data-hero-layout":v,"data-hero-align":M,className:[`grid gap-10 ${Z} py-14 max-view-tablet:px-[min(20px,var(--sf-site-gutter,40px))] max-view-tablet:py-8`,v==="stacked"?"grid-cols-1":"[grid-template-columns:var(--hero-cols)] max-view-desktop:[grid-template-columns:minmax(0,1fr)]"].join(" "),style:{...L?{}:{background:"var(--section-bg)"},...v==="stacked"?{}:{"--hero-cols":se}},children:[a(Ae,{product:t,view:i,angleIdx:me,onSelect:pe,isLight:L,onLightbox:d,galleryMode:ne,imageFit:re,style:v==="imageRight"?{order:2}:void 0}),n("div",{className:["flex flex-col gap-7",M==="center"?"items-center text-center":""].filter(Boolean).join(" "),style:v==="imageRight"?{order:1}:void 0,children:[n("div",{className:"w-full [container-type:inline-size]",children:[n("div",{className:"mb-2.5 flex items-center gap-2.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.2em] text-accent",children:[a("span",{children:a($,{text:t.eyebrow})}),t.badge&&n(b,{children:[a("span",{children:"·"}),a("span",{children:t.badge})]})]}),a("h1",{className:"font-heading2 text-[length:min(min(var(--size-headingMedium,clamp(48px,5.5vw,84px)),var(--hero-name-fit,9999px)),var(--sf-heading-max,9999px))] [font-weight:var(--sf-heading-weight,500)] [text-transform:var(--sf-heading-case,uppercase)] leading-[0.92] tracking-[-0.035em]",style:{"--hero-name-fit":dt(i.heading)},children:(()=>{const e=i.heading.lastIndexOf(" ");if(e===-1)return i.heading;const o=i.heading.slice(0,e),u=i.heading.slice(e+1);return n(b,{children:[o," ",n("em",{className:"font-normal italic text-accent",children:[u,"."]})]})})()})]}),c!=="belowSpecs"&&T&&z,ge,G.map(e=>a(ee,{row:e,onPick:P},e.key)),E&&i.preOrder?n(b,{children:[c==="belowSpecs"&&T&&z,i.preOrder]}):n(b,{children:[A,q.map(e=>a(ee,{row:e,onPick:P},e.key)),ae&&a(pt,{facts:fe}),(m.packs.length>0||g&&(m.extra||m.spareCounts.length>0))&&n("div",{className:"border-b border-line pb-[26px]",children:[m.packs.length>0&&n(b,{children:[a("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:"How many"}),a("div",{className:"flex flex-wrap gap-1.5",children:m.packs.map(e=>n("button",{type:"button",onClick:()=>N(o=>({...o,unit:e.value})),"aria-pressed":h.unit===e.value,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",h.unit===e.value?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:h.unit===e.value?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[h.unit===e.value&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:e.label})]},e.value))})]}),g&&m.extra&&n("label",{className:`${m.packs.length>0?"mt-3.5 ":""}flex cursor-pointer items-center gap-3 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.16em] text-fg`,children:[a("input",{type:"checkbox",checked:h.spares>0,onChange:e=>N(o=>({...o,spares:e.target.checked?Ye:0})),className:"h-4 w-4 cursor-pointer accent-[var(--accent)]"}),m.extra.label]}),g&&m.spareCounts.length>0&&n(b,{children:[a("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:Ie.howMany}),a("div",{className:"flex flex-col gap-1.5 sm:flex-row sm:flex-wrap",children:m.spareCounts.map(e=>{const o=e.value-Qe,u=h.spares===o;return n("button",{type:"button",onClick:()=>N(ke=>({...ke,spares:o})),"aria-pressed":u,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",u?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:u?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[u&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),n("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:[e.value," · ",e.label]})]},e.value)})})]}),g&&m.spareSide&&n(b,{children:[a("div",{className:"mb-3.5 mt-[26px] font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:m.spareSide.label}),a("div",{className:"flex flex-wrap gap-1.5",children:m.spareSide.options.map(e=>{const o=h.spareSide===e.value;return n("button",{type:"button",onClick:()=>N(u=>({...u,spareSide:e.value})),"aria-pressed":o,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",o?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:o?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[o&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:e.label})]},e.value)})})]})]}),c==="belowSpecs"&&T&&z,n("div",{className:ye,children:[g&&!(C&&!f.priced)&&a(Ee,{value:D,onChange:de,size:"large"}),!g||C&&!f.priced?a(Te,{className:"flex-1 cursor-pointer bg-btn px-6 py-4 text-center font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-btn-ink transition-colors hover:bg-fg"}):f.priced?B?a("button",{type:"button",disabled:!0,"aria-disabled":!0,className:"flex-1 cursor-not-allowed border-2 border-dashed border-fg-dim/20 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-fg-dim/40",children:Pe.outOfStock}):n("button",{type:"button",[qe]:"",onClick:()=>{if(!S){_(!0),window.setTimeout(()=>_(!1),ot);return}if(_(!1),s)return;const e=$e(t,x,ce,{choice:h,qty:D},{fitmentLabel:F?i.specCaption:R.appliedName?`For ${R.appliedName}`:"",fitmentKey:F?`manual|${i.specCaption}`:`vehicle|${it(R.applied?.vehicle)}`});e&&xe(e)},"aria-disabled":!S,className:["flex-1 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] transition-colors",S?"cursor-pointer bg-btn text-btn-ink hover:bg-fg hover:text-bg":"cursor-pointer border-2 border-dashed border-accent/50 text-accent/80 hover:border-accent hover:text-accent"].join(" "),style:S?void 0:{background:"color-mix(in oklab, var(--accent) 6%, transparent)"},children:["Add to Cart",f.setTotal!=null?` · ${J(U,k)}`:""]}):a("button",{type:"button",disabled:!0,"aria-disabled":!0,className:"flex-1 cursor-not-allowed border-2 border-dashed border-fg-dim/20 px-6 py-4 font-mono text-[length:var(--size-label,14px)] font-bold uppercase tracking-[0.32em] text-fg-dim/40",children:Xe}),a(ut,{slug:t.slug,name:t.name})]}),B&&x&&a(ft,{partNumbers:x.components.map(e=>e.partNumber),productSlug:t.slug},x.id),ue&&(()=>{const e=ve.filter(u=>u.chosen===null).map(u=>ie(u.prompt).replace(/^Select\s+/i,""));if(A&&i.vehicleAnswersSpecs&&!r.fitmentSet&&e.push("vehicle fitment"),e.length===0)return null;const o=e.length===1?e[0]:e.length===2?`${e[0]} and ${e[1]}`:`${e.slice(0,-1).join(", ")}, and ${e.at(-1)}`;return n("p",{role:"alert",className:"-mt-1 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em]",style:{color:"var(--alert)"},children:["Please select ",o," first."]})})()]}),le]})]})]})}function pt({facts:t}){const r=I();return t.length===0?null:a("div",{className:"border-b border-line pb-[26px]",children:a("dl",{className:"flex flex-col gap-2",children:t.map(d=>n("div",{className:"flex flex-wrap items-baseline gap-x-2 font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.22em]",children:[n("dt",{className:"text-fg-dim",children:[r(d.label)," ·"]}),a("dd",{className:"font-semibold text-fg",children:d.value.label})]},d.key))})})}function ee({row:t,onPick:r}){const d=I();if(t.values.length===0&&!t.empty)return null;const s=t.values.find(l=>l.value===t.chosen),c=s&&[s.label,s.note].filter(Boolean).join(" · ");return n("div",{className:"border-b border-line pb-[26px]",[je]:t.key,children:[n("div",{className:"mb-3.5 font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:[d(t.label)," · ",a("span",{className:"text-accent",children:c??d(t.prompt)})]}),t.values.length===0?n("p",{className:"font-mono text-[length:var(--size-body,12px)] leading-relaxed tracking-[0.1em] text-fg-dim",children:[t.empty.text," ",a(Q,{href:t.empty.href,className:"text-accent hover:underline",children:t.empty.linkText})]}):t.display==="swatch"?a("div",{className:"flex flex-wrap gap-2",children:t.values.map(l=>{const p=l.value===t.chosen;return n("button",{type:"button",onClick:()=>r(t.key,l.value),"aria-pressed":p,className:["relative flex max-w-full items-center gap-3 border-2 px-3 py-3 text-left transition-colors",p?"border-accent outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 hover:border-accent"].join(" "),style:p?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[p&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block h-5 w-5 shrink-0 rounded-full border border-fg-dim",style:{background:l.swatch}}),a("span",{className:"block min-w-0 break-words font-mono text-[length:var(--size-label,12px)] font-bold uppercase tracking-[0.18em] text-fg",children:l.label})]},l.value)})}):a("div",{className:"flex flex-wrap gap-1.5",children:t.values.map(l=>{const p=l.value===t.chosen;return n("button",{type:"button",onClick:()=>r(t.key,l.value),"aria-pressed":p,className:["relative cursor-pointer border-2 px-4 py-3 text-left font-mono uppercase transition-colors",p?"border-accent text-fg outline outline-1 outline-accent -outline-offset-1":"border-fg-dim/50 text-fg hover:border-accent"].join(" "),style:p?{background:"color-mix(in oklab, var(--accent) 14%, transparent)"}:void 0,children:[p&&a("span",{"aria-hidden":!0,className:"absolute inset-y-0 left-0 w-[3px] bg-accent"}),a("span",{className:"block text-[length:var(--size-label,14px)] tracking-[0.18em]",children:l.label}),l.note&&a("span",{className:"mt-1 block text-[length:var(--size-label,11px)] tracking-[0.12em] text-fg-dim",children:l.note})]},l.value)})})]})}function ut({slug:t,name:r}){const{has:d,toggle:s}=Oe(),c=d(t);return a("button",{type:"button",title:c?"Saved":"Save","aria-label":c?`Remove ${r} from wishlist`:`Save ${r} to wishlist`,"aria-pressed":c,onClick:()=>s(t),className:["h-12 w-12 cursor-pointer border-2 bg-transparent transition-colors",c?"border-accent text-accent":"border-fg-dim/50 text-fg hover:border-accent hover:text-accent"].join(" "),children:c?"♥":"♡"})}function ft({partNumbers:t,productSlug:r}){const[d,s]=Se(""),{status:c,submit:l,reset:p}=ze();function w(){l({partNumbers:t,email:d,productSlug:r})}return c==="sent"?a("p",{className:"-mt-1 font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.18em] text-accent",children:"We'll email you when it's back."}):a(Re,{className:"-mt-1",email:d,onEmailChange:s,status:c,onResetVerdict:p,onSubmit:w,inputAriaLabel:"Email for the back-in-stock alert",submitLabel:"Notify me when back",buttonClassName:"cursor-pointer whitespace-nowrap border-2 border-btn px-4 font-mono text-[length:var(--size-label,11px)] font-bold uppercase tracking-[0.22em] text-btn transition-colors hover:bg-btn hover:text-btn-ink disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-btn",errorMessage:"Couldn't save that — please try again."})}export{mt as default};
@@ -1 +1 @@
1
- "use client";import{jsx as l}from"react/jsx-runtime";import{createContext as c,useContext as d,useEffect as g,useState as f}from"react";import m from"./ProductCard.js";import{loadProductCatalog as h}from"./useProductCatalog.js";import{say as u}from"efficient-web-builder/format/lib/editor-words";const s=c({wheels:[],loading:!1,live:!1});function p(e,t){return e.find(r=>r.designCode===t)??e.find(r=>r.slug===t)}function S({wheels:e,children:t}){return l(s.Provider,{value:{wheels:e??[],loading:!1,live:!0},children:t})}function b({children:e}){const[t,r]=f([]),[i,a]=f(!0);return g(()=>{let n=!1;return h().then(o=>{n||(r(o),a(!1))}).catch(()=>{n||a(!1)}),()=>{n=!0}},[]),l(s.Provider,{value:{wheels:t,loading:i,live:!1},children:e})}function v({code:e,finish:t,wheel:r}){const{wheels:i,loading:a,live:n}=d(s),o=r??(e?p(i,e):void 0);return o?l(m,{wheel:o,variant:"catalog",defaultFinish:t},t??""):n?null:l("div",{className:"sf-card flex aspect-square w-full items-center justify-center bg-surface-2 p-4 text-center",children:l("span",{className:"font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.2em] text-fg-dim",children:a?u("Loading…"):e||u("Set a design code")})})}export{b as ProductCatalogProvider,S as SectionWheelsProvider,v as default,p as wheelForCode};
1
+ "use client";import{jsx as a}from"react/jsx-runtime";import{createContext as c,useContext as d,useEffect as g,useState as u}from"react";import m from"./ProductCard.js";import{loadProductCatalog as h}from"./useProductCatalog.js";import{say as f}from"efficient-web-builder/format/lib/editor-words";const i=c({wheels:[],loading:!1,live:!1});function p(e,t){return e.find(r=>r.designCode===t)??e.find(r=>r.slug===t)}function S({wheels:e,children:t}){return a(i.Provider,{value:{wheels:e??[],loading:!1,live:!0},children:t})}function b({children:e}){const[t,r]=u([]),[s,o]=u(!0);return g(()=>{let n=!1;return h().then(l=>{n||(r(l),o(!1))}).catch(()=>{n||o(!1)}),()=>{n=!0}},[]),a(i.Provider,{value:{wheels:t,loading:s,live:!1},children:e})}function v({code:e,finish:t,wheel:r}){const{wheels:s,loading:o,live:n}=d(i),l=r??(e?p(s,e):void 0);return l?a(m,{wheel:l,variant:"catalog",defaultFinish:t},`${l.slug}:${t??""}`):n?null:a("div",{className:"sf-card flex aspect-square w-full items-center justify-center bg-surface-2 p-4 text-center",children:a("span",{className:"font-mono text-[length:var(--size-label,12px)] uppercase tracking-[0.2em] text-fg-dim",children:o?f("Loading…"):e||f("Set a design code")})})}export{b as ProductCatalogProvider,S as SectionWheelsProvider,v as default,p as wheelForCode};
@@ -1,7 +1,15 @@
1
+ import type { PartStyles } from "efficient-web-builder/render/lib/document/part-styles";
1
2
  export interface CardPriceSettings {
2
3
  show?: boolean;
3
4
  quoteSets?: boolean;
4
5
  setTotal?: boolean;
5
6
  wasFollowsSize?: boolean;
6
7
  }
7
- export default function CardPrice({ show, ...settings }: CardPriceSettings): import("react").JSX.Element;
8
+ export interface CardPriceRegion {
9
+ nodeId?: string;
10
+ partStyles?: PartStyles;
11
+ editing: boolean;
12
+ }
13
+ export default function CardPrice({ show, region, ...settings }: CardPriceSettings & {
14
+ region?: CardPriceRegion;
15
+ }): import("react").JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as c,jsxs as m,Fragment as _}from"react/jsx-runtime";import{formatPrice as w}from"../../lib/commerce.js";import{setLabel as x}from"../../lib/wheels/variants.js";import{wheelCardPriceLine as u}from"../../lib/wheels/set-mode.js";import{EACH_UNIT as T,formatSelectionPrice as E,formatSelectionWasPrice as C,formatWheelPrice as d,formatWheelWasPrice as W,FROM_PREFIX as f,priceIn as g,resolveWheelPrice as p,SET_QUOTE_LABEL as y}from"../../lib/wheels/price-display.js";import{CARD_TEXT_SIZE as h,CardRow as P}from"./card-row.js";import{useProductCardState as F}from"./ProductCardState.js";function L(r,n){if(r.kind==="tyre"){const s=p(g(r.tyre.prices,r.currency),null);return{was:null,amount:d(s,r.currency,f),note:s.priced?T:null}}const{wheel:l,currency:e,price:t,sel:o,isSet:S}=r,i=p(l.prices[e],l.msrpPrices?.[e]),a=n.setTotal&&t.priced&&t.setTotal!=null&&o.selectedVariant?`${x(o.selectedVariant)} · ${w(t.setTotal,e)}`:null;return S&&n.quoteSets?{was:null,amount:i.priced?u(d(i,e,f),!0):y,note:a}:{was:n.wasFollowsSize?C(t,e):W(i,e),amount:u(E(t,e),t.priced),note:a}}function j({show:r=!0,...n}){const l=F(),{was:e,amount:t,note:o}=L(l,n);return m(_,{children:[c(P,{children:r?m("div",{className:`mt-2 font-mono ${h.labelLarge}`,children:[e&&c("span",{className:"mr-2 text-fg-dim line-through",children:e}),t]}):null}),c(P,{children:r&&o?c("div",{className:`mt-[2px] font-mono ${h.labelSmall} tracking-[0.08em] text-fg-dim`,children:o}):null})]})}export{j as default};
1
+ "use client";import{jsx as n,jsxs as c,Fragment as b}from"react/jsx-runtime";import P from"efficient-web-builder/render/components/TextRegionRun";import{SectionTextParts as S}from"efficient-web-builder/render/lib/document/editing-bridges";import{TEXT_REGION_ATTR as T}from"efficient-web-builder/format/lib/sections/text-regions";import{formatPrice as v}from"../../lib/commerce.js";import{setLabel as y}from"../../lib/wheels/variants.js";import{wheelCardPriceLine as d}from"../../lib/wheels/set-mode.js";import{EACH_UNIT as N,formatSelectionPrice as _,formatSelectionWasPrice as w,formatWheelPrice as p,formatWheelWasPrice as L,FROM_PREFIX as u,priceIn as k,resolveWheelPrice as f,SET_QUOTE_LABEL as E}from"../../lib/wheels/price-display.js";import{CARD_TEXT_SIZE as h,CardRow as x}from"./card-row.js";import{useHeroPriceStateOrNull as R,useProductCardState as I}from"./ProductCardState.js";function C(e,t){if(e.kind==="tyre"){const m=f(k(e.tyre.prices,e.currency),null);return{was:null,amount:p(m,e.currency,u),note:m.priced?N:null}}const{wheel:o,currency:r,price:i,sel:l,isSet:g}=e,a=f(o.prices[r],o.msrpPrices?.[r]),s=t.setTotal&&i.priced&&i.setTotal!=null&&l.selectedVariant?`${y(l.selectedVariant)} · ${v(i.setTotal,r)}`:null;return g&&t.quoteSets?{was:null,amount:a.priced?d(p(a,r,u),!0):E,note:s}:{was:t.wasFollowsSize?w(i,r):L(a,r),amount:d(_(i,r),i.priced),note:s}}function W({state:e,region:t}){const o=!!t?.editing,r=c("div",{className:"flex items-baseline gap-5 border-t border-line pt-[18px]",children:[e.msrpLabel&&n("div",{className:"font-mono text-[length:var(--size-label,15px)] text-fg-dim line-through",children:e.msrpLabel}),n("div",{className:"font-heading2 text-[length:min(var(--size-headingMedium,36px),var(--sf-heading-max,9999px))] font-bold leading-none tracking-[-0.01em] text-fg",...o?{[T]:"price"}:{},children:n(P,{region:"price",partStyles:t?.partStyles,children:e.amount})}),e.unitLabel&&n("div",{className:"font-mono text-[length:var(--size-label,13px)] font-semibold uppercase tracking-[0.22em] text-fg",children:e.unitLabel}),e.packBadge&&n("div",{className:"ml-auto border border-accent px-3 py-2 font-mono text-[length:var(--size-label,13px)] font-bold uppercase tracking-[0.18em] text-accent",style:{background:"color-mix(in oklab, var(--accent) 14%, transparent)"},children:e.packBadge})]});return!o||!t?.nodeId?r:n(S,{nodeId:t.nodeId,sectionType:"ProductPrice",partStyles:t.partStyles,children:r})}function z({show:e=!0,region:t,...o}){const r=R();return r?n(W,{state:r,region:t}):n(F,{show:e,...o})}function F({show:e,...t}){const o=I(),{was:r,amount:i,note:l}=C(o,t);return c(b,{children:[n(x,{children:e?c("div",{className:`mt-2 font-mono ${h.labelLarge}`,children:[r&&n("span",{className:"mr-2 text-fg-dim line-through",children:r}),i]}):null}),n(x,{children:e&&l?n("div",{className:`mt-[2px] font-mono ${h.labelSmall} tracking-[0.08em] text-fg-dim`,children:l}):null})]})}export{z as default};
@@ -0,0 +1,10 @@
1
+ import type { Ref } from "react";
2
+ export declare function ClippedPictures({ clipRef, pictures, }: {
3
+ clipRef?: Ref<HTMLDivElement>;
4
+ pictures: readonly {
5
+ src: string;
6
+ sizes?: string;
7
+ onLoad: () => void;
8
+ onError: () => void;
9
+ }[];
10
+ }): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as s}from"react/jsx-runtime";import i from"next/image";function t({clipRef:r,pictures:o}){return s("div",{ref:r,className:"pointer-events-none absolute h-px w-px overflow-hidden opacity-0","aria-hidden":!0,children:o.map(e=>s(i,{src:e.src,alt:"",width:e.sizes?1e3:16,height:e.sizes?1e3:16,sizes:e.sizes,className:"absolute inset-0",loading:"lazy",onLoad:e.onLoad,onError:e.onError},e.src))})}export{t as ClippedPictures};
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
- export default function HostPart({ label, editing, children }: {
2
+ export default function HostPart({ label, editing, onHero, children, }: {
3
3
  label: string;
4
4
  editing: boolean;
5
+ onHero?: boolean;
5
6
  children: ReactNode;
6
7
  }): import("react").JSX.Element | null;
@@ -1 +1 @@
1
- "use client";import{Fragment as o,jsx as r}from"react/jsx-runtime";import{say as s}from"efficient-web-builder/format/lib/editor-words";import{useProductCardStateOrNull as i}from"./ProductCardState.js";function n({label:t,editing:a,children:e}){return i()?r(o,{children:e}):a?r("div",{"data-host-part-sample":"",className:"opacity-60",children:s(t)}):null}export{n as default};
1
+ "use client";import{Fragment as l,jsx as r}from"react/jsx-runtime";import{say as i}from"efficient-web-builder/format/lib/editor-words";import{useHeroPriceStateOrNull as n,useProductCardStateOrNull as u}from"./ProductCardState.js";function m({label:t,editing:e,onHero:a=!1,children:o}){const s=n();return u()||a&&s?r(l,{children:o}):e?r("div",{"data-host-part-sample":"",className:"opacity-60",children:i(t)}):null}export{m as default};
@@ -36,6 +36,18 @@ export interface TyreCardState {
36
36
  readonly editing: boolean;
37
37
  }
38
38
  export type ProductCardState = WheelCardState | TyreCardState;
39
+ export interface HeroPriceState {
40
+ readonly kind: "hero";
41
+ readonly msrpLabel: string | null;
42
+ readonly amount: string;
43
+ readonly unitLabel: string | null;
44
+ readonly packBadge: string | null;
45
+ }
46
+ export declare function useHeroPriceStateOrNull(): HeroPriceState | null;
47
+ export declare function HeroPriceStateProvider({ value, children }: {
48
+ value: HeroPriceState;
49
+ children: ReactNode;
50
+ }): import("react").JSX.Element;
39
51
  export declare function useProductCardState(): ProductCardState;
40
52
  export declare function useProductCardStateOrNull(): ProductCardState | null;
41
53
  export declare function useWheelCardState(): WheelCardState;
@@ -1 +1 @@
1
- "use client";import{jsx as v}from"react/jsx-runtime";import{createContext as z,useCallback as A,useContext as P,useMemo as W,useState as y}from"react";import{useCurrency as h}from"../CurrencyContext.js";import{useTyreDetail as b}from"../useTyreDetail.js";import{usePlpCardSelection as B}from"../wheels-plp/usePlpCardSelection.js";import{tyrePagePath as N}from"../../lib/tyres/tyre-page-path.js";import{canOrderTyreVariant as T}from"../../lib/tyres/tyre-purchase.js";import{resolveSelectionPrice as j}from"../../lib/wheels/price-display.js";import{setBuildLabel as E,setIsWide as L,summarySetBuild as R}from"../../lib/wheels/set-mode.js";const c=z(null);function V(){const e=P(c);if(!e)throw new Error("A product card piece was drawn outside a product card (no ProductCardState).");return e}function K(){return P(c)}function Q(){const e=V();if(e.kind!=="wheel")throw new Error("A wheel card piece was drawn on a tyre card.");return e}const _=[];function X({wheel:e,colours:i=_,defaultFinish:u,editing:l=!1,children:a}){const{currency:t}=h(),r=B(e,i,u),[d,f]=y(!1),s=R(e),n={kind:"wheel",wheel:e,sel:r,currency:t,price:j(e,r.selectedVariant,t,1),isSet:L(s),setWords:E(s),editing:l,notifyOpen:d,setNotifyOpen:f};return v(c.Provider,{value:n,children:a})}function Y({tyre:e,currency:i,editing:u=!1,children:l}){const{currency:a}=h(),{slug:t}=e,r=N(t),[d,f]=y(!1),s=A(()=>{t&&f(!0)},[t]),{state:n,tyre:m}=b(t??null,d),o=W(()=>m?.variants??[],[m]),[x,w]=y(null),O=o.length===1?o[0].size:null,C=x??O,p=o.find(k=>k.size===C),S=n==="ready",g={kind:"tyre",tyre:e,currency:i,activeCurrency:a,pagePath:r,arm:s,detailState:n,detail:m,variants:o,chosen:C,setSize:w,variant:p,canAdd:p!=null&&T(p,a),detailReady:S,unsellable:!r||n==="error"||S&&o.length===0,editing:u};return v(c.Provider,{value:g,children:l})}export{Y as TyreCardStateProvider,X as WheelCardStateProvider,V as useProductCardState,K as useProductCardStateOrNull,Q as useWheelCardState};
1
+ "use client";import{jsx as P}from"react/jsx-runtime";import{createContext as z,useCallback as A,useContext as S,useMemo as N,useState as v}from"react";import{useCurrency as C}from"../CurrencyContext.js";import{useTyreDetail as W}from"../useTyreDetail.js";import{usePlpCardSelection as b}from"../wheels-plp/usePlpCardSelection.js";import{tyrePagePath as B}from"../../lib/tyres/tyre-page-path.js";import{canOrderTyreVariant as T}from"../../lib/tyres/tyre-purchase.js";import{resolveSelectionPrice as j}from"../../lib/wheels/price-display.js";import{setBuildLabel as E,setIsWide as H,summarySetBuild as L}from"../../lib/wheels/set-mode.js";const r=z(null);function K(){const e=S(r);return e?.kind==="hero"?e:null}function Q({value:e,children:n}){return P(r.Provider,{value:e,children:n})}function R(){const e=S(r);if(!e||e.kind==="hero")throw new Error("A product card piece was drawn outside a product card (no ProductCardState).");return e}function X(){const e=S(r);return e?.kind==="hero"?null:e}function Y(){const e=R();if(e.kind!=="wheel")throw new Error("A wheel card piece was drawn on a tyre card.");return e}const V=[];function Z({wheel:e,colours:n=V,defaultFinish:u,editing:l=!1,children:c}){const{currency:t}=C(),o=b(e,n,u),[d,f]=v(!1),i=L(e),a={kind:"wheel",wheel:e,sel:o,currency:t,price:j(e,o.selectedVariant,t,1),isSet:H(i),setWords:E(i),editing:l,notifyOpen:d,setNotifyOpen:f};return P(r.Provider,{value:a,children:c})}function $({tyre:e,currency:n,editing:u=!1,children:l}){const{currency:c}=C(),{slug:t}=e,o=B(t),[d,f]=v(!1),i=A(()=>{t&&f(!0)},[t]),{state:a,tyre:p}=W(t??null,d),s=N(()=>p?.variants??[],[p]),[x,w]=v(null),O=s.length===1?s[0].size:null,y=x??O,m=s.find(g=>g.size===y),h=a==="ready",k={kind:"tyre",tyre:e,currency:n,activeCurrency:c,pagePath:o,arm:i,detailState:a,detail:p,variants:s,chosen:y,setSize:w,variant:m,canAdd:m!=null&&T(m,c),detailReady:h,unsellable:!o||a==="error"||h&&s.length===0,editing:u};return P(r.Provider,{value:k,children:l})}export{Q as HeroPriceStateProvider,$ as TyreCardStateProvider,Z as WheelCardStateProvider,K as useHeroPriceStateOrNull,R as useProductCardState,X as useProductCardStateOrNull,Y as useWheelCardState};
@@ -0,0 +1,16 @@
1
+ import { type ReactNode } from "react";
2
+ export declare function useHeldCardPicture({ src, second, alt, sizes, failed, onFailed, near, holdEmpty, }: {
3
+ src: string | null;
4
+ second?: string | null;
5
+ alt: string;
6
+ sizes: string;
7
+ failed: ReadonlySet<string>;
8
+ onFailed: (url: string) => void;
9
+ near: boolean;
10
+ holdEmpty?: boolean;
11
+ }): {
12
+ src: string | null;
13
+ alt: string;
14
+ second: string | null;
15
+ trial: ReactNode;
16
+ };
@@ -0,0 +1 @@
1
+ "use client";import{jsx as R}from"react/jsx-runtime";import{useEffect as U,useRef as i,useState as f}from"react";import{ClippedPictures as q}from"./ClippedPictures.js";import{decodePhotoAt as B,STAGE_HOLD_LIMIT_MS as J,useStagePhotoHold as K}from"../product-hero/stage-photo.js";import{holdSignedUrl as A}from"../../lib/wheels/signed-url.js";function Y({src:e,second:M=null,alt:m,sizes:S,failed:w,onFailed:C,near:o,holdEmpty:I=!1}){A(e),A(M);const[O]=f(e),[p,k]=f(!1);!p&&e!==O&&k(!0);const s=i(e),L=i(new Map),u=i(new Map);e&&(L.current.set(e,m),u.current.set(e,M));const[T,_]=f([]),l=i(new Map),b=t=>{for(const n of l.current.get(t)??[])n();l.current.delete(t),_(n=>n.filter(c=>c!==t))},x=i(null);x.current=o?e:null;const E=t=>B(t,S).catch(n=>{const c=x.current;if(t!==c&&(!c||t!==u.current.get(c)))throw n;return new Promise(G=>{l.current.set(t,[...l.current.get(t)??[],G]),_(P=>P.includes(t)?P:[...P,t])})}),y=async t=>{const n=u.current.get(t);await Promise.all([E(t),n?E(n):void 0])},g=!e&&I&&!!s.current&&!w.has(s.current),[D,H]=f(!1);U(()=>{if(!g){H(!1);return}const t=setTimeout(()=>H(!0),J);return()=>clearTimeout(t)},[g]);const a=e??(g&&!D?s.current:null),j=K(p&&o&&a?[a]:[],o?a??void 0:void 0,y),d=o?j.drawn:a??void 0,F=!s.current&&p&&o&&!!d&&!j.settled,r=d&&!w.has(d)&&!F?d:null;s.current=r;const v=T.length>0?R(q,{pictures:T.map(t=>({src:t,sizes:S,onLoad:()=>b(t),onError:()=>{C(t),b(t)}}))}):null;if(!r)return{src:null,alt:m,second:null,trial:v};const h=u.current.get(r)??null;return{src:r,alt:L.current.get(r)??m,second:h&&!w.has(h)?h:null,trial:v}}export{Y as useHeldCardPicture};
@@ -1,10 +1,10 @@
1
1
  import type { ReactNode } from "react";
2
- import { type HeroTextRegionProps } from "../ProductHeroPanel.js";
2
+ import { type HeroPriceTemplateProps } from "../ProductHeroPanel.js";
3
3
  import type { StoreProduct } from "../../lib/catalog/store-product.js";
4
4
  import type { HeroPricePlacement } from "../../lib/sections/hero-price-placement.js";
5
5
  import type { HeroLayout, HeroTextAlign } from "../../lib/sections/hero-arrangement.js";
6
6
  import type { HeroGalleryMode, HeroImageFit } from "../../lib/sections/hero-gallery.js";
7
- interface HeroArrangement extends HeroTextRegionProps {
7
+ interface HeroArrangement extends HeroPriceTemplateProps {
8
8
  heroLayout?: HeroLayout;
9
9
  imageRatio?: number;
10
10
  textAlign?: HeroTextAlign;
@@ -7,4 +7,10 @@ export interface StageControl {
7
7
  }
8
8
  export declare function stageControls(angleIdx: number, total: number, setAngleIdx: (i: number) => void): StageControl[];
9
9
  export declare function decodeStagePhoto(url: string): Promise<void>;
10
+ export declare function decodePhotoAt(url: string, sizes: string): Promise<void>;
11
+ export declare const STAGE_HOLD_LIMIT_MS = 8000;
12
+ export declare function useStagePhotoHold(photos: readonly string[], wanted: string | undefined, decode?: (url: string) => Promise<void>): {
13
+ drawn: string | undefined;
14
+ settled: boolean;
15
+ };
10
16
  export declare function useHeldStagePhoto(photos: readonly string[], wanted: string | undefined, decode?: (url: string) => Promise<void>): string | undefined;
@@ -1,3 +1,3 @@
1
- "use client";import{getImageProps as S}from"next/image";import{useEffect as p,useState as u}from"react";const d="(max-width: 720px) 88vw, (max-width: 1100px) 44vw, 700px";function a(t,e,s){return s<=1?0:((t+e)%s+s)%s}function v(t,e,s){return[{glyph:"◁",label:"Previous angle",onClick:()=>s(a(t,-1,e))},{glyph:"⟳",label:"Reset to first angle",onClick:()=>s(0)},{glyph:"▷",label:"Next angle",onClick:()=>s(a(t,1,e))}]}function x(t){const{props:e}=S({src:t,alt:"",fill:!0,sizes:d}),s=new window.Image;return e.sizes&&(s.sizes=e.sizes),e.srcSet&&(s.srcset=e.srcSet),s.src=e.src,s.decode()}function w(t,e,s=x){const[g,h]=u(()=>new Set),[n,m]=u(e),o=t.join(`
2
- `);p(()=>{let l=!0;const f=r=>{l&&h(c=>c.has(r)?c:new Set(c).add(r))};for(const r of o?o.split(`
3
- `):[])s(r).then(()=>f(r),()=>f(r));return()=>{l=!1}},[o]);const i=e===void 0||g.has(e)||n===void 0;return p(()=>{i&&n!==e&&m(e)},[i,n,e]),i?e:n}export{d as STAGE_IMAGE_SIZES,x as decodeStagePhoto,v as stageControls,a as stepGalleryAngle,w as useHeldStagePhoto};
1
+ "use client";import{getImageProps as P}from"next/image";import{useEffect as p,useState as a}from"react";const k="(max-width: 720px) 88vw, (max-width: 1100px) 44vw, 700px";function h(o,e,t){return t<=1?0:((o+e)%t+t)%t}function b(o,e,t){return[{glyph:"◁",label:"Previous angle",onClick:()=>t(h(o,-1,e))},{glyph:"⟳",label:"Reset to first angle",onClick:()=>t(0)},{glyph:"▷",label:"Next angle",onClick:()=>t(h(o,1,e))}]}function m(o){return E(o,k)}function E(o,e){const{props:t}=P({src:o,alt:"",fill:!0,sizes:e}),n=new window.Image;return t.sizes&&(n.sizes=t.sizes),t.srcSet&&(n.srcset=t.srcSet),n.src=t.src,n.decode()}const G=8e3;function T(o,e,t=m){const[n,S]=a(()=>new Set),[s,x]=a(e),[v,y]=a(),c=o.join(`
2
+ `);p(()=>{let i=!0;const g=r=>{S(l=>l.has(r)?l:new Set(l).add(r))};for(const r of c?c.split(`
3
+ `):[])n.has(r)||t(r).then(()=>g(r),()=>{i&&g(r)});return()=>{i=!1}},[c]);const u=e!==void 0&&(n.has(e)||v===e),d=e!==void 0&&!u&&o.includes(e);p(()=>{if(!d)return;const i=setTimeout(()=>y(e),G);return()=>clearTimeout(i)},[d,e]);const f=e===void 0||u||s===void 0;return p(()=>{f&&s!==e&&x(e)},[f,s,e]),{drawn:f?e:s,settled:u}}function z(o,e,t=m){return T(o,e,t).drawn}export{G as STAGE_HOLD_LIMIT_MS,k as STAGE_IMAGE_SIZES,E as decodePhotoAt,m as decodeStagePhoto,b as stageControls,h as stepGalleryAngle,z as useHeldStagePhoto,T as useStagePhotoHold};
@@ -12,6 +12,9 @@ export interface FinishSelection {
12
12
  finish: FinishSwatch | undefined;
13
13
  shownSrc: string | null;
14
14
  showSwatches: boolean;
15
+ awaitingProbe: boolean;
16
+ nearScreen: boolean;
17
+ pictureFailed: (url: string) => void;
15
18
  probes: React.ReactNode;
16
19
  }
17
20
  export declare function useFinishSelection(finishes: FinishSwatch[], cover: string | null, defaultFinish?: string): FinishSelection;
@@ -1 +1,3 @@
1
- "use client";import{jsx as h}from"react/jsx-runtime";import S from"next/image";import{useEffect as w,useMemo as y,useState as i}from"react";function A(s,x,d){const[n,o]=i(()=>{const e=d?s.findIndex(t=>t.name===d):-1;return e>=0?e:0}),[l,a]=i(null),[c,I]=i(()=>s.map(()=>!0)),g=e=>{I(t=>{if(t[e]===!1)return t;const f=[...t];return f[e]=!1,f})},r=y(()=>c.map((e,t)=>e?t:-1).filter(e=>e!==-1),[c]);w(()=>{if(r.length===0){n!==-1&&o(-1),l!==null&&a(null);return}n>=0&&!r.includes(n)&&o(r[0]),l!==null&&!r.includes(l)&&a(null)},[r,n,l]);const u=l??n,m=u>=0?s[u]:void 0,p=m?.src??x,b=r.length>=2,v=s.length>0?h("div",{className:"hidden","aria-hidden":!0,children:s.map((e,t)=>h(S,{src:e.src,alt:"",width:16,height:16,loading:"eager",onError:()=>g(t)},e.src))}):null;return{selectedIdx:n,setSelectedIdx:o,hoverIdx:l,setHoverIdx:a,availability:c,finish:m,shownSrc:p,showSwatches:b,probes:v}}export{A as useFinishSelection};
1
+ "use client";import{jsx as se}from"react/jsx-runtime";import{AppRouterContext as oe}from"next/dist/shared/lib/app-router-context.shared-runtime";import{useCallback as U,useContext as re,useEffect as j,useMemo as D,useRef as H,useState as c}from"react";import{ClippedPictures as ce}from"./card-pieces/ClippedPictures.js";import{STAGE_HOLD_LIMIT_MS as ae}from"./product-hero/stage-photo.js";import{holdSignedUrl as le,signedUrlExpired as N}from"../lib/wheels/signed-url.js";function l(n){const o=n.indexOf("?");if(o<0)return n;const d=n.slice(o+1).split("&").filter(u=>!/^x-amz-/i.test(u));return d.length>0?`${n.slice(0,o)}?${d.join("&")}`:n.slice(0,o)}const g=n=>n?{name:n.name,file:l(n.src)}:null,de=300*1e3,T=new WeakMap,ue="1250px";function xe(n,o,d){const[u,y]=c(()=>g(d?n.find(e=>e.name===d):void 0)??void 0),[h,v]=c(null),[f,G]=c(()=>new Set),$=e=>G(t=>t.has(l(e))?t:new Set(t).add(l(e))),w=H(n);w.current=n;const q=U(e=>y(e<0?null:g(w.current[e])),[]),z=U(e=>v(e===null?null:g(w.current[e])),[]),m=re(oe);for(const e of[o,...n.map(t=>t.src)])le(e);const E=()=>{m&&Date.now()-(T.get(m)??0)>=de&&(T.set(m,Date.now()),m.refresh())},K=e=>{N(e)&&E()},V=(e,t)=>{if(!N(t))return $(t);E()},[W,Y]=c(()=>new Set),B=e=>Y(t=>t.has(e)?t:new Set(t).add(e)),[_,J]=c(()=>new Set),R=e=>J(t=>t.has(e)?t:new Set(t).add(e)),M=H(null),[x,Q]=c(!1);j(()=>{const e=M.current;if(!e||typeof IntersectionObserver>"u")return;const t=new IntersectionObserver(s=>{const S=s[s.length-1];S&&Q(S.isIntersecting)},{rootMargin:ue});return t.observe(e),()=>t.disconnect()},[]);const I=n.map(e=>l(e.src)).join(`
2
+ `),i=D(()=>(I?I.split(`
3
+ `):[]).map(e=>!f.has(e)),[I,f]),O=D(()=>i.map((e,t)=>e?t:-1).filter(e=>e!==-1),[i]),k=e=>{const t=s=>s>=0&&i[s]?s:null;return t(n.findIndex(s=>s.name===e.name&&l(s.src)===e.file))??t(n.findIndex((s,S)=>s.name===e.name&&i[S]))},A=u===null?-1:(u===void 0?null:k(u))??O[0]??-1,L=h===null?null:k(h),r=L??A,a=r>=0?n[r]:void 0,X=a?.src??o,Z=O.length>=2,ee=r>=0&&!(a&&W.has(a.src)),[F,te]=c(()=>new Set),b=e=>_.has(n[e].src)||F.has(n[e].src)||f.has(l(n[e].src)),C=!a||b(r)?n.findIndex((e,t)=>!b(t)):-1,P=a&&!b(r)?r:C,p=P>=0?n[P].src:null;j(()=>{if(!x||!p)return;const e=setTimeout(()=>te(t=>t.has(p)?t:new Set(t).add(p)),ae);return()=>clearTimeout(e)},[x,p]);const ne=n.length>0?se(ce,{clipRef:M,pictures:n.flatMap((e,t)=>_.has(e.src)||F.has(e.src)||t===r||t===C?[{src:e.src,onLoad:()=>{R(e.src),B(e.src)},onError:()=>{R(e.src),V(t,e.src)}}]:[])}):null;return{selectedIdx:A,setSelectedIdx:q,hoverIdx:L,setHoverIdx:z,availability:i,finish:a,shownSrc:X,showSwatches:Z,awaitingProbe:ee,nearScreen:x,pictureFailed:K,probes:ne}}export{xe as useFinishSelection};
@@ -24,6 +24,8 @@ export declare const loadUnifiedProductCatalog: (force?: boolean) => Promise<(({
24
24
  defaultFinishRenderings?: string[];
25
25
  description: string;
26
26
  listable?: boolean;
27
+ } & {
28
+ hoverMedia?: import("../lib/api/types.js").components["schemas"]["HoverMedia"];
27
29
  } & {
28
30
  kind: "alloy-wheel";
29
31
  } & {
@@ -1 +1 @@
1
- "use client";import{jsx as r,Fragment as $,jsxs as j}from"react/jsx-runtime";import{CARD_IMAGE_SIZES as z}from"../../lib/sections/card-image-sizes.js";import{LISTING_CARD_SHOW as P}from"../../lib/sections/card-show-defaults.js";import M from"next/image";import{useState as U}from"react";import X from"../BrandPlate.js";import H,{CardBuyDialog as V}from"../card-pieces/CardBuyButton.js";import Z from"../card-pieces/CardFinishSwatches.js";import q from"../card-pieces/CardPrice.js";import J from"../card-pieces/CardProductBadge.js";import{useWheelCardState as K,WheelCardStateProvider as Q}from"../card-pieces/ProductCardState.js";import{wheelCardEyebrow as Y,wheelCardEyebrowShows as ee}from"../ProductCardEyebrow.js";import{withRMark as N}from"efficient-web-builder/render/components/RMark";import re from"../WheelPlaceholder.js";import{cardSpinOf as oe}from"../card-spin.js";import{cardHoverOf as ae,cardTurnFor as se}from"efficient-web-builder/format/lib/animation/hover";import{CardSpecFacts as te}from"../card-pieces/CardSpecs.js";import ne from"../WheelCardFrame.js";import{CARD_IMAGE_BG_OFF as ie}from"efficient-web-builder/format/lib/content/card-image-background";import{itemBrand as le}from"../../lib/catalog/plp-item.js";import{CARD_INDEX_BADGE_CLASS as me,CARD_INDEX_CLASS as de,DEFAULT_CARD_INDEX_FORMAT as ce,DEFAULT_CARD_OUTLINE as he}from"efficient-web-builder/format/lib/sections/product-card-style";import{setSecondSrc as ue}from"../../lib/wheels/set-mode.js";import{PLP_GRID_GAP_VAR as fe}from"../../lib/wheels/plp-grid.js";import{FITMENT_FIELD_SEPARATOR as pe}from"../../lib/wheels/plp-fitment-match.js";import{coverSrcForWheel as we,DEFAULT_COVER_INDEX as Se,resolvePaintedSrc as Ce}from"../../lib/wheels/cover-rendering.js";const ge=[],_e=ae({},"AlloyWheelsListing");function Ee({wheel:n,colours:c,fit:i=null,editing:l=!1,brandPlate:m=!1,kindLabel:h=null,showBrand:s=!0,showProcess:u=!1,coverIndex:f=Se,fieldUsage:p=ge,hover:w=_e,imageBackgroundFill:S=ie,showBadge:C=!0,outline:g=he,indexBadge:_=ce,showCardSizes:E=P.showCardSizes,showCardBuy:A=P.showCardBuy,showCardPage:F=P.showCardPage,showCardPrice:e=!0,showCardFinishes:o=!0,imageSizes:d=z}){return r(Q,{wheel:n,colours:c,editing:l,children:r(Ae,{fit:i,brandPlate:m,kindLabel:h,showBrand:s,showProcess:u,coverIndex:f,fieldUsage:p,hover:w,imageBackgroundFill:S,showBadge:C,outline:g,indexBadge:_,showCardSizes:E,showCardBuy:A,showCardPage:F,showCardPrice:e,showCardFinishes:o,imageSizes:d})})}function Ae({fit:n,brandPlate:c,kindLabel:i,showBrand:l,showProcess:m,coverIndex:h,fieldUsage:s,hover:u,imageBackgroundFill:f,showBadge:p,outline:w,indexBadge:S,showCardSizes:C,showCardBuy:g,showCardPage:_,showCardPrice:E,showCardFinishes:A,imageSizes:F}){const{wheel:e,sel:o,isSet:d}=K(),k=we(e,h,o.finish?.name,o.shownSrc,n?.holes),[y,G]=U(()=>new Set),x=a=>G(t=>t.has(a)?t:new Set(t).add(a)),b=Ce({overrideSrc:k,hookSrc:o.shownSrc,failed:y}),I=le(e),B=oe(se(u,e.spokes)),R=(a,t)=>r(M,{src:a,alt:t,width:800,height:800,sizes:F,className:["block h-full w-full object-contain",B.className].filter(Boolean).join(" "),style:B.style,draggable:!1,onError:()=>x(a)},a),L=o.finish?`${e.name} — ${o.finish.name}`:e.name,O=b?R(b,L):r(re,{imageLabel:e.name,spin:B}),D=d?ue(e.finishes?.find(a=>a.name===o.finish?.name),b):null,W=D&&!y.has(D)?R(D,`${L} — right`):void 0,T=S!=="off"?r("span",{"aria-hidden":!0,className:`${de} ${me}`}):null,v=Y({kindLabel:i,brand:l&&I?N(I):null,process:m&&e.process?N(e.process):null},s);return j($,{children:[r(ne,{href:`/wheels/${e.slug}`,wide:d,setGridGap:`var(${fe})`,identityLink:!0,containerProps:{onPointerEnter:o.arm,onTouchStart:o.arm,onFocusCapture:o.arm},probes:o.probes,outline:w,imageBackgroundFill:f,indexBadge:T,badges:r(J,{show:p,numbered:T!=null,sale:!0}),image:O,imageSecond:W,plate:c?r(X,{brand:I,logo:e.brandLogo}):null,eyebrow:v,wholeCardLink:!0,reserveEyebrow:ee({kind:!!i,brand:l,process:m},s),spec:r(te,{sizes:C,fieldUsage:s,car:n,separator:pe}),price:r(q,{show:E,setTotal:!0,wasFollowsSize:!0}),swatches:r(Z,{show:A,showSingle:!0}),buy:r(H,{buy:g,page:_})}),r(V,{})]})}export{Ee as default};
1
+ "use client";import{jsx as r,Fragment as T,jsxs as G}from"react/jsx-runtime";import{CARD_IMAGE_SIZES as M}from"../../lib/sections/card-image-sizes.js";import{LISTING_CARD_SHOW as B}from"../../lib/sections/card-show-defaults.js";import U from"next/image";import{useHeldCardPicture as X}from"../card-pieces/useHeldCardPicture.js";import{useState as H}from"react";import V from"../BrandPlate.js";import Z,{CardBuyDialog as q}from"../card-pieces/CardBuyButton.js";import J from"../card-pieces/CardFinishSwatches.js";import K from"../card-pieces/CardPrice.js";import Q from"../card-pieces/CardProductBadge.js";import{useWheelCardState as Y,WheelCardStateProvider as ee}from"../card-pieces/ProductCardState.js";import{wheelCardEyebrow as re,wheelCardEyebrowShows as oe}from"../ProductCardEyebrow.js";import{withRMark as k}from"efficient-web-builder/render/components/RMark";import ae from"../WheelPlaceholder.js";import{cardSpinOf as se}from"../card-spin.js";import{cardHoverOf as te}from"efficient-web-builder/format/lib/animation/hover";import{CardSpecFacts as ne}from"../card-pieces/CardSpecs.js";import ie from"../WheelCardFrame.js";import{CARD_IMAGE_BG_OFF as le}from"efficient-web-builder/format/lib/content/card-image-background";import{itemBrand as de}from"../../lib/catalog/plp-item.js";import{CARD_INDEX_BADGE_CLASS as me,CARD_INDEX_CLASS as ce,DEFAULT_CARD_INDEX_FORMAT as he,DEFAULT_CARD_OUTLINE as pe}from"efficient-web-builder/format/lib/sections/product-card-style";import{setSecondSrc as ue}from"../../lib/wheels/set-mode.js";import{PLP_GRID_GAP_VAR as fe}from"../../lib/wheels/plp-grid.js";import{FITMENT_FIELD_SEPARATOR as we}from"../../lib/wheels/plp-fitment-match.js";import{coverSrcForWheel as Se,DEFAULT_COVER_INDEX as Ce,resolvePaintedSrc as ge}from"../../lib/wheels/cover-rendering.js";const _e=[],Ee=te({},"AlloyWheelsListing");function Ae({wheel:i,colours:p,fit:l=null,editing:d=!1,brandPlate:m=!1,kindLabel:u=null,showBrand:t=!0,showProcess:f=!1,coverIndex:w=Ce,fieldUsage:S=_e,hover:C=Ee,imageBackgroundFill:g=le,showBadge:_=!0,outline:E=pe,indexBadge:A=he,showCardSizes:F=B.showCardSizes,showCardBuy:b=B.showCardBuy,showCardPage:c=B.showCardPage,showCardPrice:o=!0,showCardFinishes:e=!0,imageSizes:h=M}){return r(ee,{wheel:i,colours:p,editing:d,children:r(Fe,{fit:l,brandPlate:m,kindLabel:u,showBrand:t,showProcess:f,coverIndex:w,fieldUsage:S,hover:C,imageBackgroundFill:g,showBadge:_,outline:E,indexBadge:A,showCardSizes:F,showCardBuy:b,showCardPage:c,showCardPrice:o,showCardFinishes:e,imageSizes:h})})}function Fe({fit:i,brandPlate:p,kindLabel:l,showBrand:d,showProcess:m,coverIndex:u,fieldUsage:t,hover:f,imageBackgroundFill:w,showBadge:S,outline:C,indexBadge:g,showCardSizes:_,showCardBuy:E,showCardPage:A,showCardPrice:F,showCardFinishes:b,imageSizes:c}){const{wheel:o,sel:e,isSet:h}=Y(),x=Se(o,u,e.finish?.name,e.shownSrc,i?.holes),[D,O]=H(()=>new Set),y=a=>{e.pictureFailed(a),O(n=>n.has(a)?n:new Set(n).add(a))},R=ge({overrideSrc:x,hookSrc:e.shownSrc,failed:D}),P=de(o),I=se(f),L=(a,n)=>r(U,{alt:n,src:a,width:800,height:800,sizes:c,className:["block h-full w-full object-contain",I.className].filter(Boolean).join(" "),style:I.style,draggable:!1,onError:()=>y(a)},a),W=e.finish?`${o.name} — ${e.finish.name}`:o.name,v=h?ue(o.finishes?.find(a=>a.name===e.finish?.name),R):null,s=X({src:R,second:v,alt:W,sizes:c,failed:D,onFailed:y,near:e.nearScreen,holdEmpty:e.awaitingProbe}),$=G(T,{children:[s.src?L(s.src,s.alt):r(ae,{imageLabel:o.name,spin:I}),s.trial]}),j=s.second?L(s.second,`${s.alt} — right`):void 0,N=g!=="off"?r("span",{"aria-hidden":!0,className:`${ce} ${me}`}):null,z=re({kindLabel:l,brand:d&&P?k(P):null,process:m&&o.process?k(o.process):null},t);return G(T,{children:[r(ie,{href:`/wheels/${o.slug}`,wide:h,setGridGap:`var(${fe})`,identityLink:!0,containerProps:{onPointerEnter:e.arm,onTouchStart:e.arm,onFocusCapture:e.arm},probes:e.probes,outline:C,imageBackgroundFill:w,indexBadge:N,badges:r(Q,{show:S,numbered:N!=null,sale:!0}),image:$,imageSecond:j,plate:p?r(V,{brand:P,logo:o.brandLogo}):null,eyebrow:z,wholeCardLink:!0,reserveEyebrow:oe({kind:!!l,brand:d,process:m},t),spec:r(ne,{sizes:_,fieldUsage:t,car:i,separator:we}),price:r(K,{show:F,setTotal:!0,wasFollowsSize:!0}),swatches:r(J,{show:b,showSingle:!0}),buy:r(Z,{buy:E,page:A})}),r(q,{})]})}export{Ae as default};
@@ -1110,7 +1110,10 @@ export interface components {
1110
1110
  loadRating: string;
1111
1111
  inStock: boolean;
1112
1112
  };
1113
- WheelSummary: {
1113
+ WheelSummary: components["schemas"]["WheelCore"] & {
1114
+ hoverMedia?: components["schemas"]["HoverMedia"];
1115
+ };
1116
+ WheelCore: {
1114
1117
  name: string;
1115
1118
  slug: string;
1116
1119
  designCode?: string;
@@ -1141,6 +1144,16 @@ export interface components {
1141
1144
  thumbnailUrl: string;
1142
1145
  kind: "image" | "video";
1143
1146
  };
1147
+ HoverMediaGroup: {
1148
+ finish: string;
1149
+ items: components["schemas"]["MediaGroupItem"][];
1150
+ };
1151
+ HoverMedia: {
1152
+ photos?: components["schemas"]["HoverMediaGroup"][];
1153
+ lifestyle?: components["schemas"]["HoverMediaGroup"][];
1154
+ accessories?: components["schemas"]["HoverMediaGroup"][];
1155
+ others?: components["schemas"]["HoverMediaGroup"][];
1156
+ };
1144
1157
  MediaGroup: {
1145
1158
  name: string;
1146
1159
  vehicle?: string;
@@ -1276,7 +1289,7 @@ export interface components {
1276
1289
  oemSizes: string[];
1277
1290
  variants: components["schemas"]["TyreFitVariant"][];
1278
1291
  };
1279
- Wheel: components["schemas"]["WheelSummary"] & {
1292
+ Wheel: components["schemas"]["WheelCore"] & {
1280
1293
  fitments: components["schemas"]["FitmentRow"][];
1281
1294
  mediaGroups: components["schemas"]["MediaGroups"];
1282
1295
  relatedProducts: components["schemas"]["RelatedProduct"][];
@@ -0,0 +1,4 @@
1
+ type Props = Record<string, unknown>;
2
+ export declare const HERO_PRICE_BLOCK = "ProductPrice";
3
+ export declare function withHeroPriceTemplate(props: Props): Props;
4
+ export {};
@@ -0,0 +1 @@
1
+ import{PART_MOTION_PROP as s}from"efficient-web-builder/render/lib/animation/part-motion";import{PART_STYLES_PROP as m,readPartStyles as u}from"efficient-web-builder/render/lib/document/part-styles";import{seedNodes as p}from"efficient-web-builder/format/lib/document/seed-parts";const R="ProductPrice",d="@price";function _(e){const{[d]:o,...t}=e&&typeof e=="object"?e:{};return{price:o,others:t}}function T(e){if(e.template!==void 0)return e;const o=typeof e.id=="string"&&e.id.trim()?e.id:"ProductHero",[t]=p([{type:R}],()=>`${o}~price`),r={...e},c={};for(const[n,f]of[[m,u(e)],[s,e[s]]]){const{price:i,others:P}=_(f);i&&(c[n]={[d]:i},Object.keys(P).length>0?r[n]=P:delete r[n])}return r.template=[{...t,props:{...t.props,...c}}],r}export{R as HERO_PRICE_BLOCK,T as withHeroPriceTemplate};
@@ -1,5 +1,9 @@
1
1
  import type { BlockRender } from "efficient-web-builder/format/lib/document/blocks/block-types";
2
2
  export declare const ProductHeroSlots: {
3
+ template: {
4
+ allow: string[];
5
+ type: "slot";
6
+ };
3
7
  trustBullets: {
4
8
  type: "slot";
5
9
  allow: string[];
@@ -1 +1 @@
1
- import{DEFAULT_HERO_PRICE_PLACEMENT as e}from"../../../../sections/hero-price-placement.js";import{DEFAULT_HERO_LAYOUT as t,DEFAULT_HERO_RATIO as r,DEFAULT_HERO_TEXT_ALIGN as E}from"../../../../sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as T,DEFAULT_HERO_IMAGE_FIT as _}from"../../../../sections/hero-gallery.js";import{TRUST_BULLETS_ALLOW as L,TRUST_BULLETS_SLOT as o}from"../../../../sections/hero-trust-bullets.js";const l={[o]:{type:"slot",allow:L}},a={label:"Product Hero",fields:l,defaultProps:{source:null,pricePlacement:e,showVehicleFitment:!0,heroLayout:t,imageRatio:r,textAlign:E,showSpecTable:!0,showPriceQuote:!0,galleryMode:T,imageFit:_,[o]:[]}};export{a as ProductHeroMeta,l as ProductHeroSlots};
1
+ import{DEFAULT_HERO_PRICE_PLACEMENT as e}from"../../../../sections/hero-price-placement.js";import{DEFAULT_HERO_LAYOUT as r,DEFAULT_HERO_RATIO as l,DEFAULT_HERO_TEXT_ALIGN as E}from"../../../../sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as _,DEFAULT_HERO_IMAGE_FIT as T}from"../../../../sections/hero-gallery.js";import{cardTemplateSlot as L}from"efficient-web-builder/format/lib/content/card-template";import{HERO_PRICE_BLOCK as m}from"../../../../content/hero-price-seed.js";import{TRUST_BULLETS_ALLOW as a,TRUST_BULLETS_SLOT as o}from"../../../../sections/hero-trust-bullets.js";const t=L(),i={template:{...t,allow:[...t.allow,m]},[o]:{type:"slot",allow:a}},u={label:"Product Hero",fields:i,defaultProps:{source:null,pricePlacement:e,showVehicleFitment:!0,heroLayout:r,imageRatio:l,textAlign:E,showSpecTable:!0,showPriceQuote:!0,galleryMode:_,imageFit:T,[o]:[]}};export{u as ProductHeroMeta,i as ProductHeroSlots};
@@ -1 +1 @@
1
- import{jsx as r}from"react/jsx-runtime";import{SITE_WIDTH_CAP as h}from"efficient-web-builder/format/lib/content/page-width";import{resolveWidth as P}from"efficient-web-builder/format/lib/content/section-width";import H from"../../../../../components/LinkedProductHero.js";import m from"../../../../../components/pdp-dynamic/DynamicProductHero.js";import L from"../../../../../components/SectionNotice.js";import{trustBulletsRow as g,trustBulletsSlot as A}from"../../../../../components/product-hero/trust-bullets.js";import{TRUST_BULLETS_SLOT as R}from"../../../../sections/hero-trust-bullets.js";import{useCurrentProduct as y}from"../../../current-product.js";import{isEditorOnDynamicPage as F}from"efficient-web-builder/format/lib/document/editor-page-context";import{DEFAULT_HERO_PRICE_PLACEMENT as O,parseHeroPricePlacement as w}from"../../../../sections/hero-price-placement.js";import{DEFAULT_HERO_LAYOUT as D,DEFAULT_HERO_RATIO as S,DEFAULT_HERO_TEXT_ALIGN as I,parseHeroLayout as U,parseHeroRatio as M,parseHeroTextAlign as x}from"../../../../sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as B,DEFAULT_HERO_IMAGE_FIT as C,parseHeroGalleryMode as k,parseHeroImageFit as p}from"../../../../sections/hero-gallery.js";import{say as G}from"efficient-web-builder/format/lib/editor-words";import{readPartStyles as N}from"efficient-web-builder/render/lib/document/part-styles";import{ProductHeroMeta as V}from"./meta.js";function b({source:e,editing:t=!1,pricePlacement:o=O,showVehicleFitment:i=!0,heroLayout:l=D,imageRatio:a=S,textAlign:u=I,showSpecTable:c=!0,showPriceQuote:d=!0,galleryMode:f=B,imageFit:s=C,trustBullets:E,nodeId:T,partStyles:_}){const n={heroLayout:l,imageRatio:a,textAlign:u,showSpecTable:c,showPriceQuote:d,galleryMode:f,imageFit:s,trustBullets:g(E,t),nodeId:T,partStyles:_};return y()||t&&F()?r(m,{editing:t,pricePlacement:o,showVehicleFitment:i,...n}):e?.slug?r(H,{slug:e.slug,kind:e.kind??"wheel",editing:t,pricePlacement:o,showVehicleFitment:i,...n}):t?r(L,{size:"tall",children:G("Pick a product in the panel to fill this hero.")}):r(m,{pricePlacement:o,showVehicleFitment:i,...n})}function j(e,t){return P(e,"full").mode!=="page"?t:r("div",{style:{"--sf-content-cap":h},children:t})}const me={...V,render:e=>j(e,r(b,{source:e.source,editing:e.editor?.isEditing,pricePlacement:w(e.pricePlacement),showVehicleFitment:e.showVehicleFitment??!0,heroLayout:U(e.heroLayout),imageRatio:M(e.imageRatio),textAlign:x(e.textAlign),showSpecTable:e.showSpecTable??!0,showPriceQuote:e.showPriceQuote??!0,galleryMode:k(e.galleryMode),imageFit:p(e.imageFit),trustBullets:A(e[R]),nodeId:typeof e.id=="string"?e.id:void 0,partStyles:N(e)}))};export{me as ProductHeroRender};
1
+ import{jsx as r}from"react/jsx-runtime";import{SITE_WIDTH_CAP as h}from"efficient-web-builder/format/lib/content/page-width";import{resolveWidth as H}from"efficient-web-builder/format/lib/content/section-width";import L from"../../../../../components/LinkedProductHero.js";import m from"../../../../../components/pdp-dynamic/DynamicProductHero.js";import P from"../../../../../components/SectionNotice.js";import{trustBulletsRow as g,trustBulletsSlot as A}from"../../../../../components/product-hero/trust-bullets.js";import{TRUST_BULLETS_SLOT as R}from"../../../../sections/hero-trust-bullets.js";import{useCurrentProduct as F}from"../../../current-product.js";import{isEditorOnDynamicPage as y}from"efficient-web-builder/format/lib/document/editor-page-context";import{DEFAULT_HERO_PRICE_PLACEMENT as O,parseHeroPricePlacement as w}from"../../../../sections/hero-price-placement.js";import{DEFAULT_HERO_LAYOUT as D,DEFAULT_HERO_RATIO as I,DEFAULT_HERO_TEXT_ALIGN as U,parseHeroLayout as S,parseHeroRatio as M,parseHeroTextAlign as p}from"../../../../sections/hero-arrangement.js";import{DEFAULT_HERO_GALLERY_MODE as x,DEFAULT_HERO_IMAGE_FIT as B,parseHeroGalleryMode as C,parseHeroImageFit as k}from"../../../../sections/hero-gallery.js";import{say as G}from"efficient-web-builder/format/lib/editor-words";import{ProductHeroMeta as N}from"./meta.js";function V({source:e,editing:t=!1,pricePlacement:i=O,showVehicleFitment:o=!0,heroLayout:l=D,imageRatio:u=I,textAlign:a=U,showSpecTable:c=!0,showPriceQuote:d=!0,galleryMode:f=x,imageFit:s=B,trustBullets:E,nodeId:T,priceTemplate:_}){const n={heroLayout:l,imageRatio:u,textAlign:a,showSpecTable:c,showPriceQuote:d,galleryMode:f,imageFit:s,trustBullets:g(E,t),nodeId:T,priceTemplate:_};return F()||t&&y()?r(m,{editing:t,pricePlacement:i,showVehicleFitment:o,...n}):e?.slug?r(L,{slug:e.slug,kind:e.kind??"wheel",editing:t,pricePlacement:i,showVehicleFitment:o,...n}):t?r(P,{size:"tall",children:G("Pick a product in the panel to fill this hero.")}):r(m,{pricePlacement:i,showVehicleFitment:o,...n})}function b(e,t){return H(e,"full").mode!=="page"?t:r("div",{style:{"--sf-content-cap":h},children:t})}const oe={...N,render:e=>b(e,r(V,{source:e.source,editing:e.editor?.isEditing,pricePlacement:w(e.pricePlacement),showVehicleFitment:e.showVehicleFitment??!0,heroLayout:S(e.heroLayout),imageRatio:M(e.imageRatio),textAlign:p(e.textAlign),showSpecTable:e.showSpecTable??!0,showPriceQuote:e.showPriceQuote??!0,galleryMode:C(e.galleryMode),imageFit:k(e.imageFit),trustBullets:A(e[R]),nodeId:typeof e.id=="string"?e.id:void 0,priceTemplate:typeof e.template=="function"?e.template:void 0}))};export{oe as ProductHeroRender};
@@ -1 +1 @@
1
- import{jsx as r}from"react/jsx-runtime";import i from"../../../../../components/card-pieces/CardPrice.js";import t from"../../../../../components/card-pieces/HostPart.js";import{ProductPriceMeta as o}from"./meta.js";const n={...o,render:e=>r(t,{label:o.label??"",editing:!!e.editor?.isEditing,children:r(i,{})})};export{n as ProductPriceRender};
1
+ import{jsx as t}from"react/jsx-runtime";import o from"../../../../../components/card-pieces/CardPrice.js";import d from"../../../../../components/card-pieces/HostPart.js";import{readPartStyles as n}from"efficient-web-builder/render/lib/document/part-styles";import{ProductPriceMeta as i}from"./meta.js";const s={...i,render:r=>{const e=!!r.editor?.isEditing;return t(d,{label:i.label??"",editing:e,onHero:!0,children:t(o,{region:{nodeId:typeof r.id=="string"?r.id:void 0,partStyles:n(r),editing:e}})})}};export{s as ProductPriceRender};
@@ -1 +1 @@
1
- import{registerCardTemplates as l}from"efficient-web-builder/format/lib/content/card-template";import{MENU_LINK_BLOCK as a,withMenuTemplate as b}from"../content/menu-card-seed.js";const e={fields:[{key:"label",label:"Label"},{key:"href",label:"Link",kind:"link"}],blocks:[{type:a,label:"Menu link"}],seed:b},o=[{block:"Reviews",fields:[{key:"quote",label:"Quote"},{key:"title",label:"Title"},{key:"name",label:"Name"},{key:"role",label:"Role · location"},{key:"rating",label:"Rating"},{key:"dateLabel",label:"Date"}]},{block:"SpecTable",fields:[{key:"label",label:"Label"},{key:"value",label:"Value"}]},{block:"FooterMenu",...e},{block:"MenuBlock",...e}];l(o);export{o as STOREFRONT_CARD_TEMPLATES};
1
+ import{registerCardTemplates as l}from"efficient-web-builder/format/lib/content/card-template";import{HERO_PRICE_BLOCK as a,withHeroPriceTemplate as o}from"../content/hero-price-seed.js";import{MENU_LINK_BLOCK as t,withMenuTemplate as b}from"../content/menu-card-seed.js";const e={fields:[{key:"label",label:"Label"},{key:"href",label:"Link",kind:"link"}],blocks:[{type:t,label:"Menu link"}],seed:b},i=[{block:"Reviews",fields:[{key:"quote",label:"Quote"},{key:"title",label:"Title"},{key:"name",label:"Name"},{key:"role",label:"Role · location"},{key:"rating",label:"Rating"},{key:"dateLabel",label:"Date"}]},{block:"SpecTable",fields:[{key:"label",label:"Label"},{key:"value",label:"Value"}]},{block:"FooterMenu",...e},{block:"MenuBlock",...e},{block:"ProductHero",fields:[],blocks:[{type:a,label:"Price"}],seed:o}];l(i);export{i as STOREFRONT_CARD_TEMPLATES};
@@ -0,0 +1,4 @@
1
+ import type { TextRegion } from "efficient-web-builder/format/lib/sections/text-regions";
2
+ type ProductPriceRegionKey = "price";
3
+ export declare const PRODUCT_PRICE_TEXT_REGIONS: Readonly<Record<ProductPriceRegionKey, TextRegion>>;
4
+ export {};
@@ -0,0 +1 @@
1
+ const e={price:{label:"Price",follows:"Heading 2",builtIn:"36px",writable:!0,sized:!0}};export{e as PRODUCT_PRICE_TEXT_REGIONS};
@@ -0,0 +1,3 @@
1
+ export declare const SIGNED_URL_CLOCK_MARGIN_MS: number;
2
+ export declare function holdSignedUrl(url: string | null | undefined, now?: number): void;
3
+ export declare function signedUrlExpired(url: string, now?: number): boolean;
@@ -0,0 +1 @@
1
+ const p=9e5,i=new Map;function r(e){const t=/[?&]X-Amz-Expires=(\d+)/.exec(e);return t&&/[?&]X-Amz-Date=/.test(e)?+t[1]*1e3:null}function x(e,t=Date.now()){if(!e||typeof window>"u"||i.has(e))return;const n=r(e);if(n!==null){for(const[d,o]of i)t-o.at>=2*o.life&&i.delete(d);i.set(e,{at:t,life:n})}}function _(e,t=Date.now()){const n=/[?&]X-Amz-Date=(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z/.exec(e),d=r(e);if(!n||d===null)return!1;const[,o,s,c,a,l,u]=n,f=i.get(e);return f!==void 0&&t-f.at>=d?!0:t+9e5>=Date.UTC(+o,+s-1,+c,+a,+l,+u)+d}export{p as SIGNED_URL_CLOCK_MARGIN_MS,x as holdSignedUrl,_ as signedUrlExpired};
package/dist/words.d.ts CHANGED
@@ -145,7 +145,6 @@ export type WebBuilderPhrase =
145
145
  | "Animation"
146
146
  | "Another group already uses this heading — pick a different one."
147
147
  | "Answer"
148
- | "Any color"
149
148
  | "App"
150
149
  | "App chips"
151
150
  | "App name"
@@ -510,7 +509,6 @@ export type WebBuilderPhrase =
510
509
  | "Follows Styles ▸ Basics ▸ Corners until you set a number here."
511
510
  | "Follows the section's Corners until you set a number here."
512
511
  | "Follows the site"
513
- | "Follows the style"
514
512
  | "Footer Box"
515
513
  | "Footnote"
516
514
  | "Form"
@@ -747,7 +745,6 @@ export type WebBuilderPhrase =
747
745
  | "Milestone title."
748
746
  | "Milestones"
749
747
  | "Mirror cards"
750
- | "Mixed"
751
748
  | "Mockup Card"
752
749
  | "Mockup card"
753
750
  | "Mockup position"