"use client"; // import gdi from "@/bootstrap/di/init-di"; /* eslint-disable react/display-name */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable react/jsx-props-no-spreading */ import IBaseVM from "@/bootstrap/helpers/vm/i-base-vm"; import { Component, ReactNode, FC, PropsWithChildren, memo } from "react"; /* -------------------------------------------------------------------------- */ /* Connector Component */ /* -------------------------------------------------------------------------- */ interface IVvmConnector<IVM, PROPS> extends PropsWithChildren { View: FC<any & { vm: IVM }>; Vm: IBaseVM<IVM>; restProps?: PROPS; memoizedByVM?: boolean; } /** * This function is just will be used in */ const VvmConnector = memo( <IVM, PROPS>(props: IVvmConnector<IVM, PROPS>) => { const { View, Vm, restProps, children } = props; const vm = Vm.useVM(); const allProps = { restProps, vm, }; return <View {...allProps}>{children}</View>; }, (prevProps) => { if (prevProps.memoizedByVM) return true; return false; }, ); /* -------------------------------------------------------------------------- */ /* BaseView */ /* -------------------------------------------------------------------------- */ type IVMParent = Record<string, any>; type IPropParent = Record<string, any> | undefined; type BaseProps<IVM extends IVMParent, PROPS extends IPropParent = undefined> = { vm: IBaseVM<IVM>; restProps?: PROPS; /** * By default it's true. * If you pass true this view will update just by changes of vm not rest props * */ memoizedByVM?: boolean; children?: ReactNode; }; export type BuildProps< IVM extends IVMParent, PROPS extends IPropParent = undefined, > = { vm: IVM; restProps: PROPS; children?: ReactNode; }; export default abstract class BaseView< IVM extends IVMParent, PROPS extends IPropParent = undefined, > extends Component<BaseProps<IVM, PROPS>> { protected get componentName() { return this.constructor.name; } protected abstract Build(props: BuildProps<IVM, PROPS>): ReactNode; render(): ReactNode { const { vm, restProps, memoizedByVM, children, ...rest } = this.props; VvmConnector.displayName = this.componentName; return ( <VvmConnector View={this.Build} Vm={vm} memoizedByVM={typeof memoizedByVM === "undefined" ? true : memoizedByVM} restProps={{ ...restProps, ...rest }} > {children} </VvmConnector> ); } /* -------------------------------------------------------------------------- */ }