{logoData ? (
@@ -24,18 +24,24 @@ export function Logo({ isTransparent }: { isTransparent?: boolean }) {
data={logoData}
sizes="auto"
className={clsx(
- "w-full h-full object-cover transition-opacity duration-300 ease-in group-hover/header:opacity-100",
- isTransparent ? "opacity-0" : "opacity-100",
- )}
- />
-
diff --git a/app/data/queries.ts b/app/data/queries.ts
index ec8d112d..dc1c8220 100644
--- a/app/data/queries.ts
+++ b/app/data/queries.ts
@@ -160,6 +160,8 @@ export let COLLECTION_QUERY = `#graphql
$last: Int
$startCursor: String
$endCursor: String
+ $customBannerNamespace: String!
+ $customBannerKey: String!
) @inContext(country: $country, language: $language) {
collection(handle: $handle) {
id
@@ -170,6 +172,20 @@ export let COLLECTION_QUERY = `#graphql
description
title
}
+ metafield(namespace: $customBannerNamespace, key: $customBannerKey) {
+ id
+ type
+ description
+ value
+ reference {
+ ... on MediaImage {
+ image {
+ id
+ url
+ }
+ }
+ }
+ }
image {
id
url
diff --git a/app/hooks/use-cart-fetchers.ts b/app/hooks/use-cart-fetchers.ts
index f9376661..98e78dc7 100644
--- a/app/hooks/use-cart-fetchers.ts
+++ b/app/hooks/use-cart-fetchers.ts
@@ -2,12 +2,12 @@ import { useFetchers } from "@remix-run/react";
import { CartForm } from "@shopify/hydrogen";
export function useCartFetchers(actionName: string) {
- const fetchers = useFetchers();
- const cartFetchers = [];
+ let fetchers = useFetchers();
+ let cartFetchers = [];
- for (const fetcher of fetchers) {
+ for (let fetcher of fetchers) {
if (fetcher.formData) {
- const formInputs = CartForm.getFormInput(fetcher.formData);
+ let formInputs = CartForm.getFormInput(fetcher.formData);
if (formInputs.action === actionName) {
cartFetchers.push(fetcher);
}
diff --git a/app/lib/collections.ts b/app/lib/collections.ts
index 9ce69223..8c04c7ae 100644
--- a/app/lib/collections.ts
+++ b/app/lib/collections.ts
@@ -1,5 +1,5 @@
import type { ProductCollectionSortKeys } from "@shopify/hydrogen/storefront-api-types";
-import type { SortParam } from "~/modules/sort-filter";
+import type { SortParam } from "./filter";
export let getSortValuesFromParam = (
sortParam: SortParam | null,
diff --git a/app/modules/add-to-cart-button.tsx b/app/modules/add-to-cart-button.tsx
index 79407111..06184091 100644
--- a/app/modules/add-to-cart-button.tsx
+++ b/app/modules/add-to-cart-button.tsx
@@ -11,6 +11,7 @@ import {
} from "@shopify/hydrogen";
import { useEffect } from "react";
import { Button } from "~/components/button";
+import { openCartDrawer } from "~/components/header/cart-drawer";
import { usePageAnalytics } from "~/hooks/use-page-analytics";
export function AddToCartButton({
@@ -48,6 +49,7 @@ export function AddToCartButton({
type="submit"
className={className}
disabled={disabled ?? fetcher.state !== "idle"}
+ onClick={openCartDrawer}
{...props}
>
{children}
diff --git a/app/modules/cart.tsx b/app/modules/cart.tsx
index 1818f2eb..73dd3131 100644
--- a/app/modules/cart.tsx
+++ b/app/modules/cart.tsx
@@ -1,3 +1,4 @@
+import { Trash } from "@phosphor-icons/react";
import {
CartForm,
Image,
@@ -15,9 +16,8 @@ import clsx from "clsx";
import { useRef } from "react";
import useScroll from "react-use/esm/useScroll";
import type { CartApiQueryFragment } from "storefrontapi.generated";
-import { Link } from "~/components/link";
import { Button } from "~/components/button";
-import { IconTrash } from "~/components/icons";
+import { Link } from "~/components/link";
import { getImageAspectRatio } from "~/lib/utils";
import { Text } from "~/modules/text";
import { CartBestSellers } from "./cart-best-sellers";
@@ -96,10 +96,7 @@ function CartDiscounts({
{codes?.join(", ")}
@@ -339,7 +336,7 @@ function ItemRemoveButton({
type="submit"
>
Remove
-
+
diff --git a/app/modules/country-selector.tsx b/app/modules/country-selector.tsx
index a81d6080..99957abc 100644
--- a/app/modules/country-selector.tsx
+++ b/app/modules/country-selector.tsx
@@ -16,12 +16,13 @@ import {
PopoverButton,
PopoverPanel,
} from "@headlessui/react";
-import { IconCaretDown, IconCheckCircle } from "~/components/icons";
+import { CheckCircle } from "@phosphor-icons/react";
+import ReactCountryFlag from "react-country-flag";
+import { IconCaretDown } from "~/components/icons";
import { getCountryUrlPath } from "~/lib/locale";
import type { Localizations } from "~/lib/type";
import { DEFAULT_LOCALE } from "~/lib/utils";
import type { RootLoader } from "~/root";
-import ReactCountryFlag from "react-country-flag";
export function CountrySelector() {
let fetcher = useFetcher();
@@ -128,7 +129,7 @@ export function CountrySelector() {
{countryLocale.label}
{isSelected ? (
-
+
) : null}
diff --git a/app/modules/footer.tsx b/app/modules/footer.tsx
index 4a5f8a70..05cbe4bb 100644
--- a/app/modules/footer.tsx
+++ b/app/modules/footer.tsx
@@ -3,17 +3,17 @@ import {
DisclosureButton,
DisclosurePanel,
} from "@headlessui/react";
+import {
+ FacebookLogo,
+ InstagramLogo,
+ LinkedinLogo,
+ XLogo,
+} from "@phosphor-icons/react";
import { Link } from "@remix-run/react";
import { Image } from "@shopify/hydrogen";
import { useThemeSettings } from "@weaverse/hydrogen";
import { cva } from "class-variance-authority";
import { Button } from "~/components/button";
-import {
- IconFacebookLogo,
- IconInstagramLogo,
- IconLinkedinLogo,
- IconXLogo,
-} from "~/components/icons";
import { useShopMenu } from "~/hooks/use-shop-menu";
import { cn } from "~/lib/cn";
import type { ChildEnhancedMenuItem } from "~/lib/utils";
@@ -61,22 +61,22 @@ export function Footer() {
{
name: "Instagram",
to: socialInstagram,
- icon: ,
+ icon: ,
},
{
name: "X",
to: socialX,
- icon: ,
+ icon: ,
},
{
name: "LinkedIn",
to: socialLinkedIn,
- icon: ,
+ icon: ,
},
{
name: "Facebook",
to: socialFacebook,
- icon: ,
+ icon: ,
},
];
diff --git a/app/modules/layout.tsx b/app/modules/layout.tsx
index b7f1421f..56a69812 100644
--- a/app/modules/layout.tsx
+++ b/app/modules/layout.tsx
@@ -1,4 +1,5 @@
import { Header } from "~/components/header";
+import { ScrollingAnnouncement } from "~/components/header/scrolling-announcement";
import { Footer } from "./footer";
export function Layout({
@@ -14,6 +15,7 @@ export function Layout({
Skip to content
+
{children}
diff --git a/app/modules/sort-filter.tsx b/app/modules/sort-filter.tsx
deleted file mode 100644
index 4820c88c..00000000
--- a/app/modules/sort-filter.tsx
+++ /dev/null
@@ -1,374 +0,0 @@
-import {
- Disclosure,
- Menu,
- MenuButton,
- MenuItem,
- MenuItems,
-} from "@headlessui/react";
-import type { Location } from "@remix-run/react";
-import {
- Link,
- useLocation,
- useNavigate,
- useSearchParams,
-} from "@remix-run/react";
-import type {
- Filter,
- ProductFilter,
-} from "@shopify/hydrogen/storefront-api-types";
-import type { SyntheticEvent } from "react";
-import { useMemo, useState } from "react";
-import useDebounce from "react-use/esm/useDebounce";
-import { IconCaret, IconFilters, IconXMark } from "~/modules/icon";
-import { Heading, Text } from "~/modules/text";
-
-export type AppliedFilter = {
- label: string;
- filter: ProductFilter;
-};
-
-export type SortParam =
- | "price-low-high"
- | "price-high-low"
- | "best-selling"
- | "newest"
- | "featured";
-
-type Props = {
- filters: Filter[];
- appliedFilters?: AppliedFilter[];
- children: React.ReactNode;
- collections?: Array<{ handle: string; title: string }>;
-};
-export const FILTER_URL_PREFIX = "filter.";
-
-export function SortFilter({
- filters,
- appliedFilters = [],
- children,
- collections = [],
-}: Props) {
- const [isOpen, setIsOpen] = useState(false);
- return (
- <>
-
-
-
-
-
- >
- );
-}
-
-export function FiltersDrawer({
- filters = [],
- appliedFilters = [],
-}: Omit) {
- const [params] = useSearchParams();
- const location = useLocation();
-
- const filterMarkup = (filter: Filter, option: Filter["values"][0]) => {
- switch (filter.type) {
- case "PRICE_RANGE": {
- const priceFilter = params.get(`${FILTER_URL_PREFIX}price`);
- const price = priceFilter
- ? (JSON.parse(priceFilter) as ProductFilter["price"])
- : undefined;
- const min = Number.isNaN(Number(price?.min))
- ? undefined
- : Number(price?.min);
- const max = Number.isNaN(Number(price?.max))
- ? undefined
- : Number(price?.max);
-
- return ;
- }
-
- default: {
- const to = getFilterLink(option.input as string, params, location);
- return (
-
- {option.label}
-
- );
- }
- }
- };
-
- return (
- <>
-
- >
- );
-}
-
-function AppliedFilters({ filters = [] }: { filters: AppliedFilter[] }) {
- const [params] = useSearchParams();
- const location = useLocation();
- return (
- <>
-
- Applied filters
-
-
- {filters.map((filter: AppliedFilter) => {
- return (
-
- {filter.label}
-
-
-
-
- );
- })}
-
- >
- );
-}
-
-function getAppliedFilterLink(
- filter: AppliedFilter,
- params: URLSearchParams,
- location: Location,
-) {
- let paramsClone = new URLSearchParams(params);
- for (let [key, value] of Object.entries(filter.filter)) {
- let fullKey = FILTER_URL_PREFIX + key;
- paramsClone.delete(fullKey, JSON.stringify(value));
- }
- return `${location.pathname}?${paramsClone.toString()}`;
-}
-
-function getSortLink(
- sort: SortParam,
- params: URLSearchParams,
- location: Location,
-) {
- params.set("sort", sort);
- return `${location.pathname}?${params.toString()}`;
-}
-
-function getFilterLink(
- rawInput: string | ProductFilter,
- params: URLSearchParams,
- location: ReturnType,
-) {
- const paramsClone = new URLSearchParams(params);
- const newParams = filterInputToParams(rawInput, paramsClone);
- return `${location.pathname}?${newParams.toString()}`;
-}
-
-const PRICE_RANGE_FILTER_DEBOUNCE = 500;
-
-function PriceRangeFilter({ max, min }: { max?: number; min?: number }) {
- const location = useLocation();
- const params = useMemo(
- () => new URLSearchParams(location.search),
- [location.search],
- );
- const navigate = useNavigate();
-
- const [minPrice, setMinPrice] = useState(min);
- const [maxPrice, setMaxPrice] = useState(max);
-
- useDebounce(
- () => {
- if (minPrice === undefined && maxPrice === undefined) {
- params.delete(`${FILTER_URL_PREFIX}price`);
- navigate(`${location.pathname}?${params.toString()}`);
- return;
- }
-
- const price = {
- ...(minPrice === undefined ? {} : { min: minPrice }),
- ...(maxPrice === undefined ? {} : { max: maxPrice }),
- };
- const newParams = filterInputToParams({ price }, params);
- navigate(`${location.pathname}?${newParams.toString()}`);
- },
- PRICE_RANGE_FILTER_DEBOUNCE,
- [minPrice, maxPrice],
- );
-
- const onChangeMax = (event: SyntheticEvent) => {
- const value = (event.target as HTMLInputElement).value;
- const newMaxPrice = Number.isNaN(Number.parseFloat(value))
- ? undefined
- : Number.parseFloat(value);
- setMaxPrice(newMaxPrice);
- };
-
- const onChangeMin = (event: SyntheticEvent) => {
- const value = (event.target as HTMLInputElement).value;
- const newMinPrice = Number.isNaN(Number.parseFloat(value))
- ? undefined
- : Number.parseFloat(value);
- setMinPrice(newMinPrice);
- };
-
- return (
-
-
-
-
- );
-}
-
-function filterInputToParams(
- rawInput: string | ProductFilter,
- params: URLSearchParams,
-) {
- let input =
- typeof rawInput === "string"
- ? (JSON.parse(rawInput) as ProductFilter)
- : rawInput;
-
- for (let [key, value] of Object.entries(input)) {
- if (params.has(`${FILTER_URL_PREFIX}${key}`, JSON.stringify(value))) {
- continue;
- }
- if (key === "price") {
- // For price, we want to overwrite
- params.set(`${FILTER_URL_PREFIX}${key}`, JSON.stringify(value));
- } else {
- params.append(`${FILTER_URL_PREFIX}${key}`, JSON.stringify(value));
- }
- }
-
- return params;
-}
-
-export default function SortMenu() {
- const items: { label: string; key: SortParam }[] = [
- { label: "Featured", key: "featured" },
- {
- label: "Price: Low - High",
- key: "price-low-high",
- },
- {
- label: "Price: High - Low",
- key: "price-high-low",
- },
- {
- label: "Best Selling",
- key: "best-selling",
- },
- {
- label: "Newest",
- key: "newest",
- },
- ];
- const [params] = useSearchParams();
- const location = useLocation();
- const activeItem = items.find((item) => item.key === params.get("sort"));
-
- return (
-
- );
-}
diff --git a/app/routes/($locale).account.tsx b/app/routes/($locale).account.tsx
index 9ba6cb58..76e1c657 100644
--- a/app/routes/($locale).account.tsx
+++ b/app/routes/($locale).account.tsx
@@ -1,3 +1,4 @@
+import { SignOut } from "@phosphor-icons/react";
import {
Await,
Form,
@@ -13,7 +14,6 @@ import type {
OrderCardFragment,
} from "customer-accountapi.generated";
import { Suspense } from "react";
-import { IconSignOut } from "~/components/icons";
import Link from "~/components/link";
import { CACHE_NONE, routeHeaders } from "~/data/cache";
import { CUSTOMER_DETAILS_QUERY } from "~/graphql/customer-account/customer-details-query";
@@ -108,7 +108,7 @@ function Account({ customer, heading, featuredDataPromise }: AccountType) {
type="submit"
className="text-body-subtle group flex gap-2 items-center"
>
-
+
Sign out
diff --git a/app/routes/($locale).collections.$collectionHandle.tsx b/app/routes/($locale).collections.$collectionHandle.tsx
index 5557b7ce..bdb50344 100644
--- a/app/routes/($locale).collections.$collectionHandle.tsx
+++ b/app/routes/($locale).collections.$collectionHandle.tsx
@@ -5,10 +5,7 @@ import {
getPaginationVariables,
getSeoMeta,
} from "@shopify/hydrogen";
-import type {
- ProductCollectionSortKeys,
- ProductFilter,
-} from "@shopify/hydrogen/storefront-api-types";
+import type { ProductFilter } from "@shopify/hydrogen/storefront-api-types";
import {
type LoaderFunctionArgs,
type MetaArgs,
@@ -20,11 +17,10 @@ import invariant from "tiny-invariant";
import { routeHeaders } from "~/data/cache";
import { COLLECTION_QUERY } from "~/data/queries";
import { getSortValuesFromParam } from "~/lib/collections";
-import { PAGINATION_SIZE } from "~/lib/const";
+import { FILTER_URL_PREFIX, PAGINATION_SIZE } from "~/lib/const";
+import type { SortParam } from "~/lib/filter";
import { seoPayload } from "~/lib/seo.server";
import { parseAsCurrency } from "~/lib/utils";
-import type { SortParam } from "~/modules/sort-filter";
-import { FILTER_URL_PREFIX } from "~/modules/sort-filter";
import { WeaverseContent } from "~/weaverse";
export let headers = routeHeaders;
@@ -63,6 +59,9 @@ export async function loader({ params, request, context }: LoaderFunctionArgs) {
reverse,
country: context.storefront.i18n.country,
language: context.storefront.i18n.language,
+ // Query custom banner stored in Shopify's collection metafields
+ customBannerNamespace: "custom",
+ customBannerKey: "collection_banner",
},
})
.catch((e) => {
diff --git a/app/sections/ali-reviews/rating.tsx b/app/sections/ali-reviews/rating.tsx
index 80ef8344..6a0efc25 100644
--- a/app/sections/ali-reviews/rating.tsx
+++ b/app/sections/ali-reviews/rating.tsx
@@ -1,20 +1,16 @@
-import {
- IconStar,
- IconStarFilled,
- IconStarHalfFilled,
-} from "~/components/icons";
+import { Star, StarHalf } from "@phosphor-icons/react";
export function Rating({ rating }: { rating: number }) {
return (
{Array.from({ length: 5 }).map((_, i) => {
if (rating >= i + 1) {
- return ;
+ return ;
}
if (rating >= i + 0.5) {
- return ;
+ return ;
}
- return ;
+ return ;
})}
);
diff --git a/app/sections/ali-reviews/review-item.tsx b/app/sections/ali-reviews/review-item.tsx
index bac8d0cb..c13fb46d 100644
--- a/app/sections/ali-reviews/review-item.tsx
+++ b/app/sections/ali-reviews/review-item.tsx
@@ -1,7 +1,8 @@
+import { SealCheck } from "@phosphor-icons/react";
import clsx from "clsx";
import { useState } from "react";
import ReactCountryFlag from "react-country-flag";
-import { IconSealCheck, IconX } from "~/components/icons";
+import { IconX } from "~/components/icons";
import { Rating } from "./rating";
export type AliReview = {
@@ -79,7 +80,7 @@ export function ReviewItem(props: ReviewItemProps) {
{showVerifiedBadge && (
)}
diff --git a/app/sections/collection-filters/index.tsx b/app/sections/collection-filters/index.tsx
index 588a53c3..2026db2e 100644
--- a/app/sections/collection-filters/index.tsx
+++ b/app/sections/collection-filters/index.tsx
@@ -7,8 +7,13 @@ import { Section, type SectionProps, layoutInputs } from "~/components/section";
import { Filters } from "./filters";
import { ProductsPagination } from "./products-pagination";
import { ToolsBar } from "./tools-bar";
+import { Image } from "@shopify/hydrogen";
export interface CollectionFiltersData {
+ showBreadcrumb: boolean;
+ showDescription: boolean;
+ showBanner: boolean;
+ bannerHeightDesktop: number;
enableSort: boolean;
showProductsCount: boolean;
enableFilter: boolean;
@@ -28,6 +33,10 @@ interface CollectionFiltersProps extends SectionProps, CollectionFiltersData {}
let CollectionFilters = forwardRef
(
(props, sectionRef) => {
let {
+ showBreadcrumb,
+ showDescription,
+ showBanner,
+ bannerHeightDesktop,
enableSort,
showFiltersCount,
enableFilter,
@@ -61,17 +70,46 @@ let CollectionFilters = forwardRef(
}, [productsPerRowDesktop, productsPerRowMobile]);
if (collection?.products && collections) {
+ let banner = collection.metafield
+ ? collection.metafield.reference.image
+ : collection.image;
return (
-
-
-
- Home
-
- /
- {collection.title}
-
+
+ {showBreadcrumb && (
+
+
+ Home
+
+ /
+ {collection.title}
+
+ )}
{collection.title}
+ {showDescription && collection.description && (
+
+ {collection.description}
+
+ )}
+ {showBanner && banner && (
+
+
+
+ )}
{
- return inp.name !== "borderRadius" && inp.name !== "gap";
- }),
+ inputs: [
+ ...layoutInputs.filter((inp) => {
+ return inp.name !== "borderRadius" && inp.name !== "gap";
+ }),
+ {
+ type: "switch",
+ name: "showBreadcrumb",
+ label: "Show breadcrumb",
+ defaultValue: true,
+ },
+ {
+ type: "switch",
+ name: "showDescription",
+ label: "Show description",
+ defaultValue: false,
+ },
+ {
+ type: "switch",
+ name: "showBanner",
+ label: "Show banner",
+ defaultValue: true,
+ helpText:
+ "A custom banner can be stored under `custom.collection_banner` metafield.",
+ },
+ {
+ type: "range",
+ name: "bannerHeightDesktop",
+ label: "Banner height (desktop)",
+ defaultValue: 350,
+ configs: {
+ min: 100,
+ max: 600,
+ step: 1,
+ },
+ condition: "showBanner.eq.true",
+ },
+ {
+ type: "range",
+ name: "bannerHeightMobile",
+ label: "Banner height (mobile)",
+ defaultValue: 200,
+ configs: {
+ min: 50,
+ max: 400,
+ step: 1,
+ },
+ condition: "showBanner.eq.true",
+ },
+ ],
},
{
group: "Filtering and sorting",
diff --git a/app/sections/collection-filters/sort.tsx b/app/sections/collection-filters/sort.tsx
index fc24429f..3a0a7ec7 100644
--- a/app/sections/collection-filters/sort.tsx
+++ b/app/sections/collection-filters/sort.tsx
@@ -40,9 +40,10 @@ export function Sort() {
return (
-
+
Sort by: {currentSort.label}
+ Sort
diff --git a/app/sections/judgeme-reviews/review-form.tsx b/app/sections/judgeme-reviews/review-form.tsx
index 7348fd5c..5f78fe2c 100644
--- a/app/sections/judgeme-reviews/review-form.tsx
+++ b/app/sections/judgeme-reviews/review-form.tsx
@@ -1,8 +1,8 @@
+import { Star } from "@phosphor-icons/react";
import { useFetcher, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
import { type FormEvent, useEffect, useRef, useState } from "react";
import { Button } from "~/components/button";
-import { IconStar, IconStarFilled } from "~/components/icons";
import type { JudgemeReviewsData } from "~/lib/judgeme";
import { StarRating } from "~/modules/star-rating";
import type { ProductLoaderType } from "~/routes/($locale).products.$productHandle";
@@ -122,12 +122,11 @@ export function ReviewForm({
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(0)}
aria-label={`Rate ${ratingValue} out of 5 stars`}
- role="button"
>
{ratingValue <= (hover || rating) ? (
-
+
) : (
-
+
)}
);
diff --git a/app/sections/newsletter/newsletter-form.tsx b/app/sections/newsletter/newsletter-form.tsx
index 0697d47a..7af2d817 100644
--- a/app/sections/newsletter/newsletter-form.tsx
+++ b/app/sections/newsletter/newsletter-form.tsx
@@ -1,3 +1,4 @@
+import { EnvelopeSimple } from "@phosphor-icons/react";
import { useFetcher } from "@remix-run/react";
import type {
HydrogenComponentProps,
@@ -6,7 +7,6 @@ import type {
import clsx from "clsx";
import { forwardRef } from "react";
import { Button } from "~/components/button";
-import { IconEnvelopeSimple } from "~/components/icons";
import type { CustomerApiPlayLoad } from "~/routes/($locale).api.customer";
interface NewsLetterInputProps extends HydrogenComponentProps {
@@ -35,7 +35,7 @@ let NewsLetterForm = forwardRef(
data-motion="fade-up"
>
-
+
(
target="_blank"
className="text-gray-500 hover:text-gray-900"
>
-
+
)}
@@ -83,7 +79,7 @@ let TeamMembers = forwardRef
(
target="_blank"
className="text-gray-500 hover:text-gray-900"
>
-
+
)}
@@ -94,7 +90,7 @@ let TeamMembers = forwardRef(
target="_blank"
className="text-gray-500 hover:text-gray-900"
>
-
+
)}
diff --git a/app/sections/product-list.tsx b/app/sections/product-list.tsx
index 195c63ce..f1a18f41 100644
--- a/app/sections/product-list.tsx
+++ b/app/sections/product-list.tsx
@@ -8,8 +8,8 @@ import { forwardRef } from "react";
import { COLLECTION_QUERY } from "~/data/queries";
import { getSortValuesFromParam } from "~/lib/collections";
import { PAGINATION_SIZE } from "~/lib/const";
+import type { SortParam } from "~/lib/filter";
import { ProductSwimlane } from "~/modules/product-swimlane";
-import type { SortParam } from "~/modules/sort-filter";
interface ProductListProps
extends HydrogenComponentProps>> {
diff --git a/package-lock.json b/package-lock.json
index 8671f82c..993c3713 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@weaverse/pilot",
- "version": "3.2.1",
+ "version": "3.2.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@weaverse/pilot",
- "version": "3.2.1",
+ "version": "3.2.2",
"dependencies": {
"@fontsource/poppins": "5.1.0",
"@graphql-codegen/cli": "5.0.3",
diff --git a/package.json b/package.json
index 41200632..23c268c5 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "@weaverse/pilot",
"private": true,
"sideEffects": false,
- "version": "3.2.1",
+ "version": "3.2.2",
"type": "module",
"author": "Weaverse",
"scripts": {
diff --git a/storefrontapi.generated.d.ts b/storefrontapi.generated.d.ts
index 0bf1944a..f799f5b4 100644
--- a/storefrontapi.generated.d.ts
+++ b/storefrontapi.generated.d.ts
@@ -665,6 +665,8 @@ export type CollectionDetailsQueryVariables = StorefrontAPI.Exact<{
endCursor?: StorefrontAPI.InputMaybe<
StorefrontAPI.Scalars['String']['input']
>;
+ customBannerNamespace: StorefrontAPI.Scalars['String']['input'];
+ customBannerKey: StorefrontAPI.Scalars['String']['input'];
}>;
export type CollectionDetailsQuery = {
@@ -674,6 +676,18 @@ export type CollectionDetailsQuery = {
'id' | 'handle' | 'title' | 'description'
> & {
seo: Pick;
+ metafield?: StorefrontAPI.Maybe<
+ Pick<
+ StorefrontAPI.Metafield,
+ 'id' | 'type' | 'description' | 'value'
+ > & {
+ reference?: StorefrontAPI.Maybe<{
+ image?: StorefrontAPI.Maybe<
+ Pick
+ >;
+ }>;
+ }
+ >;
image?: StorefrontAPI.Maybe<
Pick
>;
@@ -1826,7 +1840,7 @@ interface GeneratedQueryTypes {
return: CollectionInfoQuery;
variables: CollectionInfoQueryVariables;
};
- '#graphql\n query CollectionDetails(\n $handle: String!\n $country: CountryCode\n $language: LanguageCode\n $filters: [ProductFilter!]\n $sortKey: ProductCollectionSortKeys!\n $reverse: Boolean\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(country: $country, language: $language) {\n collection(handle: $handle) {\n id\n handle\n title\n description\n seo {\n description\n title\n }\n image {\n id\n url\n width\n height\n altText\n }\n products(\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor,\n filters: $filters,\n sortKey: $sortKey,\n reverse: $reverse\n ) {\n filters {\n id\n label\n type\n values {\n id\n label\n count\n input\n }\n }\n nodes {\n ...ProductCard\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n endCursor\n startCursor\n }\n }\n highestPriceProduct: products(first: 1, sortKey: PRICE, reverse: true) {\n nodes {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n }\n }\n lowestPriceProduct: products(first: 1, sortKey: PRICE) {\n nodes {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n }\n }\n }\n collections(first: 100) {\n edges {\n node {\n title\n handle\n }\n }\n }\n }\n #graphql\n fragment ProductCard on Product {\n id\n title\n publishedAt\n handle\n vendor\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n variants(first: 10) {\n nodes {\n id\n availableForSale\n image {\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n product {\n handle\n title\n }\n sku\n }\n }\n }\n\n': {
+ '#graphql\n query CollectionDetails(\n $handle: String!\n $country: CountryCode\n $language: LanguageCode\n $filters: [ProductFilter!]\n $sortKey: ProductCollectionSortKeys!\n $reverse: Boolean\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n $customBannerNamespace: String!\n $customBannerKey: String!\n ) @inContext(country: $country, language: $language) {\n collection(handle: $handle) {\n id\n handle\n title\n description\n seo {\n description\n title\n }\n metafield(namespace: $customBannerNamespace, key: $customBannerKey) {\n id\n type\n description\n value\n reference {\n ... on MediaImage {\n image {\n id\n url\n }\n }\n }\n }\n image {\n id\n url\n width\n height\n altText\n }\n products(\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor,\n filters: $filters,\n sortKey: $sortKey,\n reverse: $reverse\n ) {\n filters {\n id\n label\n type\n values {\n id\n label\n count\n input\n }\n }\n nodes {\n ...ProductCard\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n endCursor\n startCursor\n }\n }\n highestPriceProduct: products(first: 1, sortKey: PRICE, reverse: true) {\n nodes {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n }\n }\n lowestPriceProduct: products(first: 1, sortKey: PRICE) {\n nodes {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n }\n }\n }\n collections(first: 100) {\n edges {\n node {\n title\n handle\n }\n }\n }\n }\n #graphql\n fragment ProductCard on Product {\n id\n title\n publishedAt\n handle\n vendor\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n variants(first: 10) {\n nodes {\n id\n availableForSale\n image {\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n product {\n handle\n title\n }\n sku\n }\n }\n }\n\n': {
return: CollectionDetailsQuery;
variables: CollectionDetailsQueryVariables;
};
diff --git a/tailwind.config.js b/tailwind.config.js
index b023c22e..62774da3 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -128,15 +128,21 @@ export default {
"screen-no-nav":
"calc(var(--screen-height, 100vh) - var(--height-nav) - var(--initial-topbar-height))",
"screen-dynamic": "var(--screen-height-dynamic, 100vh)",
+ 4.5: "1.125rem",
},
width: {
mobileGallery: "calc(100vw - 3rem)",
page: "var(--page-width, 1280px)",
+ 4.5: "1.125rem",
},
maxWidth: {
page: "var(--page-width, 1280px)",
"prose-narrow": "45ch",
"prose-wide": "80ch",
+ 4.5: "1.125rem",
+ },
+ minWidth: {
+ 4.5: "1.125rem",
},
fontFamily: {
sans: ["Poppins", "ui-sans-serif", "system-ui", "sans-serif"],