Skip to content

Commit

Permalink
add sequential masonry
Browse files Browse the repository at this point in the history
  • Loading branch information
GSS-Rishi committed Nov 17, 2023
1 parent d2cd42d commit 7d06304
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
36 changes: 36 additions & 0 deletions docs/data/material/components/masonry/Sequential.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
import Paper from '@mui/material/Paper';
import Masonry from '@mui/lab/Masonry';

const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80];

const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
...theme.typography.body2,
padding: theme.spacing(0.5),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

export default function Sequential() {
return (
<Box sx={{ width: 500, minHeight: 393 }}>
<Masonry
columns={4}
spacing={2}
defaultHeight={450}
defaultColumns={4}
defaultSpacing={1}
sequential
>
{heights.map((height, index) => (
<Item key={index} sx={{ height }}>
{index + 1}
</Item>
))}
</Masonry>
</Box>
);
}
36 changes: 36 additions & 0 deletions docs/data/material/components/masonry/Sequential.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
import Paper from '@mui/material/Paper';
import Masonry from '@mui/lab/Masonry';

const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80];

const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
...theme.typography.body2,
padding: theme.spacing(0.5),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

export default function Sequential() {
return (
<Box sx={{ width: 500, minHeight: 393 }}>
<Masonry
columns={4}
spacing={2}
defaultHeight={450}
defaultColumns={4}
defaultSpacing={1}
sequential
>
{heights.map((height, index) => (
<Item key={index} sx={{ height }}>
{index + 1}
</Item>
))}
</Masonry>
</Box>
);
}
7 changes: 7 additions & 0 deletions docs/data/material/components/masonry/masonry.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ It is important to note that the value provided to the `spacing` prop is multipl

{{"demo": "ResponsiveSpacing.js", "bg": true}}

## Sequential

This example demonstrates the use of the `sequential` to configure the sequential order.
With `sequential` enabled, items are added in order from left to right rather than adding to the shortest column.

{{"demo": "Sequential.js", "bg": true}}

## Server-side rendering

This example demonstrates the use of the `defaultHeight`, `defaultColumns` and `defaultSpacing`, which are used to
Expand Down
1 change: 1 addition & 0 deletions docs/pages/material-ui/api/masonry.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"defaultColumns": { "type": { "name": "number" } },
"defaultHeight": { "type": { "name": "number" } },
"defaultSpacing": { "type": { "name": "number" } },
"sequential": { "type": { "name": "bool" }, "default": "false" },
"spacing": {
"type": {
"name": "union",
Expand Down
3 changes: 3 additions & 0 deletions docs/translations/api-docs/masonry/masonry.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"defaultSpacing": {
"description": "The default spacing of the component. Like <code>spacing</code>, it is a factor of the theme&#39;s spacing. This is provided for server-side rendering."
},
"sequential": {
"description": "Allows using sequential order rather than adding to shortest column"
},
"spacing": {
"description": "Defines the space between children. It is a factor of the theme&#39;s spacing."
},
Expand Down
5 changes: 5 additions & 0 deletions packages/mui-lab/src/Masonry/Masonry.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export interface MasonryOwnProps {
* @default 1
*/
spacing?: ResponsiveStyleValue<number | string>;
/**
* Allows using sequential order rather than adding to shortest column
* @default false
*/
sequential?: boolean;
/**
* Allows defining system overrides as well as additional CSS styles.
*/
Expand Down
26 changes: 21 additions & 5 deletions packages/mui-lab/src/Masonry/Masonry.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) {
component = 'div',
columns = 4,
spacing = 1,
sequential = false,
defaultColumns,
defaultHeight,
defaultSpacing,
Expand Down Expand Up @@ -235,6 +236,7 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) {

const columnHeights = new Array(currentNumberOfColumns).fill(0);
let skip = false;
let nextOrder = 1;
masonry.childNodes.forEach((child) => {
if (child.nodeType !== Node.ELEMENT_NODE || child.dataset.class === 'line-break' || skip) {
return;
Expand All @@ -259,11 +261,20 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) {
}
}
if (!skip) {
// find the current shortest column (where the current item will be placed)
const currentMinColumnIndex = columnHeights.indexOf(Math.min(...columnHeights));
columnHeights[currentMinColumnIndex] += childHeight;
const order = currentMinColumnIndex + 1;
child.style.order = order;
if (sequential) {
columnHeights[nextOrder - 1] += childHeight;
child.style.order = nextOrder;
nextOrder += 1;
if (nextOrder > currentNumberOfColumns) {
nextOrder = 1;
}
} else {
// find the current shortest column (where the current item will be placed)
const currentMinColumnIndex = columnHeights.indexOf(Math.min(...columnHeights));
columnHeights[currentMinColumnIndex] += childHeight;
const order = currentMinColumnIndex + 1;
child.style.order = order;
}
}
});
if (!skip) {
Expand Down Expand Up @@ -374,6 +385,11 @@ Masonry.propTypes /* remove-proptypes */ = {
* The default spacing of the component. Like `spacing`, it is a factor of the theme's spacing. This is provided for server-side rendering.
*/
defaultSpacing: PropTypes.number,
/**
* Allows using sequential order rather than adding to shortest column
* @default false
*/
sequential: PropTypes.bool,
/**
* Defines the space between children. It is a factor of the theme's spacing.
* @default 1
Expand Down

0 comments on commit 7d06304

Please sign in to comment.