social-masonry 1.0.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.
@@ -0,0 +1,550 @@
1
+ /**
2
+ * Social Masonry - Type Definitions
3
+ * Beautiful masonry layout for social media embeds
4
+ */
5
+ type SocialPlatform = 'twitter' | 'instagram';
6
+ interface TwitterPost {
7
+ platform: 'twitter';
8
+ id: string;
9
+ url: string;
10
+ author: {
11
+ username: string;
12
+ displayName: string;
13
+ avatarUrl?: string;
14
+ verified?: boolean;
15
+ };
16
+ content: {
17
+ text: string;
18
+ html?: string;
19
+ };
20
+ media?: {
21
+ type: 'image' | 'video' | 'gif';
22
+ url: string;
23
+ thumbnailUrl?: string;
24
+ aspectRatio?: number;
25
+ width?: number;
26
+ height?: number;
27
+ }[];
28
+ metrics?: {
29
+ likes?: number;
30
+ retweets?: number;
31
+ replies?: number;
32
+ views?: number;
33
+ };
34
+ createdAt: string | Date;
35
+ quotedPost?: Omit<TwitterPost, 'quotedPost'>;
36
+ }
37
+ interface InstagramPost {
38
+ platform: 'instagram';
39
+ id: string;
40
+ url: string;
41
+ author: {
42
+ username: string;
43
+ displayName?: string;
44
+ avatarUrl?: string;
45
+ verified?: boolean;
46
+ };
47
+ content: {
48
+ caption?: string;
49
+ };
50
+ media: {
51
+ type: 'image' | 'video' | 'carousel';
52
+ url: string;
53
+ thumbnailUrl?: string;
54
+ aspectRatio?: number;
55
+ width?: number;
56
+ height?: number;
57
+ carouselItems?: {
58
+ type: 'image' | 'video';
59
+ url: string;
60
+ thumbnailUrl?: string;
61
+ }[];
62
+ };
63
+ metrics?: {
64
+ likes?: number;
65
+ comments?: number;
66
+ };
67
+ createdAt: string | Date;
68
+ }
69
+ type SocialPost = TwitterPost | InstagramPost;
70
+ interface ColumnConfig {
71
+ /** Number of columns at this breakpoint */
72
+ columns: number;
73
+ /** Minimum viewport width for this config (px) */
74
+ minWidth: number;
75
+ }
76
+ interface MasonryConfig {
77
+ /** Gap between items (px or CSS value) */
78
+ gap?: number | string;
79
+ /** Responsive column configuration */
80
+ columns?: number | ColumnConfig[];
81
+ /** Default number of columns */
82
+ defaultColumns?: number;
83
+ /** Padding around the container */
84
+ padding?: number | string;
85
+ /** Animation duration for layout changes (ms) */
86
+ animationDuration?: number;
87
+ /** Enable/disable animations */
88
+ animate?: boolean;
89
+ /** Transition easing function */
90
+ easing?: string;
91
+ }
92
+ interface VirtualizationConfig {
93
+ /** Enable virtualization */
94
+ enabled?: boolean;
95
+ /** Number of items to render outside viewport */
96
+ overscan?: number;
97
+ /** Estimated item height for initial render */
98
+ estimatedItemHeight?: number;
99
+ /** Scroll container element (default: window) */
100
+ scrollContainer?: HTMLElement | Window | null;
101
+ }
102
+ type CardVariant = 'default' | 'minimal' | 'elevated' | 'bordered' | 'glass';
103
+ type CardTheme = 'light' | 'dark' | 'auto';
104
+ interface CardConfig {
105
+ /** Card visual variant */
106
+ variant?: CardVariant;
107
+ /** Color theme */
108
+ theme?: CardTheme;
109
+ /** Border radius (px or CSS value) */
110
+ borderRadius?: number | string;
111
+ /** Show platform icon */
112
+ showPlatformIcon?: boolean;
113
+ /** Show author info */
114
+ showAuthor?: boolean;
115
+ /** Show metrics (likes, comments, etc.) */
116
+ showMetrics?: boolean;
117
+ /** Show timestamp */
118
+ showTimestamp?: boolean;
119
+ /** Date format function */
120
+ formatDate?: (date: Date) => string;
121
+ /** Number format function */
122
+ formatNumber?: (num: number) => string;
123
+ /** Custom CSS class */
124
+ className?: string;
125
+ /** Enable hover effects */
126
+ hoverEffect?: boolean;
127
+ /** Image loading strategy */
128
+ imageLoading?: 'lazy' | 'eager';
129
+ /** Fallback image URL */
130
+ fallbackImage?: string;
131
+ }
132
+ interface MasonryEvents {
133
+ /** Called when a post card is clicked */
134
+ onPostClick?: (post: SocialPost, event: MouseEvent) => void;
135
+ /** Called when author is clicked */
136
+ onAuthorClick?: (post: SocialPost, event: MouseEvent) => void;
137
+ /** Called when media is clicked */
138
+ onMediaClick?: (post: SocialPost, mediaIndex: number, event: MouseEvent) => void;
139
+ /** Called when layout is recalculated */
140
+ onLayoutComplete?: (positions: ItemPosition[]) => void;
141
+ /** Called when scrolling reaches near the end */
142
+ onLoadMore?: () => void | Promise<void>;
143
+ /** Called when an image fails to load */
144
+ onImageError?: (post: SocialPost, error: Error) => void;
145
+ }
146
+ interface ItemPosition {
147
+ id: string;
148
+ x: number;
149
+ y: number;
150
+ width: number;
151
+ height: number;
152
+ column: number;
153
+ }
154
+ interface LayoutState {
155
+ positions: Map<string, ItemPosition>;
156
+ columnHeights: number[];
157
+ containerHeight: number;
158
+ columnWidth: number;
159
+ }
160
+ interface VirtualItem {
161
+ index: number;
162
+ post: SocialPost;
163
+ position: ItemPosition;
164
+ isVisible: boolean;
165
+ }
166
+ interface SocialMasonryOptions extends MasonryConfig, CardConfig, MasonryEvents {
167
+ /** Posts to display */
168
+ posts: SocialPost[];
169
+ /** Container element or selector */
170
+ container: HTMLElement | string;
171
+ /** Virtualization settings */
172
+ virtualization?: VirtualizationConfig;
173
+ /** Load more threshold (px from bottom) */
174
+ loadMoreThreshold?: number;
175
+ /** Show loading indicator */
176
+ showLoading?: boolean;
177
+ /** Custom loading element */
178
+ loadingElement?: HTMLElement | string;
179
+ /** Empty state message */
180
+ emptyMessage?: string;
181
+ /** Custom empty state element */
182
+ emptyElement?: HTMLElement | string;
183
+ /** Enable debug mode */
184
+ debug?: boolean;
185
+ }
186
+ interface SocialMasonryProps extends Omit<SocialMasonryOptions, 'container'> {
187
+ /** Additional CSS class for container */
188
+ className?: string;
189
+ /** Inline styles for container */
190
+ style?: React.CSSProperties;
191
+ /** Ref to container element */
192
+ containerRef?: React.RefObject<HTMLDivElement>;
193
+ }
194
+
195
+ declare class SocialMasonry {
196
+ private options;
197
+ private container;
198
+ private posts;
199
+ private layoutEngine;
200
+ private virtualizationEngine;
201
+ private cardRenderer;
202
+ private cards;
203
+ private itemHeights;
204
+ private resizeObserver;
205
+ private isLoading;
206
+ private instanceId;
207
+ constructor(options: SocialMasonryOptions);
208
+ /**
209
+ * Setup container styles
210
+ */
211
+ private setupContainer;
212
+ /**
213
+ * Setup resize observer
214
+ */
215
+ private setupResizeObserver;
216
+ /**
217
+ * Handle container resize
218
+ */
219
+ private handleResize;
220
+ /**
221
+ * Initialize virtualization
222
+ */
223
+ private initVirtualization;
224
+ /**
225
+ * Handle visible items change (for virtualization)
226
+ */
227
+ private handleVisibleItemsChange;
228
+ /**
229
+ * Setup infinite scroll
230
+ */
231
+ private setupInfiniteScroll;
232
+ /**
233
+ * Load more posts
234
+ */
235
+ private loadMore;
236
+ /**
237
+ * Show loading indicator
238
+ */
239
+ private showLoadingIndicator;
240
+ /**
241
+ * Hide loading indicator
242
+ */
243
+ private hideLoadingIndicator;
244
+ /**
245
+ * Render all posts
246
+ */
247
+ private render;
248
+ /**
249
+ * Render a single card
250
+ */
251
+ private renderCard;
252
+ /**
253
+ * Recalculate layout
254
+ */
255
+ private recalculateLayout;
256
+ /**
257
+ * Show empty state
258
+ */
259
+ private showEmptyState;
260
+ /**
261
+ * Hide empty state
262
+ */
263
+ private hideEmptyState;
264
+ /**
265
+ * Add posts
266
+ */
267
+ addPosts(posts: SocialPost[]): void;
268
+ /**
269
+ * Set posts (replace all)
270
+ */
271
+ setPosts(posts: SocialPost[]): void;
272
+ /**
273
+ * Remove post
274
+ */
275
+ removePost(id: string): void;
276
+ /**
277
+ * Update options
278
+ */
279
+ setOptions(options: Partial<SocialMasonryOptions>): void;
280
+ /**
281
+ * Get layout state
282
+ */
283
+ getLayoutState(): LayoutState;
284
+ /**
285
+ * Get posts
286
+ */
287
+ getPosts(): SocialPost[];
288
+ /**
289
+ * Scroll to post
290
+ */
291
+ scrollToPost(id: string, behavior?: ScrollBehavior): void;
292
+ /**
293
+ * Refresh layout
294
+ */
295
+ refresh(): void;
296
+ /**
297
+ * Destroy instance
298
+ */
299
+ destroy(): void;
300
+ }
301
+ /**
302
+ * Create a new SocialMasonry instance
303
+ */
304
+ declare function createSocialMasonry(options: SocialMasonryOptions): SocialMasonry;
305
+
306
+ /**
307
+ * Social Masonry - Layout Engine
308
+ * Calculates positions for masonry grid items
309
+ */
310
+
311
+ interface LayoutEngineOptions extends MasonryConfig {
312
+ containerWidth: number;
313
+ itemHeights: Map<string, number>;
314
+ }
315
+ declare class LayoutEngine {
316
+ private options;
317
+ private state;
318
+ constructor(options: LayoutEngineOptions);
319
+ /**
320
+ * Calculate layout for all posts
321
+ */
322
+ calculate(posts: SocialPost[]): LayoutState;
323
+ /**
324
+ * Estimate item height based on content
325
+ */
326
+ private estimateHeight;
327
+ /**
328
+ * Update single item height and recalculate affected items
329
+ */
330
+ updateItemHeight(id: string, height: number): void;
331
+ /**
332
+ * Get current layout state
333
+ */
334
+ getState(): LayoutState;
335
+ /**
336
+ * Get position for specific item
337
+ */
338
+ getPosition(id: string): ItemPosition | undefined;
339
+ /**
340
+ * Update container width
341
+ */
342
+ setContainerWidth(width: number): void;
343
+ /**
344
+ * Get current column count
345
+ */
346
+ getColumnCount(): number;
347
+ /**
348
+ * Get CSS variables for animations
349
+ */
350
+ getCSSVariables(): Record<string, string>;
351
+ }
352
+ /**
353
+ * Create a new layout engine instance
354
+ */
355
+ declare function createLayoutEngine(options: LayoutEngineOptions): LayoutEngine;
356
+
357
+ /**
358
+ * Social Masonry - Virtualization Engine
359
+ * Handles virtual scrolling for large lists
360
+ */
361
+
362
+ interface VirtualizationEngineOptions extends VirtualizationConfig {
363
+ posts: SocialPost[];
364
+ positions: Map<string, ItemPosition>;
365
+ onVisibleItemsChange?: (items: VirtualItem[]) => void;
366
+ }
367
+ declare class VirtualizationEngine {
368
+ private options;
369
+ private posts;
370
+ private positions;
371
+ private visibleItems;
372
+ private scrollHandler;
373
+ private rafId;
374
+ private lastScrollTop;
375
+ private isScrolling;
376
+ private scrollEndTimeout;
377
+ private onVisibleItemsChange?;
378
+ constructor(options: VirtualizationEngineOptions);
379
+ /**
380
+ * Initialize scroll listener
381
+ */
382
+ init(): void;
383
+ /**
384
+ * Destroy and cleanup
385
+ */
386
+ destroy(): void;
387
+ /**
388
+ * Handle scroll event
389
+ */
390
+ private handleScroll;
391
+ /**
392
+ * Calculate which items are visible
393
+ */
394
+ calculateVisibleItems(): VirtualItem[];
395
+ /**
396
+ * Check if visible items have changed
397
+ */
398
+ private hasVisibleItemsChanged;
399
+ /**
400
+ * Update posts and positions
401
+ */
402
+ update(posts: SocialPost[], positions: Map<string, ItemPosition>): void;
403
+ /**
404
+ * Get visible items
405
+ */
406
+ getVisibleItems(): VirtualItem[];
407
+ /**
408
+ * Get all items (for non-virtualized mode)
409
+ */
410
+ getAllItems(): VirtualItem[];
411
+ /**
412
+ * Check if scrolling
413
+ */
414
+ getIsScrolling(): boolean;
415
+ /**
416
+ * Get scroll direction
417
+ */
418
+ getScrollDirection(): 'up' | 'down' | 'none';
419
+ /**
420
+ * Check if near bottom (for infinite scroll)
421
+ */
422
+ isNearBottom(threshold?: number): boolean;
423
+ /**
424
+ * Scroll to item
425
+ */
426
+ scrollToItem(id: string, behavior?: ScrollBehavior): void;
427
+ /**
428
+ * Get render range for optimization
429
+ */
430
+ getRenderRange(): {
431
+ start: number;
432
+ end: number;
433
+ };
434
+ }
435
+ /**
436
+ * Create a new virtualization engine instance
437
+ */
438
+ declare function createVirtualizationEngine(options: VirtualizationEngineOptions): VirtualizationEngine;
439
+
440
+ /**
441
+ * Social Masonry - Card Renderer
442
+ * Renders social media post cards with proper styling
443
+ */
444
+
445
+ interface CardRendererOptions extends CardConfig {
446
+ onPostClick?: (post: SocialPost, event: MouseEvent) => void;
447
+ onAuthorClick?: (post: SocialPost, event: MouseEvent) => void;
448
+ onMediaClick?: (post: SocialPost, mediaIndex: number, event: MouseEvent) => void;
449
+ onImageError?: (post: SocialPost, error: Error) => void;
450
+ }
451
+ declare class CardRenderer {
452
+ private options;
453
+ constructor(options?: CardRendererOptions);
454
+ /**
455
+ * Render a single card
456
+ */
457
+ render(post: SocialPost, position: ItemPosition): HTMLElement;
458
+ /**
459
+ * Get CSS classes for card
460
+ */
461
+ private getCardClasses;
462
+ /**
463
+ * Build card HTML
464
+ */
465
+ private buildCardHTML;
466
+ /**
467
+ * Render platform icon
468
+ */
469
+ private renderPlatformIcon;
470
+ /**
471
+ * Render card header
472
+ */
473
+ private renderHeader;
474
+ /**
475
+ * Render card content
476
+ */
477
+ private renderContent;
478
+ /**
479
+ * Render Twitter content
480
+ */
481
+ private renderTwitterContent;
482
+ /**
483
+ * Render Instagram content
484
+ */
485
+ private renderInstagramContent;
486
+ /**
487
+ * Render media
488
+ */
489
+ private renderMedia;
490
+ /**
491
+ * Render Twitter media
492
+ */
493
+ private renderTwitterMedia;
494
+ /**
495
+ * Render Instagram media
496
+ */
497
+ private renderInstagramMedia;
498
+ /**
499
+ * Render footer with metrics
500
+ */
501
+ private renderFooter;
502
+ /**
503
+ * Render metrics
504
+ */
505
+ private renderMetrics;
506
+ /**
507
+ * Linkify text (URLs, mentions, hashtags)
508
+ */
509
+ private linkifyText;
510
+ /**
511
+ * Attach event listeners
512
+ */
513
+ private attachEventListeners;
514
+ /**
515
+ * Update card position
516
+ */
517
+ updatePosition(card: HTMLElement, position: ItemPosition): void;
518
+ /**
519
+ * Update options
520
+ */
521
+ setOptions(options: Partial<CardRendererOptions>): void;
522
+ }
523
+ /**
524
+ * Create a new card renderer instance
525
+ */
526
+ declare function createCardRenderer(options?: CardRendererOptions): CardRenderer;
527
+
528
+ /**
529
+ * Default responsive column configuration
530
+ */
531
+ declare const defaultColumnConfig: ColumnConfig[];
532
+ /**
533
+ * Format number with abbreviations (1K, 1M, etc.)
534
+ */
535
+ declare function formatNumber(num: number): string;
536
+ /**
537
+ * Format relative time
538
+ */
539
+ declare function formatRelativeTime(date: Date): string;
540
+ /**
541
+ * Type guard for Twitter posts
542
+ */
543
+ declare function isTwitterPost(post: SocialPost): post is TwitterPost;
544
+ /**
545
+ * Type guard for Instagram posts
546
+ */
547
+ declare function isInstagramPost(post: SocialPost): post is InstagramPost;
548
+
549
+ export { CardRenderer, LayoutEngine, SocialMasonry, VirtualizationEngine, createCardRenderer, createLayoutEngine, createSocialMasonry, createVirtualizationEngine, SocialMasonry as default, defaultColumnConfig, formatNumber, formatRelativeTime, isInstagramPost, isTwitterPost };
550
+ export type { CardConfig, CardTheme, CardVariant, ColumnConfig, InstagramPost, ItemPosition, LayoutState, MasonryConfig, MasonryEvents, SocialMasonryOptions, SocialMasonryProps, SocialPlatform, SocialPost, TwitterPost, VirtualItem, VirtualizationConfig };