返回 AiToEarn
useContainerMasonryColumns.ts
根目录 / project / aitoearn-web / src / components / draft-box / hooks / useContainerMasonryColumns.ts
1 /**
2 * 容器宽度驱动的瀑布流列数计算
3 * 用于嵌入面板场景,避免 react-masonry-css 只按屏幕宽度分列
4 */
5
6 'use client'
7
8 import { useEffect, useRef, useState } from 'react'
9
10 const CONTAINER_MASONRY_BREAKPOINTS = [
11 { minWidth: 1120, columns: 5 },
12 { minWidth: 880, columns: 4 },
13 { minWidth: 640, columns: 3 },
14 { minWidth: 360, columns: 2 },
15 ] as const
16
17 function getContainerMasonryColumns(width: number) {
18 const matched = CONTAINER_MASONRY_BREAKPOINTS.find(item => width >= item.minWidth)
19 return matched?.columns ?? 1
20 }
21
22 export function useContainerMasonryColumns(enabled: boolean) {
23 const containerRef = useRef<HTMLDivElement>(null)
24 const [masonryColumns, setMasonryColumns] = useState(1)
25
26 useEffect(() => {
27 if (!enabled)
28 return
29
30 const container = containerRef.current
31 if (!container)
32 return
33
34 const updateColumns = (width: number) => {
35 setMasonryColumns(getContainerMasonryColumns(width))
36 }
37
38 updateColumns(container.offsetWidth)
39
40 const resizeObserver = new ResizeObserver((entries) => {
41 const [entry] = entries
42 if (!entry)
43 return
44
45 updateColumns(entry.contentRect.width)
46 })
47
48 resizeObserver.observe(container)
49
50 return () => {
51 resizeObserver.disconnect()
52 }
53 }, [enabled])
54
55 return { containerRef, masonryColumns }
56 }
57
57 lines TYPESCRIPT