From 49fb66ab67234f38d6c2f3c97daa21db8a0cf7cd Mon Sep 17 00:00:00 2001 From: Thomas Cristina de Carvalho Date: Sun, 3 Dec 2023 00:36:53 -0500 Subject: [PATCH] feat:(theme) Add desktopColumns and max products options --- .../app/components/CollectionCard.tsx | 15 +++++++++++- .../app/components/CollectionListGrid.tsx | 19 ++++++++++++--- .../app/components/ProductCard.tsx | 16 +++++++++++-- .../app/components/ProductCardGrid.tsx | 21 ++++++++++++++--- .../sections/CollectionListSection.tsx | 9 +++++--- .../sections/FeaturedCollectionSection.tsx | 7 ++++-- .../app/lib/resolveShopifyPromises.ts | 6 +++-- templates/hydrogen-theme/app/qroq/sections.ts | 3 +++ .../sections/collectionListSection.tsx | 10 ++++++++ .../objects/sections/featuredCollection.tsx | 23 +++++++++++++++++++ 10 files changed, 113 insertions(+), 16 deletions(-) diff --git a/templates/hydrogen-theme/app/components/CollectionCard.tsx b/templates/hydrogen-theme/app/components/CollectionCard.tsx index f178068..f25aa0d 100644 --- a/templates/hydrogen-theme/app/components/CollectionCard.tsx +++ b/templates/hydrogen-theme/app/components/CollectionCard.tsx @@ -1,18 +1,31 @@ import {Link} from '@remix-run/react'; import {Image} from '@shopify/hydrogen'; +import {cx} from 'class-variance-authority'; + import type {CollectionsQuery} from 'storefrontapi.generated'; export function CollectionCard(props: { collection: CollectionsQuery['collections']['nodes'][0]; className?: string; + columns?: number | null; }) { const {collection} = props; + const sizes = cx([ + '(min-width: 1024px)', + props.columns ? `${100 / props.columns}vw,` : '33vw,', + '100vw', + ]); return (
{collection.image && ( - + )}
{collection.title}
diff --git a/templates/hydrogen-theme/app/components/CollectionListGrid.tsx b/templates/hydrogen-theme/app/components/CollectionListGrid.tsx index de32240..ed05cf6 100644 --- a/templates/hydrogen-theme/app/components/CollectionListGrid.tsx +++ b/templates/hydrogen-theme/app/components/CollectionListGrid.tsx @@ -1,17 +1,30 @@ -import type {CollectionsQuery} from 'storefrontapi.generated'; +import type {CSSProperties} from 'react'; import {flattenConnection} from '@shopify/hydrogen'; +import {cx} from 'class-variance-authority'; + +import type {CollectionsQuery} from 'storefrontapi.generated'; import {CollectionCard} from './CollectionCard'; export function CollectionListGrid(props: { collections?: CollectionsQuery['collections']; + columns?: number | null; }) { const collections = flattenConnection(props.collections); + const columnsVar = { + '--columns': props.columns ?? 3, + } as CSSProperties; return collections?.length > 0 ? ( -
    +
      {collections.map((collection) => (
    • - +
    • ))}
    diff --git a/templates/hydrogen-theme/app/components/ProductCard.tsx b/templates/hydrogen-theme/app/components/ProductCard.tsx index 3cd5678..d1b216c 100644 --- a/templates/hydrogen-theme/app/components/ProductCard.tsx +++ b/templates/hydrogen-theme/app/components/ProductCard.tsx @@ -1,20 +1,32 @@ import {Link} from '@remix-run/react'; import {flattenConnection, Image, Money} from '@shopify/hydrogen'; +import {cx} from 'class-variance-authority'; import type {ProductCardFragment} from 'storefrontapi.generated'; export function ProductCard(props: { product: ProductCardFragment; className?: string; + columns?: number | null; }) { - const {product} = props; + const {product, columns} = props; const firstVariant = flattenConnection(product.variants)[0]; + const sizes = cx([ + '(min-width: 1024px)', + columns ? `${100 / columns}vw,` : '33vw,', + '100vw', + ]); return (
    {firstVariant.image && ( - + )}
    {product.title}
    diff --git a/templates/hydrogen-theme/app/components/ProductCardGrid.tsx b/templates/hydrogen-theme/app/components/ProductCardGrid.tsx index 555a165..d1d8641 100644 --- a/templates/hydrogen-theme/app/components/ProductCardGrid.tsx +++ b/templates/hydrogen-theme/app/components/ProductCardGrid.tsx @@ -1,14 +1,29 @@ +import type {CSSProperties} from 'react'; +import {cx} from 'class-variance-authority'; + import type {ProductCardFragment} from 'storefrontapi.generated'; import {ProductCard} from './ProductCard'; -export function ProductCardGrid(props: {products: ProductCardFragment[]}) { +export function ProductCardGrid(props: { + products: ProductCardFragment[]; + columns?: number | null; +}) { const {products} = props; + const columnsVar = { + '--columns': props.columns ?? 3, + } as CSSProperties; return products.length > 0 ? ( -
      +
        {products.map((product) => (
      • - +
      • ))}
      diff --git a/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx b/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx index 802ecd7..3a4ffba 100644 --- a/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx +++ b/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx @@ -1,10 +1,10 @@ import type {TypeFromSelection} from 'groqd'; +import {Suspense} from 'react'; +import {Await, useLoaderData} from '@remix-run/react'; import type {COLLECTION_LIST_SECTION_FRAGMENT} from '~/qroq/sections'; import type {loader as indexLoader} from '../../routes/_index'; import type {SectionDefaultProps} from '~/lib/type'; -import {Await, useLoaderData} from '@remix-run/react'; -import {Suspense} from 'react'; import {CollectionListGrid} from '../CollectionListGrid'; type CollectionListSectionProps = TypeFromSelection< @@ -34,7 +34,10 @@ export function CollectionListSection( return (
      - +
      ); }} diff --git a/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx b/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx index df6389c..79e2795 100644 --- a/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx +++ b/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx @@ -1,12 +1,12 @@ import type {TypeFromSelection} from 'groqd'; import {Suspense} from 'react'; import {Await, useLoaderData} from '@remix-run/react'; +import {flattenConnection} from '@shopify/hydrogen'; import type {FEATURED_COLLECTION_SECTION_FRAGMENT} from '~/qroq/sections'; import type {loader as indexLoader} from '../../routes/_index'; import type {SectionDefaultProps} from '~/lib/type'; import {ProductCardGrid} from '../ProductCardGrid'; -import {flattenConnection} from '@shopify/hydrogen'; type FeaturedCollectionSectionProps = TypeFromSelection< typeof FEATURED_COLLECTION_SECTION_FRAGMENT @@ -38,7 +38,10 @@ export function FeaturedCollectionSection(

      {collection.title}

      - +
      ) : null; diff --git a/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts b/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts index 784d826..f74ed61 100644 --- a/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts +++ b/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts @@ -1,5 +1,6 @@ -import {parseGid, type Storefront} from '@shopify/hydrogen'; +import type {Storefront} from '@shopify/hydrogen'; import type {InferType} from 'groqd'; +import {parseGid} from '@shopify/hydrogen'; import type { CollectionsQuery, @@ -45,6 +46,7 @@ function resolveFeaturedCollectionPromise({ document.data?.sections?.forEach((section) => { if (section._type === 'featuredCollectionSection') { const gid = section.collection?.store.gid; + const first = section.maxProducts || 3; if (!gid) { return undefined; @@ -53,7 +55,7 @@ function resolveFeaturedCollectionPromise({ const promise = storefront.query(FEATURED_COLLECTION_QUERY, { variables: { id: gid, - first: 4, + first, country: storefront.i18n.country, language: storefront.i18n.language, }, diff --git a/templates/hydrogen-theme/app/qroq/sections.ts b/templates/hydrogen-theme/app/qroq/sections.ts index 1ab847c..4d3fcdf 100644 --- a/templates/hydrogen-theme/app/qroq/sections.ts +++ b/templates/hydrogen-theme/app/qroq/sections.ts @@ -74,6 +74,8 @@ export const FEATURED_COLLECTION_SECTION_FRAGMENT = { }), }) .nullable(), + maxProducts: q.number().nullable(), + desktopColumns: q.number().nullable(), settings: SECTION_SETTINGS_FRAGMENT, } satisfies Selection; @@ -93,6 +95,7 @@ export const COLLECTION_LIST_SECTION_FRAGMENT = { }), }) .nullable(), + desktopColumns: q.number().nullable(), settings: SECTION_SETTINGS_FRAGMENT, } satisfies Selection; diff --git a/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx b/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx index 017ad13..f837749 100644 --- a/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx +++ b/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx @@ -24,6 +24,16 @@ export default defineField({ return checkForDuplicates(array); }), }), + defineField({ + name: 'desktopColumns', + title: 'Number of columns on desktop', + type: 'rangeSlider', + options: { + min: 1, + max: 5, + }, + validation: (Rule: any) => Rule.required().min(1).max(5), + }), defineField({ type: 'sectionSettings', name: 'settings', diff --git a/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx b/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx index 6eab68d..2e0c5d1 100644 --- a/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx +++ b/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx @@ -10,11 +10,34 @@ export default defineField({ type: 'reference', to: [{type: 'collection'}], }), + defineField({ + name: 'maxProducts', + title: 'Maximum products to show', + type: 'rangeSlider', + options: { + min: 1, + max: 25, + }, + validation: (Rule: any) => Rule.required().min(1).max(25), + }), + defineField({ + name: 'desktopColumns', + title: 'Number of columns on desktop', + type: 'rangeSlider', + options: { + min: 1, + max: 5, + }, + validation: (Rule: any) => Rule.required().min(1).max(5), + }), defineField({ type: 'sectionSettings', name: 'settings', }), ], + initialValue: { + maxProducts: 6, + }, preview: { select: { collection: 'collection.store',