mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.96k stars 32.27k 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 1 year 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?