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. 40
      striker-ui/pages/_app.tsx
  3. 42
      striker-ui/pages/_document.tsx
  4. 58
      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 { 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 theme from '../theme';
import '../styles/globals.css'; import '../styles/globals.css';
const App = ({ Component, pageProps }: AppProps): JSX.Element => { const clientSideEmotionCache = createEmotionCache();
// This hook is for ensuring the styling is in sync between client and server
useEffect(() => { interface MyAppProps extends AppProps {
// Remove the server-side injected CSS. // eslint-disable-next-line react/require-default-props
const jssStyles = document.querySelector('#jss-server-side'); emotionCache?: EmotionCache;
if (jssStyles) { }
jssStyles.parentElement?.removeChild(jssStyles);
}
}, []);
const App = ({
Component,
emotionCache = clientSideEmotionCache,
pageProps,
}: MyAppProps): JSX.Element => {
return ( return (
<ThemeProvider theme={theme}> <CacheProvider value={emotionCache}>
<Component <ThemeProvider theme={theme}>
// eslint-disable-next-line react/jsx-props-no-spreading <Component
{...pageProps} // eslint-disable-next-line react/jsx-props-no-spreading
/> {...pageProps}
</ThemeProvider> />
</ThemeProvider>
</CacheProvider>
); );
}; };

@ -1,34 +1,52 @@
import Document, { DocumentInitialProps, DocumentContext } from 'next/document'; import Document, { DocumentInitialProps, DocumentContext } from 'next/document';
import { ServerStyleSheets as MaterialUiServerStyleSheets } from '@material-ui/styles'; import createEmotionServer from '@emotion/server/create-instance';
// import { ServerStyleSheet as StyledComponentSheets } from 'styled-components';
import createEmotionCache from '../lib/create_emotion_cache/createEmotionCache';
class MyDocument extends Document { class MyDocument extends Document {
static async getInitialProps( static async getInitialProps(
ctx: DocumentContext, ctx: DocumentContext,
): Promise<DocumentInitialProps> { ): Promise<DocumentInitialProps> {
const materialUiSheets = new MaterialUiServerStyleSheets();
const originalRenderPage = ctx.renderPage; const originalRenderPage = ctx.renderPage;
const emotionCache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(emotionCache);
ctx.renderPage = () => ctx.renderPage = () =>
originalRenderPage({ originalRenderPage({
/* eslint-disable react/display-name */ // Temporary; the implicit type of App doesn't include the prop "emotionCache" thus typescript will complain.
enhanceApp: (App) => (props) => // Find a way to extend the implicit type to add the cache property.
materialUiSheets.collect( // eslint-disable-next-line @typescript-eslint/no-explicit-any
<App enhanceApp: (App: any) =>
/* eslint-disable react/jsx-props-no-spreading */ function EnhanceApp(props) {
{...props} return (
/>, <App
), emotionCache={emotionCache}
/* eslint-disable react/jsx-props-no-spreading */
{...props}
/>
);
},
}); });
const initialProps = await Document.getInitialProps(ctx); 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 { return {
...initialProps, ...initialProps,
styles: ( styles: (
<> <>
{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 { import {
PANEL_BACKGROUND, PANEL_BACKGROUND,
TEXT, TEXT,
@ -7,9 +12,8 @@ import {
DISABLED, DISABLED,
BORDER_RADIUS, BORDER_RADIUS,
} from '../lib/consts/DEFAULT_THEME'; } from '../lib/consts/DEFAULT_THEME';
import 'typeface-roboto-condensed';
const theme: Theme = createMuiTheme({ const theme: Theme = createTheme({
palette: { palette: {
primary: { primary: {
main: PANEL_BACKGROUND, main: PANEL_BACKGROUND,
@ -22,37 +26,39 @@ const theme: Theme = createMuiTheme({
}, },
}, },
typography: { typography: {
fontFamily: 'Roboto Condensed', fontFamily: ['"Roboto Condensed"'].join(','),
fontWeightRegular: 200, fontWeightRegular: 200,
fontSize: 14, fontSize: 14,
}, },
overrides: { components: {
MuiSwitch: { MuiSwitch: {
switchBase: { styleOverrides: {
// Controls default (unchecked) color for the thumb switchBase: {
color: TEXT, // Controls default (unchecked) color for the thumb
}, color: TEXT,
root: { },
padding: 8, root: {
}, padding: 8,
track: { },
borderRadius: BORDER_RADIUS, track: {
border: 3, borderRadius: BORDER_RADIUS,
backgroundColor: PURPLE, border: 3,
opacity: 1, backgroundColor: PURPLE,
'$checked$checked + &': {
// Controls checked color for the track
backgroundColor: BLUE,
opacity: 1, opacity: 1,
[`.${switchClasses.checked}.${switchClasses.checked} + &`]: {
// Controls checked color for the track
backgroundColor: BLUE,
opacity: 1,
},
[`.${switchClasses.disabled}.${switchClasses.disabled} + &`]: {
backgroundColor: DISABLED,
},
}, },
'$disabled$disabled + &': { thumb: {
backgroundColor: DISABLED, color: TEXT,
borderRadius: BORDER_RADIUS,
}, },
}, },
thumb: {
color: TEXT,
borderRadius: BORDER_RADIUS,
},
}, },
}, },
}); });

Loading…
Cancel
Save