MCPcopy
hub / github.com/pmndrs/react-spring / Masonry

Function Masonry

demo/src/sandboxes/masonry/src/App.tsx:11–72  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

9import styles from './styles.module.css'
10
11function Masonry() {
12 // Hook1: Tie media queries to the number of columns
13 const columns = useMedia(
14 ['(min-width: 1500px)', '(min-width: 1000px)', '(min-width: 600px)'],
15 [5, 4, 3],
16 2
17 )
18 // Hook2: Measure the width of the container element
19 const [ref, { width }] = useMeasure()
20 // Hook3: Hold items
21 const [items, set] = React.useState(data)
22 // Hook4: shuffle data every 2 seconds
23 React.useEffect(() => {
24 const t = setInterval(() => set(shuffle), 2000)
25 return () => clearInterval(t)
26 }, [])
27 // Hook5: Form a grid of stacked items using width & columns we got from hooks 1 & 2
28 const [heights, gridItems] = React.useMemo(() => {
29 const heights = new Array(columns).fill(0) // Each column gets a height starting with zero
30 const gridItems = items.map(child => {
31 const column = heights.indexOf(Math.min(...heights)) // Basic masonry-grid placing, puts tile into the smallest column using Math.min
32 const x = (width / columns) * column // x = container width / number of columns * column index,
33 const y = (heights[column] += child.height / 2) - child.height / 2 // y = it's just the height of the current column
34 return {
35 ...child,
36 x,
37 y,
38 width: width / columns,
39 height: child.height / 2,
40 }
41 })
42 return [heights, gridItems]
43 }, [columns, items, width])
44 // Hook6: Turn the static grid values into animated transitions, any addition, removal or change will be animated
45 const transitions = useTransition(gridItems, {
46 key: (item: { css: string; height: number }) => item.css,
47 from: ({ x, y, width, height }) => ({ x, y, width, height, opacity: 0 }),
48 enter: ({ x, y, width, height }) => ({ x, y, width, height, opacity: 1 }),
49 update: ({ x, y, width, height }) => ({ x, y, width, height }),
50 leave: { height: 0, opacity: 0 },
51 config: { mass: 5, tension: 500, friction: 100 },
52 trail: 25,
53 })
54 // Render the grid
55 return (
56 <div
57 ref={ref}
58 className={styles.list}
59 style={{ height: Math.max(...heights) }}
60 >
61 {transitions((style, item) => (
62 <a.div style={style}>
63 <div
64 style={{
65 backgroundImage: `url(${item.css}?auto=compress&dpr=2&h=500&w=500)`,
66 }}
67 />
68 </a.div>

Callers

nothing calls this directly

Calls 3

useMediaFunction · 0.85
setFunction · 0.85
useTransitionFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…