@thorprovider/blocks 0.1.1 → 0.1.3

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 (70) hide show
  1. package/.turbo/turbo-build.log +15 -15
  2. package/.turbo/turbo-test.log +42 -5
  3. package/AGENTS.md +1 -1
  4. package/README.md +94 -1
  5. package/dist/.tsbuildinfo +1 -1
  6. package/dist/contracts.d.mts +1266 -97
  7. package/dist/contracts.d.ts +1266 -97
  8. package/dist/contracts.js +225 -9
  9. package/dist/contracts.js.map +1 -1
  10. package/dist/contracts.mjs +207 -10
  11. package/dist/contracts.mjs.map +1 -1
  12. package/dist/index.d.mts +756 -96
  13. package/dist/index.d.ts +756 -96
  14. package/dist/index.js +5114 -3702
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +4939 -3551
  17. package/dist/index.mjs.map +1 -1
  18. package/docs/standards/theming.md +32 -5
  19. package/package.json +2 -2
  20. package/src/blocks/e-commerce/category-filters/category-filter-2-filter-panel.tsx +136 -93
  21. package/src/blocks/e-commerce/category-filters/category-filter-2.test.tsx +513 -0
  22. package/src/blocks/e-commerce/category-filters/category-filter-2.tsx +728 -148
  23. package/src/blocks/e-commerce/checkout-forms/checkout-confirmation-fulfilment-progress.tsx +14 -8
  24. package/src/blocks/e-commerce/checkout-forms/checkout-confirmation.test.tsx +136 -0
  25. package/src/blocks/e-commerce/checkout-forms/checkout-confirmation.tsx +145 -99
  26. package/src/blocks/e-commerce/checkout-forms/checkout-form-1-order-summary.tsx +215 -102
  27. package/src/blocks/e-commerce/checkout-forms/checkout-form-1-payment-step.tsx +6 -2
  28. package/src/blocks/e-commerce/checkout-forms/checkout-form-1-shipping-step.tsx +51 -2
  29. package/src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx +216 -0
  30. package/src/blocks/e-commerce/checkout-forms/checkout-form-1.tsx +114 -11
  31. package/src/blocks/e-commerce/navigation/back-to-top.test.tsx +27 -0
  32. package/src/blocks/e-commerce/navigation/back-to-top.tsx +71 -0
  33. package/src/blocks/e-commerce/navigation/breadcrumb.test.tsx +174 -0
  34. package/src/blocks/e-commerce/navigation/breadcrumb.tsx +130 -0
  35. package/src/blocks/e-commerce/navigation/mobile-bottom-nav.test.tsx +74 -0
  36. package/src/blocks/e-commerce/navigation/mobile-bottom-nav.tsx +78 -0
  37. package/src/blocks/e-commerce/navigation/mobile-category-drawer.test.tsx +42 -2
  38. package/src/blocks/e-commerce/navigation/mobile-category-drawer.tsx +10 -8
  39. package/src/blocks/e-commerce/navigation/skip-to-content.test.tsx +35 -0
  40. package/src/blocks/e-commerce/navigation/skip-to-content.tsx +37 -0
  41. package/src/blocks/e-commerce/product-categories/product-category-2.test.tsx +51 -0
  42. package/src/blocks/e-commerce/product-categories/product-category-2.tsx +56 -36
  43. package/src/blocks/e-commerce/product-list/product-card-1.test.tsx +88 -0
  44. package/src/blocks/e-commerce/product-list/product-card-1.tsx +141 -80
  45. package/src/blocks/e-commerce/product-list/product-showcase-1.test.tsx +78 -0
  46. package/src/blocks/e-commerce/product-list/product-showcase-1.tsx +277 -0
  47. package/src/blocks/e-commerce/product-overview/product-overview-1.test.tsx +182 -0
  48. package/src/blocks/e-commerce/product-overview/product-overview-1.tsx +298 -129
  49. package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.test.tsx +229 -0
  50. package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.tsx +313 -110
  51. package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.test.tsx +72 -0
  52. package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.tsx +20 -1
  53. package/src/blocks/marketing/footers/footer-section-1.test.tsx +117 -0
  54. package/src/blocks/marketing/footers/footer-section-1.tsx +46 -9
  55. package/src/blocks/marketing/navbars/navbar-4-account-menu.test.tsx +38 -0
  56. package/src/blocks/marketing/navbars/navbar-4-account-menu.tsx +30 -14
  57. package/src/blocks/marketing/navbars/navbar-4-cart-sheet.test.tsx +204 -0
  58. package/src/blocks/marketing/navbars/navbar-4-cart-sheet.tsx +144 -21
  59. package/src/blocks/marketing/navbars/navbar-4.test.tsx +233 -0
  60. package/src/blocks/marketing/navbars/navbar-4.tsx +235 -60
  61. package/src/index.ts +56 -0
  62. package/src/lib/cart.test.ts +15 -0
  63. package/src/lib/cart.ts +11 -0
  64. package/src/lib/contracts-curated.test.ts +207 -0
  65. package/src/lib/contracts-server-boundary.test.ts +52 -0
  66. package/src/lib/contracts.ts +234 -6
  67. package/src/lib/money.test.ts +64 -0
  68. package/src/lib/money.ts +65 -0
  69. package/tsup.config.ts +0 -1
  70. package/vitest.config.ts +9 -1
package/dist/index.d.ts CHANGED
@@ -5,10 +5,10 @@ import { ReactNode, JSX } from 'react';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import { Avatar as Avatar$1 } from 'radix-ui';
7
7
  import { LucideIcon } from 'lucide-react';
8
- import { StoreCategory } from './contracts.js';
9
- export { AccountMenuItem, ButtonSpecProps, CanonMoney, CanonProduct, CardProduct, CartItem, NavCartItem, Navbar4SpecProps, PRODUCT_IMAGE_FALLBACK, ProductCard1SpecProps, Promotion, ShoppingCart4SpecProps, StoreContainer1SpecProps, StoreUser, UtilityLink, accountMenuItemSchema, buttonPropsSchema, cardProductSchema, cartItemSchema, navCartItemSchema, navbar4PropsSchema, paymentMethodSchema, productCard1PropsSchema, promotionSchema, shoppingCart4PropsSchema, storeCategorySchema, storeContainer1PropsSchema, storeUserSchema, utilityLinkSchema } from './contracts.js';
8
+ import { Money, ProductOption, SelectedOption, Image, PaymentMethod } from '@thorprovider/types';
9
+ import { StoreCategory, ProductPresentation } from './contracts.js';
10
+ export { AccountMenuItem, ButtonSpecProps, CanonMoney, CanonProduct, CardProduct, CartItem, CartTotals, NavCartItem, Navbar4SpecProps, PRODUCT_IMAGE_FALLBACK, ProductCard1SpecProps, ProductDetailProductSpec, ProductDetailVariantSpec, ProductOverview1SpecProps, ProductShowcase1SpecProps, Promotion, ShoppingCart4SpecProps, StoreContainer1SpecProps, StoreUser, UtilityLink, accountMenuItemSchema, buttonPropsSchema, cardProductSchema, cartItemSchema, cartTotalsSchema, formatMoney, isAvailableMoney, isCompleteFiniteDecimal, moneySchema, navCartItemSchema, navbar4PropsSchema, paymentMethodSchema, productCard1PropsSchema, productDetailProductSchema, productDetailVariantSchema, productOverview1PropsSchema, productPresentationSchema, productShowcase1PropsSchema, promotionSchema, resolveAbsoluteQuantity, shoppingCart4PropsSchema, storeCategorySchema, storeContainer1PropsSchema, storeUserSchema, utilityLinkSchema } from './contracts.js';
10
11
  import { z } from 'zod';
11
- import { PaymentMethod } from '@thorprovider/types';
12
12
 
13
13
  /**
14
14
  * Merge Tailwind CSS class names safely.
@@ -22,15 +22,15 @@ interface CTA {
22
22
  }
23
23
 
24
24
  declare const badgeVariants: (props?: ({
25
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
25
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
26
26
  } & class_variance_authority_types.ClassProp) | undefined) => string;
27
27
  declare function Badge({ className, variant, asChild, ...props }: react.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
28
28
  asChild?: boolean;
29
29
  }): react.JSX.Element;
30
30
 
31
31
  declare const buttonVariants: (props?: ({
32
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
33
- size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
32
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
33
+ size?: "icon" | "default" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
34
34
  } & class_variance_authority_types.ClassProp) | undefined) => string;
35
35
  declare function Button({ className, variant, size, asChild, ...props }: react.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
36
36
  asChild?: boolean;
@@ -140,7 +140,7 @@ declare function Navbar3({ navLinks, logoText, logoHref, currentPath, signIn, ct
140
140
  interface StoreUser {
141
141
  name: string;
142
142
  email: string;
143
- avatar: string;
143
+ avatar?: string;
144
144
  initials: string;
145
145
  }
146
146
  interface AccountMenuItem {
@@ -151,40 +151,130 @@ interface AccountMenuItem {
151
151
  }
152
152
 
153
153
  interface CartItem {
154
+ /** Backend cart line-item id — the stable identity for update/removal. */
154
155
  id: string;
155
156
  name: string;
156
- variant: string;
157
+ variant?: string;
157
158
  price: number;
158
159
  qty: number;
159
- image: string;
160
+ /** Optional; an absent image is omitted rather than serialized as `""`. */
161
+ image?: string;
162
+ /**
163
+ * Canonical backend line amount. Required for truthful rendering in
164
+ * `canonical` mode; when absent/invalid the line shows the unavailable
165
+ * label rather than a numeric fallback.
166
+ */
167
+ lineTotal?: Money;
160
168
  }
169
+ type CartSheetState = 'idle' | 'pending' | 'error';
161
170
 
162
171
  interface UtilityLink {
163
172
  label: string;
164
173
  href: string;
165
174
  }
166
175
 
176
+ interface LogoAccent {
177
+ /** Trailing segment of `logoText` to render with the accent styling. */
178
+ text: string;
179
+ /** Consumer-supplied classes for the accent span (e.g. a brand color token). */
180
+ className?: string;
181
+ }
167
182
  interface Navbar4Props {
168
183
  storeCategories: StoreCategory[];
169
- shippingNote: string;
184
+ /**
185
+ * Optional note shown in the desktop utility strip. When omitted (or empty)
186
+ * and there are no `utilityLinks`, the strip is not rendered at all, so a
187
+ * block with no optional content paints no empty decorative chrome.
188
+ */
189
+ shippingNote?: string;
170
190
  utilityLinks: UtilityLink[];
171
191
  logoText: string;
172
192
  logoHref?: string;
173
- /** When provided, a mobile-only "Account" link is appended to the utility links. */
193
+ /**
194
+ * Optional accent for a trailing segment of `logoText` (e.g. the "Cuba" in
195
+ * "ElectroCuba"). When omitted, or when `text` is not a trailing segment of
196
+ * `logoText`, the wordmark renders unchanged.
197
+ */
198
+ logoAccent?: LogoAccent;
199
+ /** Account destination for anonymous shoppers on every viewport. */
174
200
  accountHref?: string;
201
+ /**
202
+ * When `false`, no search control is rendered at all — neither the desktop
203
+ * input, the mobile trigger, nor the mobile panel. Defaults to `true` so
204
+ * legacy consumers keep the existing self-contained search. The generated
205
+ * storefront passes `false` while no verified global search contract exists
206
+ * (E2 task 5.4), so no global search is presented as working.
207
+ */
208
+ /**
209
+ * The storefront's current route path. When it matches a destination the link
210
+ * is marked as the current page (accessibly, beyond color alone).
211
+ */
212
+ currentPath?: string;
213
+ showSearch?: boolean;
175
214
  searchQuery?: string;
176
215
  onSearchChange?: (value: string) => void;
177
216
  items?: CartItem[];
217
+ /**
218
+ * Quantity DELTA for a backend cart line-item id. The boundary converts the
219
+ * delta into an absolute quantity against the authoritative current line
220
+ * quantity before mutating the cart.
221
+ */
178
222
  onQtyChange?: (id: string, delta: number) => void;
223
+ /** Remove the backend cart line-item id. */
179
224
  onRemove?: (id: string) => void;
225
+ /** Authoritative backend subtotal for the mini-cart. */
226
+ subtotal?: Money;
227
+ /** Shown when an authoritative subtotal is supplied but absent/malformed. */
228
+ subtotalUnavailableLabel?: string;
229
+ /** Override money formatting (locale, currency). Defaults to `Money.currencyCode`. */
230
+ formatMoney?: (money: Money) => string;
180
231
  user?: StoreUser;
181
232
  accountMenuItems?: AccountMenuItem[];
182
233
  onHelp?: () => void;
183
234
  onSignOut?: () => void;
235
+ accountPending?: boolean;
236
+ accountUnavailable?: boolean;
237
+ onAccountRetry?: () => void;
184
238
  onCheckout?: () => void;
185
239
  onViewCart?: () => void;
240
+ /**
241
+ * Controlled visibility for the cart sheet. When provided, the sheet opens
242
+ * and closes from this value and `onCartOpenChange` instead of internal
243
+ * state, so a host can share one cart surface across the navbar trigger and
244
+ * successful add-to-cart. Omit both to keep the legacy uncontrolled sheet.
245
+ */
246
+ cartOpen?: boolean;
247
+ /** Change handler paired with `cartOpen` for a controlled sheet. */
248
+ onCartOpenChange?: (open: boolean) => void;
249
+ /**
250
+ * Backend-authoritative cart rendering for the sheet. When `true`, line
251
+ * amounts use each item's canonical `lineTotal` Money and never fall back to
252
+ * numeric `price * qty`. Omit for the legacy numeric rendering.
253
+ */
254
+ canonicalCart?: boolean;
255
+ /** Cart read/mutation lifecycle for the sheet. */
256
+ cartState?: CartSheetState;
257
+ /** Message shown when `cartState` is `error`. */
258
+ cartErrorLabel?: string;
259
+ /** Recovery action label for the error state. */
260
+ cartRetryLabel?: string;
261
+ /** Recovery action invoked from the error state. */
262
+ onCartRetry?: () => void;
263
+ /** When `true`, the sheet's checkout action is suppressed (checkout not installed). */
264
+ checkoutUnavailable?: boolean;
265
+ /** When `true`, the sheet's checkout action is disabled (cart not ready). */
266
+ checkoutDisabled?: boolean;
267
+ /** When `true`, the sheet's review action is suppressed (cart view not installed). */
268
+ viewCartUnavailable?: boolean;
269
+ /**
270
+ * Consumer-supplied classes merged onto the outer `<header>` as the final
271
+ * argument, so a semantic surface such as `bg-brand-nav
272
+ * text-brand-nav-foreground` overrides the default `bg-background`. Purely
273
+ * presentational: no layout, structure, or behavior changes.
274
+ */
275
+ className?: string;
186
276
  }
187
- declare function Navbar4({ storeCategories, shippingNote, utilityLinks, logoText, logoHref, accountHref, searchQuery: searchQueryProp, onSearchChange, items: itemsProp, onQtyChange: onQtyChangeProp, onRemove: onRemoveProp, user, accountMenuItems, onHelp, onSignOut, onCheckout, onViewCart, }: Navbar4Props): react.JSX.Element;
277
+ declare function Navbar4({ storeCategories, shippingNote, utilityLinks, logoText, logoHref, logoAccent, accountHref, currentPath, showSearch, searchQuery: searchQueryProp, onSearchChange, items: itemsProp, onQtyChange: onQtyChangeProp, onRemove: onRemoveProp, subtotal, subtotalUnavailableLabel, formatMoney, user, accountMenuItems, onHelp, onSignOut, accountPending, accountUnavailable, onAccountRetry, onCheckout, onViewCart, cartOpen, onCartOpenChange, canonicalCart, cartState, cartErrorLabel, cartRetryLabel, onCartRetry, checkoutUnavailable, checkoutDisabled, viewCartUnavailable, className, }: Navbar4Props): react.JSX.Element;
188
278
 
189
279
  type Banner1Shape = 'bar' | 'pill';
190
280
  interface Banner1Props {
@@ -391,15 +481,39 @@ interface FooterLinkColumn$1 {
391
481
  interface FooterNewsletter {
392
482
  placeholder?: string;
393
483
  buttonLabel: string;
484
+ /**
485
+ * Submit handler. The interactive form (input + submit button) renders only
486
+ * when this is supplied. A newsletter without `onSubmit` renders no form,
487
+ * input, or button — never a fake form.
488
+ */
394
489
  onSubmit?: (email: string) => void;
395
490
  }
491
+ interface BrandAccent {
492
+ /** Trailing segment of `brandName` to render with the accent styling. */
493
+ text: string;
494
+ /** Consumer-supplied classes for the accent span (e.g. a brand color token). */
495
+ className?: string;
496
+ }
396
497
  interface FooterSection1Props {
397
498
  brandName: string;
499
+ /**
500
+ * Optional accent for a trailing segment of `brandName` (e.g. the "Cuba" in
501
+ * "ElectroCuba"). When omitted, or when `text` is not a trailing segment of
502
+ * `brandName`, the brand name renders unchanged.
503
+ */
504
+ brandAccent?: BrandAccent;
398
505
  brandDescription?: string;
399
506
  linkColumns: FooterLinkColumn$1[];
400
507
  newsletter?: FooterNewsletter;
508
+ /**
509
+ * Consumer-supplied classes merged onto the outer `<footer>` as the final
510
+ * argument, so a semantic surface such as `bg-brand-nav
511
+ * text-brand-nav-foreground` overrides the default `bg-secondary`. Purely
512
+ * presentational: no layout, structure, or behavior changes.
513
+ */
514
+ className?: string;
401
515
  }
402
- declare function FooterSection1({ brandName, brandDescription, linkColumns, newsletter, }: FooterSection1Props): react.JSX.Element;
516
+ declare function FooterSection1({ brandName, brandAccent, brandDescription, linkColumns, newsletter, className, }: FooterSection1Props): react.JSX.Element;
403
517
 
404
518
  interface FooterLink {
405
519
  label: string;
@@ -502,15 +616,24 @@ interface Product {
502
616
  image: string;
503
617
  badge?: string;
504
618
  }
619
+ /**
620
+ * A card entry is either the legacy numeric-price product or the canonical
621
+ * `Money`-price presentation. The block renders both without breaking legacy
622
+ * consumers: a numeric `price` keeps the legacy `$` output unchanged, while a
623
+ * canonical `Money` price is formatted in its own currency and locale.
624
+ */
625
+ type ProductCard1Product = Product | ProductPresentation;
505
626
  interface ProductCard1Props {
506
- products: Product[];
627
+ products: ProductCard1Product[];
507
628
  heading?: string;
508
629
  maxItems?: number;
509
- onAddToCart?: (product: Product) => void;
510
- onProductClick?: (product: Product) => void;
630
+ onAddToCart?: (product: ProductCard1Product) => void;
631
+ onProductClick?: (product: ProductCard1Product) => void;
511
632
  addToCartLabel?: string;
633
+ /** Shown when a canonical price is present but unavailable (never `$0`). */
634
+ unavailablePriceLabel?: string;
512
635
  }
513
- declare function ProductCard1({ products, heading, maxItems, onAddToCart, onProductClick, addToCartLabel, }: ProductCard1Props): react.JSX.Element;
636
+ declare function ProductCard1({ products, heading, maxItems, onAddToCart, onProductClick, addToCartLabel, unavailablePriceLabel, }: ProductCard1Props): react.JSX.Element;
514
637
 
515
638
  interface ProductCard2Product {
516
639
  id: string | number;
@@ -573,39 +696,104 @@ interface ProductCard5Props {
573
696
  }
574
697
  declare function ProductCard5({ products, onToggleWishlist, onAddToCart, onQuickView, onCompare, onExport, }: ProductCard5Props): react.JSX.Element;
575
698
 
576
- interface ProductOverview1ProductImage {
577
- id: number;
578
- src: string;
579
- alt: string;
580
- }
581
- interface ProductOverview1ProductColor {
582
- name: string;
583
- value: string;
699
+ interface ProductShowcase1Props {
700
+ products: ProductPresentation[];
701
+ heading?: string;
702
+ description?: string;
703
+ pageSize?: number;
704
+ prevLabel?: string;
705
+ nextLabel?: string;
706
+ /** Label for the current-page status, e.g. "Página". */
707
+ pageLabel?: string;
708
+ unavailablePriceLabel?: string;
709
+ emptyLabel?: string;
710
+ addToCartLabel?: string;
711
+ onAddToCart?: (product: ProductPresentation) => void;
712
+ onProductClick?: (product: ProductPresentation) => void;
584
713
  }
585
- interface ProductOverview1Product {
714
+ /**
715
+ * Combined grid-and-carousel product presentation: fixed-size grid pages
716
+ * navigated manually (prev/next) with a visible current-page indication. There
717
+ * is no autoplay, no auto-advance, and no infinite loop. Controls are real
718
+ * buttons (keyboard operable and visible at every breakpoint); touch swipe is an
719
+ * addition, never the only way to navigate. Below-fold images are lazy.
720
+ *
721
+ * Data access lives in the host: this block only renders the props it receives
722
+ * and reports interactions through callbacks (no backend/router/measurement
723
+ * imports).
724
+ */
725
+ declare function ProductShowcase1({ products, heading, description, pageSize, prevLabel, nextLabel, pageLabel, unavailablePriceLabel, emptyLabel, addToCartLabel, onAddToCart, onProductClick, }: ProductShowcase1Props): react.JSX.Element;
726
+
727
+ /**
728
+ * Canonical product-detail projection.
729
+ *
730
+ * The block consumes the canonical `@thorprovider/types` shapes (`Money`,
731
+ * `ProductOption`, `SelectedOption`, `Image`) so adapter output maps without a
732
+ * second, drifting product type. The only deviation is `price`: the canon marks
733
+ * it required, but a missing/unresolved backend price is a real, distinct state
734
+ * that must disable purchase — so the projection allows `price` to be absent
735
+ * and the block treats absence as "unavailable", never as zero.
736
+ */
737
+ interface ProductDetailVariant {
586
738
  id: string;
587
- brand: string;
588
- name: string;
589
- description: string;
590
- price: number;
591
- currency: string;
592
- rating: number;
593
- images: ProductOverview1ProductImage[];
594
- sizes: number[];
595
- colors: ProductOverview1ProductColor[];
739
+ title: string;
740
+ sku?: string;
741
+ availableForSale: boolean;
742
+ selectedOptions: SelectedOption[];
743
+ /** Canonical Money; omit/null when the backend has no resolved price. */
744
+ price?: Money | null;
745
+ compareAtPrice?: Money;
746
+ image?: Image;
747
+ }
748
+ interface ProductDetailProduct {
749
+ id: string;
750
+ handle?: string;
751
+ title: string;
752
+ description?: string;
753
+ vendor?: string;
754
+ options: ProductOption[];
755
+ variants: ProductDetailVariant[];
756
+ images: Image[];
757
+ featuredImage?: Image;
758
+ }
759
+ interface ProductOverview1Rating {
760
+ value: number;
761
+ count: number;
596
762
  }
597
763
  interface ProductOverview1Props {
598
- product: ProductOverview1Product;
764
+ product: ProductDetailProduct;
765
+ /** Controlled selection: the backend variant id, or null/undefined when nothing is explicitly selected. */
766
+ selectedVariantId?: string | null;
767
+ onSelectVariant?: (variantId: string) => void;
768
+ /** Controlled quantity for the add-to-cart action; defaults to 1 when omitted. */
769
+ quantity?: number;
770
+ onQuantityChange?: (quantity: number) => void;
771
+ /** Add-to-cart identity is the selected backend variant id, with the requested quantity. */
772
+ onAddToCart?: (variantId: string, quantity: number) => void;
773
+ isWishlisted?: boolean;
774
+ onToggleWishlist?: (variantId: string, isWishlisted: boolean) => void;
775
+ /** Rendered only when the backend supplies it. */
776
+ rating?: ProductOverview1Rating;
777
+ /** Rendered only when the backend supplies it. */
778
+ deliveryEstimate?: string;
779
+ /** Rendered only when the backend supplies it. */
780
+ shipping?: Money;
781
+ formatPrice?: (money: Money) => string;
599
782
  sizesLabel?: string;
600
- colorLabel?: string;
783
+ variantLabel?: string;
601
784
  reviewsLabel?: string;
602
785
  addToCartLabel?: string;
786
+ outOfStockLabel?: string;
787
+ unavailablePriceLabel?: string;
788
+ selectVariantLabel?: string;
789
+ quantityLabel?: string;
790
+ deliveryEstimateLabel?: string;
791
+ shippingLabel?: string;
603
792
  removeFromWishlistLabel?: string;
604
793
  addToWishlistLabel?: string;
605
- onAddToCart?: (product: ProductOverview1Product) => void;
606
- onToggleWishlist?: (product: ProductOverview1Product, isWishlisted: boolean) => void;
794
+ imageFallback?: string;
607
795
  }
608
- declare function ProductOverview1({ product, sizesLabel, colorLabel, reviewsLabel, addToCartLabel, removeFromWishlistLabel, addToWishlistLabel, onAddToCart, onToggleWishlist, }: ProductOverview1Props): react.JSX.Element;
796
+ declare function ProductOverview1({ product, selectedVariantId, onSelectVariant, quantity, onQuantityChange, onAddToCart, isWishlisted, onToggleWishlist, rating, deliveryEstimate, shipping, formatPrice, sizesLabel, variantLabel, reviewsLabel, addToCartLabel, outOfStockLabel, unavailablePriceLabel, selectVariantLabel, quantityLabel, deliveryEstimateLabel, shippingLabel, removeFromWishlistLabel, addToWishlistLabel, imageFallback, }: ProductOverview1Props): react.JSX.Element;
609
797
 
610
798
  interface ProductOverview2ProductImage {
611
799
  src: string;
@@ -855,7 +1043,12 @@ interface ProductCategory2Category {
855
1043
  handle?: string;
856
1044
  name: string;
857
1045
  description: string;
858
- itemCount: number;
1046
+ /**
1047
+ * Number of items in the category. Optional: when omitted, or when it is not
1048
+ * a finite non-negative number, no count is rendered — an unknown projection
1049
+ * must not be shown as a fabricated `0`. A real `0` is preserved.
1050
+ */
1051
+ itemCount?: number;
859
1052
  image: string;
860
1053
  trending: boolean;
861
1054
  }
@@ -937,17 +1130,17 @@ declare const collectionItemSchema: z.ZodObject<{
937
1130
  image: z.ZodOptional<z.ZodString>;
938
1131
  href: z.ZodOptional<z.ZodString>;
939
1132
  }, "strip", z.ZodTypeAny, {
940
- label: string;
941
1133
  id: string;
1134
+ label: string;
942
1135
  image?: string | undefined;
943
- href?: string | undefined;
944
1136
  description?: string | undefined;
1137
+ href?: string | undefined;
945
1138
  }, {
946
- label: string;
947
1139
  id: string;
1140
+ label: string;
948
1141
  image?: string | undefined;
949
- href?: string | undefined;
950
1142
  description?: string | undefined;
1143
+ href?: string | undefined;
951
1144
  }>;
952
1145
  type CollectionItem = z.infer<typeof collectionItemSchema>;
953
1146
 
@@ -991,17 +1184,17 @@ declare const megaMenuPropsSchema: z.ZodObject<{
991
1184
  image: z.ZodOptional<z.ZodString>;
992
1185
  href: z.ZodOptional<z.ZodString>;
993
1186
  }, "strip", z.ZodTypeAny, {
994
- label: string;
995
1187
  id: string;
1188
+ label: string;
996
1189
  image?: string | undefined;
997
- href?: string | undefined;
998
1190
  description?: string | undefined;
1191
+ href?: string | undefined;
999
1192
  }, {
1000
- label: string;
1001
1193
  id: string;
1194
+ label: string;
1002
1195
  image?: string | undefined;
1003
- href?: string | undefined;
1004
1196
  description?: string | undefined;
1197
+ href?: string | undefined;
1005
1198
  }>, "many">;
1006
1199
  onNavigate: z.ZodOptional<z.ZodType<() => void, z.ZodTypeDef, () => void>>;
1007
1200
  categoryColumnTitle: z.ZodOptional<z.ZodString>;
@@ -1021,11 +1214,11 @@ declare const megaMenuPropsSchema: z.ZodObject<{
1021
1214
  children?: MenuItem[];
1022
1215
  }[];
1023
1216
  collections: {
1024
- label: string;
1025
1217
  id: string;
1218
+ label: string;
1026
1219
  image?: string | undefined;
1027
- href?: string | undefined;
1028
1220
  description?: string | undefined;
1221
+ href?: string | undefined;
1029
1222
  }[];
1030
1223
  onNavigate?: (() => void) | undefined;
1031
1224
  categoryColumnTitle?: string | undefined;
@@ -1045,11 +1238,11 @@ declare const megaMenuPropsSchema: z.ZodObject<{
1045
1238
  children?: MenuItem[];
1046
1239
  }[];
1047
1240
  collections: {
1048
- label: string;
1049
1241
  id: string;
1242
+ label: string;
1050
1243
  image?: string | undefined;
1051
- href?: string | undefined;
1052
1244
  description?: string | undefined;
1245
+ href?: string | undefined;
1053
1246
  }[];
1054
1247
  onNavigate?: (() => void) | undefined;
1055
1248
  categoryColumnTitle?: string | undefined;
@@ -1101,17 +1294,17 @@ declare const mobileCategoryDrawerPropsSchema: z.ZodObject<{
1101
1294
  image: z.ZodOptional<z.ZodString>;
1102
1295
  href: z.ZodOptional<z.ZodString>;
1103
1296
  }, "strip", z.ZodTypeAny, {
1104
- label: string;
1105
1297
  id: string;
1298
+ label: string;
1106
1299
  image?: string | undefined;
1107
- href?: string | undefined;
1108
1300
  description?: string | undefined;
1301
+ href?: string | undefined;
1109
1302
  }, {
1110
- label: string;
1111
1303
  id: string;
1304
+ label: string;
1112
1305
  image?: string | undefined;
1113
- href?: string | undefined;
1114
1306
  description?: string | undefined;
1307
+ href?: string | undefined;
1115
1308
  }>, "many">;
1116
1309
  open: z.ZodBoolean;
1117
1310
  onClose: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodVoid>;
@@ -1135,11 +1328,11 @@ declare const mobileCategoryDrawerPropsSchema: z.ZodObject<{
1135
1328
  children?: MenuItem[];
1136
1329
  }[];
1137
1330
  collections: {
1138
- label: string;
1139
1331
  id: string;
1332
+ label: string;
1140
1333
  image?: string | undefined;
1141
- href?: string | undefined;
1142
1334
  description?: string | undefined;
1335
+ href?: string | undefined;
1143
1336
  }[];
1144
1337
  onClose: (...args: unknown[]) => void;
1145
1338
  collectionsTitle?: string | undefined;
@@ -1162,11 +1355,11 @@ declare const mobileCategoryDrawerPropsSchema: z.ZodObject<{
1162
1355
  children?: MenuItem[];
1163
1356
  }[];
1164
1357
  collections: {
1165
- label: string;
1166
1358
  id: string;
1359
+ label: string;
1167
1360
  image?: string | undefined;
1168
- href?: string | undefined;
1169
1361
  description?: string | undefined;
1362
+ href?: string | undefined;
1170
1363
  }[];
1171
1364
  onClose: (...args: unknown[]) => void;
1172
1365
  collectionsTitle?: string | undefined;
@@ -1190,11 +1383,11 @@ declare const categoryIconPropsSchema: z.ZodObject<{
1190
1383
  name: z.ZodOptional<z.ZodEnum<["wrench", "bolt", "tree", "refrigerator", "wind", "droplet", "zap", "hard-hat", "car", "utensils", "boxes", "sofa", "shield", "sun", "chef-hat", "tractor", "store", "home"]>>;
1191
1384
  className: z.ZodOptional<z.ZodString>;
1192
1385
  }, "strip", z.ZodTypeAny, {
1193
- className?: string | undefined;
1194
1386
  name?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1195
- }, {
1196
1387
  className?: string | undefined;
1388
+ }, {
1197
1389
  name?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1390
+ className?: string | undefined;
1198
1391
  }>;
1199
1392
  type CategoryIconProps = z.infer<typeof categoryIconPropsSchema>;
1200
1393
  /**
@@ -1207,6 +1400,187 @@ type CategoryIconProps = z.infer<typeof categoryIconPropsSchema>;
1207
1400
  */
1208
1401
  declare function CategoryIcon({ name, className }: CategoryIconProps): react.JSX.Element | null;
1209
1402
 
1403
+ declare const breadcrumbItemSchema: z.ZodObject<{
1404
+ label: z.ZodString;
1405
+ href: z.ZodOptional<z.ZodString>;
1406
+ }, "strip", z.ZodTypeAny, {
1407
+ label: string;
1408
+ href?: string | undefined;
1409
+ }, {
1410
+ label: string;
1411
+ href?: string | undefined;
1412
+ }>;
1413
+ type BreadcrumbItemData = z.infer<typeof breadcrumbItemSchema>;
1414
+ declare const breadcrumbPropsSchema: z.ZodObject<{
1415
+ items: z.ZodArray<z.ZodObject<{
1416
+ label: z.ZodString;
1417
+ href: z.ZodOptional<z.ZodString>;
1418
+ }, "strip", z.ZodTypeAny, {
1419
+ label: string;
1420
+ href?: string | undefined;
1421
+ }, {
1422
+ label: string;
1423
+ href?: string | undefined;
1424
+ }>, "many">;
1425
+ maxItems: z.ZodOptional<z.ZodNumber>;
1426
+ ariaLabel: z.ZodOptional<z.ZodString>;
1427
+ backLabel: z.ZodOptional<z.ZodString>;
1428
+ className: z.ZodOptional<z.ZodString>;
1429
+ }, "strip", z.ZodTypeAny, {
1430
+ items: {
1431
+ label: string;
1432
+ href?: string | undefined;
1433
+ }[];
1434
+ className?: string | undefined;
1435
+ maxItems?: number | undefined;
1436
+ ariaLabel?: string | undefined;
1437
+ backLabel?: string | undefined;
1438
+ }, {
1439
+ items: {
1440
+ label: string;
1441
+ href?: string | undefined;
1442
+ }[];
1443
+ className?: string | undefined;
1444
+ maxItems?: number | undefined;
1445
+ ariaLabel?: string | undefined;
1446
+ backLabel?: string | undefined;
1447
+ }>;
1448
+ type BreadcrumbProps = z.infer<typeof breadcrumbPropsSchema>;
1449
+ /**
1450
+ * Breadcrumb trail for a real navigation path (Home → … → current).
1451
+ *
1452
+ * Framework-agnostic and prop-driven: plain anchors (no router) and the shared
1453
+ * shadcn breadcrumb primitives. The last item is the current page and is never
1454
+ * a link (`aria-current="page"`); earlier items link only when an `href` is
1455
+ * given. Long labels truncate, and trails longer than `maxItems` collapse the
1456
+ * intermediate levels behind an ellipsis. On mobile the full list is replaced
1457
+ * by a single back link to the parent, so a wide trail never overflows.
1458
+ *
1459
+ * Renders nothing when there are no labelled items.
1460
+ */
1461
+ declare function Breadcrumb({ items, maxItems, ariaLabel, backLabel, className, }: BreadcrumbProps): react.JSX.Element | null;
1462
+
1463
+ declare const skipToContentPropsSchema: z.ZodObject<{
1464
+ targetId: z.ZodString;
1465
+ label: z.ZodOptional<z.ZodString>;
1466
+ className: z.ZodOptional<z.ZodString>;
1467
+ }, "strip", z.ZodTypeAny, {
1468
+ targetId: string;
1469
+ label?: string | undefined;
1470
+ className?: string | undefined;
1471
+ }, {
1472
+ targetId: string;
1473
+ label?: string | undefined;
1474
+ className?: string | undefined;
1475
+ }>;
1476
+ type SkipToContentProps = z.infer<typeof skipToContentPropsSchema>;
1477
+ /**
1478
+ * Skip-to-content link (WCAG 2.4.1 Bypass Blocks).
1479
+ *
1480
+ * Framework-agnostic and prop-driven: a plain anchor to the main content id,
1481
+ * visually hidden until it receives focus, then pinned at the top-left with
1482
+ * visible contrast. The target element is responsible for carrying the id (and
1483
+ * being focusable); this block only renders the bypass affordance.
1484
+ */
1485
+ declare function SkipToContent({ targetId, label, className, }: SkipToContentProps): react.JSX.Element;
1486
+
1487
+ declare const backToTopPropsSchema: z.ZodObject<{
1488
+ threshold: z.ZodOptional<z.ZodNumber>;
1489
+ label: z.ZodOptional<z.ZodString>;
1490
+ className: z.ZodOptional<z.ZodString>;
1491
+ }, "strip", z.ZodTypeAny, {
1492
+ threshold?: number | undefined;
1493
+ label?: string | undefined;
1494
+ className?: string | undefined;
1495
+ }, {
1496
+ threshold?: number | undefined;
1497
+ label?: string | undefined;
1498
+ className?: string | undefined;
1499
+ }>;
1500
+ type BackToTopProps = z.infer<typeof backToTopPropsSchema>;
1501
+ /**
1502
+ * Resolve the scroll behavior for a back-to-top activation. Pure so it can be
1503
+ * unit-tested without a DOM: reduced motion yields an instant jump.
1504
+ */
1505
+ declare function resolveScrollBehavior(prefersReducedMotion: boolean): 'auto' | 'smooth';
1506
+ /**
1507
+ * Back-to-top control that appears once the page is scrolled past `threshold`
1508
+ * and returns the viewport to the top. Honors `prefers-reduced-motion` (instant
1509
+ * jump instead of a smooth scroll). Framework-agnostic; icon-only with an
1510
+ * accessible label.
1511
+ */
1512
+ declare function BackToTop({ threshold, label, className, }: BackToTopProps): react.JSX.Element | null;
1513
+
1514
+ declare const mobileBottomNavItemSchema: z.ZodObject<{
1515
+ id: z.ZodOptional<z.ZodString>;
1516
+ label: z.ZodString;
1517
+ href: z.ZodString;
1518
+ icon: z.ZodOptional<z.ZodEnum<["wrench", "bolt", "tree", "refrigerator", "wind", "droplet", "zap", "hard-hat", "car", "utensils", "boxes", "sofa", "shield", "sun", "chef-hat", "tractor", "store", "home"]>>;
1519
+ }, "strip", z.ZodTypeAny, {
1520
+ label: string;
1521
+ href: string;
1522
+ id?: string | undefined;
1523
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1524
+ }, {
1525
+ label: string;
1526
+ href: string;
1527
+ id?: string | undefined;
1528
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1529
+ }>;
1530
+ type MobileBottomNavItem = z.infer<typeof mobileBottomNavItemSchema>;
1531
+ declare const mobileBottomNavPropsSchema: z.ZodObject<{
1532
+ items: z.ZodArray<z.ZodObject<{
1533
+ id: z.ZodOptional<z.ZodString>;
1534
+ label: z.ZodString;
1535
+ href: z.ZodString;
1536
+ icon: z.ZodOptional<z.ZodEnum<["wrench", "bolt", "tree", "refrigerator", "wind", "droplet", "zap", "hard-hat", "car", "utensils", "boxes", "sofa", "shield", "sun", "chef-hat", "tractor", "store", "home"]>>;
1537
+ }, "strip", z.ZodTypeAny, {
1538
+ label: string;
1539
+ href: string;
1540
+ id?: string | undefined;
1541
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1542
+ }, {
1543
+ label: string;
1544
+ href: string;
1545
+ id?: string | undefined;
1546
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1547
+ }>, "many">;
1548
+ currentHref: z.ZodOptional<z.ZodString>;
1549
+ ariaLabel: z.ZodOptional<z.ZodString>;
1550
+ className: z.ZodOptional<z.ZodString>;
1551
+ }, "strip", z.ZodTypeAny, {
1552
+ items: {
1553
+ label: string;
1554
+ href: string;
1555
+ id?: string | undefined;
1556
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1557
+ }[];
1558
+ className?: string | undefined;
1559
+ ariaLabel?: string | undefined;
1560
+ currentHref?: string | undefined;
1561
+ }, {
1562
+ items: {
1563
+ label: string;
1564
+ href: string;
1565
+ id?: string | undefined;
1566
+ icon?: "tree" | "home" | "wrench" | "bolt" | "refrigerator" | "wind" | "droplet" | "zap" | "hard-hat" | "car" | "utensils" | "boxes" | "sofa" | "shield" | "sun" | "chef-hat" | "tractor" | "store" | undefined;
1567
+ }[];
1568
+ className?: string | undefined;
1569
+ ariaLabel?: string | undefined;
1570
+ currentHref?: string | undefined;
1571
+ }>;
1572
+ type MobileBottomNavProps = z.infer<typeof mobileBottomNavPropsSchema>;
1573
+ /**
1574
+ * Mobile-only bottom navigation offering the primary destinations.
1575
+ *
1576
+ * Framework-agnostic and prop-driven: plain anchors (no router). Hidden at
1577
+ * `md` and up; offsets the iOS home indicator via `env(safe-area-inset-bottom)`;
1578
+ * each destination meets the 44px minimum touch target. The current
1579
+ * destination is marked with `aria-current="page"` and a non-colour cue (weight
1580
+ * + indicator bar), never colour alone.
1581
+ */
1582
+ declare function MobileBottomNav({ items, currentHref, ariaLabel, className, }: MobileBottomNavProps): react.JSX.Element | null;
1583
+
1210
1584
  interface CategoryFilter1Category {
1211
1585
  id: string;
1212
1586
  name: string;
@@ -1242,12 +1616,24 @@ interface FilterProduct {
1242
1616
  id: string;
1243
1617
  name: string;
1244
1618
  price: string;
1245
- image: string;
1619
+ /** Optional: an absent image is omitted so the block never renders `src=""`. */
1620
+ image?: string;
1621
+ /**
1622
+ * Optional product-detail link. When present the card renders as a real
1623
+ * `<a href>` (keyboard focus, middle-click, crawlers); when absent the block
1624
+ * falls back to the `onProductClick` path. The href is produced by the
1625
+ * presentation layer — the block never builds a route.
1626
+ */
1627
+ href?: string;
1246
1628
  }
1247
1629
  interface CategoryFilter2Category {
1248
1630
  id: string;
1249
1631
  label: string;
1250
1632
  }
1633
+ interface CategoryFilter2Collection {
1634
+ id: string;
1635
+ label: string;
1636
+ }
1251
1637
  interface CategoryFilter2Color {
1252
1638
  id: string;
1253
1639
  color: string;
@@ -1263,19 +1649,99 @@ interface CategoryFilter2SortOption {
1263
1649
  }
1264
1650
  interface CategoryFilter2Filters {
1265
1651
  categories: string[];
1652
+ /** Collections requested by the `category-filters` feature (E2). */
1653
+ collections?: string[];
1266
1654
  priceRange: number[];
1267
1655
  size: string | null;
1268
1656
  color: string | null;
1269
1657
  }
1658
+ /**
1659
+ * A typed catalog-query error the listing renders for repair. It is a structural
1660
+ * mirror of the runtime boundary error (`CatalogQueryError`/`CatalogQueryFailure`):
1661
+ * `fields` names the exact raw parameters to remove and `feature` is present only
1662
+ * for `unmounted-capability`. The block never builds a host URL — it emits the
1663
+ * fields through `onRepair` (E2 task 4.5).
1664
+ */
1665
+ interface CategoryFilter2QueryError {
1666
+ code: 'invalid-query' | 'unsupported-query' | 'unmounted-capability';
1667
+ /** Exact raw URL parameter names that must be removed to repair the query. */
1668
+ fields: string[];
1669
+ message?: string;
1670
+ feature?: 'catalog-search' | 'category-filters';
1671
+ }
1672
+ /**
1673
+ * The observable listing status. The host derives it from the URL boundary and
1674
+ * the provider outcome (`mapCatalogOutcomeToStatus`) and passes it down; the
1675
+ * block only renders it. `loading` is in flight; `ready` shows products; `empty`
1676
+ * is a valid zero-result query; `invalid-query`/`unsupported-query`/
1677
+ * `unmounted-capability` are typed repair states; `error` is a query/network
1678
+ * failure with retry. Distinct states stay distinct — a valid empty result is
1679
+ * never shown as an error and a raw failure is never swallowed as empty.
1680
+ */
1681
+ type CategoryFilter2Status = {
1682
+ state: 'loading';
1683
+ } | {
1684
+ state: 'ready';
1685
+ } | {
1686
+ state: 'empty';
1687
+ } | {
1688
+ state: 'invalid-query';
1689
+ error: CategoryFilter2QueryError;
1690
+ } | {
1691
+ state: 'unsupported-query';
1692
+ error: CategoryFilter2QueryError;
1693
+ } | {
1694
+ state: 'unmounted-capability';
1695
+ error: CategoryFilter2QueryError;
1696
+ } | {
1697
+ state: 'error';
1698
+ message?: string;
1699
+ };
1700
+ /** The kind of canonical filter an active chip represents. */
1701
+ type CategoryFilter2ActiveFilterKind = 'text' | 'category' | 'collection' | 'price' | 'attribute';
1702
+ /**
1703
+ * A removable active-filter chip. Built only from the actual canonical query
1704
+ * (never from claimed provider filtering): `params` are the raw URL parameter
1705
+ * names carrying the filter and `value` is the specific list value to drop.
1706
+ */
1707
+ interface CategoryFilter2ActiveFilter {
1708
+ /** Stable identity for React keys and removal callbacks. */
1709
+ id: string;
1710
+ kind: CategoryFilter2ActiveFilterKind;
1711
+ /** Human-readable label shown on the chip. */
1712
+ label: string;
1713
+ /** Raw URL parameter names that carry this filter. */
1714
+ params: string[];
1715
+ /** The specific list value this chip removes; absent for scalar filters. */
1716
+ value?: string;
1717
+ }
1270
1718
  interface CategoryFilter2Props {
1271
1719
  products: FilterProduct[];
1272
1720
  categories?: CategoryFilter2Category[];
1721
+ collections?: CategoryFilter2Collection[];
1273
1722
  sizes?: string[];
1274
1723
  colors?: CategoryFilter2Color[];
1724
+ /**
1725
+ * Real backend-provided price range only. When absent the price control is
1726
+ * omitted; the block never falls back to a fabricated `0..1000` default
1727
+ * (E2 design Decision 8 / spec "Price controls require real price metadata").
1728
+ */
1275
1729
  priceRange?: CategoryFilter2PriceRange;
1276
1730
  viewOptions?: (number | string)[];
1731
+ /** Adapter-advertised sort options only. When absent/empty no sort control is rendered. */
1277
1732
  sortOptions?: CategoryFilter2SortOption[];
1278
1733
  pagination?: (number | string)[];
1734
+ searchValue?: string;
1735
+ selectedCategories?: string[];
1736
+ selectedCollections?: string[];
1737
+ selectedPriceRange?: number[];
1738
+ selectedSort?: string;
1739
+ selectedPage?: number | string;
1740
+ selectedPageSize?: number | string;
1741
+ showSearch?: boolean;
1742
+ showFilters?: boolean;
1743
+ showPrice?: boolean;
1744
+ showSort?: boolean;
1279
1745
  filtersTitle?: string;
1280
1746
  selectedText?: string;
1281
1747
  clearAllLabel?: string;
@@ -1283,6 +1749,7 @@ interface CategoryFilter2Props {
1283
1749
  minLabel?: string;
1284
1750
  maxLabel?: string;
1285
1751
  categoriesTitle?: string;
1752
+ collectionsTitle?: string;
1286
1753
  sizesTitle?: string;
1287
1754
  colorsTitle?: string;
1288
1755
  viewLabel?: string;
@@ -1290,13 +1757,72 @@ interface CategoryFilter2Props {
1290
1757
  sortPlaceholder?: string;
1291
1758
  productsTitle?: string;
1292
1759
  currentLabel?: string;
1760
+ searchLabel?: string;
1761
+ searchPlaceholder?: string;
1293
1762
  onProductClick?: (product: FilterProduct) => void;
1294
1763
  onPageChange?: (page: number | string) => void;
1295
1764
  onViewChange?: (view: number | string) => void;
1765
+ onPageSizeChange?: (pageSize: number | string) => void;
1296
1766
  onSortChange?: (sort: string) => void;
1297
1767
  onFilterChange?: (filters: CategoryFilter2Filters) => void;
1768
+ onSearchChange?: (text: string) => void;
1769
+ /** Observable listing status. Defaults to `ready` so legacy consumers are unchanged. */
1770
+ status?: CategoryFilter2Status;
1771
+ /** Removable active-filter chips built from the canonical query. */
1772
+ activeFilters?: CategoryFilter2ActiveFilter[];
1773
+ loadingLabel?: string;
1774
+ emptyTitle?: string;
1775
+ emptyDescription?: string;
1776
+ clearFiltersLabel?: string;
1777
+ invalidQueryTitle?: string;
1778
+ unsupportedQueryTitle?: string;
1779
+ unmountedCapabilityTitle?: string;
1780
+ errorTitle?: string;
1781
+ errorDescription?: string;
1782
+ repairLabel?: string;
1783
+ retryLabel?: string;
1784
+ activeFiltersTitle?: string;
1785
+ removeFilterLabel?: string;
1786
+ /** Empty-state clear: drops the active filters but never base scope/sort/pageSize. */
1787
+ onClearFilters?: () => void;
1788
+ /** Invalid/unsupported/unmounted repair: receives the exact bad fields to remove. */
1789
+ onRepair?: (remove: string[]) => void;
1790
+ /** Query/network failure retry: preserves the current query/input. */
1791
+ onRetry?: () => void;
1792
+ /** Removes a single active-filter chip. */
1793
+ onRemoveFilter?: (filter: CategoryFilter2ActiveFilter) => void;
1794
+ }
1795
+ interface CategoryFilter2StatusViewProps {
1796
+ status: CategoryFilter2Status;
1797
+ activeFilters?: CategoryFilter2ActiveFilter[];
1798
+ activeFiltersTitle?: string;
1799
+ removeFilterLabel?: string;
1800
+ loadingLabel?: string;
1801
+ emptyTitle?: string;
1802
+ emptyDescription?: string;
1803
+ clearFiltersLabel?: string;
1804
+ invalidQueryTitle?: string;
1805
+ unsupportedQueryTitle?: string;
1806
+ unmountedCapabilityTitle?: string;
1807
+ errorTitle?: string;
1808
+ errorDescription?: string;
1809
+ repairLabel?: string;
1810
+ retryLabel?: string;
1811
+ onClearFilters?: () => void;
1812
+ onRepair?: (remove: string[]) => void;
1813
+ onRetry?: () => void;
1814
+ onRemoveFilter?: (filter: CategoryFilter2ActiveFilter) => void;
1298
1815
  }
1299
- declare function CategoryFilter2({ products, categories, sizes, colors, priceRange: priceRangeConfig, viewOptions, sortOptions, pagination, filtersTitle, selectedText, clearAllLabel, priceRangeTitle, minLabel, maxLabel, categoriesTitle, sizesTitle, colorsTitle, viewLabel, viewPlaceholder, sortPlaceholder, productsTitle, currentLabel, onProductClick, onPageChange, onViewChange, onSortChange, onFilterChange, }: CategoryFilter2Props): react.JSX.Element;
1816
+ /**
1817
+ * Hooks-free presentation of the observable listing states and the removable
1818
+ * active-filter chips (E2 task 4.5). Kept separate from `CategoryFilter2` so the
1819
+ * interaction contract (clear / repair / retry / chip removal) is testable by
1820
+ * invoking the rendered handlers without a DOM (this package's tests render with
1821
+ * `react-dom/server`). It renders no products and performs no fetch — it only
1822
+ * emits the host callbacks. When `ready` with no chips it renders nothing.
1823
+ */
1824
+ declare function CategoryFilter2StatusView({ status, activeFilters, activeFiltersTitle, removeFilterLabel, loadingLabel, emptyTitle, emptyDescription, clearFiltersLabel, invalidQueryTitle, unsupportedQueryTitle, unmountedCapabilityTitle, errorTitle, errorDescription, repairLabel, retryLabel, onClearFilters, onRepair, onRetry, onRemoveFilter, }: CategoryFilter2StatusViewProps): react.JSX.Element | null;
1825
+ declare function CategoryFilter2({ products, categories, collections, sizes, colors, priceRange: priceRangeConfig, viewOptions, sortOptions, pagination, searchValue, selectedCategories, selectedCollections, selectedPriceRange, selectedSort, selectedPage, selectedPageSize, showSearch, showFilters, showPrice, showSort, filtersTitle, selectedText, clearAllLabel, priceRangeTitle, minLabel, maxLabel, categoriesTitle, collectionsTitle, sizesTitle, colorsTitle, viewLabel, viewPlaceholder, sortPlaceholder, productsTitle, currentLabel, searchLabel, searchPlaceholder, onProductClick, onPageChange, onViewChange, onPageSizeChange, onSortChange, onFilterChange, onSearchChange, status, activeFilters, loadingLabel, emptyTitle, emptyDescription, clearFiltersLabel, invalidQueryTitle, unsupportedQueryTitle, unmountedCapabilityTitle, errorTitle, errorDescription, repairLabel, retryLabel, activeFiltersTitle, removeFilterLabel, onClearFilters, onRepair, onRetry, onRemoveFilter, }: CategoryFilter2Props): react.JSX.Element;
1300
1826
 
1301
1827
  interface CategoryFilter4SortOption {
1302
1828
  value: string;
@@ -1465,13 +1991,27 @@ interface ShoppingCart2Props {
1465
1991
  declare function ShoppingCart2({ items, recommendations, taxRate, shippingCost, freeShippingThreshold, validatePromo, titleLabel, itemsCountLabel, cartItemsLabel, orderSummaryLabel, subtotalLabel, savingsLabel, shippingLabel, freeShippingLabel, taxLabel, totalLabel, promoPlaceholder, applyPromoLabel, promoAppliedLabel, continueShoppingLabel, emptyCartTitleLabel, emptyCartDescriptionLabel, checkoutLabel, freeShippingNoteLabel, freeShippingThresholdNoteLabel, secureCheckoutLabel, recommendationsLabel, onQuantityChange, onRemove, onAddToWishlist, onCheckout, onContinueShopping, onRecommendationClick, }: ShoppingCart2Props): react.JSX.Element;
1466
1992
 
1467
1993
  interface ShoppingCart4Item {
1994
+ /** Backend cart line-item id — the stable identity for update/removal. */
1468
1995
  id: string;
1469
1996
  name: string;
1470
1997
  price: number;
1471
1998
  quantity: number;
1472
- image: string;
1999
+ /** Optional; an absent image is omitted rather than serialized as `""`. */
2000
+ image?: string;
1473
2001
  variant?: string;
1474
- }
2002
+ /** Canonical backend per-unit price; preferred for display when present. */
2003
+ unitPrice?: Money;
2004
+ /** Canonical backend line total; preferred over `price * quantity`. */
2005
+ lineTotal?: Money;
2006
+ }
2007
+ interface ShoppingCart4Totals {
2008
+ subtotal: Money;
2009
+ discount?: Money;
2010
+ tax?: Money;
2011
+ shipping?: Money;
2012
+ total: Money;
2013
+ }
2014
+ type ShoppingCart4TotalsState = 'idle' | 'pending' | 'error';
1475
2015
  interface ShoppingCart4Promotion {
1476
2016
  threshold: number;
1477
2017
  reward: string;
@@ -1481,19 +2021,48 @@ interface ShoppingCart4RecentlyViewed {
1481
2021
  id: string;
1482
2022
  name: string;
1483
2023
  price: number;
1484
- image: string;
2024
+ image?: string;
1485
2025
  }
2026
+ type ShoppingCart4Presentation = 'compact' | 'page';
1486
2027
  interface ShoppingCart4Props {
1487
2028
  items: ShoppingCart4Item[];
1488
2029
  promotions: ShoppingCart4Promotion[];
1489
2030
  recentlyViewed?: ShoppingCart4RecentlyViewed[];
2031
+ /**
2032
+ * Layout presentation. `compact` (default) is the collapsible quick-cart
2033
+ * card; `page` is a wide, always-expanded review layout with a primary
2034
+ * heading, no collapse control, and normal page scrolling. Both use the same
2035
+ * line controls and authoritative monetary rendering.
2036
+ */
2037
+ presentation?: ShoppingCart4Presentation;
2038
+ /**
2039
+ * Backend-authoritative totals. The curated cart renders these verbatim; it
2040
+ * never computes subtotal/tax/shipping/total locally.
2041
+ */
2042
+ totals?: ShoppingCart4Totals;
2043
+ /** Controlled state of the totals fetch/mutation. */
2044
+ totalsState?: ShoppingCart4TotalsState;
2045
+ totalsErrorLabel?: string;
2046
+ /** Shown when a required total amount is absent or malformed (never as zero). */
2047
+ totalsUnavailableLabel?: string;
2048
+ /** Shown for a line whose supplied line total is absent or malformed. */
2049
+ amountUnavailableLabel?: string;
2050
+ retryLabel?: string;
2051
+ onRetryTotals?: () => void;
2052
+ /** Override money formatting (locale, currency). Defaults to `Money.currencyCode`. */
2053
+ formatMoney?: (money: Money) => string;
2054
+ /** @deprecated legacy numeric formatter, used only when `totals` is absent. */
2055
+ formatPrice?: (value: number) => string;
2056
+ /** @deprecated legacy local tax rate, used only when `totals` is absent. */
1490
2057
  taxRate?: number;
1491
2058
  titleLabel?: string;
1492
2059
  subtotalLabel?: string;
2060
+ discountLabel?: string;
1493
2061
  taxLabel?: string;
1494
2062
  shippingLabel?: string;
1495
2063
  shippingFreeLabel?: string;
1496
2064
  totalLabel?: string;
2065
+ totalsPendingLabel?: string;
1497
2066
  awayFromLabel?: string;
1498
2067
  activatedLabel?: string;
1499
2068
  itemsLabel?: string;
@@ -1508,15 +2077,31 @@ interface ShoppingCart4Props {
1508
2077
  checkoutLabel?: string;
1509
2078
  quickCheckoutLabel?: string;
1510
2079
  checkoutNowLabel?: string;
2080
+ emptyLabel?: string;
2081
+ removeLabel?: string;
2082
+ decreaseLabel?: string;
2083
+ increaseLabel?: string;
2084
+ continueShoppingLabel?: string;
2085
+ /** Suppress the checkout action (e.g. the checkout feature is not installed). */
2086
+ checkoutUnavailable?: boolean;
2087
+ /** Disable checkout while the cart is not ready (pending/error/invalid totals). */
2088
+ checkoutDisabled?: boolean;
2089
+ /**
2090
+ * ABSOLUTE quantity for a backend cart line-item id (distinct from the
2091
+ * Navbar's DELTA). The boundary mutates the cart by line-item id.
2092
+ */
1511
2093
  onQuantityChange?: (id: string, quantity: number) => void;
2094
+ /** Remove the backend cart line-item id. */
1512
2095
  onRemove?: (id: string) => void;
1513
2096
  onCheckout?: () => void;
1514
2097
  onQuickCheckout?: () => void;
1515
2098
  onPayWithApple?: () => void;
1516
2099
  onPayWithGoogle?: () => void;
1517
2100
  onRecentlyViewedClick?: (id: string) => void;
2101
+ /** Page presentation only: navigate back to browsing. */
2102
+ onContinueShopping?: () => void;
1518
2103
  }
1519
- declare function ShoppingCart4({ items, promotions, recentlyViewed, taxRate, titleLabel, subtotalLabel, taxLabel, shippingLabel, shippingFreeLabel, totalLabel, awayFromLabel, activatedLabel, itemsLabel, expressCheckoutLabel, expressLabel, standardLabel, estimatedDeliveryLabel, secureCheckoutLabel, recentlyViewedLabel, collapseLabel, expandLabel, checkoutLabel, quickCheckoutLabel, checkoutNowLabel, onQuantityChange, onRemove, onCheckout, onQuickCheckout, onPayWithApple, onPayWithGoogle, onRecentlyViewedClick, }: ShoppingCart4Props): react.JSX.Element;
2104
+ declare function ShoppingCart4({ items, promotions, recentlyViewed, presentation, totals, totalsState, totalsErrorLabel, totalsUnavailableLabel, amountUnavailableLabel, retryLabel, onRetryTotals, formatMoney: formatMoneyProp, formatPrice, titleLabel, subtotalLabel, discountLabel, taxLabel, shippingLabel, shippingFreeLabel, totalLabel, totalsPendingLabel, awayFromLabel, activatedLabel, itemsLabel, expressCheckoutLabel, expressLabel, standardLabel, estimatedDeliveryLabel, secureCheckoutLabel, recentlyViewedLabel, collapseLabel, expandLabel, checkoutLabel, quickCheckoutLabel, checkoutNowLabel, emptyLabel, removeLabel, decreaseLabel, increaseLabel, continueShoppingLabel, checkoutUnavailable, checkoutDisabled, onQuantityChange, onRemove, onCheckout, onQuickCheckout, onPayWithApple, onPayWithGoogle, onRecentlyViewedClick, onContinueShopping, }: ShoppingCart4Props): react.JSX.Element;
1520
2105
 
1521
2106
  type ShoppingCart3Tag = 'Limited Edition' | 'Best Seller' | 'New Arrival';
1522
2107
  interface ShoppingCart3CartItem {
@@ -1610,32 +2195,82 @@ type CheckoutForm1FieldDescriptions = Partial<Record<keyof CheckoutForm1FormData
1610
2195
  interface CheckoutForm1OrderSummaryItem {
1611
2196
  id: string | number;
1612
2197
  name: string;
1613
- variant: string;
1614
- price: number;
2198
+ variant?: string;
1615
2199
  quantity: number;
1616
- image: string;
2200
+ /** Canonical backend line total; preferred over `price * quantity`. */
2201
+ lineTotal?: Money;
2202
+ /** @deprecated legacy numeric price, used only when `lineTotal` is absent. */
2203
+ price?: number;
2204
+ /** Optional; an absent image is omitted rather than serialized as `""`. */
2205
+ image?: string;
2206
+ }
2207
+ interface CheckoutForm1Totals {
2208
+ subtotal: Money;
2209
+ discount?: Money;
2210
+ tax?: Money;
2211
+ shipping?: Money;
2212
+ total: Money;
1617
2213
  }
2214
+ type CheckoutForm1TotalsState = 'idle' | 'pending' | 'error';
1618
2215
  interface CheckoutForm1OrderSummary {
1619
2216
  items: CheckoutForm1OrderSummaryItem[];
1620
- shipping: number;
1621
- tax: number;
2217
+ /** Backend-authoritative totals; rendered verbatim when present. */
2218
+ totals?: CheckoutForm1Totals;
2219
+ /** @deprecated legacy numeric amounts, used only when `totals` is absent. */
2220
+ shipping?: number;
2221
+ /** @deprecated */
2222
+ tax?: number;
2223
+ /** @deprecated */
1622
2224
  discount?: number;
2225
+ /** @deprecated */
1623
2226
  promoDiscount?: number;
1624
2227
  }
1625
2228
  interface CheckoutForm1CountryOption {
1626
2229
  value: string;
1627
2230
  label: string;
1628
2231
  }
2232
+ interface CheckoutForm1ShippingOption {
2233
+ /** Backend shipping method id — the controlled selection identity. */
2234
+ id: string;
2235
+ name: string;
2236
+ price?: Money;
2237
+ description?: string;
2238
+ estimatedDays?: string;
2239
+ }
1629
2240
  type CheckoutForm1ChangeHandler = (field: keyof CheckoutForm1FormData, value: string | boolean) => void;
1630
2241
  interface CheckoutForm1Props {
1631
2242
  title?: string;
1632
2243
  description?: string;
1633
2244
  orderSummary?: CheckoutForm1OrderSummary;
2245
+ /** Controlled state of the totals fetch/mutation. */
2246
+ totalsState?: CheckoutForm1TotalsState;
2247
+ totalsErrorLabel?: string;
2248
+ retryLabel?: string;
2249
+ onRetryTotals?: () => void;
1634
2250
  countries?: CheckoutForm1CountryOption[];
2251
+ /** Eligible shipping options for the cart's region/address. */
2252
+ shippingOptions?: CheckoutForm1ShippingOption[];
2253
+ /** Controlled selection of a shipping option id. */
2254
+ selectedShippingOptionId?: string;
2255
+ onSelectShippingOption?: (id: string) => void;
1635
2256
  paymentMethods?: PaymentMethod[];
1636
2257
  noPaymentMethodsLabel?: string;
2258
+ /** Override money formatting (locale, currency). Defaults to `Money.currencyCode`. */
2259
+ formatMoney?: (money: Money) => string;
2260
+ /**
2261
+ * Raw card fields are legacy-only and never collected in the launch flow.
2262
+ * Defaults to `false`: the curated surface renders no card inputs.
2263
+ */
2264
+ collectCardFields?: boolean;
2265
+ onApplyPromo?: (code: string) => void;
2266
+ promoPending?: boolean;
2267
+ promoApplyLabel?: string;
2268
+ promoPlaceholder?: string;
2269
+ /** Optional trust copy; rendered only when supplied (never fabricated). */
2270
+ trustNotes?: string[];
1637
2271
  backLabel?: string;
1638
2272
  completeOrderLabel?: string;
2273
+ processingLabel?: string;
1639
2274
  continueLabel?: string;
1640
2275
  values: CheckoutForm1FormData;
1641
2276
  onChange: CheckoutForm1ChangeHandler;
@@ -1647,8 +2282,11 @@ interface CheckoutForm1Props {
1647
2282
  submitting?: boolean;
1648
2283
  /** Order-level error surfaced above the footer actions. */
1649
2284
  submitError?: string;
2285
+ /** Optional recovery action for a failed submission. */
2286
+ onRetrySubmit?: () => void;
2287
+ submitErrorActionLabel?: string;
1650
2288
  }
1651
- declare function CheckoutForm1({ title, description, orderSummary, countries, paymentMethods, noPaymentMethodsLabel, backLabel, completeOrderLabel, continueLabel, values, onChange, fieldErrors, fieldDescriptions, validateStep, onSubmit, submitting, submitError, }: CheckoutForm1Props): react.JSX.Element;
2289
+ declare function CheckoutForm1({ title, description, orderSummary, totalsState, totalsErrorLabel, retryLabel, onRetryTotals, countries, shippingOptions, selectedShippingOptionId, onSelectShippingOption, paymentMethods, noPaymentMethodsLabel, formatMoney, collectCardFields, onApplyPromo, promoPending, promoApplyLabel, promoPlaceholder, trustNotes, backLabel, completeOrderLabel, processingLabel, continueLabel, values, onChange, fieldErrors, fieldDescriptions, validateStep, onSubmit, submitting, submitError, onRetrySubmit, submitErrorActionLabel, }: CheckoutForm1Props): react.JSX.Element;
1652
2290
 
1653
2291
  interface CheckoutForm2Item {
1654
2292
  id: string;
@@ -1831,10 +2469,13 @@ type FulfilmentStage = 'Confirmed' | 'Packed' | 'Shipped' | 'Delivered';
1831
2469
  interface OrderLine {
1832
2470
  id: string;
1833
2471
  name: string;
1834
- variant: string;
2472
+ variant?: string;
1835
2473
  quantity: number;
1836
- price: number;
1837
- image: string;
2474
+ /** Canonical backend line total. */
2475
+ lineTotal: Money;
2476
+ unitPrice?: Money;
2477
+ /** Optional; an absent image is omitted rather than serialized as `""`. */
2478
+ image?: string;
1838
2479
  }
1839
2480
  interface FulfilmentStageDetail {
1840
2481
  stage: FulfilmentStage;
@@ -1852,46 +2493,55 @@ interface FulfilmentStageDetail {
1852
2493
  interface OrderAddress {
1853
2494
  name: string;
1854
2495
  lines: string[];
1855
- method: string;
2496
+ method?: string;
1856
2497
  }
1857
2498
  interface OrderTotals {
1858
- subtotal: number;
1859
- shipping: number;
1860
- tax: number;
2499
+ subtotal?: Money;
2500
+ discount?: Money;
2501
+ shipping?: Money;
2502
+ tax?: Money;
2503
+ total?: Money;
1861
2504
  }
1862
2505
  interface Order$1 {
1863
2506
  number: string;
1864
2507
  /** ISO date */
1865
2508
  placedAt: string;
1866
- email: string;
1867
- currentStage: FulfilmentStage;
1868
- /** ISO date */
1869
- estimatedDelivery: string;
2509
+ email?: string;
2510
+ /** Present only when the backend reports a fulfilment stage. */
2511
+ currentStage?: FulfilmentStage;
2512
+ /** ISO date. Rendered only when supplied; no delivery estimate is fabricated. */
2513
+ estimatedDelivery?: string | null;
1870
2514
  trackingHref?: string;
1871
- shipping: OrderAddress;
1872
- billing: OrderAddress;
2515
+ shipping?: OrderAddress;
2516
+ billing?: OrderAddress;
1873
2517
  totals: OrderTotals;
1874
2518
  }
1875
2519
  interface CheckoutConfirmationProps {
1876
2520
  order: Order$1;
1877
2521
  orderLines: OrderLine[];
1878
2522
  /**
1879
- * Keyed by `FulfilmentStage`. The stage strip is ordered by `Object.keys`,
1880
- * so define the record in the canonical `Confirmed → Packed → Shipped → Delivered` order.
2523
+ * Keyed by `FulfilmentStage`. Rendered only when supplied; the stage strip is
2524
+ * ordered by `Object.keys`, so define the record in the canonical
2525
+ * `Confirmed → Packed → Shipped → Delivered` order.
1881
2526
  */
1882
- fulfilmentDetails: Record<FulfilmentStage, FulfilmentStageDetail>;
1883
- /** Override price formatting (locale, currency). Defaults to USD. */
1884
- formatPrice?: (value: number) => string;
2527
+ fulfilmentDetails?: Record<FulfilmentStage, FulfilmentStageDetail>;
2528
+ /** Override money formatting (locale, currency). Defaults to `Money.currencyCode`. */
2529
+ formatPrice?: (money: Money) => string;
1885
2530
  titleLabel?: string;
1886
2531
  /** Template with `{number}`/`{date}`/`{email}` placeholders, resolved internally. */
1887
2532
  orderPlacedLabel?: string;
2533
+ /** Used when the order carries no email. */
2534
+ orderPlacedNoEmailLabel?: string;
1888
2535
  itemsLabel?: string;
1889
2536
  quantityLabel?: string;
1890
2537
  subtotalLabel?: string;
2538
+ discountLabel?: string;
1891
2539
  shippingLabel?: string;
1892
2540
  taxLabel?: string;
1893
2541
  totalLabel?: string;
1894
2542
  freeLabel?: string;
2543
+ /** Shown for a line whose supplied line total is absent or malformed. */
2544
+ amountUnavailableLabel?: string;
1895
2545
  shippingAddressLabel?: string;
1896
2546
  billingAddressLabel?: string;
1897
2547
  continueShoppingLabel?: string;
@@ -1918,7 +2568,7 @@ interface CheckoutConfirmationProps {
1918
2568
  * your order record. Only the progress tabs are interactive, and they carry their own
1919
2569
  * `'use client'` — the boundary is one child rather than the whole page.
1920
2570
  */
1921
- declare function CheckoutConfirmation({ order, orderLines, fulfilmentDetails, formatPrice, titleLabel, orderPlacedLabel, itemsLabel, quantityLabel, subtotalLabel, shippingLabel, taxLabel, totalLabel, freeLabel, shippingAddressLabel, billingAddressLabel, continueShoppingLabel, contactSupportLabel, supportLabel, progressLabel, estimatedDeliveryLabel, currentStageLabel, inProgressLabel, expectedByLabel, completedLabel, statusLabel, locationLabel, trackOrderLabel, continueShoppingHref, supportHref, onContinueShopping, }: CheckoutConfirmationProps): react.JSX.Element;
2571
+ declare function CheckoutConfirmation({ order, orderLines, fulfilmentDetails, formatPrice, titleLabel, orderPlacedLabel, orderPlacedNoEmailLabel, itemsLabel, quantityLabel, subtotalLabel, discountLabel, shippingLabel, taxLabel, totalLabel, freeLabel, amountUnavailableLabel, shippingAddressLabel, billingAddressLabel, continueShoppingLabel, contactSupportLabel, supportLabel, progressLabel, estimatedDeliveryLabel, currentStageLabel, inProgressLabel, expectedByLabel, completedLabel, statusLabel, locationLabel, trackOrderLabel, continueShoppingHref, supportHref, onContinueShopping, }: CheckoutConfirmationProps): react.JSX.Element;
1922
2572
 
1923
2573
  interface OrderHistory1Order {
1924
2574
  name: string;
@@ -1994,6 +2644,10 @@ interface FeaturedProduct$1 {
1994
2644
  image: string;
1995
2645
  colors: string[];
1996
2646
  }
2647
+ interface HeroImage {
2648
+ src: string;
2649
+ alt: string;
2650
+ }
1997
2651
  interface StorefrontHero1Props {
1998
2652
  title: string;
1999
2653
  description: string;
@@ -2002,6 +2656,12 @@ interface StorefrontHero1Props {
2002
2656
  badge?: string;
2003
2657
  primaryCta?: CTA;
2004
2658
  secondaryCta?: CTA;
2659
+ /**
2660
+ * Optional editorial image. Rendered as a native `<img>` when `src` is a
2661
+ * non-empty string; omitted entirely when absent or blank (never an empty
2662
+ * `src`). The product grid is unaffected.
2663
+ */
2664
+ heroImage?: HeroImage;
2005
2665
  onAddToCart?: (product: FeaturedProduct$1) => void;
2006
2666
  onBuyNow?: (product: FeaturedProduct$1) => void;
2007
2667
  onSelectColor?: (product: FeaturedProduct$1, index: number, color: string) => void;
@@ -2011,7 +2671,7 @@ interface StorefrontHero1Props {
2011
2671
  outOfStockLabel?: string;
2012
2672
  colorsLabel?: string;
2013
2673
  }
2014
- declare function StorefrontHero1({ title, description, products, titleAccent, badge, primaryCta, secondaryCta, onAddToCart, onBuyNow, onSelectColor, addToCartLabel, buyNowLabel, newLabel, outOfStockLabel, colorsLabel, }: StorefrontHero1Props): react.JSX.Element;
2674
+ declare function StorefrontHero1({ title, description, products, titleAccent, badge, primaryCta, secondaryCta, heroImage, onAddToCart, onBuyNow, onSelectColor, addToCartLabel, buyNowLabel, newLabel, outOfStockLabel, colorsLabel, }: StorefrontHero1Props): react.JSX.Element;
2015
2675
 
2016
2676
  interface FeaturedProduct {
2017
2677
  /** Unique identifier for the product. */
@@ -2405,4 +3065,4 @@ interface Verify1Props {
2405
3065
  }
2406
3066
  declare function Verify1({ verifyTitleLabel, verifyDescriptionLabel, backupCodeTitleLabel, backupCodeDescriptionLabel, backupCodeLabel, backupCodePlaceholder, otpAriaLabel, verifyLabel, resendCodeLabel, resendCooldownLabel, useBackupCodeLabel, useAuthenticatorLabel, tooManyAttemptsLabel, attemptsLeftLabel, verifiedTitleLabel, verifiedDescriptionLabel, continueLabel, demoOtpHintLabel, demoBackupHintLabel, onVerify, onVerifyBackup, onResend, onContinue, }: Verify1Props): react.JSX.Element;
2407
3067
 
2408
- export { AppShell1, Avatar, AvatarFallback, AvatarImage, Badge, Banner1, Button, type CTA, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryFilter1, CategoryFilter2, type CategoryFilter2Category, type CategoryFilter2Color, type CategoryFilter2Filters, type CategoryFilter2PriceRange, type CategoryFilter2Props, type CategoryFilter2SortOption, CategoryFilter4, type CategoryFilter4Facets, type CategoryFilter4Product, type CategoryFilter4Props, CategoryIcon, type CategoryIconName, type CategoryIconProps, CheckoutConfirmation, type CheckoutConfirmationProps, type CheckoutFieldError, type CheckoutFieldErrors, CheckoutForm1, type CheckoutForm1ChangeHandler, type CheckoutForm1CountryOption, type CheckoutForm1FieldDescriptions, type CheckoutForm1FieldErrors, type CheckoutForm1FormData, type CheckoutForm1OrderSummary, type CheckoutForm1OrderSummaryItem, type CheckoutForm1Props, CheckoutForm2, type CheckoutForm2Data, type CheckoutForm2FieldDescriptions, type CheckoutForm2FieldErrors, type CheckoutForm2Item, type CheckoutForm2Props, type CheckoutForm2Totals, CheckoutForm3, type CheckoutForm3CartItem, type CheckoutForm3CountryOption, type CheckoutForm3FormData, type CheckoutForm3Props, type CheckoutForm3ShippingMethod, type CollectionItem, CtaSection1, type CtaSection1Props, FaqBlock1, type FaqBlock1Props, type FaqItem, Feature1, type Feature1Item, type Feature1Props, Feature2, type Feature2Item, type Feature2Props, type FeaturedProduct$1 as FeaturedProduct, type FilterProduct, type FooterLink, type FooterLinkColumn, FooterSection1, FooterSection3, type FooterSection3Props, FooterSection4, type FooterSection4Contact, type FooterSection4Link, type FooterSection4LinkColumn, type FooterSection4Props, type FooterSection4SocialIcon, type FooterSection4SocialLink, ForgotPasswordPage1, type ForgotPasswordPage1Props, type FulfilmentStage, type FulfilmentStageDetail, HeroSection1, LoginPage1, type LoginPage1FormData, type LoginPage1Props, type LoginPage1SocialButton, LoginPage2, type LoginPage2Props, type LoginPage2SocialButton, LogoCloud1, type LogoCloud1Platform, type LogoCloud1Props, MegaMenu, type MegaMenuProps, type MenuItem, MobileCategoryDrawer, type MobileCategoryDrawerProps, Navbar1, Navbar2, Navbar3, Navbar4, type Order$1 as Order, type OrderAddress, OrderHistory1, OrderHistory2, type OrderLine, type OrderTotals, PricingSection1, type PricingSection1Props, type PricingTier, ProductCard1, ProductCard2, ProductCard3, ProductCard5, ProductCategory1, type ProductCategory1Category, type ProductCategory1CategoryIcon, type ProductCategory1Props, ProductCategory2, type ProductCategory2Category, type ProductCategory2Props, ProductCategory4, ProductCategory5, ProductOverview1, ProductOverview2, type ProductOverview2Product, type ProductOverview2Props, ProductOverview5, type ProductOverview5Product, type ProductOverview5Props, type ProductOverview5Review, ProductQuickView, ReviewRating1, type ReviewRating1Review, ReviewRating2, ShoppingCart1, ShoppingCart2, type ShoppingCart2Item, type ShoppingCart2Props, ShoppingCart3, type ShoppingCart3CartItem, type ShoppingCart3Props, ShoppingCart4, type ShoppingCart4Item, type ShoppingCart4Props, SignUpPage1, type SignUpPage1Data, type SignUpPage1Props, type SignUpPage1SocialButton, type SocialLink, Statistic1, type Statistic1Props, type StatisticItem, StoreCategory, StoreContainer1, type StoreContainer1Props, StorefrontHero1, type StorefrontHero1Props, StorefrontHero2, StorefrontHero5, StorefrontHero6, Testimonial1, type Testimonial1Item, type Testimonial1Props, Testimonial2, type Testimonial2Item, type Testimonial2Props, Verify1, type Verify1Props, badgeVariants, buttonVariants, categoryIconNameSchema, categoryIconPropsSchema, cn, collectionItemSchema, megaMenuPropsSchema, menuItemSchema, mobileCategoryDrawerPropsSchema };
3068
+ export { AppShell1, Avatar, AvatarFallback, AvatarImage, BackToTop, type BackToTopProps, Badge, Banner1, Breadcrumb, type BreadcrumbItemData, type BreadcrumbProps, Button, type CTA, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryFilter1, type CategoryFilter1Category, type CategoryFilter1PriceRange, type CategoryFilter1SortOption, CategoryFilter2, type CategoryFilter2ActiveFilter, type CategoryFilter2ActiveFilterKind, type CategoryFilter2Category, type CategoryFilter2Collection, type CategoryFilter2Color, type CategoryFilter2Filters, type CategoryFilter2PriceRange, type CategoryFilter2Props, type CategoryFilter2QueryError, type CategoryFilter2SortOption, type CategoryFilter2Status, CategoryFilter2StatusView, type CategoryFilter2StatusViewProps, CategoryFilter4, type CategoryFilter4Facets, type CategoryFilter4Product, type CategoryFilter4Props, CategoryIcon, type CategoryIconName, type CategoryIconProps, CheckoutConfirmation, type CheckoutConfirmationProps, type CheckoutFieldError, type CheckoutFieldErrors, CheckoutForm1, type CheckoutForm1ChangeHandler, type CheckoutForm1CountryOption, type CheckoutForm1FieldDescriptions, type CheckoutForm1FieldErrors, type CheckoutForm1FormData, type CheckoutForm1OrderSummary, type CheckoutForm1OrderSummaryItem, type CheckoutForm1Props, type CheckoutForm1ShippingOption, type CheckoutForm1Totals, type CheckoutForm1TotalsState, CheckoutForm2, type CheckoutForm2Data, type CheckoutForm2FieldDescriptions, type CheckoutForm2FieldErrors, type CheckoutForm2Item, type CheckoutForm2Props, type CheckoutForm2Totals, CheckoutForm3, type CheckoutForm3CartItem, type CheckoutForm3CountryOption, type CheckoutForm3FormData, type CheckoutForm3Props, type CheckoutForm3ShippingMethod, type CollectionItem, CtaSection1, type CtaSection1Props, FaqBlock1, type FaqBlock1Props, type FaqItem, Feature1, type Feature1Item, type Feature1Props, Feature2, type Feature2Item, type Feature2Props, type FeaturedProduct$1 as FeaturedProduct, type FilterProduct, type FooterLink, type FooterLinkColumn, FooterSection1, FooterSection3, type FooterSection3Props, FooterSection4, type FooterSection4Contact, type FooterSection4Link, type FooterSection4LinkColumn, type FooterSection4Props, type FooterSection4SocialIcon, type FooterSection4SocialLink, ForgotPasswordPage1, type ForgotPasswordPage1Props, type FulfilmentStage, type FulfilmentStageDetail, HeroSection1, LoginPage1, type LoginPage1FormData, type LoginPage1Props, type LoginPage1SocialButton, LoginPage2, type LoginPage2Props, type LoginPage2SocialButton, LogoCloud1, type LogoCloud1Platform, type LogoCloud1Props, MegaMenu, type MegaMenuProps, type MenuItem, MobileBottomNav, type MobileBottomNavItem, type MobileBottomNavProps, MobileCategoryDrawer, type MobileCategoryDrawerProps, Navbar1, Navbar2, Navbar3, Navbar4, type Order$1 as Order, type OrderAddress, OrderHistory1, OrderHistory2, type OrderLine, type OrderTotals, PricingSection1, type PricingSection1Props, type PricingTier, ProductCard1, type ProductCard1Product, type ProductCard1Props, ProductCard2, ProductCard3, ProductCard5, ProductCategory1, type ProductCategory1Category, type ProductCategory1CategoryIcon, type ProductCategory1Props, ProductCategory2, type ProductCategory2Category, type ProductCategory2Props, ProductCategory4, ProductCategory5, type ProductDetailProduct, type ProductDetailVariant, ProductOverview1, type ProductOverview1Props, type ProductOverview1Rating, ProductOverview2, type ProductOverview2Product, type ProductOverview2Props, ProductOverview5, type ProductOverview5Product, type ProductOverview5Props, type ProductOverview5Review, ProductPresentation, ProductQuickView, ProductShowcase1, type ProductShowcase1Props, ReviewRating1, type ReviewRating1Review, ReviewRating2, ShoppingCart1, ShoppingCart2, type ShoppingCart2Item, type ShoppingCart2Props, ShoppingCart3, type ShoppingCart3CartItem, type ShoppingCart3Props, ShoppingCart4, type ShoppingCart4Item, type ShoppingCart4Props, SignUpPage1, type SignUpPage1Data, type SignUpPage1Props, type SignUpPage1SocialButton, SkipToContent, type SkipToContentProps, type SocialLink, Statistic1, type Statistic1Props, type StatisticItem, StoreCategory, StoreContainer1, type StoreContainer1Props, StorefrontHero1, type StorefrontHero1Props, StorefrontHero2, StorefrontHero5, StorefrontHero6, Testimonial1, type Testimonial1Item, type Testimonial1Props, Testimonial2, type Testimonial2Item, type Testimonial2Props, Verify1, type Verify1Props, backToTopPropsSchema, badgeVariants, breadcrumbItemSchema, breadcrumbPropsSchema, buttonVariants, categoryIconNameSchema, categoryIconPropsSchema, cn, collectionItemSchema, megaMenuPropsSchema, menuItemSchema, mobileBottomNavItemSchema, mobileBottomNavPropsSchema, mobileCategoryDrawerPropsSchema, resolveScrollBehavior, skipToContentPropsSchema };