smart-masonry-grid 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/dist/index.cjs +694 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +165 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +689 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +616 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +165 -0
- package/dist/react/index.d.ts +165 -0
- package/dist/react/index.js +612 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/layout.ts","../../src/react/utils.ts","../../src/react/Masonry.tsx","../../src/react/VirtualMasonry.tsx","../../src/react/useMasonryGrid.ts"],"names":["useRef","useState","Children","useMemo","useCallback","useEffect","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { LayoutInput, LayoutOutput, ItemPosition, ColumnStrategy } from './types';\n\n/**\n * Computes absolute positions for all items using the shortest-column algorithm.\n *\n * 1. Initialize N column heights to 0.\n * 2. columnWidth = (containerWidth - (columnCount - 1) * gap) / columnCount\n * 3. For each item: place in shortest column, update column height.\n * 4. totalHeight = max(columnHeights) - trailing gap.\n *\n * O(n * k) where n = items, k = columns. Effectively O(n) for typical k <= 10.\n */\nexport function computeLayout(input: LayoutInput): LayoutOutput {\n const { items, containerWidth, columnCount, gap } = input;\n\n if (columnCount <= 0 || containerWidth <= 0 || items.length === 0) {\n return { positions: [], columnHeights: [], totalHeight: 0 };\n }\n\n const columnWidth = (containerWidth - (columnCount - 1) * gap) / columnCount;\n const columnHeights = new Float64Array(columnCount);\n const positions: ItemPosition[] = new Array(items.length);\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n\n // Find shortest column (ties broken by leftmost)\n let shortestCol = 0;\n let shortestHeight = columnHeights[0];\n for (let c = 1; c < columnCount; c++) {\n if (columnHeights[c] < shortestHeight) {\n shortestHeight = columnHeights[c];\n shortestCol = c;\n }\n }\n\n const left = shortestCol * (columnWidth + gap);\n const top = columnHeights[shortestCol];\n\n positions[i] = {\n id: item.id,\n index: item.index,\n top,\n left,\n width: columnWidth,\n height: item.height,\n column: shortestCol,\n };\n\n columnHeights[shortestCol] = top + item.height + gap;\n }\n\n let maxHeight = 0;\n for (let c = 0; c < columnCount; c++) {\n if (columnHeights[c] > maxHeight) {\n maxHeight = columnHeights[c];\n }\n }\n const totalHeight = maxHeight > 0 ? maxHeight - gap : 0;\n\n return {\n positions,\n columnHeights: Array.from(columnHeights),\n totalHeight,\n };\n}\n\n/**\n * Determine column count given container width and strategy.\n */\nexport function resolveColumnCount(\n containerWidth: number,\n strategy: ColumnStrategy,\n gap: number,\n): number {\n if (strategy.type === 'fixed') {\n return Math.max(1, strategy.count);\n }\n if (strategy.type === 'responsive') {\n return resolveResponsiveColumns(containerWidth, strategy.breakpoints);\n }\n // auto: containerWidth >= n * minColumnWidth + (n-1) * gap\n // n <= (containerWidth + gap) / (minColumnWidth + gap)\n const count = Math.floor((containerWidth + gap) / (strategy.minColumnWidth + gap));\n return Math.max(1, count);\n}\n\n/**\n * Resolve column count from responsive breakpoints.\n * Breakpoints map container width thresholds to column counts.\n * Picks the largest breakpoint that containerWidth meets, or falls back to the smallest.\n */\nfunction resolveResponsiveColumns(\n containerWidth: number,\n breakpoints: Record<number, number>,\n): number {\n const entries = Object.keys(breakpoints)\n .map((w) => [Number(w), breakpoints[Number(w)]] as [number, number])\n .sort((a, b) => b[0] - a[0]); // descending by width\n\n for (const [minWidth, cols] of entries) {\n if (containerWidth >= minWidth) {\n return Math.max(1, cols);\n }\n }\n // Below all breakpoints: use the smallest breakpoint's column count\n return entries.length > 0 ? Math.max(1, entries[entries.length - 1][1]) : 1;\n}\n","import type { ColumnStrategy } from '../types';\nimport type { AnimateProp, AnimationConfig, ColumnsProp } from './types';\n\n/** Predefined breakpoint widths matching common CSS frameworks */\nexport const NAMED_BREAKPOINTS: Record<string, number> = {\n sm: 640,\n md: 768,\n lg: 1024,\n xl: 1280,\n};\n\n/**\n * Normalize all accepted column prop formats into a ColumnStrategy.\n * Handles: number, ColumnStrategy, named breakpoints, numeric breakpoints.\n */\nexport function resolveStrategy(columns: ColumnsProp | undefined): ColumnStrategy {\n if (columns === undefined) return { type: 'auto', minColumnWidth: 250 };\n if (typeof columns === 'number') return { type: 'fixed', count: columns };\n\n // Already a ColumnStrategy (has 'type' property)\n if ('type' in columns) return columns;\n\n // Object with breakpoint keys — named (sm/md/lg/xl) or numeric\n const breakpoints: Record<number, number> = {};\n for (const [key, value] of Object.entries(columns)) {\n const namedPx = NAMED_BREAKPOINTS[key];\n breakpoints[namedPx ?? Number(key)] = value;\n }\n\n return { type: 'responsive', breakpoints };\n}\n\n/**\n * Resolve animate prop into a full AnimationConfig or null.\n */\nexport function resolveAnimationConfig(animate: AnimateProp | undefined): AnimationConfig | null {\n if (!animate) return null;\n if (animate === true) {\n return { duration: 300, easing: 'ease-out', offset: 20 };\n }\n return {\n duration: animate.duration ?? 300,\n easing: animate.easing ?? 'ease-out',\n offset: animate.offset ?? 20,\n };\n}\n","import {\n Children,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from 'react';\nimport { computeLayout, resolveColumnCount } from '../layout';\nimport type { ItemPosition } from '../types';\nimport type { MasonryProps } from './types';\nimport { resolveStrategy, resolveAnimationConfig } from './utils';\n\n/**\n * React masonry layout component.\n * Measures children, computes shortest-column layout, positions via transforms.\n *\n * ```tsx\n * <Masonry columns={4} gap={16}>\n * {items.map(item => <Card key={item.id} />)}\n * </Masonry>\n * ```\n */\nexport function Masonry({\n children,\n columns,\n gap = 16,\n className,\n style,\n onLayout,\n animate,\n onReachEnd,\n reachEndThreshold = 200,\n}: MasonryProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n const [positions, setPositions] = useState<ItemPosition[]>([]);\n const [totalHeight, setTotalHeight] = useState(0);\n\n // Animation state\n const animConfig = resolveAnimationConfig(animate);\n const animatedRef = useRef<Set<number>>(new Set());\n const pendingAnimRef = useRef<Set<number>>(new Set());\n const [, forceUpdate] = useState(0);\n\n // onReachEnd state\n const sentinelRef = useRef<HTMLDivElement>(null);\n const reachEndFiredRef = useRef(false);\n\n const childArray = Children.toArray(children);\n const childCount = childArray.length;\n const strategy = resolveStrategy(columns);\n\n // Memoize strategy to avoid new object reference every render\n const stableStrategy = useMemo(() => strategy, [\n strategy.type,\n strategy.type === 'fixed' ? strategy.count : undefined,\n strategy.type === 'auto' ? strategy.minColumnWidth : undefined,\n strategy.type === 'responsive' ? JSON.stringify(strategy.breakpoints) : undefined,\n ]);\n\n const computePositions = useCallback(() => {\n const container = containerRef.current;\n if (!container || childCount === 0) return;\n\n const containerWidth = container.offsetWidth;\n if (containerWidth <= 0) return;\n\n const colCount = resolveColumnCount(containerWidth, stableStrategy, gap);\n\n const items = [];\n for (let i = 0; i < childCount; i++) {\n const el = itemRefs.current.get(i);\n const height = el ? el.offsetHeight : 0;\n items.push({ id: i, index: i, height });\n }\n\n const result = computeLayout({\n items,\n containerWidth,\n columnCount: colCount,\n gap,\n });\n\n setPositions(result.positions);\n setTotalHeight(result.totalHeight);\n onLayout?.(result);\n }, [childCount, gap, stableStrategy, onLayout]);\n\n // Observe container resize\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const ro = new ResizeObserver(() => computePositions());\n ro.observe(container);\n return () => ro.disconnect();\n }, [computePositions]);\n\n // Observe individual item resizes (images loading, dynamic content)\n useEffect(() => {\n const items = itemRefs.current;\n if (items.size === 0) return;\n\n const ro = new ResizeObserver(() => computePositions());\n for (const [, el] of items) {\n ro.observe(el);\n }\n return () => ro.disconnect();\n }, [childCount, computePositions]);\n\n // Initial layout\n useEffect(() => {\n computePositions();\n }, [computePositions]);\n\n // Animation: detect newly positioned items\n useEffect(() => {\n if (!animConfig || positions.length === 0) return;\n\n const newItems: number[] = [];\n for (let i = 0; i < positions.length; i++) {\n if (!animatedRef.current.has(i)) {\n animatedRef.current.add(i);\n pendingAnimRef.current.add(i);\n newItems.push(i);\n }\n }\n\n if (newItems.length === 0) return;\n\n // Force render with initial animation state (offset + opacity:0)\n forceUpdate((c) => c + 1);\n\n // Next frame: clear pending to trigger transition to final state\n requestAnimationFrame(() => {\n pendingAnimRef.current.clear();\n forceUpdate((c) => c + 1);\n });\n }, [positions, animConfig]);\n\n // onReachEnd: IntersectionObserver on sentinel\n useEffect(() => {\n reachEndFiredRef.current = false;\n }, [childCount]);\n\n useEffect(() => {\n if (!onReachEnd) return;\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !reachEndFiredRef.current) {\n reachEndFiredRef.current = true;\n onReachEnd();\n }\n },\n { rootMargin: `0px 0px ${reachEndThreshold}px 0px` },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onReachEnd, reachEndThreshold, totalHeight]);\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n overflow: 'hidden',\n height: totalHeight > 0 ? totalHeight : undefined,\n ...style,\n };\n\n return (\n <div ref={containerRef} className={className} style={containerStyle}>\n {childArray.map((child, index) => {\n const pos = positions[index];\n const isPending = animConfig && pendingAnimRef.current.has(index);\n const hasAnimated = animConfig && animatedRef.current.has(index);\n\n const itemStyle: CSSProperties = pos\n ? {\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translate3d(${pos.left}px, ${pos.top + (isPending ? (animConfig!.offset ?? 20) : 0)}px, 0)`,\n width: pos.width,\n willChange: 'transform',\n opacity: isPending ? 0 : 1,\n transition: hasAnimated\n ? `opacity ${animConfig!.duration}ms ${animConfig!.easing}, transform ${animConfig!.duration}ms ${animConfig!.easing}`\n : undefined,\n }\n : { visibility: 'hidden' as const };\n\n return (\n <div\n key={index}\n ref={(el) => {\n if (el) {\n itemRefs.current.set(index, el);\n } else {\n itemRefs.current.delete(index);\n }\n }}\n style={itemStyle}\n >\n {child}\n </div>\n );\n })}\n {onReachEnd && (\n <div\n ref={sentinelRef}\n style={{\n position: 'absolute',\n bottom: 0,\n height: 1,\n width: '100%',\n pointerEvents: 'none',\n }}\n />\n )}\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from 'react';\nimport { computeLayout, resolveColumnCount } from '../layout';\nimport type { ItemPosition } from '../types';\nimport type { VirtualMasonryProps } from './types';\nimport { resolveStrategy, resolveAnimationConfig } from './utils';\n\n/**\n * Find visible items using binary search over positions sorted by top.\n */\nfunction findVisibleItems(\n positions: ItemPosition[],\n sortedIndices: number[],\n scrollTop: number,\n viewportHeight: number,\n overscan: number,\n maxItemHeight: number,\n): number[] {\n if (sortedIndices.length === 0) return [];\n\n const rangeTop = scrollTop - overscan;\n const rangeBottom = scrollTop + viewportHeight + overscan;\n const searchTop = rangeTop - maxItemHeight;\n\n // Binary search for first item where top >= searchTop\n let lo = 0;\n let hi = sortedIndices.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (positions[sortedIndices[mid]].top < searchTop) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n const result: number[] = [];\n for (let i = lo; i < sortedIndices.length; i++) {\n const idx = sortedIndices[i];\n const pos = positions[idx];\n if (pos.top >= rangeBottom) break;\n if (pos.top + pos.height > rangeTop) {\n result.push(idx);\n }\n }\n\n return result;\n}\n\n/**\n * Virtualized masonry component for 1k+ items.\n * Only renders items visible in the viewport.\n *\n * ```tsx\n * <VirtualMasonry\n * totalItems={10000}\n * renderItem={(index) => <Card index={index} />}\n * height={600}\n * gap={16}\n * />\n * ```\n */\nexport function VirtualMasonry({\n totalItems,\n renderItem,\n columns,\n gap = 16,\n height,\n overscan = 600,\n estimatedItemHeight = 300,\n className,\n style,\n onLayout,\n animate,\n onReachEnd,\n reachEndThreshold = 200,\n placeholder,\n}: VirtualMasonryProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n const [heightMap, setHeightMap] = useState<Map<number, number>>(\n () => new Map(),\n );\n const [scrollTop, setScrollTop] = useState(0);\n const [containerWidth, setContainerWidth] = useState(0);\n\n // Animation state\n const animConfig = resolveAnimationConfig(animate);\n const animatedRef = useRef<Set<number>>(new Set());\n const pendingAnimRef = useRef<Set<number>>(new Set());\n const [, forceUpdate] = useState(0);\n\n // onReachEnd state\n const reachEndFiredRef = useRef(false);\n\n // Reset all accumulated state when totalItems changes\n const prevTotalItemsRef = useRef(totalItems);\n if (prevTotalItemsRef.current !== totalItems) {\n prevTotalItemsRef.current = totalItems;\n setHeightMap(new Map());\n animatedRef.current.clear();\n pendingAnimRef.current.clear();\n }\n\n const strategy = resolveStrategy(columns);\n\n // Memoize strategy to avoid new object reference every render\n const stableStrategy = useMemo(() => strategy, [\n strategy.type,\n strategy.type === 'fixed' ? strategy.count : undefined,\n strategy.type === 'auto' ? strategy.minColumnWidth : undefined,\n strategy.type === 'responsive' ? JSON.stringify(strategy.breakpoints) : undefined,\n ]);\n\n // Compute column count from container width\n const columnCount = useMemo(\n () => (containerWidth > 0 ? resolveColumnCount(containerWidth, stableStrategy, gap) : 1),\n [containerWidth, stableStrategy, gap],\n );\n\n // Build layout items with measured or estimated heights\n const layoutItems = useMemo(() => {\n const items = [];\n for (let i = 0; i < totalItems; i++) {\n items.push({\n id: i,\n index: i,\n height: heightMap.get(i) ?? estimatedItemHeight,\n });\n }\n return items;\n }, [totalItems, heightMap, estimatedItemHeight]);\n\n // Compute full layout\n const layout = useMemo(() => {\n if (containerWidth <= 0) return null;\n const result = computeLayout({\n items: layoutItems,\n containerWidth,\n columnCount,\n gap,\n });\n return result;\n }, [layoutItems, containerWidth, columnCount, gap]);\n\n // Fire onLayout callback\n useEffect(() => {\n if (layout) onLayout?.(layout);\n }, [layout, onLayout]);\n\n // Sorted indices for binary search\n const sortedIndices = useMemo(() => {\n if (!layout) return [];\n const indices = layout.positions.map((_, i) => i);\n indices.sort((a, b) => layout.positions[a].top - layout.positions[b].top);\n return indices;\n }, [layout]);\n\n // Max measured height for search adjustment\n const maxItemHeight = useMemo(() => {\n let max = estimatedItemHeight;\n for (const h of heightMap.values()) {\n if (h > max) max = h;\n }\n return max;\n }, [heightMap, estimatedItemHeight]);\n\n // Visible items\n const visibleIndices = useMemo(() => {\n if (!layout) return [];\n return findVisibleItems(\n layout.positions,\n sortedIndices,\n scrollTop,\n height,\n overscan,\n maxItemHeight,\n );\n }, [layout, sortedIndices, scrollTop, height, overscan, maxItemHeight]);\n\n // Observe container width\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const w =\n entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n setContainerWidth(w);\n }\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n // Observe rendered items for size changes (e.g. images loading, dynamic content)\n const itemRORef = useRef<ResizeObserver | null>(null);\n const observedRef = useRef<Set<HTMLDivElement>>(new Set());\n\n // Stable measurement callback that reads current refs\n const measureItems = useCallback(() => {\n const refs = itemRefs.current;\n if (refs.size === 0) return;\n\n setHeightMap((prev) => {\n let changed = false;\n const updates = new Map(prev);\n\n for (const [index, el] of refs) {\n const measured = el.offsetHeight;\n if (measured > 0 && measured !== updates.get(index)) {\n updates.set(index, measured);\n changed = true;\n }\n }\n\n return changed ? updates : prev;\n });\n }, []);\n\n // Create a single ResizeObserver for item elements\n useEffect(() => {\n const ro = new ResizeObserver(() => {\n measureItems();\n });\n itemRORef.current = ro;\n return () => {\n ro.disconnect();\n itemRORef.current = null;\n observedRef.current.clear();\n };\n }, [measureItems]);\n\n // Sync observed elements with currently rendered items\n useEffect(() => {\n const ro = itemRORef.current;\n if (!ro) return;\n\n const refs = itemRefs.current;\n const observed = observedRef.current;\n\n // Build a Set of current elements for O(1) lookup\n const currentEls = new Set<HTMLDivElement>();\n for (const [, el] of refs) {\n currentEls.add(el);\n if (!observed.has(el)) {\n ro.observe(el);\n observed.add(el);\n }\n }\n\n // Unobserve removed elements — O(n) instead of O(n*m)\n for (const el of observed) {\n if (!currentEls.has(el)) {\n ro.unobserve(el);\n observed.delete(el);\n }\n }\n });\n\n // Also measure on every render as a fallback\n useEffect(() => {\n measureItems();\n });\n\n // Reset onReachEnd when totalItems changes\n useEffect(() => {\n reachEndFiredRef.current = false;\n }, [totalItems]);\n\n const handleScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n\n const currentScrollTop = el.scrollTop;\n setScrollTop(currentScrollTop);\n\n // onReachEnd check\n if (onReachEnd && !reachEndFiredRef.current && layout) {\n if (currentScrollTop + height + reachEndThreshold >= layout.totalHeight) {\n reachEndFiredRef.current = true;\n onReachEnd();\n }\n }\n }, [onReachEnd, reachEndThreshold, height, layout]);\n\n // Animation: detect newly visible items\n useEffect(() => {\n if (!animConfig || visibleIndices.length === 0) return;\n\n const newItems: number[] = [];\n for (const idx of visibleIndices) {\n if (!animatedRef.current.has(idx)) {\n animatedRef.current.add(idx);\n pendingAnimRef.current.add(idx);\n newItems.push(idx);\n }\n }\n\n if (newItems.length === 0) return;\n\n forceUpdate((c) => c + 1);\n\n requestAnimationFrame(() => {\n pendingAnimRef.current.clear();\n forceUpdate((c) => c + 1);\n });\n }, [visibleIndices, animConfig]);\n\n const containerStyle: CSSProperties = {\n height,\n overflowY: 'auto',\n position: 'relative',\n ...style,\n };\n\n const innerStyle: CSSProperties = {\n position: 'relative',\n height: layout?.totalHeight ?? 0,\n width: '100%',\n };\n\n return (\n <div\n ref={scrollRef}\n className={className}\n style={containerStyle}\n onScroll={handleScroll}\n >\n <div style={innerStyle}>\n {visibleIndices.map((index) => {\n const pos = layout?.positions[index];\n if (!pos) return null;\n\n const isMeasured = heightMap.has(index);\n const isPending = animConfig && pendingAnimRef.current.has(index);\n const hasAnimated = animConfig && animatedRef.current.has(index);\n\n const itemStyle: CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translate3d(${pos.left}px, ${pos.top + (isPending ? (animConfig!.offset ?? 20) : 0)}px, 0)`,\n width: pos.width,\n willChange: 'transform',\n opacity: isPending ? 0 : 1,\n transition: hasAnimated\n ? `opacity ${animConfig!.duration}ms ${animConfig!.easing}, transform ${animConfig!.duration}ms ${animConfig!.easing}`\n : undefined,\n };\n\n return (\n <div\n key={index}\n ref={(el) => {\n if (el) {\n itemRefs.current.set(index, el);\n } else {\n itemRefs.current.delete(index);\n }\n }}\n style={itemStyle}\n >\n {placeholder && !isMeasured ? placeholder : renderItem(index)}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\nimport { computeLayout, resolveColumnCount } from '../layout';\nimport type { LayoutOutput } from '../types';\nimport type { UseMasonryGridOptions, UseMasonryGridReturn } from './types';\nimport { resolveStrategy } from './utils';\n\n/**\n * Low-level hook for full control over masonry layout.\n *\n * ```tsx\n * const { containerRef, layout, getItemStyle } = useMasonryGrid({ gap: 16, columns: 3 });\n * return (\n * <div ref={containerRef} style={{ position: 'relative', height: layout?.totalHeight }}>\n * {items.map((item, i) => (\n * <div key={item.id} style={getItemStyle(i)}>{item.content}</div>\n * ))}\n * </div>\n * );\n * ```\n */\nexport function useMasonryGrid(\n options: UseMasonryGridOptions = {},\n): UseMasonryGridReturn {\n const { columns, gap = 16, onLayout } = options;\n const strategy = resolveStrategy(columns);\n\n const containerElRef = useRef<HTMLElement | null>(null);\n const itemHeights = useRef<Map<number, number>>(new Map());\n const [layout, setLayout] = useState<LayoutOutput | null>(null);\n const [columnCount, setColumnCount] = useState(0);\n\n const compute = useCallback(() => {\n const container = containerElRef.current;\n if (!container) return;\n\n const containerWidth = container.offsetWidth;\n if (containerWidth <= 0) return;\n\n const colCount = resolveColumnCount(containerWidth, strategy, gap);\n setColumnCount(colCount);\n\n // Measure all direct children\n const children = Array.from(container.children) as HTMLElement[];\n const items = children.map((el, i) => ({\n id: i,\n index: i,\n height: itemHeights.current.get(i) ?? el.offsetHeight,\n }));\n\n if (items.length === 0) return;\n\n const result = computeLayout({\n items,\n containerWidth,\n columnCount: colCount,\n gap,\n });\n\n // Cache measured heights\n children.forEach((el, i) => {\n const h = el.offsetHeight;\n if (h > 0) itemHeights.current.set(i, h);\n });\n\n setLayout(result);\n onLayout?.(result);\n }, [gap, strategy, onLayout]);\n\n // Container ref callback — set up ResizeObserver when container is attached\n const containerRef = useCallback(\n (el: HTMLElement | null) => {\n containerElRef.current = el;\n if (!el) return;\n\n // Initial compute\n compute();\n\n // Observe container resize\n const ro = new ResizeObserver(() => compute());\n ro.observe(el);\n\n // Cleanup on unmount (will be called when ref changes)\n return () => ro.disconnect();\n },\n [compute],\n );\n\n // Re-observe children for size changes\n useEffect(() => {\n const container = containerElRef.current;\n if (!container) return;\n\n const ro = new ResizeObserver(() => compute());\n const children = Array.from(container.children) as HTMLElement[];\n for (const child of children) {\n ro.observe(child);\n }\n return () => ro.disconnect();\n }, [layout?.positions.length, compute]);\n\n const getItemStyle = useCallback(\n (index: number): CSSProperties => {\n const pos = layout?.positions[index];\n if (!pos) return { visibility: 'hidden' as const };\n return {\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translate3d(${pos.left}px, ${pos.top}px, 0)`,\n width: pos.width,\n willChange: 'transform',\n };\n },\n [layout],\n );\n\n const refresh = useCallback(() => {\n itemHeights.current.clear();\n compute();\n }, [compute]);\n\n return {\n containerRef,\n layout,\n columnCount,\n refresh,\n getItemStyle,\n };\n}\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode, CSSProperties, ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
/** Unique identifier for a masonry item */
|
|
5
|
+
type ItemId = string | number;
|
|
6
|
+
/** Computed position of a single item after layout */
|
|
7
|
+
interface ItemPosition {
|
|
8
|
+
id: ItemId;
|
|
9
|
+
index: number;
|
|
10
|
+
top: number;
|
|
11
|
+
left: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
column: number;
|
|
15
|
+
}
|
|
16
|
+
/** Layout engine output */
|
|
17
|
+
interface LayoutOutput {
|
|
18
|
+
positions: ItemPosition[];
|
|
19
|
+
columnHeights: number[];
|
|
20
|
+
totalHeight: number;
|
|
21
|
+
}
|
|
22
|
+
/** Column computation strategy */
|
|
23
|
+
type ColumnStrategy = {
|
|
24
|
+
type: 'fixed';
|
|
25
|
+
count: number;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'auto';
|
|
28
|
+
minColumnWidth: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'responsive';
|
|
31
|
+
breakpoints: Record<number, number>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** Predefined breakpoint names */
|
|
35
|
+
type BreakpointName = 'sm' | 'md' | 'lg' | 'xl';
|
|
36
|
+
/** Named breakpoints: { sm: 2, md: 3, lg: 4, xl: 5 } */
|
|
37
|
+
type NamedBreakpoints = Partial<Record<BreakpointName, number>>;
|
|
38
|
+
/** All accepted formats for the columns prop */
|
|
39
|
+
type ColumnsProp = number | ColumnStrategy | NamedBreakpoints | Record<number, number>;
|
|
40
|
+
/** Configuration for entry animations */
|
|
41
|
+
interface AnimationConfig {
|
|
42
|
+
/** Duration in milliseconds. Default: 300 */
|
|
43
|
+
duration?: number;
|
|
44
|
+
/** CSS easing function. Default: 'ease-out' */
|
|
45
|
+
easing?: string;
|
|
46
|
+
/** Initial vertical offset in pixels (slide-up distance). Default: 20 */
|
|
47
|
+
offset?: number;
|
|
48
|
+
}
|
|
49
|
+
/** animate prop: boolean shorthand or config object */
|
|
50
|
+
type AnimateProp = boolean | AnimationConfig;
|
|
51
|
+
interface MasonryProps {
|
|
52
|
+
/** Child elements to lay out in masonry pattern */
|
|
53
|
+
children: ReactNode;
|
|
54
|
+
/** Number of columns, strategy, or responsive breakpoints. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
55
|
+
columns?: ColumnsProp;
|
|
56
|
+
/** Gap between items in pixels. Default: 16 */
|
|
57
|
+
gap?: number;
|
|
58
|
+
/** Container className */
|
|
59
|
+
className?: string;
|
|
60
|
+
/** Container inline style */
|
|
61
|
+
style?: CSSProperties;
|
|
62
|
+
/** Callback when layout is computed */
|
|
63
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
64
|
+
/** Enable entry animations. Pass true for defaults or a config object. */
|
|
65
|
+
animate?: AnimateProp;
|
|
66
|
+
/** Callback when user scrolls near the bottom. Useful for infinite scroll. */
|
|
67
|
+
onReachEnd?: () => void;
|
|
68
|
+
/** Pixels from bottom to trigger onReachEnd. Default: 200 */
|
|
69
|
+
reachEndThreshold?: number;
|
|
70
|
+
}
|
|
71
|
+
interface VirtualMasonryProps {
|
|
72
|
+
/** Total number of items */
|
|
73
|
+
totalItems: number;
|
|
74
|
+
/** Render function for each item */
|
|
75
|
+
renderItem: (index: number) => ReactElement;
|
|
76
|
+
/** Number of columns, strategy, or responsive breakpoints. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
77
|
+
columns?: ColumnsProp;
|
|
78
|
+
/** Gap between items in pixels. Default: 16 */
|
|
79
|
+
gap?: number;
|
|
80
|
+
/** Container height in pixels (required for scroll container) */
|
|
81
|
+
height: number;
|
|
82
|
+
/** Pixels above/below viewport to pre-render. Default: 600 */
|
|
83
|
+
overscan?: number;
|
|
84
|
+
/** Estimated item height for unmeasured items. Default: 300 */
|
|
85
|
+
estimatedItemHeight?: number;
|
|
86
|
+
/** Container className */
|
|
87
|
+
className?: string;
|
|
88
|
+
/** Container inline style */
|
|
89
|
+
style?: CSSProperties;
|
|
90
|
+
/** Callback when layout is computed */
|
|
91
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
92
|
+
/** Enable entry animations. Pass true for defaults or a config object. */
|
|
93
|
+
animate?: AnimateProp;
|
|
94
|
+
/** Callback when user scrolls near the bottom. Useful for infinite scroll. */
|
|
95
|
+
onReachEnd?: () => void;
|
|
96
|
+
/** Pixels from bottom to trigger onReachEnd. Default: 200 */
|
|
97
|
+
reachEndThreshold?: number;
|
|
98
|
+
/** Placeholder element to show for unmeasured items */
|
|
99
|
+
placeholder?: ReactElement;
|
|
100
|
+
}
|
|
101
|
+
interface UseMasonryGridOptions {
|
|
102
|
+
/** Number of columns, strategy, or responsive breakpoints */
|
|
103
|
+
columns?: ColumnsProp;
|
|
104
|
+
/** Gap between items in pixels. Default: 16 */
|
|
105
|
+
gap?: number;
|
|
106
|
+
/** Callback when layout is computed */
|
|
107
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
108
|
+
}
|
|
109
|
+
interface UseMasonryGridReturn {
|
|
110
|
+
/** Ref to attach to the container div */
|
|
111
|
+
containerRef: React.RefCallback<HTMLElement>;
|
|
112
|
+
/** Current layout output (null before first compute) */
|
|
113
|
+
layout: LayoutOutput | null;
|
|
114
|
+
/** Current column count */
|
|
115
|
+
columnCount: number;
|
|
116
|
+
/** Force a relayout */
|
|
117
|
+
refresh: () => void;
|
|
118
|
+
/** Get a position style for a specific item index */
|
|
119
|
+
getItemStyle: (index: number) => CSSProperties;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* React masonry layout component.
|
|
124
|
+
* Measures children, computes shortest-column layout, positions via transforms.
|
|
125
|
+
*
|
|
126
|
+
* ```tsx
|
|
127
|
+
* <Masonry columns={4} gap={16}>
|
|
128
|
+
* {items.map(item => <Card key={item.id} />)}
|
|
129
|
+
* </Masonry>
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare function Masonry({ children, columns, gap, className, style, onLayout, animate, onReachEnd, reachEndThreshold, }: MasonryProps): react_jsx_runtime.JSX.Element;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Virtualized masonry component for 1k+ items.
|
|
136
|
+
* Only renders items visible in the viewport.
|
|
137
|
+
*
|
|
138
|
+
* ```tsx
|
|
139
|
+
* <VirtualMasonry
|
|
140
|
+
* totalItems={10000}
|
|
141
|
+
* renderItem={(index) => <Card index={index} />}
|
|
142
|
+
* height={600}
|
|
143
|
+
* gap={16}
|
|
144
|
+
* />
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function VirtualMasonry({ totalItems, renderItem, columns, gap, height, overscan, estimatedItemHeight, className, style, onLayout, animate, onReachEnd, reachEndThreshold, placeholder, }: VirtualMasonryProps): react_jsx_runtime.JSX.Element;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Low-level hook for full control over masonry layout.
|
|
151
|
+
*
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { containerRef, layout, getItemStyle } = useMasonryGrid({ gap: 16, columns: 3 });
|
|
154
|
+
* return (
|
|
155
|
+
* <div ref={containerRef} style={{ position: 'relative', height: layout?.totalHeight }}>
|
|
156
|
+
* {items.map((item, i) => (
|
|
157
|
+
* <div key={item.id} style={getItemStyle(i)}>{item.content}</div>
|
|
158
|
+
* ))}
|
|
159
|
+
* </div>
|
|
160
|
+
* );
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function useMasonryGrid(options?: UseMasonryGridOptions): UseMasonryGridReturn;
|
|
164
|
+
|
|
165
|
+
export { type AnimateProp, type AnimationConfig, type ColumnStrategy, type ColumnsProp, type ItemPosition, type LayoutOutput, Masonry, type MasonryProps, type NamedBreakpoints, type UseMasonryGridOptions, type UseMasonryGridReturn, VirtualMasonry, type VirtualMasonryProps, useMasonryGrid };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode, CSSProperties, ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
/** Unique identifier for a masonry item */
|
|
5
|
+
type ItemId = string | number;
|
|
6
|
+
/** Computed position of a single item after layout */
|
|
7
|
+
interface ItemPosition {
|
|
8
|
+
id: ItemId;
|
|
9
|
+
index: number;
|
|
10
|
+
top: number;
|
|
11
|
+
left: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
column: number;
|
|
15
|
+
}
|
|
16
|
+
/** Layout engine output */
|
|
17
|
+
interface LayoutOutput {
|
|
18
|
+
positions: ItemPosition[];
|
|
19
|
+
columnHeights: number[];
|
|
20
|
+
totalHeight: number;
|
|
21
|
+
}
|
|
22
|
+
/** Column computation strategy */
|
|
23
|
+
type ColumnStrategy = {
|
|
24
|
+
type: 'fixed';
|
|
25
|
+
count: number;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'auto';
|
|
28
|
+
minColumnWidth: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'responsive';
|
|
31
|
+
breakpoints: Record<number, number>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** Predefined breakpoint names */
|
|
35
|
+
type BreakpointName = 'sm' | 'md' | 'lg' | 'xl';
|
|
36
|
+
/** Named breakpoints: { sm: 2, md: 3, lg: 4, xl: 5 } */
|
|
37
|
+
type NamedBreakpoints = Partial<Record<BreakpointName, number>>;
|
|
38
|
+
/** All accepted formats for the columns prop */
|
|
39
|
+
type ColumnsProp = number | ColumnStrategy | NamedBreakpoints | Record<number, number>;
|
|
40
|
+
/** Configuration for entry animations */
|
|
41
|
+
interface AnimationConfig {
|
|
42
|
+
/** Duration in milliseconds. Default: 300 */
|
|
43
|
+
duration?: number;
|
|
44
|
+
/** CSS easing function. Default: 'ease-out' */
|
|
45
|
+
easing?: string;
|
|
46
|
+
/** Initial vertical offset in pixels (slide-up distance). Default: 20 */
|
|
47
|
+
offset?: number;
|
|
48
|
+
}
|
|
49
|
+
/** animate prop: boolean shorthand or config object */
|
|
50
|
+
type AnimateProp = boolean | AnimationConfig;
|
|
51
|
+
interface MasonryProps {
|
|
52
|
+
/** Child elements to lay out in masonry pattern */
|
|
53
|
+
children: ReactNode;
|
|
54
|
+
/** Number of columns, strategy, or responsive breakpoints. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
55
|
+
columns?: ColumnsProp;
|
|
56
|
+
/** Gap between items in pixels. Default: 16 */
|
|
57
|
+
gap?: number;
|
|
58
|
+
/** Container className */
|
|
59
|
+
className?: string;
|
|
60
|
+
/** Container inline style */
|
|
61
|
+
style?: CSSProperties;
|
|
62
|
+
/** Callback when layout is computed */
|
|
63
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
64
|
+
/** Enable entry animations. Pass true for defaults or a config object. */
|
|
65
|
+
animate?: AnimateProp;
|
|
66
|
+
/** Callback when user scrolls near the bottom. Useful for infinite scroll. */
|
|
67
|
+
onReachEnd?: () => void;
|
|
68
|
+
/** Pixels from bottom to trigger onReachEnd. Default: 200 */
|
|
69
|
+
reachEndThreshold?: number;
|
|
70
|
+
}
|
|
71
|
+
interface VirtualMasonryProps {
|
|
72
|
+
/** Total number of items */
|
|
73
|
+
totalItems: number;
|
|
74
|
+
/** Render function for each item */
|
|
75
|
+
renderItem: (index: number) => ReactElement;
|
|
76
|
+
/** Number of columns, strategy, or responsive breakpoints. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
77
|
+
columns?: ColumnsProp;
|
|
78
|
+
/** Gap between items in pixels. Default: 16 */
|
|
79
|
+
gap?: number;
|
|
80
|
+
/** Container height in pixels (required for scroll container) */
|
|
81
|
+
height: number;
|
|
82
|
+
/** Pixels above/below viewport to pre-render. Default: 600 */
|
|
83
|
+
overscan?: number;
|
|
84
|
+
/** Estimated item height for unmeasured items. Default: 300 */
|
|
85
|
+
estimatedItemHeight?: number;
|
|
86
|
+
/** Container className */
|
|
87
|
+
className?: string;
|
|
88
|
+
/** Container inline style */
|
|
89
|
+
style?: CSSProperties;
|
|
90
|
+
/** Callback when layout is computed */
|
|
91
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
92
|
+
/** Enable entry animations. Pass true for defaults or a config object. */
|
|
93
|
+
animate?: AnimateProp;
|
|
94
|
+
/** Callback when user scrolls near the bottom. Useful for infinite scroll. */
|
|
95
|
+
onReachEnd?: () => void;
|
|
96
|
+
/** Pixels from bottom to trigger onReachEnd. Default: 200 */
|
|
97
|
+
reachEndThreshold?: number;
|
|
98
|
+
/** Placeholder element to show for unmeasured items */
|
|
99
|
+
placeholder?: ReactElement;
|
|
100
|
+
}
|
|
101
|
+
interface UseMasonryGridOptions {
|
|
102
|
+
/** Number of columns, strategy, or responsive breakpoints */
|
|
103
|
+
columns?: ColumnsProp;
|
|
104
|
+
/** Gap between items in pixels. Default: 16 */
|
|
105
|
+
gap?: number;
|
|
106
|
+
/** Callback when layout is computed */
|
|
107
|
+
onLayout?: (output: LayoutOutput) => void;
|
|
108
|
+
}
|
|
109
|
+
interface UseMasonryGridReturn {
|
|
110
|
+
/** Ref to attach to the container div */
|
|
111
|
+
containerRef: React.RefCallback<HTMLElement>;
|
|
112
|
+
/** Current layout output (null before first compute) */
|
|
113
|
+
layout: LayoutOutput | null;
|
|
114
|
+
/** Current column count */
|
|
115
|
+
columnCount: number;
|
|
116
|
+
/** Force a relayout */
|
|
117
|
+
refresh: () => void;
|
|
118
|
+
/** Get a position style for a specific item index */
|
|
119
|
+
getItemStyle: (index: number) => CSSProperties;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* React masonry layout component.
|
|
124
|
+
* Measures children, computes shortest-column layout, positions via transforms.
|
|
125
|
+
*
|
|
126
|
+
* ```tsx
|
|
127
|
+
* <Masonry columns={4} gap={16}>
|
|
128
|
+
* {items.map(item => <Card key={item.id} />)}
|
|
129
|
+
* </Masonry>
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare function Masonry({ children, columns, gap, className, style, onLayout, animate, onReachEnd, reachEndThreshold, }: MasonryProps): react_jsx_runtime.JSX.Element;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Virtualized masonry component for 1k+ items.
|
|
136
|
+
* Only renders items visible in the viewport.
|
|
137
|
+
*
|
|
138
|
+
* ```tsx
|
|
139
|
+
* <VirtualMasonry
|
|
140
|
+
* totalItems={10000}
|
|
141
|
+
* renderItem={(index) => <Card index={index} />}
|
|
142
|
+
* height={600}
|
|
143
|
+
* gap={16}
|
|
144
|
+
* />
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function VirtualMasonry({ totalItems, renderItem, columns, gap, height, overscan, estimatedItemHeight, className, style, onLayout, animate, onReachEnd, reachEndThreshold, placeholder, }: VirtualMasonryProps): react_jsx_runtime.JSX.Element;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Low-level hook for full control over masonry layout.
|
|
151
|
+
*
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { containerRef, layout, getItemStyle } = useMasonryGrid({ gap: 16, columns: 3 });
|
|
154
|
+
* return (
|
|
155
|
+
* <div ref={containerRef} style={{ position: 'relative', height: layout?.totalHeight }}>
|
|
156
|
+
* {items.map((item, i) => (
|
|
157
|
+
* <div key={item.id} style={getItemStyle(i)}>{item.content}</div>
|
|
158
|
+
* ))}
|
|
159
|
+
* </div>
|
|
160
|
+
* );
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function useMasonryGrid(options?: UseMasonryGridOptions): UseMasonryGridReturn;
|
|
164
|
+
|
|
165
|
+
export { type AnimateProp, type AnimationConfig, type ColumnStrategy, type ColumnsProp, type ItemPosition, type LayoutOutput, Masonry, type MasonryProps, type NamedBreakpoints, type UseMasonryGridOptions, type UseMasonryGridReturn, VirtualMasonry, type VirtualMasonryProps, useMasonryGrid };
|