97 lines
2.7 KiB
TypeScript
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>
|
|
);
|
|
}
|
|
/* -------------------------------------------------------------------------- */
|
|
}
|