UNPKG

mobx-view-model

Version:
84 lines (83 loc) 3.67 kB
import { jsx as _jsx } from "react/jsx-runtime"; /* eslint-disable @typescript-eslint/no-use-before-define */ /* eslint-disable sonarjs/no-nested-functions */ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; import { viewModelsConfig } from '../config/global-config.js'; import { ActiveViewModelContext, ViewModelsContext, } from '../contexts/index.js'; import { useCreateViewModel, } from '../hooks/use-create-view-model.js'; /** * Creates new instance of ViewModel * * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html) */ export function withViewModel(VM, configOrComponent, configOrNothing) { if (typeof configOrComponent === 'function' || (configOrComponent && configOrComponent.$$typeof !== undefined)) { const config = configOrNothing ?? {}; return withViewModelWrapper(VM, { ...config, ctx: { VM, generateId: config.generateId, ...config.ctx, }, }, configOrComponent); } else { const config = configOrComponent ?? {}; const finalConfig = { ...config, ctx: { VM, generateId: config.generateId, ...config.ctx, }, }; return (Component) => withViewModelWrapper(VM, finalConfig, Component); } } const REACT_MEMO_SYMBOL = Symbol.for('react.memo'); const withViewModelWrapper = (VM, config, OriginalComponent) => { const processViewComponent = config.config?.processViewComponent ?? config.vmConfig?.processViewComponent ?? viewModelsConfig.processViewComponent; const wrapViewsInObserver = config.config?.wrapViewsInObserver ?? config.vmConfig?.wrapViewsInObserver ?? viewModelsConfig.wrapViewsInObserver; let Component = processViewComponent?.(OriginalComponent, VM, config) ?? OriginalComponent; if (wrapViewsInObserver && Component && Component.$$typeof !== REACT_MEMO_SYMBOL) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Component = observer(Component); } const reactHook = config.reactHook; const getPayload = config.getPayload; const FallbackComponent = config.fallback ?? viewModelsConfig.fallbackComponent; const ConnectedViewModel = observer((allProps) => { const viewModels = useContext(ViewModelsContext); reactHook?.(allProps, config.ctx, viewModels); const { payload: rawPayload, ...componentProps } = allProps; const payload = getPayload?.(allProps) ?? rawPayload; const model = useCreateViewModel(VM, payload, { ...config, component: ConnectedViewModel, props: componentProps, }); const isRenderAllowedByStore = !viewModels || viewModels.isAbleToRenderView(model.id); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const isRenderAllowedLocally = model.isMounted !== false; const isRenderAllowed = isRenderAllowedByStore && isRenderAllowedLocally; if (isRenderAllowed) { return (_jsx(ActiveViewModelContext.Provider, { value: model, children: Component && _jsx(Component, { ...componentProps, model: model }) })); } return FallbackComponent ? (_jsx(FallbackComponent, { ...allProps, payload: payload })) : null; }); if (process.env.NODE_ENV !== 'production') { ConnectedViewModel.displayName = `ConnectedViewModel(${VM.name}->Component)`; } return ConnectedViewModel; };