Skip to content

Commit

Permalink
Merge branch 'Weaverse:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
hta218 authored Jul 30, 2024
2 parents 2e59605 + 6ced6d3 commit e4f5eb7
Show file tree
Hide file tree
Showing 27 changed files with 739 additions and 865 deletions.
4 changes: 3 additions & 1 deletion @/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const buttonVariants = cva(
},
shape: {
default: 'rounded',
round: 'rounded-md'
round: 'rounded-md',
}
},
defaultVariants: {
Expand All @@ -43,6 +43,7 @@ export interface ButtonProps
asChild?: boolean;
as?: React.ElementType;
to?: string;
target?: string;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
Expand Down Expand Up @@ -70,6 +71,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
)}
ref={ref}
{...props}
target={props.to ? props?.target || '_self' : undefined}
>
{loading && (
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
Expand Down
2 changes: 1 addition & 1 deletion app/components/DrawerFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ export default function SortMenu({
items.find((item) => item.key === params.get('sort')) || items[0];

return (
<Menu as="div" className="relative z-40">
<Menu as="div" className="relative z-30">
<Menu.Button className="flex h-[50px] items-center gap-[10px] rounded border border-foreground px-4 py-3">
<span className="font-heading text-xl font-medium">Sort by</span>
<IconCaret />
Expand Down
10 changes: 5 additions & 5 deletions app/components/ProductSwimlane.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import type {HomepageFeaturedProductsQuery} from 'storefrontapi.generated';
import type {FeaturedItemsQuery} from 'storefrontapi.generated';
import { Section} from '~/components/Text';
import {ProductCard} from '~/components/ProductCard';
import { IconArrowScrollLeft, IconArrowScrollRight } from './Icon';
import React, { useRef } from 'react';
import { useRef } from 'react';

const mockProducts = {
nodes: new Array(12).fill(''),
};

type ProductSwimlaneProps = HomepageFeaturedProductsQuery & {
type ProductSwimlaneProps = Pick<FeaturedItemsQuery, 'featuredProducts'> & {
title?: string;
count?: number;
};

export function ProductSwimlane({
title = 'Featured Products',
products = mockProducts,
featuredProducts = mockProducts,
count = 12,
...props
}: ProductSwimlaneProps) {
Expand All @@ -35,7 +35,7 @@ export function ProductSwimlane({
return (
<Section heading={title} padding="y" {...props} className='relative group'>
<div ref={swimlaneRef} className="swimlane hiddenScroll scroll-px-0 px-0">
{products.nodes.slice(0, count).map((product) => (
{featuredProducts.nodes.slice(0, count).map((product) => (
<ProductCard
product={product}
key={product.id}
Expand Down
2 changes: 1 addition & 1 deletion app/components/QuickView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export function QuickViewTrigger(props: {productHandle: string}) {
}, [quickAddOpen, data, load, state]);
return (
<>
<div className="mt-2 absolute bottom-4 hidden lg:group-hover:block py-5 px-3 w-full opacity-100 bg-[rgba(238,239,234,0.10)] backdrop-blur-2xl">
<div className="mt-2 absolute bottom-0 hidden lg:group-hover:block py-5 px-3 w-full opacity-100 bg-[rgba(238,239,234,0.10)] backdrop-blur-2xl">
<Button
onClick={(e) => {
e.preventDefault();
Expand Down
197 changes: 75 additions & 122 deletions app/components/product-form/product-media.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {Image} from '@shopify/hydrogen';
import clsx from 'clsx';
import {useKeenSlider, KeenSliderPlugin} from 'keen-slider/react';
import {useCallback, useEffect, useState} from 'react';
import type {MediaFragment} from 'storefrontapi.generated';
import { Image } from "@shopify/hydrogen";
import clsx from "clsx";
import { useState } from "react";
import type { MediaFragment } from "storefrontapi.generated";
import { FreeMode, Pagination, Thumbs } from "swiper/modules";
import { Swiper, type SwiperClass, SwiperSlide } from "swiper/react";

interface ProductMediaProps {
selectedVariant: any;
Expand All @@ -12,129 +13,81 @@ interface ProductMediaProps {
spacing: number;
}


export function ProductMedia(props: ProductMediaProps) {
let {
selectedVariant,
media: _media,
showThumbnails,
numberOfThumbnails,
spacing,
} = props;
let media = _media.filter((med) => med.__typename === 'MediaImage');
let slideOptions = {
initial: 0,
loop: true,
slides: {
perView: 1,
spacing: 0,
},
};

let thumbnailOptions = {
initial: 0,
slides: {
perView: numberOfThumbnails,
spacing: spacing,
},
};

let [activeInd, setActiveInd] = useState(0);
let [sliderRef, instanceRef] = useKeenSlider({
...slideOptions,
slideChanged: (slider) => {
let pos = slider.track.details.rel;
setActiveInd(pos);
let maxThumbnailIndex =
thumbnailInstance.current?.track.details.maxIdx || 0;
let thumbnailNext = Math.min(
Math.floor((pos + 1) / numberOfThumbnails),
maxThumbnailIndex,
);
thumbnailInstance.current?.moveToIdx(thumbnailNext);
},
});


function moveToIdx(idx: number) {
setActiveInd(idx);
if (instanceRef.current) {
instanceRef.current.moveToIdx(idx);
}
}

let [thumbnailRef, thumbnailInstance] = useKeenSlider(thumbnailOptions);
function handleClickThumbnail(idx: number) {
moveToIdx(idx);
}

useEffect(() => {
// instanceRef.current?.update(slideOptions);
// thumbnailInstance.current?.update(thumbnailOptions);
let selectedInd = media.findIndex((med) => {
if (med.__typename !== 'MediaImage') return false;
return med.image?.url === selectedVariant?.image.url;
});
moveToIdx(selectedInd);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedVariant?.id]);

let { selectedVariant, showThumbnails, media: _media, numberOfThumbnails, spacing } = props;
let media = _media.filter((med) => med.__typename === "MediaImage");
let [thumbsSwiper, setThumbsSwiper] = useState<SwiperClass | null>(null);
let [activeIndex, setActiveIndex] = useState(0);

return (
<div
className="grid vt-product-image"
style={{ gap: spacing, }}
>
<div ref={sliderRef} className="keen-slider flex overflow-hidden">
<div className="flex flex-col-reverse md:flex-col-reverse gap-4 w-full overflow-hidden">
<Swiper
onSwiper={setThumbsSwiper}
direction="horizontal"
spaceBetween={spacing}
freeMode
slidesPerView={"auto"}
threshold={2}
modules={[FreeMode, Thumbs]}
className="w-full overflow-visible hidden md:block"
>
{media.map((med, i) => {
let image = { ...med.image, altText: med.alt || "Product image" };
return (
<SwiperSlide
key={med.id}
className={clsx(
"!h-fit !w-fit p-1 border transition-colors !aspect-[3/4] cursor-pointer",
activeIndex === i ? "border-black" : "border-transparent",
)}
>
<Image
data={image}
loading={i === 0 ? "eager" : "lazy"}
className="object-contain fadeIn h-[100px] w-full"
sizes="auto"
/>
</SwiperSlide>
);
})}
</Swiper>
<Swiper
modules={[FreeMode, Thumbs, Pagination]}
pagination={{ type: "fraction" }}
spaceBetween={10}
thumbs={
thumbsSwiper
? {
swiper: thumbsSwiper,
slideThumbActiveClass: "thumb-active",
}
: undefined
}
onSlideChange={(swiper) => {
setActiveIndex(swiper.activeIndex);
}}
className="vt-product-image max-w-full pb-14 md:pb-0 md:[&_.swiper-pagination-fraction]:hidden"
style={
{
"--swiper-pagination-bottom": "20px",
} as React.CSSProperties
}
>
{media.map((med, i) => {
let image =
med.__typename === 'MediaImage'
? {...med.image, altText: med.alt || 'Product image'}
: null;
let image = { ...med.image, altText: med.alt || "Product image" };
return (
image && (
<div className="keen-slider__slide" key={med.id}>
<Image
data={image}
loading={i === 0 ? 'eager' : 'lazy'}
aspectRatio={'4/5'}
className="object-cover w-full h-full aspect-square fadeIn"
/>
</div>
)
<SwiperSlide key={med.id}>
<Image
data={image}
loading={i === 0 ? "eager" : "lazy"}
aspectRatio={"3/4"}
className="object-cover w-full h-auto fadeIn"
sizes="auto"
/>
</SwiperSlide>
);
})}
</div>
{showThumbnails && (
<div ref={thumbnailRef} className="keen-slider thumbnail flex">
{media.map((med, i) => {
let image =
med.__typename === 'MediaImage'
? {...med.image, altText: med.alt || 'Product image'}
: null;
return (
image && (
<div
key={med.id}
className={clsx(
'keen-slider__slide cursor-pointer rounded',
i === activeInd ? 'border-bar border-2' : '',
)}
onClick={() => handleClickThumbnail(i)}
>
<Image
data={image}
loading="lazy"
width={200}
sizes="100px 100w, 300px 300w, 500px 500w, 1000px 1000w"
aspectRatio="1/1"
className="object-cover w-full h-full aspect-square fadeIn"
/>
</div>
)
);
})}
</div>
)}
</Swiper>
</div>
);
}
4 changes: 2 additions & 2 deletions app/routes/($locale).search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export default function Search() {
productNumber={products.totalCount}
filters={productfilters}
/>
<div className="px-4 lg:container md:px-6">
<div className="px-4 container md:px-6">
{noResults ? (
<NoResults
noResults={noResults}
Expand Down Expand Up @@ -290,7 +290,7 @@ function NoResults({
/> */}
<ProductSwimlane
title="Trending Products"
products={featuredProducts}
featuredProducts={featuredProducts}
/>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion app/sections/atoms/Section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let variants = cva("relative", {
width: {
full: "w-full h-full",
stretch: "w-full h-full",
fixed: "w-full h-full max-w-[var(--page-width,1280px)] mx-auto",
fixed: "w-full h-full max-w-[var(--page-width,1440px)] mx-auto",
},
padding: {
full: "",
Expand Down
Loading

0 comments on commit e4f5eb7

Please sign in to comment.