how to prevent a material-ui package from overriding my app style? - reactjs

I am using the latest Material-UI installation in a React-Gatsby app.
I installed a third party package for a carousel (react-material-ui-carousel).
When I use this package I see it overrides some of my material-ui styles by adding css divs that compete with my app's css divs.
the data-emotion divs are added by my app, and the data-jss style divs are added by the package react-material-ui-carousel.
Is there a way to limit the carousel styling only to the carousel component and not impact the other material-ui components on my page?
(for example the MuiButtonBase contains the MuiButtonBase-root rules that override my site's rules)

try to check your package-lock
and use 3 blocs
"node_modules/react-material-ui-carousel": {
"version": "2.3.7-mui5",
"resolved": "https://registry.npmjs.org/react-material-ui-carousel/-/react-material-ui-carousel-2.3.7-mui5.tgz",
"integrity": "sha512-XM6+kn6db++riBKUufl7XQI8eE/qj5XWpkDpHUWnioICCdUqx6cvWJmIqjBqcMNB4FgcgJFVmsE3iEKs/4gRIA==",
"dependencies": {
"auto-bind": "^2.1.1",
"react-swipeable": "^6.1.0"
},
"peerDependencies": {
"#emotion/react": "^11.4.1",
"#emotion/styled": "^11.3.0",
"#mui/icons-material": "^5.0.0",
"#mui/material": "^5.0.0",
"#mui/styles": "^5.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
}
},
"react-material-ui-carousel": {
"version": "2.3.7-mui5",
"resolved": "https://registry.npmjs.org/react-material-ui-carousel/-/react-material-ui-carousel-2.3.7-mui5.tgz",
"integrity": "sha512-XM6+kn6db++riBKUufl7XQI8eE/qj5XWpkDpHUWnioICCdUqx6cvWJmIqjBqcMNB4FgcgJFVmsE3iEKs/4gRIA==",
"requires": {
"auto-bind": "^2.1.1",
"react-swipeable": "^6.1.0"
}
},
"react-material-ui-carousel": "^2.3.7-mui5",

You can use StylesProvider from #material-ui/core/styles with this you can put prefix to classes names and avoid styles override
import {
MuiThemeProvider,
ThemeProvider,
StylesProvider,
createGenerateClassName,
} from '#material-ui/core/styles';
const generateClassName = createGenerateClassName({
seed: 'classes-custom-prefix',
});
export const Provider = ({ children, theme }) => {
return (
<StylesProvider generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</MuiThemeProvider>
</StylesProvider>
);
};

I was having issues/inconsistencies with styles between production and deploy. For me, the best way to style elements and override MUI styles without "!important" is using:
import { styled } from "#mui/material/styles";
import Button from "#material-ui/core/Button";
const CustomButton = styled(Button)(({ theme }) => ({
display: "flex",
...
}));
And then instead of using
<Button ...args>label</Button>
use
<CustomButton ...args>label</CustomButton>

Related

mui cannot override size style to Rating component

I cannot override default style of MUI Rating component. No matter what it defaults to medium 24 fontSize, and does not increase it. What had I done wrong?
import { Rating } from '#mui/material';
export const Stars = () => {
return (
<>
<Rating name="size-large" defaultValue={2} size="large" />
<Rating
name="size-large"
value={4.5}
precision={0.5}
sx={{ fontSize: '48px' }}
size="large"
readOnly
/>
</>
);
};
package.json
"dependencies": {
"#emotion/react": "^11.10.6",
"#emotion/styled": "^11.10.6",
"#mui/icons-material": "^5.11.0",
"#mui/lab": "^5.0.0-alpha.115",
"#mui/material": "^5.11.9",
"#tanstack/react-query": "^4.22.0",
"axios": "^1.2.2",
"formik": "^2.2.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.6.2",
"styled-components": "^5.3.6",
"yup": "^0.32.11"
},
You're probably not calling this component and seeing some other component. Your code has the first stars with a default value of 2, but your screenshot shows the value at 440 / 550.
Or you may have an MUI Ratings style override or global stylesheet preventing the inline sx styling from taking hold.
You can right click Inspect the stars you are expecting to have a font-size: 48px then see what CSS stylesheet it's getting it's actual font-size from.
Using your code and dependencies in a simple sandbox I see the larger stars as expected.

IonContent not rendering under IonicPage. React. No error

EDIT: I believe the reason that I ran into this problem is I didn't use the ionic start command to create my project and because I didn't have the Ionic CDN in my HTML file.
I hope I can explain this issue I'm having in a clean and concise way.
Environment Information
I am currently using Ionic 6 with React 18
And here are my Dependencies:
"dependencies": {
"#ionic/react": "^6.1.2",
"#ionic/react-router": "^6.1.2",
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.1.1",
"#testing-library/user-event": "^13.5.0",
"#types/jest": "^27.4.1",
"#types/node": "^16.11.27",
"#types/react": "^18.0.6",
"#types/react-dom": "^18.0.2",
"axios": "^0.26.1",
"bootstrap": "^5.1.3",
"dart-sass": "^1.25.0",
"node": "16.14.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router": "^5.3.1",
"react-router-dom": "^5.3.1",
"react-scripts": "5.0.1",
"reactstrap": "^9.0.2",
"testcafe-react-selectors": "^4.1.5",
"typescript": "^4.6.3",
"web-vitals": "^2.1.4",
"xlsx": "^0.18.5"
},
"devDependencies": {
"#types/jest": "^27.4.1",
"#types/node": "17.0.24",
"#types/react": "^18.0.5",
"#types/react-dom": "^18.0.1",
"#types/react-router": "^5.1.18",
"#types/react-router-dom": "^5.3.3",
"#typescript-eslint/eslint-plugin": "^5.19.0",
"#typescript-eslint/parser": "^5.19.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.5.1",
"prettier": "^2.6.2",
"react-scripts": "^5.0.1",
"start-server-and-test": "^1.14.0",
"testcafe": "^1.18.6",
"typescript": "4.6.3",
"typescript-plugin-css-modules": "^3.4.0"
},
Goal
I want to be able to have an Ionic React multi-page application. Obviously it will still be a SPA and not actually have different pages but I want to utilize Ionic's IonPage component which creates a new React View that can be navigated to.
Expected Results
I've stripped much of my project to just bare bones components that I want to be able to use to create a side navigation and be able to navigate to each page and see the contents. Currently I'm just trying to get the ability to see everything from a React Component wrapped in IonPage. This is my App.tsx page:
App.tsx
import { IonApp, IonRouterOutlet, setupIonicReact } from '#ionic/react';
import { IonReactRouter } from '#ionic/react-router';
import React from 'react';
import { Route } from 'react-router';
import Home from './components/Home';
import './custom.css';
setupIonicReact({
mode: 'md',
});
function App() {
return (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/" component={Home} exact={true} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
}
export default App;
I've tried a variety of layouts for my Home.tsx file. Currently this is what is inside
First situation
Home.tsx Current Version
import { IonContent, IonHeader, IonPage } from '#ionic/react';
import React from 'react';
const Home: React.FC = () => {
return (
<IonPage>
<IonHeader>Example</IonHeader>
<IonContent fullscreen>
<h1>Test</h1>
</IonContent>
</IonPage>
);
};
export default Home;
With this setup, the Example Header text shows and is styled like a header correctly. However, the Content Text doesn't show up at all on this. I've determined the reason why it doesn't show up is because the ion-content element/component's height is set to 0. This is not expected. We don't have any css in our project targeting ion-content elements.
Second situation
import { IonContent, IonPage } from '#ionic/react';
import React from 'react';
const Home: React.FC = () => {
return (
<IonPage>
<IonContent fullscreen>
<h1>Test</h1>
</IonContent>
</IonPage>
);
};
export default Home;
In this situation I expect the elements inside of the IonContent Component to be rendered. I originally didn't have the 'fullscreen' attribute but added it recently to test if it was different. It didn't have an affect. What the result is is a completely blank page with the ion-page having width of 0 as well as the ion-content having a width of 0. If I set the widths of the ion-page manually it appears the ion-content's width and height update as well and it shows the content I was looing for.
Third Situation
import { IonContent } from '#ionic/react';
import React from 'react';
const Home: React.FC = () => {
return (
<IonContent fullscreen>
<h1>Test</h1>
</IonContent>
);
};
export default Home;
In this situation I've removed the IonPage element from the page. Surprisingly it appears that the content is displayed in this situation even though I've seen online that the IonRouter need to find an element with IonPage.
What I want to achieve:
I want to be able to have a react component with IonPage, IonHeader, and IonContent and have all elements inside of these render on the page when navigated to it.
What I want to know
What is causing the IonPage to behave strangely by having 0 height at some points. Why does the Content not show when wrapped around an IonPage but an IonHeader wrapped around an IonPage does show.
No Error Messages Available
Additional Notes
I also attempted to create a new IonicProject with react 17 instead of 18 as I thought it was a support issue, but it appears with the same full code with IonPage, IonContent, and IonHeader the content was not displaying. Thank you for your time!
I basically created a sidenav template from ionic start and determined all of the differences between the two projects.
I eventually determined that there are additional css import statements that I didn't realize I needed to add to my App.tsx in order for the IonApp,IonHeader,IonContent to work correctly.
These are the imports I found from the template project:
/* Core CSS required for Ionic components to work properly */
import "#ionic/react/css/core.css";
/* Basic CSS for apps built with Ionic */
import "#ionic/react/css/normalize.css";
import "#ionic/react/css/structure.css";
import "#ionic/react/css/typography.css";
/* Optional CSS utils that can be commented out */
import "#ionic/react/css/padding.css";
import "#ionic/react/css/float-elements.css";
import "#ionic/react/css/text-alignment.css";
import "#ionic/react/css/text-transformation.css";
import "#ionic/react/css/flex-utils.css";
import "#ionic/react/css/display.css";
/* Theme variables */
import "./theme/variables.css";
The theme variables are option and if there isn't a variables.css file in the theme folder it will give an error.
However after adding these import statements all of the content on the page renders.

Material UI V5 : makeStyles not working in material ui V5

I was trying to upgrate material v5(from v4). As per documentation , it is recommended to use
Styled or sx API but I wanted to use makeStyles approach as in v4. Even though it is deprecated in v5 but can be used(as per documentation). But I am unable to get theme variable inside makeStyles callback function causing cann't access property of undefined(eg. theme.breakpoints.between...)
import makeStyles from '#mui/styles/makeStyles';
const useStyles = makeStyles((theme) => ({
// here theme variable is undefined
appBar: {
backgroundColor: "white",
height: "60px",
padding: "0px 5em",
[theme.breakpoints.between("xs", 'lg')]: {
padding: "0px",
},
},
.......
Here is my index.js
import { ThemeProvider, StyledEngineProvider } from "#mui/material/styles";
import theme from "./theme/theme"
ReactDOM.render(
<React.StrictMode>
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
</StyledEngineProvider>
</React.StrictMode>,
document.getElementById("root")
);
theme.js
import { createTheme, responsiveFontSizes, adaptV4Theme } from "#mui/material/styles";
import baseTheme from "./baseTheme";
let theme = createTheme(adaptV4Theme(baseTheme));
theme = responsiveFontSizes(theme);
export default theme;
Also I noticed, StyledEngineProvider is not being property imported(followed this)
package.json
"#emotion/react": "^11.5.0",
"#emotion/styled": "^11.3.0",
"#fortawesome/fontawesome-svg-core": "^1.2.32",
"#fortawesome/free-solid-svg-icons": "^5.15.1",
"#fortawesome/react-fontawesome": "^0.1.13",
"#mui/icons-material": "^5.1.0",
"#mui/lab": "^5.0.0-alpha.54",
"#mui/material": "^5.1.0",
"#mui/styles": "^5.1.0",
Do I have to install additional package to make it working?
Okay, just had this problem. The makeStyles and styled uses a different context to get theme. In order for your makeStyles to access the theme you need import { ThemeProvider } from '#mui/styles'. But to use styled(), you need import { ThemeProvider } from '#mui/material'.
And if you use both styled() AND makeStyles for migration, you need to have BOTH of those theme providers....

error - unhandledRejection: Error: Not supported at Object.react-markdown

Currently I'm using react-markdown as my markdown component in my react project. Along with this I'm also using rehype-raw and remark-gfm. Whenever I run the project I get the following error:
The following is my package.json:
"dependencies": {
"next": "11.1.2",
"next-images": "^1.8.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-markdown": "^7.0.1",
"rehype-raw": "^6.1.0",
"remark-gfm": "^2.0.0",
},
and my component:
import ReactMarkdown from "react-markdown";
import styles from "../styles/Home.module.css";
import remarkGfm from "remark-gfm";
import rehypeRaw from "rehype-raw";
export default function Home({ posts }) {
return (
<main className={styles.main}>
{posts &&
posts.map((image) => (
<div style={{ height: "100%" }}>
<ReactMarkdown
children={image.Content}
rehypePlugins={[rehypeRaw]}
/>
</div>
))}
</main>
);
}
Error shown in logs:
I experienced similar error too, then I've found this solution:
https://github.com/vercel/next.js/issues/25454#issuecomment-903513941
ReactMarkdown is an ESM module which means it cannot be required but rather imported. If you are actually importing in your code, it can be, that the transpiler (e.g.: Babel) changes this, hence the error. So this can be a possible cause of the error.
What you can do to solve this (also described in the issue commit by others):
npm i next-transpile-modules
In next.config.js do the following:
const withTM = require('next-transpile-modules')(['react-markdown']);
module.exports = withTM({
...restOfYourConfig
})
Import ReactMarkdown like this: import ReactMarkdown from 'react-markdown/react-markdown.min';
Other sources:
https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
https://nextjs.org/docs/messages/import-esm-externals
https://www.npmjs.com/package/next-transpile-modules

MenuIcon not found in material-ui/icons

I am trying to create a basic navigation bar with Material UI. The boilerplate template on Material-UI's doc site https://material-ui.com/components/app-bar/ is returning the following error in the browser:
"Attempted import error: '#material-ui/icons' does not contain a default export (imported as 'MenuIcon')."
I have installed #material-ui/core and #material-ui/icons using npm. See package.json:
{
"name": "profile_v4",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.11.2",
"#material-ui/icons": "^4.11.2",
"#testing-library/jest-dom": "^5.11.8",
"#testing-library/react": "^11.2.2",
"#testing-library/user-event": "^12.6.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
"web-vitals": "^0.2.4"
},
My Navbar.js component file:
import React from 'react'
import { AppBar, Toolbar, IconButton, Typography, Button } from '#material-ui/core';
import MenuIcon from "#material-ui/icons";
const Navbar = () => {
return (
<AppBar position="static">
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
News
</Typography>
<Button color="inherit">Login</Button>
</Toolbar>
</AppBar>
)
}
export default Navbar;
I have looked elsewhere on SO for a solve but all answers are a variation on "You have not installed npm material-ui/icons package" so I was hoping someone could tell me what I'm missing. Thanks in advance!
The problem is with how you are importing the icon. You can fix it by either changing to a named import or provide the full path to the icon.
import MenuIcon from "#material-ui/icons/Menu";
import { Menu as MenuIcon } from "#material-ui/icons";
In v5.10.10 this component is not installed with mui
npm install #mui/icons-material
Run an install for the icons-material will bring them into your node_modules/#mui folder.
You can repeat this process for other missing components you are trying to use.

Resources