How to style and position Material UI Link component - reactjs

I'm trying to style and change position of a Link component, I'm trying to have the Link (Forget Password?) at the right end, but now it's centered as shown in the image below
Also I want to change the color of it, I tried color="black" but didn't work
I'm using grids trying to have the texts apart from each other.
The Code
{/* Password */}
<Grid container mt={4}>
<Grid item xs={6} justify={"flex-start"}>
<Typography
variant="h9"
gutterBottom
component="div"
style={{ fontWeight: "bold", textAlign: "left"}}
>
Password
</Typography>
</Grid>
<Grid item xs={6} justify={"flex-end"}>
<Typography
variant="body2"
gutterBottom
component={Link}
// align="right"
to="/register"
>
{/* <Link to="/register">Forget Password?</Link> */}
Forget Password?
</Typography>
</Grid>
</Grid>

If "black" isn't defined in your theme, that won't work. color="primary" should work, but if you can also define black as a color in your theme.
Alternatively, if you want only this link to be black, you can add the attribute sx={{ color: 'black' }} to <Link> and that should work.
If it's not necessary to do so, I wouldn't wrap the link in a typography; just apply all the styles directly to link, as link already uses a typography element under the hood.

Try this to right-align your password link:
<Grid item xs={6}>
<Box display="flex" justifyContent="flex-end">
<Typography
variant="body2"
gutterBottom
component={Link}
// align="right"
to="/register"
>
{/* <Link to="/register">Forget Password?</Link> */}
Forget Password?
</Typography>
</Box>
</Grid>

Related

How can I keep Link and IconButton on the same line?

I have a link with a long text and a "copy" icon after it. I don't want the icon to be aware rendered on a separate line alone.
So these should be ok:
But not this:
The basic code is:
<>
<Link>cat dog cow pig owl rabbit hare wolf fox</Link>
<IconButton><EditIcon/></IconButton>
</>
I can easily place the icon to the right with a flexbox, but not sure how I effectively insert a non-breaking space between a text and an icon.
I just ran into the same problem and I managed to solve it using MUI's Grid.
I had to do some string splitting in my case, so I included here as well. Hope this helps!
<Link onClick={() => { alert('test'); }}>
<Grid container direction="row" alignItems="center">
<Grid item>
<Typography variant="body1">
{linkText.split(' ').slice(0, -1).join(' ')}
</Typography>
</Grid>
<Grid item>
<Typography variant="body1" display="flex" alignItems="center">
{linkText.split(' ').slice(-1)}
<IconButton>
<EditIcon
onClick={(event) => {
event?.stopPropagation();
// do stuff
}}
/>
</IconButton>
</Typography>
</Grid>
</Grid>
</Link>

How to remove MUI 5 Card Action Area Default Hover State

This question has probably been answered but i cant seem to find a solution.
I want to remove the default hover state on the CardActionArea component from mui 5. When i hover over the action area, there is a light grey background that i want to remove. Any help is much appreciated.
<Grid container spacing={2}>
{todos.map((todo) => (
<Grid key={todo.db_id} item xs={12} md={4}>
<Card variant='outlined' sx={{ minWidth: 200 }}>
<CardActionArea onClick={() => handleRedirect(todo.db_id)}>
<CardContent>
<Typography variant='h4' color='text.secondary' gutterBottom>
{todo.title}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button
onClick={() => deleteHandler(todo.db_id)}
variant='contained'
size='small'
>
Delete
</Button>
</CardActions>
</Card>
</Grid>
))}
</Grid>
I'm using the styled-components engine for MUI 5, so my answer will be based on that, but I was able to remove the grey hover by accessing the .MuiCardActionArea-focusHighlight, as described on this page:
https://mui.com/material-ui/api/card-action-area/
I was able to remove it with the following code:
const StyledCardActionArea = styled(CardActionArea)(({theme}) => `
.MuiCardActionArea-focusHighlight {
background: transparent;
}
`);
Then just put that component in place of CardActionArea within your code.

How can I automatically import an icon which fetches from the server in NextJS?

I want to dynamically generate a page in the Next-JS app. Inside this page should be imported automatically Icons which fetches from the server Instead of writing it statically:
{
"id": 1,
"title": "Budget",
"value": "$24K",
"persent" :"12%",
"duration" :"Since Last Month",
"icon":"MoneyIcon",
"rise":"false"
},
in this timeMoneyIcon from Material-UI.
In this case, was used map method in order to render fetched data.
How can I put this fetched icon name as a tag same as <MoneyIcon/> in the component?
{posts.map((post) => (
<>
<Grid item lg={3} sm={6} xl={3} xs={12}>
<Card sx={{ height: "100%" }}>
<CardContent>
<Grid container spacing={3} sx={{ justifyContent: "space-between" }}>
<Grid item>
<Typography color="textSecondary" gutterBottom variant="overline">
{post.title}
</Typography>
<Typography color="textPrimary" variant="h4">
{post.value}
</Typography>
</Grid>
<Grid item>
<Avatar
sx={{
backgroundColor: "error.main",
height: 56,
width: 56,
}}
>
**<MoneyIcon />**
</Avatar>
</Grid>
</Grid>
<Box
sx={{
pt: 2,
display: "flex",
alignItems: "center",
}}
>
<ArrowDownwardIcon color="error" />
<Typography
color="error"
sx={{
mr: 1,
}}
variant="body2"
>
{post.persent}
</Typography>
<Typography color="textSecondary" variant="caption">
{post.duration}
</Typography>
</Box>
</CardContent>
</Card>
</Grid>
</>
))}
If I understand you correctly you are trying to pass the MUI Icon to the Component and render the icon. For that you can simply pass the Icon as a value of your object wrapped in a React Fragment.
import AccountBalanceIcon from '#mui/icons-material/AccountBalance';
const myObject = {
id: 1,
value: "24K",
icon: <><AccountBalanceIcon/></>
)};
export default function MyComponent(props) {
return(
<div>
<span>{myObject.value}</span>
{myObject.icon}
<div>
)
}
You can import them dynamically by name for example you can fetch the Icon name from server then in the page do this:
import * as MuiIcons from '#mui/icons-material'
function YourPage({IconName}){
const IconComponent = MuiIcons[IconName]
return <Grid container>
<IconComponent />
</Grid>
}
and if you want for example #mui/icons-material/Memory the Icon name is "Memory".
But I think this approach is not treeshakable you may bring the entire jungle , I am not sure about that though, you should check the bundle after compiling.

Box component inserting text to 'start' and 'end'

I am using material UI components and I'm trying to make a card component. I want my text will be in the same row inbox component("phase" and "2" have to be in the same row). However, I couldn't do it. Here is my code;
<Card className={classes.rootMultiple} variant='outlined'>
<CardContent>
<Box>
<Box justifyContent={'start'}>
<Typography
variant='h5'
component='h2'
className={classes.titleMultiple}
>
phase
</Typography>
</Box>
<Box display='flex' justifyContent={'end'}>
<Typography
variant='h7'
component='h2'
className={classes.descriptionMultiple}
>
2
</Typography>
</Box>
</Box>
</CardContent>
</Card>;
Try to specify the display and flexDirection attributes in the parent's Box.
Then use the flex attribute on the children's `Box:
<Card className={classes.rootMultiple} variant='outlined'>
<CardContent>
<Box sx={{
display: 'flex',
flexDirection: 'row',
}}>
<Box flex={1}>
<Typography
variant='h5'
component='h2'
className={classes.titleMultiple}
>
phase
</Typography>
</Box>
<Box flex={0}>
<Typography
variant='h7'
component='h2'
className={classes.descriptionMultiple}
>
2
</Typography>
</Box>
</Box>
</CardContent>
</Card>
You can just write a Grid (that uses flex) with justify-content: space-between.
<Card className={classes.rootMultiple} variant='outlined'>
<CardContent>
<Grid container justifyContent="space-between">
<Grid item>
<Typography
variant='h5'
component='h2'
className={classes.titleMultiple}
>
phase
</Typography>
</Grid>
<Grid item>
<Typography
variant='h7'
component='h2'
className={classes.descriptionMultiple}
>
2
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
No need to make other components; less is better. Of course you can use Box with flex style, but Grid does it for you.
Note that h7 isn't a valid value for variant inside Typography.
EDIT: I wrote space-between only because your example prints the texts in the margins, but of corse you can use what you want: they will be always in same row.

How do I close a card when onclick on a button in react?

I have a material-ui card in which it contains image, input field, check-box and a submit button. In which card is displaying onclick on some other option which is not mentioned in the below code. I want to close a card when I click on submit. How can I achieve this?
<Card
className="details-card"
style={{ paddingTop: "0px" }}
color="primary"
>
<CardHeader
style={{
paddingBottom: 0,
paddingTop: 0
}}
title="Image"
/>
<img src="https://unsplash.it/200/?random" />
<CardContent className="details-card-body">
<TextField label="Name" fullWidth />
<Grid container>
<Grid item xs={4}>
<Typography>
New User
<Checkbox
checked={this.state.addNew}
name="addNew"
onChange={this.handleCheckBox("addNew")}
value="new user"
inputProps={{ "aria-label": "Checkbox B" }}
/>
</Typography>
</Grid>
</Grid>
<Button variant="contained" color="primary">
Click to Tag
</Button>
</CardContent>
</Card>
Here below is my code on CodeSandbox
https://codesandbox.io/embed/lppzx48r0m
There are multiple ways to achieve what you want to do
you'll need a flag to conditionally hide or show the card.
For example lets take flag variable in state, and change state variable flag based on submit button and on the basis of this.state.flag you can do
{this.state.flag ?
(<Card
className="details-card"
style={{ paddingTop: "0px" }}
color="primary"
>
//Card content
</Card>)
:
null
}
You can also provide conditional css based on this.state.flag
<Card
className="details-card"
style={{ paddingTop: "0px", display: this.state.flag ? block : 'none'}}
color="primary"
>
//Card content
</Card>
P.S.: The second approach is not recommended because we are rendering element even if it is not needed.

Resources