@thangdevalone/meet-layout-grid-react 1.0.0 → 1.0.3
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 +114 -114
- package/dist/index.cjs +28 -13
- package/dist/index.d.cts +11 -3
- package/dist/index.d.mts +11 -3
- package/dist/index.d.ts +121 -113
- package/dist/index.mjs +19 -4
- package/package.json +63 -62
package/LICENSE
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
MIT License with Attribution Requirement
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 ThangDevAlone
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
1. The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
2. ATTRIBUTION REQUIREMENT: Any project using this Software must include
|
|
16
|
+
visible attribution to the original author in one of the following ways:
|
|
17
|
+
|
|
18
|
+
a) In the project's README or documentation file, include:
|
|
19
|
+
"This project uses meet-layout-grid by @thangdevalone
|
|
20
|
+
(https://github.com/thangdevalone/meet-layout-grid)"
|
|
21
|
+
|
|
22
|
+
b) In an "About" or "Credits" section of the application, include:
|
|
23
|
+
"Powered by meet-layout-grid - https://github.com/thangdevalone/meet-layout-grid"
|
|
24
|
+
|
|
25
|
+
c) In the project's package.json or equivalent dependency manifest, ensure
|
|
26
|
+
the package is listed with its original name and author information intact.
|
|
27
|
+
|
|
28
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
29
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
30
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
31
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
32
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
33
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
34
|
+
SOFTWARE.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
TL;DR - Bạn được phép:
|
|
39
|
+
✅ Sử dụng miễn phí cho dự án cá nhân và thương mại
|
|
40
|
+
✅ Chỉnh sửa và phân phối lại
|
|
41
|
+
✅ Sử dụng trong các dự án closed-source
|
|
42
|
+
|
|
43
|
+
Yêu cầu duy nhất:
|
|
44
|
+
📝 Ghi nguồn/credit cho tác giả gốc trong README hoặc phần About của dự án
|
package/README.md
CHANGED
|
@@ -1,114 +1,114 @@
|
|
|
1
|
-
# @meet-layout-grid/react
|
|
2
|
-
|
|
3
|
-
React integration for meet-layout-grid with Motion animations.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @meet-layout-grid/react
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Quick Start
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
import { GridContainer, GridItem } from '@meet-layout-grid/react'
|
|
15
|
-
|
|
16
|
-
function MeetingGrid({ participants }) {
|
|
17
|
-
return (
|
|
18
|
-
<GridContainer
|
|
19
|
-
aspectRatio="16:9"
|
|
20
|
-
gap={8}
|
|
21
|
-
layoutMode="gallery"
|
|
22
|
-
count={participants.length}
|
|
23
|
-
>
|
|
24
|
-
{participants.map((p, index) => (
|
|
25
|
-
<GridItem key={p.id} index={index}>
|
|
26
|
-
<VideoTile participant={p} />
|
|
27
|
-
</GridItem>
|
|
28
|
-
))}
|
|
29
|
-
</GridContainer>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Components
|
|
35
|
-
|
|
36
|
-
### `<GridContainer>`
|
|
37
|
-
|
|
38
|
-
Container component that calculates grid layout and provides context.
|
|
39
|
-
|
|
40
|
-
```tsx
|
|
41
|
-
<GridContainer
|
|
42
|
-
aspectRatio="16:9" // Item aspect ratio
|
|
43
|
-
gap={8} // Gap between items (px)
|
|
44
|
-
count={6} // Number of items
|
|
45
|
-
layoutMode="gallery" // Layout mode
|
|
46
|
-
speakerIndex={0} // Active speaker
|
|
47
|
-
pinnedIndex={0} // Pinned item
|
|
48
|
-
sidebarPosition="right" // Sidebar position
|
|
49
|
-
sidebarRatio={0.25} // Sidebar width ratio
|
|
50
|
-
springPreset="smooth" // Animation preset
|
|
51
|
-
>
|
|
52
|
-
{children}
|
|
53
|
-
</GridContainer>
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### `<GridItem>`
|
|
57
|
-
|
|
58
|
-
Animated grid item with Motion spring animations.
|
|
59
|
-
|
|
60
|
-
```tsx
|
|
61
|
-
<GridItem
|
|
62
|
-
index={0} // Item index (required)
|
|
63
|
-
disableAnimation={false} // Disable animations
|
|
64
|
-
>
|
|
65
|
-
{content}
|
|
66
|
-
</GridItem>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Hooks
|
|
70
|
-
|
|
71
|
-
### `useGridDimensions(ref)`
|
|
72
|
-
|
|
73
|
-
Track element dimensions with ResizeObserver.
|
|
74
|
-
|
|
75
|
-
```tsx
|
|
76
|
-
const ref = useRef<HTMLDivElement>(null)
|
|
77
|
-
const dimensions = useGridDimensions(ref)
|
|
78
|
-
// { width: number, height: number }
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### `useMeetGrid(options)`
|
|
82
|
-
|
|
83
|
-
Calculate grid layout manually.
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
const grid = useMeetGrid({
|
|
87
|
-
dimensions: { width: 800, height: 600 },
|
|
88
|
-
count: 6,
|
|
89
|
-
aspectRatio: '16:9',
|
|
90
|
-
gap: 8,
|
|
91
|
-
layoutMode: 'speaker',
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
const { top, left } = grid.getPosition(index)
|
|
95
|
-
const { width, height } = grid.getItemDimensions(index)
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Layout Modes
|
|
99
|
-
|
|
100
|
-
- **gallery** - Equal-sized tiles
|
|
101
|
-
- **speaker** - Active speaker larger
|
|
102
|
-
- **spotlight** - Single participant focus
|
|
103
|
-
- **sidebar** - Main view + thumbnails
|
|
104
|
-
|
|
105
|
-
## Animation Presets
|
|
106
|
-
|
|
107
|
-
- `snappy` - Quick UI interactions
|
|
108
|
-
- `smooth` - Layout changes (default)
|
|
109
|
-
- `gentle` - Subtle effects
|
|
110
|
-
- `bouncy` - Playful effects
|
|
111
|
-
|
|
112
|
-
## License
|
|
113
|
-
|
|
114
|
-
MIT
|
|
1
|
+
# @meet-layout-grid/react
|
|
2
|
+
|
|
3
|
+
React integration for meet-layout-grid with Motion animations.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @meet-layout-grid/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { GridContainer, GridItem } from '@meet-layout-grid/react'
|
|
15
|
+
|
|
16
|
+
function MeetingGrid({ participants }) {
|
|
17
|
+
return (
|
|
18
|
+
<GridContainer
|
|
19
|
+
aspectRatio="16:9"
|
|
20
|
+
gap={8}
|
|
21
|
+
layoutMode="gallery"
|
|
22
|
+
count={participants.length}
|
|
23
|
+
>
|
|
24
|
+
{participants.map((p, index) => (
|
|
25
|
+
<GridItem key={p.id} index={index}>
|
|
26
|
+
<VideoTile participant={p} />
|
|
27
|
+
</GridItem>
|
|
28
|
+
))}
|
|
29
|
+
</GridContainer>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Components
|
|
35
|
+
|
|
36
|
+
### `<GridContainer>`
|
|
37
|
+
|
|
38
|
+
Container component that calculates grid layout and provides context.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<GridContainer
|
|
42
|
+
aspectRatio="16:9" // Item aspect ratio
|
|
43
|
+
gap={8} // Gap between items (px)
|
|
44
|
+
count={6} // Number of items
|
|
45
|
+
layoutMode="gallery" // Layout mode
|
|
46
|
+
speakerIndex={0} // Active speaker
|
|
47
|
+
pinnedIndex={0} // Pinned item
|
|
48
|
+
sidebarPosition="right" // Sidebar position
|
|
49
|
+
sidebarRatio={0.25} // Sidebar width ratio
|
|
50
|
+
springPreset="smooth" // Animation preset
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
</GridContainer>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `<GridItem>`
|
|
57
|
+
|
|
58
|
+
Animated grid item with Motion spring animations.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<GridItem
|
|
62
|
+
index={0} // Item index (required)
|
|
63
|
+
disableAnimation={false} // Disable animations
|
|
64
|
+
>
|
|
65
|
+
{content}
|
|
66
|
+
</GridItem>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Hooks
|
|
70
|
+
|
|
71
|
+
### `useGridDimensions(ref)`
|
|
72
|
+
|
|
73
|
+
Track element dimensions with ResizeObserver.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
77
|
+
const dimensions = useGridDimensions(ref)
|
|
78
|
+
// { width: number, height: number }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `useMeetGrid(options)`
|
|
82
|
+
|
|
83
|
+
Calculate grid layout manually.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const grid = useMeetGrid({
|
|
87
|
+
dimensions: { width: 800, height: 600 },
|
|
88
|
+
count: 6,
|
|
89
|
+
aspectRatio: '16:9',
|
|
90
|
+
gap: 8,
|
|
91
|
+
layoutMode: 'speaker',
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const { top, left } = grid.getPosition(index)
|
|
95
|
+
const { width, height } = grid.getItemDimensions(index)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Layout Modes
|
|
99
|
+
|
|
100
|
+
- **gallery** - Equal-sized tiles
|
|
101
|
+
- **speaker** - Active speaker larger
|
|
102
|
+
- **spotlight** - Single participant focus
|
|
103
|
+
- **sidebar** - Main view + thumbnails
|
|
104
|
+
|
|
105
|
+
## Animation Presets
|
|
106
|
+
|
|
107
|
+
- `snappy` - Quick UI interactions
|
|
108
|
+
- `smooth` - Layout changes (default)
|
|
109
|
+
- `gentle` - Subtle effects
|
|
110
|
+
- `bouncy` - Playful effects
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const React = require('react');
|
|
4
|
-
const
|
|
4
|
+
const meetLayoutGridCore = require('@thangdevalone/meet-layout-grid-core');
|
|
5
5
|
const react = require('motion/react');
|
|
6
6
|
|
|
7
7
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -47,7 +47,7 @@ function useGridDimensions(ref) {
|
|
|
47
47
|
}
|
|
48
48
|
function useMeetGrid(options) {
|
|
49
49
|
return React.useMemo(() => {
|
|
50
|
-
return
|
|
50
|
+
return meetLayoutGridCore.createMeetGrid(options);
|
|
51
51
|
}, [
|
|
52
52
|
options.dimensions.width,
|
|
53
53
|
options.dimensions.height,
|
|
@@ -58,11 +58,15 @@ function useMeetGrid(options) {
|
|
|
58
58
|
options.pinnedIndex,
|
|
59
59
|
options.speakerIndex,
|
|
60
60
|
options.sidebarPosition,
|
|
61
|
-
options.sidebarRatio
|
|
61
|
+
options.sidebarRatio,
|
|
62
|
+
options.maxItemsPerPage,
|
|
63
|
+
options.currentPage,
|
|
64
|
+
options.maxVisibleOthers,
|
|
65
|
+
options.currentOthersPage
|
|
62
66
|
]);
|
|
63
67
|
}
|
|
64
68
|
function useGridAnimation(preset = "smooth") {
|
|
65
|
-
return React.useMemo(() =>
|
|
69
|
+
return React.useMemo(() => meetLayoutGridCore.getSpringConfig(preset), [preset]);
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
const GridContainer = React.forwardRef(
|
|
@@ -79,6 +83,10 @@ const GridContainer = React.forwardRef(
|
|
|
79
83
|
springPreset = "smooth",
|
|
80
84
|
style,
|
|
81
85
|
className,
|
|
86
|
+
maxItemsPerPage,
|
|
87
|
+
currentPage,
|
|
88
|
+
maxVisibleOthers,
|
|
89
|
+
currentOthersPage,
|
|
82
90
|
...props
|
|
83
91
|
}, forwardedRef) {
|
|
84
92
|
const internalRef = React.useRef(null);
|
|
@@ -94,7 +102,11 @@ const GridContainer = React.forwardRef(
|
|
|
94
102
|
pinnedIndex,
|
|
95
103
|
speakerIndex,
|
|
96
104
|
sidebarPosition,
|
|
97
|
-
sidebarRatio
|
|
105
|
+
sidebarRatio,
|
|
106
|
+
maxItemsPerPage,
|
|
107
|
+
currentPage,
|
|
108
|
+
maxVisibleOthers,
|
|
109
|
+
currentOthersPage
|
|
98
110
|
};
|
|
99
111
|
const grid = useMeetGrid(gridOptions);
|
|
100
112
|
const containerStyle = {
|
|
@@ -121,13 +133,16 @@ const GridItem = React.forwardRef(
|
|
|
121
133
|
if (!grid) {
|
|
122
134
|
return null;
|
|
123
135
|
}
|
|
136
|
+
if (!grid.isItemVisible(index)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
124
139
|
const { top, left } = grid.getPosition(index);
|
|
125
140
|
const { width, height } = grid.getItemDimensions(index);
|
|
126
141
|
const isMain = grid.isMainItem(index);
|
|
127
142
|
if (grid.layoutMode === "spotlight" && !isMain) {
|
|
128
143
|
return null;
|
|
129
144
|
}
|
|
130
|
-
const springConfig =
|
|
145
|
+
const springConfig = meetLayoutGridCore.getSpringConfig(springPreset);
|
|
131
146
|
const transition = customTransition ?? {
|
|
132
147
|
type: springConfig.type,
|
|
133
148
|
stiffness: springConfig.stiffness,
|
|
@@ -196,13 +211,13 @@ const GridOverlay = React.forwardRef(
|
|
|
196
211
|
}
|
|
197
212
|
);
|
|
198
213
|
|
|
199
|
-
exports.createGrid =
|
|
200
|
-
exports.createGridItemPositioner =
|
|
201
|
-
exports.createMeetGrid =
|
|
202
|
-
exports.getAspectRatio =
|
|
203
|
-
exports.getGridItemDimensions =
|
|
204
|
-
exports.getSpringConfig =
|
|
205
|
-
exports.springPresets =
|
|
214
|
+
exports.createGrid = meetLayoutGridCore.createGrid;
|
|
215
|
+
exports.createGridItemPositioner = meetLayoutGridCore.createGridItemPositioner;
|
|
216
|
+
exports.createMeetGrid = meetLayoutGridCore.createMeetGrid;
|
|
217
|
+
exports.getAspectRatio = meetLayoutGridCore.getAspectRatio;
|
|
218
|
+
exports.getGridItemDimensions = meetLayoutGridCore.getGridItemDimensions;
|
|
219
|
+
exports.getSpringConfig = meetLayoutGridCore.getSpringConfig;
|
|
220
|
+
exports.springPresets = meetLayoutGridCore.springPresets;
|
|
206
221
|
exports.GridContainer = GridContainer;
|
|
207
222
|
exports.GridContext = GridContext;
|
|
208
223
|
exports.GridItem = GridItem;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { RefObject, HTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@meet-layout-grid
|
|
4
|
-
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@meet-layout-grid
|
|
3
|
+
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@thangdevalone/meet-layout-grid-core';
|
|
4
|
+
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, PaginationInfo, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
5
5
|
import { HTMLMotionProps, Transition } from 'motion/react';
|
|
6
6
|
|
|
7
7
|
interface GridContextValue {
|
|
@@ -64,7 +64,7 @@ interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'child
|
|
|
64
64
|
/** Index of active speaker */
|
|
65
65
|
speakerIndex?: number;
|
|
66
66
|
/** Sidebar position */
|
|
67
|
-
sidebarPosition?: 'left' | 'right' | 'bottom';
|
|
67
|
+
sidebarPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
68
68
|
/** Sidebar ratio (0-1) */
|
|
69
69
|
sidebarRatio?: number;
|
|
70
70
|
/** Spring animation preset */
|
|
@@ -73,6 +73,14 @@ interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'child
|
|
|
73
73
|
style?: CSSProperties;
|
|
74
74
|
/** Additional class name */
|
|
75
75
|
className?: string;
|
|
76
|
+
/** Maximum items per page for pagination (0 = no pagination) */
|
|
77
|
+
maxItemsPerPage?: number;
|
|
78
|
+
/** Current page index (0-based) for pagination */
|
|
79
|
+
currentPage?: number;
|
|
80
|
+
/** Maximum visible "others" in speaker/sidebar modes (0 = show all) */
|
|
81
|
+
maxVisibleOthers?: number;
|
|
82
|
+
/** Current page for "others" in speaker/sidebar modes (0-based) */
|
|
83
|
+
currentOthersPage?: number;
|
|
76
84
|
}
|
|
77
85
|
/**
|
|
78
86
|
* Container component for the meet grid.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { RefObject, HTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@meet-layout-grid
|
|
4
|
-
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@meet-layout-grid
|
|
3
|
+
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@thangdevalone/meet-layout-grid-core';
|
|
4
|
+
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, PaginationInfo, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
5
5
|
import { HTMLMotionProps, Transition } from 'motion/react';
|
|
6
6
|
|
|
7
7
|
interface GridContextValue {
|
|
@@ -64,7 +64,7 @@ interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'child
|
|
|
64
64
|
/** Index of active speaker */
|
|
65
65
|
speakerIndex?: number;
|
|
66
66
|
/** Sidebar position */
|
|
67
|
-
sidebarPosition?: 'left' | 'right' | 'bottom';
|
|
67
|
+
sidebarPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
68
68
|
/** Sidebar ratio (0-1) */
|
|
69
69
|
sidebarRatio?: number;
|
|
70
70
|
/** Spring animation preset */
|
|
@@ -73,6 +73,14 @@ interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'child
|
|
|
73
73
|
style?: CSSProperties;
|
|
74
74
|
/** Additional class name */
|
|
75
75
|
className?: string;
|
|
76
|
+
/** Maximum items per page for pagination (0 = no pagination) */
|
|
77
|
+
maxItemsPerPage?: number;
|
|
78
|
+
/** Current page index (0-based) for pagination */
|
|
79
|
+
currentPage?: number;
|
|
80
|
+
/** Maximum visible "others" in speaker/sidebar modes (0 = show all) */
|
|
81
|
+
maxVisibleOthers?: number;
|
|
82
|
+
/** Current page for "others" in speaker/sidebar modes (0-based) */
|
|
83
|
+
currentOthersPage?: number;
|
|
76
84
|
}
|
|
77
85
|
/**
|
|
78
86
|
* Container component for the meet grid.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,113 +1,121 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import React__default, { RefObject, HTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@thangdevalone/meet-layout-grid-core';
|
|
4
|
-
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
5
|
-
import { HTMLMotionProps, Transition } from 'motion/react';
|
|
6
|
-
|
|
7
|
-
interface GridContextValue {
|
|
8
|
-
dimensions: GridDimensions;
|
|
9
|
-
grid: MeetGridResult | null;
|
|
10
|
-
springPreset: SpringPreset;
|
|
11
|
-
}
|
|
12
|
-
declare const GridContext: React.Context<GridContextValue | null>;
|
|
13
|
-
/**
|
|
14
|
-
* Hook to access the grid context
|
|
15
|
-
*/
|
|
16
|
-
declare function useGridContext(): GridContextValue;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* A React hook to calculate dimensions of an element using ResizeObserver.
|
|
20
|
-
* @param ref An element ref
|
|
21
|
-
* @returns Dimensions of the element
|
|
22
|
-
*/
|
|
23
|
-
declare function useGridDimensions(ref: RefObject<HTMLElement | null>): GridDimensions;
|
|
24
|
-
/**
|
|
25
|
-
* React hook for creating a meet-style responsive grid.
|
|
26
|
-
* @param options Grid options including dimensions, count, aspectRatio, gap, and layoutMode
|
|
27
|
-
* @returns Grid result with width, height, and position getter
|
|
28
|
-
*/
|
|
29
|
-
declare function useMeetGrid(options: MeetGridOptions): MeetGridResult;
|
|
30
|
-
/**
|
|
31
|
-
* Hook to get animation configuration for Motion
|
|
32
|
-
*/
|
|
33
|
-
declare function useGridAnimation(preset?: SpringPreset): {
|
|
34
|
-
stiffness: 400;
|
|
35
|
-
damping: 30;
|
|
36
|
-
type: "spring";
|
|
37
|
-
} | {
|
|
38
|
-
stiffness: 300;
|
|
39
|
-
damping: 30;
|
|
40
|
-
type: "spring";
|
|
41
|
-
} | {
|
|
42
|
-
stiffness: 200;
|
|
43
|
-
damping: 25;
|
|
44
|
-
type: "spring";
|
|
45
|
-
} | {
|
|
46
|
-
stiffness: 400;
|
|
47
|
-
damping: 15;
|
|
48
|
-
type: "spring";
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
52
|
-
/** Children to render inside the grid */
|
|
53
|
-
children: ReactNode;
|
|
54
|
-
/** Aspect ratio in format "width:height" (e.g., "16:9") */
|
|
55
|
-
aspectRatio?: string;
|
|
56
|
-
/** Gap between items in pixels */
|
|
57
|
-
gap?: number;
|
|
58
|
-
/** Number of items (if not using GridItem children) */
|
|
59
|
-
count?: number;
|
|
60
|
-
/** Layout mode */
|
|
61
|
-
layoutMode?: LayoutMode;
|
|
62
|
-
/** Index of pinned item */
|
|
63
|
-
pinnedIndex?: number;
|
|
64
|
-
/** Index of active speaker */
|
|
65
|
-
speakerIndex?: number;
|
|
66
|
-
/** Sidebar position */
|
|
67
|
-
sidebarPosition?: 'left' | 'right' | 'bottom';
|
|
68
|
-
/** Sidebar ratio (0-1) */
|
|
69
|
-
sidebarRatio?: number;
|
|
70
|
-
/** Spring animation preset */
|
|
71
|
-
springPreset?: SpringPreset;
|
|
72
|
-
/** Custom container style */
|
|
73
|
-
style?: CSSProperties;
|
|
74
|
-
/** Additional class name */
|
|
75
|
-
className?: string;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { RefObject, HTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
|
+
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode } from '@thangdevalone/meet-layout-grid-core';
|
|
4
|
+
export { GridDimensions, GridOptions, LayoutMode, MeetGridOptions, MeetGridResult, PaginationInfo, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
5
|
+
import { HTMLMotionProps, Transition } from 'motion/react';
|
|
6
|
+
|
|
7
|
+
interface GridContextValue {
|
|
8
|
+
dimensions: GridDimensions;
|
|
9
|
+
grid: MeetGridResult | null;
|
|
10
|
+
springPreset: SpringPreset;
|
|
11
|
+
}
|
|
12
|
+
declare const GridContext: React.Context<GridContextValue | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Hook to access the grid context
|
|
15
|
+
*/
|
|
16
|
+
declare function useGridContext(): GridContextValue;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A React hook to calculate dimensions of an element using ResizeObserver.
|
|
20
|
+
* @param ref An element ref
|
|
21
|
+
* @returns Dimensions of the element
|
|
22
|
+
*/
|
|
23
|
+
declare function useGridDimensions(ref: RefObject<HTMLElement | null>): GridDimensions;
|
|
24
|
+
/**
|
|
25
|
+
* React hook for creating a meet-style responsive grid.
|
|
26
|
+
* @param options Grid options including dimensions, count, aspectRatio, gap, and layoutMode
|
|
27
|
+
* @returns Grid result with width, height, and position getter
|
|
28
|
+
*/
|
|
29
|
+
declare function useMeetGrid(options: MeetGridOptions): MeetGridResult;
|
|
30
|
+
/**
|
|
31
|
+
* Hook to get animation configuration for Motion
|
|
32
|
+
*/
|
|
33
|
+
declare function useGridAnimation(preset?: SpringPreset): {
|
|
34
|
+
stiffness: 400;
|
|
35
|
+
damping: 30;
|
|
36
|
+
type: "spring";
|
|
37
|
+
} | {
|
|
38
|
+
stiffness: 300;
|
|
39
|
+
damping: 30;
|
|
40
|
+
type: "spring";
|
|
41
|
+
} | {
|
|
42
|
+
stiffness: 200;
|
|
43
|
+
damping: 25;
|
|
44
|
+
type: "spring";
|
|
45
|
+
} | {
|
|
46
|
+
stiffness: 400;
|
|
47
|
+
damping: 15;
|
|
48
|
+
type: "spring";
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
interface GridContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
52
|
+
/** Children to render inside the grid */
|
|
53
|
+
children: ReactNode;
|
|
54
|
+
/** Aspect ratio in format "width:height" (e.g., "16:9") */
|
|
55
|
+
aspectRatio?: string;
|
|
56
|
+
/** Gap between items in pixels */
|
|
57
|
+
gap?: number;
|
|
58
|
+
/** Number of items (if not using GridItem children) */
|
|
59
|
+
count?: number;
|
|
60
|
+
/** Layout mode */
|
|
61
|
+
layoutMode?: LayoutMode;
|
|
62
|
+
/** Index of pinned item */
|
|
63
|
+
pinnedIndex?: number;
|
|
64
|
+
/** Index of active speaker */
|
|
65
|
+
speakerIndex?: number;
|
|
66
|
+
/** Sidebar position */
|
|
67
|
+
sidebarPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
68
|
+
/** Sidebar ratio (0-1) */
|
|
69
|
+
sidebarRatio?: number;
|
|
70
|
+
/** Spring animation preset */
|
|
71
|
+
springPreset?: SpringPreset;
|
|
72
|
+
/** Custom container style */
|
|
73
|
+
style?: CSSProperties;
|
|
74
|
+
/** Additional class name */
|
|
75
|
+
className?: string;
|
|
76
|
+
/** Maximum items per page for pagination (0 = no pagination) */
|
|
77
|
+
maxItemsPerPage?: number;
|
|
78
|
+
/** Current page index (0-based) for pagination */
|
|
79
|
+
currentPage?: number;
|
|
80
|
+
/** Maximum visible "others" in speaker/sidebar modes (0 = show all) */
|
|
81
|
+
maxVisibleOthers?: number;
|
|
82
|
+
/** Current page for "others" in speaker/sidebar modes (0-based) */
|
|
83
|
+
currentOthersPage?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Container component for the meet grid.
|
|
87
|
+
* Provides grid context to child GridItem components.
|
|
88
|
+
*/
|
|
89
|
+
declare const GridContainer: React__default.ForwardRefExoticComponent<GridContainerProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
90
|
+
interface GridItemProps extends Omit<HTMLMotionProps<'div'>, 'animate' | 'initial' | 'transition'> {
|
|
91
|
+
/** Index of this item in the grid */
|
|
92
|
+
index: number;
|
|
93
|
+
/** Children to render inside the item */
|
|
94
|
+
children: ReactNode;
|
|
95
|
+
/** Custom transition override */
|
|
96
|
+
transition?: Transition;
|
|
97
|
+
/** Whether to disable animations */
|
|
98
|
+
disableAnimation?: boolean;
|
|
99
|
+
/** Additional class name */
|
|
100
|
+
className?: string;
|
|
101
|
+
/** Custom style (merged with animated styles) */
|
|
102
|
+
style?: CSSProperties;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Grid item component with Motion animations.
|
|
106
|
+
* Automatically positions itself based on index in the grid.
|
|
107
|
+
*/
|
|
108
|
+
declare const GridItem: React__default.ForwardRefExoticComponent<Omit<GridItemProps, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
|
|
109
|
+
interface GridOverlayProps extends HTMLAttributes<HTMLDivElement> {
|
|
110
|
+
/** Whether to show the overlay */
|
|
111
|
+
visible?: boolean;
|
|
112
|
+
/** Overlay background color */
|
|
113
|
+
backgroundColor?: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Overlay component for grid items (e.g., for muted indicator, name label)
|
|
117
|
+
*/
|
|
118
|
+
declare const GridOverlay: React__default.ForwardRefExoticComponent<GridOverlayProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
119
|
+
|
|
120
|
+
export { GridContainer, GridContext, GridItem, GridOverlay, useGridAnimation, useGridContext, useGridDimensions, useMeetGrid };
|
|
121
|
+
export type { GridContainerProps, GridItemProps, GridOverlayProps };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { createContext, useContext, useState, useEffect, useMemo, forwardRef, useRef } from 'react';
|
|
2
|
-
import { createMeetGrid, getSpringConfig } from '@meet-layout-grid
|
|
3
|
-
export { createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@meet-layout-grid
|
|
2
|
+
import { createMeetGrid, getSpringConfig } from '@thangdevalone/meet-layout-grid-core';
|
|
3
|
+
export { createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
4
4
|
import { motion } from 'motion/react';
|
|
5
5
|
|
|
6
6
|
const GridContext = createContext(null);
|
|
@@ -53,7 +53,11 @@ function useMeetGrid(options) {
|
|
|
53
53
|
options.pinnedIndex,
|
|
54
54
|
options.speakerIndex,
|
|
55
55
|
options.sidebarPosition,
|
|
56
|
-
options.sidebarRatio
|
|
56
|
+
options.sidebarRatio,
|
|
57
|
+
options.maxItemsPerPage,
|
|
58
|
+
options.currentPage,
|
|
59
|
+
options.maxVisibleOthers,
|
|
60
|
+
options.currentOthersPage
|
|
57
61
|
]);
|
|
58
62
|
}
|
|
59
63
|
function useGridAnimation(preset = "smooth") {
|
|
@@ -74,6 +78,10 @@ const GridContainer = forwardRef(
|
|
|
74
78
|
springPreset = "smooth",
|
|
75
79
|
style,
|
|
76
80
|
className,
|
|
81
|
+
maxItemsPerPage,
|
|
82
|
+
currentPage,
|
|
83
|
+
maxVisibleOthers,
|
|
84
|
+
currentOthersPage,
|
|
77
85
|
...props
|
|
78
86
|
}, forwardedRef) {
|
|
79
87
|
const internalRef = useRef(null);
|
|
@@ -89,7 +97,11 @@ const GridContainer = forwardRef(
|
|
|
89
97
|
pinnedIndex,
|
|
90
98
|
speakerIndex,
|
|
91
99
|
sidebarPosition,
|
|
92
|
-
sidebarRatio
|
|
100
|
+
sidebarRatio,
|
|
101
|
+
maxItemsPerPage,
|
|
102
|
+
currentPage,
|
|
103
|
+
maxVisibleOthers,
|
|
104
|
+
currentOthersPage
|
|
93
105
|
};
|
|
94
106
|
const grid = useMeetGrid(gridOptions);
|
|
95
107
|
const containerStyle = {
|
|
@@ -116,6 +128,9 @@ const GridItem = forwardRef(
|
|
|
116
128
|
if (!grid) {
|
|
117
129
|
return null;
|
|
118
130
|
}
|
|
131
|
+
if (!grid.isItemVisible(index)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
119
134
|
const { top, left } = grid.getPosition(index);
|
|
120
135
|
const { width, height } = grid.getItemDimensions(index);
|
|
121
136
|
const isMain = grid.isMainItem(index);
|
package/package.json
CHANGED
|
@@ -1,62 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@thangdevalone/meet-layout-grid-react",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "React integration for meet-layout-grid with Motion animations",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"react",
|
|
26
|
+
"grid",
|
|
27
|
+
"meeting",
|
|
28
|
+
"video",
|
|
29
|
+
"motion",
|
|
30
|
+
"animation"
|
|
31
|
+
],
|
|
32
|
+
"author": "ThangDevAlone",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"homepage": "https://github.com/thangdevalone/meet-layout-grid#readme",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/thangdevalone/meet-layout-grid"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"react": ">=18.0.0",
|
|
41
|
+
"react-dom": ">=18.0.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"motion": "^11.15.0",
|
|
45
|
+
"@thangdevalone/meet-layout-grid-core": "1.0.3"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "^18.2.0",
|
|
49
|
+
"@types/react-dom": "^18.2.0",
|
|
50
|
+
"react": "^18.2.0",
|
|
51
|
+
"react-dom": "^18.2.0",
|
|
52
|
+
"unbuild": "^2.0.0",
|
|
53
|
+
"vitest": "^1.0.0",
|
|
54
|
+
"rimraf": "^5.0.0"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "unbuild",
|
|
58
|
+
"dev": "unbuild --watch",
|
|
59
|
+
"clean": "rimraf dist",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest"
|
|
62
|
+
}
|
|
63
|
+
}
|