Skip to content

Commit

Permalink
Merge pull request #5157 from Couchers-org/web/techdebt/material-ui-u…
Browse files Browse the repository at this point in the history
…pgrade

Material UI upgrade to v5
  • Loading branch information
nabramow authored Nov 21, 2024
2 parents 2987f27 + ec8f08e commit 574471e
Show file tree
Hide file tree
Showing 252 changed files with 6,200 additions and 6,497 deletions.
17 changes: 15 additions & 2 deletions app/web/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const path = require("path");
const toPath = (filePath) => path.join(process.cwd(), filePath);

module.exports = {
core: {
builder: "webpack5",
Expand All @@ -13,11 +16,21 @@ module.exports = {
"../stories/serviceMocks.ts"
);
config.resolve.alias["fs"] = require.resolve("./fsMock.js");
config.resolve.alias["@emotion/core"] = toPath(
"node_modules/@emotion/react"
);
config.resolve.alias["emotion-theming"] = toPath(
"node_modules/@emotion/react"
);
config.resolve.modules = [".", ...(config.resolve.modules || [])];

console.log('⚠️ Note: filtering out CaseSensitivePathsPlugin to avoid issues with libraries that use import paths with wrong case');
console.log(
"⚠️ Note: filtering out CaseSensitivePathsPlugin to avoid issues with libraries that use import paths with wrong case"
);
// @see https://github.com/Urthen/case-sensitive-paths-webpack-plugin
config.plugins = config.plugins.filter((plugin) => plugin.constructor.name !== 'CaseSensitivePathsPlugin')
config.plugins = config.plugins.filter(
(plugin) => plugin.constructor.name !== "CaseSensitivePathsPlugin"
);

return config;
},
Expand Down
23 changes: 17 additions & 6 deletions app/web/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { ThemeProvider } from "@material-ui/core";
import {
ThemeProvider,
StyledEngineProvider,
createTheme,
} from "@mui/material/styles";
import { QueryClient, QueryClientProvider } from "react-query";
import { ThemeProvider as Emotion10ThemeProvider } from "emotion-theming";

import { theme } from "../theme";
import { AuthContext } from "../features/auth/AuthProvider";
Expand All @@ -8,6 +13,8 @@ import "./i18n";
import "./reset.css";
import { Suspense } from "react";

const defaultTheme = createTheme();

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
options: {
Expand All @@ -29,11 +36,15 @@ export const decorators = [
<AuthContext.Provider
value={{ authState: { authenticated: true, userId: 1 } }}
>
<ThemeProvider theme={theme}>
<QueryClientProvider client={client}>
<Story {...context} />
</QueryClientProvider>
</ThemeProvider>
<StyledEngineProvider injectFirst>
<Emotion10ThemeProvider theme={defaultTheme}>
<ThemeProvider theme={theme}>
<QueryClientProvider client={client}>
<Story {...context} />
</QueryClientProvider>
</ThemeProvider>
</Emotion10ThemeProvider>
</StyledEngineProvider>
</AuthContext.Provider>
</Suspense>
);
Expand Down
5 changes: 1 addition & 4 deletions app/web/components/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
Alert as MuiAlert,
AlertProps as MuiAlertProps,
} from "@material-ui/lab/";
import { Alert as MuiAlert, AlertProps as MuiAlertProps } from "@mui/material";
import { grpcErrorStrings, ObscureGrpcErrorMessages } from "appConstants";
import classNames from "classnames";
import React from "react";
Expand Down
96 changes: 43 additions & 53 deletions app/web/components/AppRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Container } from "@material-ui/core";
import classNames from "classnames";
import { Container } from "@mui/material";
import { styled } from "@mui/material/styles";
import CircularProgress from "components/CircularProgress";
import CookieBanner from "components/CookieBanner";
import ErrorBoundary from "components/ErrorBoundary";
Expand All @@ -9,56 +9,33 @@ import { useRouter } from "next/router";
import { useIsNativeEmbed } from "platform/nativeLink";
import { ReactNode, useEffect, useState } from "react";
import { jailRoute, loginRoute } from "routes";
import makeStyles from "utils/makeStyles";
import { theme } from "theme";

import Navigation from "./Navigation";

export const useAppRouteStyles = makeStyles((theme) => ({
fullscreenContainer: {
margin: "0 auto",
padding: 0,
},
nonFullScreenStyles: {
height: "100%",
},
standardContainer: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2),
paddingBottom: theme.spacing(2),
flex: 1,
},
fullWidthContainer: {
margin: "0 auto",
paddingLeft: 0,
paddingRight: 0,
},
nativeEmbedContainer: {
margin: "0 auto",
padding: 0,
},
loader: {
//minimal-effort reduction of layout shifting
minHeight: "50vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginBlockStart: theme.spacing(6),
},
"@global html": {
const StyledLoader = styled("div")(({ theme }) => ({
minHeight: "50vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginBlockStart: theme.spacing(6),
}));

const GlobalStyles = styled("div")(({ theme }) => ({
html: {
scrollPaddingTop: `calc(${theme.shape.navPaddingXs} + ${theme.spacing(2)})`,
height: "100%",
},
[theme.breakpoints.up("sm")]: {
"@global html": {

[theme.breakpoints.up("sm")]: {
scrollPaddingTop: `calc(${theme.shape.navPaddingSmUp} + ${theme.spacing(
2
)})`,
},
},
"@global body": {
body: {
height: "100%",
},
"@global #__next": {
"#__next": {
display: "flex",
flexDirection: "column",
minHeight: "100%",
Expand All @@ -78,7 +55,6 @@ export default function AppRoute({
noFooter = false,
variant = "standard",
}: AppRouteProps) {
const classes = useAppRouteStyles();
const router = useRouter();
const { authState, authActions } = useAuthContext();
const isAuthenticated = authState.authenticated;
Expand All @@ -99,36 +75,50 @@ export default function AppRoute({
if (isAuthenticated && isJailed && router.pathname !== jailRoute) {
router.push(jailRoute);
}
});
}, [isAuthenticated, isJailed, isPrivate, authActions, router]);

const containerSx = {
...(variant !== "full-screen" && { height: "100%" }),
...(variant === "standard" && {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2),
paddingBottom: theme.spacing(2),
flex: 1,
}),
...(variant === "full-width" && {
margin: "0 auto",
paddingLeft: 0,
paddingRight: 0,
}),
...(isNativeEmbed && {
margin: "0 auto",
padding: 0,
}),
};

return (
<ErrorBoundary>
{isPrivate && (!isMounted || !isAuthenticated) ? (
<div className={classes.loader}>
<StyledLoader>
<CircularProgress />
</div>
</StyledLoader>
) : (
<>
<GlobalStyles />
{!isNativeEmbed && <Navigation />}
{/* Temporary container injected for marketing to test dynamic "announcements".
* Find a better spot to componentise this code once plan is more finalised with this */}
<div id="announcements"></div>
<Container
className={classNames({
[classes.nativeEmbedContainer]: isNativeEmbed,
[classes.nonFullScreenStyles]: variant !== "full-screen",
[classes.fullWidthContainer]: variant === "full-width",
[classes.fullscreenContainer]: variant === "full-screen",
[classes.standardContainer]: variant === "standard",
})}
disableGutters
sx={containerSx}
maxWidth={
variant === "full-screen" || variant === "full-width"
? false
: "lg"
}
>
{/* Have to wrap this in a fragment because of https://github.com/mui-org/material-ui/issues/21711 */}
<>{children}</>
{children}
</Container>
{!noFooter && !isNativeEmbed && <Footer />}
</>
Expand Down
2 changes: 1 addition & 1 deletion app/web/components/AuthHeader/AuthHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Divider, Typography } from "@material-ui/core";
import { Divider, Typography } from "@mui/material";
import React from "react";
import makeStyles from "utils/makeStyles";

Expand Down
5 changes: 3 additions & 2 deletions app/web/components/Autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Autocomplete as MuiAutocomplete,
AutocompleteProps as MuiAutocompleteProps,
} from "@material-ui/lab";
} from "@mui/material";
import classNames from "classnames";
import React from "react";
import makeStyles from "utils/makeStyles";
Expand Down Expand Up @@ -53,12 +53,13 @@ export default function Autocomplete<
return (
<MuiAutocomplete
{...otherProps}
options={otherProps.options}
className={classNames(classes.root, className)}
id={id}
renderInput={(params) => (
<TextField
variant={variant}
{...params}
variant={variant}
error={!!error}
label={label}
placeholder={placeholder}
Expand Down
7 changes: 3 additions & 4 deletions app/web/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Avatar as MuiAvatar } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { Skeleton } from "@material-ui/lab";
import { Avatar as MuiAvatar, Skeleton } from "@mui/material";
import makeStyles from "@mui/styles/makeStyles";
import classNames from "classnames";
import Link from "next/link";
import { LiteUser } from "proto/api_pb";
Expand Down Expand Up @@ -98,7 +97,7 @@ export default function Avatar({
) : otherProps.children ? (
<MuiAvatar className={classes.avatar}>{otherProps.children}</MuiAvatar>
) : (
<Skeleton variant="circle" className={classes.avatar} />
<Skeleton variant="circular" className={classes.avatar} />
)}
</div>
);
Expand Down
8 changes: 6 additions & 2 deletions app/web/components/Bar/BarWithHelp.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IconButton, Tooltip } from "@material-ui/core";
import { IconButton, Tooltip } from "@mui/material";
import classNames from "classnames";
import { HelpIcon } from "components/Icons";
import React from "react";
Expand Down Expand Up @@ -37,7 +37,11 @@ export default function BarWithHelp({
<div className={classNames(classes.root, className)}>
<ScoreBar value={value}>{label}</ScoreBar>
<Tooltip title={description}>
<IconButton aria-label="help icon" className={classes.button}>
<IconButton
aria-label="help icon"
className={classes.button}
size="large"
>
<HelpIcon />
</IconButton>
</Tooltip>
Expand Down
2 changes: 1 addition & 1 deletion app/web/components/Bar/ScoreBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ContainerProps,
LinearProgress,
Typography,
} from "@material-ui/core";
} from "@mui/material";
import React from "react";
import makeStyles from "utils/makeStyles";

Expand Down
2 changes: 1 addition & 1 deletion app/web/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ export const Loading = Template.bind({});
Loading.args = { loading: true };

export const AsyncOnClick = Template.bind({});
AsyncOnClick.args = { onClick: () => wait(1e3) };
AsyncOnClick.args = { onClick: async () => (await wait(1e3)) as void };
36 changes: 24 additions & 12 deletions app/web/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Button as MuiButton, ButtonProps, useTheme } from "@material-ui/core";
import { Button as MuiButton, ButtonProps, useTheme } from "@mui/material";
import classNames from "classnames";
import Sentry from "platform/sentry";
import React, { ElementType, ForwardedRef, forwardRef } from "react";
import React, {
ElementType,
ForwardedRef,
forwardRef,
MouseEventHandler,
} from "react";
import { useIsMounted, useSafeState } from "utils/hooks";
import makeStyles from "utils/makeStyles";

Expand Down Expand Up @@ -30,16 +35,20 @@ const useStyles = makeStyles((theme) => ({
},
}));

type ButtonClasses = {
[key: string]: string;
};

//type generics required to allow component prop
//see https://github.com/mui-org/material-ui/issues/15827
export type AppButtonProps<
D extends ElementType = "button",
P = Record<string, unknown>
> = ButtonProps<D, P> & {
loading?: boolean;
};
export type AppButtonProps<D extends ElementType = "button"> =
ButtonProps<D> & {
loading?: boolean;
onClick?: MouseEventHandler<HTMLButtonElement>; // Dynamic type for different component types
classes?: Partial<ButtonClasses>; // Use the flexible ButtonClasses type here
};

function _Button<D extends ElementType = "button", P = Record<string, unknown>>(
function _Button<D extends ElementType = "button">(
{
children,
disabled,
Expand All @@ -49,17 +58,20 @@ function _Button<D extends ElementType = "button", P = Record<string, unknown>>(
variant = "contained",
color = "primary",
...otherProps
}: AppButtonProps<D, P>,
}: AppButtonProps<D>,
ref: ForwardedRef<any> // eslint-disable-line
) {
const isMounted = useIsMounted();
const [waiting, setWaiting] = useSafeState(isMounted, false);
const classes = useStyles();
const theme = useTheme();
async function asyncOnClick(event: unknown) {
async function asyncOnClick(event: React.MouseEvent<HTMLButtonElement>) {
try {
setWaiting(true);
await onClick(event);

if (onClick) {
await onClick(event);
}
} catch (e) {
Sentry.captureException(e);
} finally {
Expand Down
2 changes: 1 addition & 1 deletion app/web/components/CircularProgress.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
CircularProgress as MuiCircularProgress,
CircularProgressProps,
} from "@material-ui/core";
} from "@mui/material";
import classNames from "classnames";
import React, { ForwardedRef } from "react";
import makeStyles from "utils/makeStyles";
Expand Down
2 changes: 1 addition & 1 deletion app/web/components/Comments/CommentBox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card } from "@material-ui/core";
import { Card } from "@mui/material";
import Alert from "components/Alert";
import CircularProgress from "components/CircularProgress";
import NewComment from "components/Comments/NewComment";
Expand Down
Loading

0 comments on commit 574471e

Please sign in to comment.