mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.59k stars 31.92k forks source link

[Masonry] Allow individual width of card #37433

Open redimongo opened 1 year ago

redimongo commented 1 year ago

Duplicates

Latest version

Summary 💡

I am using import Masonry from '@mui/lab/Masonry'; (could not find the GitHub for lab)

Basiclly I have Cards and I have some cards that are to tall and others that are to short, so Masonry works wonders, however now my cards won't do as I need them to do.

basically my Tip card should be full length of the screen {12} however with Masonry I can't force it to as the Masonry code requires us to limit into columns.

I don't know if anyone would have any suggestions but would really love the help if someone has a solution.

Examples 🌈

Full page code

import React, { Suspense } from 'react';
import dynamic from 'next/dynamic';

import withTheme from '../../hocs/withTheme';
import { Container, Card, Grid, Box, CardHeader, CardContent, CircularProgress } from '@mui/material';
import { Dashboard } from '@mui/icons-material';
import Masonry from '@mui/lab/Masonry';

type IndexProps = {
  minimized: boolean; // Replace 'boolean' with the appropriate type for 'minimized' prop
  apiData: {
    data: {
      _id: string;
    };
  };
};

const Index: React.FC<IndexProps> = ({ minimized, apiData }) => {
  const contentStyle = {
    paddingLeft: minimized ? '70px' : '260px', // Adjust these values according to your design
    paddingRight: '20px',
  };

  const cards = [
    { id: 1, title: '7 Day Downloads', showtitle: true, component: 'Podcast', size: 7 },
    { id: 3, title: 'Tip of The Day', showtitle: false, component: 'Tips', size: 12, cardStyle: { padding: 0 }, contentClass: 'removeLastChildPaddingBottom' },
    { id: 2, title: 'My Team', showtitle: true, component: 'Team', size: 5, cardStyle: { padding: 0 }, contentClass: 'removeLastChildPaddingBottom' },
    { id: 4, title: '7 Day Downloads', showtitle: true, component: 'Podcast', size: 7 },
  ];

  const renderComponentByType = (componentType: string) => {
    const Component = dynamic(() => import(`../../components/dashboard/plugins/${componentType}`));

    // Define the prop types for the Component
    interface ComponentProps {
      userid: string;
      // Other props specific to the Component
    }
    return Component as React.ComponentType<ComponentProps>;
  };

  return (
    <Box pt={10} sx={contentStyle}>
      <Container maxWidth="xl">
        <Masonry columns={2} spacing={2}>
        {cards.map((card) => {
            const DynamicComponent = renderComponentByType(card.component);

            if (!DynamicComponent) {
              return null;
            }

            return (
              <Grid item xs={12} md={card.size} key={card.id}>
                <div className={card.contentClass}>
                  <Card>
                    {card.showtitle && <CardHeader title={card.title} />}
                    <CardContent>
                      <Suspense fallback={<CircularProgress />}>
                        <DynamicComponent userid={apiData.data._id} />
                      </Suspense>
                    </CardContent>
                  </Card>
                </div>
              </Grid>
            );
          })}
        </Masonry>
      </Container>
    </Box>
  );
};

export default withTheme(Index, 'dashboard', true);

Motivation 🔦

The issue is card Teams could be really long taller than any other card as it has user data on it, when I tried to get it to work with a simple grid layout there was a big space between the two cards on the left. So I thought Masonry would fix it.

it does but it to has limitations.

hbjORbj commented 1 year ago

(could not find the GitHub for lab) @redimongo

We use a monorepo. Here is code of lab package: https://github.com/mui/material-ui/tree/master/packages/mui-lab if you were interested.

hbjORbj commented 1 year ago

Basiclly I have Cards and I have some cards that are to tall and others that are to short, so Masonry works wonders, however now my cards won't do as I need them to do. basically my Tip card should be full length of the screen {12} however with Masonry I can't force it to as the Masonry code requires us to limit into columns.

I see your struggle due to the limitation of the component. I will give it some thought.

redimongo commented 1 year ago

(could not find the GitHub for lab) @redimongo

We use a monorepo. Here is code of lab package: https://github.com/mui/material-ui/tree/master/packages/mui-lab if you were interested.

Yes thank you, I could not find the repo so I thought I would put the issue here.

redimongo commented 1 year ago

Basiclly I have Cards and I have some cards that are to tall and others that are to short, so Masonry works wonders, however now my cards won't do as I need them to do. basically my Tip card should be full length of the screen {12} however with Masonry I can't force it to as the Masonry code requires us to limit into columns.

I see your struggle due to the limitation of the component. I will give it some thought.

Temp solution was to put all full width cards up top, and outside of the Masonry. Not the ideal solution, but works.

stjohnson44 commented 10 months ago

Before closing this issue, I would like to second the need for allowing custom widths (or even something a little more conventional, like column span) on masonry children. If there is current development on this, could I please be pointed towards it?