From 7a46e5eedc3785cdf9fc95744700ba810699cff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Azevedo?= Date: Mon, 8 Jan 2024 17:16:10 -0300 Subject: [PATCH] chore: improve overrides bundle size (#2186) ## What's the purpose of this pull request? This PR improves the performance of the Section Override API. ## How it works? It works by removing the centralized imports where an object would contain the components for all of the sections. This made the sections and default components to be imported even where they were not used, making the bundle to be bigger than necessary. It also introduces a breaking change to the previously proposed API: instead of providing the name of the section to be overridden, users should provide the section itself. ```tsx import { Alert, getOverriddenSection } from "@faststore/core"; const NewAlert = getOverriddenSection({ Section: Alert, components: {} }); export default NewAlert; ``` ## How to test it? Use this version of the package on the starter and try to create overrides for the supported V2 sections! --- packages/core/index.ts | 13 + .../src/components/sections/Alert/Alert.tsx | 14 +- .../sections/Alert/OverriddenDefaultAlert.ts | 11 +- .../sections/BannerText/BannerText.tsx | 12 +- .../BannerText/OverriddenDefaultBannerText.ts | 11 +- .../sections/Breadcrumb/Breadcrumb.tsx | 12 +- .../Breadcrumb/OverriddenDefaultBreadcrumb.ts | 11 +- .../CrossSellingShelf/CrossSellingShelf.tsx | 10 +- .../OverriddenDefaultCrossSellingShelf.ts | 3 +- .../sections/EmptyState/Overrides.tsx | 4 +- .../src/components/sections/Hero/Hero.tsx | 14 +- .../sections/Hero/OverriddenDefaultHero.ts | 11 +- .../src/components/sections/Navbar/Navbar.tsx | 12 +- .../Navbar/OverriddenDefaultNavbar.ts | 10 +- .../sections/Newsletter/Newsletter.tsx | 12 +- .../Newsletter/OverriddenDefaultNewsletter.ts | 10 +- .../OverriddenDefaultProductDetails.ts | 11 +- .../ProductDetails/ProductDetails.tsx | 24 +- .../OverriddenDefaultProductGallery.ts | 10 +- .../ProductGallery/ProductGallery.tsx | 18 +- .../OverriddenDefaultProductShelf.ts | 11 +- .../sections/ProductShelf/ProductShelf.tsx | 14 +- .../RegionBar/OverriddenDefaultRegionBar.ts | 10 +- .../sections/RegionBar/RegionBar.tsx | 16 +- .../sdk/overrides/getOverriddenSection.tsx | 89 ++-- packages/core/src/sdk/overrides/overrides.ts | 4 +- packages/core/src/sdk/overrides/sections.tsx | 58 --- packages/core/src/typings/overrides.ts | 452 ++++++++++-------- .../core/src/typings/overridesDefinition.ts | 26 +- 29 files changed, 536 insertions(+), 377 deletions(-) delete mode 100644 packages/core/src/sdk/overrides/sections.tsx diff --git a/packages/core/index.ts b/packages/core/index.ts index d2c37589b0..33b1e00c30 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -18,3 +18,16 @@ export { useProductsQuery } from './src/sdk/product/useProductsQuery' export * from './src/typings/overrides' export { getOverriddenSection } from './src/sdk/overrides/getOverriddenSection' + +// Overridable Sections +export { default as AlertSection } from './src/components/sections/Alert' +export { default as BannerTextSection } from './src/components/sections/BannerText' +export { default as BreadcrumbSection } from './src/components/sections/Breadcrumb' +export { default as CrossSellingShelfSection } from './src/components/sections/CrossSellingShelf' +export { default as HeroSection } from './src/components/sections/Hero' +export { default as NavbarSection } from './src/components/sections/Navbar' +export { default as NewsletterSection } from './src/components/sections/Newsletter' +export { default as ProductDetailsSection } from './src/components/sections/ProductDetails' +export { default as ProductGallerySection } from './src/components/sections/ProductGallery' +export { default as ProductShelfSection } from './src/components/sections/ProductShelf' +export { default as RegionBarSection } from './src/components/sections/RegionBar' diff --git a/packages/core/src/components/sections/Alert/Alert.tsx b/packages/core/src/components/sections/Alert/Alert.tsx index e5a9d75b4c..8d413effc8 100644 --- a/packages/core/src/components/sections/Alert/Alert.tsx +++ b/packages/core/src/components/sections/Alert/Alert.tsx @@ -2,8 +2,10 @@ import type { ReactNode } from 'react' import CommonAlert, { type AlertProps as CommonAlertProps, -} from 'src/components/common/Alert' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +} from '../../../components/common/Alert' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' +import { AlertDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' export interface AlertProps extends Omit { icon: string @@ -35,4 +37,10 @@ function Alert({ icon, content, link: { text, to }, dismissible }: AlertProps) { ) } -export default Alert +const OverridableAlert = getOverridableSection( + 'Alert', + Alert, + AlertDefaultComponents +) + +export default OverridableAlert diff --git a/packages/core/src/components/sections/Alert/OverriddenDefaultAlert.ts b/packages/core/src/components/sections/Alert/OverriddenDefaultAlert.ts index 7711dfd3d8..801671febb 100644 --- a/packages/core/src/components/sections/Alert/OverriddenDefaultAlert.ts +++ b/packages/core/src/components/sections/Alert/OverriddenDefaultAlert.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/Alert' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import Alert from '.' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default Alert section present in the Headless CMS */ -export const OverriddenDefaultAlert = getOverriddenSection( - override as SectionOverrideDefinition<'Alert'> -) +export const OverriddenDefaultAlert = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'Alert'>), + Section: Alert, +}) diff --git a/packages/core/src/components/sections/BannerText/BannerText.tsx b/packages/core/src/components/sections/BannerText/BannerText.tsx index 34d1fdeea3..8378690aa0 100644 --- a/packages/core/src/components/sections/BannerText/BannerText.tsx +++ b/packages/core/src/components/sections/BannerText/BannerText.tsx @@ -3,10 +3,12 @@ import { BannerTextContentProps as UIBannerTextContentProps, } from '@faststore/ui' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' import Section from '../Section' import styles from './section.module.scss' +import { BannerTextDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' export interface BannerTextProps { title: UIBannerTextContentProps['title'] @@ -55,4 +57,10 @@ function BannerText({ ) } -export default BannerText +const OverridableBannerText = getOverridableSection( + 'BannerText', + BannerText, + BannerTextDefaultComponents +) + +export default OverridableBannerText diff --git a/packages/core/src/components/sections/BannerText/OverriddenDefaultBannerText.ts b/packages/core/src/components/sections/BannerText/OverriddenDefaultBannerText.ts index 57ba114a0f..35ba287938 100644 --- a/packages/core/src/components/sections/BannerText/OverriddenDefaultBannerText.ts +++ b/packages/core/src/components/sections/BannerText/OverriddenDefaultBannerText.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/BannerText' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import BannerText from '.' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default BannerText section present in the Headless CMS */ -export const OverriddenDefaultBannerText = getOverriddenSection( - override as SectionOverrideDefinition<'BannerText'> -) +export const OverriddenDefaultBannerText = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'BannerText'>), + Section: BannerText, +}) diff --git a/packages/core/src/components/sections/Breadcrumb/Breadcrumb.tsx b/packages/core/src/components/sections/Breadcrumb/Breadcrumb.tsx index 4880f87a92..dd7d9e443c 100644 --- a/packages/core/src/components/sections/Breadcrumb/Breadcrumb.tsx +++ b/packages/core/src/components/sections/Breadcrumb/Breadcrumb.tsx @@ -9,8 +9,10 @@ import { isPDP, isPLP, usePage, -} from 'src/sdk/overrides/PageProvider' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +} from '../../../sdk/overrides/PageProvider' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' +import { BreadcrumbDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' interface BreadcrumbSectionProps { icon: string @@ -39,4 +41,8 @@ function BreadcrumbSection({ ...otherProps }: BreadcrumbSectionProps) { ) } -export default memo(BreadcrumbSection) +const OverridableBreadcrumbSection = getOverridableSection< + typeof BreadcrumbSection +>('Breadcrumb', BreadcrumbSection, BreadcrumbDefaultComponents) + +export default memo(OverridableBreadcrumbSection) diff --git a/packages/core/src/components/sections/Breadcrumb/OverriddenDefaultBreadcrumb.ts b/packages/core/src/components/sections/Breadcrumb/OverriddenDefaultBreadcrumb.ts index b709b85ad2..21af53e079 100644 --- a/packages/core/src/components/sections/Breadcrumb/OverriddenDefaultBreadcrumb.ts +++ b/packages/core/src/components/sections/Breadcrumb/OverriddenDefaultBreadcrumb.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/Breadcrumb' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import Breadcrumb from '.' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default Breadcrumb section present in the Headless CMS */ -export const OverriddenDefaultBreadcrumb = getOverriddenSection( - override as SectionOverrideDefinition<'Breadcrumb'> -) +export const OverriddenDefaultBreadcrumb = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'Breadcrumb'>), + Section: Breadcrumb, +}) diff --git a/packages/core/src/components/sections/CrossSellingShelf/CrossSellingShelf.tsx b/packages/core/src/components/sections/CrossSellingShelf/CrossSellingShelf.tsx index a673764f0c..8ecd926b0c 100644 --- a/packages/core/src/components/sections/CrossSellingShelf/CrossSellingShelf.tsx +++ b/packages/core/src/components/sections/CrossSellingShelf/CrossSellingShelf.tsx @@ -1,10 +1,12 @@ import { useMemo } from 'react' -import UIProductShelf from 'src/components/ui/ProductShelf' +import UIProductShelf from '../../../components/ui/ProductShelf' import { useInView } from 'react-intersection-observer' import { usePDP } from 'src/sdk/overrides/PageProvider' import styles from '../ProductShelf/section.module.scss' import Section from '../Section' +import { CrossSellingShelfDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' interface Props { numberOfItems: number @@ -43,4 +45,8 @@ const CrossSellingShelf = ({ ) } -export default CrossSellingShelf +const OverridableCrossSellingShelf = getOverridableSection< + typeof CrossSellingShelf +>('CrossSellingShelf', CrossSellingShelf, CrossSellingShelfDefaultComponents) + +export default OverridableCrossSellingShelf diff --git a/packages/core/src/components/sections/CrossSellingShelf/OverriddenDefaultCrossSellingShelf.ts b/packages/core/src/components/sections/CrossSellingShelf/OverriddenDefaultCrossSellingShelf.ts index e6c586fb82..f3f6d5b09c 100644 --- a/packages/core/src/components/sections/CrossSellingShelf/OverriddenDefaultCrossSellingShelf.ts +++ b/packages/core/src/components/sections/CrossSellingShelf/OverriddenDefaultCrossSellingShelf.ts @@ -1,5 +1,6 @@ import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' +import CrossSellingShelf from '.' export const OverriddenDefaultCrossSellingShelf = getOverriddenSection({ - section: 'CrossSellingShelf', + Section: CrossSellingShelf, }) diff --git a/packages/core/src/components/sections/EmptyState/Overrides.tsx b/packages/core/src/components/sections/EmptyState/Overrides.tsx index 387430c9e6..203f9b69e7 100644 --- a/packages/core/src/components/sections/EmptyState/Overrides.tsx +++ b/packages/core/src/components/sections/EmptyState/Overrides.tsx @@ -2,13 +2,13 @@ import { EmptyState as UIEmptyState } from '@faststore/ui' import { getSectionOverrides } from 'src/sdk/overrides/overrides' import { override } from 'src/customizations/src/components/overrides/EmptyState' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' const { EmptyState } = getSectionOverrides( { EmptyState: UIEmptyState, }, - override as SectionOverrideDefinition<'EmptyState'> + override as SectionOverrideDefinitionV1<'EmptyState'> ) export { EmptyState } diff --git a/packages/core/src/components/sections/Hero/Hero.tsx b/packages/core/src/components/sections/Hero/Hero.tsx index dd9f980025..c530491e23 100644 --- a/packages/core/src/components/sections/Hero/Hero.tsx +++ b/packages/core/src/components/sections/Hero/Hero.tsx @@ -3,13 +3,15 @@ import { HeroHeaderProps as UIHeroHeaderProps, } from '@faststore/ui' import { ReactNode } from 'react' -import { Image } from 'src/components/ui/Image' +import { Image } from '../../../components/ui/Image' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' import Section from '../Section' import styles from './section.module.scss' +import { HeroDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' export type HeroProps = { title: UIHeroHeaderProps['title'] @@ -74,4 +76,10 @@ const Hero = ({ ) } -export default Hero +const OverridableHero = getOverridableSection( + 'Hero', + Hero, + HeroDefaultComponents +) + +export default OverridableHero diff --git a/packages/core/src/components/sections/Hero/OverriddenDefaultHero.ts b/packages/core/src/components/sections/Hero/OverriddenDefaultHero.ts index f4441ba1d3..48754cfd28 100644 --- a/packages/core/src/components/sections/Hero/OverriddenDefaultHero.ts +++ b/packages/core/src/components/sections/Hero/OverriddenDefaultHero.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/Hero' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import Hero from '.' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default Hero section present in the Headless CMS */ -export const OverriddenDefaultHero = getOverriddenSection( - override as SectionOverrideDefinition<'Hero'> -) +export const OverriddenDefaultHero = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'Hero'>), + Section: Hero, +}) diff --git a/packages/core/src/components/sections/Navbar/Navbar.tsx b/packages/core/src/components/sections/Navbar/Navbar.tsx index 4d04b56cae..daa8c80afa 100644 --- a/packages/core/src/components/sections/Navbar/Navbar.tsx +++ b/packages/core/src/components/sections/Navbar/Navbar.tsx @@ -1,8 +1,10 @@ +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' import Section from '../Section' import styles from './section.module.scss' -import Navbar from 'src/components/navigation/Navbar' +import Navbar from '../../../components/navigation/Navbar' +import { NavbarDefaultComponents } from './DefaultComponents' type PageLinks = { url: string @@ -91,4 +93,10 @@ function NavbarSection({ ) } -export default NavbarSection +const OverridableNavbar = getOverridableSection( + 'Navbar', + NavbarSection, + NavbarDefaultComponents +) + +export default OverridableNavbar diff --git a/packages/core/src/components/sections/Navbar/OverriddenDefaultNavbar.ts b/packages/core/src/components/sections/Navbar/OverriddenDefaultNavbar.ts index b4b0bc705b..c5c4075fd6 100644 --- a/packages/core/src/components/sections/Navbar/OverriddenDefaultNavbar.ts +++ b/packages/core/src/components/sections/Navbar/OverriddenDefaultNavbar.ts @@ -1,12 +1,14 @@ import { override } from 'src/customizations/src/components/overrides/Navbar' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' +import Navbar from './Navbar' /** * This component exists to support overrides 1.0 * * This allows users to override the default Navbar section present in the Headless CMS */ -export const OverriddenDefaultNavbar = getOverriddenSection( - override as SectionOverrideDefinition<'Navbar'> -) +export const OverriddenDefaultNavbar = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'Navbar'>), + Section: Navbar, +}) diff --git a/packages/core/src/components/sections/Newsletter/Newsletter.tsx b/packages/core/src/components/sections/Newsletter/Newsletter.tsx index 27fbe83af2..6131f2bed0 100644 --- a/packages/core/src/components/sections/Newsletter/Newsletter.tsx +++ b/packages/core/src/components/sections/Newsletter/Newsletter.tsx @@ -4,10 +4,12 @@ import { NewsletterHeaderProps as UINewsletterHeaderProps, } from '@faststore/ui' -import UINewsletter from 'src/components/ui/Newsletter' +import UINewsletter from '../../ui/Newsletter' import Section from '../Section' import styles from './section.module.scss' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' +import { NewsletterDefaultComponents } from './DefaultComponents' type SubscribeMessage = { icon: string @@ -111,4 +113,10 @@ function Newsletter({ ) } -export default Newsletter +const OverridableNewsletter = getOverridableSection( + 'Newsletter', + Newsletter, + NewsletterDefaultComponents +) + +export default OverridableNewsletter diff --git a/packages/core/src/components/sections/Newsletter/OverriddenDefaultNewsletter.ts b/packages/core/src/components/sections/Newsletter/OverriddenDefaultNewsletter.ts index f2c3307087..79ee9dc12d 100644 --- a/packages/core/src/components/sections/Newsletter/OverriddenDefaultNewsletter.ts +++ b/packages/core/src/components/sections/Newsletter/OverriddenDefaultNewsletter.ts @@ -1,12 +1,14 @@ import { override } from 'src/customizations/src/components/overrides/Newsletter' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' +import Newsletter from './Newsletter' /** * This component exists to support overrides 1.0 * * This allows users to override the default Newsletter section present in the Headless CMS */ -export const OverriddenDefaultNewsletter = getOverriddenSection( - override as SectionOverrideDefinition<'Newsletter'> -) +export const OverriddenDefaultNewsletter = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'Newsletter'>), + Section: Newsletter, +}) diff --git a/packages/core/src/components/sections/ProductDetails/OverriddenDefaultProductDetails.ts b/packages/core/src/components/sections/ProductDetails/OverriddenDefaultProductDetails.ts index 87d1e31b29..fee8029b1f 100644 --- a/packages/core/src/components/sections/ProductDetails/OverriddenDefaultProductDetails.ts +++ b/packages/core/src/components/sections/ProductDetails/OverriddenDefaultProductDetails.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/ProductDetails' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import ProductDetails from './ProductDetails' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default ProductDetails section present in the Headless CMS */ -export const OverriddenDefaultProductDetails = getOverriddenSection( - override as SectionOverrideDefinition<'ProductDetails'> -) +export const OverriddenDefaultProductDetails = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'ProductDetails'>), + Section: ProductDetails, +}) diff --git a/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx b/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx index 098751ad6f..dc17c8c235 100644 --- a/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx +++ b/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx @@ -4,18 +4,20 @@ import { gql } from '@faststore/graphql-utils' import type { CurrencyCode, ViewItemEvent } from '@faststore/sdk' import { sendAnalyticsEvent } from '@faststore/sdk' -import type { AnalyticsItem } from 'src/sdk/analytics/types' -import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice' -import { useSession } from 'src/sdk/session' +import type { AnalyticsItem } from '../../../sdk/analytics/types' +import { useFormattedPrice } from '../../../sdk/product/useFormattedPrice' +import { useSession } from '../../../sdk/session' import Section from '../Section' -import ProductDescription from 'src/components/ui/ProductDescription' -import { ProductDetailsSettings } from 'src/components/ui/ProductDetails' +import ProductDescription from '../../../components/ui/ProductDescription' +import { ProductDetailsSettings } from '../../../components/ui/ProductDetails' import styles from './section.module.scss' -import { usePDP } from 'src/sdk/overrides/PageProvider' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +import { usePDP } from '../../../sdk/overrides/PageProvider' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' +import { ProductDetailsDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' export interface ProductDetailsProps { productTitle: { @@ -280,4 +282,10 @@ export const fragment = gql` } ` -export default ProductDetails +const OverridableProductDetails = getOverridableSection( + 'ProductDetails', + ProductDetails, + ProductDetailsDefaultComponents +) + +export default OverridableProductDetails diff --git a/packages/core/src/components/sections/ProductGallery/OverriddenDefaultProductGallery.ts b/packages/core/src/components/sections/ProductGallery/OverriddenDefaultProductGallery.ts index 81242703dc..2358cc96a1 100644 --- a/packages/core/src/components/sections/ProductGallery/OverriddenDefaultProductGallery.ts +++ b/packages/core/src/components/sections/ProductGallery/OverriddenDefaultProductGallery.ts @@ -1,12 +1,14 @@ import { override } from 'src/customizations/src/components/overrides/ProductGallery' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' +import ProductGallery from '.' /** * This component exists to support overrides 1.0 * * This allows users to override the default ProductGallery section present in the Headless CMS */ -export const OverriddenDefaultProductGallery = getOverriddenSection( - override as SectionOverrideDefinition<'ProductGallery'> -) +export const OverriddenDefaultProductGallery = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'ProductGallery'>), + Section: ProductGallery, +}) diff --git a/packages/core/src/components/sections/ProductGallery/ProductGallery.tsx b/packages/core/src/components/sections/ProductGallery/ProductGallery.tsx index 1790a5bef2..8bd65f32a6 100644 --- a/packages/core/src/components/sections/ProductGallery/ProductGallery.tsx +++ b/packages/core/src/components/sections/ProductGallery/ProductGallery.tsx @@ -1,8 +1,8 @@ -import { mark } from 'src/sdk/tests/mark' +import { mark } from '../../../sdk/tests/mark' import ProductGallery, { ProductGalleryProps, -} from 'src/components/ui/ProductGallery/ProductGallery' +} from '../../ui/ProductGallery/ProductGallery' import Section from '../Section' import type { EmptyGalleryProps } from './EmptyGallery' @@ -13,8 +13,10 @@ import { isPLP, isSearchPage, usePage, -} from 'src/sdk/overrides/PageProvider' -import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext' +} from '../../../sdk/overrides/PageProvider' +import { useOverrideComponents } from '../../../sdk/overrides/OverrideContext' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' +import { ProductGalleryDefaultComponents } from './DefaultComponents' export interface ProductGallerySectionProps { searchTermLabel?: ProductGalleryProps['searchTermLabel'] @@ -69,4 +71,10 @@ function ProductGallerySection({ } ProductGallerySection.displayName = 'ProductGallery' -export default mark(ProductGallerySection) +const MarkedProductGallery = mark(ProductGallerySection) + +const OverridableProductGallery = getOverridableSection< + typeof MarkedProductGallery +>('ProductGallery', MarkedProductGallery, ProductGalleryDefaultComponents) + +export default OverridableProductGallery diff --git a/packages/core/src/components/sections/ProductShelf/OverriddenDefaultProductShelf.ts b/packages/core/src/components/sections/ProductShelf/OverriddenDefaultProductShelf.ts index e3f6b6781e..0303b79a2e 100644 --- a/packages/core/src/components/sections/ProductShelf/OverriddenDefaultProductShelf.ts +++ b/packages/core/src/components/sections/ProductShelf/OverriddenDefaultProductShelf.ts @@ -1,12 +1,15 @@ import { override } from 'src/customizations/src/components/overrides/ProductShelf' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import ProductShelf from '.' + +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' /** * This component exists to support overrides 1.0 * * This allows users to override the default ProductShelf section present in the Headless CMS */ -export const OverriddenDefaultProductShelf = getOverriddenSection( - override as SectionOverrideDefinition<'ProductShelf'> -) +export const OverriddenDefaultProductShelf = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'ProductShelf'>), + Section: ProductShelf, +}) diff --git a/packages/core/src/components/sections/ProductShelf/ProductShelf.tsx b/packages/core/src/components/sections/ProductShelf/ProductShelf.tsx index 32e79d68db..1b9d9d8ac9 100644 --- a/packages/core/src/components/sections/ProductShelf/ProductShelf.tsx +++ b/packages/core/src/components/sections/ProductShelf/ProductShelf.tsx @@ -1,8 +1,12 @@ import { useInView } from 'react-intersection-observer' import Section from '../Section' -import ProductShelf, { ProductShelfProps } from 'src/components/ui/ProductShelf' +import ProductShelf, { + ProductShelfProps, +} from '../../../components/ui/ProductShelf' import styles from './section.module.scss' +import { ProductShelfDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../../sdk/overrides/getOverriddenSection' function ProductShelfSection({ ...otherProps @@ -19,4 +23,10 @@ function ProductShelfSection({ ) } -export default ProductShelfSection +const OverridableProductShelf = getOverridableSection( + 'ProductShelf', + ProductShelfSection, + ProductShelfDefaultComponents +) + +export default OverridableProductShelf diff --git a/packages/core/src/components/sections/RegionBar/OverriddenDefaultRegionBar.ts b/packages/core/src/components/sections/RegionBar/OverriddenDefaultRegionBar.ts index 3d5eda13ce..b937467d5d 100644 --- a/packages/core/src/components/sections/RegionBar/OverriddenDefaultRegionBar.ts +++ b/packages/core/src/components/sections/RegionBar/OverriddenDefaultRegionBar.ts @@ -1,12 +1,14 @@ import { override } from 'src/customizations/src/components/overrides/RegionBar' import { getOverriddenSection } from 'src/sdk/overrides/getOverriddenSection' -import type { SectionOverrideDefinition } from 'src/typings/overridesDefinition' +import type { SectionOverrideDefinitionV1 } from 'src/typings/overridesDefinition' +import RegionBar from '.' /** * This component exists to support overrides 1.0 * * This allows users to override the default RegionBar section present in the Headless CMS */ -export const OverriddenDefaultRegionBar = getOverriddenSection( - override as SectionOverrideDefinition<'RegionBar'> -) +export const OverriddenDefaultRegionBar = getOverriddenSection({ + ...(override as SectionOverrideDefinitionV1<'RegionBar'>), + Section: RegionBar, +}) diff --git a/packages/core/src/components/sections/RegionBar/RegionBar.tsx b/packages/core/src/components/sections/RegionBar/RegionBar.tsx index 28cefa2ea6..ce23231319 100644 --- a/packages/core/src/components/sections/RegionBar/RegionBar.tsx +++ b/packages/core/src/components/sections/RegionBar/RegionBar.tsx @@ -1,8 +1,8 @@ -import RegionBar, { - RegionBarProps, -} from 'src/components/region/RegionBar/RegionBar' -import Section from 'src/components/sections/Section/Section' +import RegionBar, { RegionBarProps } from '../../region/RegionBar/RegionBar' +import Section from '../Section/Section' import styles from './section.module.scss' +import { RegionBarDefaultComponents } from './DefaultComponents' +import { getOverridableSection } from '../../..//sdk/overrides/getOverriddenSection' type RegionBarSectionProps = { /** @@ -38,4 +38,10 @@ function RegionBarSection({ ) } -export default RegionBarSection +const OverridableRegionBar = getOverridableSection( + 'RegionBar', + RegionBarSection, + RegionBarDefaultComponents +) + +export default OverridableRegionBar diff --git a/packages/core/src/sdk/overrides/getOverriddenSection.tsx b/packages/core/src/sdk/overrides/getOverriddenSection.tsx index f818e6968a..8d91872c88 100644 --- a/packages/core/src/sdk/overrides/getOverriddenSection.tsx +++ b/packages/core/src/sdk/overrides/getOverriddenSection.tsx @@ -1,44 +1,52 @@ -import type { ComponentProps, ComponentType } from 'react' +import { useMemo, type ComponentProps, type ComponentType } from 'react' -import { OverrideProvider } from './OverrideContext' -import { DefaultComponents, Sections } from './sections' -import { getSectionOverrides } from './overrides' import type { DefaultSectionComponentsDefinitions, - OverriddenComponents, SectionOverrideDefinition, + SectionOverrideDefinitionV1, } from '../../typings/overridesDefinition' -import type { SupportedSectionsOverridesV2 } from '../../typings/overrides' - -/** - * This function adds OverrideContext to the tree. It is essential for the compatible sections - * to consume the components it provides. - */ -function createOverriddenSection< - SectionName extends keyof SupportedSectionsOverridesV2 ->({ - Section, - sectionOverrides, - className, -}: { - Section: (typeof Sections)[SectionName] - sectionOverrides: OverriddenComponents - className?: string -}) { - const overrideContextValue = { className, components: sectionOverrides } +import type { SectionsOverrides } from '../../typings/overrides' +import { getSectionOverrides } from './overrides' +import { OverrideProvider } from './OverrideContext' - return function OverriddenSection( - props: React.ComponentProps +export function getOverridableSection< + Section extends ComponentType, + SectionName extends keyof SectionsOverrides = keyof SectionsOverrides +>( + sectionName: SectionName, + Section: Section, + defaultComponents: DefaultSectionComponentsDefinitions +) { + function OverridableSection( + propsWithOverrides: ComponentProps & { + __overrides?: Omit, 'Section'> + } ) { + const { __overrides: overrides, ...props } = propsWithOverrides + + const overrideContextValue = useMemo( + () => ({ + ...(overrides ?? {}), + components: getSectionOverrides(defaultComponents, { + ...(overrides ?? {}), + section: sectionName, + }), + }), + [overrides] + ) + /** This type wizardry is here because the props won't behave correctly if nothing is done */ - const SectionComponent = Section as ComponentType + const SectionComponent = Section as ComponentType> return ( - + )} /> ) } + + // This type cast is here so the symbol prop doesn't show up in the type definition + return OverridableSection as Section } /** @@ -50,23 +58,16 @@ function createOverriddenSection< * @see https://www.faststore.dev/docs/building-sections/overriding-components-and-props */ export function getOverriddenSection< - SectionName extends keyof SupportedSectionsOverridesV2 ->(override: SectionOverrideDefinition) { - const defaultComponents = DefaultComponents[ - override.section - ] as DefaultSectionComponentsDefinitions + Section extends SectionsOverrides[keyof SectionsOverrides]['Section'] +>(override: SectionOverrideDefinition
) { + const { Section, ...rest } = override - if (!defaultComponents) { - throw new Error( - `Section ${override.section} does not exist. Please provide a valid section name to override.` - ) - } + /** This type wizardry is here because the props won't behave correctly if nothing is done */ + const OverridableSection = Section as ComponentType> - const sectionOverrides = getSectionOverrides(defaultComponents, override) - - return createOverriddenSection({ - Section: Sections[override.section], - sectionOverrides: sectionOverrides, - className: override.className, - }) + return function OverriddenSection( + props: ComponentProps + ) { + return + } } diff --git a/packages/core/src/sdk/overrides/overrides.ts b/packages/core/src/sdk/overrides/overrides.ts index 5e0c3bad49..b438f1f050 100644 --- a/packages/core/src/sdk/overrides/overrides.ts +++ b/packages/core/src/sdk/overrides/overrides.ts @@ -1,8 +1,8 @@ import type { DefaultSectionComponentsDefinitions, ComponentOverrideDefinition, - SectionOverrideDefinition, OverriddenComponents, + SectionOverrideDefinitionV1, } from '../../typings/overridesDefinition' import type { SectionsOverrides } from '../../typings/overrides' @@ -11,7 +11,7 @@ export function getSectionOverrides< SectionName extends keyof SectionsOverrides >( defaultComponents: DefaultSectionComponentsDefinitions, - override: SectionOverrideDefinition + override: SectionOverrideDefinitionV1 ): OverriddenComponents { const overriddenComponents = {} as OverriddenComponents diff --git a/packages/core/src/sdk/overrides/sections.tsx b/packages/core/src/sdk/overrides/sections.tsx deleted file mode 100644 index 05e7cf686e..0000000000 --- a/packages/core/src/sdk/overrides/sections.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import Alert from '../../components/sections/Alert' -import BannerText from '../../components/sections/BannerText' -import Breadcrumb from '../../components/sections/Breadcrumb' -import Hero from '../../components/sections/Hero' -import Navbar from '../../components/sections/Navbar' -import Newsletter from '../../components/sections/Newsletter' -import ProductShelf from '../../components/sections/ProductShelf' -import CrossSellingShelf from '../../components/sections/CrossSellingShelf' -import ProductDetails from '../../components/sections/ProductDetails' -import ProductGallery from '../../components/sections/ProductGallery' -import RegionBar from '../../components/sections/RegionBar' - -import type { DefaultSectionComponentsDefinitions } from '../../typings/overridesDefinition' -import type { SectionsOverrides } from '../../typings/overrides' -import { AlertDefaultComponents } from '../../components/sections/Alert/DefaultComponents' -import { BannerTextDefaultComponents } from '../../components/sections/BannerText/DefaultComponents' -import { BreadcrumbDefaultComponents } from 'src/components/sections/Breadcrumb/DefaultComponents' -import { CrossSellingShelfDefaultComponents } from 'src/components/sections/CrossSellingShelf/DefaultComponents' -import { HeroDefaultComponents } from '../../components/sections/Hero/DefaultComponents' -import { NavbarDefaultComponents } from 'src/components/sections/Navbar/DefaultComponents' -import { NewsletterDefaultComponents } from '../../components/sections/Newsletter/DefaultComponents' -import { ProductDetailsDefaultComponents } from '../../components/sections/ProductDetails/DefaultComponents' -import { ProductGalleryDefaultComponents } from '../../components/sections/ProductGallery/DefaultComponents' -import { ProductShelfDefaultComponents } from '../../components/sections/ProductShelf/DefaultComponents' -import { RegionBarDefaultComponents } from '../../components/sections/RegionBar/DefaultComponents' - -export const Sections = { - Alert, - BannerText, - Breadcrumb, - CrossSellingShelf, - Hero, - Navbar, - Newsletter, - ProductDetails, - ProductGallery, - ProductShelf, - RegionBar, -} - -export const DefaultComponents: Partial< - Record< - keyof SectionsOverrides, - DefaultSectionComponentsDefinitions - > -> = { - Alert: AlertDefaultComponents, - BannerText: BannerTextDefaultComponents, - Breadcrumb: BreadcrumbDefaultComponents, - CrossSellingShelf: CrossSellingShelfDefaultComponents, - Hero: HeroDefaultComponents, - Navbar: NavbarDefaultComponents, - Newsletter: NewsletterDefaultComponents, - ProductDetails: ProductDetailsDefaultComponents, - ProductGallery: ProductGalleryDefaultComponents, - ProductShelf: ProductShelfDefaultComponents, - RegionBar: RegionBarDefaultComponents, -} diff --git a/packages/core/src/typings/overrides.ts b/packages/core/src/typings/overrides.ts index ab58fa6313..387c25838b 100644 --- a/packages/core/src/typings/overrides.ts +++ b/packages/core/src/typings/overrides.ts @@ -43,28 +43,62 @@ import type { import type { ComponentOverrideDefinition, - SectionOverrideDefinition, + SectionOverrideDefinitionV1, } from './overridesDefinition' +import Alert from '../components/sections/Alert' +import Breadcrumb from '../components/sections/Breadcrumb' +import BannerText from '../components/sections/BannerText' +import CrossSellingShelf from '../components/sections/CrossSellingShelf' +import Hero from '../components/sections/Hero' +import ProductShelf from '../components/sections/ProductShelf' +import ProductDetails from '../components/sections/ProductDetails' +import Navbar from '../components/sections/Navbar' +import Newsletter from '../components/sections/Newsletter' +import ProductGallery from '../components/sections/ProductGallery' +import RegionBar from '../components/sections/RegionBar' export type SectionOverride = { - [K in keyof SectionsOverrides]: SectionOverrideDefinition + [K in keyof SectionsOverrides]: SectionOverrideDefinitionV1 }[keyof SectionsOverrides] -/** TODO: every use of this type should be replaced by SectionsOverrides after all sections are supported */ -export type SupportedSectionsOverridesV2 = Pick< - SectionsOverrides, - | 'Alert' - | 'BannerText' - | 'Breadcrumb' - | 'CrossSellingShelf' - | 'Hero' - | 'Navbar' - | 'Newsletter' - | 'ProductShelf' - | 'ProductDetails' - | 'ProductGallery' - | 'RegionBar' -> +/** + * This type exists for us to be able to provide proper autocomplete + * and type checking for the override components. + * + * What it does is it maps a section component to its override components. + * + * OverrideComponentsForSection translates to: + * { + * Alert: { + * Alert: ComponentOverrideDefinition> + * Icon: ComponentOverrideDefinition + * } + * } + * + * We then use ComponentsFromSection to extract the list of components + */ +export type OverrideComponentsForSection< + Section extends SectionsOverrides[keyof SectionsOverrides]['Section'] +> = { + // The first 'extends' condition is used to filter out sections that don't have overrides (typed 'never') + [K in keyof SectionsOverrides as SectionsOverrides[K] extends { + Section: never + } + ? never + : // In the second 'extends' condition, we check if the section matches the one we're looking for + SectionsOverrides[K] extends { + Section: Section + } + ? // If it does, we return the components. Otherwise, we return 'never', which is filtered out + K + : never]: SectionsOverrides[K]['components'] +} + +// This type is used to extract only the list of components from the section override +export type ComponentsFromSection< + Section extends SectionsOverrides[keyof SectionsOverrides]['Section'] +> = + OverrideComponentsForSection
[keyof OverrideComponentsForSection
] /** * Originally, these types were defined in their respective Overrides file @@ -74,199 +108,243 @@ export type SupportedSectionsOverridesV2 = Pick< * For some reason, defining them in the same file as SectionOverride seems to fix the issue. * Consider that before moving them elsewhere and test it on the starter as well. */ - export type SectionsOverrides = { Alert: { - Alert: ComponentOverrideDefinition> - Icon: ComponentOverrideDefinition + Section: typeof Alert + components: { + Alert: ComponentOverrideDefinition< + AlertProps, + Omit + > + Icon: ComponentOverrideDefinition + } } BannerText: { - BannerText: ComponentOverrideDefinition - BannerTextContent: ComponentOverrideDefinition< - BannerTextContentProps, - BannerTextContentProps - > + Section: typeof BannerText + components: { + BannerText: ComponentOverrideDefinition + BannerTextContent: ComponentOverrideDefinition< + BannerTextContentProps, + BannerTextContentProps + > + } } Breadcrumb: { - Breadcrumb: ComponentOverrideDefinition - Icon: ComponentOverrideDefinition + Section: typeof Breadcrumb + components: { + Breadcrumb: ComponentOverrideDefinition + Icon: ComponentOverrideDefinition + } } EmptyState: { - EmptyState: ComponentOverrideDefinition< - PropsWithChildren, - EmptyStateProps - > + Section: never + components: { + EmptyState: ComponentOverrideDefinition< + PropsWithChildren, + EmptyStateProps + > + } } Hero: { - Hero: ComponentOverrideDefinition - HeroImage: ComponentOverrideDefinition - HeroHeader: ComponentOverrideDefinition + Section: typeof Hero + components: { + Hero: ComponentOverrideDefinition + HeroImage: ComponentOverrideDefinition + HeroHeader: ComponentOverrideDefinition + } } Navbar: { - Navbar: ComponentOverrideDefinition - NavbarLinks: ComponentOverrideDefinition - NavbarLinksList: ComponentOverrideDefinition< - NavbarLinksListProps, - NavbarLinksListProps - > - NavbarSlider: ComponentOverrideDefinition< - NavbarSliderProps, - NavbarSliderProps - > - NavbarSliderHeader: ComponentOverrideDefinition< - NavbarSliderHeaderProps, - NavbarSliderHeaderProps - > - NavbarSliderContent: ComponentOverrideDefinition< - NavbarSliderContentProps, - NavbarSliderContentProps - > - NavbarSliderFooter: ComponentOverrideDefinition< - NavbarSliderFooterProps, - NavbarSliderFooterProps - > - NavbarHeader: ComponentOverrideDefinition< - NavbarHeaderProps, - NavbarHeaderProps - > - NavbarRow: ComponentOverrideDefinition - NavbarButtons: ComponentOverrideDefinition< - NavbarButtonsProps, - NavbarButtonsProps - > - IconButton: ComponentOverrideDefinition< - IconButtonProps, - Omit - > + Section: typeof Navbar, + components: { + Navbar: ComponentOverrideDefinition + NavbarLinks: ComponentOverrideDefinition< + NavbarLinksProps, + NavbarLinksProps + > + NavbarLinksList: ComponentOverrideDefinition< + NavbarLinksListProps, + NavbarLinksListProps + > + NavbarSlider: ComponentOverrideDefinition< + NavbarSliderProps, + NavbarSliderProps + > + NavbarSliderHeader: ComponentOverrideDefinition< + NavbarSliderHeaderProps, + NavbarSliderHeaderProps + > + NavbarSliderContent: ComponentOverrideDefinition< + NavbarSliderContentProps, + NavbarSliderContentProps + > + NavbarSliderFooter: ComponentOverrideDefinition< + NavbarSliderFooterProps, + NavbarSliderFooterProps + > + NavbarHeader: ComponentOverrideDefinition< + NavbarHeaderProps, + NavbarHeaderProps + > + NavbarRow: ComponentOverrideDefinition + NavbarButtons: ComponentOverrideDefinition< + NavbarButtonsProps, + NavbarButtonsProps + > + IconButton: ComponentOverrideDefinition< + IconButtonProps, + Omit + > + } } Newsletter: { - Newsletter: ComponentOverrideDefinition - NewsletterAddendum: ComponentOverrideDefinition< - NewsletterAddendumProps, - NewsletterAddendumProps - > - NewsletterContent: ComponentOverrideDefinition< - NewsletterContentProps, - NewsletterContentProps - > - NewsletterForm: ComponentOverrideDefinition< - NewsletterFormProps, - NewsletterFormProps - > - NewsletterHeader: ComponentOverrideDefinition< - NewsletterHeaderProps, - NewsletterHeaderProps - > - ToastIconSuccess: ComponentOverrideDefinition - ToastIconError: ComponentOverrideDefinition - HeaderIcon: ComponentOverrideDefinition - InputFieldName: ComponentOverrideDefinition< - InputFieldProps, - Omit - > - InputFieldEmail: ComponentOverrideDefinition< - InputFieldProps, - Omit - > - Button: ComponentOverrideDefinition + Section: typeof Newsletter + components: { + Newsletter: ComponentOverrideDefinition + NewsletterAddendum: ComponentOverrideDefinition< + NewsletterAddendumProps, + NewsletterAddendumProps + > + NewsletterContent: ComponentOverrideDefinition< + NewsletterContentProps, + NewsletterContentProps + > + NewsletterForm: ComponentOverrideDefinition< + NewsletterFormProps, + NewsletterFormProps + > + NewsletterHeader: ComponentOverrideDefinition< + NewsletterHeaderProps, + NewsletterHeaderProps + > + ToastIconSuccess: ComponentOverrideDefinition + ToastIconError: ComponentOverrideDefinition + HeaderIcon: ComponentOverrideDefinition + InputFieldName: ComponentOverrideDefinition< + InputFieldProps, + Omit + > + InputFieldEmail: ComponentOverrideDefinition< + InputFieldProps, + Omit + > + Button: ComponentOverrideDefinition + } } ProductDetails: { - ProductTitle: ComponentOverrideDefinition< - ProductTitleProps, - ProductTitleProps - > - DiscountBadge: ComponentOverrideDefinition< - DiscountBadgeProps, - Omit - > - BuyButton: ComponentOverrideDefinition - Icon: ComponentOverrideDefinition - ProductPrice: ComponentOverrideDefinition< - ProductPriceProps, - Omit - > - QuantitySelector: ComponentOverrideDefinition< - QuantitySelectorProps, - Omit - > - SkuSelector: ComponentOverrideDefinition - ShippingSimulation: ComponentOverrideDefinition< - ShippingSimulationProps, - ShippingSimulationProps - > - ImageGallery: ComponentOverrideDefinition< - ImageGalleryProps, - ImageGalleryProps - > - ImageGalleryViewer: ComponentOverrideDefinition< - ImageGalleryViewerProps, - ImageGalleryViewerProps - > - __experimentalImageGalleryImage: ComponentOverrideDefinition - __experimentalImageGallery: ComponentOverrideDefinition - __experimentalShippingSimulation: ComponentOverrideDefinition - __experimentalNotAvailableButton: ComponentOverrideDefinition + Section: typeof ProductDetails + components: { + ProductTitle: ComponentOverrideDefinition< + ProductTitleProps, + ProductTitleProps + > + DiscountBadge: ComponentOverrideDefinition< + DiscountBadgeProps, + Omit + > + BuyButton: ComponentOverrideDefinition + Icon: ComponentOverrideDefinition + ProductPrice: ComponentOverrideDefinition< + ProductPriceProps, + Omit + > + QuantitySelector: ComponentOverrideDefinition< + QuantitySelectorProps, + Omit + > + SkuSelector: ComponentOverrideDefinition< + SkuSelectorProps, + SkuSelectorProps + > + ShippingSimulation: ComponentOverrideDefinition< + ShippingSimulationProps, + ShippingSimulationProps + > + ImageGallery: ComponentOverrideDefinition< + ImageGalleryProps, + ImageGalleryProps + > + ImageGalleryViewer: ComponentOverrideDefinition< + ImageGalleryViewerProps, + ImageGalleryViewerProps + > + __experimentalImageGalleryImage: ComponentOverrideDefinition + __experimentalImageGallery: ComponentOverrideDefinition + __experimentalShippingSimulation: ComponentOverrideDefinition + __experimentalNotAvailableButton: ComponentOverrideDefinition + } } ProductGallery: { - MobileFilterButton: ComponentOverrideDefinition< - ButtonProps, - Omit - > - FilterIcon: ComponentOverrideDefinition - PrevIcon: ComponentOverrideDefinition - ResultsCountSkeleton: ComponentOverrideDefinition< - SkeletonProps, - Omit - > - SortSkeleton: ComponentOverrideDefinition< - SkeletonProps, - Omit - > - FilterButtonSkeleton: ComponentOverrideDefinition< - SkeletonProps, - Omit - > - LinkButtonPrev: ComponentOverrideDefinition< - LinkButtonProps, - Omit - > - LinkButtonNext: ComponentOverrideDefinition< - LinkButtonProps, - Omit - > - __experimentalFilterDesktop: ComponentOverrideDefinition - __experimentalFilterSlider: ComponentOverrideDefinition - __experimentalProductCard: ComponentOverrideDefinition - __experimentalEmptyGallery: ComponentOverrideDefinition + Section: typeof ProductGallery + components: { + MobileFilterButton: ComponentOverrideDefinition< + ButtonProps, + Omit + > + FilterIcon: ComponentOverrideDefinition + PrevIcon: ComponentOverrideDefinition + ResultsCountSkeleton: ComponentOverrideDefinition< + SkeletonProps, + Omit + > + SortSkeleton: ComponentOverrideDefinition< + SkeletonProps, + Omit + > + FilterButtonSkeleton: ComponentOverrideDefinition< + SkeletonProps, + Omit + > + LinkButtonPrev: ComponentOverrideDefinition< + LinkButtonProps, + Omit + > + LinkButtonNext: ComponentOverrideDefinition< + LinkButtonProps, + Omit + > + __experimentalFilterDesktop: ComponentOverrideDefinition + __experimentalFilterSlider: ComponentOverrideDefinition + __experimentalProductCard: ComponentOverrideDefinition + __experimentalEmptyGallery: ComponentOverrideDefinition + } } ProductShelf: { - ProductShelf: ComponentOverrideDefinition< - ProductShelfProps, - ProductShelfProps - > - __experimentalCarousel: ComponentOverrideDefinition - __experimentalProductCard: ComponentOverrideDefinition< - any, - Omit - > + Section: typeof ProductShelf + components: { + ProductShelf: ComponentOverrideDefinition< + ProductShelfProps, + ProductShelfProps + > + __experimentalCarousel: ComponentOverrideDefinition + __experimentalProductCard: ComponentOverrideDefinition< + any, + Omit + > + } } CrossSellingShelf: { - ProductShelf: ComponentOverrideDefinition< - ProductShelfProps, - ProductShelfProps - > - __experimentalCarousel: ComponentOverrideDefinition - __experimentalProductCard: ComponentOverrideDefinition< - any, - Omit - > + Section: typeof CrossSellingShelf + components: { + ProductShelf: ComponentOverrideDefinition< + ProductShelfProps, + ProductShelfProps + > + __experimentalCarousel: ComponentOverrideDefinition + __experimentalProductCard: ComponentOverrideDefinition< + any, + Omit + > + } } RegionBar: { - RegionBar: ComponentOverrideDefinition< - RegionBarProps, - Omit - > - LocationIcon: ComponentOverrideDefinition - ButtonIcon: ComponentOverrideDefinition + Section: typeof RegionBar + components: { + RegionBar: ComponentOverrideDefinition< + RegionBarProps, + Omit + > + LocationIcon: ComponentOverrideDefinition + ButtonIcon: ComponentOverrideDefinition + } } } diff --git a/packages/core/src/typings/overridesDefinition.ts b/packages/core/src/typings/overridesDefinition.ts index 56ed16ffa8..4efc220ac9 100644 --- a/packages/core/src/typings/overridesDefinition.ts +++ b/packages/core/src/typings/overridesDefinition.ts @@ -1,6 +1,6 @@ -import { SectionsOverrides } from './overrides' +import { ComponentsFromSection, SectionsOverrides } from './overrides' -export type SectionOverrideDefinition< +export type SectionOverrideDefinitionV1< SectionName extends keyof SectionsOverrides > = { /** @@ -11,19 +11,33 @@ export type SectionOverrideDefinition< /** Name of the section to override */ section: SectionName /** An object containing component and prop overrides for section components */ - components?: Partial> + components?: Partial> +} + +export type SectionOverrideDefinition< + Section extends SectionsOverrides[keyof SectionsOverrides]['Section'] +> = { + /** + * CSS class to be appended to the \ element. Behaves similarly to React's className. + * Default classNames from \ element will still be applied. + */ + className?: string + /** Section to override. Accepts a React Component. */ + Section: Section + /** An object containing component and prop overrides for section components */ + components?: Partial>> } export type OverriddenComponents = { - [Key in keyof SectionsOverrides[SectionName]]: Merge< - SectionsOverrides[SectionName][Key] + [Key in keyof SectionsOverrides[SectionName]['components']]: Merge< + SectionsOverrides[SectionName]['components'][Key] > } export type DefaultSectionComponentsDefinitions< K extends keyof SectionsOverrides -> = Record +> = Record export type ComponentOverrideDefinition = | {