2024-11-15 19:44:26 +03:00

97 lines
2.7 KiB
TypeScript

"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>
);
}
/* -------------------------------------------------------------------------- */
}