Skip to content

Commit b8e408d

Browse files
committed
feat: partial support simple VMs for withLazyViewModel HOC
1 parent c54d82b commit b8e408d

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

.changeset/neat-symbols-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mobx-view-model": minor
3+
---
4+
5+
support `ViewModelSimple` for `withLazyViewModel` HOC

src/hoc/with-lazy-view-model.tsx

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,45 @@ import { PackedAsyncModule, unpackAsyncModule } from 'yummies/imports';
44

55
import { viewModelsConfig } from '../config/global-config.js';
66
import { Class, Maybe, MaybePromise } from '../utils/types.js';
7-
import { AnyViewModel } from '../view-model/index.js';
7+
import { AnyViewModel, AnyViewModelSimple } from '../view-model/index.js';
88

99
import {
1010
VMComponent,
1111
ViewModelHocConfig,
12+
ViewModelSimpleHocConfig,
1213
withViewModel,
1314
} from './with-view-model.js';
1415

1516
export interface LazyViewAndModel<
16-
TViewModel extends AnyViewModel,
17+
TViewModel extends AnyViewModel | AnyViewModelSimple,
1718
TView extends ComponentType<any>,
1819
> {
1920
Model: Class<TViewModel> | PackedAsyncModule<Class<TViewModel>>;
2021
View?: TView | PackedAsyncModule<TView>;
2122
}
2223

2324
export type VMLazyComponent<
24-
TViewModel extends AnyViewModel,
25+
TViewModel extends AnyViewModel | AnyViewModelSimple,
2526
TView extends ComponentType<any>,
2627
> = VMComponent<TViewModel, ComponentProps<TView>> & LoadableMixin;
2728

2829
/**
2930
* @deprecated use `VMLazyComponent` instead. Will be removed in next major release
3031
*/
3132
export type ComponentWithLazyViewModel<
32-
TViewModel extends AnyViewModel,
33+
TViewModel extends AnyViewModel | AnyViewModelSimple,
3334
TView extends ComponentType<any>,
3435
> = VMLazyComponent<TViewModel, ComponentProps<TView>> & LoadableMixin;
3536

3637
export interface LazyViewModelHocConfig<TViewModel extends AnyViewModel>
3738
extends ViewModelHocConfig<TViewModel>,
3839
Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {}
3940

41+
export interface LazyViewModelSimpleHocConfig<
42+
TViewModel extends AnyViewModelSimple,
43+
> extends ViewModelSimpleHocConfig<TViewModel>,
44+
Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {}
45+
4046
/**
4147
* A Higher-Order Component that **LAZY** connects React components to their ViewModels, providing seamless MobX integration.
4248
*
@@ -50,17 +56,52 @@ export function withLazyViewModel<
5056
configOrFallbackComponent?:
5157
| LazyViewModelHocConfig<NoInfer<TViewModel>>
5258
| LoadableConfig['loading'],
59+
): VMLazyComponent<TViewModel, TView>;
60+
61+
/**
62+
* A Higher-Order Component that **LAZY** connects React components to their ViewModels, providing seamless MobX integration.
63+
*
64+
* [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-lazy-view-model.html)
65+
*/
66+
export function withLazyViewModel<
67+
TViewModel extends AnyViewModelSimple,
68+
TView extends ComponentType<any>,
69+
>(
70+
loadFunction: () => MaybePromise<LazyViewAndModel<TViewModel, TView>>,
71+
configOrFallbackComponent?:
72+
| LazyViewModelSimpleHocConfig<NoInfer<TViewModel>>
73+
| LoadableConfig['loading'],
74+
): VMLazyComponent<TViewModel, TView>;
75+
76+
/**
77+
* A Higher-Order Component that **LAZY** connects React components to their ViewModels, providing seamless MobX integration.
78+
*
79+
* [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-lazy-view-model.html)
80+
*/
81+
export function withLazyViewModel<
82+
TViewModel extends AnyViewModel | AnyViewModelSimple,
83+
TView extends ComponentType<any>,
84+
>(
85+
loadFunction: () => MaybePromise<LazyViewAndModel<TViewModel, TView>>,
86+
configOrFallbackComponent?:
87+
| LazyViewModelSimpleHocConfig<any>
88+
| LazyViewModelHocConfig<any>
89+
| LoadableConfig['loading'],
5390
): VMLazyComponent<TViewModel, TView> {
54-
const config: Maybe<LazyViewModelHocConfig<NoInfer<TViewModel>>> =
91+
const config: Maybe<
92+
LazyViewModelHocConfig<any> | LazyViewModelSimpleHocConfig<any>
93+
> =
5594
typeof configOrFallbackComponent === 'function'
5695
? {
5796
fallback: configOrFallbackComponent,
5897
}
5998
: configOrFallbackComponent;
6099

61-
const patchedConfig: LazyViewModelHocConfig<NoInfer<TViewModel>> = {
100+
const patchedConfig: LazyViewModelHocConfig<any> = {
62101
...config,
63102
ctx: {
103+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
104+
// @ts-expect-error
64105
...config?.ctx,
65106
externalComponent: null,
66107
},

src/hoc/with-view-model.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { createCounter } from 'yummies/complex';
2222

2323
import {
2424
ViewModelParams,
25+
ViewModelSimple,
2526
ViewModelStore,
2627
ViewModelsProvider,
2728
ViewModelsRawConfig,
@@ -1385,4 +1386,32 @@ describe('withViewModel', () => {
13851386

13861387
circularVmPayloadDependencyTestCases.forEach(createTest);
13871388
});
1389+
1390+
describe('ViewModelSimple', () => {
1391+
test('renders (1 overload)', async () => {
1392+
class VM implements ViewModelSimple {
1393+
id: string = '1234';
1394+
}
1395+
const View = ({ model }: ViewModelProps<VM>) => {
1396+
return <div data-testid={'view'}>{`hello ${model.id}`}</div>;
1397+
};
1398+
const Component = withViewModel(VM)(View);
1399+
1400+
await act(async () => render(<Component />));
1401+
expect(screen.getByText('hello 1234')).toBeDefined();
1402+
});
1403+
1404+
test('renders (1 overload)', async () => {
1405+
class VM implements ViewModelSimple {
1406+
id: string = '1234';
1407+
}
1408+
const View = ({ model }: ViewModelProps<VM>) => {
1409+
return <div data-testid={'view'}>{`hello ${model.id}`}</div>;
1410+
};
1411+
const Component = withViewModel(VM, View);
1412+
1413+
await act(async () => render(<Component />));
1414+
expect(screen.getByText('hello 1234')).toBeDefined();
1415+
});
1416+
});
13881417
});

0 commit comments

Comments
 (0)