MUI makeStyles isn't working on the Card component - reactjs

I have this component called Product which is based off this example. Here is my component:
Product.tsx:
import useStyles from './useStyles'
const Product: React.FC = () => {
const classes = useStyles();
return (
<Card className={classes.secondaryBorder}>
<CardActionArea>
<CardContent>
<Typography gutterBottom variant="h5">
This is my title
</Typography>
<Typography variant="body2" color="text.secondary">
This is my body
</Typography>
</CardContent>
</CardActionArea>
</Card>
);
};
useStyles.ts:
import { makeStyles } from '#mui/styles';
const useStyles = makeStyles({
secondaryBorder: {
border: '2px solid blue',
},
flex: {
display: 'flex',
},
});
The problem is that the Card component does not have the secondaryBorder i.e. it does not have a blue border around it. So what is the problem?
Thank you!

Related

How to make a kind of synoptic table

Excuse me for having to ask, but the following topic is costing me a lot.
I want to make a table with connections, but I can't find the formula to do it, and I couldn't find any example, I tried to find an example and copy its code but it doesn't convince me either. This is what I want to do:
enter image description here
The idea is that, this is how I currently have it:
`
import React from "react";
import { useState, useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import MundialButtons from "../../componentes/mundial-buttons";
const useStyles = makeStyles((theme) => ({
root: {
minWidth: 100,
maxWidth: 250,
flexGrow: 1
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)"
},
title: {
fontSize: 14
},
pos: {
marginBottom: 12
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.primary
},
logo: {
float: "left"
}
}));
export default function Two() {
const url =
"https://adad1EUmIOwosuGTI7L2DD6S02RjOG7vbxU3FjVVD1u-iYiw/a!A1:Z1000";
const [todos, setTodos] = useState();
const fetchApi = async () => {
const response = await fetch(url);
const responseJSON = await response.json();
setTodos(responseJSON);
};
useEffect(() => {
fetchApi();
}, []);
const classes = useStyles();
const styleRed2 = [
{ marginTop: "90px" },
{ marginTop: "180px" },
{ marginTop: "270px" }
];
return (
<div id="all">
<MundialButtons />
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>
<Typography>asd</Typography>
</Paper>
</Grid>
</Grid>
</div>
<div id="all">
{!todos
? "Cargando..."
: todos.map((todo, index) => {
return (
<Grid item xs={6}>
<div className={classes.root} id="octavos">
{todo.Local === undefined ||
todo.Local === "" ||
todo.Visitante === undefined ||
todo.Visitante === "" ? (
<div></div>
) : (
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Octavos:
</Typography>
<Typography variant="h5" component="h2">
test
</Typography>
<Typography variant="h5" component="h2">
test
</Typography>
{/*<Typography
className={classes.pos}
color="textSecondary"
>
hora
</Typography>*/}
</CardContent>
</Card>
)}
<p></p>
</div>
</Grid>
);
})}
</div>
</div>
);
}
`
A box with connections between them
It's probably best to lean on open-source libraries for this, no need to reinvent the wheel. As it happens, what you require kind of already exists: https://www.npmjs.com/package/#g-loot/react-tournament-brackets. Demo.

Create card on button click

so I've made a calendar with some text fields underneath that you can fill in.
How can I make it so that when you fill in everything here and click on the button, that it automatically creates a card with the stuff filled in above?
Firebase works without problems and everything you fill in also arrives in the database
It should look like this if you click on the button
And here my code:
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
import { Checkbox, Container, Slide } from "#material-ui/core";
import Icon from "#material-ui/core/Icon";
import { StyleSheet } from "react-native";
import firebase from "firebase/app";
import "firebase/firestore";
import { db } from "../../firebase";
import { ScrollView } from "react-native-gesture-handler";
export default function DateAndTimePickers() {
const classes = useStyles();
const [ort, setOrt] = useState("");
const [notiz, setNotiz] = useState("");
const [hinweis, setHinweis] = useState("");
const [eintragen, setEintragen] = useState([]);
const [dateandtime, setDateandtime] = useState([]);
function handelDateandTime(e) {
setDateandtime(e.target.value);
}
function handelOrt(e) {
setOrt(e.target.value);
}
function handelNotiz(e) {
setNotiz(e.target.value);
}
function handelHinweis(e) {
setHinweis(e.target.value);
}
function KalenderEintrag() {
db.collection("Eintrag")
.doc()
.set({
ort,
notiz,
hinweis,
dateandtime,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setEintragen([...eintragen, { ort, notiz, hinweis, dateandtime }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
return (
<ScrollView style={styles.root}>
<Container>
<TextField
id="datetime-local"
label="Neues Ereigniss"
type="datetime-local"
defaultValue="2021-09-16T10:30"
className={classes.root}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelDateandTime(value);
}}
/>
</Container>
{/* ORT */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Ort"
defaultValue="Text"
onChange={(value) => {
handelOrt(value);
}}
/>
</Container>
{/* Hinweis */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Hinweis"
defaultValue="Text"
onChange={(value) => {
handelHinweis(value);
}}
/>
</Container>
{/* Notizen */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Notizen"
defaultValue="Text"
onChange={(value) => {
handelNotiz(value);
}}
/>
</Container>
<Container>
<Button onClick={() => KalenderEintrag()} className={classes.btn} variant="outlined">Absenden</Button>
</Container>
{/* Kalender einträge */}
<Card className={classes.card}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
AUSFLUG
</Typography>
<Typography variant="h5" component="h2">
Wilheminenberg
</Typography>
<Typography className={classes.pos} color="textSecondary">
Jause wird mitgegeben
</Typography>
<Typography variant="body2" component="p">
Am 13.9.21 von 09:00 - 13:00
<br />
{"Abholung erfolgt im KG"}
</Typography>
</CardContent>
<CardActions>
<Button size="small" variant="outlined">
Zur Kenntniss genommen
</Button>
</CardActions>
</Card>
</ScrollView>
);
}
//material UI style
const useStyles = makeStyles({
root: {
marginTop: 30,
marginLeft: 16,
},
card: {
marginTop: 30,
marginLeft: 15,
marginRight: 15,
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
table: {
marginTop: 30,
},
ortContainer: {
marginTop: 30,
marginLeft: 15,
marginRight: 15,
},
btn:{
marginTop: 20,
marginLeft: 15,
}
});
//React native style
const styles = StyleSheet.create({
root: {
backgroundColor: "white",
},
});
Just like that https://codesandbox.io/s/peaceful-hugle-ufkso
{/* Kalender einträge */}
{eintragen.map((item) => {
return (
<Card className={classes.card}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
{item.ort}
</Typography>
<Typography variant="h5" component="h2">
{item.notiz}
</Typography>
<Typography className={classes.pos} color="textSecondary">
{item.hinweis}
</Typography>
<Typography variant="body2" component="p">
{item.dateandtime}
<br />
{"Abholung erfolgt im KG"}
</Typography>
</CardContent>
<CardActions>
<Button size="small" variant="outlined">
Zur Kenntniss genommen
</Button>
</CardActions>
</Card>
)
})}
You can reference variables within your JSX code with curly brackets (this has already been done to apply styles for example at {classes.ortContainer}). Replacing text by variables works the same way, so for example replace "Wilheminenberg" by {ort} to have your website display the respective value.
import the card on react-bootstrab or material ui ,the use this method
**const [open ,setOpen] = useState(false);
enter code here
import React,{useState} from 'react';
import {Card} from '#material-ui/core'
function CreateCardButtonOnClick(){
const [open, setOpen] =useState(false);
const OpenCard=()=>{
setOpen(true);
};
const closeCard =()=>{
setOpen(false);
};
return(
<div>
<span>click to open Card viwe</span>
<button onClick={openCard}>openCard</button>
<Card>
<h1 onClick={openCard}>close</h1>
</Card>
</div>
)
export defult CreateCardButtonOnClick;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/0.14.6/react-dom.min.js"></script>
`/* import React,{useState} from 'react';
import {Card} from '#material-ui/core'
function CreateCardButtonOnClick(){
const [open, setOpen] =useState(false);
const OpenCard=()=>{
setOpen(true);
};
const closeCard =()=>{
setOpen(false);
};
return(
<div>
<span>click to open Card viwe</span>
<button onClick={openCard}>openCard</button>
<Card>
<h1 onClick={openCard}>close</h1>
</Card>
</div>
)
export defult CreateCardButtonOnClick;*/`

What is wrong with my iconButton in React JS?

The console announce mistake at my IconButton open tag as unexpected token. i have installed material ui...i don't know what is the problem? can anyone help me? Thank you so much!
This is my product.js:
import React from 'react'
import {
Card,
CardMedia,
CardContent,
CardActions,
Typography,
IconButton
} from '#material-ui/core'
import {
AddShoppingCart
} from '#material-ui/icons'
import useStyles from './styles'
const Product = ({
product
}) => {
const classes = useStyles()
return (
<Card className={classes.root}>
<CardMedia className={classes.media} image='' title={product.name} />
<CardContent>
<div className={classes.cardContent}>
<Typography gutterBottom variant="h5" >
{product.name}
</Typography>
<Typography variant="h5" >
{product.price}
</Typography>
</div>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart">
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
)
}
export default Product
This is my styles.js:
import {
makeStyles
} from '#material-ui/core/styles'
export default makeStyles(() => ({
{
root: {
maxWidth: '100%'
},
media: {
height: 0,
paddingTop: '56.25%'
},
cardActions: {
display: 'flex',
justifyContent: 'space-between'
},
}
}))
Btw i don't get where useStyles in my product.js come from when in my styles.js it's makeStyles not useStyles (i follow a tutorial on yt and he does so)
This: import useStyles from './styles' is named that because you/him wanted to, because you're exporting export default makeStyles.
export default means that you can import it with any name you want, its not a named export.
The problem maybe because here:
// You're returning an object of an object, instead of the inner { root: ... }.
({
{
root: {
maxWidth: '100%'
},
media: {
height: 0,
paddingTop: '56.25%'
},
cardActions: {
display: 'flex',
justifyContent: 'space-between'
},
}
}))
so maybe classes is not defined correctly, it would be needed the error stack to make sure where the error is, or at least a simple jsfiddle with the error would do.
There is nothing wrong with your IconButton component.
Some hints:
You can import your styles as classes right away, otherwise I doubt the class definitions will work at all.
Ensure you have installed #material-ui/icons
I took your code and did above changes:
import React from "react";
import {
Card,
CardMedia,
CardContent,
CardActions,
Typography,
IconButton
} from "#material-ui/core";
import { AddShoppingCart } from "#material-ui/icons";
import classes from "./styles";
const Product = ({ product }) => {
return (
<Card className={classes.root}>
<CardMedia className={classes.media} image="/" title={product.name} />
<CardContent>
<div className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
{product.name}
</Typography>
<Typography gutterBottom variant="h5" component="h2">
{product.price}
</Typography>
</div>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart">
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
);
};
export default Product;
See: https://codesandbox.io/s/ecstatic-sea-m9k33?file=/src/Product.js
we have used an arrow function to inline the event handler for out input field
So use
function Product({product}) {...}
instead of
const Product = ({ product }) => {}

How can I reuse code wrapping Material-UI's Grid while varying the number of columns?

I would like the second grid block under the title "Other Projects of Note" to be mapped through as a 3 column grid. How can I do this without creating a new component? Material-UI controls it's columns with the grid item xs={12} sm={6} and on the 3 column grid I'd need it to read as grid item xs={12} sm={6} lg={4}.
It seems like I'd be copying and pasting the <Card /> component and renaming it to achieve this. I'd like to avoid that. Demo below:
codesandbox
Here's the code for my current Card component:
import React from 'react';
import Grid from '#material-ui/core/Grid';
import Card from '#material-ui/core/Card';
import CardActionArea from '#material-ui/core/CardActionArea';
import CardActions from '#material-ui/core/CardActions';
import { makeStyles } from '#material-ui/core/styles';
import { loadCSS } from 'fg-loadcss';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import Box from '#material-ui/core/Box';
import Icon from '#material-ui/core/Icon';
import GitHubIcon from '#material-ui/icons/GitHub';
import Tooltip from '#material-ui/core/Tooltip';
import Zoom from '#material-ui/core/Zoom';
import Link from '#material-ui/core/Link';
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: '100%',
flexGrow: 1,
},
cardGrid: {
paddingTop: theme.spacing(2),
},
media: {
height: 340,
},
button: {
margin: theme.spacing(1),
},
arrow: {
color: theme.palette.common.black,
},
tooltip: {
backgroundColor: theme.palette.common.black,
},
icons: {
'& > .fab': {
marginRight: theme.spacing(4),
},
margin: '1rem 0',
},
}));
function TwoCard(props) {
const classes = useStyles();
React.useEffect(() => {
const node = loadCSS(
'https://use.fontawesome.com/releases/v5.12.0/css/all.css',
document.querySelector('#font-awesome-css')
);
return () => {
node.parentNode.removeChild(node);
};
}, []);
return (
<>
<Grid item xs={12} sm={6}>
<Card>
<CardActionArea>
<CardMedia
className={classes.media}
image={props.card.image}
title='Contemplative Reptile'
/>
<CardContent className={classes.content}>
<Typography gutterBottom variant='h5' component='h2'>
{props.card.project}
</Typography>
<Typography variant='subtitle1' gutterBottom>
{props.card.framework}
</Typography>
<Typography gutterBottom variant='body2' component='p'>
{props.card.description}
</Typography>
<Box className={classes.icons}>
<Typography gutterBottom variant='subtitle2'>
TOOLS USED
</Typography>
<Tooltip
TransitionComponent={Zoom}
arrow
title='REACT'
aria-label='react'
>
<Icon className='fab fa-react fa-3x' color='primary' />
</Tooltip>
<Tooltip
TransitionComponent={Zoom}
arrow
title='HTML5'
aria-label='add'
>
<Icon className='fab fa-html5 fa-3x' color='primary' />
</Tooltip>
<Tooltip
TransitionComponent={Zoom}
arrow
title='CSS3'
aria-label='add'
>
<Icon className='fab fa-css3 fa-3x' color='primary' />
</Tooltip>
</Box>
</CardContent>
</CardActionArea>
<CardActions>
<Button variant='outlined' size='small' color='primary'>
<Link
href={props.card.projectUrl}
target='_blank'
rel='noopener noreferrer'
className={classes.links}
underline='none'
color='inherit'
>
View Project
</Link>
</Button>
<Button
variant='outlined'
size='small'
color='primary'
className={classes.button}
endIcon={<GitHubIcon />}
>
<Link
href={props.card.githubUrl}
target='_blank'
rel='noopener noreferrer'
underline='none'
color='inherit'
>
Code
</Link>
</Button>
</CardActions>
</Card>
</Grid>
</>
);
}
export default TwoCard;
and here's the code that uses that Card component:
import React from "react";
import Grid from "#material-ui/core/Grid";
import Card from "./Card.js";
import { Typography } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
headings: {
padding: "20px 0"
}
}));
function Projects(props) {
const classes = useStyles();
let cards = props.data.map((card, i) => {
return <Card card={card} key={i} />;
});
return (
<>
<Typography variant="h4" gutterBottom>
Featured Projects
</Typography>
<Grid container spacing={2}>
{cards}
</Grid>
<Typography variant="h4" className={classes.headings}>
Other Projects of note
</Typography>
<Grid container spacing={2}>
{cards}
</Grid>
</>
);
}
export default Projects;
You can pass a prop to your Card component to control whether it is two-column or three-column. For instance, you can pass a maxColumns prop and use it in the following manner:
<Grid item xs={12} sm={6} lg={maxColumns > 2 ? 4 : undefined}>
Then your Projects component can pass the prop (in my example, I'm defaulting maxColumns to 2, so it doesn't need to be specified in that case):
import React from "react";
import Grid from "#material-ui/core/Grid";
import Card from "./Card.js";
import { Typography } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
headings: {
padding: "20px 0"
}
}));
function Projects(props) {
const classes = useStyles();
let twoColumnCards = props.data.map((card, i) => {
return <Card card={card} key={i} />;
});
let threeColumnCards = props.data.map((card, i) => {
return <Card maxColumns={3} card={card} key={i} />;
});
return (
<>
<Typography variant="h4" gutterBottom>
Featured Projects
</Typography>
<Grid container spacing={2}>
{twoColumnCards}
</Grid>
<Typography variant="h4" className={classes.headings}>
Other Projects of note
</Typography>
<Grid container spacing={2}>
{threeColumnCards}
</Grid>
</>
);
}
export default Projects;

Vertical align using MUI Paper

I want to vertically align some text in a MUI Paper component.
The code is here.
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),
height: 200,
verticalAlign: 'middle'
},
}));
function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
This is a sheet of paper.
</Typography>
<Typography component="p">
Paper can be used to build surface or other elements for your application.
</Typography>
</Paper>
</div>
);
}
export default PaperSheet;
vertical-align CSS property only works with display: block element.
An option for you could be to declare your root class using flexbox:
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
height: 200,
display: "flex",
flexDirection: "column",
justifyContent: "center"
},
}));
You can use Stack in MUI v5. Set the direction to column and justifyContent to center to center align the content inside the Card:
<Paper component={Stack} direction="column" justifyContent="center">
<div>
This content is vertically aligned
</div>
</Paper>
Live Demo

Resources