Root.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { useState, useCallback } from 'react';
  2. import React from 'react';
  3. import { ThemeProvider, makeStyles } from '@material-ui/core/styles';
  4. import { SwipeableDrawer } from '@material-ui/core';
  5. import {
  6. RootContextType,
  7. DialogType,
  8. SnackBarType,
  9. OpenSnackBarType,
  10. } from './Types';
  11. import CustomSnackBar from '../components/customSnackBar/CustomSnackBar';
  12. import CustomDialog from '../components/customDialog/CustomDialog';
  13. import { theme } from '../styles/theme';
  14. const DefaultDialogConfigs: DialogType = {
  15. open: false,
  16. type: 'notice',
  17. params: {
  18. title: '',
  19. component: <></>,
  20. confirm: () => new Promise((res, rej) => res(true)),
  21. cancel: () => new Promise((res, rej) => res(true)),
  22. },
  23. };
  24. export const rootContext = React.createContext<RootContextType>({
  25. openSnackBar: (
  26. message,
  27. type = 'success',
  28. autoHideDuration,
  29. position = { vertical: 'top', horizontal: 'right' }
  30. ) => {},
  31. dialog: DefaultDialogConfigs,
  32. setDialog: params => {},
  33. handleCloseDialog: () => {},
  34. setDrawer: (params: any) => {},
  35. });
  36. const { Provider } = rootContext;
  37. // Dialog has two type : normal | custom;
  38. // notice type mean it's a notice dialog you need to set props like title, content, actions
  39. // custom type could have own state, you could set a complete component in dialog.
  40. export const RootProvider = (props: { children: React.ReactNode }) => {
  41. const classes = makeStyles({
  42. paper: {
  43. minWidth: '300px',
  44. borderRadius: '0px',
  45. },
  46. paperAnchorRight: {
  47. width: '40vw',
  48. },
  49. })();
  50. const [snackBar, setSnackBar] = useState<SnackBarType>({
  51. open: false,
  52. type: 'success',
  53. message: '',
  54. vertical: 'top',
  55. horizontal: 'right',
  56. autoHideDuration: 3000,
  57. });
  58. const [dialog, setDialog] = useState<DialogType>(DefaultDialogConfigs);
  59. const [drawer, setDrawer]: any = useState({
  60. anchor: 'right',
  61. open: false,
  62. child: <></>,
  63. });
  64. const handleSnackBarClose = () => {
  65. setSnackBar(v => ({ ...v, open: false }));
  66. };
  67. const openSnackBar: OpenSnackBarType = useCallback(
  68. (
  69. message = '',
  70. type = 'success',
  71. autoHideDuration: number | null | undefined = 5000,
  72. position = { vertical: 'top', horizontal: 'right' }
  73. ) => {
  74. setSnackBar({
  75. open: true,
  76. message,
  77. type,
  78. autoHideDuration,
  79. ...position,
  80. });
  81. },
  82. []
  83. );
  84. const handleCloseDialog = () => {
  85. // setDialog(DefaultDialogConfigs);
  86. setDialog({
  87. ...dialog,
  88. open: false,
  89. });
  90. };
  91. const toggleDrawer =
  92. (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
  93. if (
  94. event.type === 'keydown' &&
  95. ((event as React.KeyboardEvent).key === 'Tab' ||
  96. (event as React.KeyboardEvent).key === 'Shift')
  97. ) {
  98. return;
  99. }
  100. setDrawer({ ...drawer, open: open });
  101. };
  102. return (
  103. <Provider
  104. value={{
  105. openSnackBar,
  106. dialog,
  107. setDialog,
  108. handleCloseDialog,
  109. setDrawer,
  110. }}
  111. >
  112. <ThemeProvider theme={theme}>
  113. <CustomSnackBar {...snackBar} onClose={handleSnackBarClose} />
  114. {props.children}
  115. <CustomDialog {...dialog} onClose={handleCloseDialog} />
  116. <SwipeableDrawer
  117. anchor={drawer.anchor}
  118. open={drawer.open}
  119. onClose={toggleDrawer(false)}
  120. onOpen={toggleDrawer(true)}
  121. classes={{ paperAnchorRight: classes.paperAnchorRight }}
  122. >
  123. {drawer.child}
  124. </SwipeableDrawer>
  125. </ThemeProvider>
  126. </Provider>
  127. );
  128. };