-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a Masonry Component #17000
Comments
Just a remark, in case this does get enough momentum. I don't want to make excuses, but with this being my senior year, landing a place in programming team, and working, I am utterly swamped. I want to contribute though in anyway I can. If everyone is fine with waiting on me, that's cool and I apologize in advance. However, if someone picks it up, that's cool too I just want to be involved in some way if possible. |
Wish there was a masonry component similar to Muuri.js. The gridlist just doesn't cut it. |
Any news about this component? I think there is a lot of people which are waiting for something like this :) |
We weren't expecting this component to be that much requested, but yeah, we will think about something for it :). |
Voting this request up. Have tried a few npm packages and not super confident in performance of any of the ones available. I haven't gotten exactly the expected behavior out of those available. I would be super confident in you guys to put out a reliable component :) |
I'm using https://github.com/paulcollett/react-masonry-css for now and it's serving it's purpose well |
Dashue, Thank you for the reference. Right now my cards are in a Grid, but the content will never be even even if I limit the number of items within the card. This is where I get caught up -- for mobile it is not an issue because the grid collapses to one row. I want something that very light that which I can implement only for desktop. It seems a natural extension of the Grid Component...to just add a prop in there that says collapse vertical whitespace within rows. I get that it is not that simple... |
I also use react-masonry-css and made a simple wrapper component that takes the breakpoints from the theme and configures the masonry accordingly - works pretty well: import React from "react";
import PropTypes from "prop-types";
import { makeStyles, useTheme } from "@material-ui/core/styles";
import Masonry from "react-masonry-css";
/////////////////////////////////////////
// Styles
/////////////////////////////////////////
const useStyles = makeStyles((theme) => ({
root: {
margin: theme.spacing(3, 0, 2, 0),
},
paper: {
marginBottom: theme.spacing(4),
},
masonryGrid: {
display: "flex",
marginLeft: theme.spacing(-4),
width: "inherit",
},
masonryColumn: {
paddingLeft: theme.spacing(4),
backgroundClip: "padding-box",
},
}));
/////////////////////////////////////////
// PropTypes
/////////////////////////////////////////
const propTypes = {
children: PropTypes.node,
};
/////////////////////////////////////////
// Component
/////////////////////////////////////////
const BreakpointMasonry = ({ children }) => {
const classes = useStyles();
const theme = useTheme();
const breakpointCols = {
default: 4,
[theme.breakpoints.values.xl]: 4,
[theme.breakpoints.values.lg]: 3,
[theme.breakpoints.values.md]: 2,
[theme.breakpoints.values.sm]: 1,
[theme.breakpoints.values.xs]: 1,
};
return (
<Masonry
breakpointCols={breakpointCols}
className={classes.masonryGrid}
columnClassName={classes.masonryColumn}
>
{children}
</Masonry>
);
};
BreakpointMasonry.propTypes = propTypes;
export default BreakpointMasonry; |
Any updates on this visually it would be so amazing! |
Did you try the wrapper component I posted above? Just import it and wrap the components you want to show in a masonry with it. <BreakpointMasonry>
<...yourComponent>
<...yourComponent>
<...yourComponent>
</BreakpointMasonry> if you need different breakpoints adjust the |
can confirm that the wrapper component above works incredibly well! |
Taken from [this comment](mui/material-ui#17000 (comment)).
The above example integrating react-material-css and the MUI theme breakpoints works well. I also encountered this issue a while ago, and came up with a solution using only MUI by nesting two Grid containers, and dynamically arranging the Grid items into new columns when the width changes (detecting width changes using useWidth()). I've uploaded a working minimal demo to CodeSandbox in case it helps anyone coming across this thread. I'm using this prop to dynamically arrange the grid items into columns of customizable widths:
E.g.: One of the challenges I've faced with this solution (and also with react-material-css) is that some of the children of the Masonry grid need to be unmounted and remounted into new parents (new columns) when the viewport width changes. I'm not confident that this is a problem that can be solved when using Masonry layouts with dynamic columns in React though (and it isn't a big problem if you can lift state out of the Masonry grid's children). Hope this helps someone! |
@chrishoermann awesome wrapper! Thanks for sharing this. Although, an actual component shipped by MUI would be perfect. |
This is something I'm interested to start working on, if no one has started working on it yet |
@atnpcg I'm not aware anyone is working on it, you are clear to go :). I think that the first step is to get a pretty clear picture of what should be built. What problem did developers face when coming here to upvote the issue? |
@oliviertassinari for me it was a stop when trying to implement it with cards in a masonry layout like shown on: |
@atnpcg I have updated the |
@oliviertassinari |
I think also what we have on https://next.material-ui.com/components/image-list/#masonry-image-list is close enough, but currently is just a variation for the ImageList, we can try start by there, extracting some of the logic and have it as a standalone component |
@atnpcg We can benchmark what the ImageList is doing but it's a great opportunity to challenge the implementation. Happy to try https://paulcollett.github.io/react-masonry-css/demo/ out, it seems to have a nice compromise in terms of simplicity. Regarding the breakpoint API, I would suggest we use the same one as the system: https://next.material-ui.com/system/basics/#responsive-values. It will also be an opportunity to implement a |
@atnpcg Despite the new name, an ImageListLtem's child doesn't have to be an image. (Even the MD spec alludes to this IIRC). It would be trivial to set the The challenge would be reordering the items so that they are distributed from left-to-right, rather than top-to-bottom. That's probably going to be a performance suck. Also, beware accessibility concerns, and how infinite scroll could work with that approach. There's experimental native masonry grid layout in Firefox, but that's too early for our use. |
https://material.io/components/image-lists#usage, section "Types", item 4 is Masonry image lists (yes, it's deep) |
you are right @mbrookes and even the library we are suggesting, is rendered in columns, affecting accessibility (screen readers will read top to bottom instead of left to right), also focusable elements will have a top to bottom flow, unless we start detecting what elements are focusable and calculate every single focusIndex. |
My first approach was to use Grid component inside of Masonry, |
Masonry component will render children from left to right, accepting cols and spacing props fix mui#17000
Masonry component will render children from left to right, accepting cols and spacing props fix mui#17000
Considering the high volume of upvotes for this issue, and the large spectrum of the different solutions that we can build, we have created a survey to identify the most frequent pain points. There are 5 questions, it shouldn't take more than 1 minute to fill: Take the survey! 📣 🙏 |
This comment has been minimized.
This comment has been minimized.
@weiluntong @bluefire2121 @atnpcg @GuillaumeDesforges @chrishoermann @WojtekHerisz @Dashue @HarmanSran @megphillips91 For your information, Masonry component is now live as part of It comes with a limitation which is explained in this issue. To address this limitation, a new implementation for Masonry is waiting in this PR. In short,
I would really appreciate if you could share your preference between the two! You can leave your comments in either the PR for new masonry or in the issue. |
This references issue #7602. I propose MUI adds a a new Masonry component.
Summary 💡
A masonry component is a grid layout in which "Elements from a single-column format may reflow to fill the content area in various combinations."
The current Grid component with its underlying flexbox does not support this. However, I believe the MUI Grid behavior has its place, and a MUI Masonry can be sufficiently separate and distinct from MUI Grid.
The main interest in having such a component would be to support an aspect of the Material UI specification with a MUI component. As a MUI component, there is more control over the component, making it behave as expected of a MUI component. This gives way to a consolidated definition of component themes, in this case, access to MUI's breakpoint definitions; a MUI-like width range consisting of 1-12, 'auto', and boolean values for MUI's implementation of responsiveness; and custom props such as xs, md, lg, component, spacing, etc. which --again-- give it a more MUI-like behavior expected of MUI components.
This component needs more upvotes to be considered for MUI. This proposal mainly isolates those upvotes for an accurate record of users who would like the MUI library to support this component.
Benchmarks
The text was updated successfully, but these errors were encountered: