Goal: Hide navMenu when breakpoint is tablet and under, so I can replace with a hamburger menu
In terminal in VS code, it says compiled successfully, but in the browser I see:
TypeError: Cannot read properties of undefined (reading 'down')
I tried instructions here: StackOverflow Question, with no luck.
Can someone point me in the right direction?
import AppBar from "#mui/material/AppBar";
import Box from "#mui/material/Box";
import Toolbar from "#mui/material/Toolbar";
import Typography from "#mui/material/Typography";
import Button from "#mui/material/Button";
import { makeStyles } from "#mui/styles";
const useStyles = makeStyles((theme) => ({
navMenu: {
[theme.breakpoints.down('md')]: {
display: "none",
},
},
}));
const Navbar = () => {
const classes = useStyles();
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static" style={{ backgroundColor: "#061B2E" }}>
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
Name
</Typography>
<Box className={classes.navMenu}>
<Button color="inherit">Item 1</Button>
<Button color="inherit">Item 2</Button>
<Button color="inherit">Item 3</Button>
<Button color="inherit">Item 4</Button>
</Box>
</Toolbar>
</AppBar>
</Box>
);
};
export default Navbar;
Great question, which version of MUI are you using? They're kind of shifting away from makeSyles in favor of styled components, but this method is still supported (we still use it exclusively on my team). You may need to change your import statement to import { makeStyles } from '#material-ui/core';
Related
I am making a new react app which have multiple music cards on same page. I want to change the state of previous card before updating the state of new card. In short I want to pause previous audio before playing new one.
import React, { useState , useEffect , useRef} from "react";
import Card from '#mui/material/Card';
import CardContent from '#mui/material/CardContent';
import CardMedia from '#mui/material/CardMedia';
import Typography from '#mui/material/Typography';
import { CardActionArea } from '#mui/material';
import PlayArrowIcon from '#mui/icons-material/PlayArrow';
import IconButton from '#mui/material/IconButton';
import PauseICon from "#mui/icons-material/Pause";
import { logDOM } from "#testing-library/react";
export default function ActionAreaCard(props) {
const audioRef = useRef(new Audio("http://myinstants.org/games/22ecaa5e-f90f-4e81-96b1-b240751439fa.mp3"));
const [clicked, setClicked] = useState(false);
useEffect(() => {
audioRef.current.addEventListener('ended', () => setClicked(false));
if (clicked) {
audioRef.current.play();
} else {
audioRef.current.pause();
}
},[clicked]);
return (
<Card sx={{ maxWidth: 256 }} >
<CardMedia
component="img"
height="140"
image="https://picsum.photos/400/200"
alt="green iguana"
/>
<CardContent style={{ display: 'flex', flexDirection: 'column' }}>
<Typography gutterBottom variant="h5" component="div" style={{ textAlign: 'center', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
lorem Spem kjb j kl lk n lkn lk nlk n kln lkn kln kln kl nlk n vdr rtgvrt rtwbtr rtbvrt vbwrt vwretvw
</Typography>
{/* <PlayArrowIcon sx={{ height: 38, width: 38}}/> */}
<IconButton onClick={() => setClicked(!clicked)}>
{
clicked ? <PauseICon sx={{ height: 38, width: 38 }} /> : <PlayArrowIcon sx={{ height: 38, width: 38 }} />
}
</IconButton>
</CardContent>
</Card>
);
}
The above one is my playing card component.
The above GIF is the working app. In which when I play the second Audio it starts it before stopping the old when. MY background is from android development in which we have only one object of media player and we can manage this using that object. But here i found no solution may be we can do it by accessing the other component state in an other component or may be using a hook etc.
Make a common state in parent storing active playing:
const [activePlaying,setActivePlaying]=useState(null);
Make a handler for it:
const activePlayerhandler=useCallback((id)=>{
setActivePlaying(id);
},[id]);
Pass this handler as a prop:
...
{players.map((player,index)=>(
< ActionAreaCard onPlay={()=>activePlayerhandler(index)} playing={activePlaying===index}/>
))
...
now you just need to call this prop on play button click.
I have been trying to use material ui backdrop element in my code. I am referring to this example: https://mui.com/components/backdrop/#example
As soon as I introduce this code into my component, it fails with error message as below.
Unhandled Runtime Error Error: Invalid hook call. Hooks can only be
called inside of the body of a function component. This could happen
for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug
and fix this problem.
My code is as below.
import React, { useState } from 'react'
import { makeStyles } from '#material-ui/core/styles'
import { Box,Typography } from '#material-ui/core'
import CategoryCard from '../shop-categories/category-card'
import { useSelector } from 'react-redux';
//import NavigateBeforeIcon from '#material-ui/icons/NavigateBefore';
//import ProductsInCategory from '../../../pages/shops/product-in-category';
import {useRouter} from 'next/router'
import Backdrop from '#mui/material/Backdrop'
import CircularProgress from '#mui/material/CircularProgress';
import { withStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
heading : {
fontFamily: 'Roboto',
fontSize: 14,
fontStyle: 'normal',
fontWeight: 700,
lineHeight: 1,
color: props => props.pColor
}
})
export default function CategoryGrid(props) {
const { categories, shopId, title} = props;
const shopColors = useSelector(state => state.main.currentShop)
const classes = useStyles(shopColors);
const router = useRouter()
const [open, setOpen] = React.useState(false);
const handleClose = () => {
setOpen(false);
};
const gotoSubCategories = (shopId, id,cat_Name) => {
setOpen(true)
router.push(`/shops/shop-sub-categories?shop=${shopId}&category=${id}&categoryName=${cat_Name}`)
}
return (
<>
<div>
<Backdrop sx={{color: '#fff', zIndex: (theme) => theme.zIndex.drawer +1}}
open={open}
onClick={handleClose}
>
<CircularProgress color='inherit' />
</Backdrop>
</div>
<Typography variant="body2" style={{ fontWeight: 'bold' }}
className={classes.heading}>
{title}
</Typography>
<Box display="flex" mb={2} mx={1} flexDirection="column">
<Box display="flex" fontWeight='fontWeightBold' width={1/2} mb={1}>
</Box>
<Box display="flex" flexWrap="wrap">
{
categories.map((category, index) => {
return <CategoryCard key={index}
name={category.name}
onClick={() => gotoSubCategories(shopId, category.id,category.name)}
imageURL={category.url}
shopId={shopId} callParent={props.callParent}
/>
})
}
</Box>
</Box>
</>
)
}
If I remove out this portion, then it works fine.
<div>
<Backdrop sx={{color: '#fff', zIndex: (theme) => theme.zIndex.drawer +1}}
open={open}
onClick={handleClose}
>
<CircularProgress color='inherit' />
</Backdrop>
</div>
How to fix this?
why my button is not redirecting to the respective .js file? Basically i am usiing Button with href tage where href="signup.js" and signup.js file is present in my project...... Can we use href tag to link a ".js" file properly and redirect properly... Button has been imported from react-bootstrap so what changes should be madeso user click on Button and go to signup.js file?
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import { Button } from 'react-bootstrap';
import Typography from '../components/Typography';
import ProductHeroLayout from './ProductHeroLayout';
const backgroundImage =
'https://thumbs.dreamstime.com/z/female-boss-online-conference-meeting-woman-crossed-hands-office-desk-front-laptop-student-teaches-exam-139215819.jpg';
const styles = (theme) => ({
background: {
backgroundImage: `url(${backgroundImage})`,
backgroundColor: '#7fc7d9', // Average color of the background image.
backgroundPosition: 'center',
},
button: {
minWidth: 200,
},
h5: {
marginBottom: theme.spacing(4),
marginTop: theme.spacing(4),
[theme.breakpoints.up('sm')]: {
marginTop: theme.spacing(10),
},
},
more: {
marginTop: theme.spacing(2),
},
});
function ProductHero(props) {
const { classes } = props;
return (
<ProductHeroLayout backgroundClassName={classes.background}>
{/* Increase the network loading priority of the background image. */}
<img style={{ display: 'none' }} src={backgroundImage} alt="increase priority" />
<Typography color="inherit" align="center" variant="h2" marked="center">
Upgrade your knowledge
</Typography>
<Typography color="inherit" align="center" variant="h5" className={classes.h5}>
Test Your Skills.
</Typography>
<Button
color="secondary"
variant="contained"
size="large"
href="SignUp.js"
>
User Registeration
</Button>
<Typography variant="body2" color="inherit" className={classes.more}>
Be Digital
</Typography>
</ProductHeroLayout>
);
}
ProductHero.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ProductHero);
To programmatically navigate between React components use ReactRouter
I was able to pass Material-UI's IconButton inside Material-UI's Tooltip title.
All the views are working properly, except I cannot press the button.
I want to add a Close button to make the tooltip close on clicking the close button, but I cannot do that. Is there a way to do this? If yes, please provide a solution to this.
MUI's Tooltip has pointer-events set to none by default, so you need to enable this. Add a class to your tooltip and then add this to the css:
pointer-events: auto;
I solved it by using Popper from Material-UI.
In case someone looking for this, here are some useful snippet for it.
import * as React from 'react';
import {Tooltip, Typography} from '#mui/material'
import CloseIcon from '#mui/icons-material/Close'
export const TooltipWithIcon = (title, message) => {
const [open, setOpen] = useState(false)
const handleClose = e => {
if (open) {
setOpen(false)
}
return null
}
return(
<Tooltip
open={open}
title={
<>
<CloseIcon sx={{ float: 'right' }} onClick={e => handleClose(e)}></CloseIcon>
<Typography variant="h6" sx={{ fontWeight: 700 }}>
{title}
</Typography>
<Typography variant="body1" sx={{ fontSize: 14 }}>
{message}
</Typography>
</>
}
>
</Tooltip>
)
}
I am trying to create a list of articles with switching to a list of other entities in React + material UI. But I faced some problems, namely, I can't center Card, which displays an article in the way, that will correspond to centered Tabs. So, I get something like this:
Can anyone help me to make it to look symmetric?
I want the Card to be centered in the same way, the Tabs are.
TabsMenu.js, which itself is displayed:
import React from "react";
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 Box from "#material-ui/core/Box";
import Typography from "#material-ui/core/Typography";
import * as PropTypes from "prop-types";
import ArticlesList from "./ArticlesList";
function TabPanel(props) {
const {children, value, index, ...other} = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tab-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box p={3}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired,
};
const useStyles = makeStyles({
root: {
flexGrow: 1,
},
tabpanel: {
marginLeft: "auto"
}
});
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
export default function CenteredTabs(props) {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
}
return (
<Paper className={classes.root}>
<article>
<Tabs
value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
centered
>
<Tab label="Articles" {...a11yProps(0)}/>
<Tab label="News" {...a11yProps(1)}/>
<Tab label="Authors" {...a11yProps(2)}/>
</Tabs>
<TabPanel value={value} index={0} className={classes.tabpanel}>
<ArticlesList articles={[{
imageSrc: "https://frontendmasters.com/static-assets/learn/og-learning-path-react.jpg",
authorImageSrc: "https://lh5.googleusercontent.com/--OlyHl449xI/AAAAAAAAAAI/AAAAAAAAAAA/ACevoQNk7ZZElQ_vKIQT_6d4HZw_wN3Qxg/mo/photo.jpg?sz=64",
authorName: "Denis Ivanenko",
dateTime: "2017-02-14",
imageAlt: "Article Image",
title: "Test title",
subtitle: "Test subtitle"
}]}/>
</TabPanel>
<TabPanel value={value} index={1} className={classes.tabpanel}>
Item Two
</TabPanel>
<TabPanel value={value} index={2} className={classes.tabpanel}>
Item Three
</TabPanel>
</article>
</Paper>
);
}
ArticlesList.js, which is used in TabsMenu.js
import React from 'react';
import {makeStyles} from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import ArticleCard from "./ArticleCard";
import Box from "#material-ui/core/Box";
import Grid from '#material-ui/core/Grid';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
}));
export default function ArticlesList(props) {
const classes = useStyles();
return (
<React.Fragment>
<div className={classes.root}>
<Grid container
spacing={0}
direction="column"
alignItems="center"
justify="center"
style={{minHeight: '100vh'}}>
<Grid item xs={12}>
<Box width={"150%"}>
<List component="nav" aria-label="secondary mailbox folders">
<ArticleCard title={"Introducing \"Dead Simple Python\"\n"}
text={"Ever spent three hours trying to find that bit of knowledge that everyone seemed to have but you?\n" +
"\n" +
"As a self-trained Python developer, I've sometimes found myself stuck in that knowledge crater, between tutorials far simpler than real life, and articles more advanced than I could comprehend. Even the documentation felt like a firehose of information, making it nearly impossible to find the one basic thing I needed to know.\n" +
"\n" +
"In this series, I'll be exploring a few of these topics, in a way that hopefully makes them dead simple!\n" +
"\n" +
"Intended Audience\n" +
"While programmers at all experience levels may find this series useful, I'm specifically targeting Python novices. I am assuming, however, that you have a very basic understanding of programming. The coding topics especially will be more focused on the Python way of doing things, not on the underlying generic concept.\n" +
"\n" +
"With that said, if you're an intermediate-level Python developer, you may still find it helpful to follow along with the series. Although I've been working with Python for nearly eight years, some of these topics didn't really \"click\" for me until recent years. These are the explanations I wish I'd had!\n" +
"\n" +
"What You Won't Find Here\n" +
"All of the topics I'm discussing here go much, much deeper. However, I don't want to muddy the waters, so I'll be omitting a considerable amount of detail. Once you're comfortable with a topic, and have done it a few times yourself, I recommend going back and reading through the official Python documentation on the topic.\n" +
"\n" +
"A Note on Python Versions\n" +
"The official end-of-life for Python 2 is rapidly approaching, so you should learn and begin using Python 3 as soon as possible! This entire series is geared towards Python 3, with a bias towards 3.6 and 3.7, except as otherwise noted.\n" +
"\n" +
"Edits\n" +
"The articles in this series are frequently being reviewed by my fellow Python experts, and by the Dev community at large. I will expand and revise accordingly. Always check the edit timestamp at the top of the article.\n" +
"\n" +
"Roadmap\n" +
"The current series plan is below. Please note, I may rearrange, add, or remove planned sections."}
imageSrc={"https://insights.dice.com/wp-content/uploads/2017/09/shutterstock_315465929.jpg"}
authorImageSrc={"https://lh5.googleusercontent.com/--OlyHl449xI/AAAAAAAAAAI/AAAAAAAAAAA/ACevoQNk7ZZElQ_vKIQT_6d4HZw_wN3Qxg/mo/photo.jpg?sz=64"}
authorName={"Denis Ivanenko"}/>
</List>
</Box>
</Grid>
</Grid>
</div>
</React.Fragment>
);
}
ArticleCard.js
import React from "react";
import {red} from '#material-ui/core/colors';
import makeStyles from "#material-ui/core/styles/makeStyles";
import Card from "#material-ui/core/Card";
import CardHeader from "#material-ui/core/CardHeader";
import Avatar from "#material-ui/core/Avatar";
import IconButton from "#material-ui/core/IconButton";
import CardMedia from "#material-ui/core/CardMedia";
import CardContent from "#material-ui/core/CardContent";
import Typography from "#material-ui/core/Typography";
import CardActions from "#material-ui/core/CardActions";
import clsx from "clsx";
import FavoriteIcon from '#material-ui/icons/Favorite';
import ShareIcon from '#material-ui/icons/Share';
import Button from "#material-ui/core/Button";
const useStyles = makeStyles((theme) => ({
root: {
width:"155%",
gridColumn: "2/span 7"
},
media: {
height: 0,
paddingTop: '56.25%',
},
expand: {
transform: 'rotate(0deg)',
marginLeft: 'auto',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
},
avatar: {
backgroundColor: red[500],
},
}));
export default function ArticleCard(props) {
const classes = useStyles();
const [expanded] = React.useState(false);
const title = props.title;
const date = props.dateTime;
const imageSrc = props.imageSrc;
const imageAlt = props.imageAlt;
const previewText = props.text.substring(0,158)+"...";
return (
<Card className={classes.root}>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
<img src={props.authorImageSrc} alt={props.authorName}/>
</Avatar>
}
title={title}
subheader={date}
/>
<CardMedia
className={classes.media}
image={imageSrc}
title={imageAlt}
/>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{previewText}
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon/>
</IconButton>
<IconButton aria-label="share">
<ShareIcon/>
</IconButton>
<Button
className={clsx(classes.expand, {
[classes.expandOpen]: expanded,
})}
aria-expanded={expanded}
aria-label="show more"
href={"/article"}
>
Read More
</Button>
</CardActions>
</Card>
);
}
This has got nothing to do with material-ui,
you've applied marginLeft: auto, which will not apply marginRight: auto, so it would not be center aligned
you should add marginRight: auto, as well to center it.
const useStyles = makeStyles({
root: {
flexGrow: 1,
},
tabpanel: {
marginLeft: "auto",
marginRight: "auto"
}
});