social-masonry 1.0.0 → 1.0.1
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/README.md +97 -308
- package/dist/index.d.ts +62 -437
- package/dist/index.esm.js +93 -1354
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +101 -1366
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +35 -141
- package/dist/react/index.esm.js +280 -651
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +278 -649
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/layout-engine.ts","../src/virtualization-engine.ts","../src/card-renderer.ts","../src/core.ts"],"sourcesContent":["/**\n * Social Masonry - Utility Functions\n */\n\nimport type { ColumnConfig, SocialPost } from './types';\n\n/**\n * Debounce function execution\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n timeoutId = null;\n }, delay);\n };\n}\n\n/**\n * Throttle function execution\n */\nexport function throttle<T extends (...args: unknown[]) => unknown>(\n fn: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n let lastArgs: Parameters<T> | null = null;\n \n return function (this: unknown, ...args: Parameters<T>) {\n if (!inThrottle) {\n fn.apply(this, args);\n inThrottle = true;\n setTimeout(() => {\n inThrottle = false;\n if (lastArgs) {\n fn.apply(this, lastArgs);\n lastArgs = null;\n }\n }, limit);\n } else {\n lastArgs = args;\n }\n };\n}\n\n/**\n * Get number of columns based on viewport width\n */\nexport function getColumnCount(\n columns: number | ColumnConfig[],\n containerWidth: number\n): number {\n if (typeof columns === 'number') {\n return columns;\n }\n \n // Sort by minWidth descending\n const sorted = [...columns].sort((a, b) => b.minWidth - a.minWidth);\n \n for (const config of sorted) {\n if (containerWidth >= config.minWidth) {\n return config.columns;\n }\n }\n \n // Return smallest breakpoint's columns or default to 1\n return sorted[sorted.length - 1]?.columns ?? 1;\n}\n\n/**\n * Default responsive column configuration\n */\nexport const defaultColumnConfig: ColumnConfig[] = [\n { columns: 4, minWidth: 1200 },\n { columns: 3, minWidth: 900 },\n { columns: 2, minWidth: 600 },\n { columns: 1, minWidth: 0 },\n];\n\n/**\n * Format number with abbreviations (1K, 1M, etc.)\n */\nexport function formatNumber(num: number): string {\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1).replace(/\\.0$/, '')}M`;\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1).replace(/\\.0$/, '')}K`;\n }\n return num.toString();\n}\n\n/**\n * Format relative time\n */\nexport function formatRelativeTime(date: Date): string {\n const now = new Date();\n const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);\n \n if (diffInSeconds < 60) {\n return 'now';\n }\n \n const diffInMinutes = Math.floor(diffInSeconds / 60);\n if (diffInMinutes < 60) {\n return `${diffInMinutes}m`;\n }\n \n const diffInHours = Math.floor(diffInMinutes / 60);\n if (diffInHours < 24) {\n return `${diffInHours}h`;\n }\n \n const diffInDays = Math.floor(diffInHours / 24);\n if (diffInDays < 7) {\n return `${diffInDays}d`;\n }\n \n const diffInWeeks = Math.floor(diffInDays / 7);\n if (diffInWeeks < 4) {\n return `${diffInWeeks}w`;\n }\n \n // Format as date for older posts\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n });\n}\n\n/**\n * Parse CSS value to pixels\n */\nexport function parseCSSValue(value: number | string, containerWidth?: number): number {\n if (typeof value === 'number') {\n return value;\n }\n \n const numMatch = value.match(/^([\\d.]+)(px|rem|em|%|vw)?$/);\n if (!numMatch) {\n return 0;\n }\n \n const num = parseFloat(numMatch[1]);\n const unit = numMatch[2] || 'px';\n \n switch (unit) {\n case 'px':\n return num;\n case 'rem':\n return num * 16; // Assume 16px base\n case 'em':\n return num * 16;\n case '%':\n return containerWidth ? (num / 100) * containerWidth : 0;\n case 'vw':\n return (num / 100) * window.innerWidth;\n default:\n return num;\n }\n}\n\n/**\n * Generate unique ID\n */\nexport function generateId(): string {\n return `sm-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Check if element is in viewport\n */\nexport function isInViewport(\n element: { top: number; bottom: number },\n scrollTop: number,\n viewportHeight: number,\n overscan: number = 0\n): boolean {\n const expandedTop = scrollTop - overscan;\n const expandedBottom = scrollTop + viewportHeight + overscan;\n \n return element.bottom >= expandedTop && element.top <= expandedBottom;\n}\n\n/**\n * Get scroll position\n */\nexport function getScrollPosition(scrollContainer: HTMLElement | Window | null): {\n scrollTop: number;\n viewportHeight: number;\n} {\n if (!scrollContainer || scrollContainer === window) {\n return {\n scrollTop: window.scrollY || document.documentElement.scrollTop,\n viewportHeight: window.innerHeight,\n };\n }\n \n return {\n scrollTop: (scrollContainer as HTMLElement).scrollTop,\n viewportHeight: (scrollContainer as HTMLElement).clientHeight,\n };\n}\n\n/**\n * Type guard for Twitter posts\n */\nexport function isTwitterPost(post: SocialPost): post is import('./types').TwitterPost {\n return post.platform === 'twitter';\n}\n\n/**\n * Type guard for Instagram posts\n */\nexport function isInstagramPost(post: SocialPost): post is import('./types').InstagramPost {\n return post.platform === 'instagram';\n}\n\n/**\n * Clamp number between min and max\n */\nexport function clamp(num: number, min: number, max: number): number {\n return Math.min(Math.max(num, min), max);\n}\n\n/**\n * Merge objects deeply\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n ...sources: Partial<T>[]\n): T {\n const result = { ...target };\n \n for (const source of sources) {\n if (!source) continue;\n \n for (const key of Object.keys(source)) {\n const targetValue = result[key as keyof T];\n const sourceValue = source[key as keyof T];\n \n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else if (sourceValue !== undefined) {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n }\n \n return result;\n}\n\n/**\n * Create CSS custom properties from config\n */\nexport function createCSSVariables(prefix: string, config: Record<string, unknown>): string {\n const vars: string[] = [];\n \n function processValue(key: string, value: unknown): void {\n if (value === undefined || value === null) return;\n \n if (typeof value === 'object' && !Array.isArray(value)) {\n for (const [subKey, subValue] of Object.entries(value as Record<string, unknown>)) {\n processValue(`${key}-${subKey}`, subValue);\n }\n } else {\n const cssValue = typeof value === 'number' ? `${value}px` : String(value);\n vars.push(`--${prefix}-${key}: ${cssValue};`);\n }\n }\n \n for (const [key, value] of Object.entries(config)) {\n processValue(key, value);\n }\n \n return vars.join('\\n');\n}\n\n/**\n * Request animation frame with fallback\n */\nexport const raf =\n typeof requestAnimationFrame !== 'undefined'\n ? requestAnimationFrame\n : (callback: FrameRequestCallback) => setTimeout(callback, 16);\n\n/**\n * Cancel animation frame with fallback\n */\nexport const cancelRaf =\n typeof cancelAnimationFrame !== 'undefined'\n ? cancelAnimationFrame\n : (id: number) => clearTimeout(id);\n\n/**\n * Check if we're in a browser environment\n */\nexport const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n\n/**\n * Check if ResizeObserver is supported\n */\nexport const supportsResizeObserver = isBrowser && typeof ResizeObserver !== 'undefined';\n\n/**\n * Check if IntersectionObserver is supported\n */\nexport const supportsIntersectionObserver =\n isBrowser && typeof IntersectionObserver !== 'undefined';\n","/**\n * Social Masonry - Layout Engine\n * Calculates positions for masonry grid items\n */\n\nimport type {\n ItemPosition,\n LayoutState,\n MasonryConfig,\n SocialPost,\n} from './types';\nimport {\n defaultColumnConfig,\n getColumnCount,\n parseCSSValue,\n} from './utils';\n\nexport interface LayoutEngineOptions extends MasonryConfig {\n containerWidth: number;\n itemHeights: Map<string, number>;\n}\n\nexport class LayoutEngine {\n private options: Required<LayoutEngineOptions>;\n private state: LayoutState;\n\n constructor(options: LayoutEngineOptions) {\n this.options = {\n gap: 16,\n columns: defaultColumnConfig,\n defaultColumns: 3,\n padding: 0,\n animationDuration: 300,\n animate: true,\n easing: 'cubic-bezier(0.4, 0, 0.2, 1)',\n ...options,\n };\n\n this.state = {\n positions: new Map(),\n columnHeights: [],\n containerHeight: 0,\n columnWidth: 0,\n };\n }\n\n /**\n * Calculate layout for all posts\n */\n calculate(posts: SocialPost[]): LayoutState {\n const { containerWidth, itemHeights } = this.options;\n const gap = parseCSSValue(this.options.gap);\n const padding = parseCSSValue(this.options.padding);\n \n // Calculate column count and width\n const columnCount = getColumnCount(this.options.columns, containerWidth);\n const availableWidth = containerWidth - padding * 2;\n const totalGapWidth = gap * (columnCount - 1);\n const columnWidth = (availableWidth - totalGapWidth) / columnCount;\n\n // Initialize column heights\n const columnHeights = new Array(columnCount).fill(0);\n const positions = new Map<string, ItemPosition>();\n\n // Place each item in the shortest column\n for (const post of posts) {\n const itemHeight = itemHeights.get(post.id) ?? this.estimateHeight(post, columnWidth);\n \n // Find shortest column\n const shortestColumn = columnHeights.indexOf(Math.min(...columnHeights));\n \n // Calculate position\n const x = padding + shortestColumn * (columnWidth + gap);\n const y = columnHeights[shortestColumn];\n \n positions.set(post.id, {\n id: post.id,\n x,\n y,\n width: columnWidth,\n height: itemHeight,\n column: shortestColumn,\n });\n\n // Update column height\n columnHeights[shortestColumn] = y + itemHeight + gap;\n }\n\n // Remove last gap from column heights\n const containerHeight = Math.max(...columnHeights.map(h => h - gap), 0);\n\n this.state = {\n positions,\n columnHeights,\n containerHeight,\n columnWidth,\n };\n\n return this.state;\n }\n\n /**\n * Estimate item height based on content\n */\n private estimateHeight(post: SocialPost, columnWidth: number): number {\n let height = 0;\n\n // Header (avatar, name, etc.)\n height += 56;\n\n // Text content\n if (post.platform === 'twitter') {\n const textLength = post.content.text.length;\n const avgCharsPerLine = Math.floor(columnWidth / 8); // ~8px per char\n const lines = Math.ceil(textLength / avgCharsPerLine);\n height += lines * 24; // ~24px per line\n } else if (post.content.caption) {\n const captionLength = post.content.caption.length;\n const avgCharsPerLine = Math.floor(columnWidth / 8);\n const lines = Math.min(Math.ceil(captionLength / avgCharsPerLine), 4); // Max 4 lines\n height += lines * 20;\n }\n\n // Media\n if (post.platform === 'twitter' && post.media?.length) {\n const media = post.media[0];\n const aspectRatio = media.aspectRatio ?? 16 / 9;\n height += columnWidth / aspectRatio;\n } else if (post.platform === 'instagram') {\n const aspectRatio = post.media.aspectRatio ?? 1;\n height += columnWidth / aspectRatio;\n }\n\n // Footer (metrics, timestamp)\n height += 44;\n\n // Padding\n height += 24;\n\n return Math.round(height);\n }\n\n /**\n * Update single item height and recalculate affected items\n */\n updateItemHeight(id: string, height: number): void {\n this.options.itemHeights.set(id, height);\n }\n\n /**\n * Get current layout state\n */\n getState(): LayoutState {\n return this.state;\n }\n\n /**\n * Get position for specific item\n */\n getPosition(id: string): ItemPosition | undefined {\n return this.state.positions.get(id);\n }\n\n /**\n * Update container width\n */\n setContainerWidth(width: number): void {\n this.options.containerWidth = width;\n }\n\n /**\n * Get current column count\n */\n getColumnCount(): number {\n return getColumnCount(this.options.columns, this.options.containerWidth);\n }\n\n /**\n * Get CSS variables for animations\n */\n getCSSVariables(): Record<string, string> {\n return {\n '--sm-animation-duration': `${this.options.animationDuration}ms`,\n '--sm-easing': this.options.easing,\n '--sm-gap': typeof this.options.gap === 'number' \n ? `${this.options.gap}px` \n : this.options.gap,\n '--sm-column-width': `${this.state.columnWidth}px`,\n '--sm-container-height': `${this.state.containerHeight}px`,\n };\n }\n}\n\n/**\n * Create a new layout engine instance\n */\nexport function createLayoutEngine(options: LayoutEngineOptions): LayoutEngine {\n return new LayoutEngine(options);\n}\n","/**\n * Social Masonry - Virtualization Engine\n * Handles virtual scrolling for large lists\n */\n\nimport type {\n ItemPosition,\n SocialPost,\n VirtualItem,\n VirtualizationConfig,\n} from './types';\nimport {\n getScrollPosition,\n isInViewport,\n throttle,\n raf,\n cancelRaf,\n} from './utils';\n\nexport interface VirtualizationEngineOptions extends VirtualizationConfig {\n posts: SocialPost[];\n positions: Map<string, ItemPosition>;\n onVisibleItemsChange?: (items: VirtualItem[]) => void;\n}\n\nexport class VirtualizationEngine {\n private options: Required<VirtualizationConfig>;\n private posts: SocialPost[];\n private positions: Map<string, ItemPosition>;\n private visibleItems: VirtualItem[] = [];\n private scrollHandler: () => void;\n private rafId: number | null = null;\n private lastScrollTop = 0;\n private isScrolling = false;\n private scrollEndTimeout: ReturnType<typeof setTimeout> | null = null;\n private onVisibleItemsChange?: (items: VirtualItem[]) => void;\n\n constructor(options: VirtualizationEngineOptions) {\n this.options = {\n enabled: true,\n overscan: 3,\n estimatedItemHeight: 400,\n scrollContainer: null,\n ...options,\n };\n \n this.posts = options.posts;\n this.positions = options.positions;\n this.onVisibleItemsChange = options.onVisibleItemsChange;\n\n this.scrollHandler = throttle(this.handleScroll.bind(this), 16);\n }\n\n /**\n * Initialize scroll listener\n */\n init(): void {\n if (!this.options.enabled) return;\n\n const container = this.options.scrollContainer ?? window;\n container.addEventListener('scroll', this.scrollHandler, { passive: true });\n \n // Initial calculation\n this.calculateVisibleItems();\n }\n\n /**\n * Destroy and cleanup\n */\n destroy(): void {\n const container = this.options.scrollContainer ?? window;\n container.removeEventListener('scroll', this.scrollHandler);\n \n if (this.rafId !== null) {\n cancelRaf(this.rafId);\n }\n \n if (this.scrollEndTimeout) {\n clearTimeout(this.scrollEndTimeout);\n }\n }\n\n /**\n * Handle scroll event\n */\n private handleScroll(): void {\n if (this.rafId !== null) return;\n\n this.isScrolling = true;\n \n // Clear existing scroll end timeout\n if (this.scrollEndTimeout) {\n clearTimeout(this.scrollEndTimeout);\n }\n \n // Set scroll end detection\n this.scrollEndTimeout = setTimeout(() => {\n this.isScrolling = false;\n }, 150);\n\n this.rafId = raf(() => {\n this.rafId = null;\n this.calculateVisibleItems();\n });\n }\n\n /**\n * Calculate which items are visible\n */\n calculateVisibleItems(): VirtualItem[] {\n const { scrollTop, viewportHeight } = getScrollPosition(this.options.scrollContainer);\n const overscanPx = this.options.overscan * this.options.estimatedItemHeight;\n \n this.lastScrollTop = scrollTop;\n \n const newVisibleItems: VirtualItem[] = [];\n\n for (let i = 0; i < this.posts.length; i++) {\n const post = this.posts[i];\n const position = this.positions.get(post.id);\n \n if (!position) continue;\n\n const isVisible = isInViewport(\n {\n top: position.y,\n bottom: position.y + position.height,\n },\n scrollTop,\n viewportHeight,\n overscanPx\n );\n\n if (isVisible) {\n newVisibleItems.push({\n index: i,\n post,\n position,\n isVisible: true,\n });\n }\n }\n\n // Check if visible items changed\n const hasChanged = this.hasVisibleItemsChanged(newVisibleItems);\n \n if (hasChanged) {\n this.visibleItems = newVisibleItems;\n this.onVisibleItemsChange?.(newVisibleItems);\n }\n\n return this.visibleItems;\n }\n\n /**\n * Check if visible items have changed\n */\n private hasVisibleItemsChanged(newItems: VirtualItem[]): boolean {\n if (newItems.length !== this.visibleItems.length) {\n return true;\n }\n\n for (let i = 0; i < newItems.length; i++) {\n if (newItems[i].post.id !== this.visibleItems[i].post.id) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Update posts and positions\n */\n update(posts: SocialPost[], positions: Map<string, ItemPosition>): void {\n this.posts = posts;\n this.positions = positions;\n this.calculateVisibleItems();\n }\n\n /**\n * Get visible items\n */\n getVisibleItems(): VirtualItem[] {\n return this.visibleItems;\n }\n\n /**\n * Get all items (for non-virtualized mode)\n */\n getAllItems(): VirtualItem[] {\n return this.posts.map((post, index) => ({\n index,\n post,\n position: this.positions.get(post.id)!,\n isVisible: true,\n }));\n }\n\n /**\n * Check if scrolling\n */\n getIsScrolling(): boolean {\n return this.isScrolling;\n }\n\n /**\n * Get scroll direction\n */\n getScrollDirection(): 'up' | 'down' | 'none' {\n const { scrollTop } = getScrollPosition(this.options.scrollContainer);\n \n if (scrollTop > this.lastScrollTop) {\n return 'down';\n } else if (scrollTop < this.lastScrollTop) {\n return 'up';\n }\n \n return 'none';\n }\n\n /**\n * Check if near bottom (for infinite scroll)\n */\n isNearBottom(threshold: number = 500): boolean {\n const { scrollTop, viewportHeight } = getScrollPosition(this.options.scrollContainer);\n \n // Get container height from positions\n let maxBottom = 0;\n for (const position of this.positions.values()) {\n maxBottom = Math.max(maxBottom, position.y + position.height);\n }\n \n return scrollTop + viewportHeight >= maxBottom - threshold;\n }\n\n /**\n * Scroll to item\n */\n scrollToItem(id: string, behavior: ScrollBehavior = 'smooth'): void {\n const position = this.positions.get(id);\n if (!position) return;\n\n const container = this.options.scrollContainer ?? window;\n \n if (container === window) {\n window.scrollTo({\n top: position.y,\n behavior,\n });\n } else {\n (container as HTMLElement).scrollTo({\n top: position.y,\n behavior,\n });\n }\n }\n\n /**\n * Get render range for optimization\n */\n getRenderRange(): { start: number; end: number } {\n if (this.visibleItems.length === 0) {\n return { start: 0, end: 0 };\n }\n\n const indices = this.visibleItems.map(item => item.index);\n return {\n start: Math.min(...indices),\n end: Math.max(...indices) + 1,\n };\n }\n}\n\n/**\n * Create a new virtualization engine instance\n */\nexport function createVirtualizationEngine(\n options: VirtualizationEngineOptions\n): VirtualizationEngine {\n return new VirtualizationEngine(options);\n}\n","/**\n * Social Masonry - Card Renderer\n * Renders social media post cards with proper styling\n */\n\nimport type {\n CardConfig,\n InstagramPost,\n ItemPosition,\n SocialPost,\n TwitterPost,\n} from './types';\nimport {\n formatNumber as defaultFormatNumber,\n formatRelativeTime,\n isTwitterPost,\n isInstagramPost,\n} from './utils';\n\nexport interface CardRendererOptions extends CardConfig {\n onPostClick?: (post: SocialPost, event: MouseEvent) => void;\n onAuthorClick?: (post: SocialPost, event: MouseEvent) => void;\n onMediaClick?: (post: SocialPost, mediaIndex: number, event: MouseEvent) => void;\n onImageError?: (post: SocialPost, error: Error) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<CardConfig> = {\n variant: 'default',\n theme: 'auto',\n borderRadius: 12,\n showPlatformIcon: true,\n showAuthor: true,\n showMetrics: true,\n showTimestamp: true,\n formatDate: (date: Date) => formatRelativeTime(date),\n formatNumber: defaultFormatNumber,\n className: '',\n hoverEffect: true,\n imageLoading: 'lazy',\n fallbackImage: 'data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"100\" height=\"100\" viewBox=\"0 0 100 100\"%3E%3Crect fill=\"%23f0f0f0\" width=\"100\" height=\"100\"/%3E%3Ctext fill=\"%23999\" font-family=\"sans-serif\" font-size=\"14\" x=\"50%\" y=\"50%\" text-anchor=\"middle\" dy=\".3em\"%3ENo Image%3C/text%3E%3C/svg%3E',\n};\n\nexport class CardRenderer {\n private options: Required<CardRendererOptions>;\n\n constructor(options: CardRendererOptions = {}) {\n this.options = {\n ...DEFAULT_OPTIONS,\n onPostClick: undefined,\n onAuthorClick: undefined,\n onMediaClick: undefined,\n onImageError: undefined,\n ...options,\n } as Required<CardRendererOptions>;\n }\n\n /**\n * Render a single card\n */\n render(post: SocialPost, position: ItemPosition): HTMLElement {\n const card = document.createElement('div');\n card.className = this.getCardClasses(post);\n card.setAttribute('data-post-id', post.id);\n card.setAttribute('data-platform', post.platform);\n \n // Apply position styles\n Object.assign(card.style, {\n position: 'absolute',\n left: `${position.x}px`,\n top: `${position.y}px`,\n width: `${position.width}px`,\n borderRadius: typeof this.options.borderRadius === 'number'\n ? `${this.options.borderRadius}px`\n : this.options.borderRadius,\n });\n\n // Build card content\n card.innerHTML = this.buildCardHTML(post);\n\n // Attach event listeners\n this.attachEventListeners(card, post);\n\n return card;\n }\n\n /**\n * Get CSS classes for card\n */\n private getCardClasses(post: SocialPost): string {\n const classes = [\n 'sm-card',\n `sm-card--${post.platform}`,\n `sm-card--${this.options.variant}`,\n `sm-card--${this.options.theme}`,\n ];\n\n if (this.options.hoverEffect) {\n classes.push('sm-card--hover');\n }\n\n if (this.options.className) {\n classes.push(this.options.className);\n }\n\n return classes.join(' ');\n }\n\n /**\n * Build card HTML\n */\n private buildCardHTML(post: SocialPost): string {\n const parts: string[] = [];\n\n // Platform icon\n if (this.options.showPlatformIcon) {\n parts.push(this.renderPlatformIcon(post.platform));\n }\n\n // Header with author\n if (this.options.showAuthor) {\n parts.push(this.renderHeader(post));\n }\n\n // Content\n parts.push(this.renderContent(post));\n\n // Media\n parts.push(this.renderMedia(post));\n\n // Footer with metrics\n if (this.options.showMetrics || this.options.showTimestamp) {\n parts.push(this.renderFooter(post));\n }\n\n return parts.join('');\n }\n\n /**\n * Render platform icon\n */\n private renderPlatformIcon(platform: string): string {\n const icons: Record<string, string> = {\n twitter: `<svg viewBox=\"0 0 24 24\" class=\"sm-platform-icon sm-platform-icon--twitter\"><path fill=\"currentColor\" d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>`,\n instagram: `<svg viewBox=\"0 0 24 24\" class=\"sm-platform-icon sm-platform-icon--instagram\"><path fill=\"currentColor\" d=\"M12 2c2.717 0 3.056.01 4.122.06 1.065.05 1.79.217 2.428.465.66.254 1.216.598 1.772 1.153a4.908 4.908 0 0 1 1.153 1.772c.247.637.415 1.363.465 2.428.047 1.066.06 1.405.06 4.122 0 2.717-.01 3.056-.06 4.122-.05 1.065-.218 1.79-.465 2.428a4.883 4.883 0 0 1-1.153 1.772 4.915 4.915 0 0 1-1.772 1.153c-.637.247-1.363.415-2.428.465-1.066.047-1.405.06-4.122.06-2.717 0-3.056-.01-4.122-.06-1.065-.05-1.79-.218-2.428-.465a4.89 4.89 0 0 1-1.772-1.153 4.904 4.904 0 0 1-1.153-1.772c-.248-.637-.415-1.363-.465-2.428C2.013 15.056 2 14.717 2 12c0-2.717.01-3.056.06-4.122.05-1.066.217-1.79.465-2.428a4.88 4.88 0 0 1 1.153-1.772A4.897 4.897 0 0 1 5.45 2.525c.638-.248 1.362-.415 2.428-.465C8.944 2.013 9.283 2 12 2zm0 1.802c-2.67 0-2.986.01-4.04.058-.976.045-1.505.207-1.858.344-.466.182-.8.398-1.15.748-.35.35-.566.684-.748 1.15-.137.353-.3.882-.344 1.857-.048 1.055-.058 1.37-.058 4.041 0 2.67.01 2.986.058 4.04.045.976.207 1.505.344 1.858.182.466.399.8.748 1.15.35.35.684.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058 2.67 0 2.987-.01 4.04-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.684.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041 0-2.67-.01-2.986-.058-4.04-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 0 0-.748-1.15 3.098 3.098 0 0 0-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.055-.048-1.37-.058-4.041-.058zm0 3.063a5.135 5.135 0 1 1 0 10.27 5.135 5.135 0 0 1 0-10.27zm0 8.468a3.333 3.333 0 1 0 0-6.666 3.333 3.333 0 0 0 0 6.666zm6.538-8.671a1.2 1.2 0 1 1-2.4 0 1.2 1.2 0 0 1 2.4 0z\"/></svg>`,\n };\n\n return `<div class=\"sm-card__platform-icon\">${icons[platform] || ''}</div>`;\n }\n\n /**\n * Render card header\n */\n private renderHeader(post: SocialPost): string {\n const author = post.author;\n const avatarUrl = author.avatarUrl || this.options.fallbackImage;\n const verifiedBadge = author.verified\n ? `<svg class=\"sm-card__verified\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M22.25 12c0-1.43-.88-2.67-2.19-3.34.46-1.39.2-2.9-.81-3.91s-2.52-1.27-3.91-.81c-.66-1.31-1.91-2.19-3.34-2.19s-2.67.88-3.34 2.19c-1.39-.46-2.9-.2-3.91.81s-1.27 2.52-.81 3.91C2.63 9.33 1.75 10.57 1.75 12s.88 2.67 2.19 3.34c-.46 1.39-.2 2.9.81 3.91s2.52 1.27 3.91.81c.66 1.31 1.91 2.19 3.34 2.19s2.67-.88 3.34-2.19c1.39.46 2.9.2 3.91-.81s1.27-2.52.81-3.91c1.31-.67 2.19-1.91 2.19-3.34zm-11.71 4.2L6.8 12.46l1.41-1.42 2.26 2.26 4.8-5.23 1.47 1.36-6.2 6.77z\"/></svg>`\n : '';\n\n return `\n <div class=\"sm-card__header\">\n <img \n src=\"${avatarUrl}\" \n alt=\"${author.displayName || author.username}\" \n class=\"sm-card__avatar\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n <div class=\"sm-card__author\">\n <span class=\"sm-card__author-name\">\n ${author.displayName || author.username}\n ${verifiedBadge}\n </span>\n <span class=\"sm-card__author-handle\">@${author.username}</span>\n </div>\n </div>\n `;\n }\n\n /**\n * Render card content\n */\n private renderContent(post: SocialPost): string {\n if (isTwitterPost(post)) {\n return this.renderTwitterContent(post);\n } else if (isInstagramPost(post)) {\n return this.renderInstagramContent(post);\n }\n return '';\n }\n\n /**\n * Render Twitter content\n */\n private renderTwitterContent(post: TwitterPost): string {\n const text = post.content.html || this.linkifyText(post.content.text);\n \n let quotedPost = '';\n if (post.quotedPost) {\n quotedPost = `\n <div class=\"sm-card__quoted\">\n <div class=\"sm-card__quoted-header\">\n <span class=\"sm-card__quoted-name\">${post.quotedPost.author.displayName}</span>\n <span class=\"sm-card__quoted-handle\">@${post.quotedPost.author.username}</span>\n </div>\n <div class=\"sm-card__quoted-text\">${post.quotedPost.content.text}</div>\n </div>\n `;\n }\n\n return `\n <div class=\"sm-card__content\">\n <p class=\"sm-card__text\">${text}</p>\n ${quotedPost}\n </div>\n `;\n }\n\n /**\n * Render Instagram content\n */\n private renderInstagramContent(post: InstagramPost): string {\n if (!post.content.caption) return '';\n \n // Truncate caption if too long\n const maxLength = 150;\n let caption = post.content.caption;\n let showMore = false;\n \n if (caption.length > maxLength) {\n caption = caption.substring(0, maxLength);\n showMore = true;\n }\n\n return `\n <div class=\"sm-card__content\">\n <p class=\"sm-card__caption\">\n ${this.linkifyText(caption)}${showMore ? '<span class=\"sm-card__more\">... more</span>' : ''}\n </p>\n </div>\n `;\n }\n\n /**\n * Render media\n */\n private renderMedia(post: SocialPost): string {\n if (isTwitterPost(post)) {\n return this.renderTwitterMedia(post);\n } else if (isInstagramPost(post)) {\n return this.renderInstagramMedia(post);\n }\n return '';\n }\n\n /**\n * Render Twitter media\n */\n private renderTwitterMedia(post: TwitterPost): string {\n if (!post.media?.length) return '';\n\n const mediaCount = post.media.length;\n const gridClass = mediaCount > 1 ? `sm-card__media-grid sm-card__media-grid--${Math.min(mediaCount, 4)}` : '';\n\n const mediaItems = post.media.slice(0, 4).map((media, index) => {\n if (media.type === 'video' || media.type === 'gif') {\n return `\n <div class=\"sm-card__media-item sm-card__media-item--video\" data-index=\"${index}\">\n <img \n src=\"${media.thumbnailUrl || media.url}\" \n alt=\"Video thumbnail\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n <div class=\"sm-card__play-button\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M8 5v14l11-7z\"/></svg>\n </div>\n </div>\n `;\n }\n \n return `\n <div class=\"sm-card__media-item\" data-index=\"${index}\">\n <img \n src=\"${media.url}\" \n alt=\"Post media\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n </div>\n `;\n }).join('');\n\n return `<div class=\"sm-card__media ${gridClass}\">${mediaItems}</div>`;\n }\n\n /**\n * Render Instagram media\n */\n private renderInstagramMedia(post: InstagramPost): string {\n const media = post.media;\n const aspectRatio = media.aspectRatio || 1;\n \n if (media.type === 'carousel' && media.carouselItems?.length) {\n return `\n <div class=\"sm-card__media sm-card__carousel\" style=\"aspect-ratio: ${aspectRatio}\">\n <img \n src=\"${media.carouselItems[0].url}\" \n alt=\"Post media\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n <div class=\"sm-card__carousel-indicator\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm12 0c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-6 0c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z\"/></svg>\n </div>\n </div>\n `;\n }\n\n if (media.type === 'video') {\n return `\n <div class=\"sm-card__media sm-card__media--video\" style=\"aspect-ratio: ${aspectRatio}\">\n <img \n src=\"${media.thumbnailUrl || media.url}\" \n alt=\"Video thumbnail\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n <div class=\"sm-card__play-button\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M8 5v14l11-7z\"/></svg>\n </div>\n </div>\n `;\n }\n\n return `\n <div class=\"sm-card__media\" style=\"aspect-ratio: ${aspectRatio}\">\n <img \n src=\"${media.url}\" \n alt=\"Post media\"\n loading=\"${this.options.imageLoading}\"\n onerror=\"this.src='${this.options.fallbackImage}'\"\n />\n </div>\n `;\n }\n\n /**\n * Render footer with metrics\n */\n private renderFooter(post: SocialPost): string {\n const parts: string[] = [];\n\n if (this.options.showMetrics && post.metrics) {\n parts.push(this.renderMetrics(post));\n }\n\n if (this.options.showTimestamp) {\n const date = post.createdAt instanceof Date \n ? post.createdAt \n : new Date(post.createdAt);\n parts.push(`\n <time class=\"sm-card__timestamp\" datetime=\"${date.toISOString()}\">\n ${this.options.formatDate(date)}\n </time>\n `);\n }\n\n return `<div class=\"sm-card__footer\">${parts.join('')}</div>`;\n }\n\n /**\n * Render metrics\n */\n private renderMetrics(post: SocialPost): string {\n if (!post.metrics) return '';\n\n const formatNum = this.options.formatNumber;\n\n if (isTwitterPost(post)) {\n const metrics = post.metrics;\n return `\n <div class=\"sm-card__metrics\">\n ${metrics.replies !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z\"/></svg>\n ${formatNum(metrics.replies)}\n </span>\n ` : ''}\n ${metrics.retweets !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M4.5 3.88l4.432 4.14-1.364 1.46L5.5 7.55V16c0 1.1.896 2 2 2H13v2H7.5c-2.209 0-4-1.79-4-4V7.55L1.432 9.48.068 8.02 4.5 3.88zM16.5 6H11V4h5.5c2.209 0 4 1.79 4 4v8.45l2.068-1.93 1.364 1.46-4.432 4.14-4.432-4.14 1.364-1.46 2.068 1.93V8c0-1.1-.896-2-2-2z\"/></svg>\n ${formatNum(metrics.retweets)}\n </span>\n ` : ''}\n ${metrics.likes !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M16.697 5.5c-1.222-.06-2.679.51-3.89 2.16l-.805 1.09-.806-1.09C9.984 6.01 8.526 5.44 7.304 5.5c-1.243.07-2.349.78-2.91 1.91-.552 1.12-.633 2.78.479 4.82 1.074 1.97 3.257 4.27 7.129 6.61 3.87-2.34 6.052-4.64 7.126-6.61 1.111-2.04 1.03-3.7.477-4.82-.561-1.13-1.666-1.84-2.908-1.91zm4.187 7.69c-1.351 2.48-4.001 5.12-8.379 7.67l-.503.3-.504-.3c-4.379-2.55-7.029-5.19-8.382-7.67-1.36-2.5-1.41-4.86-.514-6.67.887-1.79 2.647-2.91 4.601-3.01 1.651-.09 3.368.56 4.798 2.01 1.429-1.45 3.146-2.1 4.796-2.01 1.954.1 3.714 1.22 4.601 3.01.896 1.81.846 4.17-.514 6.67z\"/></svg>\n ${formatNum(metrics.likes)}\n </span>\n ` : ''}\n ${metrics.views !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M8.75 21V3h2v18h-2zM18 21V8.5h2V21h-2zM4 21l.004-10h2L6 21H4zm9.248 0v-7h2v7h-2z\"/></svg>\n ${formatNum(metrics.views)}\n </span>\n ` : ''}\n </div>\n `;\n }\n\n if (isInstagramPost(post)) {\n const metrics = post.metrics;\n return `\n <div class=\"sm-card__metrics\">\n ${metrics.likes !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M16.792 3.904A4.989 4.989 0 0 1 21.5 9.122c0 3.072-2.652 4.959-5.197 7.222-2.512 2.243-3.865 3.469-4.303 3.752-.477-.309-2.143-1.823-4.303-3.752C5.141 14.072 2.5 12.167 2.5 9.122a4.989 4.989 0 0 1 4.708-5.218 4.21 4.21 0 0 1 3.675 1.941c.84 1.175.98 1.763 1.12 1.763s.278-.588 1.11-1.766a4.17 4.17 0 0 1 3.679-1.938m0-2a6.04 6.04 0 0 0-4.797 2.127 6.052 6.052 0 0 0-4.787-2.127A6.985 6.985 0 0 0 .5 9.122c0 3.61 2.55 5.827 5.015 7.97.283.246.569.494.853.747l1.027.918a44.998 44.998 0 0 0 3.518 3.018 2 2 0 0 0 2.174 0 45.263 45.263 0 0 0 3.626-3.115l.922-.824c.293-.26.59-.519.885-.774 2.334-2.025 4.98-4.32 4.98-7.94a6.985 6.985 0 0 0-6.708-7.218z\"/></svg>\n ${formatNum(metrics.likes)}\n </span>\n ` : ''}\n ${metrics.comments !== undefined ? `\n <span class=\"sm-card__metric\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M20.656 17.008a9.993 9.993 0 1 0-3.59 3.615L22 22l-1.344-4.992zM10 12a1 1 0 1 1 1 1 1 1 0 0 1-1-1zm-4 0a1 1 0 1 1 1 1 1 1 0 0 1-1-1zm8 0a1 1 0 1 1 1 1 1 1 0 0 1-1-1z\"/></svg>\n ${formatNum(metrics.comments)}\n </span>\n ` : ''}\n </div>\n `;\n }\n\n return '';\n }\n\n /**\n * Linkify text (URLs, mentions, hashtags)\n */\n private linkifyText(text: string): string {\n // Escape HTML\n let result = text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n\n // URLs\n result = result.replace(\n /(https?:\\/\\/[^\\s]+)/g,\n '<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"sm-card__link\">$1</a>'\n );\n\n // Mentions\n result = result.replace(\n /@(\\w+)/g,\n '<a href=\"#\" class=\"sm-card__mention\" data-username=\"$1\">@$1</a>'\n );\n\n // Hashtags\n result = result.replace(\n /#(\\w+)/g,\n '<a href=\"#\" class=\"sm-card__hashtag\" data-tag=\"$1\">#$1</a>'\n );\n\n return result;\n }\n\n /**\n * Attach event listeners\n */\n private attachEventListeners(card: HTMLElement, post: SocialPost): void {\n // Post click\n if (this.options.onPostClick) {\n card.addEventListener('click', (e) => {\n // Don't fire for links, buttons, etc.\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.closest('a')) return;\n \n this.options.onPostClick?.(post, e);\n });\n card.style.cursor = 'pointer';\n }\n\n // Author click\n if (this.options.onAuthorClick) {\n const header = card.querySelector('.sm-card__header');\n if (header) {\n header.addEventListener('click', (e) => {\n e.stopPropagation();\n this.options.onAuthorClick?.(post, e as MouseEvent);\n });\n (header as HTMLElement).style.cursor = 'pointer';\n }\n }\n\n // Media click\n if (this.options.onMediaClick) {\n const mediaItems = card.querySelectorAll('.sm-card__media-item');\n mediaItems.forEach((item) => {\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n const index = parseInt((item as HTMLElement).dataset.index || '0', 10);\n this.options.onMediaClick?.(post, index, e as MouseEvent);\n });\n (item as HTMLElement).style.cursor = 'pointer';\n });\n }\n\n // Image error handling\n if (this.options.onImageError) {\n const images = card.querySelectorAll('img');\n images.forEach((img) => {\n img.addEventListener('error', () => {\n this.options.onImageError?.(post, new Error('Image failed to load'));\n });\n });\n }\n }\n\n /**\n * Update card position\n */\n updatePosition(card: HTMLElement, position: ItemPosition): void {\n Object.assign(card.style, {\n left: `${position.x}px`,\n top: `${position.y}px`,\n width: `${position.width}px`,\n });\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<CardRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n}\n\n/**\n * Create a new card renderer instance\n */\nexport function createCardRenderer(options?: CardRendererOptions): CardRenderer {\n return new CardRenderer(options);\n}\n","/**\n * Social Masonry - Main Class\n * Beautiful masonry layout for X (Twitter) and Instagram embeds\n */\n\nimport type {\n SocialMasonryOptions,\n SocialPost,\n ItemPosition,\n VirtualItem,\n} from './types';\nimport { LayoutEngine } from './layout-engine';\nimport { VirtualizationEngine } from './virtualization-engine';\nimport { CardRenderer } from './card-renderer';\nimport {\n debounce,\n defaultColumnConfig,\n supportsResizeObserver,\n isBrowser,\n generateId,\n} from './utils';\n\nconst DEFAULT_OPTIONS: Partial<SocialMasonryOptions> = {\n // Layout\n gap: 16,\n columns: defaultColumnConfig,\n defaultColumns: 3,\n padding: 0,\n animationDuration: 300,\n animate: true,\n easing: 'cubic-bezier(0.4, 0, 0.2, 1)',\n \n // Card\n variant: 'default',\n theme: 'auto',\n borderRadius: 12,\n showPlatformIcon: true,\n showAuthor: true,\n showMetrics: true,\n showTimestamp: true,\n hoverEffect: true,\n imageLoading: 'lazy',\n \n // Virtualization\n virtualization: {\n enabled: false,\n overscan: 3,\n estimatedItemHeight: 400,\n scrollContainer: null,\n },\n \n // Infinite scroll\n loadMoreThreshold: 500,\n showLoading: true,\n \n // Debug\n debug: false,\n};\n\nexport class SocialMasonry {\n private options: SocialMasonryOptions;\n private container: HTMLElement;\n private posts: SocialPost[] = [];\n private layoutEngine: LayoutEngine;\n private virtualizationEngine: VirtualizationEngine | null = null;\n private cardRenderer: CardRenderer;\n private cards: Map<string, HTMLElement> = new Map();\n private itemHeights: Map<string, number> = new Map();\n private resizeObserver: ResizeObserver | null = null;\n private isLoading = false;\n private instanceId: string;\n\n constructor(options: SocialMasonryOptions) {\n if (!isBrowser) {\n throw new Error('SocialMasonry requires a browser environment');\n }\n\n this.instanceId = generateId();\n this.options = { ...DEFAULT_OPTIONS, ...options } as SocialMasonryOptions;\n \n // Get container element\n const container = typeof options.container === 'string'\n ? document.querySelector(options.container)\n : options.container;\n \n if (!container) {\n throw new Error('Container element not found');\n }\n \n this.container = container as HTMLElement;\n this.posts = options.posts || [];\n\n // Initialize layout engine\n this.layoutEngine = new LayoutEngine({\n ...this.options,\n containerWidth: this.container.clientWidth,\n itemHeights: this.itemHeights,\n });\n\n // Initialize card renderer\n this.cardRenderer = new CardRenderer({\n ...this.options,\n });\n\n // Initialize virtualization if enabled\n if (this.options.virtualization?.enabled) {\n this.initVirtualization();\n }\n\n // Setup\n this.setupContainer();\n this.setupResizeObserver();\n this.render();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Initialized', {\n instanceId: this.instanceId,\n posts: this.posts.length,\n containerWidth: this.container.clientWidth,\n });\n }\n }\n\n /**\n * Setup container styles\n */\n private setupContainer(): void {\n this.container.classList.add('sm-container');\n this.container.setAttribute('data-sm-instance', this.instanceId);\n \n Object.assign(this.container.style, {\n position: 'relative',\n width: '100%',\n });\n }\n\n /**\n * Setup resize observer\n */\n private setupResizeObserver(): void {\n if (!supportsResizeObserver) {\n // Fallback to window resize\n window.addEventListener('resize', debounce(() => this.handleResize(), 150));\n return;\n }\n\n this.resizeObserver = new ResizeObserver(\n debounce((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n if (entry.target === this.container) {\n this.handleResize();\n }\n }\n }, 150)\n );\n\n this.resizeObserver.observe(this.container);\n }\n\n /**\n * Handle container resize\n */\n private handleResize(): void {\n const newWidth = this.container.clientWidth;\n this.layoutEngine.setContainerWidth(newWidth);\n this.recalculateLayout();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Resize', { width: newWidth });\n }\n }\n\n /**\n * Initialize virtualization\n */\n private initVirtualization(): void {\n const state = this.layoutEngine.getState();\n \n this.virtualizationEngine = new VirtualizationEngine({\n ...this.options.virtualization,\n posts: this.posts,\n positions: state.positions,\n onVisibleItemsChange: (items) => this.handleVisibleItemsChange(items),\n });\n\n this.virtualizationEngine.init();\n\n // Setup infinite scroll\n if (this.options.onLoadMore) {\n this.setupInfiniteScroll();\n }\n }\n\n /**\n * Handle visible items change (for virtualization)\n */\n private handleVisibleItemsChange(items: VirtualItem[]): void {\n const visibleIds = new Set(items.map(item => item.post.id));\n \n // Remove cards that are no longer visible\n for (const [id, card] of this.cards) {\n if (!visibleIds.has(id)) {\n card.remove();\n this.cards.delete(id);\n }\n }\n\n // Add new visible cards\n for (const item of items) {\n if (!this.cards.has(item.post.id)) {\n this.renderCard(item.post, item.position);\n }\n }\n }\n\n /**\n * Setup infinite scroll\n */\n private setupInfiniteScroll(): void {\n const checkLoadMore = () => {\n if (\n !this.isLoading &&\n this.virtualizationEngine?.isNearBottom(this.options.loadMoreThreshold || 500)\n ) {\n this.loadMore();\n }\n };\n\n const scrollContainer = this.options.virtualization?.scrollContainer ?? window;\n scrollContainer.addEventListener('scroll', checkLoadMore, { passive: true });\n }\n\n /**\n * Load more posts\n */\n private async loadMore(): Promise<void> {\n if (this.isLoading || !this.options.onLoadMore) return;\n\n this.isLoading = true;\n this.showLoadingIndicator();\n\n try {\n await this.options.onLoadMore();\n } finally {\n this.isLoading = false;\n this.hideLoadingIndicator();\n }\n }\n\n /**\n * Show loading indicator\n */\n private showLoadingIndicator(): void {\n if (!this.options.showLoading) return;\n\n let loader = this.container.querySelector('.sm-loader');\n if (!loader) {\n loader = document.createElement('div');\n loader.className = 'sm-loader';\n \n if (this.options.loadingElement) {\n if (typeof this.options.loadingElement === 'string') {\n loader.innerHTML = this.options.loadingElement;\n } else {\n loader.appendChild(this.options.loadingElement.cloneNode(true));\n }\n } else {\n loader.innerHTML = `\n <div class=\"sm-loader__spinner\">\n <div></div><div></div><div></div>\n </div>\n `;\n }\n \n this.container.appendChild(loader);\n }\n\n (loader as HTMLElement).style.display = 'flex';\n }\n\n /**\n * Hide loading indicator\n */\n private hideLoadingIndicator(): void {\n const loader = this.container.querySelector('.sm-loader');\n if (loader) {\n (loader as HTMLElement).style.display = 'none';\n }\n }\n\n /**\n * Render all posts\n */\n private render(): void {\n // Calculate layout\n const state = this.layoutEngine.calculate(this.posts);\n \n // Update container height\n this.container.style.height = `${state.containerHeight}px`;\n\n // Apply CSS variables\n const cssVars = this.layoutEngine.getCSSVariables();\n for (const [key, value] of Object.entries(cssVars)) {\n this.container.style.setProperty(key, value);\n }\n\n // Render cards\n if (this.virtualizationEngine) {\n // Virtualized rendering\n this.virtualizationEngine.update(this.posts, state.positions);\n const visibleItems = this.virtualizationEngine.calculateVisibleItems();\n this.handleVisibleItemsChange(visibleItems);\n } else {\n // Full rendering\n for (const post of this.posts) {\n const position = state.positions.get(post.id);\n if (position) {\n this.renderCard(post, position);\n }\n }\n }\n\n // Show empty state if no posts\n if (this.posts.length === 0) {\n this.showEmptyState();\n } else {\n this.hideEmptyState();\n }\n\n // Callback\n this.options.onLayoutComplete?.(Array.from(state.positions.values()));\n }\n\n /**\n * Render a single card\n */\n private renderCard(post: SocialPost, position: ItemPosition): void {\n let card = this.cards.get(post.id);\n\n if (card) {\n // Update existing card position\n this.cardRenderer.updatePosition(card, position);\n } else {\n // Create new card\n card = this.cardRenderer.render(post, position);\n this.container.appendChild(card);\n this.cards.set(post.id, card);\n\n // Measure actual height after render\n requestAnimationFrame(() => {\n if (card) {\n const actualHeight = card.offsetHeight;\n if (actualHeight !== position.height) {\n this.itemHeights.set(post.id, actualHeight);\n this.recalculateLayout();\n }\n }\n });\n }\n }\n\n /**\n * Recalculate layout\n */\n private recalculateLayout(): void {\n const state = this.layoutEngine.calculate(this.posts);\n this.container.style.height = `${state.containerHeight}px`;\n\n // Update virtualization\n if (this.virtualizationEngine) {\n this.virtualizationEngine.update(this.posts, state.positions);\n }\n\n // Update card positions with animation\n for (const [id, card] of this.cards) {\n const position = state.positions.get(id);\n if (position) {\n if (this.options.animate) {\n card.style.transition = `left ${this.options.animationDuration}ms ${this.options.easing}, top ${this.options.animationDuration}ms ${this.options.easing}, width ${this.options.animationDuration}ms ${this.options.easing}`;\n }\n this.cardRenderer.updatePosition(card, position);\n }\n }\n\n this.options.onLayoutComplete?.(Array.from(state.positions.values()));\n }\n\n /**\n * Show empty state\n */\n private showEmptyState(): void {\n let empty = this.container.querySelector('.sm-empty');\n if (!empty) {\n empty = document.createElement('div');\n empty.className = 'sm-empty';\n \n if (this.options.emptyElement) {\n if (typeof this.options.emptyElement === 'string') {\n empty.innerHTML = this.options.emptyElement;\n } else {\n empty.appendChild(this.options.emptyElement.cloneNode(true));\n }\n } else {\n empty.textContent = this.options.emptyMessage || 'No posts to display';\n }\n \n this.container.appendChild(empty);\n }\n\n (empty as HTMLElement).style.display = 'flex';\n }\n\n /**\n * Hide empty state\n */\n private hideEmptyState(): void {\n const empty = this.container.querySelector('.sm-empty');\n if (empty) {\n (empty as HTMLElement).style.display = 'none';\n }\n }\n\n // ============================================\n // Public API\n // ============================================\n\n /**\n * Add posts\n */\n addPosts(posts: SocialPost[]): void {\n this.posts = [...this.posts, ...posts];\n this.render();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Added posts', { count: posts.length, total: this.posts.length });\n }\n }\n\n /**\n * Set posts (replace all)\n */\n setPosts(posts: SocialPost[]): void {\n // Clear existing cards\n for (const card of this.cards.values()) {\n card.remove();\n }\n this.cards.clear();\n this.itemHeights.clear();\n\n this.posts = posts;\n this.render();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Set posts', { count: posts.length });\n }\n }\n\n /**\n * Remove post\n */\n removePost(id: string): void {\n const card = this.cards.get(id);\n if (card) {\n card.remove();\n this.cards.delete(id);\n }\n \n this.itemHeights.delete(id);\n this.posts = this.posts.filter(p => p.id !== id);\n this.recalculateLayout();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Removed post', { id });\n }\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<SocialMasonryOptions>): void {\n this.options = { ...this.options, ...options };\n this.cardRenderer.setOptions(options);\n this.recalculateLayout();\n }\n\n /**\n * Get layout state\n */\n getLayoutState() {\n return this.layoutEngine.getState();\n }\n\n /**\n * Get posts\n */\n getPosts(): SocialPost[] {\n return [...this.posts];\n }\n\n /**\n * Scroll to post\n */\n scrollToPost(id: string, behavior: ScrollBehavior = 'smooth'): void {\n if (this.virtualizationEngine) {\n this.virtualizationEngine.scrollToItem(id, behavior);\n } else {\n const position = this.layoutEngine.getPosition(id);\n if (position) {\n window.scrollTo({\n top: position.y,\n behavior,\n });\n }\n }\n }\n\n /**\n * Refresh layout\n */\n refresh(): void {\n this.itemHeights.clear();\n this.recalculateLayout();\n }\n\n /**\n * Destroy instance\n */\n destroy(): void {\n // Remove cards\n for (const card of this.cards.values()) {\n card.remove();\n }\n this.cards.clear();\n\n // Remove observers\n this.resizeObserver?.disconnect();\n\n // Destroy virtualization\n this.virtualizationEngine?.destroy();\n\n // Clean up container\n this.container.classList.remove('sm-container');\n this.container.removeAttribute('data-sm-instance');\n this.container.style.cssText = '';\n\n // Remove internal elements\n const loader = this.container.querySelector('.sm-loader');\n const empty = this.container.querySelector('.sm-empty');\n loader?.remove();\n empty?.remove();\n \n if (this.options.debug) {\n console.log('[SocialMasonry] Destroyed', { instanceId: this.instanceId });\n }\n }\n}\n\n/**\n * Create a new SocialMasonry instance\n */\nexport function createSocialMasonry(options: SocialMasonryOptions): SocialMasonry {\n return new SocialMasonry(options);\n}\n\nexport default SocialMasonry;\n"],"names":["DEFAULT_OPTIONS","defaultFormatNumber"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/layout-engine.ts"],"sourcesContent":["/**\n * Social Masonry - Utility Functions\n */\n\nimport type { ColumnConfig, SocialPost, SocialPlatform } from './types';\n\n// ============================================\n// URL Parsing Utilities\n// ============================================\n\n/**\n * Extract tweet ID from Twitter/X URL\n */\nexport function extractTweetId(url: string): string | null {\n if (!url) return null;\n const match = url.match(/(?:twitter\\.com|x\\.com)\\/\\w+\\/status\\/(\\d+)/);\n return match ? match[1] : null;\n}\n\n/**\n * Extract post ID from Instagram URL\n */\nexport function extractInstagramId(url: string): string | null {\n if (!url) return null;\n const match = url.match(/instagram\\.com\\/(?:p|reel)\\/([A-Za-z0-9_-]+)/);\n return match ? match[1] : null;\n}\n\n/**\n * Detect platform from URL\n */\nexport function detectPlatform(url: string): SocialPlatform | null {\n if (/(?:twitter\\.com|x\\.com)\\/\\w+\\/status\\/\\d+/.test(url)) {\n return 'twitter';\n }\n if (/instagram\\.com\\/(?:p|reel)\\/[A-Za-z0-9_-]+/.test(url)) {\n return 'instagram';\n }\n return null;\n}\n\n/**\n * Generate embed URL for Twitter\n */\nexport function getTwitterEmbedUrl(\n tweetId: string,\n options: { theme?: 'light' | 'dark'; hideCard?: boolean; hideThread?: boolean } = {}\n): string {\n const params = new URLSearchParams();\n params.set('id', tweetId);\n if (options.theme) params.set('theme', options.theme);\n if (options.hideCard) params.set('cards', 'hidden');\n if (options.hideThread) params.set('conversation', 'none');\n return `https://platform.twitter.com/embed/Tweet.html?${params.toString()}`;\n}\n\n/**\n * Generate embed URL for Instagram\n */\nexport function getInstagramEmbedUrl(postId: string): string {\n return `https://www.instagram.com/p/${postId}/embed/`;\n}\n\n/**\n * Generate unique ID from post URL\n */\nexport function generatePostId(post: SocialPost): string {\n if (post.id) return post.id;\n\n if (post.platform === 'twitter') {\n const tweetId = extractTweetId(post.url);\n return tweetId ? `tw-${tweetId}` : `tw-${hashString(post.url)}`;\n }\n\n if (post.platform === 'instagram') {\n const igId = extractInstagramId(post.url);\n return igId ? `ig-${igId}` : `ig-${hashString(post.url)}`;\n }\n\n return `post-${hashString(post.url)}`;\n}\n\n/**\n * Simple string hash function\n */\nfunction hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n// ============================================\n// Layout Utilities\n// ============================================\n\n/**\n * Debounce function execution\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n timeoutId = null;\n }, delay);\n };\n}\n\n/**\n * Get number of columns based on viewport width\n */\nexport function getColumnCount(\n columns: number | ColumnConfig[],\n containerWidth: number\n): number {\n if (typeof columns === 'number') {\n return columns;\n }\n\n // Sort by minWidth descending\n const sorted = [...columns].sort((a, b) => b.minWidth - a.minWidth);\n\n for (const config of sorted) {\n if (containerWidth >= config.minWidth) {\n return config.columns;\n }\n }\n\n // Return smallest breakpoint's columns or default to 1\n return sorted[sorted.length - 1]?.columns ?? 1;\n}\n\n/**\n * Default responsive column configuration\n */\nexport const defaultColumnConfig: ColumnConfig[] = [\n { columns: 4, minWidth: 1200 },\n { columns: 3, minWidth: 900 },\n { columns: 2, minWidth: 600 },\n { columns: 1, minWidth: 0 },\n];\n\n/**\n * Default embed heights\n */\nexport const DEFAULT_TWITTER_HEIGHT = 500;\nexport const DEFAULT_INSTAGRAM_HEIGHT = 600;\n\n// ============================================\n// Environment Checks\n// ============================================\n\n/**\n * Check if we're in a browser environment\n */\nexport const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n\n/**\n * Check if ResizeObserver is supported\n */\nexport const supportsResizeObserver = isBrowser && typeof ResizeObserver !== 'undefined';\n","/**\n * Social Masonry - Layout Engine\n * Calculates positions for masonry grid items\n */\n\nimport type {\n ItemPosition,\n LayoutState,\n MasonryConfig,\n SocialPost,\n} from './types';\nimport {\n defaultColumnConfig,\n getColumnCount,\n generatePostId,\n DEFAULT_TWITTER_HEIGHT,\n DEFAULT_INSTAGRAM_HEIGHT,\n} from './utils';\n\nexport interface LayoutEngineOptions extends MasonryConfig {\n containerWidth: number;\n itemHeights: Map<string, number>;\n twitterHeight?: number;\n instagramHeight?: number;\n}\n\nexport class LayoutEngine {\n private options: Required<LayoutEngineOptions>;\n private state: LayoutState;\n\n constructor(options: LayoutEngineOptions) {\n this.options = {\n gap: 16,\n columns: defaultColumnConfig,\n padding: 0,\n animationDuration: 300,\n animate: true,\n twitterHeight: DEFAULT_TWITTER_HEIGHT,\n instagramHeight: DEFAULT_INSTAGRAM_HEIGHT,\n ...options,\n };\n\n this.state = {\n positions: new Map(),\n columnHeights: [],\n containerHeight: 0,\n columnWidth: 0,\n };\n }\n\n /**\n * Calculate layout for all posts\n */\n calculate(posts: SocialPost[]): LayoutState {\n const { containerWidth, itemHeights, gap, padding } = this.options;\n\n // Calculate column count and width\n const columnCount = getColumnCount(this.options.columns, containerWidth);\n const availableWidth = containerWidth - padding * 2;\n const totalGapWidth = gap * (columnCount - 1);\n const columnWidth = (availableWidth - totalGapWidth) / columnCount;\n\n // Initialize column heights\n const columnHeights = new Array(columnCount).fill(0);\n const positions = new Map<string, ItemPosition>();\n\n // Place each item in the shortest column\n for (const post of posts) {\n const postId = generatePostId(post);\n const itemHeight = itemHeights.get(postId) ?? this.getDefaultHeight(post);\n\n // Find shortest column\n const shortestColumn = columnHeights.indexOf(Math.min(...columnHeights));\n\n // Calculate position\n const x = padding + shortestColumn * (columnWidth + gap);\n const y = columnHeights[shortestColumn];\n\n positions.set(postId, {\n id: postId,\n x,\n y,\n width: columnWidth,\n height: itemHeight,\n column: shortestColumn,\n });\n\n // Update column height\n columnHeights[shortestColumn] = y + itemHeight + gap;\n }\n\n // Remove last gap from column heights\n const containerHeight = Math.max(...columnHeights.map(h => h - gap), 0);\n\n this.state = {\n positions,\n columnHeights,\n containerHeight,\n columnWidth,\n };\n\n return this.state;\n }\n\n /**\n * Get default height for embed based on platform\n */\n private getDefaultHeight(post: SocialPost): number {\n if (post.platform === 'twitter') {\n return this.options.twitterHeight;\n }\n if (post.platform === 'instagram') {\n return this.options.instagramHeight;\n }\n return DEFAULT_TWITTER_HEIGHT;\n }\n\n /**\n * Update single item height\n */\n updateItemHeight(id: string, height: number): void {\n this.options.itemHeights.set(id, height);\n }\n\n /**\n * Get current layout state\n */\n getState(): LayoutState {\n return this.state;\n }\n\n /**\n * Get position for specific item\n */\n getPosition(id: string): ItemPosition | undefined {\n return this.state.positions.get(id);\n }\n\n /**\n * Update container width\n */\n setContainerWidth(width: number): void {\n this.options.containerWidth = width;\n }\n\n /**\n * Get current column count\n */\n getColumnCount(): number {\n return getColumnCount(this.options.columns, this.options.containerWidth);\n }\n}\n\n/**\n * Create a new layout engine instance\n */\nexport function createLayoutEngine(options: LayoutEngineOptions): LayoutEngine {\n return new LayoutEngine(options);\n}\n"],"names":[],"mappings":"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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,69 +1,18 @@
|
|
|
1
1
|
import React$1 from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
text: string;
|
|
15
|
-
html?: string;
|
|
16
|
-
};
|
|
17
|
-
media?: {
|
|
18
|
-
type: 'image' | 'video' | 'gif';
|
|
19
|
-
url: string;
|
|
20
|
-
thumbnailUrl?: string;
|
|
21
|
-
aspectRatio?: number;
|
|
22
|
-
width?: number;
|
|
23
|
-
height?: number;
|
|
24
|
-
}[];
|
|
25
|
-
metrics?: {
|
|
26
|
-
likes?: number;
|
|
27
|
-
retweets?: number;
|
|
28
|
-
replies?: number;
|
|
29
|
-
views?: number;
|
|
30
|
-
};
|
|
31
|
-
createdAt: string | Date;
|
|
32
|
-
quotedPost?: Omit<TwitterPost, 'quotedPost'>;
|
|
33
|
-
}
|
|
34
|
-
interface InstagramPost {
|
|
35
|
-
platform: 'instagram';
|
|
36
|
-
id: string;
|
|
3
|
+
/**
|
|
4
|
+
* Social Masonry - Type Definitions
|
|
5
|
+
* Masonry layout for social media iframe embeds
|
|
6
|
+
*/
|
|
7
|
+
type SocialPlatform = 'twitter' | 'instagram';
|
|
8
|
+
interface SocialPost {
|
|
9
|
+
/** Unique identifier (auto-generated from URL if not provided) */
|
|
10
|
+
id?: string;
|
|
11
|
+
/** Social media platform */
|
|
12
|
+
platform: SocialPlatform;
|
|
13
|
+
/** Post URL */
|
|
37
14
|
url: string;
|
|
38
|
-
author: {
|
|
39
|
-
username: string;
|
|
40
|
-
displayName?: string;
|
|
41
|
-
avatarUrl?: string;
|
|
42
|
-
verified?: boolean;
|
|
43
|
-
};
|
|
44
|
-
content: {
|
|
45
|
-
caption?: string;
|
|
46
|
-
};
|
|
47
|
-
media: {
|
|
48
|
-
type: 'image' | 'video' | 'carousel';
|
|
49
|
-
url: string;
|
|
50
|
-
thumbnailUrl?: string;
|
|
51
|
-
aspectRatio?: number;
|
|
52
|
-
width?: number;
|
|
53
|
-
height?: number;
|
|
54
|
-
carouselItems?: {
|
|
55
|
-
type: 'image' | 'video';
|
|
56
|
-
url: string;
|
|
57
|
-
thumbnailUrl?: string;
|
|
58
|
-
}[];
|
|
59
|
-
};
|
|
60
|
-
metrics?: {
|
|
61
|
-
likes?: number;
|
|
62
|
-
comments?: number;
|
|
63
|
-
};
|
|
64
|
-
createdAt: string | Date;
|
|
65
15
|
}
|
|
66
|
-
type SocialPost = TwitterPost | InstagramPost;
|
|
67
16
|
interface ColumnConfig {
|
|
68
17
|
/** Number of columns at this breakpoint */
|
|
69
18
|
columns: number;
|
|
@@ -71,74 +20,36 @@ interface ColumnConfig {
|
|
|
71
20
|
minWidth: number;
|
|
72
21
|
}
|
|
73
22
|
interface MasonryConfig {
|
|
74
|
-
/** Gap between items (px
|
|
75
|
-
gap?: number
|
|
23
|
+
/** Gap between items (px) */
|
|
24
|
+
gap?: number;
|
|
76
25
|
/** Responsive column configuration */
|
|
77
26
|
columns?: number | ColumnConfig[];
|
|
78
|
-
/**
|
|
79
|
-
|
|
80
|
-
/** Padding around the container */
|
|
81
|
-
padding?: number | string;
|
|
27
|
+
/** Padding around the container (px) */
|
|
28
|
+
padding?: number;
|
|
82
29
|
/** Animation duration for layout changes (ms) */
|
|
83
30
|
animationDuration?: number;
|
|
84
31
|
/** Enable/disable animations */
|
|
85
32
|
animate?: boolean;
|
|
86
|
-
/** Transition easing function */
|
|
87
|
-
easing?: string;
|
|
88
33
|
}
|
|
89
|
-
interface
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
type CardTheme = 'light' | 'dark' | 'auto';
|
|
101
|
-
interface CardConfig {
|
|
102
|
-
/** Card visual variant */
|
|
103
|
-
variant?: CardVariant;
|
|
104
|
-
/** Color theme */
|
|
105
|
-
theme?: CardTheme;
|
|
106
|
-
/** Border radius (px or CSS value) */
|
|
107
|
-
borderRadius?: number | string;
|
|
108
|
-
/** Show platform icon */
|
|
109
|
-
showPlatformIcon?: boolean;
|
|
110
|
-
/** Show author info */
|
|
111
|
-
showAuthor?: boolean;
|
|
112
|
-
/** Show metrics (likes, comments, etc.) */
|
|
113
|
-
showMetrics?: boolean;
|
|
114
|
-
/** Show timestamp */
|
|
115
|
-
showTimestamp?: boolean;
|
|
116
|
-
/** Date format function */
|
|
117
|
-
formatDate?: (date: Date) => string;
|
|
118
|
-
/** Number format function */
|
|
119
|
-
formatNumber?: (num: number) => string;
|
|
120
|
-
/** Custom CSS class */
|
|
121
|
-
className?: string;
|
|
122
|
-
/** Enable hover effects */
|
|
123
|
-
hoverEffect?: boolean;
|
|
124
|
-
/** Image loading strategy */
|
|
125
|
-
imageLoading?: 'lazy' | 'eager';
|
|
126
|
-
/** Fallback image URL */
|
|
127
|
-
fallbackImage?: string;
|
|
34
|
+
interface EmbedConfig {
|
|
35
|
+
/** Theme for embeds: 'light' or 'dark' */
|
|
36
|
+
theme?: 'light' | 'dark';
|
|
37
|
+
/** Default height for Twitter embeds (px) */
|
|
38
|
+
twitterHeight?: number;
|
|
39
|
+
/** Default height for Instagram embeds (px) */
|
|
40
|
+
instagramHeight?: number;
|
|
41
|
+
/** Hide Twitter card (show only text) */
|
|
42
|
+
twitterHideCard?: boolean;
|
|
43
|
+
/** Hide Twitter conversation thread */
|
|
44
|
+
twitterHideThread?: boolean;
|
|
128
45
|
}
|
|
129
46
|
interface MasonryEvents {
|
|
130
|
-
/** Called when a post card is clicked */
|
|
131
|
-
onPostClick?: (post: SocialPost, event: MouseEvent) => void;
|
|
132
|
-
/** Called when author is clicked */
|
|
133
|
-
onAuthorClick?: (post: SocialPost, event: MouseEvent) => void;
|
|
134
|
-
/** Called when media is clicked */
|
|
135
|
-
onMediaClick?: (post: SocialPost, mediaIndex: number, event: MouseEvent) => void;
|
|
136
47
|
/** Called when layout is recalculated */
|
|
137
48
|
onLayoutComplete?: (positions: ItemPosition[]) => void;
|
|
138
|
-
/** Called when
|
|
139
|
-
|
|
140
|
-
/** Called when an
|
|
141
|
-
|
|
49
|
+
/** Called when an embed loads */
|
|
50
|
+
onEmbedLoad?: (post: SocialPost) => void;
|
|
51
|
+
/** Called when an embed fails to load */
|
|
52
|
+
onEmbedError?: (post: SocialPost, error: Error) => void;
|
|
142
53
|
}
|
|
143
54
|
interface ItemPosition {
|
|
144
55
|
id: string;
|
|
@@ -148,38 +59,22 @@ interface ItemPosition {
|
|
|
148
59
|
height: number;
|
|
149
60
|
column: number;
|
|
150
61
|
}
|
|
151
|
-
interface SocialMasonryOptions extends MasonryConfig,
|
|
62
|
+
interface SocialMasonryOptions extends MasonryConfig, EmbedConfig, MasonryEvents {
|
|
152
63
|
/** Posts to display */
|
|
153
64
|
posts: SocialPost[];
|
|
154
|
-
/** Container element or selector */
|
|
155
|
-
container
|
|
156
|
-
/** Virtualization settings */
|
|
157
|
-
virtualization?: VirtualizationConfig;
|
|
158
|
-
/** Load more threshold (px from bottom) */
|
|
159
|
-
loadMoreThreshold?: number;
|
|
160
|
-
/** Show loading indicator */
|
|
161
|
-
showLoading?: boolean;
|
|
162
|
-
/** Custom loading element */
|
|
163
|
-
loadingElement?: HTMLElement | string;
|
|
164
|
-
/** Empty state message */
|
|
165
|
-
emptyMessage?: string;
|
|
166
|
-
/** Custom empty state element */
|
|
167
|
-
emptyElement?: HTMLElement | string;
|
|
168
|
-
/** Enable debug mode */
|
|
169
|
-
debug?: boolean;
|
|
65
|
+
/** Container element or selector (for vanilla JS) */
|
|
66
|
+
container?: HTMLElement | string;
|
|
170
67
|
}
|
|
171
68
|
interface SocialMasonryProps extends Omit<SocialMasonryOptions, 'container'> {
|
|
172
69
|
/** Additional CSS class for container */
|
|
173
70
|
className?: string;
|
|
174
71
|
/** Inline styles for container */
|
|
175
72
|
style?: React.CSSProperties;
|
|
176
|
-
/** Ref to container element */
|
|
177
|
-
containerRef?: React.RefObject<HTMLDivElement>;
|
|
178
73
|
}
|
|
179
74
|
|
|
180
75
|
/**
|
|
181
76
|
* Social Masonry - React Component
|
|
182
|
-
*
|
|
77
|
+
* Masonry layout for X (Twitter) and Instagram embeds using official widgets
|
|
183
78
|
*/
|
|
184
79
|
|
|
185
80
|
interface SocialMasonryRef {
|
|
@@ -187,9 +82,8 @@ interface SocialMasonryRef {
|
|
|
187
82
|
setPosts: (posts: SocialPost[]) => void;
|
|
188
83
|
removePost: (id: string) => void;
|
|
189
84
|
refresh: () => void;
|
|
190
|
-
scrollToPost: (id: string, behavior?: ScrollBehavior) => void;
|
|
191
85
|
}
|
|
192
86
|
declare const SocialMasonry: React$1.ForwardRefExoticComponent<SocialMasonryProps & React$1.RefAttributes<SocialMasonryRef>>;
|
|
193
87
|
|
|
194
88
|
export { SocialMasonry, SocialMasonry as default };
|
|
195
|
-
export type {
|
|
89
|
+
export type { ColumnConfig, EmbedConfig, ItemPosition, MasonryConfig, SocialMasonryProps, SocialMasonryRef, SocialPlatform, SocialPost };
|