UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

74 lines 2.18 kB
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