MUI alternative to CardHeader - reactjs

Good evening,
I am looking for a better way to display what you see in the picture. With the CardHeader this is all not centered and I can't use any useState methods.
how it should look
<Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<CardHeader avatar={<Avatar sx={{ bgcolor: red[500] }} aria-label="logo">N</Avatar>} action={<IconButton aria-label="enable"><FavoriteBorderIcon /></IconButton>} title="Netflix" subheader="netflix.com" />
</Card>
The way it looks here is how I want it to look in the end, but I can't useState methods here. Also the content (e.g. the icon) is not centered vertically.

I dont know why there is a problem with useState hook. Feel free to add it to the and depending on the state switch between normal and red icon.
https://codesandbox.io/s/distracted-oskar-1h7xmj?file=/src/App.js

Related

How to avoid initial lag after input using Material UI

Context
I have a carousel of MUI cards for a website that I'm building that is a box using a stack as it's underlying component. A problem that's come up is that whenever I try to scroll, there's at least a 4 second lag before seeing any new render. I tried
cropping down the images
compressing them
converting to .webp's
moving the logic into one place instead of passing props
Thouhgts
Memoizing the component works as a band-aid after the initial lag and
it scrolls as it should after but I'm assuming that's not the correct way
to do this.
(Idea) After looking back into the docs for an alternative I figured
virtualizing the list might work as well
Would probably be easier to just write them out by hand
Cut off a lot of the unnecessary bits
Index.tsx snippet mapping through data
<Box
component={Stack}
direction="row"
spacing={5}
>
{carouselData.map((item: CarouselProps) => (
<CreativeCarousel
src={item.src}
/>
))}
</Box>
Carousel Component
//Consistent typing for properties
export type CarouselProps = {
src: StaticImageData;
};
const CreativeCarousel = (props: CarouselProps) => {
return (
<Card sx={{ maxWidth: 300, minWidth: 300, height: "100%" }}>
<CardMedia component="img" height="75" image={props.src.src} />
</Card>
);
};
export default CreativeCarousel;
Troubleshooting
The lag went away after removing the <CardMedia /> so my guess is that rerendering full-res images for every frame of scrolling isn't the most optimal move.
Solution
But replacing the underlying component from the standard html img to an optimized Next.js Image most definitely was. I was under the impression that I needed to pass a component as a property or else I'd need to use an img like what was used in the example. I only found out later that I could also pass react nodes as children in the API page.
const Carousel = () => {
return carouselData.map((item) => (
<Card
key={item.heading}
sx={{ maxWidth: 300, minWidth: 300, height: "100%", mx: 4 }}
>
<CardMedia sx={{ width: "100%", height: "auto" }}>
<Image
alt={item.heading}
src={item.src}
layout="responsive"
/>
</CardMedia>
</Card>
));
};
export default Carousel;

Half page image on MUI v5

I'm trying to create a landing page in MUI v5 where half of the page is an image and the second part of the page is a form to login. I want the image and form to always fill the page completely with no scroll.
However, when doing so, it seems that MUI root is always affecting the margin so that the view has a horizontal scroll and there is white space on the left-hand side (See example below - and ignore the silly image):
How the page should look (and what it looks like if I scroll to the right):
How the page should look when I load it before scrolling:
I've spent hours trying to edit the CSS and figuring out where this is coming from with no luck. There is probably a better way to format this but I am using Grid and have tried Box with no luck.
My source code looks something like:
import React from "react";
import PropTypes from "prop-types";
import Grid from "#mui/material/Grid/Grid";
import Box from "#mui/material/Box";
import Paper from "#mui/material/Paper";
import SomeComponent from "...{some_path}...";
import SomeFormComponent from "...{some_path}...";
const SomeComponent = ({children, title, width}) => {
return (
<Grid container disableGutters sx={{height: "100vh", width: "100vw"}}>
<Grid
item
xs={false}
sm={4}
md={7}
sx={{
backgroundImage: `url(${SomeImage})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
backgroundPosition: "center",
}}
/>
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<Box
sx={{
my: 8,
mx: 4,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<SomeFormComponent width={width} title={title}>
{children}
</SomeFormComponent>
</Box>
</Grid>
</Grid>
);
};
Also, inspecting the page elements, I've identified the padding and margin come from a class called css-ayh9c9-MuiGrid-root which seems to be causing this because if I remove the class from the parent, everything works as expected. However, this is being added by MUI behind the scenes because it is nowhere in my source code.
Any help would be greatly appreciated!
I prefer Box whenever possible because Grid does some funky stuff with margins. In this case you can use the flex attribute on the children to get the right proportions. here is a working example https://codesandbox.io/s/material-demo-forked-rur3t?file=/App.tsx

MUI Grid System to Take Up 100% of Width

hope you're all good.
I'm having an issue finding out how to make my MUI Grid take up the entire width of the Box component it is nested within.
Here is how it looks:
I want the empty space at the end right to be taken up by the entire grid but I can't seem to find a concise answer on how to fix this.
Here is my code in VS Code:
Here is the code in text for the Grid:
<Grid item key={days}>
<Box
key={days}
sx={{
width: 150,
height: 150,
backgroundColor: 'primary.dark',
'&:hover': {
backgroundColor: 'primary.main',
opacity: [0.9, 0.8, 0.7],
},
}}
/>
</Grid>
);
}
return (
<Grid container spacing={1}>
{/* And here I render the box array */}
{box}
</Grid>
);
And here is the parent elements:
Here is the code in real text for the parent elements:
// Parent Element
<Container>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: 1,
}}
>
{/* The Title of The Page */}
<Typography align="center" variant="h4" mt={2} mb={2} sx={{ fontWeight: 'bold' }}>
{t('Happy Chocolate Days!')}
</Typography>
{/* My Calendar Grid Component Inside The Box Component */}
<Calendar />
</Box>
</Container>
Thanks for any help in advance
You are setting the boxes to a fixed width & height of 150, thus even though their wrapper has more space left, there is not enough space for another box so it breaks into a new line, thus leaving you with the empty space on the right.
You either set the boxes all of them in the middle of the Container,
OR pick a width for the Container that can have 7 boxes of the same width with some space between them, like 770px width for container, and 10px spaces between them. but in that case you wont need Grid, just pure css.

MaterialUI Appbar with Tabs - can it be scrollable AND fullwidth

I would like my tab buttons to spread out across the entire screen.
When the screen width is too skinny to fit all the tabs, I would like the scroll buttons to show up.
MaterialUI has variant='scrollable' and the variant='fullWidth'. It does not appear to allow both of these to be used at the same time.
If I use the property scrollButtons='auto' in combination with variant='fullWidth' I don't get scroll buttons when things get to skinny.
Is there a mechanism for letting this work? Centering the buttons mitigates the issue somewhat, but isn't the real answer.
I know this question has been asked a while ago but in case someone would wonder, here is what I did:
import { Tabs, Tab } from '#mui/material'
<Tabs {...propsTabs} variant="scrollable">
<Tab {...propsTab1} sx={{ minWidth: "fit-content", flex: 1 }} />
<Tab {...propsTab2} sx={{ minWidth: "fit-content", flex: 1 }} />
{/*...*/}
</Tabs>
The MUI Tabs component has a { display: "flex" } property.

scroll to first element using List and AutoSizer doesn't work

I wanted to scroll back up to the first element in the List when a user clicks pagination buttons.
So far I come across scrollToRow and scrollToIndex and both of them didn't work.
Here's my current code:
<AutoSizer disableWidth>
{({ height }) => (
<div>
<List
ref="list"
height={height}
rowCount={this.state.items.length}
rowHeight={115}
rowRenderer={this._rowRenderer}
width={1}
scrollToRow={0}
containerStyle={{
width: '100%',
maxWidth: '100%',
}}
style={{
width: '100%',
marginBottom: '10px',
}}
/>
</div>
)}
</AutoSizer>
After a little bit of thinking, I found out that there's no need to use react-virtualized package anymore. Since I refactored the list to make use of SSR pagination showing 24 items at a time. So, it was an overkill.
Anyway, I just reused the same _rowRenderer() function to map items into a list. To achieve the scrolling behavior I just added the styling prop of "overflow: scroll".
Thats all.

Resources