Skip to content

Commit

Permalink
add mui support
Browse files Browse the repository at this point in the history
  • Loading branch information
mahmoudmoravej committed Mar 19, 2024
1 parent 0a62ecc commit d095d37
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 37 deletions.
5 changes: 4 additions & 1 deletion app/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
AuthenticationClientProvider,
SettingsClientProvider,
} from "./contexts";
import { MuiClientProvider } from "./mui/MuiClientProvider";

startTransition(() => {
hydrateRoot(
Expand All @@ -22,7 +23,9 @@ startTransition(() => {
<AuthenticationClientProvider>
<ApolloClientProvider>
<ThemeProvider>
<RemixBrowser />
<MuiClientProvider>
<RemixBrowser />
</MuiClientProvider>
</ThemeProvider>
</ApolloClientProvider>
</AuthenticationClientProvider>
Expand Down
9 changes: 6 additions & 3 deletions app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
SettingsServerProvider,
} from "./contexts";
import { User } from "./models/user";
import { MuiServerProvider } from "./mui/MuiServerProvider";

const ABORT_DELAY = 5_000;
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; //TODO: remove this line. It is dangerous. We have it because there is an issue with the SSL certificate chain of render.com in production
Expand Down Expand Up @@ -207,9 +208,11 @@ function getServerApp(
}
>
<AuthenticationServerProvider user={user}>
<ApolloServerProvider client={client}>
{remixServer}
</ApolloServerProvider>
<MuiServerProvider>
<ApolloServerProvider client={client}>
{remixServer}
</ApolloServerProvider>
</MuiServerProvider>
</AuthenticationServerProvider>
</SettingsServerProvider>
);
Expand Down
9 changes: 9 additions & 0 deletions app/mui/ClientStyleContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from "react";

export interface ClientStyleContextData {
reset: () => void;
}

export default React.createContext<ClientStyleContextData>({
reset: () => {},
});
43 changes: 43 additions & 0 deletions app/mui/MuiClientProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { CacheProvider } from "@emotion/react";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";

import ClientStyleContext from "./ClientStyleContext";
import createEmotionCache from "./createEmotionCache";
import { useMemo, useState } from "react";
import theme from "./theme";

interface ClientCacheProviderProps {
children: React.ReactNode;
}

function ClientCacheProvider({ children }: ClientCacheProviderProps) {
const [cache, setCache] = useState(createEmotionCache());

const clientStyleContextValue = useMemo(
() => ({
reset() {
setCache(createEmotionCache());
},
}),
[],
);

return (
<ClientStyleContext.Provider value={clientStyleContextValue}>
<CacheProvider value={cache}>{children}</CacheProvider>
</ClientStyleContext.Provider>
);
}

export function MuiClientProvider({ children }: { children: React.ReactNode }) {
return (
<ClientCacheProvider>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
{children}
</ThemeProvider>
</ClientCacheProvider>
);
}
35 changes: 35 additions & 0 deletions app/mui/MuiDocument.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { EmotionCache, withEmotionCache } from "@emotion/react";
import { unstable_useEnhancedEffect as useEnhancedEffect } from "@mui/material";
import { useContext } from "react";
import ClientStyleContext from "./ClientStyleContext";

interface DocumentProps {
children: React.ReactNode;
title?: string;
}

//TODO: Do we really need this one???
export const MuiDocument = withEmotionCache(
({ children }: DocumentProps, emotionCache: EmotionCache) => {
const clientStyleData = useContext(ClientStyleContext);

// Only executed on client
useEnhancedEffect(() => {
debugger;
// re-link sheet container
emotionCache.sheet.container = document.head;
// re-inject tags
const tags = emotionCache.sheet.tags;
emotionCache.sheet.flush();
tags.forEach((tag) => {
// eslint-disable-next-line no-underscore-dangle
(emotionCache.sheet as any)._insertTag(tag);
});
// reset cache to reapply global styles
clientStyleData.reset();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return children;
},
);
21 changes: 21 additions & 0 deletions app/mui/MuiServerProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { CacheProvider } from "@emotion/react";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";

import createEmotionCache from "./createEmotionCache";

import theme from "./theme";

export function MuiServerProvider({ children }: { children: React.ReactNode }) {
const cache = createEmotionCache();

return (
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
{children}
</ThemeProvider>
</CacheProvider>
);
}
5 changes: 5 additions & 0 deletions app/mui/createEmotionCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import createCache from "@emotion/cache";

export default function createEmotionCache() {
return createCache({ key: "css" });
}
15 changes: 15 additions & 0 deletions app/mui/getMuiLinks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LinksFunction } from "@remix-run/node";

export const getMuiLinks: LinksFunction = () => [
// Google Fonts for MUI
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
{
rel: "preconnect",
href: "https://fonts.gstatic.com",
crossOrigin: "anonymous",
},
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap",
},
];
6 changes: 6 additions & 0 deletions app/mui/getMuiMeta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import theme from "./theme";
import { MetaDescriptor } from "@remix-run/react";

export const getMuiMeta = (): MetaDescriptor[] => [
{ name: "theme-color", content: theme.palette.primary.main },
];
19 changes: 19 additions & 0 deletions app/mui/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createTheme } from "@mui/material/styles";
import { red } from "@mui/material/colors";

// Create a theme instance.
const theme = createTheme({
palette: {
primary: {
main: "#556cd6",
},
secondary: {
main: "#19857b",
},
error: {
main: red.A400,
},
},
});

export default theme;
50 changes: 25 additions & 25 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,44 @@ import {
Links,
LiveReload,
Meta,
MetaFunction,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";

import stylesheet from "~/tailwind.css";

import { getMuiLinks } from "./mui/getMuiLinks";
import { getMuiMeta } from "./mui/getMuiMeta";
import { MuiDocument } from "./mui/MuiDocument";

export const links: LinksFunction = () => [
...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
{ rel: "stylesheet", href: stylesheet },

// Google Fonts for MUI
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
{
rel: "preconnect",
href: "https://fonts.gstatic.com",
crossOrigin: "anonymous",
},
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap",
},
...getMuiLinks(),
];

export const meta: MetaFunction = () => [...getMuiMeta()];

export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
<MuiDocument>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
</MuiDocument>
);
}
10 changes: 5 additions & 5 deletions app/widgets/layout/site-navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import {
Navbar as MTNavbar,
MobileNav,
Typography,
Button,
IconButton,
Collapse,
} from "@material-tailwind/react";
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
import { siteRouteType } from "~/routesData";
Expand Down Expand Up @@ -97,11 +97,11 @@ export function SiteNavbar({
)}
</IconButton>
</div>
<MobileNav
className="rounded-xl bg-white px-4 pb-4 pt-2 text-blue-gray-900"
<Collapse
className="rounded-xl bg-white text-blue-gray-900"
open={openNav}
>
<div className="container mx-auto">
<div className="mx-aut container px-4 pb-4 pt-2">
{navList}
<a
href="https://www.material-tailwind.com/blocks/react?ref=mtkr"
Expand All @@ -117,7 +117,7 @@ export function SiteNavbar({
className: "w-full block",
})}
</div>
</MobileNav>
</Collapse>
</MTNavbar>
);
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@apollo/client": "^3.9.5",
"@emotion/react": "^11.11.4",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@graphql-codegen/typescript-react-apollo": "^4.3.0",
"@heroicons/react": "^2.1.1",
Expand Down
Loading

0 comments on commit d095d37

Please sign in to comment.