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/virtualizer.ts","../src/observers.ts","../src/styles.ts","../src/utils.ts","../src/masonry.ts"],"names":["item"],"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 { ItemPosition, VisibleRange, VirtualizerConfig, ItemId } from './types';\n\nconst DEFAULT_CONFIG: VirtualizerConfig = {\n overscan: 600,\n estimatedItemHeight: 300,\n};\n\n/**\n * Manages which items are in the DOM based on scroll position.\n * Uses binary search over sorted positions for O(log n) visible range lookup.\n */\nexport class Virtualizer {\n private config: VirtualizerConfig;\n private positions: ItemPosition[] = [];\n private sortedByTop: number[] = [];\n private renderedIndices: Set<number> = new Set();\n private heightEstimates: Map<ItemId, number> = new Map();\n private scrollTop = 0;\n private viewportHeight = 0;\n private totalHeight = 0;\n private maxMeasuredHeight = 0;\n private scrollRafId: number | null = null;\n\n private onRenderItem: (index: number, position: ItemPosition) => void;\n private onRecycleItem: (index: number) => void;\n\n constructor(\n config: Partial<VirtualizerConfig>,\n onRenderItem: (index: number, position: ItemPosition) => void,\n onRecycleItem: (index: number) => void,\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.onRenderItem = onRenderItem;\n this.onRecycleItem = onRecycleItem;\n }\n\n /** Update positions after layout recomputation */\n updatePositions(positions: ItemPosition[], totalHeight: number): void {\n this.positions = positions;\n this.totalHeight = totalHeight;\n this.rebuildSortedIndex();\n this.update();\n }\n\n private rebuildSortedIndex(): void {\n this.sortedByTop = this.positions.map((_, i) => i);\n this.sortedByTop.sort((a, b) => this.positions[a].top - this.positions[b].top);\n }\n\n /** Handle scroll event (throttled via rAF) */\n onScroll(scrollTop: number, viewportHeight: number): void {\n this.scrollTop = scrollTop;\n this.viewportHeight = viewportHeight;\n\n if (this.scrollRafId !== null) return;\n this.scrollRafId = requestAnimationFrame(() => {\n this.scrollRafId = null;\n this.update();\n });\n }\n\n /** Core: diff visible set and mount/unmount items */\n private update(): void {\n const { overscan } = this.config;\n const rangeTop = this.scrollTop - overscan;\n const rangeBottom = this.scrollTop + this.viewportHeight + overscan;\n\n const visibleIndices = this.findVisibleIndices(rangeTop, rangeBottom);\n const visibleSet = new Set(visibleIndices);\n\n // Remove items no longer visible\n for (const idx of this.renderedIndices) {\n if (!visibleSet.has(idx)) {\n this.onRecycleItem(idx);\n }\n }\n\n // Add newly visible items\n for (const idx of visibleIndices) {\n if (!this.renderedIndices.has(idx)) {\n const position = this.positions[idx];\n if (position) {\n this.onRenderItem(idx, position);\n }\n }\n }\n\n this.renderedIndices = visibleSet;\n }\n\n /**\n * Binary search to find items in [rangeTop, rangeBottom].\n * An item is visible if: item.top + item.height > rangeTop AND item.top < rangeBottom\n */\n private findVisibleIndices(rangeTop: number, rangeBottom: number): number[] {\n const sorted = this.sortedByTop;\n const positions = this.positions;\n if (sorted.length === 0) return [];\n\n const searchTop =\n rangeTop - Math.max(this.maxMeasuredHeight, this.config.estimatedItemHeight);\n\n // Binary search: first index where positions[sorted[i]].top >= searchTop\n let lo = 0;\n let hi = sorted.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (positions[sorted[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 < sorted.length; i++) {\n const idx = sorted[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 /** Record a measured height */\n recordMeasurement(id: ItemId, height: number): void {\n this.heightEstimates.set(id, height);\n if (height > this.maxMeasuredHeight) {\n this.maxMeasuredHeight = height;\n }\n }\n\n /** Get current visible range */\n getVisibleRange(): VisibleRange {\n if (this.renderedIndices.size === 0) {\n return { startIndex: 0, endIndex: 0 };\n }\n let min = Infinity;\n let max = -Infinity;\n for (const idx of this.renderedIndices) {\n if (idx < min) min = idx;\n if (idx > max) max = idx;\n }\n return { startIndex: min, endIndex: max };\n }\n\n getTotalHeight(): number {\n return this.totalHeight;\n }\n\n destroy(): void {\n if (this.scrollRafId !== null) {\n cancelAnimationFrame(this.scrollRafId);\n }\n this.renderedIndices.clear();\n this.heightEstimates.clear();\n this.positions = [];\n this.sortedByTop = [];\n }\n}\n","import type { ItemId } from './types';\n\nexport interface ObserverCallbacks {\n onContainerResize: (width: number, height: number) => void;\n onItemResize: (id: ItemId, element: HTMLElement, width: number, height: number) => void;\n}\n\n/**\n * Manages a single shared ResizeObserver for ALL items.\n * Uses WeakMap<HTMLElement, ItemId> so entries are GC'd when elements are removed.\n * Batches item resize callbacks via queueMicrotask to prevent layout thrashing.\n */\nexport class ObserverManager {\n private containerObserver: ResizeObserver | null = null;\n private itemObserver: ResizeObserver | null = null;\n private elementToId: WeakMap<HTMLElement, ItemId> = new WeakMap();\n private callbacks: ObserverCallbacks;\n private pendingItemResizes: Map<\n ItemId,\n { element: HTMLElement; width: number; height: number }\n > = new Map();\n private batchScheduled = false;\n\n constructor(callbacks: ObserverCallbacks) {\n this.callbacks = callbacks;\n }\n\n /** Observe container for width changes */\n observeContainer(container: HTMLElement): void {\n this.containerObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width =\n entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n const height =\n entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height;\n this.callbacks.onContainerResize(width, height);\n }\n });\n this.containerObserver.observe(container);\n }\n\n /** Initialize the shared item observer (lazy) */\n private initItemObserver(): void {\n this.itemObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n const id = this.elementToId.get(element);\n if (id === undefined) continue;\n\n const height =\n entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height;\n const width =\n entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n\n this.pendingItemResizes.set(id, { element, width, height });\n }\n\n if (!this.batchScheduled) {\n this.batchScheduled = true;\n queueMicrotask(() => {\n this.batchScheduled = false;\n const batch = new Map(this.pendingItemResizes);\n this.pendingItemResizes.clear();\n for (const [id, { element, width, height }] of batch) {\n this.callbacks.onItemResize(id, element, width, height);\n }\n });\n }\n });\n }\n\n /** Observe a single item element */\n observeItem(element: HTMLElement, id: ItemId): void {\n if (!this.itemObserver) this.initItemObserver();\n this.elementToId.set(element, id);\n this.itemObserver!.observe(element);\n }\n\n /** Stop observing a single item element */\n unobserveItem(element: HTMLElement): void {\n this.elementToId.delete(element);\n this.itemObserver?.unobserve(element);\n }\n\n /** Clean up everything */\n destroy(): void {\n this.containerObserver?.disconnect();\n this.itemObserver?.disconnect();\n this.containerObserver = null;\n this.itemObserver = null;\n this.elementToId = new WeakMap();\n this.pendingItemResizes.clear();\n }\n}\n","const STYLE_ID = 'smart-masonry-grid-styles';\n\n/**\n * Injects a <style> tag with base styles (idempotent).\n * Called once on first MasonryGrid instantiation.\n */\nexport function injectBaseStyles(prefix: string = 'smg'): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID)) return;\n\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = `\n .${prefix}-container--ssr {\n column-gap: var(--${prefix}-gap, 16px);\n column-count: var(--${prefix}-columns, 3);\n }\n .${prefix}-container--ssr > .${prefix}-item {\n break-inside: avoid;\n margin-bottom: var(--${prefix}-gap, 16px);\n }\n .${prefix}-container--js {\n position: relative;\n overflow: hidden;\n }\n .${prefix}-container--js > .${prefix}-item {\n position: absolute;\n top: 0;\n left: 0;\n will-change: transform;\n }\n .${prefix}-container--transitioning > .${prefix}-item {\n transition: transform 0.2s ease-out, opacity 0.2s ease-out;\n }\n `;\n document.head.appendChild(style);\n}\n\n/**\n * Returns a CSS string for SSR <head> injection.\n * Use this on the server to include styles without JS.\n */\nexport function getSSRStyles(\n prefix: string = 'smg',\n columns: number = 3,\n gap: number = 16,\n): string {\n return `.${prefix}-container--ssr{column-gap:${gap}px;column-count:${columns}}.${prefix}-container--ssr>.${prefix}-item{break-inside:avoid;margin-bottom:${gap}px}`;\n}\n","let idCounter = 0;\n\n/** Generate a unique ID for masonry items */\nexport function generateId(): string {\n return `smg-${++idCounter}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/** Debounce a function with cancel support */\nexport function debounce<T extends (...args: never[]) => void>(\n fn: T,\n delayMs: number,\n): T & { cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const debounced = function (this: unknown, ...args: Parameters<T>) {\n if (timeoutId !== null) clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n timeoutId = null;\n fn.apply(this, args);\n }, delayMs);\n } as T & { cancel: () => void };\n\n debounced.cancel = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n return debounced;\n}\n","import type {\n MasonryGridOptions,\n MasonryGridEvents,\n MasonryEventName,\n ItemPosition,\n LayoutOutput,\n MeasuredItem,\n ItemId,\n ColumnStrategy,\n VirtualizerConfig,\n} from './types';\nimport { computeLayout, resolveColumnCount } from './layout';\nimport { Virtualizer } from './virtualizer';\nimport { ObserverManager } from './observers';\nimport { injectBaseStyles } from './styles';\nimport { debounce, generateId } from './utils';\n\ninterface ResolvedOptions {\n columns: ColumnStrategy;\n gap: number;\n virtualize: boolean;\n virtualizer: VirtualizerConfig;\n renderItem: ((index: number) => HTMLElement) | null;\n totalItems: number;\n ssrFallback: boolean;\n classPrefix: string;\n resizeDebounceMs: number;\n}\n\nfunction resolveOptions(options: Partial<MasonryGridOptions>): ResolvedOptions {\n const gap = options.gap ?? 16;\n let columns: ColumnStrategy;\n if (typeof options.columns === 'number') {\n columns = { type: 'fixed', count: options.columns };\n } else if (options.columns) {\n columns = options.columns;\n } else {\n columns = { type: 'auto', minColumnWidth: 250 };\n }\n\n return {\n columns,\n gap,\n virtualize: options.virtualize ?? true,\n virtualizer: {\n overscan: options.virtualizer?.overscan ?? 600,\n estimatedItemHeight: options.virtualizer?.estimatedItemHeight ?? 300,\n },\n renderItem: options.renderItem ?? null,\n totalItems: options.totalItems ?? 0,\n ssrFallback: options.ssrFallback ?? false,\n classPrefix: options.classPrefix ?? 'smg',\n resizeDebounceMs: options.resizeDebounceMs ?? 100,\n };\n}\n\nexport class MasonryGrid {\n private container: HTMLElement;\n private opts: ResolvedOptions;\n private prefix: string;\n\n // State\n private items: MeasuredItem[] = [];\n private itemMap: Map<ItemId, MeasuredItem> = new Map();\n private elementMap: Map<ItemId, HTMLElement> = new Map();\n private indexToElement: Map<number, HTMLElement> = new Map();\n private currentLayout: LayoutOutput | null = null;\n private containerWidth = 0;\n private columnCount = 0;\n private isDestroyed = false;\n\n // Subsystems\n private virtualizer: Virtualizer | null = null;\n private observers: ObserverManager;\n private scrollContainer: HTMLElement | Window;\n\n // Events\n private listeners: Map<MasonryEventName, Set<Function>> = new Map();\n\n // Debounced\n private debouncedRelayout: (() => void) & { cancel: () => void };\n private boundScrollHandler: (() => void) | null = null;\n\n constructor(container: HTMLElement, options: Partial<MasonryGridOptions> = {}) {\n this.container = container;\n this.opts = resolveOptions(options);\n this.prefix = this.opts.classPrefix;\n\n injectBaseStyles(this.prefix);\n\n this.observers = new ObserverManager({\n onContainerResize: (width) => this.handleContainerResize(width),\n onItemResize: (id, _element, _width, height) =>\n this.handleItemResize(id, height),\n });\n\n this.debouncedRelayout = debounce(() => {\n this.relayout();\n this.applyPositions();\n }, this.opts.resizeDebounceMs);\n\n this.scrollContainer = this.findScrollParent(container) ?? window;\n\n this.init();\n }\n\n // ==================== INITIALIZATION ====================\n\n private init(): void {\n const isSSR = this.container.classList.contains(\n `${this.prefix}-container--ssr`,\n );\n\n this.observers.observeContainer(this.container);\n this.containerWidth = this.container.offsetWidth;\n this.columnCount = resolveColumnCount(\n this.containerWidth,\n this.opts.columns,\n this.opts.gap,\n );\n\n if (isSSR) {\n this.hydrateFromSSR();\n } else if (\n this.opts.virtualize &&\n this.opts.renderItem &&\n this.opts.totalItems > 0\n ) {\n this.container.classList.add(`${this.prefix}-container--js`);\n this.initVirtualized();\n } else {\n this.container.classList.add(`${this.prefix}-container--js`);\n this.initFromExistingChildren();\n }\n }\n\n private hydrateFromSSR(): void {\n const children = Array.from(this.container.children) as HTMLElement[];\n this.collectItems(children);\n this.relayout();\n\n requestAnimationFrame(() => {\n this.container.classList.add(`${this.prefix}-container--transitioning`);\n this.container.classList.remove(`${this.prefix}-container--ssr`);\n this.container.classList.add(`${this.prefix}-container--js`);\n this.applyPositions();\n\n setTimeout(() => {\n this.container.classList.remove(\n `${this.prefix}-container--transitioning`,\n );\n }, 250);\n });\n }\n\n private initFromExistingChildren(): void {\n const children = Array.from(this.container.children) as HTMLElement[];\n if (children.length > 0) {\n this.collectItems(children);\n this.relayout();\n this.applyPositions();\n }\n }\n\n private initVirtualized(): void {\n this.virtualizer = new Virtualizer(\n this.opts.virtualizer,\n (index, position) => this.renderVirtualItem(index, position),\n (index) => this.recycleVirtualItem(index),\n );\n\n const estimatedHeight = this.opts.virtualizer.estimatedItemHeight;\n for (let i = 0; i < this.opts.totalItems; i++) {\n this.items.push({\n id: i,\n index: i,\n element: null,\n height: estimatedHeight,\n measured: false,\n });\n }\n\n this.relayout();\n this.bindScrollListener();\n }\n\n // ==================== LAYOUT ====================\n\n private relayout(): void {\n if (this.isDestroyed) return;\n\n const layoutItems = this.items.map((item) => ({\n id: item.id,\n index: item.index,\n height: item.height,\n }));\n\n this.currentLayout = computeLayout({\n items: layoutItems,\n containerWidth: this.containerWidth,\n columnCount: this.columnCount,\n gap: this.opts.gap,\n });\n\n this.container.style.height = `${this.currentLayout.totalHeight}px`;\n\n if (this.virtualizer) {\n this.virtualizer.updatePositions(\n this.currentLayout.positions,\n this.currentLayout.totalHeight,\n );\n }\n\n this.emit('layout', this.currentLayout);\n }\n\n private applyPositions(): void {\n if (!this.currentLayout) return;\n\n for (const pos of this.currentLayout.positions) {\n const element = this.elementMap.get(pos.id);\n if (!element) continue;\n\n element.style.transform = `translate3d(${pos.left}px, ${pos.top}px, 0)`;\n element.style.width = `${pos.width}px`;\n }\n }\n\n // ==================== VIRTUAL ITEM LIFECYCLE ====================\n\n private renderVirtualItem(index: number, position: ItemPosition): void {\n let element = this.indexToElement.get(index);\n if (!element) {\n element = this.opts.renderItem!(index);\n element.classList.add(`${this.prefix}-item`);\n this.container.appendChild(element);\n this.indexToElement.set(index, element);\n this.elementMap.set(position.id, element);\n this.observers.observeItem(element, position.id);\n }\n\n element.style.transform = `translate3d(${position.left}px, ${position.top}px, 0)`;\n element.style.width = `${position.width}px`;\n element.style.display = '';\n\n // Measure after render\n requestAnimationFrame(() => {\n if (this.isDestroyed || !element) return;\n const measuredHeight = element.offsetHeight;\n const item = this.items[index];\n if (item && !item.measured && Math.abs(item.height - measuredHeight) > 1) {\n item.height = measuredHeight;\n item.measured = true;\n this.virtualizer?.recordMeasurement(position.id, measuredHeight);\n this.relayout();\n }\n });\n }\n\n private recycleVirtualItem(index: number): void {\n const element = this.indexToElement.get(index);\n if (element) {\n element.style.display = 'none';\n this.observers.unobserveItem(element);\n }\n }\n\n // ==================== OBSERVER HANDLERS ====================\n\n private handleContainerResize(width: number): void {\n if (Math.abs(width - this.containerWidth) < 1) return;\n\n this.containerWidth = width;\n this.columnCount = resolveColumnCount(\n width,\n this.opts.columns,\n this.opts.gap,\n );\n\n this.debouncedRelayout();\n this.emit('resize', width, this.columnCount);\n }\n\n private handleItemResize(id: ItemId, newHeight: number): void {\n const item = this.itemMap.get(id);\n if (!item) return;\n\n const oldHeight = item.height;\n if (Math.abs(oldHeight - newHeight) < 1) return;\n\n item.height = newHeight;\n item.measured = true;\n\n this.emit('itemResize', id, oldHeight, newHeight);\n this.debouncedRelayout();\n }\n\n // ==================== SCROLL ====================\n\n private bindScrollListener(): void {\n this.boundScrollHandler = () => {\n const scrollTop =\n this.scrollContainer === window\n ? window.scrollY\n : (this.scrollContainer as HTMLElement).scrollTop;\n const viewportHeight =\n this.scrollContainer === window\n ? window.innerHeight\n : (this.scrollContainer as HTMLElement).clientHeight;\n\n this.virtualizer?.onScroll(scrollTop, viewportHeight);\n\n const visibleRange = this.virtualizer?.getVisibleRange() ?? {\n startIndex: 0,\n endIndex: 0,\n };\n this.emit('scroll', scrollTop, visibleRange);\n };\n\n this.scrollContainer.addEventListener('scroll', this.boundScrollHandler, {\n passive: true,\n });\n\n // Trigger initial render\n this.boundScrollHandler();\n }\n\n // ==================== PUBLIC API ====================\n\n /** Add items to the end of the grid */\n append(elements: HTMLElement[]): void {\n const startIndex = this.items.length;\n this.collectItems(elements, startIndex);\n this.relayout();\n this.applyPositions();\n }\n\n /** Add items to the beginning of the grid */\n prepend(elements: HTMLElement[]): void {\n const newItems: MeasuredItem[] = [];\n elements.forEach((el, i) => {\n const id = generateId();\n el.classList.add(`${this.prefix}-item`);\n this.container.prepend(el);\n const height =\n el.offsetHeight || this.opts.virtualizer.estimatedItemHeight;\n const item: MeasuredItem = {\n id,\n index: i,\n element: el,\n height,\n measured: el.offsetHeight > 0,\n };\n newItems.push(item);\n this.itemMap.set(id, item);\n this.elementMap.set(id, el);\n this.observers.observeItem(el, id);\n });\n\n // Reindex existing items\n this.items.forEach((item) => {\n item.index += elements.length;\n });\n this.items = [...newItems, ...this.items];\n\n this.relayout();\n this.applyPositions();\n }\n\n /** Remove an item by ID */\n remove(id: ItemId): void {\n const item = this.itemMap.get(id);\n if (!item) return;\n\n const element = this.elementMap.get(id);\n if (element) {\n this.observers.unobserveItem(element);\n element.remove();\n }\n\n this.items = this.items.filter((i) => i.id !== id);\n this.items.forEach((item, i) => {\n item.index = i;\n });\n this.itemMap.delete(id);\n this.elementMap.delete(id);\n\n this.relayout();\n this.applyPositions();\n }\n\n /** Force a full relayout */\n refresh(): void {\n for (const item of this.items) {\n const el = this.elementMap.get(item.id);\n if (el) {\n item.height = el.offsetHeight;\n item.measured = true;\n }\n }\n this.relayout();\n this.applyPositions();\n }\n\n /** Get current layout data */\n getLayout(): LayoutOutput | null {\n return this.currentLayout;\n }\n\n /** Get the number of columns */\n getColumnCount(): number {\n return this.columnCount;\n }\n\n /** Subscribe to events. Returns an unsubscribe function. */\n on<E extends MasonryEventName>(\n event: E,\n callback: MasonryGridEvents[E],\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n return () => {\n this.listeners.get(event)?.delete(callback);\n };\n }\n\n private emit<E extends MasonryEventName>(\n event: E,\n ...args: Parameters<MasonryGridEvents[E]>\n ): void {\n const callbacks = this.listeners.get(event);\n if (!callbacks) return;\n for (const cb of callbacks) {\n (cb as (...a: unknown[]) => void)(...args);\n }\n }\n\n /** Tear down everything */\n destroy(): void {\n this.isDestroyed = true;\n\n // Emit before clearing listeners so subscribers can react\n this.emit('destroy');\n\n this.observers.destroy();\n this.virtualizer?.destroy();\n this.debouncedRelayout.cancel();\n\n if (this.boundScrollHandler) {\n this.scrollContainer.removeEventListener('scroll', this.boundScrollHandler);\n }\n\n this.container.classList.remove(`${this.prefix}-container--js`);\n this.container.style.height = '';\n\n for (const [, element] of this.elementMap) {\n element.style.transform = '';\n element.style.width = '';\n }\n\n this.items = [];\n this.itemMap.clear();\n this.elementMap.clear();\n this.indexToElement.clear();\n this.listeners.clear();\n }\n\n // ==================== HELPERS ====================\n\n private collectItems(elements: HTMLElement[], startIndex = 0): void {\n elements.forEach((el, i) => {\n const id = el.dataset.masonryId ?? generateId();\n el.classList.add(`${this.prefix}-item`);\n const height =\n el.offsetHeight || this.opts.virtualizer.estimatedItemHeight;\n const item: MeasuredItem = {\n id,\n index: startIndex + i,\n element: el,\n height,\n measured: el.offsetHeight > 0,\n };\n this.items.push(item);\n this.itemMap.set(id, item);\n this.elementMap.set(id, el);\n this.observers.observeItem(el, id);\n });\n }\n\n private findScrollParent(element: HTMLElement): HTMLElement | null {\n let parent = element.parentElement;\n while (parent) {\n const overflow = getComputedStyle(parent).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') return parent;\n parent = parent.parentElement;\n }\n return null;\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/** Unique identifier for a masonry item */
|
|
2
|
+
type ItemId = string | number;
|
|
3
|
+
/** Computed position of a single item after layout */
|
|
4
|
+
interface ItemPosition {
|
|
5
|
+
id: ItemId;
|
|
6
|
+
index: number;
|
|
7
|
+
top: number;
|
|
8
|
+
left: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
column: number;
|
|
12
|
+
}
|
|
13
|
+
/** Internal representation of a measured item */
|
|
14
|
+
interface MeasuredItem {
|
|
15
|
+
id: ItemId;
|
|
16
|
+
index: number;
|
|
17
|
+
element: HTMLElement | null;
|
|
18
|
+
height: number;
|
|
19
|
+
measured: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Layout engine input — pure data, no DOM refs */
|
|
22
|
+
interface LayoutInput {
|
|
23
|
+
items: ReadonlyArray<{
|
|
24
|
+
id: ItemId;
|
|
25
|
+
index: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}>;
|
|
28
|
+
containerWidth: number;
|
|
29
|
+
columnCount: number;
|
|
30
|
+
gap: number;
|
|
31
|
+
}
|
|
32
|
+
/** Layout engine output */
|
|
33
|
+
interface LayoutOutput {
|
|
34
|
+
positions: ItemPosition[];
|
|
35
|
+
columnHeights: number[];
|
|
36
|
+
totalHeight: number;
|
|
37
|
+
}
|
|
38
|
+
/** Range of items visible in the viewport */
|
|
39
|
+
interface VisibleRange {
|
|
40
|
+
startIndex: number;
|
|
41
|
+
endIndex: number;
|
|
42
|
+
}
|
|
43
|
+
/** Configuration for the virtualizer */
|
|
44
|
+
interface VirtualizerConfig {
|
|
45
|
+
/** Pixels above and below viewport to pre-render. Default: 600 */
|
|
46
|
+
overscan: number;
|
|
47
|
+
/** Estimated height for unmeasured items. Default: 300 */
|
|
48
|
+
estimatedItemHeight: number;
|
|
49
|
+
}
|
|
50
|
+
/** Column computation strategy */
|
|
51
|
+
type ColumnStrategy = {
|
|
52
|
+
type: 'fixed';
|
|
53
|
+
count: number;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'auto';
|
|
56
|
+
minColumnWidth: number;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'responsive';
|
|
59
|
+
breakpoints: Record<number, number>;
|
|
60
|
+
};
|
|
61
|
+
/** Full constructor options */
|
|
62
|
+
interface MasonryGridOptions {
|
|
63
|
+
/** Column strategy. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
64
|
+
columns?: number | ColumnStrategy;
|
|
65
|
+
/** Gap between items in pixels. Default: 16 */
|
|
66
|
+
gap?: number;
|
|
67
|
+
/** Enable virtualization. Default: true */
|
|
68
|
+
virtualize?: boolean;
|
|
69
|
+
/** Virtualizer-specific config */
|
|
70
|
+
virtualizer?: Partial<VirtualizerConfig>;
|
|
71
|
+
/** Render function for virtualized mode: given an index, produce an HTMLElement */
|
|
72
|
+
renderItem?: (index: number) => HTMLElement;
|
|
73
|
+
/** Total item count (used with renderItem for virtualized mode) */
|
|
74
|
+
totalItems?: number;
|
|
75
|
+
/** Enable SSR-compatible initial render with CSS columns. Default: false */
|
|
76
|
+
ssrFallback?: boolean;
|
|
77
|
+
/** Custom class name prefix. Default: 'smg' */
|
|
78
|
+
classPrefix?: string;
|
|
79
|
+
/** Debounce delay for container resize (ms). Default: 100 */
|
|
80
|
+
resizeDebounceMs?: number;
|
|
81
|
+
}
|
|
82
|
+
/** Events emitted by MasonryGrid */
|
|
83
|
+
interface MasonryGridEvents {
|
|
84
|
+
layout: (output: LayoutOutput) => void;
|
|
85
|
+
resize: (containerWidth: number, columnCount: number) => void;
|
|
86
|
+
scroll: (scrollTop: number, visibleRange: VisibleRange) => void;
|
|
87
|
+
itemResize: (id: ItemId, oldHeight: number, newHeight: number) => void;
|
|
88
|
+
destroy: () => void;
|
|
89
|
+
}
|
|
90
|
+
type MasonryEventName = keyof MasonryGridEvents;
|
|
91
|
+
|
|
92
|
+
declare class MasonryGrid {
|
|
93
|
+
private container;
|
|
94
|
+
private opts;
|
|
95
|
+
private prefix;
|
|
96
|
+
private items;
|
|
97
|
+
private itemMap;
|
|
98
|
+
private elementMap;
|
|
99
|
+
private indexToElement;
|
|
100
|
+
private currentLayout;
|
|
101
|
+
private containerWidth;
|
|
102
|
+
private columnCount;
|
|
103
|
+
private isDestroyed;
|
|
104
|
+
private virtualizer;
|
|
105
|
+
private observers;
|
|
106
|
+
private scrollContainer;
|
|
107
|
+
private listeners;
|
|
108
|
+
private debouncedRelayout;
|
|
109
|
+
private boundScrollHandler;
|
|
110
|
+
constructor(container: HTMLElement, options?: Partial<MasonryGridOptions>);
|
|
111
|
+
private init;
|
|
112
|
+
private hydrateFromSSR;
|
|
113
|
+
private initFromExistingChildren;
|
|
114
|
+
private initVirtualized;
|
|
115
|
+
private relayout;
|
|
116
|
+
private applyPositions;
|
|
117
|
+
private renderVirtualItem;
|
|
118
|
+
private recycleVirtualItem;
|
|
119
|
+
private handleContainerResize;
|
|
120
|
+
private handleItemResize;
|
|
121
|
+
private bindScrollListener;
|
|
122
|
+
/** Add items to the end of the grid */
|
|
123
|
+
append(elements: HTMLElement[]): void;
|
|
124
|
+
/** Add items to the beginning of the grid */
|
|
125
|
+
prepend(elements: HTMLElement[]): void;
|
|
126
|
+
/** Remove an item by ID */
|
|
127
|
+
remove(id: ItemId): void;
|
|
128
|
+
/** Force a full relayout */
|
|
129
|
+
refresh(): void;
|
|
130
|
+
/** Get current layout data */
|
|
131
|
+
getLayout(): LayoutOutput | null;
|
|
132
|
+
/** Get the number of columns */
|
|
133
|
+
getColumnCount(): number;
|
|
134
|
+
/** Subscribe to events. Returns an unsubscribe function. */
|
|
135
|
+
on<E extends MasonryEventName>(event: E, callback: MasonryGridEvents[E]): () => void;
|
|
136
|
+
private emit;
|
|
137
|
+
/** Tear down everything */
|
|
138
|
+
destroy(): void;
|
|
139
|
+
private collectItems;
|
|
140
|
+
private findScrollParent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Computes absolute positions for all items using the shortest-column algorithm.
|
|
145
|
+
*
|
|
146
|
+
* 1. Initialize N column heights to 0.
|
|
147
|
+
* 2. columnWidth = (containerWidth - (columnCount - 1) * gap) / columnCount
|
|
148
|
+
* 3. For each item: place in shortest column, update column height.
|
|
149
|
+
* 4. totalHeight = max(columnHeights) - trailing gap.
|
|
150
|
+
*
|
|
151
|
+
* O(n * k) where n = items, k = columns. Effectively O(n) for typical k <= 10.
|
|
152
|
+
*/
|
|
153
|
+
declare function computeLayout(input: LayoutInput): LayoutOutput;
|
|
154
|
+
/**
|
|
155
|
+
* Determine column count given container width and strategy.
|
|
156
|
+
*/
|
|
157
|
+
declare function resolveColumnCount(containerWidth: number, strategy: ColumnStrategy, gap: number): number;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns a CSS string for SSR <head> injection.
|
|
161
|
+
* Use this on the server to include styles without JS.
|
|
162
|
+
*/
|
|
163
|
+
declare function getSSRStyles(prefix?: string, columns?: number, gap?: number): string;
|
|
164
|
+
|
|
165
|
+
export { type ColumnStrategy, type ItemId, type ItemPosition, type LayoutInput, type LayoutOutput, type MasonryEventName, MasonryGrid, type MasonryGridEvents, type MasonryGridOptions, type MeasuredItem, type VirtualizerConfig, type VisibleRange, computeLayout, getSSRStyles, resolveColumnCount };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/** Unique identifier for a masonry item */
|
|
2
|
+
type ItemId = string | number;
|
|
3
|
+
/** Computed position of a single item after layout */
|
|
4
|
+
interface ItemPosition {
|
|
5
|
+
id: ItemId;
|
|
6
|
+
index: number;
|
|
7
|
+
top: number;
|
|
8
|
+
left: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
column: number;
|
|
12
|
+
}
|
|
13
|
+
/** Internal representation of a measured item */
|
|
14
|
+
interface MeasuredItem {
|
|
15
|
+
id: ItemId;
|
|
16
|
+
index: number;
|
|
17
|
+
element: HTMLElement | null;
|
|
18
|
+
height: number;
|
|
19
|
+
measured: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Layout engine input — pure data, no DOM refs */
|
|
22
|
+
interface LayoutInput {
|
|
23
|
+
items: ReadonlyArray<{
|
|
24
|
+
id: ItemId;
|
|
25
|
+
index: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}>;
|
|
28
|
+
containerWidth: number;
|
|
29
|
+
columnCount: number;
|
|
30
|
+
gap: number;
|
|
31
|
+
}
|
|
32
|
+
/** Layout engine output */
|
|
33
|
+
interface LayoutOutput {
|
|
34
|
+
positions: ItemPosition[];
|
|
35
|
+
columnHeights: number[];
|
|
36
|
+
totalHeight: number;
|
|
37
|
+
}
|
|
38
|
+
/** Range of items visible in the viewport */
|
|
39
|
+
interface VisibleRange {
|
|
40
|
+
startIndex: number;
|
|
41
|
+
endIndex: number;
|
|
42
|
+
}
|
|
43
|
+
/** Configuration for the virtualizer */
|
|
44
|
+
interface VirtualizerConfig {
|
|
45
|
+
/** Pixels above and below viewport to pre-render. Default: 600 */
|
|
46
|
+
overscan: number;
|
|
47
|
+
/** Estimated height for unmeasured items. Default: 300 */
|
|
48
|
+
estimatedItemHeight: number;
|
|
49
|
+
}
|
|
50
|
+
/** Column computation strategy */
|
|
51
|
+
type ColumnStrategy = {
|
|
52
|
+
type: 'fixed';
|
|
53
|
+
count: number;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'auto';
|
|
56
|
+
minColumnWidth: number;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'responsive';
|
|
59
|
+
breakpoints: Record<number, number>;
|
|
60
|
+
};
|
|
61
|
+
/** Full constructor options */
|
|
62
|
+
interface MasonryGridOptions {
|
|
63
|
+
/** Column strategy. Default: { type: 'auto', minColumnWidth: 250 } */
|
|
64
|
+
columns?: number | ColumnStrategy;
|
|
65
|
+
/** Gap between items in pixels. Default: 16 */
|
|
66
|
+
gap?: number;
|
|
67
|
+
/** Enable virtualization. Default: true */
|
|
68
|
+
virtualize?: boolean;
|
|
69
|
+
/** Virtualizer-specific config */
|
|
70
|
+
virtualizer?: Partial<VirtualizerConfig>;
|
|
71
|
+
/** Render function for virtualized mode: given an index, produce an HTMLElement */
|
|
72
|
+
renderItem?: (index: number) => HTMLElement;
|
|
73
|
+
/** Total item count (used with renderItem for virtualized mode) */
|
|
74
|
+
totalItems?: number;
|
|
75
|
+
/** Enable SSR-compatible initial render with CSS columns. Default: false */
|
|
76
|
+
ssrFallback?: boolean;
|
|
77
|
+
/** Custom class name prefix. Default: 'smg' */
|
|
78
|
+
classPrefix?: string;
|
|
79
|
+
/** Debounce delay for container resize (ms). Default: 100 */
|
|
80
|
+
resizeDebounceMs?: number;
|
|
81
|
+
}
|
|
82
|
+
/** Events emitted by MasonryGrid */
|
|
83
|
+
interface MasonryGridEvents {
|
|
84
|
+
layout: (output: LayoutOutput) => void;
|
|
85
|
+
resize: (containerWidth: number, columnCount: number) => void;
|
|
86
|
+
scroll: (scrollTop: number, visibleRange: VisibleRange) => void;
|
|
87
|
+
itemResize: (id: ItemId, oldHeight: number, newHeight: number) => void;
|
|
88
|
+
destroy: () => void;
|
|
89
|
+
}
|
|
90
|
+
type MasonryEventName = keyof MasonryGridEvents;
|
|
91
|
+
|
|
92
|
+
declare class MasonryGrid {
|
|
93
|
+
private container;
|
|
94
|
+
private opts;
|
|
95
|
+
private prefix;
|
|
96
|
+
private items;
|
|
97
|
+
private itemMap;
|
|
98
|
+
private elementMap;
|
|
99
|
+
private indexToElement;
|
|
100
|
+
private currentLayout;
|
|
101
|
+
private containerWidth;
|
|
102
|
+
private columnCount;
|
|
103
|
+
private isDestroyed;
|
|
104
|
+
private virtualizer;
|
|
105
|
+
private observers;
|
|
106
|
+
private scrollContainer;
|
|
107
|
+
private listeners;
|
|
108
|
+
private debouncedRelayout;
|
|
109
|
+
private boundScrollHandler;
|
|
110
|
+
constructor(container: HTMLElement, options?: Partial<MasonryGridOptions>);
|
|
111
|
+
private init;
|
|
112
|
+
private hydrateFromSSR;
|
|
113
|
+
private initFromExistingChildren;
|
|
114
|
+
private initVirtualized;
|
|
115
|
+
private relayout;
|
|
116
|
+
private applyPositions;
|
|
117
|
+
private renderVirtualItem;
|
|
118
|
+
private recycleVirtualItem;
|
|
119
|
+
private handleContainerResize;
|
|
120
|
+
private handleItemResize;
|
|
121
|
+
private bindScrollListener;
|
|
122
|
+
/** Add items to the end of the grid */
|
|
123
|
+
append(elements: HTMLElement[]): void;
|
|
124
|
+
/** Add items to the beginning of the grid */
|
|
125
|
+
prepend(elements: HTMLElement[]): void;
|
|
126
|
+
/** Remove an item by ID */
|
|
127
|
+
remove(id: ItemId): void;
|
|
128
|
+
/** Force a full relayout */
|
|
129
|
+
refresh(): void;
|
|
130
|
+
/** Get current layout data */
|
|
131
|
+
getLayout(): LayoutOutput | null;
|
|
132
|
+
/** Get the number of columns */
|
|
133
|
+
getColumnCount(): number;
|
|
134
|
+
/** Subscribe to events. Returns an unsubscribe function. */
|
|
135
|
+
on<E extends MasonryEventName>(event: E, callback: MasonryGridEvents[E]): () => void;
|
|
136
|
+
private emit;
|
|
137
|
+
/** Tear down everything */
|
|
138
|
+
destroy(): void;
|
|
139
|
+
private collectItems;
|
|
140
|
+
private findScrollParent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Computes absolute positions for all items using the shortest-column algorithm.
|
|
145
|
+
*
|
|
146
|
+
* 1. Initialize N column heights to 0.
|
|
147
|
+
* 2. columnWidth = (containerWidth - (columnCount - 1) * gap) / columnCount
|
|
148
|
+
* 3. For each item: place in shortest column, update column height.
|
|
149
|
+
* 4. totalHeight = max(columnHeights) - trailing gap.
|
|
150
|
+
*
|
|
151
|
+
* O(n * k) where n = items, k = columns. Effectively O(n) for typical k <= 10.
|
|
152
|
+
*/
|
|
153
|
+
declare function computeLayout(input: LayoutInput): LayoutOutput;
|
|
154
|
+
/**
|
|
155
|
+
* Determine column count given container width and strategy.
|
|
156
|
+
*/
|
|
157
|
+
declare function resolveColumnCount(containerWidth: number, strategy: ColumnStrategy, gap: number): number;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns a CSS string for SSR <head> injection.
|
|
161
|
+
* Use this on the server to include styles without JS.
|
|
162
|
+
*/
|
|
163
|
+
declare function getSSRStyles(prefix?: string, columns?: number, gap?: number): string;
|
|
164
|
+
|
|
165
|
+
export { type ColumnStrategy, type ItemId, type ItemPosition, type LayoutInput, type LayoutOutput, type MasonryEventName, MasonryGrid, type MasonryGridEvents, type MasonryGridOptions, type MeasuredItem, type VirtualizerConfig, type VisibleRange, computeLayout, getSSRStyles, resolveColumnCount };
|