Skip to content

Commit 6fce996

Browse files
authored
Merge pull request #263 from Weaverse/dev
Update product card content layout, update collection filters schema
2 parents e8881bc + 5a09271 commit 6fce996

5 files changed

Lines changed: 106 additions & 63 deletions

File tree

app/components/product/badges.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ export function SaleBadge({
7777
let { saleBadgeText = "Sale", saleBadgeColor } = useThemeSettings();
7878
let { amount, percentage } = calculateDiscount(price, compareAtPrice);
7979
let text = saleBadgeText
80-
.replace("[amount]", amount.toString())
81-
.replace("[percentage]", percentage.toString());
80+
.replace("[amount]", amount)
81+
.replace("[percentage]", percentage);
8282

83-
if (percentage > 0) {
83+
if (percentage !== "0") {
8484
return (
8585
<Badge
8686
text={text}
@@ -111,9 +111,9 @@ function calculateDiscount(price: MoneyV2, compareAtPrice: MoneyV2) {
111111
}).withoutTrailingZeros,
112112
percentage: Math.round(
113113
((compareAtPriceNumber - priceNumber) / compareAtPriceNumber) * 100,
114-
),
114+
).toString(),
115115
};
116116
}
117117
}
118-
return { amount: "0", percentage: 0 };
118+
return { amount: "0", percentage: "0" };
119119
}

app/components/product/product-card.tsx

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { flattenConnection } from "@shopify/hydrogen";
1+
import { flattenConnection, Money } from "@shopify/hydrogen";
22
import type {
33
MoneyV2,
44
ProductVariant,
@@ -12,6 +12,17 @@ import { NavLink } from "~/components/nav-link";
1212
import { VariantPrices } from "~/components/variant-prices";
1313
import { getImageAspectRatio } from "~/utils/image";
1414
import { 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

1627
export 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>

app/sections/collection-filters/index.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,11 @@ export let schema: HydrogenComponentSchema = {
173173
label: "Show description",
174174
defaultValue: false,
175175
},
176-
{
177-
type: "heading",
178-
label: "Banner",
179-
},
176+
],
177+
},
178+
{
179+
group: "Banner",
180+
inputs: [
180181
{
181182
type: "switch",
182183
name: "showBanner",
@@ -290,7 +291,7 @@ export let schema: HydrogenComponentSchema = {
290291
],
291292
},
292293
{
293-
group: "Products",
294+
group: "Products grid",
294295
inputs: [
295296
{
296297
type: "select",

app/sections/collection-filters/products-pagination.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ function ProductsLoadedOnScroll(props: ProductsLoadedOnScrollProps) {
156156
return (
157157
<div
158158
className={clsx([
159-
"w-full gap-x-1.5 gap-y-6 lg:gap-y-10",
159+
"w-full gap-x-4 gap-y-6 lg:gap-y-10",
160160
"grid grid-cols-[--cols-mobile] lg:grid-cols-[--cols-desktop]",
161161
])}
162162
>

app/weaverse/schema.server.ts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -651,25 +651,10 @@ export let themeSchema: HydrogenThemeSchema = {
651651
group: "Product cards",
652652
inputs: [
653653
{
654-
type: "heading",
655-
label: "Layout",
656-
},
657-
{
658-
type: "toggle-group",
659-
name: "pcardAlignment",
660-
label: "Content alignment",
661-
configs: {
662-
options: [
663-
{ value: "start", label: "Left", icon: "align-start-vertical" },
664-
{
665-
value: "center",
666-
label: "Center",
667-
icon: "align-center-vertical",
668-
},
669-
{ value: "end", label: "Right", icon: "align-end-vertical" },
670-
],
671-
},
672-
defaultValue: "center",
654+
type: "color",
655+
name: "pcardBackgroundColor",
656+
label: "Background color",
657+
defaultValue: "",
673658
},
674659
{
675660
type: "range",
@@ -683,12 +668,6 @@ export let themeSchema: HydrogenThemeSchema = {
683668
},
684669
defaultValue: 0,
685670
},
686-
{
687-
type: "color",
688-
name: "pcardBackgroundColor",
689-
label: "Background color",
690-
defaultValue: "",
691-
},
692671
{
693672
type: "heading",
694673
label: "Image",
@@ -720,6 +699,36 @@ export let themeSchema: HydrogenThemeSchema = {
720699
type: "heading",
721700
label: "Content",
722701
},
702+
{
703+
type: "select",
704+
label: "Title & prices alignment",
705+
name: "pcardTitlePricesAlignment",
706+
configs: {
707+
options: [
708+
{ value: "horizontal", label: "Horizontal" },
709+
{ value: "vertical", label: "Vertical" },
710+
],
711+
},
712+
defaultValue: "horizontal",
713+
},
714+
{
715+
type: "toggle-group",
716+
name: "pcardAlignment",
717+
label: "Content alignment",
718+
configs: {
719+
options: [
720+
{ value: "left", label: "Left", icon: "align-start-vertical" },
721+
{
722+
value: "center",
723+
label: "Center",
724+
icon: "align-center-vertical",
725+
},
726+
{ value: "right", label: "Right", icon: "align-end-vertical" },
727+
],
728+
},
729+
defaultValue: "center",
730+
condition: "pcardTitlePricesAlignment.eq.vertical",
731+
},
723732
{
724733
type: "switch",
725734
label: "Show vendor",
@@ -743,6 +752,7 @@ export let themeSchema: HydrogenThemeSchema = {
743752
label: "Show sale price",
744753
name: "pcardShowSalePrice",
745754
defaultValue: true,
755+
condition: "pcardShowLowestPrice.ne.true",
746756
},
747757
{
748758
type: "switch",

0 commit comments

Comments
 (0)