@thangdevalone/meeting-grid-layout-core 1.4.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/LICENSE +44 -0
- package/README.md +68 -0
- package/dist/index.cjs +914 -0
- package/dist/index.d.cts +351 -0
- package/dist/index.d.mts +351 -0
- package/dist/index.d.ts +351 -0
- package/dist/index.mjs +902 -0
- package/package.json +50 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dimensions of an element (width and height in pixels)
|
|
3
|
+
*/
|
|
4
|
+
interface GridDimensions {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Position of a grid item
|
|
10
|
+
*/
|
|
11
|
+
interface Position {
|
|
12
|
+
top: number;
|
|
13
|
+
left: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Layout modes for the grid
|
|
17
|
+
* - gallery: Flexible grid that fills all available space. Supports pin mode with pinnedIndex.
|
|
18
|
+
* - spotlight: Single participant in focus, others hidden
|
|
19
|
+
*/
|
|
20
|
+
type LayoutMode = 'gallery' | 'spotlight';
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating a basic grid
|
|
23
|
+
*/
|
|
24
|
+
interface GridOptions {
|
|
25
|
+
/** Aspect ratio in format "width:height" (e.g., "16:9", "4:3") */
|
|
26
|
+
aspectRatio: string;
|
|
27
|
+
/** Number of items in the grid */
|
|
28
|
+
count: number;
|
|
29
|
+
/** Container dimensions */
|
|
30
|
+
dimensions: GridDimensions;
|
|
31
|
+
/** Gap between items in pixels */
|
|
32
|
+
gap: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Aspect ratio configuration for individual items
|
|
36
|
+
* - string: Custom ratio like "16:9", "9:16", "4:3", "1:1"
|
|
37
|
+
* - 'auto': Use actual content dimensions (requires callback)
|
|
38
|
+
*/
|
|
39
|
+
type ItemAspectRatio = string | 'auto';
|
|
40
|
+
/**
|
|
41
|
+
* Extended options for meet-style grid with layout modes
|
|
42
|
+
*/
|
|
43
|
+
interface MeetGridOptions extends GridOptions {
|
|
44
|
+
/** Layout mode for the grid */
|
|
45
|
+
layoutMode?: LayoutMode;
|
|
46
|
+
/** Index of pinned/focused item (main participant for spotlight/pin modes) */
|
|
47
|
+
pinnedIndex?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Position of "others" thumbnails when a participant is pinned.
|
|
50
|
+
* In portrait containers, this is forced to 'bottom'.
|
|
51
|
+
* @default 'right'
|
|
52
|
+
*/
|
|
53
|
+
othersPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
54
|
+
/** Maximum items per page for pagination (0 = no pagination) */
|
|
55
|
+
maxItemsPerPage?: number;
|
|
56
|
+
/** Current page index (0-based) for pagination */
|
|
57
|
+
currentPage?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Maximum visible items (0 = show all).
|
|
60
|
+
* - In gallery mode without pin: limits total items displayed
|
|
61
|
+
* - In gallery mode with pin: limits "others" thumbnails (pinned item always visible)
|
|
62
|
+
* When set, shows a '+X' indicator on the last visible item.
|
|
63
|
+
* @default 0
|
|
64
|
+
*/
|
|
65
|
+
maxVisible?: number;
|
|
66
|
+
/** Current page for items (0-based), used when maxVisible > 0 for pagination */
|
|
67
|
+
currentVisiblePage?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Per-item aspect ratio configurations (index-based)
|
|
70
|
+
* Allows different aspect ratios per participant:
|
|
71
|
+
* - Use "9:16" for mobile/portrait participants
|
|
72
|
+
* - Use "16:9" for desktop/landscape participants
|
|
73
|
+
* - Use undefined to inherit from global aspectRatio
|
|
74
|
+
* @example
|
|
75
|
+
* itemAspectRatios: ["16:9", "9:16", undefined]
|
|
76
|
+
*/
|
|
77
|
+
itemAspectRatios?: (ItemAspectRatio | undefined)[];
|
|
78
|
+
/**
|
|
79
|
+
* Custom width for the floating PiP item in 2-person mode.
|
|
80
|
+
* When set, overrides the width resolved from floatBreakpoints.
|
|
81
|
+
*/
|
|
82
|
+
floatWidth?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Custom height for the floating PiP item in 2-person mode.
|
|
85
|
+
* When set, overrides the height resolved from floatBreakpoints.
|
|
86
|
+
*/
|
|
87
|
+
floatHeight?: number;
|
|
88
|
+
/**
|
|
89
|
+
* Responsive breakpoints for the floating PiP in 2-person mode.
|
|
90
|
+
* When provided, PiP size auto-adjusts based on container width.
|
|
91
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` as a starting point or define your own.
|
|
92
|
+
* `floatWidth`/`floatHeight` still override the resolved size when set.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* // Use default 5-level responsive breakpoints
|
|
96
|
+
* floatBreakpoints: DEFAULT_FLOAT_BREAKPOINTS
|
|
97
|
+
*
|
|
98
|
+
* // Custom breakpoints
|
|
99
|
+
* floatBreakpoints: [
|
|
100
|
+
* { minWidth: 0, width: 80, height: 110 },
|
|
101
|
+
* { minWidth: 600, width: 150, height: 200 },
|
|
102
|
+
* { minWidth: 1200, width: 250, height: 330 },
|
|
103
|
+
* ]
|
|
104
|
+
*/
|
|
105
|
+
floatBreakpoints?: PipBreakpoint[];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Pagination info returned with grid result
|
|
109
|
+
*/
|
|
110
|
+
interface PaginationInfo {
|
|
111
|
+
/** Whether pagination is enabled */
|
|
112
|
+
enabled: boolean;
|
|
113
|
+
/** Current page (0-based) */
|
|
114
|
+
currentPage: number;
|
|
115
|
+
/** Total number of pages */
|
|
116
|
+
totalPages: number;
|
|
117
|
+
/** Items shown on current page */
|
|
118
|
+
itemsOnPage: number;
|
|
119
|
+
/** Start index of items on current page */
|
|
120
|
+
startIndex: number;
|
|
121
|
+
/** End index of items on current page (exclusive) */
|
|
122
|
+
endIndex: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Result from grid calculations
|
|
126
|
+
*/
|
|
127
|
+
interface GridResult {
|
|
128
|
+
/** Width of each grid item */
|
|
129
|
+
width: number;
|
|
130
|
+
/** Height of each grid item */
|
|
131
|
+
height: number;
|
|
132
|
+
/** Number of rows */
|
|
133
|
+
rows: number;
|
|
134
|
+
/** Number of columns */
|
|
135
|
+
cols: number;
|
|
136
|
+
/** Function to get position of item at index */
|
|
137
|
+
getPosition: (index: number) => Position;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Content dimensions result with positioning info
|
|
141
|
+
*/
|
|
142
|
+
interface ContentDimensions extends GridDimensions {
|
|
143
|
+
/** Offset from cell top to center the content */
|
|
144
|
+
offsetTop: number;
|
|
145
|
+
/** Offset from cell left to center the content */
|
|
146
|
+
offsetLeft: number;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Responsive breakpoint configuration for PiP sizing.
|
|
150
|
+
* The system selects the breakpoint with the largest `minWidth` that is <= container width.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* // Custom breakpoints
|
|
154
|
+
* const breakpoints: PipBreakpoint[] = [
|
|
155
|
+
* { minWidth: 0, width: 80, height: 110 }, // Small mobile
|
|
156
|
+
* { minWidth: 480, width: 120, height: 160 }, // Mobile
|
|
157
|
+
* { minWidth: 768, width: 160, height: 215 }, // Tablet
|
|
158
|
+
* { minWidth: 1024, width: 200, height: 270 }, // Desktop
|
|
159
|
+
* ]
|
|
160
|
+
*/
|
|
161
|
+
interface PipBreakpoint {
|
|
162
|
+
/** Minimum container width (px) for this breakpoint to apply */
|
|
163
|
+
minWidth: number;
|
|
164
|
+
/** PiP width at this breakpoint (px) */
|
|
165
|
+
width: number;
|
|
166
|
+
/** PiP height at this breakpoint (px) */
|
|
167
|
+
height: number;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Default responsive breakpoints for PiP sizing.
|
|
171
|
+
* Provides 5 levels from small mobile to large desktop.
|
|
172
|
+
*
|
|
173
|
+
* | Breakpoint | Container Width | PiP Size |
|
|
174
|
+
* | -------------- | --------------- | ---------- |
|
|
175
|
+
* | Small mobile | 0 – 479px | 100 × 135 |
|
|
176
|
+
* | Mobile/Tablet | 480 – 767px | 130 × 175 |
|
|
177
|
+
* | Tablet | 768 – 1023px | 160 × 215 |
|
|
178
|
+
* | Desktop | 1024 – 1439px | 180 × 240 |
|
|
179
|
+
* | Large Desktop | 1440px+ | 220 × 295 |
|
|
180
|
+
*/
|
|
181
|
+
declare const DEFAULT_FLOAT_BREAKPOINTS: PipBreakpoint[];
|
|
182
|
+
/**
|
|
183
|
+
* Resolve PiP size from responsive breakpoints based on container width.
|
|
184
|
+
* Selects the breakpoint with the largest `minWidth` that is <= `containerWidth`.
|
|
185
|
+
*
|
|
186
|
+
* @param containerWidth - Current container width in pixels
|
|
187
|
+
* @param breakpoints - Array of PipBreakpoint configurations
|
|
188
|
+
* @returns Resolved { width, height } for the PiP
|
|
189
|
+
*/
|
|
190
|
+
declare function resolveFloatSize(containerWidth: number, breakpoints: PipBreakpoint[]): GridDimensions;
|
|
191
|
+
/**
|
|
192
|
+
* Extended result for meet-style grid
|
|
193
|
+
*/
|
|
194
|
+
interface MeetGridResult extends GridResult {
|
|
195
|
+
/** Layout mode used */
|
|
196
|
+
layoutMode: LayoutMode;
|
|
197
|
+
/** Get item cell dimensions (the grid cell size, may vary by index in some modes) */
|
|
198
|
+
getItemDimensions: (index: number) => GridDimensions;
|
|
199
|
+
/** Check if item is the main/featured item */
|
|
200
|
+
isMainItem: (index: number) => boolean;
|
|
201
|
+
/** Pagination info (if pagination is enabled) */
|
|
202
|
+
pagination: PaginationInfo;
|
|
203
|
+
/** Check if item should be visible on current page */
|
|
204
|
+
isItemVisible: (index: number) => boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Number of hidden items (for '+X more' indicator).
|
|
207
|
+
* When maxVisible is set and there are more participants than allowed,
|
|
208
|
+
* this indicates how many are hidden.
|
|
209
|
+
*/
|
|
210
|
+
hiddenCount: number;
|
|
211
|
+
/**
|
|
212
|
+
* Get the last visible item index in the "others" section.
|
|
213
|
+
* Returns -1 if no items are visible or if there's no "others" section.
|
|
214
|
+
* Useful for showing '+X more' indicator on the last visible item.
|
|
215
|
+
*/
|
|
216
|
+
getLastVisibleOthersIndex: () => number;
|
|
217
|
+
/**
|
|
218
|
+
* Get the actual content dimensions within a cell.
|
|
219
|
+
* Use this when items have different aspect ratios (e.g., phone vs desktop).
|
|
220
|
+
* Returns dimensions fitted within the cell while maintaining the item's aspect ratio.
|
|
221
|
+
*
|
|
222
|
+
* @param index - The item index
|
|
223
|
+
* @param itemRatio - The item's aspect ratio ("16:9", "9:16", or undefined for cell dimensions)
|
|
224
|
+
* @returns Content dimensions with offset for centering within the cell
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* // For a mobile participant (9:16)
|
|
228
|
+
* const content = grid.getItemContentDimensions(0, "9:16")
|
|
229
|
+
*
|
|
230
|
+
* // Apply in React:
|
|
231
|
+
* <div style={{
|
|
232
|
+
* width: content.width,
|
|
233
|
+
* height: content.height,
|
|
234
|
+
* marginTop: content.offsetTop,
|
|
235
|
+
* marginLeft: content.offsetLeft
|
|
236
|
+
* }}>
|
|
237
|
+
*/
|
|
238
|
+
getItemContentDimensions: (index: number, itemRatio?: ItemAspectRatio) => ContentDimensions;
|
|
239
|
+
/**
|
|
240
|
+
* Index of the item that should be rendered as a floating PiP overlay.
|
|
241
|
+
* When set, the component layer (GridItem) should render this item as a
|
|
242
|
+
* draggable FloatingGridItem instead of a regular positioned item.
|
|
243
|
+
* Used automatically in 2-person mode (Zoom-style layout).
|
|
244
|
+
*/
|
|
245
|
+
floatIndex?: number;
|
|
246
|
+
/**
|
|
247
|
+
* Dimensions for the floating PiP item.
|
|
248
|
+
* Only set when floatIndex is defined.
|
|
249
|
+
*/
|
|
250
|
+
floatDimensions?: GridDimensions;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Parses the Aspect Ratio string to actual ratio (height/width)
|
|
254
|
+
* @param ratio The aspect ratio in the format of "width:height" (e.g., "16:9")
|
|
255
|
+
* @returns The parsed value of aspect ratio (height/width)
|
|
256
|
+
*/
|
|
257
|
+
declare function getAspectRatio(ratio: string): number;
|
|
258
|
+
/**
|
|
259
|
+
* Parse aspect ratio to get width/height multiplier
|
|
260
|
+
*/
|
|
261
|
+
declare function parseAspectRatio(ratio: string): {
|
|
262
|
+
widthRatio: number;
|
|
263
|
+
heightRatio: number;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Calculate content dimensions that fit within a cell while maintaining aspect ratio
|
|
267
|
+
* @param cellDimensions - The cell dimensions to fit content into
|
|
268
|
+
* @param itemRatio - The content's aspect ratio ("16:9", "9:16", etc.)
|
|
269
|
+
* @param defaultRatio - The default aspect ratio to use if itemRatio is undefined
|
|
270
|
+
* @returns Content dimensions with offset for centering
|
|
271
|
+
*/
|
|
272
|
+
declare function calculateContentDimensions(cellDimensions: GridDimensions, itemRatio?: ItemAspectRatio, defaultRatio?: string): ContentDimensions;
|
|
273
|
+
/**
|
|
274
|
+
* Calculates grid item dimensions for items that can fit in a container.
|
|
275
|
+
* Adapted from: https://stackoverflow.com/a/28268965
|
|
276
|
+
*/
|
|
277
|
+
declare function getGridItemDimensions({ count, dimensions, aspectRatio, gap }: GridOptions): {
|
|
278
|
+
width: number;
|
|
279
|
+
height: number;
|
|
280
|
+
rows: number;
|
|
281
|
+
cols: number;
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Creates a utility function which helps you position grid items in a container.
|
|
285
|
+
*/
|
|
286
|
+
declare function createGridItemPositioner({ parentDimensions, dimensions, rows, cols, count, gap, }: {
|
|
287
|
+
parentDimensions: GridDimensions;
|
|
288
|
+
dimensions: GridDimensions;
|
|
289
|
+
rows: number;
|
|
290
|
+
cols: number;
|
|
291
|
+
count: number;
|
|
292
|
+
gap: number;
|
|
293
|
+
}): (index: number) => Position;
|
|
294
|
+
/**
|
|
295
|
+
* Calculates data required for making a responsive grid.
|
|
296
|
+
*/
|
|
297
|
+
declare function createGrid({ aspectRatio, count, dimensions, gap }: GridOptions): GridResult;
|
|
298
|
+
/**
|
|
299
|
+
* Create a meet-style grid with support for different layout modes.
|
|
300
|
+
* This is the main function for creating video conferencing-style layouts.
|
|
301
|
+
*/
|
|
302
|
+
declare function createMeetGrid(options: MeetGridOptions): MeetGridResult;
|
|
303
|
+
/**
|
|
304
|
+
* Spring animation configuration presets
|
|
305
|
+
*/
|
|
306
|
+
declare const springPresets: {
|
|
307
|
+
/** Snappy animations for UI interactions */
|
|
308
|
+
readonly snappy: {
|
|
309
|
+
readonly stiffness: 400;
|
|
310
|
+
readonly damping: 30;
|
|
311
|
+
};
|
|
312
|
+
/** Smooth animations for layout changes */
|
|
313
|
+
readonly smooth: {
|
|
314
|
+
readonly stiffness: 300;
|
|
315
|
+
readonly damping: 30;
|
|
316
|
+
};
|
|
317
|
+
/** Gentle animations for subtle effects */
|
|
318
|
+
readonly gentle: {
|
|
319
|
+
readonly stiffness: 200;
|
|
320
|
+
readonly damping: 25;
|
|
321
|
+
};
|
|
322
|
+
/** Bouncy animations for playful effects */
|
|
323
|
+
readonly bouncy: {
|
|
324
|
+
readonly stiffness: 400;
|
|
325
|
+
readonly damping: 15;
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
type SpringPreset = keyof typeof springPresets;
|
|
329
|
+
/**
|
|
330
|
+
* Get spring configuration for Motion animations
|
|
331
|
+
*/
|
|
332
|
+
declare function getSpringConfig(preset?: SpringPreset): {
|
|
333
|
+
stiffness: 400;
|
|
334
|
+
damping: 30;
|
|
335
|
+
type: "spring";
|
|
336
|
+
} | {
|
|
337
|
+
stiffness: 300;
|
|
338
|
+
damping: 30;
|
|
339
|
+
type: "spring";
|
|
340
|
+
} | {
|
|
341
|
+
stiffness: 200;
|
|
342
|
+
damping: 25;
|
|
343
|
+
type: "spring";
|
|
344
|
+
} | {
|
|
345
|
+
stiffness: 400;
|
|
346
|
+
damping: 15;
|
|
347
|
+
type: "spring";
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
export { DEFAULT_FLOAT_BREAKPOINTS, calculateContentDimensions, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, parseAspectRatio, resolveFloatSize, springPresets };
|
|
351
|
+
export type { ContentDimensions, GridDimensions, GridOptions, GridResult, ItemAspectRatio, LayoutMode, MeetGridOptions, MeetGridResult, PaginationInfo, PipBreakpoint, Position, SpringPreset };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dimensions of an element (width and height in pixels)
|
|
3
|
+
*/
|
|
4
|
+
interface GridDimensions {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Position of a grid item
|
|
10
|
+
*/
|
|
11
|
+
interface Position {
|
|
12
|
+
top: number;
|
|
13
|
+
left: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Layout modes for the grid
|
|
17
|
+
* - gallery: Flexible grid that fills all available space. Supports pin mode with pinnedIndex.
|
|
18
|
+
* - spotlight: Single participant in focus, others hidden
|
|
19
|
+
*/
|
|
20
|
+
type LayoutMode = 'gallery' | 'spotlight';
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating a basic grid
|
|
23
|
+
*/
|
|
24
|
+
interface GridOptions {
|
|
25
|
+
/** Aspect ratio in format "width:height" (e.g., "16:9", "4:3") */
|
|
26
|
+
aspectRatio: string;
|
|
27
|
+
/** Number of items in the grid */
|
|
28
|
+
count: number;
|
|
29
|
+
/** Container dimensions */
|
|
30
|
+
dimensions: GridDimensions;
|
|
31
|
+
/** Gap between items in pixels */
|
|
32
|
+
gap: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Aspect ratio configuration for individual items
|
|
36
|
+
* - string: Custom ratio like "16:9", "9:16", "4:3", "1:1"
|
|
37
|
+
* - 'auto': Use actual content dimensions (requires callback)
|
|
38
|
+
*/
|
|
39
|
+
type ItemAspectRatio = string | 'auto';
|
|
40
|
+
/**
|
|
41
|
+
* Extended options for meet-style grid with layout modes
|
|
42
|
+
*/
|
|
43
|
+
interface MeetGridOptions extends GridOptions {
|
|
44
|
+
/** Layout mode for the grid */
|
|
45
|
+
layoutMode?: LayoutMode;
|
|
46
|
+
/** Index of pinned/focused item (main participant for spotlight/pin modes) */
|
|
47
|
+
pinnedIndex?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Position of "others" thumbnails when a participant is pinned.
|
|
50
|
+
* In portrait containers, this is forced to 'bottom'.
|
|
51
|
+
* @default 'right'
|
|
52
|
+
*/
|
|
53
|
+
othersPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
54
|
+
/** Maximum items per page for pagination (0 = no pagination) */
|
|
55
|
+
maxItemsPerPage?: number;
|
|
56
|
+
/** Current page index (0-based) for pagination */
|
|
57
|
+
currentPage?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Maximum visible items (0 = show all).
|
|
60
|
+
* - In gallery mode without pin: limits total items displayed
|
|
61
|
+
* - In gallery mode with pin: limits "others" thumbnails (pinned item always visible)
|
|
62
|
+
* When set, shows a '+X' indicator on the last visible item.
|
|
63
|
+
* @default 0
|
|
64
|
+
*/
|
|
65
|
+
maxVisible?: number;
|
|
66
|
+
/** Current page for items (0-based), used when maxVisible > 0 for pagination */
|
|
67
|
+
currentVisiblePage?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Per-item aspect ratio configurations (index-based)
|
|
70
|
+
* Allows different aspect ratios per participant:
|
|
71
|
+
* - Use "9:16" for mobile/portrait participants
|
|
72
|
+
* - Use "16:9" for desktop/landscape participants
|
|
73
|
+
* - Use undefined to inherit from global aspectRatio
|
|
74
|
+
* @example
|
|
75
|
+
* itemAspectRatios: ["16:9", "9:16", undefined]
|
|
76
|
+
*/
|
|
77
|
+
itemAspectRatios?: (ItemAspectRatio | undefined)[];
|
|
78
|
+
/**
|
|
79
|
+
* Custom width for the floating PiP item in 2-person mode.
|
|
80
|
+
* When set, overrides the width resolved from floatBreakpoints.
|
|
81
|
+
*/
|
|
82
|
+
floatWidth?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Custom height for the floating PiP item in 2-person mode.
|
|
85
|
+
* When set, overrides the height resolved from floatBreakpoints.
|
|
86
|
+
*/
|
|
87
|
+
floatHeight?: number;
|
|
88
|
+
/**
|
|
89
|
+
* Responsive breakpoints for the floating PiP in 2-person mode.
|
|
90
|
+
* When provided, PiP size auto-adjusts based on container width.
|
|
91
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` as a starting point or define your own.
|
|
92
|
+
* `floatWidth`/`floatHeight` still override the resolved size when set.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* // Use default 5-level responsive breakpoints
|
|
96
|
+
* floatBreakpoints: DEFAULT_FLOAT_BREAKPOINTS
|
|
97
|
+
*
|
|
98
|
+
* // Custom breakpoints
|
|
99
|
+
* floatBreakpoints: [
|
|
100
|
+
* { minWidth: 0, width: 80, height: 110 },
|
|
101
|
+
* { minWidth: 600, width: 150, height: 200 },
|
|
102
|
+
* { minWidth: 1200, width: 250, height: 330 },
|
|
103
|
+
* ]
|
|
104
|
+
*/
|
|
105
|
+
floatBreakpoints?: PipBreakpoint[];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Pagination info returned with grid result
|
|
109
|
+
*/
|
|
110
|
+
interface PaginationInfo {
|
|
111
|
+
/** Whether pagination is enabled */
|
|
112
|
+
enabled: boolean;
|
|
113
|
+
/** Current page (0-based) */
|
|
114
|
+
currentPage: number;
|
|
115
|
+
/** Total number of pages */
|
|
116
|
+
totalPages: number;
|
|
117
|
+
/** Items shown on current page */
|
|
118
|
+
itemsOnPage: number;
|
|
119
|
+
/** Start index of items on current page */
|
|
120
|
+
startIndex: number;
|
|
121
|
+
/** End index of items on current page (exclusive) */
|
|
122
|
+
endIndex: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Result from grid calculations
|
|
126
|
+
*/
|
|
127
|
+
interface GridResult {
|
|
128
|
+
/** Width of each grid item */
|
|
129
|
+
width: number;
|
|
130
|
+
/** Height of each grid item */
|
|
131
|
+
height: number;
|
|
132
|
+
/** Number of rows */
|
|
133
|
+
rows: number;
|
|
134
|
+
/** Number of columns */
|
|
135
|
+
cols: number;
|
|
136
|
+
/** Function to get position of item at index */
|
|
137
|
+
getPosition: (index: number) => Position;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Content dimensions result with positioning info
|
|
141
|
+
*/
|
|
142
|
+
interface ContentDimensions extends GridDimensions {
|
|
143
|
+
/** Offset from cell top to center the content */
|
|
144
|
+
offsetTop: number;
|
|
145
|
+
/** Offset from cell left to center the content */
|
|
146
|
+
offsetLeft: number;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Responsive breakpoint configuration for PiP sizing.
|
|
150
|
+
* The system selects the breakpoint with the largest `minWidth` that is <= container width.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* // Custom breakpoints
|
|
154
|
+
* const breakpoints: PipBreakpoint[] = [
|
|
155
|
+
* { minWidth: 0, width: 80, height: 110 }, // Small mobile
|
|
156
|
+
* { minWidth: 480, width: 120, height: 160 }, // Mobile
|
|
157
|
+
* { minWidth: 768, width: 160, height: 215 }, // Tablet
|
|
158
|
+
* { minWidth: 1024, width: 200, height: 270 }, // Desktop
|
|
159
|
+
* ]
|
|
160
|
+
*/
|
|
161
|
+
interface PipBreakpoint {
|
|
162
|
+
/** Minimum container width (px) for this breakpoint to apply */
|
|
163
|
+
minWidth: number;
|
|
164
|
+
/** PiP width at this breakpoint (px) */
|
|
165
|
+
width: number;
|
|
166
|
+
/** PiP height at this breakpoint (px) */
|
|
167
|
+
height: number;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Default responsive breakpoints for PiP sizing.
|
|
171
|
+
* Provides 5 levels from small mobile to large desktop.
|
|
172
|
+
*
|
|
173
|
+
* | Breakpoint | Container Width | PiP Size |
|
|
174
|
+
* | -------------- | --------------- | ---------- |
|
|
175
|
+
* | Small mobile | 0 – 479px | 100 × 135 |
|
|
176
|
+
* | Mobile/Tablet | 480 – 767px | 130 × 175 |
|
|
177
|
+
* | Tablet | 768 – 1023px | 160 × 215 |
|
|
178
|
+
* | Desktop | 1024 – 1439px | 180 × 240 |
|
|
179
|
+
* | Large Desktop | 1440px+ | 220 × 295 |
|
|
180
|
+
*/
|
|
181
|
+
declare const DEFAULT_FLOAT_BREAKPOINTS: PipBreakpoint[];
|
|
182
|
+
/**
|
|
183
|
+
* Resolve PiP size from responsive breakpoints based on container width.
|
|
184
|
+
* Selects the breakpoint with the largest `minWidth` that is <= `containerWidth`.
|
|
185
|
+
*
|
|
186
|
+
* @param containerWidth - Current container width in pixels
|
|
187
|
+
* @param breakpoints - Array of PipBreakpoint configurations
|
|
188
|
+
* @returns Resolved { width, height } for the PiP
|
|
189
|
+
*/
|
|
190
|
+
declare function resolveFloatSize(containerWidth: number, breakpoints: PipBreakpoint[]): GridDimensions;
|
|
191
|
+
/**
|
|
192
|
+
* Extended result for meet-style grid
|
|
193
|
+
*/
|
|
194
|
+
interface MeetGridResult extends GridResult {
|
|
195
|
+
/** Layout mode used */
|
|
196
|
+
layoutMode: LayoutMode;
|
|
197
|
+
/** Get item cell dimensions (the grid cell size, may vary by index in some modes) */
|
|
198
|
+
getItemDimensions: (index: number) => GridDimensions;
|
|
199
|
+
/** Check if item is the main/featured item */
|
|
200
|
+
isMainItem: (index: number) => boolean;
|
|
201
|
+
/** Pagination info (if pagination is enabled) */
|
|
202
|
+
pagination: PaginationInfo;
|
|
203
|
+
/** Check if item should be visible on current page */
|
|
204
|
+
isItemVisible: (index: number) => boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Number of hidden items (for '+X more' indicator).
|
|
207
|
+
* When maxVisible is set and there are more participants than allowed,
|
|
208
|
+
* this indicates how many are hidden.
|
|
209
|
+
*/
|
|
210
|
+
hiddenCount: number;
|
|
211
|
+
/**
|
|
212
|
+
* Get the last visible item index in the "others" section.
|
|
213
|
+
* Returns -1 if no items are visible or if there's no "others" section.
|
|
214
|
+
* Useful for showing '+X more' indicator on the last visible item.
|
|
215
|
+
*/
|
|
216
|
+
getLastVisibleOthersIndex: () => number;
|
|
217
|
+
/**
|
|
218
|
+
* Get the actual content dimensions within a cell.
|
|
219
|
+
* Use this when items have different aspect ratios (e.g., phone vs desktop).
|
|
220
|
+
* Returns dimensions fitted within the cell while maintaining the item's aspect ratio.
|
|
221
|
+
*
|
|
222
|
+
* @param index - The item index
|
|
223
|
+
* @param itemRatio - The item's aspect ratio ("16:9", "9:16", or undefined for cell dimensions)
|
|
224
|
+
* @returns Content dimensions with offset for centering within the cell
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* // For a mobile participant (9:16)
|
|
228
|
+
* const content = grid.getItemContentDimensions(0, "9:16")
|
|
229
|
+
*
|
|
230
|
+
* // Apply in React:
|
|
231
|
+
* <div style={{
|
|
232
|
+
* width: content.width,
|
|
233
|
+
* height: content.height,
|
|
234
|
+
* marginTop: content.offsetTop,
|
|
235
|
+
* marginLeft: content.offsetLeft
|
|
236
|
+
* }}>
|
|
237
|
+
*/
|
|
238
|
+
getItemContentDimensions: (index: number, itemRatio?: ItemAspectRatio) => ContentDimensions;
|
|
239
|
+
/**
|
|
240
|
+
* Index of the item that should be rendered as a floating PiP overlay.
|
|
241
|
+
* When set, the component layer (GridItem) should render this item as a
|
|
242
|
+
* draggable FloatingGridItem instead of a regular positioned item.
|
|
243
|
+
* Used automatically in 2-person mode (Zoom-style layout).
|
|
244
|
+
*/
|
|
245
|
+
floatIndex?: number;
|
|
246
|
+
/**
|
|
247
|
+
* Dimensions for the floating PiP item.
|
|
248
|
+
* Only set when floatIndex is defined.
|
|
249
|
+
*/
|
|
250
|
+
floatDimensions?: GridDimensions;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Parses the Aspect Ratio string to actual ratio (height/width)
|
|
254
|
+
* @param ratio The aspect ratio in the format of "width:height" (e.g., "16:9")
|
|
255
|
+
* @returns The parsed value of aspect ratio (height/width)
|
|
256
|
+
*/
|
|
257
|
+
declare function getAspectRatio(ratio: string): number;
|
|
258
|
+
/**
|
|
259
|
+
* Parse aspect ratio to get width/height multiplier
|
|
260
|
+
*/
|
|
261
|
+
declare function parseAspectRatio(ratio: string): {
|
|
262
|
+
widthRatio: number;
|
|
263
|
+
heightRatio: number;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Calculate content dimensions that fit within a cell while maintaining aspect ratio
|
|
267
|
+
* @param cellDimensions - The cell dimensions to fit content into
|
|
268
|
+
* @param itemRatio - The content's aspect ratio ("16:9", "9:16", etc.)
|
|
269
|
+
* @param defaultRatio - The default aspect ratio to use if itemRatio is undefined
|
|
270
|
+
* @returns Content dimensions with offset for centering
|
|
271
|
+
*/
|
|
272
|
+
declare function calculateContentDimensions(cellDimensions: GridDimensions, itemRatio?: ItemAspectRatio, defaultRatio?: string): ContentDimensions;
|
|
273
|
+
/**
|
|
274
|
+
* Calculates grid item dimensions for items that can fit in a container.
|
|
275
|
+
* Adapted from: https://stackoverflow.com/a/28268965
|
|
276
|
+
*/
|
|
277
|
+
declare function getGridItemDimensions({ count, dimensions, aspectRatio, gap }: GridOptions): {
|
|
278
|
+
width: number;
|
|
279
|
+
height: number;
|
|
280
|
+
rows: number;
|
|
281
|
+
cols: number;
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Creates a utility function which helps you position grid items in a container.
|
|
285
|
+
*/
|
|
286
|
+
declare function createGridItemPositioner({ parentDimensions, dimensions, rows, cols, count, gap, }: {
|
|
287
|
+
parentDimensions: GridDimensions;
|
|
288
|
+
dimensions: GridDimensions;
|
|
289
|
+
rows: number;
|
|
290
|
+
cols: number;
|
|
291
|
+
count: number;
|
|
292
|
+
gap: number;
|
|
293
|
+
}): (index: number) => Position;
|
|
294
|
+
/**
|
|
295
|
+
* Calculates data required for making a responsive grid.
|
|
296
|
+
*/
|
|
297
|
+
declare function createGrid({ aspectRatio, count, dimensions, gap }: GridOptions): GridResult;
|
|
298
|
+
/**
|
|
299
|
+
* Create a meet-style grid with support for different layout modes.
|
|
300
|
+
* This is the main function for creating video conferencing-style layouts.
|
|
301
|
+
*/
|
|
302
|
+
declare function createMeetGrid(options: MeetGridOptions): MeetGridResult;
|
|
303
|
+
/**
|
|
304
|
+
* Spring animation configuration presets
|
|
305
|
+
*/
|
|
306
|
+
declare const springPresets: {
|
|
307
|
+
/** Snappy animations for UI interactions */
|
|
308
|
+
readonly snappy: {
|
|
309
|
+
readonly stiffness: 400;
|
|
310
|
+
readonly damping: 30;
|
|
311
|
+
};
|
|
312
|
+
/** Smooth animations for layout changes */
|
|
313
|
+
readonly smooth: {
|
|
314
|
+
readonly stiffness: 300;
|
|
315
|
+
readonly damping: 30;
|
|
316
|
+
};
|
|
317
|
+
/** Gentle animations for subtle effects */
|
|
318
|
+
readonly gentle: {
|
|
319
|
+
readonly stiffness: 200;
|
|
320
|
+
readonly damping: 25;
|
|
321
|
+
};
|
|
322
|
+
/** Bouncy animations for playful effects */
|
|
323
|
+
readonly bouncy: {
|
|
324
|
+
readonly stiffness: 400;
|
|
325
|
+
readonly damping: 15;
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
type SpringPreset = keyof typeof springPresets;
|
|
329
|
+
/**
|
|
330
|
+
* Get spring configuration for Motion animations
|
|
331
|
+
*/
|
|
332
|
+
declare function getSpringConfig(preset?: SpringPreset): {
|
|
333
|
+
stiffness: 400;
|
|
334
|
+
damping: 30;
|
|
335
|
+
type: "spring";
|
|
336
|
+
} | {
|
|
337
|
+
stiffness: 300;
|
|
338
|
+
damping: 30;
|
|
339
|
+
type: "spring";
|
|
340
|
+
} | {
|
|
341
|
+
stiffness: 200;
|
|
342
|
+
damping: 25;
|
|
343
|
+
type: "spring";
|
|
344
|
+
} | {
|
|
345
|
+
stiffness: 400;
|
|
346
|
+
damping: 15;
|
|
347
|
+
type: "spring";
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
export { DEFAULT_FLOAT_BREAKPOINTS, calculateContentDimensions, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, parseAspectRatio, resolveFloatSize, springPresets };
|
|
351
|
+
export type { ContentDimensions, GridDimensions, GridOptions, GridResult, ItemAspectRatio, LayoutMode, MeetGridOptions, MeetGridResult, PaginationInfo, PipBreakpoint, Position, SpringPreset };
|