fix(striker-ui): switch from JSS to Emotion engine (MUI v4 to v5)

main
Tsu-ba-me 3 years ago
parent 237d73f673
commit 9025f109eb
  1. 8
      striker-ui/lib/create_emotion_cache/createEmotionCache.ts
  2. 26
      striker-ui/pages/_app.tsx
  3. 36
      striker-ui/pages/_document.tsx
  4. 20
      striker-ui/theme/index.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;

@ -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 (
<CacheProvider value={emotionCache}>
<ThemeProvider theme={theme}>
<Component
// eslint-disable-next-line react/jsx-props-no-spreading
{...pageProps}
/>
</ThemeProvider>
</CacheProvider>
);
};

@ -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<DocumentInitialProps> {
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 (
<App
emotionCache={emotionCache}
/* eslint-disable react/jsx-props-no-spreading */
{...props}
/>,
),
/>
);
},
});
const initialProps = await Document.getInitialProps(ctx);
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(' ')}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
));
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{materialUiSheets.getStyleElement()}
{emotionStyleTags}
</>
),
};

@ -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,12 +26,13 @@ const theme: Theme = createMuiTheme({
},
},
typography: {
fontFamily: 'Roboto Condensed',
fontFamily: ['"Roboto Condensed"'].join(','),
fontWeightRegular: 200,
fontSize: 14,
},
overrides: {
components: {
MuiSwitch: {
styleOverrides: {
switchBase: {
// Controls default (unchecked) color for the thumb
color: TEXT,
@ -40,12 +45,12 @@ const theme: Theme = createMuiTheme({
border: 3,
backgroundColor: PURPLE,
opacity: 1,
'$checked$checked + &': {
[`.${switchClasses.checked}.${switchClasses.checked} + &`]: {
// Controls checked color for the track
backgroundColor: BLUE,
opacity: 1,
},
'$disabled$disabled + &': {
[`.${switchClasses.disabled}.${switchClasses.disabled} + &`]: {
backgroundColor: DISABLED,
},
},
@ -55,6 +60,7 @@ const theme: Theme = createMuiTheme({
},
},
},
},
});
export default theme;

Loading…
Cancel
Save