UNPKG

story-az-card-kit

Version:

A flexible and customizable story card component with multiple layouts

76 lines (66 loc) 1.94 kB
import React, { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import StoryCard from '../components/StoryCard'; const MasonryCard = ({ stories = [], columns = 3, gap = 'medium', theme = 'default', onCardClick, className = '', children, ...props }) => { const masonryRef = useRef(null); useEffect(() => { const masonry = masonryRef.current; if (!masonry) return; const resizeObserver = new ResizeObserver(() => { // Trigger reflow for masonry layout masonry.style.opacity = '0.99'; setTimeout(() => { masonry.style.opacity = '1'; }, 10); }); resizeObserver.observe(masonry); return () => { resizeObserver.disconnect(); }; }, []); const masonryClass = `story-card-masonry story-card-masonry--${columns}-cols story-card-masonry--gap-${gap}`; const masonryClasses = [ masonryClass, className ].filter(Boolean).join(' '); return ( <div ref={masonryRef} className={masonryClasses} {...props}> {stories.map((story, index) => ( <div key={index} className="story-card-masonry__item"> <StoryCard {...story} theme={theme} onClick={onCardClick ? (e, data) => onCardClick(e, data, index) : undefined} /> </div> ))} {children} </div> ); }; MasonryCard.propTypes = { stories: PropTypes.arrayOf(PropTypes.shape({ title: PropTypes.string, description: PropTypes.string, image: PropTypes.string, author: PropTypes.string, date: PropTypes.string, tags: PropTypes.arrayOf(PropTypes.string) })), columns: PropTypes.oneOf([2, 3, 4, 5]), gap: PropTypes.oneOf(['small', 'medium', 'large']), theme: PropTypes.oneOf(['default', 'dark', 'minimal', 'elegant', 'modern']), onCardClick: PropTypes.func, className: PropTypes.string, children: PropTypes.node }; export default MasonryCard;