Skip to content

Commit

Permalink
Provide SSR via height prop and optimise images in demo
Browse files Browse the repository at this point in the history
  • Loading branch information
hbjORbj committed Jul 27, 2021
1 parent 8819da6 commit 9d8596b
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 74 deletions.
1 change: 1 addition & 0 deletions docs/pages/api-docs/masonry-item.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"classes": { "type": { "name": "object" } },
"columnSpan": { "type": { "name": "number" }, "default": "1" },
"component": { "type": { "name": "elementType" } },
"height": { "type": { "name": "number" } },
"sx": { "type": { "name": "object" } }
},
"name": "MasonryItem",
Expand Down
46 changes: 17 additions & 29 deletions docs/src/pages/components/masonry/ImageMasonry.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import MasonryItem from '@material-ui/lab/MasonryItem';
export default function ImageMasonry() {
return (
<Masonry
columns={{ xs: 3, sm: 5, md: 7 }}
spacing={{ xs: 1, sm: 2, md: 3 }}
columns={{ xs: 3, sm: 5 }}
spacing={{ xs: 1, sm: 1.5 }}
sx={{ height: 300 }}
>
{itemData.map((item) => (
<MasonryItem key={item.img}>
<img
srcSet={`${item.img}?fit=crop&auto=format 1x,
${item.img}?fit=crop&auto=format&dpr=2 2x`}
srcSet={`${item.img}?w=164&h=164&auto=format 1x,
${item.img}?w=164&h=164&auto=format&dpr=2 2x`}
alt={item.title}
loading="lazy"
/>
Expand All @@ -29,69 +29,53 @@ const itemData = [
img: 'https://images.unsplash.com/photo-1518756131217-31eb79b20e8f',
title: 'Fern',
},
{
img: 'https://images.unsplash.com/photo-1627308595229-7830a5c91f9f',
title: 'Snacks',
},
{
img: 'https://images.unsplash.com/photo-1597645587822-e99fa5d45d25',
title: 'Mushrooms',
},
{
img: 'https://images.unsplash.com/photo-1529655683826-aba9b3e77383?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bG9uZG9ufGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&w=1000&q=80',
img: 'https://images.unsplash.com/photo-1529655683826-aba9b3e77383',
title: 'Tower',
},
{
img: 'https://images.unsplash.com/photo-1471357674240-e1a485acb3e1',
title: 'Sea star',
},
{
img: 'https://images.pexels.com/photos/1761279/pexels-photo-1761279.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
title: 'Bridge',
},
{
img: 'https://images.unsplash.com/photo-1558642452-9d2a7deb7f62',
title: 'Honey',
},
{
img: 'https://www.nature.com/immersive/d41586-021-00095-y/assets/3TP4N718ac/2021-01-xx_jan-iom_tree-of-life_sh-1080x1440.jpeg',
title: 'Lake',
},
{
img: 'https://images.unsplash.com/photo-1516802273409-68526ee1bdd6',
title: 'Basketball',
},
{
img: 'https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg',
title: 'Birds',
},
{
img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e',
title: 'Breakfast',
},
{
img: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg',
title: 'Sunset',
img: 'https://images.unsplash.com/photo-1627328715728-7bcc1b5db87d',
title: 'Tree',
},
{
img: 'https://images.unsplash.com/photo-1551782450-a2132b4ba21d',
title: 'Burger',
},
{
img: 'https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
title: 'Picture',
},
{
img: 'https://images.unsplash.com/photo-1522770179533-24471fcdba45',
title: 'Camera',
},
{
img: 'https://cdn.pixabay.com/photo/2016/05/05/02/37/sunset-1373171__340.jpg',
title: 'Landscape',
},
{
img: 'https://images.unsplash.com/photo-1444418776041-9c7e33cc5a9c',
title: 'Coffee',
},
{
img: 'https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510__340.jpg',
title: 'Flower',
img: 'https://images.unsplash.com/photo-1627000086207-76eabf23aa2e',
title: 'Camping Car',
},
{
img: 'https://images.unsplash.com/photo-1533827432537-70133748f5c8',
Expand All @@ -101,6 +85,10 @@ const itemData = [
img: 'https://images.unsplash.com/photo-1567306301408-9b74779a11af',
title: 'Tomato basil',
},
{
img: 'https://images.unsplash.com/photo-1627328561499-a3584d4ee4f7',
title: 'Mountain',
},
{
img: 'https://images.unsplash.com/photo-1589118949245-7d38baf380d6',
title: 'Bike',
Expand Down
46 changes: 17 additions & 29 deletions docs/src/pages/components/masonry/ImageMasonry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import MasonryItem from '@material-ui/lab/MasonryItem';
export default function ImageMasonry() {
return (
<Masonry
columns={{ xs: 3, sm: 5, md: 7 }}
spacing={{ xs: 1, sm: 2, md: 3 }}
columns={{ xs: 3, sm: 5 }}
spacing={{ xs: 1, sm: 1.5 }}
sx={{ height: 300 }}
>
{itemData.map((item) => (
<MasonryItem key={item.img}>
<img
srcSet={`${item.img}?fit=crop&auto=format 1x,
${item.img}?fit=crop&auto=format&dpr=2 2x`}
srcSet={`${item.img}?w=164&h=164&auto=format 1x,
${item.img}?w=164&h=164&auto=format&dpr=2 2x`}
alt={item.title}
loading="lazy"
/>
Expand All @@ -29,69 +29,53 @@ const itemData = [
img: 'https://images.unsplash.com/photo-1518756131217-31eb79b20e8f',
title: 'Fern',
},
{
img: 'https://images.unsplash.com/photo-1627308595229-7830a5c91f9f',
title: 'Snacks',
},
{
img: 'https://images.unsplash.com/photo-1597645587822-e99fa5d45d25',
title: 'Mushrooms',
},
{
img: 'https://images.unsplash.com/photo-1529655683826-aba9b3e77383?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bG9uZG9ufGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&w=1000&q=80',
img: 'https://images.unsplash.com/photo-1529655683826-aba9b3e77383',
title: 'Tower',
},
{
img: 'https://images.unsplash.com/photo-1471357674240-e1a485acb3e1',
title: 'Sea star',
},
{
img: 'https://images.pexels.com/photos/1761279/pexels-photo-1761279.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
title: 'Bridge',
},
{
img: 'https://images.unsplash.com/photo-1558642452-9d2a7deb7f62',
title: 'Honey',
},
{
img: 'https://www.nature.com/immersive/d41586-021-00095-y/assets/3TP4N718ac/2021-01-xx_jan-iom_tree-of-life_sh-1080x1440.jpeg',
title: 'Lake',
},
{
img: 'https://images.unsplash.com/photo-1516802273409-68526ee1bdd6',
title: 'Basketball',
},
{
img: 'https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg',
title: 'Birds',
},
{
img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e',
title: 'Breakfast',
},
{
img: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg',
title: 'Sunset',
img: 'https://images.unsplash.com/photo-1627328715728-7bcc1b5db87d',
title: 'Tree',
},
{
img: 'https://images.unsplash.com/photo-1551782450-a2132b4ba21d',
title: 'Burger',
},
{
img: 'https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
title: 'Picture',
},
{
img: 'https://images.unsplash.com/photo-1522770179533-24471fcdba45',
title: 'Camera',
},
{
img: 'https://cdn.pixabay.com/photo/2016/05/05/02/37/sunset-1373171__340.jpg',
title: 'Landscape',
},
{
img: 'https://images.unsplash.com/photo-1444418776041-9c7e33cc5a9c',
title: 'Coffee',
},
{
img: 'https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510__340.jpg',
title: 'Flower',
img: 'https://images.unsplash.com/photo-1627000086207-76eabf23aa2e',
title: 'Camping Car',
},
{
img: 'https://images.unsplash.com/photo-1533827432537-70133748f5c8',
Expand All @@ -101,6 +85,10 @@ const itemData = [
img: 'https://images.unsplash.com/photo-1567306301408-9b74779a11af',
title: 'Tomato basil',
},
{
img: 'https://images.unsplash.com/photo-1627328561499-a3584d4ee4f7',
title: 'Mountain',
},
{
img: 'https://images.unsplash.com/photo-1589118949245-7d38baf380d6',
title: 'Bike',
Expand Down
27 changes: 27 additions & 0 deletions docs/src/pages/components/masonry/SSRMasonry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
import * as React from 'react';
import Box from '@material-ui/core/Box';
import Masonry from '@material-ui/lab/Masonry';
import MasonryItem from '@material-ui/lab/MasonryItem';

export default function SSRMasonry() {
return (
<Masonry columns={4} spacing={1}>
{heights.map((height, index) => (
<MasonryItem key={index} height={height}>
<Box
sx={{
textAlign: 'center',
height: '100%',
border: 1,
bgcolor: 'background.paper',
}}
>
{index + 1}
</Box>
</MasonryItem>
))}
</Masonry>
);
}
const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80];
27 changes: 27 additions & 0 deletions docs/src/pages/components/masonry/SSRMasonry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
import * as React from 'react';
import Box from '@material-ui/core/Box';
import Masonry from '@material-ui/lab/Masonry';
import MasonryItem from '@material-ui/lab/MasonryItem';

export default function SSRMasonry() {
return (
<Masonry columns={4} spacing={1}>
{heights.map((height, index) => (
<MasonryItem key={index} height={height}>
<Box
sx={{
textAlign: 'center',
height: '100%',
border: 1,
bgcolor: 'background.paper',
}}
>
{index + 1}
</Box>
</MasonryItem>
))}
</Masonry>
);
}
const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80];
4 changes: 4 additions & 0 deletions docs/src/pages/components/masonry/masonry.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ Masonry maintains a list of content blocks with a consistent width but variable
> You can configure the number of columns taken up by each `<MasonryItem />` as shown in the following demo:
{{"demo": "pages/components/masonry/DiffColSizeMasonry.js", "bg": true}}

> In order to use server-side rendering, you can pass the height of the content of `<MasonryItem />` as shown in the following demo:
{{"demo": "pages/components/masonry/SSRMasonry.js", "bg": true}}
1 change: 1 addition & 0 deletions docs/translations/api-docs/masonry-item/masonry-item.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"columnSpan": "The number of columns taken up by the component",
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"height": "The height of the component in px.",
"sx": "Allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/the-sx-prop/\">`sx` page</a> for more details."
},
"classDescriptions": { "root": { "description": "Styles applied to the root element." } }
Expand Down
4 changes: 4 additions & 0 deletions packages/material-ui-lab/src/MasonryItem/MasonryItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export interface MasonryItemTypeMap<P = {}, D extends React.ElementType = 'div'>
* Override or extend the styles applied to the component.
*/
classes?: Partial<MasonryItemClasses>;
/**
* The height of the component in px.
*/
height?: number;
/**
* The number of columns taken up by the component
* @default 1
Expand Down
34 changes: 18 additions & 16 deletions packages/material-ui-lab/src/MasonryItem/MasonryItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const style = ({ styleProps, theme }) => {
// all contents should have a width of 100%
width: '100%',
},
visibility: styleProps.contentHeight ? 'visible' : 'hidden',
visibility: styleProps.height ? 'visible' : 'hidden',
gridColumnEnd: `span ${styleProps.columnSpan}`,
};

Expand All @@ -45,7 +45,7 @@ export const style = ({ styleProps, theme }) => {
const transformer = createUnarySpacing(theme);
const styleFromPropValue = (propValue) => {
const gap = Number(getValue(transformer, propValue).replace('px', ''));
const rowSpan = styleProps.contentHeight ? Math.ceil(styleProps.contentHeight + gap) : 0;
const rowSpan = styleProps.height ? Math.ceil(styleProps.height + gap) : 0;
return {
gridRowEnd: `span ${rowSpan}`,
paddingBottom: gap - 1,
Expand Down Expand Up @@ -86,29 +86,31 @@ const MasonryItem = React.forwardRef(function MasonryItem(inProps, ref) {
const child = masonryItemRef.current.firstChild;
setStyleProps({
...styleProps,
contentHeight: child?.getBoundingClientRect().height,
height: child?.getBoundingClientRect().height,
});
};
const resizeObserver = React.useRef(new ResizeObserver(computeHeight));
const resizedItemRef = React.useCallback(
(item) => {
if (item !== null) {
resizeObserver.current.observe(item);
} else if (resizeObserver.current) {
resizeObserver.current.disconnect();
}
},
[resizeObserver],
);

React.useEffect(() => {
if (documentReady) {
computeHeight();
resizeObserver.current.observe(masonryItemRef.current);
}
}, [documentReady]); // eslint-disable-line
const handleOwnRef = useForkRef(masonryItemRef, resizedItemRef);
const handleRef = useForkRef(ref, handleOwnRef);

// eslint-disable-next-line
React.useEffect(() => {
if (resizeObserver?.current && masonryItemRef?.current) {
const observer = resizeObserver.current;
const item = masonryItemRef.current;
observer.observe(item);
return () => {
observer.unobserve(item);
};
}
}, [masonryItemRef]);

const handleRef = useForkRef(ref, masonryItemRef);

return (
<MasonryItemRoot
as={component}
Expand Down

0 comments on commit 9d8596b

Please sign in to comment.