Skip to content
This repository was archived by the owner on Jan 26, 2026. It is now read-only.

Commit 58fe7ff

Browse files
Merge branch 'Weaverse:main' into main
2 parents 9b7cf60 + 72c816c commit 58fe7ff

File tree

11 files changed

+212
-100
lines changed

11 files changed

+212
-100
lines changed

app/components/cart/cart.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import type { CartApiQueryFragment } from "storefront-api.generated";
1515
import { Button } from "~/components/button";
1616
import { Image } from "~/components/image";
1717
import { Link } from "~/components/link";
18-
import { RevealUnderline } from "~/reveal-underline";
1918
import { getImageAspectRatio } from "~/utils/image";
2019
import { toggleCartDrawer } from "../layout/cart-drawer";
2120
import { CartBestSellers } from "./cart-best-sellers";

app/components/layout/desktop-menu.tsx

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function DesktopMenu() {
2424
onValueChange={setValue}
2525
onMouseLeave={() => setValue(null)}
2626
>
27-
<nav className="hidden lg:flex grow justify-center h-full">
27+
<nav className="hidden lg:flex grow justify-center h-full desktop-menu">
2828
{items.map((menuItem) => {
2929
const { id, items = [], title, to } = menuItem;
3030
const level = getMaxDepth(menuItem);
@@ -45,18 +45,40 @@ export function DesktopMenu() {
4545
setValue(id);
4646
}
4747
}}
48-
onPointerDown={hasSubmenu ? (e) => {
49-
// Allow navigation on left click while preserving submenu behavior
50-
if (e.button === 0 && !e.ctrlKey && !e.metaKey) {
51-
navigate(to);
52-
}
53-
} : undefined}
48+
onPointerDown={
49+
hasSubmenu
50+
? (e) => {
51+
// Allow navigation on left click while preserving submenu behavior
52+
if (e.button === 0 && !e.ctrlKey && !e.metaKey) {
53+
navigate(to);
54+
}
55+
}
56+
: undefined
57+
}
5458
>
5559
{hasSubmenu ? (
56-
<span>{title}</span>
60+
<span
61+
className={cn(
62+
"font-heading relative cursor-pointer",
63+
"after:absolute after:left-0 after:bottom-[-2px] after:w-full after:h-[2px] after:bg-current",
64+
"after:opacity-0 hover:after:opacity-100 group-data-[state=open]:after:opacity-100",
65+
"after:transition-opacity after:duration-[360ms] after:ease-[cubic-bezier(0.22,1,0.36,1)]",
66+
)}
67+
>
68+
{title}
69+
</span>
5770
) : (
5871
<Link to={to} className="transition-none">
59-
{title}
72+
<span
73+
className={cn(
74+
"font-heading relative cursor-pointer",
75+
"after:absolute after:left-0 after:bottom-[-2px] after:w-full after:h-[2px] after:bg-current",
76+
"after:opacity-0 hover:after:opacity-100 group-data-[state=open]:after:opacity-100",
77+
"after:transition-opacity after:duration-[360ms] after:ease-[cubic-bezier(0.22,1,0.36,1)]",
78+
)}
79+
>
80+
{title}
81+
</span>
6082
</Link>
6183
)}
6284
</Menubar.Trigger>
@@ -65,7 +87,7 @@ export function DesktopMenu() {
6587
className={cn([
6688
"px-3 md:px-4 lg:px-6",
6789
"bg-(--color-header-bg-hover) shadow-lg border-t border-line-subtle mt-1.5 lg:mt-3",
68-
isDropdown ? "py-6" : "w-screen py-8",
90+
isDropdown ? "py-6 max-w-[300px]" : "w-screen py-8",
6991
])}
7092
>
7193
{isDropdown ? (
@@ -98,7 +120,7 @@ function DropdownSubMenu({ items }: { items: SingleMenuItem[] }) {
98120
prefetch="intent"
99121
className="transition-none block"
100122
>
101-
<span>{title}</span>
123+
<span className="font-normal line-clamp-2">{title}</span>
102124
</Link>
103125
))}
104126
</ul>
@@ -118,7 +140,11 @@ function MegaMenu({ items }: { items: SingleMenuItem[] }) {
118140
<Link
119141
to={to}
120142
prefetch="intent"
121-
className={clsx(["text-left", "font-normal uppercase", "flex flex-col gap-5"])}
143+
className={clsx([
144+
"text-left",
145+
"font-normal uppercase",
146+
"flex flex-col gap-5",
147+
])}
122148
>
123149
<div className="relative overflow-hidden max-w-72 w-72 aspect-square">
124150
<Image

app/components/layout/footer.tsx

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -97,49 +97,46 @@ export function Footer() {
9797
return (
9898
<footer
9999
className={cn(
100-
"w-full bg-(--color-footer-bg) text-(--color-footer-text) pt-9 lg:pt-16",
100+
"w-full bg-(--color-footer-bg) text-(--color-footer-text) pt-5 lg:pt-7",
101101
variants({ padding: footerWidth }),
102102
)}
103103
>
104104
<div className={cn("w-full h-full", variants({ width: footerWidth }))}>
105-
<div className="md:space-y-6 divide-y divide-line-subtle">
106-
<div className="w-full grid md:grid-cols-2 grid-cols-1 gap-8 md:pb-6 pb-0">
107-
<div className="flex flex-col justify-between gap-6">
108-
{footerLogoData ? (
109-
<div className="relative" style={{ width: footerLogoWidth }}>
110-
<Image
111-
data={footerLogoData}
112-
sizes="auto"
113-
width={500}
114-
className="w-full h-full object-contain object-left"
115-
/>
116-
</div>
117-
) : (
118-
<div className="font-medium text-base uppercase">
119-
{shopName}
120-
</div>
121-
)}
122-
<div className="flex flex-col gap-2">
105+
<div className="md:space-y-6 md:divide-y divide-line-subtle">
106+
<div className="w-full grid lg:grid-cols-2 grid-cols-1 gap-0 md:gap-8 md:pb-6 pb-0">
107+
{footerLogoData ? (
108+
<div
109+
className="relative md:order-none lg:order-1"
110+
style={{ width: footerLogoWidth }}
111+
>
112+
<Image
113+
data={footerLogoData}
114+
sizes="auto"
115+
width={500}
116+
className="w-full h-full object-contain object-left"
117+
/>
118+
</div>
119+
) : (
120+
<div className="font-medium text-base uppercase md:order-none lg:order-1">
121+
{shopName}
122+
</div>
123+
)}
124+
<div className="hidden gap-4 lg:hidden md:flex">
125+
<div className="flex flex-col gap-2 w-full">
123126
<div className="flex flex-col gap-6">
124127
<span className="font-semibold">{addressTitle}</span>
125128
<div className="space-y-2">
126129
<p>{storeAddress}</p>
127-
<p>Email: {storeEmail}</p>
130+
<p>{storeEmail}</p>
128131
</div>
129132
</div>
130-
{bio ? (
133+
{bio && (
131134
<div className="flex flex-col gap-4">
132135
<div dangerouslySetInnerHTML={{ __html: bio }} />
133136
</div>
134-
) : null}
135-
</div>
136-
</div>
137-
<div className="flex flex-col gap-10">
138-
<div className="lg:block md:hidden block">
139-
<FooterMenu />
137+
)}
140138
</div>
141-
142-
<div className="flex flex-col gap-6 lg:w-fit w-full">
139+
<div className="flex flex-col gap-6 w-full">
143140
<span className="font-semibold">{newsletterTitle}</span>
144141
<div className="space-y-2">
145142
<p>{newsletterDescription}</p>
@@ -152,7 +149,7 @@ export function Footer() {
152149
action="/api/klaviyo"
153150
method="POST"
154151
encType="multipart/form-data"
155-
className="flex gap-3"
152+
className="flex gap-3 h-[54px]"
156153
>
157154
<input
158155
name="email"
@@ -186,6 +183,73 @@ export function Footer() {
186183
</div>
187184
</div>
188185
</div>
186+
<div className="flex flex-col gap-2 md:order-none lg:order-3 lg:flex md:hidden">
187+
<div className="flex flex-col gap-6">
188+
<span className="font-semibold">{addressTitle}</span>
189+
<div className="space-y-2">
190+
<p>{storeAddress}</p>
191+
<p>{storeEmail}</p>
192+
</div>
193+
</div>
194+
{bio ? (
195+
<div className="flex flex-col gap-4">
196+
<div dangerouslySetInnerHTML={{ __html: bio }} />
197+
</div>
198+
) : null}
199+
</div>
200+
<div className="lg:block md:hidden block order-2">
201+
<FooterMenu />
202+
</div>
203+
204+
<div className="flex flex-col gap-6 lg:w-fit w-full order-4 md:order-none lg:order-4 lg:flex md:hidden pt-6 md:pt-0">
205+
<span className="font-semibold">{newsletterTitle}</span>
206+
<div className="space-y-2">
207+
<p>{newsletterDescription}</p>
208+
<fetcher.Form
209+
onSubmit={(event: FormEvent<HTMLFormElement>) => {
210+
setMessage("");
211+
setError("");
212+
fetcher.submit(event.currentTarget);
213+
}}
214+
action="/api/klaviyo"
215+
method="POST"
216+
encType="multipart/form-data"
217+
className="flex gap-3 h-[54px]"
218+
>
219+
<input
220+
name="email"
221+
type="email"
222+
required
223+
placeholder={newsletterPlaceholder}
224+
className="text-body bg-white focus-visible:outline-hidden px-3 placeholder:text-[#918379] border border-line-subtle lg:w-80 w-full"
225+
/>
226+
<Button
227+
variant="primary"
228+
type="submit"
229+
loading={fetcher.state === "submitting"}
230+
className="uppercase"
231+
>
232+
{newsletterButtonText}
233+
</Button>
234+
</fetcher.Form>
235+
{error ||
236+
(message && (
237+
<div className="h-8">
238+
{error && (
239+
<div className="bg-red-100 border-l-4 border-red-500 text-red-700 py-1 px-2 mb-6 flex gap-1 w-fit">
240+
<p className="font-semibold">ERROR:</p>
241+
<p>{error}</p>
242+
</div>
243+
)}
244+
{message && (
245+
<div className="bg-green-100 border-l-4 border-green-500 text-green-700 py-1 px-2 mb-6 flex gap-1 w-fit">
246+
<p>{message}</p>
247+
</div>
248+
)}
249+
</div>
250+
))}
251+
</div>
252+
</div>
189253
</div>
190254
<div>
191255
<div className="lg:hidden md:block hidden">
@@ -196,7 +260,10 @@ export function Footer() {
196260
{copyright}
197261
</p>
198262
<div className="flex justify-start lg:justify-center items-center order-1">
199-
<CountrySelector inputClassName="px-4 py-2" enableFlag={false} />
263+
<CountrySelector
264+
inputClassName="px-4 py-2"
265+
enableFlag={false}
266+
/>
200267
</div>
201268
<div className="flex gap-4 justify-start md:justify-end order-2">
202269
{SOCIAL_ACCOUNTS.map((social) =>

app/components/layout/predictive-search/search-desktop/PopularSearch.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ export function PopularSearch() {
1010
];
1111

1212
return (
13-
<div className="flex flex-col gap-4 max-w-(--page-width) mx-auto">
14-
<h3 className="text-sm font-semibold uppercase">
13+
<div className="flex flex-col gap-4 max-w-(--page-width) mx-auto pb-6">
14+
<span className="font-normal uppercase">
1515
Popular Searches
16-
</h3>
16+
</span>
1717
<ul className="flex flex-col gap-2">
1818
{popularSearches.map((search, index) => (
1919
<li key={index}>

app/components/layout/predictive-search/search-desktop/index.tsx

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function PredictiveSearchButtonDesktop({ setIsSearchOpen }) {
6767
<div className="relative p-6">
6868
<PredictiveSearchForm>
6969
{({ fetchResults, inputRef }) => (
70-
<div className="flex items-center gap-3 max-w-(--page-width) mx-auto px-3 my-6 border-b border-line-subtle">
70+
<div className="flex items-center gap-3 max-w-(--page-width) mx-auto px-3 mb-6 border-b border-line-subtle">
7171
<MagnifyingGlassIcon className="h-5 w-5 shrink-0 text-gray-500" />
7272
<input
7373
name="q"
@@ -130,21 +130,28 @@ function PredictiveSearchResults() {
130130
</div>
131131
<div className="w-4/5">
132132
<div className="flex gap-6 border-b border-line-subtle">
133-
{["articles", "products"].map((type) => (
134-
<button
135-
type="button"
136-
key={type}
137-
className={clsx(
138-
"relative font-normal px-3 py-1 transition",
139-
activeType === type
140-
? "border-b border-line text-[#524B46] -mb-[2px]"
141-
: "text-[#918379]",
142-
)}
143-
onClick={() => setActiveType(type)}
144-
>
145-
<span className="uppercase">{type}</span>
146-
</button>
147-
))}
133+
{["articles", "products"].map((type) => {
134+
const itemCount = type === "articles"
135+
? articles?.items?.length || 0
136+
: products?.items?.length || 0;
137+
138+
return (
139+
<button
140+
type="button"
141+
key={type}
142+
className={clsx(
143+
"relative font-normal px-3 py-1 transition",
144+
activeType === type
145+
? "border-b border-line text-[#524B46] -mb-[2px]"
146+
: "text-[#918379]",
147+
)}
148+
onClick={() => setActiveType(type)}
149+
>
150+
<span className="uppercase">{type}</span>
151+
<span className="ml-2 text-sm opacity-70">({itemCount})</span>
152+
</button>
153+
);
154+
})}
148155
</div>
149156
<div className="flex flex-col gap-4 mt-5 px-4">
150157
{activeType === "articles" && (

app/components/layout/predictive-search/search-desktop/predictive-search-result.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ function SearchResultItem({
6060
price,
6161
title,
6262
url,
63-
vendor,
6463
styledTitle,
6564
},
6665
}: SearchResultItemProps) {
@@ -88,9 +87,6 @@ function SearchResultItem({
8887
</div>
8988
)}
9089
<div className="space-y-1">
91-
{vendor && (
92-
<div className="text-body-subtle text-sm">By {vendor}</div>
93-
)}
9490
{styledTitle ? (
9591
<RevealUnderline as="div">
9692
<span dangerouslySetInnerHTML={{ __html: styledTitle }} />
@@ -101,11 +97,11 @@ function SearchResultItem({
10197
__typename === "Product" ? "line-clamp-1" : "line-clamp-2"
10298
)}
10399
>
104-
<RevealUnderline>{title}</RevealUnderline>
100+
<span className={clsx(__typename === "Product" ? "font-semibold uppercase line-clamp-1" : "font-normal")}>{title}</span>
105101
</div>
106102
)}
107103
{price && (
108-
<div className="flex gap-2 text-sm pt-1">
104+
<div className="flex gap-2 pt-1">
109105
<Money withoutTrailingZeros data={price as MoneyV2} />
110106
{isDiscounted(price as MoneyV2, compareAtPrice as MoneyV2) && (
111107
<CompareAtPrice data={compareAtPrice as MoneyV2} />

0 commit comments

Comments
 (0)