timetable-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

_app.tsx (2228B)


      1 import CloseIcon from '@mui/icons-material/Close';
      2 import { CssBaseline, IconButton } from '@mui/material';
      3 import { styled, ThemeProvider } from '@mui/material/styles';
      4 import { AppCacheProvider } from '@mui/material-nextjs/v14-pagesRouter';
      5 import Head from 'next/head';
      6 import {
      7 	MaterialDesignContent,
      8 	SnackbarProvider,
      9 	closeSnackbar,
     10 } from 'notistack';
     11 import { useMemo } from 'react';
     12 import { CookiesProvider } from 'react-cookie';
     13 
     14 import createEmotionCache from 'client/utils/createEmotionCache';
     15 import getMuiTheme from 'client/utils/getMuiTheme';
     16 import { trpc } from 'client/utils/trpc';
     17 
     18 import type { EmotionCache } from '@emotion/react';
     19 import type { AppProps } from 'next/app';
     20 import type { ReactNode } from 'react';
     21 
     22 import 'client/styles/global.css';
     23 
     24 const clientSideEmotionCache = createEmotionCache();
     25 
     26 const StyledMaterialDesignContent = styled(MaterialDesignContent)(
     27 	({ theme }) => ({
     28 		'&.notistack-MuiContent-warning': {
     29 			backgroundColor: theme.vars.palette.warning.main,
     30 		},
     31 	}),
     32 );
     33 
     34 interface MyAppProps extends AppProps<{ children: ReactNode }> {
     35 	emotionCache?: EmotionCache;
     36 }
     37 
     38 // TODO: 軽量モードを実装
     39 function App({
     40 	Component,
     41 	pageProps,
     42 	emotionCache = clientSideEmotionCache,
     43 }: MyAppProps) {
     44 	const theme = useMemo(() => getMuiTheme(), []);
     45 
     46 	return (
     47 		<AppCacheProvider emotionCache={emotionCache}>
     48 			<ThemeProvider theme={theme} defaultMode='system'>
     49 				<CookiesProvider>
     50 					<SnackbarProvider
     51 						maxSnack={3}
     52 						style={{
     53 							whiteSpace: 'pre-wrap', // \n で改行
     54 							flexWrap: 'nowrap', // 閉じるボタンを横並び
     55 						}}
     56 						Components={{ warning: StyledMaterialDesignContent }}
     57 						action={(key) => (
     58 							<IconButton
     59 								size='small'
     60 								aria-label='close'
     61 								color='inherit'
     62 								onClick={() => closeSnackbar(key)}
     63 							>
     64 								<CloseIcon fontSize='small' />
     65 							</IconButton>
     66 						)}
     67 					>
     68 						<Head>
     69 							<meta
     70 								name='viewport'
     71 								content='initial-scale=1, width=device-width'
     72 							/>
     73 						</Head>
     74 						<CssBaseline />
     75 						<Component {...pageProps} />
     76 					</SnackbarProvider>
     77 				</CookiesProvider>
     78 			</ThemeProvider>
     79 		</AppCacheProvider>
     80 	);
     81 }
     82 
     83 export default trpc.withTRPC(App);