From 1b8830c969fa0c9733c1aceb0d7644e9680e9222 Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 15:05:45 -0300 Subject: [PATCH 1/6] feat: removes suspense --- .../src/components/search/Filter/Filter.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/search/Filter/Filter.tsx b/packages/core/src/components/search/Filter/Filter.tsx index 3a21dae689..a12c000dfb 100644 --- a/packages/core/src/components/search/Filter/Filter.tsx +++ b/packages/core/src/components/search/Filter/Filter.tsx @@ -1,6 +1,5 @@ import { useUI } from '@faststore/ui' import type { Filter_FacetsFragment } from '@generated/graphql' -import { Suspense } from 'react' import { gql } from '@generated' import { ProductGalleryProps } from 'src/components/ui/ProductGallery/ProductGallery' @@ -50,16 +49,14 @@ function Filter({ )} {displayFilter && ( - - - + )} ) From 69bf2ee199113079f7f3a149fdbddb4d210a9492 Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 15:07:41 -0300 Subject: [PATCH 2/6] feat: removes lazy and import FilterSlider and FilterDesktop using next/dynamic --- .../ProductGallery/DefaultComponents.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts b/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts index 48a901d9ea..608f82c163 100644 --- a/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts +++ b/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts @@ -1,18 +1,26 @@ -import { lazy } from 'react' import { Button as UIButton, + Icon as UIIcon, LinkButton as UILinkButton, Skeleton as UISkeleton, - Icon as UIIcon, } from '@faststore/ui' +import dynamic from 'next/dynamic' + import ProductCard from 'src/components/product/ProductCard' -import FilterDesktop from 'src/components/search/Filter/FilterDesktop' import EmptyGallery from './EmptyGallery' -const FilterSlider = lazy( - () => import('src/components/search/Filter/FilterSlider') +const FilterDesktop = dynamic( + () => + /* webpackChunkName: "FilterDesktop" */ + import('src/components/search/Filter/FilterDesktop') ) +const FilterSlider = dynamic( + () => + /* webpackChunkName: "FilterSlider" */ + import('src/components/search/Filter/FilterSlider') +) + export const ProductGalleryDefaultComponents = { MobileFilterButton: UIButton, FilterIcon: UIIcon, From 6a9efd66cbfa64f0bcc9f70ac0e143252844fb2d Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 15:22:29 -0300 Subject: [PATCH 3/6] feat: lift Filter component and controls lazy loading --- .../ui/ProductGallery/ProductGallery.tsx | 62 ++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/packages/core/src/components/ui/ProductGallery/ProductGallery.tsx b/packages/core/src/components/ui/ProductGallery/ProductGallery.tsx index 64b26d7492..b14528a8ac 100644 --- a/packages/core/src/components/ui/ProductGallery/ProductGallery.tsx +++ b/packages/core/src/components/ui/ProductGallery/ProductGallery.tsx @@ -4,11 +4,11 @@ import type { MouseEvent } from 'react' import { Suspense, lazy } from 'react' import { useUI } from '@faststore/ui' -import Filter from 'src/components/search/Filter' import Sort from 'src/components/search/Sort' -import FilterSkeleton from 'src/components/skeletons/FilterSkeleton' import ProductGridSkeleton from 'src/components/skeletons/ProductGridSkeleton' +import dynamic from 'next/dynamic' + import { ProductCardProps } from 'src/components/product/ProductCard' import { FilterSliderProps } from 'src/components/search/Filter/FilterSlider' import { SortProps } from 'src/components/search/Sort/Sort' @@ -21,8 +21,18 @@ import { import { useProductsPrefetch } from 'src/sdk/product/useProductsPrefetch' import { useDelayedFacets } from 'src/sdk/search/useDelayedFacets' import { useDelayedPagination } from 'src/sdk/search/useDelayedPagination' +import { useFilter } from 'src/sdk/search/useFilter' +import useScreenResize from 'src/sdk/ui/useScreenResize' const ProductGalleryPage = lazy(() => import('./ProductGalleryPage')) +const FilterSkeleton = dynamic( + () => + import( + /* webpackChunkName: "FilterSkeleton" */ + 'src/components/skeletons/FilterSkeleton' + ) +) + const GalleryPageSkeleton = export interface ProductGalleryProps { @@ -69,7 +79,7 @@ function ProductGallery({ totalCount, searchTermLabel, totalCountLabel, - filter, + filter: filterCmsData, previousPageButton, loadMorePageButton, sortBySelector, @@ -84,20 +94,25 @@ function ProductGallery({ PrevIcon, ResultsCountSkeleton, SortSkeleton, + __experimentalFilterDesktop: FilterDesktop, + __experimentalFilterSlider: FilterSlider, } = useOverrideComponents<'ProductGallery'>() - const { openFilter } = useUI() + const { openFilter, filter: displayFilter } = useUI() const { pages, addNextPage, addPrevPage, itemsPerPage } = useSearch() const context = usePage() const data = context?.data const facets = useDelayedFacets(data) ?? [] const { next, prev } = useDelayedPagination(totalCount) + const { isDesktop } = useScreenResize() + useProductsPrefetch(prev ? prev.cursor : null) useProductsPrefetch(next ? next.cursor : null) const hasFacetsLoaded = Boolean(data?.search?.facets) const hasProductsLoaded = Boolean(data?.search?.products) + const filter = useFilter(facets) return (
@@ -115,13 +130,32 @@ function ProductGallery({ data-fs-product-listing-content-grid data-fs-content="product-gallery" > -
- - {hasFacetsLoaded && facets?.length > 0 && ( - - )} - -
+ {isDesktop && ( +
+ + {hasFacetsLoaded && facets?.length > 0 && ( +
+ +
+ )} +
+
+ )} + {!isDesktop && displayFilter && ( +
+ +
+ )}
@@ -183,7 +217,7 @@ function ProductGallery({ // This decision can be reviewed later if needed onClick={openFilter} > - {filter?.mobileOnly?.filterButton?.label} + {filterCmsData?.mobileOnly?.filterButton?.label} )} From 41f7c85b2089e061da65e91db0e14e97bb9eda2b Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 15:29:36 -0300 Subject: [PATCH 4/6] feat: removes generic filter after lift state --- .../src/components/search/Filter/Filter.tsx | 98 ------------------- .../search/Filter/FilterDesktop.tsx | 34 +++++++ .../src/components/search/Filter/index.ts | 2 +- 3 files changed, 35 insertions(+), 99 deletions(-) delete mode 100644 packages/core/src/components/search/Filter/Filter.tsx diff --git a/packages/core/src/components/search/Filter/Filter.tsx b/packages/core/src/components/search/Filter/Filter.tsx deleted file mode 100644 index a12c000dfb..0000000000 --- a/packages/core/src/components/search/Filter/Filter.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useUI } from '@faststore/ui' -import type { Filter_FacetsFragment } from '@generated/graphql' - -import { gql } from '@generated' -import { ProductGalleryProps } from 'src/components/ui/ProductGallery/ProductGallery' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' -import { useFilter } from 'src/sdk/search/useFilter' -import useScreenResize from 'src/sdk/ui/useScreenResize' - -interface Props { - /** - * CMS defined data to be used in filter component. - */ - filter: ProductGalleryProps['filter'] - /** - * The array that represents the details of every facet. - */ - facets: Filter_FacetsFragment[] - /** - * ID to find this component in testing tools (e.g.: cypress, - * testing-library, and jest). - */ - testId?: string -} - -function Filter({ - facets: allFacets, - testId = 'fs-filter', - filter: filterCmsData, -}: Props) { - const { - __experimentalFilterDesktop: FilterDesktop, - __experimentalFilterSlider: FilterSlider, - } = useOverrideComponents<'ProductGallery'>() - - const filter = useFilter(allFacets) - const { filter: displayFilter } = useUI() - const { isDesktop } = useScreenResize() - - return ( - <> - {isDesktop && ( - - )} - - {displayFilter && ( - - )} - - ) -} - -export const fragment = gql(` - fragment Filter_facets on StoreFacet { - ... on StoreFacetRange { - key - label - - min { - selected - absolute - } - - max { - selected - absolute - } - - __typename - } - ... on StoreFacetBoolean { - key - label - values { - label - value - selected - quantity - } - - __typename - } - } -`) - -export default Filter diff --git a/packages/core/src/components/search/Filter/FilterDesktop.tsx b/packages/core/src/components/search/Filter/FilterDesktop.tsx index 0b0646534c..3cdd981769 100644 --- a/packages/core/src/components/search/Filter/FilterDesktop.tsx +++ b/packages/core/src/components/search/Filter/FilterDesktop.tsx @@ -7,6 +7,7 @@ import { FilterFacetRange as UIFilterFacetRange, FilterFacets as UIFilterFacets, } from '@faststore/ui' +import { gql } from '@generated/gql' import type { Filter_FacetsFragment } from '@generated/graphql' import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice' import { useFilter } from 'src/sdk/search/useFilter' @@ -110,4 +111,37 @@ function FilterDesktop({ ) } +export const fragment = gql(` + fragment Filter_facets on StoreFacet { + ... on StoreFacetRange { + key + label + + min { + selected + absolute + } + + max { + selected + absolute + } + + __typename + } + ... on StoreFacetBoolean { + key + label + values { + label + value + selected + quantity + } + + __typename + } + } +`) + export default FilterDesktop diff --git a/packages/core/src/components/search/Filter/index.ts b/packages/core/src/components/search/Filter/index.ts index efe74e9205..a87e2e962d 100644 --- a/packages/core/src/components/search/Filter/index.ts +++ b/packages/core/src/components/search/Filter/index.ts @@ -1,2 +1,2 @@ -export { default } from './Filter' +export { default as FilterDesktop } from './FilterDesktop' export { default as FilterSlider } from './FilterSlider' From c41310a420034799900b2e192ab7247e90a073b0 Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 15:35:32 -0300 Subject: [PATCH 5/6] feat: dynamic import some components and sections --- .../components/search/Filter/FilterSlider.tsx | 35 ++++++++++++++----- .../ProductGallery/DefaultComponents.ts | 12 +++++-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/core/src/components/search/Filter/FilterSlider.tsx b/packages/core/src/components/search/Filter/FilterSlider.tsx index 1600ace297..37b1db565d 100644 --- a/packages/core/src/components/search/Filter/FilterSlider.tsx +++ b/packages/core/src/components/search/Filter/FilterSlider.tsx @@ -1,14 +1,33 @@ +import dynamic from 'next/dynamic' + import { useSearch } from '@faststore/sdk' -import { - Filter as UIFilter, - FilterFacetBoolean as UIFilterFacetBoolean, - FilterFacetBooleanItem as UIFilterFacetBooleanItem, - FilterFacetRange as UIFilterFacetRange, - FilterFacets as UIFilterFacets, - FilterSlider as UIFilterSlider, -} from '@faststore/ui' import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice' +const UIFilter = dynamic(() => + /* webpackChunkName: "UIFilter" */ + import('@faststore/ui').then((mod) => mod.Filter) +) +const UIFilterFacetBoolean = dynamic(() => + /* webpackChunkName: "UIFilterFacetBoolean" */ + import('@faststore/ui').then((mod) => mod.FilterFacetBoolean) +) +const UIFilterFacetBooleanItem = dynamic(() => + /* webpackChunkName: "UIFilterFacetBooleanItem" */ + import('@faststore/ui').then((mod) => mod.FilterFacetBooleanItem) +) +const UIFilterFacetRange = dynamic(() => + /* webpackChunkName: "UIFilterFacetRange" */ + import('@faststore/ui').then((mod) => mod.FilterFacetRange) +) +const UIFilterFacets = dynamic(() => + /* webpackChunkName: "UIFilterFacets" */ + import('@faststore/ui').then((mod) => mod.FilterFacets) +) +const UIFilterSlider = dynamic(() => + /* webpackChunkName: "UIFilterSlider" */ + import('@faststore/ui').then((mod) => mod.FilterSlider) +) + import type { Filter_FacetsFragment } from '@generated/graphql' import type { useFilter } from 'src/sdk/search/useFilter' diff --git a/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts b/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts index 608f82c163..26ab6e974b 100644 --- a/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts +++ b/packages/core/src/components/sections/ProductGallery/DefaultComponents.ts @@ -7,8 +7,16 @@ import { import dynamic from 'next/dynamic' -import ProductCard from 'src/components/product/ProductCard' -import EmptyGallery from './EmptyGallery' +const ProductCard = dynamic( + () => + /* webpackChunkName: "ProductCard" */ + import('src/components/product/ProductCard') +) +const EmptyGallery = dynamic( + () => + /* webpackChunkName: "EmptyGallery" */ + import('./EmptyGallery') +) const FilterDesktop = dynamic( () => From 8f15af4aa11d601bc7c46b458661d32d54c6bda3 Mon Sep 17 00:00:00 2001 From: eduardoformiga Date: Fri, 13 Dec 2024 16:33:52 -0300 Subject: [PATCH 6/6] fix: adds generics to dynamic props --- .../components/search/Filter/FilterSlider.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/search/Filter/FilterSlider.tsx b/packages/core/src/components/search/Filter/FilterSlider.tsx index 37b1db565d..e3b2733ff4 100644 --- a/packages/core/src/components/search/Filter/FilterSlider.tsx +++ b/packages/core/src/components/search/Filter/FilterSlider.tsx @@ -3,27 +3,37 @@ import dynamic from 'next/dynamic' import { useSearch } from '@faststore/sdk' import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice' -const UIFilter = dynamic(() => +import type { + FilterFacetBooleanItemProps as UIFilterFacetBooleanItemProps, + FilterFacetRangeProps as UIFilterFacetRangeProps, + FilterFacetsProps as UIFilterFacetsProps, + FilterProps as UIFilterProps, + FilterSliderProps as UIFilterSliderProps, +} from '@faststore/ui' + +const UIFilter = dynamic<{ children: React.ReactNode } & UIFilterProps>(() => /* webpackChunkName: "UIFilter" */ import('@faststore/ui').then((mod) => mod.Filter) ) -const UIFilterFacetBoolean = dynamic(() => +const UIFilterFacetBoolean = dynamic<{ children: React.ReactNode }>(() => /* webpackChunkName: "UIFilterFacetBoolean" */ import('@faststore/ui').then((mod) => mod.FilterFacetBoolean) ) -const UIFilterFacetBooleanItem = dynamic(() => +const UIFilterFacetBooleanItem = dynamic(() => /* webpackChunkName: "UIFilterFacetBooleanItem" */ import('@faststore/ui').then((mod) => mod.FilterFacetBooleanItem) ) -const UIFilterFacetRange = dynamic(() => +const UIFilterFacetRange = dynamic(() => /* webpackChunkName: "UIFilterFacetRange" */ import('@faststore/ui').then((mod) => mod.FilterFacetRange) ) -const UIFilterFacets = dynamic(() => +const UIFilterFacets = dynamic< + { children: React.ReactNode } & UIFilterFacetsProps +>(() => /* webpackChunkName: "UIFilterFacets" */ import('@faststore/ui').then((mod) => mod.FilterFacets) ) -const UIFilterSlider = dynamic(() => +const UIFilterSlider = dynamic(() => /* webpackChunkName: "UIFilterSlider" */ import('@faststore/ui').then((mod) => mod.FilterSlider) ) @@ -106,7 +116,7 @@ function FilterSlider({ + onAccordionChange={(index: number) => dispatch({ type: 'toggleExpanded', payload: index }) } >