Skip to content

Commit

Permalink
Handle negative heights and set default value of height to undefined
Browse files Browse the repository at this point in the history
  • Loading branch information
hbjORbj committed Jul 28, 2021
1 parent fefd78a commit cec63ac
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api-docs/masonry-item.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"classes": { "type": { "name": "object" } },
"columnSpan": { "type": { "name": "number" }, "default": "1" },
"component": { "type": { "name": "elementType" } },
"height": { "type": { "name": "number" } },
"height": { "type": { "name": "number" }, "default": "undefined" },
"sx": { "type": { "name": "object" } }
},
"name": "MasonryItem",
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui-lab/src/MasonryItem/MasonryItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface MasonryItemTypeMap<P = {}, D extends React.ElementType = 'div'>
classes?: Partial<MasonryItemClasses>;
/**
* The height of the component in px.
* @default undefined
*/
height?: number;
/**
Expand Down
39 changes: 28 additions & 11 deletions packages/material-ui-lab/src/MasonryItem/MasonryItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export const style = ({ styleProps, theme }) => {
const spacingValues = resolveBreakpointValues({ values: styleProps.spacing, base });
const transformer = createUnarySpacing(theme);
const styleFromPropValue = (propValue) => {
const gap = Number(getValue(transformer, propValue).replace('px', ''));
const rowSpan = Math.ceil(styleProps.height + gap);
const gap = styleProps.height ? Number(getValue(transformer, propValue).replace('px', '')) : 0;
const rowSpan = styleProps.height ? Math.ceil(styleProps.height + gap) : 0;
return {
gridRowEnd: `span ${rowSpan}`,
paddingBottom: gap - 1,
Expand Down Expand Up @@ -73,32 +73,47 @@ const MasonryItem = React.forwardRef(function MasonryItem(inProps, ref) {
const masonryItemRef = React.useRef(null);

const { spacing = 1, documentReady = false } = React.useContext(MasonryContext);
const { children, className, component = 'div', columnSpan = 1, height = 0, ...other } = props;
const {
children,
className,
component = 'div',
columnSpan = 1,
height = undefined,
...other
} = props;
const [styleProps, setStyleProps] = React.useState({
...props,
spacing,
columnSpan,
height,
height: height < 0 ? 0 : height, // MasonryItems to which negative or zero height is passed will be hidden
});

const classes = useUtilityClasses(styleProps);

const computeHeight = () => {
const child = masonryItemRef.current.firstChild;
setStyleProps({
...styleProps,
height: child?.getBoundingClientRect().height,
});
if (masonryItemRef?.current) {
const child = masonryItemRef.current.firstChild;
setStyleProps({
...styleProps,
height:
styleProps.height === undefined
? child?.getBoundingClientRect().height
: styleProps.height,
});
}
};
const resizeObserver = React.useRef(new ResizeObserver(computeHeight));

// If height is passed by user, ResizeObserver is not used.
const resizeObserver = React.useRef(
height === undefined ? new ResizeObserver(computeHeight) : null,
);

React.useEffect(() => {
if (documentReady) {
computeHeight();
}
}, [documentReady]); // eslint-disable-line

// eslint-disable-next-line
React.useEffect(() => {
if (resizeObserver?.current && masonryItemRef?.current) {
const observer = resizeObserver.current;
Expand All @@ -108,6 +123,7 @@ const MasonryItem = React.forwardRef(function MasonryItem(inProps, ref) {
observer.unobserve(item);
};
}
return true;
}, [masonryItemRef]);

const handleRef = useForkRef(ref, masonryItemRef);
Expand Down Expand Up @@ -154,6 +170,7 @@ MasonryItem.propTypes /* remove-proptypes */ = {
component: PropTypes.elementType,
/**
* The height of the component in px.
* @default undefined
*/
height: PropTypes.number,
/**
Expand Down

0 comments on commit cec63ac

Please sign in to comment.