@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
74 lines • 2.18 kB
JavaScript
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { AnimatePresence } from 'motion/react';
import { useElementSize } from '../../hooks/element';
import { MasonryContext } from './Masonry.context';
import { StyledMasonry } from './Masonry.styles';
import { useMasonryColumnCount, useMasonryItems, useMasonryLayout } from './Masonry.hooks';
import { getMasonryItemKey } from './Masonry.utils';
import MasonryItem, { InternalMasonryItem } from './masonry-item/MasonryItem';
const MasonryBase = ({
children,
gap = 8,
columnWidth = 80,
rowHeight = 80
}) => {
const ref = useRef(null);
const size = useElementSize(ref);
const containerWidth = size?.width ?? 0;
const [itemHeights, setItemHeights] = useState({});
const items = useMasonryItems({
children
});
const columnCount = useMasonryColumnCount({
containerWidth,
columnWidth,
gap
});
const layout = useMasonryLayout({
items,
itemHeights,
columnCount,
columnWidth,
rowHeight,
gap
});
const registerItem = useCallback((key, height) => {
setItemHeights(currentHeights => {
if (currentHeights[key] === height) {
return currentHeights;
}
return {
...currentHeights,
[key]: height
};
});
}, []);
const contextValue = useMemo(() => ({
registerItem
}), [registerItem]);
return /*#__PURE__*/React.createElement(MasonryContext.Provider, {
value: contextValue
}, /*#__PURE__*/React.createElement(StyledMasonry, {
ref: ref,
$height: layout.height
}, /*#__PURE__*/React.createElement(AnimatePresence, null, items.map((item, index) => {
const key = getMasonryItemKey(item, index);
const packedItem = layout.items[key];
if (!packedItem) {
return null;
}
return /*#__PURE__*/React.createElement(InternalMasonryItem, {
key: key,
itemKey: key,
x: packedItem.x,
y: packedItem.y,
width: packedItem.width
}, item.props.children);
}))));
};
MasonryBase.displayName = 'Masonry';
const Masonry = Object.assign(MasonryBase, {
Item: MasonryItem
});
export default Masonry;
//# sourceMappingURL=Masonry.js.map