1- import { flattenConnection } from "@shopify/hydrogen" ;
1+ import { flattenConnection , Money } from "@shopify/hydrogen" ;
22import type {
33 MoneyV2 ,
44 ProductVariant ,
@@ -12,6 +12,17 @@ import { NavLink } from "~/components/nav-link";
1212import { VariantPrices } from "~/components/variant-prices" ;
1313import { getImageAspectRatio } from "~/utils/image" ;
1414import { BestSellerBadge , NewBadge , SaleBadge , SoldOutBadge } from "./badges" ;
15+ import { cva } from "class-variance-authority" ;
16+
17+ let styleVariants = cva ( "" , {
18+ variants : {
19+ alignment : {
20+ left : "" ,
21+ center : "text-center [&_.title-and-price]:items-center" ,
22+ right : "text-right [&_.title-and-price]:items-end" ,
23+ } ,
24+ } ,
25+ } ) ;
1526
1627export function ProductCard ( {
1728 product,
@@ -21,11 +32,12 @@ export function ProductCard({
2132 className ?: string ;
2233} ) {
2334 let {
24- pcardAlignment,
2535 pcardBorderRadius,
2636 pcardBackgroundColor,
2737 pcardShowImageOnHover,
2838 pcardImageRatio,
39+ pcardTitlePricesAlignment,
40+ pcardAlignment,
2941 pcardShowVendor,
3042 pcardShowLowestPrice,
3143 pcardShowSku,
@@ -45,15 +57,18 @@ export function ProductCard({
4557 } = useThemeSettings ( ) ;
4658
4759 let variants = flattenConnection ( product . variants ) ;
48- let { images, badges } = product ;
49- let [ image , secondImage ] = images . nodes ;
5060 let selectedVariant = variants [ 0 ] ;
51- let isBestSellerProduct = badges
52- . filter ( Boolean )
53- . some ( ( { key, value } ) => key === "best_seller" && value === "true" ) ;
61+
5462 if ( ! selectedVariant ) return null ;
5563
5664 let { price, compareAtPrice } = selectedVariant ;
65+ let { images, badges, priceRange } = product ;
66+ let [ image , secondImage ] = images . nodes ;
67+ let isBestSellerProduct = badges
68+ . filter ( Boolean )
69+ . some ( ( { key, value } ) => key === "best_seller" && value === "true" ) ;
70+ let { minVariantPrice } = priceRange ;
71+ let isVertical = pcardTitlePricesAlignment === "vertical" ;
5772
5873 return (
5974 < div
@@ -119,33 +134,50 @@ export function ProductCard({
119134 { /* <QuickShopTrigger productHandle={product.handle} /> */ }
120135 </ div >
121136 < div
122- className = "flex flex-col py-3"
123- style = { { alignItems : pcardAlignment } }
137+ className = { clsx (
138+ "py-3 text-sm" ,
139+ isVertical && styleVariants ( { alignment : pcardAlignment } )
140+ ) }
124141 >
125142 { pcardShowVendor && (
126- < div className = "text-sm uppercase text-body-subtle mb-2" >
143+ < div className = "uppercase text-body-subtle mb-2" >
127144 { product . vendor }
128145 </ div >
129146 ) }
130- < div className = "flex items-center gap-2 mb-1" >
131- < NavLink
132- to = { `/products/${ product . handle } ` }
133- prefetch = "intent"
134- className = { ( { isTransitioning } ) =>
135- clsx ( "font-bold" , isTransitioning && "vt-product-image" )
136- }
137- >
138- < span > { product . title } </ span >
139- </ NavLink >
140- { pcardShowSku && selectedVariant . sku && (
141- < span className = "text-body-subtle" > ({ selectedVariant . sku } )</ span >
147+ < div
148+ className = { clsx (
149+ "flex mb-1" ,
150+ isVertical
151+ ? "title-and-price flex-col gap-1"
152+ : "justify-between gap-4"
153+ ) }
154+ >
155+ < div className = "flex items-center gap-1.5" >
156+ < NavLink
157+ to = { `/products/${ product . handle } ` }
158+ prefetch = "intent"
159+ className = { ( { isTransitioning } ) =>
160+ clsx ( "font-bold " , isTransitioning && "vt-product-image" )
161+ }
162+ >
163+ { product . title }
164+ </ NavLink >
165+ { pcardShowSku && selectedVariant . sku && (
166+ < span className = "text-body-subtle" > ({ selectedVariant . sku } )</ span >
167+ ) }
168+ </ div >
169+ { pcardShowLowestPrice ? (
170+ < div className = "flex gap-1" >
171+ < span > From</ span >
172+ < Money withoutTrailingZeros data = { minVariantPrice } />
173+ </ div >
174+ ) : (
175+ < VariantPrices
176+ variant = { selectedVariant as ProductVariant }
177+ showCompareAtPrice = { pcardShowSalePrice }
178+ />
142179 ) }
143180 </ div >
144- < VariantPrices
145- variant = { selectedVariant as ProductVariant }
146- showCompareAtPrice = { pcardShowSalePrice }
147- className = "mb-2"
148- />
149181 { /* {pcardShowOptionSwatches && <div>options here</div>} */ }
150182 </ div >
151183 </ div >
0 commit comments