How to use TailwindCSS with Material UI? - next.js

I am using Next.js with Material UI. I am having troubles with using Tailwind with MUI. I've been following this guide but it still doesn't work. The file loads but the classes just don't apply. If someone could help, that would be wonderful!
My Tailwind Config
module.exports = {
important: "#__next",
content: ["./pages/**/*.{js,jsx}"],
theme: {
extend: {},
},
plugins: [],
}
My _app.js
//import '../styles/globals.css'
//function MyApp({ Component, pageProps }) {
// return <Component {...pageProps} />
//}
//export default MyApp
import '../styles/edit.css';
import * as React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider, StyledEngineProvider } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline';
import { CacheProvider } from '#emotion/react';
import theme from '../config/themeConfig';
import createEmotionCache from '../functions/createEmotionCache';
import Layout from "../components/Layout";
//import '../styles/tailwind.css';
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function MyApp(props) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
return (
<Layout>
<CacheProvider value={emotionCache}>
<Head>
<meta name="viewport" content="initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<StyledEngineProvider injectFirst>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<Component {...pageProps} />
</StyledEngineProvider>
</ThemeProvider>
</CacheProvider>
</Layout>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};
Thanks!

You didn't follow the guide ( https://mui.com/material-ui/guides/interoperability/#tailwind-css ) correctly.
In your tailwind.config.js file you need to set the corePlugins parameter to disable the preflight CSS. The preflight CSS is overriding some of the styles of MUI.

Related

How to migrate MUI _document.js and _app.js to next.js13 app/layout.js

I found these documents (_document.js, _app.js) but it is not so clear to me how it should be defined.
This is the layout.js file I started building, Is there something missing, or something that needs fixing?
Thanks.
app/layout.js
import React from 'react'
import PropTypes from 'prop-types'
import { ThemeProvider } from '#mui/material/styles'
import CssBaseline from '#mui/material/CssBaseline'
import { CacheProvider } from '#emotion/react'
import theme, { roboto } from '../utility/theme'
import Head from './Head'
import createEmotionCache from '../utility/createEmotionCache'
const clientSideEmotionCache = createEmotionCache()
export default function RootLayout({ children }, props) {
const { Component, cache = clientSideEmotionCache, pageProps } = props
return (
<html className={roboto.className}>
<CacheProvider value={cache}>
<Head />
<body>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps}>{children}</Component>
</ThemeProvider>
</body>
</CacheProvider>
</html>
)
}
RootLayout.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
}

How do I pass a property (specifically "theme") to "Components" in a next.js app?

I have a next.js app and this is the _app.tsx file:
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { createTheme } from '#arwes/design'
import { ThemeProvider, Global, css } from '#emotion/react'
import { globalStyles, blueOnBlack } from '../shared/styles.js'
function MyApp({ Component, pageProps }: AppProps) {
const theme = createTheme();
return (
<ThemeProvider theme={theme}>
{globalStyles}
<div style={blueOnBlack(theme)}>
Futuristic Sci-Fi UI Web Framework
</div>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
The problem is that I need to access theme in index.tsx. So how do I pass this into Component?
In the children components, use:
const theme = useContext(ThemeProvider)
I was eventually able to access the parent's theme via emotion's useTheme(). I have to actually build the component outside of the render area of the page's exported function. In the index.tsx file for example:
function SomeText(props: any) {
const theme = useTheme()
return <div style={{ color: theme.palette.primary.dark3 }} {...props} />
}
// Now that above function "SomeText" can be accessed as a component in "Home"
const Home: NextPage = () => {
return (
...
<SomeText className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>pages/index.tsx</code>
</SomeText>
...
)
}
export default Home
And that works because the text above is set to "dark3" color.

Ordering problem using css import alongside styled components in nextjs app

I am using NextJS and when I use direct css import ...css alongside a styled-component createGlobalStyle. My direct css imports are always included last in my html causing some overriding issues that I've setup in GlobalStyles.
How can I resolve this?
rendered html
<head>
<link href="/_next/static/chunks/main.js?ts=1609163560022">
<style></style> // global styled component
<style></style> // bootstrap imported after global styled component
</head>
_app.js
import { ThemeProvider } from "styled-components";
import 'bootstrap/dist/css/bootstrap.min.css' // this is always loaded last <head>
import GlobalStylesfrom 'styles/global'; // this is always loaded first in <head>
const theme = {
...
};
export default function App({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<GlobalStyles/>
<Component {...pageProps} />
</ThemeProvider>
)
}
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static getInitialProps({ renderPage }) {
const sheet = new ServerStyleSheet();
const page = renderPage(App => props =>
sheet.collectStyles(<App {...props} />)
);
const styleTags = sheet.getStyleElement();
return { ...page, styleTags };
}
render() {
return (
<Html>
<Head>{this.props.styleTags}</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}

Why is ThemeProvider (Material UI) not working for me here?

I've used Material UI quite a lot, so this is baffling. I've looked through the docs, I've checked my code, I can't see the issue. I want my H2 tag in the nested component to use Arial. However, it's rendering using Times. I'm not sure why.
Here's my index.tsx:
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { Provider } from "react-redux";
import configureStore from "./redux/stores/main";
import * as serviceWorker from "./serviceWorker";
import { createMuiTheme } from "#material-ui/core";
import myTheme from "./styling/mainTheme";
import { ThemeProvider } from "#material-ui/styles";
const theme = createMuiTheme({
typography: {
fontFamily: ["Arial"].join(",")
}
});
ReactDOM.render(
<ThemeProvider theme={theme}>
<Provider store={configureStore()}>
<App />
</Provider>
</ThemeProvider>,
document.getElementById("root")
);
serviceWorker.unregister();
My app component:
import React from "react";
import { useSelector } from "react-redux";
import HeaderContainer from "../containers/layout/header/HeaderContainer";
import { ThemeProvider, useTheme } from "#material-ui/styles";
import theme from "../styling/mainTheme";
import { createMuiTheme } from "#material-ui/core";
const App: React.FC = () => {
const theme = useTheme();
return (
<div className="App">
<HeaderContainer />
</div>
);
};
export default App;
The header container (will contain logic):
import * as React from 'react';
import Header from '../../../components/layout/header/Header';
export interface HeaderContainerProps {
}
export default class HeaderContainer extends React.Component<HeaderContainerProps> {
public render() {
return <Header />
}
}
And finally the header:
import * as React from "react";
import { styled } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
export default function Header() {
return (
<AppBar>
<h2>Hello</h2>
</AppBar>
)
}
I've tried putting the ThemeProvider in different components, but my h2 is still rendering as Times. Would be great if someone could spot the issue. Thanks
Checking the documents of material-ui it turns out you have imported some of the things from library in a wrong way. Like the docs state -
import { useTheme } from '#material-ui/core/styles';
import { createMuiTheme } from '#material-ui/core/styles';
Which can basically be
import { useTheme, createMuiTheme } from '#material-ui/core/styles';
Same goes for ThemeProvider
import { ThemeProvider } from '#material-ui/core/styles';
In MUI V5 you need to import ThemeProvider and createTheme from #mui/material/styles instead of #mui/styles.
import * as React from 'react';
import ReactDOM from 'react-dom';
import {red} from '#mui/material/colors';
import { ThemeProvider, createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: red[500],
},
},
});
function App() {
return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
ReactDOM.render(<App />, document.querySelector('#app'));
source

Material-UI for React: cannot see changes when applying <ThemeProvider>

I cannot see any change when applying "ThemeProvider" tag, even in a simple project as shown below.
There is no errors/warnings in the browser console (except for unused imports, but it fails even if I remove them all).
import React, { Component } from "react";
import Grid from "#material-ui/core/Grid";
import CssBaseline from "#material-ui/core/CssBaseline";
import MainBar from "./modules/MainBar";
import MainTemplate from "./style/MainTemplate";
import Palette from "./palette";
import { Button } from "#material-ui/core";
import { createMuiTheme } from "#material-ui/core/styles";
import { ThemeProvider } from "#material-ui/styles";
import purple from '#material-ui/core/colors/purple';
const theme = createMuiTheme({
typography: {
useNextVariants: true
},
palette: {
primary: purple,
secondary: {
main: "#f44336"
}
}
});
class App extends Component {
render() {
return (
<div className="App">
<ThemeProvider theme={theme}>
<Button color="primary">BUTTON</Button>
</ThemeProvider>
</div>
);
}
}
export default App;
Any idea about it? Its almost like documentation example, and it doesn't work.
Thank you.
Import MuiThemeProvider like,
import { MuiThemeProvider } from '#material-ui/core/styles';
And replace your code,
<ThemeProvider theme={theme}>
<Button color="primary">BUTTON</Button>
</ThemeProvider>
with this,
<MuiThemeProvider theme={theme}>
<Button color="primary">BUTTON</Button>
</MuiThemeProvider>
Ref

Resources