Can't override AppBar background color - reactjs

could someone please help me with this issue.
this is the code:
import { AppBar } from "#mui/material";
import { makeStyles } from "#mui/styles";
const useStyles = makeStyles({
root: {
backgroundColor: 'red'
}
})
const App = () => {
const classes = useStyles();
return <>
<AppBar className={classes.root}>
test
</AppBar>
<h1 className={classes.root}>test</h1>
</>
}
export default App;
The question is:
why the background-color of the AppBar component is not changing;
No problem with the h1 tag thought;
The other problem I've found is, sometimes it changes, but when I refresh the page, it becomes blue -> color by default;
So, thanks a lot for the answer if there is any :);

I faced a similar issue where styles applied to the AppBar component did not override some of the default styles. The fix was to wrap my component tree with <StyledEngineProvider injectFirst>. The solution looks something like this in the end:
import React from 'react';
import { StyledEngineProvider } from '#mui/material/styles';
export default function GlobalCssPriority() {
return (
<StyledEngineProvider injectFirst>
{/* Your component tree. Now you can override MUI's styles. */}
</StyledEngineProvider>
);
}
Link to source

<AppBar className={classes.root}>
test
</AppBar>
instead wrap your text in a div and use className on that div
<AppBar >
<div className={classes.root}>
test
</div>
</AppBar>

Related

MUI createTheme fonts

Just as the title says. Not sure what's wrong exactly, and would love to learn what I'm doing that's making this not work. I tested the import to see if it works through the web console, and it does, so I'm doing something wrong with createTheme. Here's my code:
import React from 'react';
import AppBar from '../components/appbar';
import { Typography } from '#mui/material'
import Footer from '../components/footer';
import { ThemeProvider, createTheme } from "#mui/material/styles";
const theme = createTheme({
typography: {
fontFamily: [
'Press Start 2P',
'cursive',
].join(','),
},});
const Home = props => {
return (
<div>
<AppBar title="Home" />
<ThemeProvider theme={theme}>
<Typography variant="h2">
Hello World!
</Typography>
</ThemeProvider>
<Footer />
</div>
);
}
export default Home;
Any help is thoroughly appreciated. Thank you very much for your time.

Apply MUI styles to non-MUI markup elements

In my Gatsby app I am using MUI v5, and must also output user created markup. I want the user-markup to get the same base-styles as their analogous Typography elements (see below). How can I achieve this?
Note - the user markup already contains <p> <h1> or other tags, which cannot be directly modified by React.
Additionally the app is wrapped with ThemeProvider and I'm using styled-components as the style engine for MUI (if that matters...).
import {Typography} from "#mui/material"
export default function() {
return (
<>
<Typography variant="body1" paragraph>My styled Typography</Typography>
// The next line can't receive any classses or modifiers,
// but must end up styled like the <Typography> element.
<p>my custom user content - how can i style this like above?</p>
</>
)
}
You need to import your theme. From there you can access the body1 default typography style to apply to the p element.
import {Typography} from '#mui/material'
import {useTheme} from //im not exactly sure where this comes from '#mui/material' or '#mui/styles'
export default function() {
const theme = useTheme()
return (
<>
<Typography variant="body1" paragraph>My styled Typography</Typography>
<p style={theme.typography.body1}>my custom user content - how can i style this like above?</p>
</>
)
}
import {useTheme ,Typography} from "#mui/material"
export default function() {
const theme = useTheme()
return (
<>
<Typography variant="body1" paragraph>My styled Typography</Typography>
<p style={theme.typography.body1}>my custom user content - how can i style this like above?</p>
</>
)
}
If you want to add the sx prop in your custom component:
const P = styled("p")({});
const theme = useTheme()
<P sx={{ ...theme.typography.body1 }}>
If you want to use system properties:
import { unstable_extendSxProp as extendSxProp } from "#mui/system";
const Psx = styled("p")();
function P(inProps) {
const { sx, ...other } = extendSxProp(inProps);
return <Psx sx={sx} {...other} />;
}
<P {...theme.typography.body1}>
If you want to use variant prop like in Typography:
const T = styled('p')(({ theme, variant = 'body1' }) => ({
...theme.typography[variant],
}));
<T variant="h3">
Live Demo
Related Answer
Passing props to MUI styles

Problem with showing a component which is in another file onclick

I am currently building an website in React with a navigation bar which I use Material-UI for.
My problem is that when I for example click "About" in my navigation bar, I want to show the content/component in About, and when I click Home I want the component Home to be shown and others hidden.
The problem is I am still a beginner in React and want to practice my React skills and now I have the navbar, Home, About in seperate files and not sure on how to pass through state, props and so in this case.
I will show a screen shot on the website and code-snippets to show my code so far.
My website:
File structure of my program:
Here is Code:
App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import NavBar from './Components/Navigationbar'
import Home from './Components/Home'
import About from './Components/About'
class App extends Component {
constructor(props){
super(props);
this.state = {showAbout: true};
this.handleAbout = this.handleAbout.bind(this);
}
handleAbout(){
this.setState({showAbout: true})
}
render() {
return (
<div className="App">
<div className="App-header">
</div>
<NavBar></NavBar>
<p className="App-intro">
<Home></Home>
</p>
{this.state.showAbout ? <About /> : null}
</div>
);
}
}
export default App;
Home.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
Home
</Typography>
<Typography component="p">
Welcome Home
</Typography>
</Paper>
</div>
);
}
About.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
About
</Typography>
<Typography component="p">
About
</Typography>
</Paper>
</div>
);
}
And finally the navigation bar which is from Material UI:
Navigationbar.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import Button from '#material-ui/core/Button';
import App from '../App';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import About from './About';
const useStyles = makeStyles({
root: {
flexGrow: 1,
},
});
function handleAbout(props){
alert('About');
}
const navBar = (props) => {
return (
<Paper >
<Tabs
//value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
centered
>
<Tab label="Home" />
<Tab label="About" onClick={() => handleAbout(props)} />
<Tab label="Contact" />
</Tabs>
</Paper>
);
}
//ReactDOM.render(<navBar />, document.querySelector('#app'));
export default navBar;
My problem is I want to when I click "About" in the navbar, I want to show the About component(the content in About.jsx) on my website but not sure on how to handle state and props in the case when they are in seperate files.
Would appreciate if someone could help me.
Thanks a lot.
You can use react-router for navigation. How to install and use it is quite nicely shown on the page: https://reacttraining.com/react-router/web/guides/quick-start
Oh boy, this is a big one...
In the simplest case, you pass state though props like this:
<ChildComponent showAbout={this.state.showAbout}/>, and access it in ChildComponent by props.showAbout (or this.props.showAbout if it's a class component).
But things can get complicated as your application scales. Values can only be passed through props downwards inside the component tree; in other words, a component can only see a state that's somewhere above it. You can't use state from a sibling component or a component below it.
And that's the whole reason state management libraries exist. They provide a 'global' state that is available anywhere in the app. Redux is one of them.
You should sit down and learn Redux, as you can't really make a big app without a state management tool.
Another thing you should learn is react-router, for client-side routing.
Those things combined will provide a powerful tool for making useful apps.

How do you style a component to be under another component?

I'm setting up a small webapp using React and Material-UI, and I can't figure out how to make my drawer component fit under my app bar. Using the react developer tools I can see in the console that my components are picking up the classNames, but no matter what I do my styles aren't being applied to them. Currently, the drawer is clipping through the app bar at the top of the screen, taking up the entire height of the page instead of fitting under the app bar. What do I need to change in order to make my "Sidebar" component fit under my "Navbar" component? One of the reasons why I created these two as separate components is because I'm planning on adding more functionality to them later. Thank you.
I've been following the "clipped under the app bar" component demo at https://material-ui.com/components/drawers/ and I've also referenced Material UI Drawer won't move under Appbar
Here's a snippet of my code
My main app
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import Navbar from './Navbar';
import Sidebar from './Sidebar';
const useStyles = makeStyles(theme => ({
App: {
display: 'flex',
},
navbar: {
zIndex: theme.zIndex.drawer + 1,
},
drawer: {
width: 240,
flexShrink: 0,
},
toolbar: theme.mixins.toolbar,
}));
function App() {
const classes = useStyles();
return (
<div className="App">
<CssBaseline/>
<Navbar position="fixed" className={classes.navbar}></Navbar>
<Sidebar className={classes.drawer}></Sidebar>
</div>
);
}
export default App;
My Navbar component
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
function Navbar() {
return (
<AppBar positon="static">
<Toolbar>
<h2>Earthquake Mapper</h2>
</Toolbar>
</AppBar>
);
}
export default Navbar;
My Sidebar component
import React from 'react';
import Drawer from '#material-ui/core/Drawer';
function Sidebar() {
return (
<Drawer variant="permanent">
<div>
<ul>
<li>This</li>
<li>Will</li>
<li>Be</li>
<li>Where</li>
<li>Our</li>
<li>Data</li>
<li>Go</li>
</ul>
</div>
</Drawer>
);
}
export default Sidebar;
First, set the AppBar position as "fixed".
The way that Material-UI solves this is by adding an empty div with equal height to the Toolbar (which you put as the first child inside the AppBar component so your header min-height is equal to the Toolbar height) as the first child of the Drawer component.
This height is 64px by default, but you should get this value from theme.mixins.toolbar. You can see this in action in this tutorial.
So you'll end up doing something like this:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Drawer from '#material-ui/core/Drawer';
const useStyles = makeStyles(theme => ({
toolbar: theme.mixins.toolbar,
}));
function Sidebar() {
const classes = useStyles();
return (
<Drawer variant="permanent">
<div className={classes.toolbar} />
<div>
<ul>
<li>This</li>
<li>Will</li>
<li>Be</li>
<li>Where</li>
<li>Our</li>
<li>Data</li>
<li>Go</li>
</ul>
</div>
</Drawer>
);
}
export default Sidebar;
Check out themes for more information on how to use theme providers and custom
theme configuration.
An alternative is to place an empty <Toolbar /> in the Drawer to fill the space.
import React from 'react';
import Drawer from '#material-ui/core/Drawer';
import Toolbar from '#material-ui/core/Toolbar';
function Sidebar() {
return (
<Drawer variant="permanent">
<Toolbar />
<div>
<ul>
<li>This</li>
<li>Will</li>
<li>Be</li>
<li>Where</li>
<li>Our</li>
<li>Data</li>
<li>Go</li>
</ul>
</div>
</Drawer>
);
}
export default Sidebar;

Insert image into Material-UI AppBar

I've been looking for a way to insert a plain image file into the AppBar of Material-UI on the official docs but it seems like the only non-text things you can put in the AppBar are either text icons or SVG icons. Is there a way to display actual images in the AppBar?
There are several options to insert a background image for Material-UI AppBar.
Here is one that I prefer:
Import the image:
import headerBackground from "../../Assets/headerBackground.png";
Add the image to the stylesheet as follow:
header: {
backgroundImage: `url(${headerBackground})`,
},
Set the class component:
const classes = useStyles();
return (
<>
<AppBar className={classes.header}> ... </AppBar>
Here is a complete example:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import { AppBar, Toolbar, Typography } from "#material-ui/core";
import headerBackground from "../../Assets/headerBackground.png";
const useStyles = makeStyles((theme) => ({
header: {
backgroundImage: `url(${headerBackground})`,
},
}));
export default function Header(props) {
const classes = useStyles();
return (
<AppBar className={classes.header}>
<Toolbar>
<Typography variant="h6">Scroll to Hide App Bar</Typography>
</Toolbar>
</AppBar>
);
}
Material-UI has some components in which there are properties that can be assigned to the image. For example CardMedia - the properties of image. But you can also use the standard tag to insert the image.
<AppBar position="static" color="default" elevation={0} className={classes.appBar}>
<Toolbar className={classes.toolbar}>
<img src="/assets/logo.svg" />
<nav>
<Link variant="button" color="textPrimary" href="#" className={classes.link}>
About
</Link>
</nav>
</Toolbar>
</AppBar>
It works for me.

Resources