Skip to content

Commit 7b628d6

Browse files
committed
feat(#72): added Suspense wrapper for the modals
1 parent a33a8b6 commit 7b628d6

File tree

7 files changed

+64
-9
lines changed

7 files changed

+64
-9
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,26 @@ root.render(
6060
);
6161
```
6262

63-
## Compatibility
63+
## API
6464

65-
For [Material-UI v4](https://v4.mui.com/) use `legacy` prop on the ModalProvider.
65+
### Modal Provider
66+
| Property | Type | Default | Description | Required |
67+
|--|--|--|--|--|
68+
| `legacy` | `Boolean` | `false` | Set to `true` if you want to use mui < 5 version. | false |
69+
| `suspense` | `Boolean` | `true` | Wraps your modal with the [Suspense](https://beta.reactjs.org/reference/react/Suspense) | false |
70+
| `fallback` | `Nullable<ReactNode>` | `null` | Custom component for the Suspense [fallback](https://beta.reactjs.org/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) prop | false |
71+
| `children` | `ReactNode` | `undefined` | - | true
72+
73+
*The rest will be added later... Look at examples* 😊
6674

6775
## Examples
6876

6977
See more examples in [example](https://github.com/Quernest/mui-modal-provider/tree/master/example) folder
7078

79+
## Compatibility
80+
81+
For [Material-UI v4](https://v4.mui.com/) use `legacy` prop on the ModalProvider.
82+
7183
## Developing & linking locally
7284

7385
Because this module utilizes react hooks, it must be linked in a special way that is described here in this [react github issue comment](https://github.com/facebook/react/issues/14257#issuecomment-439967377)

example/src/app.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import Button from '@mui/material/Button';
33
import Grid from '@mui/material/Grid';
44

55
import { useModal } from '../../src';
6-
76
import {
87
SimpleDialog,
98
NestedDialog,
@@ -12,6 +11,10 @@ import {
1211
TransitionModal,
1312
} from './components';
1413

14+
const SimpleLazyLoadedDialog = React.lazy(() =>
15+
import('./components/dialogs/simple-dialog-for-lazy-loading')
16+
);
17+
1518
const App = () => {
1619
const { showModal } = useModal();
1720

@@ -59,6 +62,15 @@ const App = () => {
5962
simple dialog
6063
</Button>
6164
</Grid>
65+
<Grid item>
66+
<Button
67+
variant="contained"
68+
onClick={() => showModal(SimpleLazyLoadedDialog)}
69+
color="primary"
70+
>
71+
simple lazy loaded dialog
72+
</Button>
73+
</Grid>
6274
<Grid item>
6375
<Button
6476
variant="contained"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as React from 'react';
2+
import Dialog, { DialogProps } from '@mui/material/Dialog';
3+
import DialogTitle from '@mui/material/DialogTitle';
4+
5+
const SimpleDialogForLazyLoading: React.FC<DialogProps> = props => (
6+
<Dialog {...props}>
7+
<DialogTitle>Simple Dialog</DialogTitle>
8+
</Dialog>
9+
);
10+
11+
export default SimpleDialogForLazyLoading;

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "2.1.0",
2+
"version": "2.2.0",
33
"license": "MIT",
44
"name": "mui-modal-provider",
55
"author": "Quernest",
@@ -70,7 +70,8 @@
7070
],
7171
"coverageReporters": [
7272
"json",
73-
"text"
73+
"text",
74+
"html"
7475
],
7576
"testPathIgnorePatterns": [
7677
"/node_modules/"

src/modal-provider.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ModalContext from './modal-context';
66
import {
77
LegacyModalProviderWrapper as legacyWrapper,
88
ModalProviderWrapper as wrapper,
9+
NoSuspenseModalProviderWrapper as noSuspenseWrapper,
910
OnCloseEvent,
1011
OnExitedEvent,
1112
} from './test-utils';
@@ -186,7 +187,7 @@ describe('ModalProvider', () => {
186187

187188
it('should fire TransitionProps.onExited prop event on hide', () => {
188189
const { result } = renderHook(() => React.useContext(ModalContext), {
189-
wrapper,
190+
wrapper: noSuspenseWrapper,
190191
});
191192

192193
const onExited = jest.fn();

src/modal-provider.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { ReactNode, Fragment, Suspense } from 'react';
22
import ModalContext from './modal-context';
33
import reducer, { initialState, Types } from './reducer';
44
import {
@@ -15,16 +15,28 @@ import {
1515
import { uid } from './utils';
1616

1717
export interface ModalProviderProps {
18-
children: React.ReactNode;
18+
children: ReactNode;
1919
/**
2020
* Enable it if you want to use mui < 5 version
2121
*/
2222
legacy?: boolean;
23+
/**
24+
* Enable it if you want to wrap the modals with the Suspense feature.
25+
* @see https://beta.reactjs.org/reference/react/Suspense
26+
*/
27+
suspense?: boolean;
28+
/**
29+
* Custom fallback for the Suspense fallback
30+
* @see https://beta.reactjs.org/reference/react/Suspense#displaying-a-fallback-while-content-is-loading
31+
*/
32+
fallback?: ReactNode | null;
2333
}
2434

2535
export default function ModalProvider({
2636
children,
2737
legacy = false,
38+
suspense = true,
39+
fallback = null,
2840
}: ModalProviderProps) {
2941
const [state, dispatch] = React.useReducer(reducer, initialState);
3042

@@ -178,6 +190,8 @@ export default function ModalProvider({
178190
);
179191
});
180192

193+
const SuspenseWrapper = suspense ? Suspense : Fragment;
194+
181195
return (
182196
<ModalContext.Provider
183197
value={{
@@ -190,7 +204,7 @@ export default function ModalProvider({
190204
}}
191205
>
192206
{children}
193-
{renderState()}
207+
<SuspenseWrapper fallback={fallback}>{renderState()}</SuspenseWrapper>
194208
</ModalContext.Provider>
195209
);
196210
}

src/test-utils/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export const LegacyModalProviderWrapper: FC<Props> = ({ children }) => (
1818
<ModalProvider legacy>{children}</ModalProvider>
1919
);
2020

21+
export const NoSuspenseModalProviderWrapper: FC<Props> = ({ children }) => (
22+
<ModalProvider suspense={false}>{children}</ModalProvider>
23+
);
24+
2125
export const ModalContextProviderWrapper: FC<Props> = ({ children }) => (
2226
<ModalContext.Provider value={initialContextState}>
2327
{children}

0 commit comments

Comments
 (0)