diff --git a/striker-ui/lib/create_emotion_cache/createEmotionCache.ts b/striker-ui/lib/create_emotion_cache/createEmotionCache.ts
new file mode 100644
index 00000000..e221910d
--- /dev/null
+++ b/striker-ui/lib/create_emotion_cache/createEmotionCache.ts
@@ -0,0 +1,8 @@
+import { EmotionCache } from '@emotion/react';
+import createCache from '@emotion/cache';
+
+const createEmotionCache = (): EmotionCache => {
+ return createCache({ key: 'css' });
+};
+
+export default createEmotionCache;
diff --git a/striker-ui/pages/_app.tsx b/striker-ui/pages/_app.tsx
index 9d2dff4c..75a5d7bb 100644
--- a/striker-ui/pages/_app.tsx
+++ b/striker-ui/pages/_app.tsx
@@ -1,26 +1,32 @@
-import { useEffect } from 'react';
import { AppProps } from 'next/app';
-import { ThemeProvider } from '@material-ui/core/styles';
+import { ThemeProvider } from '@mui/material';
+import { CacheProvider, EmotionCache } from '@emotion/react';
+
+import createEmotionCache from '../lib/create_emotion_cache/createEmotionCache';
import theme from '../theme';
import '../styles/globals.css';
-const App = ({ Component, pageProps }: AppProps): JSX.Element => {
- // This hook is for ensuring the styling is in sync between client and server
- useEffect(() => {
- // Remove the server-side injected CSS.
- const jssStyles = document.querySelector('#jss-server-side');
- if (jssStyles) {
- jssStyles.parentElement?.removeChild(jssStyles);
- }
- }, []);
+const clientSideEmotionCache = createEmotionCache();
+
+interface MyAppProps extends AppProps {
+ // eslint-disable-next-line react/require-default-props
+ emotionCache?: EmotionCache;
+}
+const App = ({
+ Component,
+ emotionCache = clientSideEmotionCache,
+ pageProps,
+}: MyAppProps): JSX.Element => {
return (
-
-
-
+
+
+
+
+
);
};
diff --git a/striker-ui/pages/_document.tsx b/striker-ui/pages/_document.tsx
index 14b48a82..3b0d58c5 100644
--- a/striker-ui/pages/_document.tsx
+++ b/striker-ui/pages/_document.tsx
@@ -1,34 +1,52 @@
import Document, { DocumentInitialProps, DocumentContext } from 'next/document';
-import { ServerStyleSheets as MaterialUiServerStyleSheets } from '@material-ui/styles';
-// import { ServerStyleSheet as StyledComponentSheets } from 'styled-components';
+import createEmotionServer from '@emotion/server/create-instance';
+
+import createEmotionCache from '../lib/create_emotion_cache/createEmotionCache';
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext,
): Promise {
- const materialUiSheets = new MaterialUiServerStyleSheets();
const originalRenderPage = ctx.renderPage;
+ const emotionCache = createEmotionCache();
+ const { extractCriticalToChunks } = createEmotionServer(emotionCache);
+
ctx.renderPage = () =>
originalRenderPage({
- /* eslint-disable react/display-name */
- enhanceApp: (App) => (props) =>
- materialUiSheets.collect(
- ,
- ),
+ // Temporary; the implicit type of App doesn't include the prop "emotionCache" thus typescript will complain.
+ // Find a way to extend the implicit type to add the cache property.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ enhanceApp: (App: any) =>
+ function EnhanceApp(props) {
+ return (
+
+ );
+ },
});
const initialProps = await Document.getInitialProps(ctx);
+ const emotionStyles = extractCriticalToChunks(initialProps.html);
+ const emotionStyleTags = emotionStyles.styles.map((style) => (
+
+ ));
+
return {
...initialProps,
styles: (
<>
{initialProps.styles}
- {materialUiSheets.getStyleElement()}
+ {emotionStyleTags}
>
),
};
diff --git a/striker-ui/theme/index.ts b/striker-ui/theme/index.ts
index 8d684c09..a460072f 100644
--- a/striker-ui/theme/index.ts
+++ b/striker-ui/theme/index.ts
@@ -1,4 +1,9 @@
-import { createMuiTheme, Theme } from '@material-ui/core/styles';
+import { createTheme, Theme } from '@mui/material';
+import { switchClasses } from '@mui/material/Switch';
+import '@fontsource/roboto-condensed/300.css';
+import '@fontsource/roboto-condensed/400.css';
+import '@fontsource/roboto-condensed/700.css';
+
import {
PANEL_BACKGROUND,
TEXT,
@@ -7,9 +12,8 @@ import {
DISABLED,
BORDER_RADIUS,
} from '../lib/consts/DEFAULT_THEME';
-import 'typeface-roboto-condensed';
-const theme: Theme = createMuiTheme({
+const theme: Theme = createTheme({
palette: {
primary: {
main: PANEL_BACKGROUND,
@@ -22,37 +26,39 @@ const theme: Theme = createMuiTheme({
},
},
typography: {
- fontFamily: 'Roboto Condensed',
+ fontFamily: ['"Roboto Condensed"'].join(','),
fontWeightRegular: 200,
fontSize: 14,
},
- overrides: {
+ components: {
MuiSwitch: {
- switchBase: {
- // Controls default (unchecked) color for the thumb
- color: TEXT,
- },
- root: {
- padding: 8,
- },
- track: {
- borderRadius: BORDER_RADIUS,
- border: 3,
- backgroundColor: PURPLE,
- opacity: 1,
- '$checked$checked + &': {
- // Controls checked color for the track
- backgroundColor: BLUE,
+ styleOverrides: {
+ switchBase: {
+ // Controls default (unchecked) color for the thumb
+ color: TEXT,
+ },
+ root: {
+ padding: 8,
+ },
+ track: {
+ borderRadius: BORDER_RADIUS,
+ border: 3,
+ backgroundColor: PURPLE,
opacity: 1,
+ [`.${switchClasses.checked}.${switchClasses.checked} + &`]: {
+ // Controls checked color for the track
+ backgroundColor: BLUE,
+ opacity: 1,
+ },
+ [`.${switchClasses.disabled}.${switchClasses.disabled} + &`]: {
+ backgroundColor: DISABLED,
+ },
},
- '$disabled$disabled + &': {
- backgroundColor: DISABLED,
+ thumb: {
+ color: TEXT,
+ borderRadius: BORDER_RADIUS,
},
},
- thumb: {
- color: TEXT,
- borderRadius: BORDER_RADIUS,
- },
},
},
});