react-motion-gallery 2.0.75 → 2.0.77

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.
Files changed (142) hide show
  1. package/README.md +123 -44
  2. package/dist/{FullscreenRuntime-YUCNZSE6.mjs → FullscreenRuntime-GNSZ2OS3.mjs} +1 -1
  3. package/dist/FullscreenRuntime-OE6CYK62.css +1 -0
  4. package/dist/{GridSkeleton-BmMxvXie.d.mts → GridSkeleton-DHuqcIFL.d.mts} +1 -1
  5. package/dist/{MasonrySkeleton-Dju7PDw7.d.mts → MasonrySkeleton-C7WkAbFh.d.mts} +1 -1
  6. package/dist/chunk-2WM2A4RK.mjs +4 -0
  7. package/dist/chunk-2YTRLSWQ.mjs +1 -0
  8. package/dist/chunk-3GLW5FCD.mjs +1 -0
  9. package/dist/{chunk-4QZCHWR5.mjs → chunk-3TFKVS63.mjs} +1 -1
  10. package/dist/{chunk-536MNOJH.mjs → chunk-5OYXAAEQ.mjs} +1 -1
  11. package/dist/chunk-6BPMRW6K.mjs +1 -0
  12. package/dist/{chunk-CIETZWGT.mjs → chunk-6G2EJHW6.mjs} +1 -1
  13. package/dist/{chunk-WE3JOHED.mjs → chunk-6MX5FBOB.mjs} +1 -1
  14. package/dist/{chunk-VJPQSYY6.mjs → chunk-7CUGPJMX.mjs} +1 -1
  15. package/dist/{chunk-E52DTULL.mjs → chunk-7G5QBCV3.mjs} +1 -1
  16. package/dist/chunk-A5ERE5BW.mjs +3 -0
  17. package/dist/{chunk-AJHLDKVD.mjs → chunk-B3L6FFUP.mjs} +1 -1
  18. package/dist/{chunk-S72WUSQL.mjs → chunk-F443J6CZ.mjs} +1 -1
  19. package/dist/chunk-GVW2FBCS.mjs +1 -0
  20. package/dist/{chunk-ZE6FIVKA.mjs → chunk-HNMR7ZQY.mjs} +1 -1
  21. package/dist/{chunk-SOWWUXCL.mjs → chunk-IFU7FJFX.mjs} +1 -1
  22. package/dist/chunk-IGSEIMAQ.mjs +1 -0
  23. package/dist/chunk-JHKY7OB7.mjs +0 -0
  24. package/dist/{chunk-M32PXYQO.mjs → chunk-JYIGG2JK.mjs} +1 -1
  25. package/dist/chunk-KOI77DGH.mjs +1 -0
  26. package/dist/chunk-MUYJLDYM.mjs +1 -0
  27. package/dist/{chunk-AIFIRFXZ.mjs → chunk-PAX6EZMX.mjs} +1 -1
  28. package/dist/chunk-QUY5FE75.mjs +1 -0
  29. package/dist/chunk-S23S23HP.mjs +2 -0
  30. package/dist/chunk-SMR2CHXT.mjs +1 -0
  31. package/dist/{chunk-Q7CX2MQ5.mjs → chunk-UBCYWKG3.mjs} +1 -1
  32. package/dist/{chunk-26PS4IG4.mjs → chunk-Y33KEQVI.mjs} +1 -1
  33. package/dist/{chunk-XEHEQE3K.mjs → chunk-YTIARAWT.mjs} +1 -1
  34. package/dist/chunk-ZVFKCJM2.mjs +1 -0
  35. package/dist/entries-cache.css +1 -1
  36. package/dist/entries-cache.d.mts +5 -5
  37. package/dist/entries-cache.mjs +1 -1
  38. package/dist/entries.css +1 -1
  39. package/dist/entries.d.mts +5 -5
  40. package/dist/entries.mjs +1 -1
  41. package/dist/fullscreen-captions.css +1 -1
  42. package/dist/fullscreen-captions.mjs +1 -1
  43. package/dist/fullscreen-lazy-load.css +1 -1
  44. package/dist/fullscreen-lazy-load.mjs +1 -1
  45. package/dist/fullscreen-slider.css +1 -1
  46. package/dist/fullscreen-slider.mjs +1 -1
  47. package/dist/fullscreen-video.css +1 -1
  48. package/dist/fullscreen-video.mjs +1 -1
  49. package/dist/fullscreen.css +1 -1
  50. package/dist/fullscreen.mjs +1 -1
  51. package/dist/fullscreenThumbnails.css +1 -1
  52. package/dist/fullscreenThumbnails.mjs +1 -1
  53. package/dist/grid-fullscreen.d.mts +12 -0
  54. package/dist/grid-fullscreen.mjs +1 -0
  55. package/dist/grid-lazy-load.css +1 -1
  56. package/dist/grid-lazy-load.d.mts +1 -1
  57. package/dist/grid-lazy-load.mjs +1 -1
  58. package/dist/grid-ready.d.mts +1 -1
  59. package/dist/grid.css +1 -1
  60. package/dist/grid.d.mts +3 -3
  61. package/dist/grid.mjs +1 -1
  62. package/dist/{index-Dop14JX0.d.mts → index-k9JcWxFa.d.mts} +1 -1
  63. package/dist/index.css +1 -1
  64. package/dist/index.d.mts +6 -4
  65. package/dist/index.mjs +1 -1
  66. package/dist/masonry-BHq_xi-F.d.mts +76 -0
  67. package/dist/{masonry-Bapgkuum.d.mts → masonry-C7eQ6whX.d.mts} +4 -4
  68. package/dist/masonry-fullscreen.d.mts +10 -0
  69. package/dist/masonry-fullscreen.mjs +1 -0
  70. package/dist/masonry-lazy-load.css +1 -1
  71. package/dist/masonry-lazy-load.d.mts +5 -3
  72. package/dist/masonry-lazy-load.mjs +1 -1
  73. package/dist/masonry-measured-ready.d.mts +4 -0
  74. package/dist/masonry-measured-ready.mjs +1 -0
  75. package/dist/masonry-measured.css +1 -0
  76. package/dist/masonry-measured.d.mts +21 -0
  77. package/dist/masonry-measured.mjs +1 -0
  78. package/dist/masonry-ready.d.mts +1 -1
  79. package/dist/masonry.css +1 -1
  80. package/dist/masonry.d.mts +48 -11
  81. package/dist/masonry.mjs +1 -1
  82. package/dist/metafile-esm.json +1 -1
  83. package/dist/placement-BWKxkHD8.d.mts +5 -0
  84. package/dist/skeleton-base.css +1 -1
  85. package/dist/skeleton-base.mjs +1 -1
  86. package/dist/skeleton-cache-base.css +1 -1
  87. package/dist/skeleton-cache-base.mjs +1 -1
  88. package/dist/skeleton-cache-grid.css +1 -1
  89. package/dist/skeleton-cache-grid.d.mts +2 -2
  90. package/dist/skeleton-cache-grid.mjs +1 -1
  91. package/dist/skeleton-cache-masonry-structured.css +1 -0
  92. package/dist/skeleton-cache-masonry-structured.d.mts +20 -0
  93. package/dist/skeleton-cache-masonry-structured.mjs +1 -0
  94. package/dist/skeleton-cache-masonry.css +1 -1
  95. package/dist/skeleton-cache-masonry.d.mts +4 -10
  96. package/dist/skeleton-cache-masonry.mjs +1 -1
  97. package/dist/skeleton-cache-slider.css +1 -1
  98. package/dist/skeleton-cache-slider.mjs +1 -1
  99. package/dist/skeleton-grid.css +1 -1
  100. package/dist/skeleton-grid.d.mts +3 -3
  101. package/dist/skeleton-grid.mjs +1 -1
  102. package/dist/skeleton-masonry-structured.css +1 -0
  103. package/dist/skeleton-masonry-structured.d.mts +62 -0
  104. package/dist/skeleton-masonry-structured.mjs +1 -0
  105. package/dist/skeleton-masonry.css +1 -1
  106. package/dist/skeleton-masonry.d.mts +8 -60
  107. package/dist/skeleton-masonry.mjs +1 -1
  108. package/dist/skeleton-slider-restore.css +1 -1
  109. package/dist/skeleton-slider-restore.mjs +1 -1
  110. package/dist/skeleton-slider.css +1 -1
  111. package/dist/skeleton-slider.mjs +1 -1
  112. package/dist/slider-dots.css +1 -1
  113. package/dist/slider-dots.mjs +1 -1
  114. package/dist/slider-lazy-load.css +1 -1
  115. package/dist/slider-lazy-load.mjs +1 -1
  116. package/dist/slider-loading.css +1 -1
  117. package/dist/slider-loading.mjs +1 -1
  118. package/dist/slider-scrollbar.css +1 -1
  119. package/dist/slider-scrollbar.mjs +1 -1
  120. package/dist/slider.css +1 -1
  121. package/dist/slider.mjs +1 -1
  122. package/dist/styles.css +7 -3
  123. package/dist/thumbnails.css +1 -1
  124. package/dist/thumbnails.mjs +1 -1
  125. package/dist/types-0ntfoMKP.d.mts +35 -0
  126. package/dist/{types-ap0Mfoo0.d.mts → types-CYB4fl6-.d.mts} +16 -4
  127. package/dist/{types-plwyER1z.d.mts → types-Cc37Drgz.d.mts} +2 -1
  128. package/dist/video.css +1 -1
  129. package/dist/video.mjs +1 -1
  130. package/dist/zoomPan.mjs +1 -1
  131. package/package.json +25 -1
  132. package/dist/FullscreenRuntime-N57MGEC6.css +0 -1
  133. package/dist/chunk-5BPPBSSK.mjs +0 -3
  134. package/dist/chunk-DJFTY42G.mjs +0 -1
  135. package/dist/chunk-ESPDSNI6.mjs +0 -1
  136. package/dist/chunk-I3HJIUHX.mjs +0 -1
  137. package/dist/chunk-JB7UY72X.mjs +0 -1
  138. package/dist/chunk-OI76LZVE.mjs +0 -1
  139. package/dist/chunk-QBGBTFT4.mjs +0 -2
  140. package/dist/chunk-TOYDNDZ6.mjs +0 -4
  141. package/dist/chunk-WS5Y5APY.mjs +0 -1
  142. package/dist/chunk-YOOKXYP6.mjs +0 -1
package/README.md CHANGED
@@ -11,15 +11,19 @@ This table reports local gzip measurements for selected runtime surfaces. Type-o
11
11
  <!-- bundle-size:start -->
12
12
  | Surface | JS gzip |
13
13
  | --- | --- |
14
- | `Entries` | 12.2kB |
15
- | `entries/cache` | 16.9kB |
14
+ | `Entries` | 12.3kB |
15
+ | `entries/cache` | 17.0kB |
16
16
  | `FullscreenThumbnailSlider` | 20.3kB |
17
17
  | `GalleryCore` | 2.6kB |
18
- | `Grid` | 6.4kB |
18
+ | `Grid` | 5.4kB |
19
19
  | `grid/ready` | 323.0B |
20
20
  | `grid/lazy-load` | 3.3kB |
21
- | `Masonry` | 7.2kB |
21
+ | `grid/fullscreen` | 1.6kB |
22
+ | `Masonry` | 4.2kB |
22
23
  | `masonry/ready` | 323.0B |
24
+ | `masonry/fullscreen` | 1.1kB |
25
+ | `masonry/measured` | 7.2kB |
26
+ | `masonry/measured/ready` | 323.0B |
23
27
  | `masonry/lazy-load` | 3.3kB |
24
28
  | `Skeleton base` | 8.9kB |
25
29
  | `skeleton/cache/base` | 13.6kB |
@@ -28,8 +32,10 @@ This table reports local gzip measurements for selected runtime surfaces. Type-o
28
32
  | `skeleton/slider/restore` | 25.2kB |
29
33
  | `skeleton/grid` | 11.2kB |
30
34
  | `skeleton/cache/grid` | 16.0kB |
31
- | `skeleton/masonry` | 20.1kB |
32
- | `skeleton/cache/masonry` | 25.3kB |
35
+ | `skeleton/masonry` | 4.4kB |
36
+ | `skeleton/cache/masonry` | 4.4kB |
37
+ | `skeleton/masonry/structured` | 20.2kB |
38
+ | `skeleton/cache/masonry/structured` | 25.3kB |
33
39
  | `Slider core` | 19.0kB |
34
40
  | `slider/ready` | 894.0B |
35
41
  | `slider/arrows` | 1.2kB |
@@ -49,11 +55,11 @@ This table reports local gzip measurements for selected runtime surfaces. Type-o
49
55
  | `fullscreen/controls` | 173.0B |
50
56
  | `fullscreen/captions` | 13.2kB |
51
57
  | `fullscreen/zoom-pan` | 12.4kB |
52
- | `fullscreen/video` | 16.4kB |
58
+ | `fullscreen/video` | 16.5kB |
53
59
  | `fullscreen/lazy-load` | 13.2kB |
54
60
  | `fullscreen/crossfade` | 181.0B |
55
61
  | `fullscreen/thumbnails` | 160.0B |
56
- | `Video` | 12.7kB |
62
+ | `Video` | 12.8kB |
57
63
  | `ZoomPanImage` | 11.0kB |
58
64
  | `zoomPan/hover` | 124.0B |
59
65
  | `media / toMediaItems` | 260.0B |
@@ -64,10 +70,15 @@ This table reports local gzip measurements for selected runtime surfaces. Type-o
64
70
 
65
71
  ## Installation
66
72
 
67
- Install the package, then add the optional video peers only if you use `Video`.
73
+ Install the package:
68
74
 
69
75
  ```bash
70
76
  npm install react-motion-gallery
77
+ ```
78
+
79
+ If you use `Video` or fullscreen video playback, also install the optional Plyr peers:
80
+
81
+ ```bash
71
82
  npm install plyr plyr-react
72
83
  ```
73
84
 
@@ -77,6 +88,12 @@ Import the stylesheet. The package uses CSS Modules internally, but consumers on
77
88
  import "react-motion-gallery/styles.css";
78
89
  ```
79
90
 
91
+ Most examples in this README use hooks, event handlers, or browser-only behavior. In Next.js App Router, put those components in a client file with `"use client";`; server components can still prepare media data and pass it down.
92
+
93
+ ## License
94
+
95
+ React Motion Gallery is licensed under `PolyForm-Noncommercial-1.0.0`. Non-commercial use is free. Commercial use requires a paid license; see [react-motion-gallery.com/license](https://react-motion-gallery.com/license).
96
+
80
97
  ## Overview
81
98
 
82
99
  Mental model:
@@ -160,21 +177,27 @@ Subpaths give bundlers a smaller graph than the root. Less JS to transfer, parse
160
177
  | `react-motion-gallery/grid` | `Grid`, `Grid.Item`, grid types |
161
178
  | `react-motion-gallery/grid/ready` | `useGridReady` |
162
179
  | `react-motion-gallery/grid/lazy-load` | `gridLazyLoad` |
180
+ | `react-motion-gallery/grid/fullscreen` | `gridFullscreen` for Grid + `GalleryCore` |
163
181
  | `react-motion-gallery/masonry` | `Masonry`, `Masonry.Item`, masonry types |
164
182
  | `react-motion-gallery/masonry/ready` | `useMasonryReady` |
183
+ | `react-motion-gallery/masonry/fullscreen` | `masonryFullscreen` for light Masonry + `GalleryCore` |
184
+ | `react-motion-gallery/masonry/measured` | Measured `Masonry`, `Masonry.Item`, plugins/reveal/fullscreen types |
185
+ | `react-motion-gallery/masonry/measured/ready` | `useMasonryReady` for measured masonry |
165
186
  | `react-motion-gallery/masonry/lazy-load` | `masonryLazyLoad` |
166
187
  | `react-motion-gallery/entries` | `Entries`, `flattenEntries`, entry media container helpers |
167
188
  | `react-motion-gallery/entries/cache` | `CachedEntries` with `entries.loading.cache` |
168
189
  | `react-motion-gallery/skeleton/base` | Standalone `Skeleton` and generic skeleton authoring types |
169
190
  | `react-motion-gallery/skeleton/slider` | `SliderSkeleton` and slider skeleton authoring types |
170
191
  | `react-motion-gallery/skeleton/grid` | `GridSkeleton` and grid skeleton authoring types |
171
- | `react-motion-gallery/skeleton/masonry` | `MasonrySkeleton` and masonry skeleton authoring types |
192
+ | `react-motion-gallery/skeleton/masonry` | Lightweight `MasonrySkeleton` for dimensioned placeholders |
193
+ | `react-motion-gallery/skeleton/masonry/structured` | Structured `MasonrySkeleton` and masonry skeleton authoring types |
172
194
  | `react-motion-gallery/skeleton/cache` | Server-safe skeleton cookie cache helpers and types |
173
195
  | `react-motion-gallery/skeleton/cache/provider` | Client `SkeletonCacheProvider` for SSR snapshots and client cookie refresh |
174
196
  | `react-motion-gallery/skeleton/cache/base` | `CachedSkeleton` with `cache` |
175
197
  | `react-motion-gallery/skeleton/cache/slider` | `CachedSliderSkeleton` with `cache` |
176
198
  | `react-motion-gallery/skeleton/cache/grid` | `CachedGridSkeleton` with `cache` |
177
- | `react-motion-gallery/skeleton/cache/masonry` | `CachedMasonrySkeleton` with `cache` |
199
+ | `react-motion-gallery/skeleton/cache/masonry` | Lightweight `CachedMasonrySkeleton` |
200
+ | `react-motion-gallery/skeleton/cache/masonry/structured` | Structured `CachedMasonrySkeleton` with `cache` |
178
201
  | `react-motion-gallery/skeleton/slider/restore` | `RestoredSliderSkeleton` with `restore` and optional `cache` |
179
202
  | `react-motion-gallery/fullscreen` | `useFullscreenController` and fullscreen types |
180
203
  | `react-motion-gallery/fullscreen/slider` | `fullscreenSlider` |
@@ -544,9 +567,9 @@ Wrap the client tree in `SkeletonCacheProvider`, then opt individual skeletons i
544
567
 
545
568
  import type { SkeletonCacheSnapshot } from "react-motion-gallery/skeleton/cache";
546
569
  import { SkeletonCacheProvider } from "react-motion-gallery/skeleton/cache/provider";
547
- import { CachedMasonrySkeleton as MasonrySkeleton } from "react-motion-gallery/skeleton/cache/masonry";
548
- import { Masonry } from "react-motion-gallery/masonry";
549
- import { useMasonryReady } from "react-motion-gallery/masonry/ready";
570
+ import { CachedMasonrySkeleton as MasonrySkeleton } from "react-motion-gallery/skeleton/cache/masonry/structured";
571
+ import { Masonry } from "react-motion-gallery/masonry/measured";
572
+ import { useMasonryReady } from "react-motion-gallery/masonry/measured/ready";
550
573
 
551
574
  export function GalleryPageClient({
552
575
  skeletonCacheSnapshots,
@@ -784,6 +807,7 @@ export function BasicSlider() {
784
807
  | `scroll.strictSnaps` | `boolean` | `false` | Prevents one drag release from settling more than one snap away from where the drag started. Overrides `scroll.skipSnaps`. |
785
808
  | `scroll.freeScroll` | `boolean` | `false` | Enables free dragging instead of strict snapping. |
786
809
  | `scroll.loop` | `boolean` | `false` | Wraps around at the ends. |
810
+ | `scroll.containScroll` | `boolean` | `false` | Clamps start/end snaps so non-looping variable-width or centered sliders do not leave excess empty space at the track edges. |
787
811
 
788
812
  `scroll.groupCells` affects the snap pages used by drag, wheel, arrows, dots, and imperative navigation. Use `true` for automatic fit-to-viewport grouping, or a count for explicit snap pages:
789
813
 
@@ -1303,8 +1327,8 @@ export function BasicGrid() {
1303
1327
  | `gap` | `number \| Record<string, number>` | `8` | Responsive grid gap. |
1304
1328
  | `rootClassName` | `string` | `—` | Class name for the grid root. |
1305
1329
  | `itemClassName` | `string` | `—` | Class name added to each wrapped grid item. |
1306
- | `fullscreenTrigger` | `"item" \| "media"` | `"media"` | Opens fullscreen from the clicked media node or the entire item shell. |
1307
- | `plugins` | `GridPlugin[]` | `[]` | Explicit first-party Grid features such as lazy-load. |
1330
+ | `fullscreenTrigger` | `"item" \| "media"` | `"media"` | When `gridFullscreen()` is active, opens fullscreen from the clicked media node or the entire item shell. |
1331
+ | `plugins` | `GridPlugin[]` | `[]` | Explicit first-party Grid features such as lazy-load and fullscreen. |
1308
1332
  | `reveal.renderReveal` | `({ active, containerProps }, content) => ReactNode` | `—` | Custom reveal wrapper. |
1309
1333
  | `reveal.staggerMs` | `number` | `60` | Reveal stagger for the fade-in. |
1310
1334
  | `reveal.durationMs` | `number` | `600` | Reveal fade duration. |
@@ -1318,17 +1342,19 @@ Import Grid plugins from their own subpaths and pass them to `plugins`.
1318
1342
  ```typescript
1319
1343
  import { Grid } from "react-motion-gallery/grid";
1320
1344
  import { gridLazyLoad } from "react-motion-gallery/grid/lazy-load";
1345
+ import { gridFullscreen } from "react-motion-gallery/grid/fullscreen";
1321
1346
 
1322
- <Grid plugins={[gridLazyLoad({ spinner: true })]}>{items}</Grid>;
1347
+ <Grid plugins={[gridLazyLoad({ spinner: true }), gridFullscreen()]}>{items}</Grid>;
1323
1348
  ```
1324
1349
 
1325
1350
  | Import | Factory | Notes |
1326
1351
  | --- | --- | --- |
1327
1352
  | `react-motion-gallery/grid/lazy-load` | `gridLazyLoad(options)` | Rewrites trackable image `src` values into `data-rmg-lazy-src`, reveals them on viewport intersection, then fades them in after decode and spinner exit. |
1353
+ | `react-motion-gallery/grid/fullscreen` | `gridFullscreen()` | Opens `GalleryCore` fullscreen from Grid items without adding fullscreen code to the default grid import. |
1328
1354
 
1329
1355
  `gridLazyLoad()` enables lazy loading by default. Pass `{ enabled: false }` to make the plugin inert.
1330
1356
 
1331
- Grid fullscreen behavior is provided by `GalleryCore` and `useFullscreenController`; Grid itself does not expose a ref-based imperative API.
1357
+ Grid fullscreen behavior is provided by `GalleryCore`, `useFullscreenController`, and the opt-in `gridFullscreen()` plugin. Grid itself does not expose a ref-based imperative API.
1332
1358
 
1333
1359
  Wrap a card in `Grid.Item` when it should span tracks or needs wrapper styling:
1334
1360
 
@@ -1422,18 +1448,29 @@ function GridWithSkeleton({ images }: { images: { src: string; alt: string }[] }
1422
1448
  ```typescript
1423
1449
  import { Masonry } from "react-motion-gallery";
1424
1450
 
1425
- const cards = [280, 360, 220, 420, 300, 340];
1451
+ const images = [
1452
+ { src: "https://picsum.photos/id/1018/1200/1600", width: 1200, height: 1600 },
1453
+ { src: "https://picsum.photos/id/1025/1200/900", width: 1200, height: 900 },
1454
+ { src: "https://picsum.photos/id/1036/1200/1500", width: 1200, height: 1500, span: { 0: 1, 1100: 2 } },
1455
+ { src: "https://picsum.photos/id/1041/1200/800", width: 1200, height: 800 },
1456
+ ];
1426
1457
 
1427
1458
  export function BasicMasonry() {
1428
1459
  return (
1429
1460
  <Masonry columns={{ 0: 1, 700: 2, 1100: 3 }} gap={{ 0: 12, 1100: 20 }}>
1430
- {cards.map((height, index) => (
1431
- <img
1432
- key={index}
1433
- src={`https://picsum.photos/seed/masonry-${index}/1000/${height * 3}`}
1434
- alt={`Masonry item ${index + 1}`}
1435
- style={{ width: "100%", height, objectFit: "cover", borderRadius: 12 }}
1436
- />
1461
+ {images.map((image, index) => (
1462
+ <Masonry.Item
1463
+ key={image.src}
1464
+ width={image.width}
1465
+ height={image.height}
1466
+ span={image.span}
1467
+ >
1468
+ <img
1469
+ src={image.src}
1470
+ alt={`Masonry item ${index + 1}`}
1471
+ style={{ width: "100%", height: "100%", objectFit: "cover", borderRadius: 12 }}
1472
+ />
1473
+ </Masonry.Item>
1437
1474
  ))}
1438
1475
  </Masonry>
1439
1476
  );
@@ -1444,7 +1481,7 @@ export function BasicMasonry() {
1444
1481
 
1445
1482
  | Option | Type | Default | Notes |
1446
1483
  | --- | --- | --- | --- |
1447
- | `children` | `React.ReactNode` | `—` | Masonry items rendered in order. Wrap individual cards in `Masonry.Item` when they need custom spans or wrapper props. |
1484
+ | `children` | `React.ReactNode` | `—` | Dimensioned masonry items. Each item should be wrapped in `Masonry.Item`. |
1448
1485
  | `breakpoints` | `Record<string, number>` | `xs: 0, sm: 600, md: 900, lg: 1200, xl: 1536` | Used to resolve responsive columns and gaps. |
1449
1486
 
1450
1487
  ### Masonry.Item props
@@ -1452,6 +1489,8 @@ export function BasicMasonry() {
1452
1489
  | Option | Type | Default | Notes |
1453
1490
  | --- | --- | --- | --- |
1454
1491
  | `children` | `React.ReactNode` | `—` | The masonry card content. |
1492
+ | `width` | `number` | `—` | Intrinsic item width used for aspect-ratio layout. |
1493
+ | `height` | `number` | `—` | Intrinsic item height used for aspect-ratio layout. |
1455
1494
  | `span` | `number \| "full" \| Record<string, number \| "full">` | `1` | Per-item track span. `"full"` resolves to the active column count and numeric values clamp to the current track count. |
1456
1495
  | `className` | `string` | `—` | Extra class name merged onto the masonry item wrapper. |
1457
1496
  | `style` | `React.CSSProperties` | `—` | Inline styles merged onto the masonry item wrapper. |
@@ -1463,41 +1502,41 @@ export function BasicMasonry() {
1463
1502
  | `columns` | `number \| Record<string, number>` | `—` | Responsive column count. |
1464
1503
  | `gap` | `number \| Record<string, number>` | `—` | Responsive gap between columns and items. |
1465
1504
  | `placement` | `"balanced" \| "roundRobin" \| "horizontalOrder"` | `"balanced"` | `balanced` packs into the shortest fitting column group, `roundRobin` cycles start columns deterministically, and `horizontalOrder` preserves a stronger left-to-right scan when spans are involved. |
1466
- | `fullscreenTrigger` | `"item" \| "media"` | `"media"` | Opens fullscreen from the clicked media node or the entire masonry item shell. |
1467
- | `itemWrapClassName` | `string` | `—` | Class name added to the masonry item wrapper. |
1468
- | `itemWrapStyle` | `React.CSSProperties` | `—` | Inline styles applied to the masonry item wrapper. |
1469
1505
  | `as` | `React.ElementType` | `"div"` | Root HTML element or custom component. |
1470
1506
  | `rootRef` | `React.Ref<HTMLDivElement>` | `—` | Ref to the masonry root. |
1471
1507
  | `classNames.root` | `string` | `—` | Root class name. |
1472
- | `classNames.column` | `string` | `—` | Retained for backwards compatibility with the legacy column-wrapper renderer. |
1473
1508
  | `classNames.item` | `string` | `—` | Item class name. |
1474
- | `plugins` | `MasonryPlugin[]` | `[]` | Explicit first-party Masonry features such as lazy-load. |
1475
- | `reveal.renderReveal` | `({ active, containerProps }, content) => ReactNode` | `—` | Custom reveal wrapper. |
1509
+ | `plugins` | `MasonryPlugin[]` | `[]` | Opt-in light Masonry plugins, currently `masonryFullscreen()` from `react-motion-gallery/masonry/fullscreen`. |
1476
1510
  | `reveal.staggerMs` | `number` | `160` | Reveal stagger for the fade-in. |
1477
1511
  | `reveal.durationMs` | `number` | `600` | Reveal fade duration. |
1478
1512
  | `reveal.easing` | `string` | `"cubic-bezier(.2,.7,.2,1)"` | Reveal fade easing. |
1479
- | `reveal.staggerLimit` | `number` | `—` | Optional cap on how many items stagger. |
1513
+ | `reveal.disabled` | `boolean` | `false` | Disables the built-in reveal classes. |
1514
+ | `revealReady` | `boolean` | `true` | Holds the reveal until external loading or viewport orchestration is ready. |
1480
1515
 
1481
1516
  ### Masonry plugins
1482
1517
 
1483
- Import Masonry plugins from their own subpaths and pass them to `plugins`.
1518
+ Import Masonry plugins from their own subpaths and pass them to `plugins`. The default dimensioned core supports the fullscreen bridge through an opt-in subpath.
1484
1519
 
1485
1520
  ```typescript
1521
+ import { GalleryCore } from "react-motion-gallery/core";
1486
1522
  import { Masonry } from "react-motion-gallery/masonry";
1487
- import { masonryLazyLoad } from "react-motion-gallery/masonry/lazy-load";
1523
+ import { masonryFullscreen } from "react-motion-gallery/masonry/fullscreen";
1488
1524
 
1489
- <Masonry plugins={[masonryLazyLoad({ spinner: true })]}>{items}</Masonry>;
1525
+ <GalleryCore layout="masonry" fullscreenItems={items}>
1526
+ <Masonry plugins={[masonryFullscreen()]}>{children}</Masonry>
1527
+ </GalleryCore>;
1490
1528
  ```
1491
1529
 
1492
1530
  | Import | Factory | Notes |
1493
1531
  | --- | --- | --- |
1532
+ | `react-motion-gallery/masonry/fullscreen` | `masonryFullscreen()` | Opens `GalleryCore` fullscreen from light dimensioned Masonry items without adding fullscreen code to the default masonry import. |
1494
1533
  | `react-motion-gallery/masonry/lazy-load` | `masonryLazyLoad(options)` | Uses the same image shell behavior as Slider: trackable image `src` values move into `data-rmg-lazy-src`, real images load on intersection, and items fade in after decode and spinner exit. |
1495
1534
 
1496
- `masonryLazyLoad()` enables lazy loading by default. Pass `{ enabled: false }` to make the plugin inert.
1535
+ `masonryLazyLoad()` is for measured Masonry and enables lazy loading by default. Pass `{ enabled: false }` to make the plugin inert.
1497
1536
 
1498
- Masonry already accepts arbitrary React children, including text-containing JSX. The wrapper props are only for styling the built-in masonry item shell.
1537
+ Measured Masonry accepts arbitrary React children, including text-containing JSX. The wrapper props are only for styling the built-in masonry item shell.
1499
1538
 
1500
- Wrap a card in `Masonry.Item` when it needs its own span, wrapper `className`, or wrapper `style`:
1539
+ In the measured subpath, wrap a card in `Masonry.Item` when it needs its own span, wrapper `className`, or wrapper `style`:
1501
1540
 
1502
1541
  ```typescript
1503
1542
  <Masonry
@@ -1522,18 +1561,23 @@ Choose a placement based on what should feel stable:
1522
1561
 
1523
1562
  Masonry no longer owns loading UI. Use `useMasonryReady` and wrap Masonry with `MasonrySkeleton`, the same composition pattern used by Slider and Grid.
1524
1563
 
1525
- Masonry skeletons live in `react-motion-gallery/skeleton/masonry` and can use a structured `layout` spec with the same inner node vocabulary as Grid skeletons, including `text` nodes and `itemWrapStyle`.
1564
+ The default Masonry import is dimensioned and lightweight, with built-in reveal timing and opt-in fullscreen through `react-motion-gallery/masonry/fullscreen`. For arbitrary measured card heights, measured lazy-load plugins, and structured skeleton text, import from `react-motion-gallery/masonry/measured` and `react-motion-gallery/skeleton/masonry/structured`.
1565
+
1566
+ Lightweight Masonry skeletons live in `react-motion-gallery/skeleton/masonry` and mirror dimensioned `Masonry.Item` data with `items`, `ratios`, or `heightsPx`.
1567
+
1568
+ Structured Masonry skeletons live in `react-motion-gallery/skeleton/masonry/structured` and can use a `layout` spec with the same inner node vocabulary as Grid skeletons, including `text` nodes and `itemWrapStyle`.
1526
1569
 
1527
1570
  Live Masonry content mounts invisibly until the current item set has completed an initial measurement pass. The Skeleton wrapper stays visible during that handoff, so the first revealed layout is based on measured DOM geometry rather than approximate height hints.
1528
1571
 
1529
1572
  `layout.slots` gives Masonry the same per-card override escape hatch that slider skeletons have. Use a slot when one card needs a different placeholder tree, wrapper styling, span, or outer height. `slot.span` can override the corresponding `Masonry.Item` span for the placeholder, `slot.ratio` maps to Masonry's card-height rhythm, and `slot.heightPx` lets you pin a specific shell height when you need an exact placeholder.
1530
1573
 
1531
1574
  ```typescript
1532
- import { Masonry, useMasonryReady } from "react-motion-gallery";
1575
+ import { Masonry } from "react-motion-gallery/masonry/measured";
1576
+ import { useMasonryReady } from "react-motion-gallery/masonry/measured/ready";
1533
1577
  import {
1534
1578
  MasonrySkeleton,
1535
1579
  type MasonrySkeletonSpec,
1536
- } from "react-motion-gallery/skeleton/masonry";
1580
+ } from "react-motion-gallery/skeleton/masonry/structured";
1537
1581
 
1538
1582
  const masonrySkeleton: MasonrySkeletonSpec = {
1539
1583
  ratios: [118, 126, 102, 146],
@@ -1675,6 +1719,37 @@ export function EntryGallery() {
1675
1719
  }
1676
1720
  ```
1677
1721
 
1722
+ For common entry media layouts, the exported helper factories can own `renderMediaContainer` for you. Use the slider, grid, or masonry helper that matches `entries.mediaLayout`, then keep custom card and media rendering focused on your data shape.
1723
+
1724
+ ```typescript
1725
+ import {
1726
+ Entries,
1727
+ createEntriesGridMedia,
1728
+ type EntriesOptions,
1729
+ } from "react-motion-gallery/entries";
1730
+
1731
+ const renderEntryGridMedia = createEntriesGridMedia({
1732
+ gridObject: {
1733
+ columns: { 0: 1, 760: 2 },
1734
+ gap: { 0: 10, 760: 14 },
1735
+ },
1736
+ });
1737
+
1738
+ export function EntryGrid({ entries }: { entries: EntriesOptions["items"] }) {
1739
+ return (
1740
+ <Entries
1741
+ entries={{
1742
+ items: entries,
1743
+ mediaLayout: "grid",
1744
+ }}
1745
+ renderMediaContainer={renderEntryGridMedia}
1746
+ />
1747
+ );
1748
+ }
1749
+ ```
1750
+
1751
+ The same pattern works with `createEntriesSliderMedia()` and `createEntriesMasonryMedia()`. Import from `react-motion-gallery/entries/cache` instead when the entry loading skeleton also uses `loading.cache`.
1752
+
1678
1753
  ### Entry loading, decode, and reveal flow
1679
1754
 
1680
1755
  When `loading.enabled` is true, entries use two viewport gates instead of one generic fade-in. `loading.nearMargin` marks a row as near the viewport, mounts the real entry content, and starts the entry media work early. `loading.viewMargin` and `loading.threshold` record when the row has actually entered view.
@@ -1888,6 +1963,7 @@ export function StandaloneFullscreen() {
1888
1963
  import * as React from "react";
1889
1964
  import { GalleryCore, Slider, useFullscreenController } from "react-motion-gallery";
1890
1965
  import { fullscreenSlider } from "react-motion-gallery/fullscreen/slider";
1966
+ import { sliderFullscreen } from "react-motion-gallery/slider/fullscreen";
1891
1967
 
1892
1968
  const slides = [
1893
1969
  "https://picsum.photos/id/1015/1600/900",
@@ -1907,7 +1983,7 @@ function FullscreenAddon() {
1907
1983
  export function SliderWithFullscreen() {
1908
1984
  return (
1909
1985
  <GalleryCore layout="slider" fullscreenItems={slides}>
1910
- <Slider>
1986
+ <Slider plugins={[sliderFullscreen()]}>
1911
1987
  {slides.map((src, index) => (
1912
1988
  <img key={src} src={src} alt={`Slide ${index + 1}`} style={{ width: "100%" }} />
1913
1989
  ))}
@@ -2088,6 +2164,8 @@ The hook returns additional refs and setters for the internal fullscreen runtime
2088
2164
  | `slider.friction` | `number` | `0.68` | Fullscreen slider friction. |
2089
2165
  | `slider.direction` | `"ltr" \| "rtl"` | `"ltr"` | Fullscreen slider interaction direction. |
2090
2166
  | `slider.gap` | `number \| Record<string, number>` | `0` | Responsive pixel gap between fullscreen slides. Named keys resolve from `GalleryCore.breakpoints`. |
2167
+ | `slider.skipSnaps` | `boolean \| { enabled?: boolean; threshold?: number }` | `false` | Allows fullscreen drag momentum to skip snap points. Object form matches the base slider `scroll.skipSnaps` behavior. |
2168
+ | `slider.strictSnaps` | `boolean` | `false` | Prevents one fullscreen drag release from settling more than one snap away from where the drag started. Overrides `slider.skipSnaps`. |
2091
2169
  | `zoom.clickZoomLevel` | `number` | `2.5` | Zoom level used for click-to-zoom. |
2092
2170
  | `zoom.maxZoomLevel` | `number` | `3` | Maximum allowed zoom level. |
2093
2171
  | `zoom.panDuration` | `number` | `43` | Pan settling duration. |
@@ -2095,6 +2173,7 @@ The hook returns additional refs and setters for the internal fullscreen runtime
2095
2173
  | `effects.introDuration` | `number \| { transform?: number; fade?: number }` | `{ transform: 300, fade: 500 }` | Open and close intro timing. A scalar applies to both paths. Use `transform` for scale/FLIP handoffs and `fade` for opacity-only paths. |
2096
2174
  | `effects.introEasing` | `string \| { transform?: string; fade?: string }` | `"cubic-bezier(.4,0,.22,1)"` | Open and close intro easing. A scalar applies to both paths. Object keys mirror `introDuration`. |
2097
2175
  | `effects.introFade` | `boolean` | `false` | Forces fade intro behavior. |
2176
+ | `effects.introStickyNavSelector` | `string` | `—` | Selector for a sticky navigation element that may cover the source image during scale intro or close path calculations. |
2098
2177
  | `effects.crossfade.controls` | `boolean` | `false` | Uses crossfade transitions for fullscreen arrow navigation and animated slide requests. Also enables wheel crossfade unless `effects.crossfade.wheel` is provided. |
2099
2178
  | `effects.crossfade.drag` | `boolean` | `false` | Scrubs adjacent fullscreen slides with crossfade during drag instead of moving the track. |
2100
2179
  | `effects.crossfade.wheel` | `boolean \| CrossFadeWheelOptions` | `effects.crossfade.controls` | Uses wheel or touchpad travel as a one-slide-at-a-time fullscreen crossfade gesture. Set `false` to keep arrow crossfades while using normal wheel scrolling. |