Shop-Storefront/src/vibentec/component-map.tsx

81 lines
3.3 KiB
TypeScript

import CartMismatchBanner from "@modules/layout/components/cart-mismatch-banner"
import FreeShippingPriceNudge from "@modules/shipping/components/free-shipping-price-nudge"
import { DynamicLayoutRenderer } from "./renderer"
import React from "react"
import VtNav from "@modules/layout/templates/vt-nav"
import VtFooter from "@modules/layout/templates/vt-footer"
import HomeButton from "@modules/layout/components/vt-homebutton"
import AccountButton from "@modules/layout/components/vt-accountbutton"
import VtCartButton from "@modules/layout/components/vt-cartbutton"
import VtHeader from "@modules/layout/templates/vt-header"
import Banner from "@modules/layout/templates/vt-banner"
import VtMegaMenu from "@modules/layout/components/vt-mega-menu"
import VtLink from "@modules/layout/components/vt-linkbutton"
import VtSideMenu from "@modules/layout/components/vt-sidemenu"
import VtImage from "@modules/layout/templates/vt-image"
import VtDropdown from "@modules/layout/templates/vt-dropdown"
import VtButton from "@modules/layout/templates/vt-button"
import VtSearchInput from "@modules/layout/templates/vt-search-input"
import VtSection from "@modules/layout/templates/vt-section"
type ComponentConfig = Record<string, any>;
export interface LayoutComponentDefinition {
config?: ComponentConfig
children?: LayoutComponentNode[]
}
export interface LayoutContext {
customer: any;
cart: any;
shippingOptions: any[];
contentChildren: React.ReactNode;
}
export type ComponentRenderer = {
render: (entry: LayoutComponentDefinition, ctx: LayoutContext) => React.ReactNode
}
// Utility methods
const configOnly = (Component: React.ComponentType<any>): ComponentRenderer => ({
render: (entry) => <Component {...entry.config} />
})
const nodesContextRenderer = (Component: React.ComponentType<any>): ComponentRenderer => ({
render: (entry: any, ctx: LayoutContext) => <Component nodes={entry} context={ctx} />
});
const renderChildren = (entry: LayoutComponentDefinition, ctx: LayoutContext) =>
entry.children ? <DynamicLayoutRenderer nodes={entry.children} context={ctx} /> : null
// Component Map
export const componentMap: Record<string, ComponentRenderer> = {
Header: nodesContextRenderer(VtHeader),
Nav: nodesContextRenderer(VtNav),
VtMegaMenu: nodesContextRenderer(VtMegaMenu),
VtSideMenu: nodesContextRenderer(VtSideMenu),
Banner: nodesContextRenderer(Banner),
HomeButton: nodesContextRenderer(HomeButton),
AccountButton: nodesContextRenderer(AccountButton),
Button: nodesContextRenderer(VtButton),
Section: nodesContextRenderer(VtSection),
SearchInput: nodesContextRenderer(VtSearchInput),
VtCartButton: nodesContextRenderer(VtCartButton),
Link: nodesContextRenderer(VtLink),
Image: nodesContextRenderer(VtImage),
Dropdown: nodesContextRenderer(VtDropdown),
CartMismatchBanner: configOnly(CartMismatchBanner),
FreeShippingPriceNudge: configOnly(FreeShippingPriceNudge),
PropsChildren: {
render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children
},
Footer: nodesContextRenderer(VtFooter)
}
export type ComponentName = keyof typeof componentMap
// //maps key = componentName to value = props + children
// export type LayoutComponentNode = Record<string, LayoutComponentDefinition>
export type LayoutComponentNode = { [K in ComponentName]: LayoutComponentDefinition }[ComponentName]