93 lines
4.0 KiB
TypeScript
93 lines
4.0 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"
|
|
import VtText from "@modules/layout/templates/vt-text"
|
|
import VtInput from "@modules/layout/templates/vt-input"
|
|
import VtCurrencySelect from "@modules/layout/templates/vt-currency-select"
|
|
import VtMenuItem from "@modules/layout/templates/vt-menu-item"
|
|
import VtCountryCodeSelect from "@modules/layout/templates/vt-country-select/server"
|
|
import VtSocialLinks from "@modules/layout/templates/vt-social-link"
|
|
|
|
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),
|
|
VtCurrencySelect: nodesContextRenderer(VtCurrencySelect),
|
|
VtCountryCodeSelect: nodesContextRenderer(VtCountryCodeSelect),
|
|
VtSocialLinks: nodesContextRenderer(VtSocialLinks),
|
|
Link: nodesContextRenderer(VtLink),
|
|
Input: nodesContextRenderer(VtInput),
|
|
Image: nodesContextRenderer(VtImage),
|
|
Text: nodesContextRenderer(VtText),
|
|
Dropdown: nodesContextRenderer(VtDropdown),
|
|
VtMenuItem: nodesContextRenderer(VtMenuItem),
|
|
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] |