@wix/fast-gallery-vibe 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +138 -0
  2. package/dist/cjs/components/GalleryWrapper.js +104 -0
  3. package/dist/cjs/components/GalleryWrapper.js.map +1 -0
  4. package/dist/cjs/components/constants.js +14 -0
  5. package/dist/cjs/components/constants.js.map +1 -0
  6. package/dist/cjs/components/gallery.css +77 -0
  7. package/dist/cjs/components/index.js +12 -0
  8. package/dist/cjs/components/index.js.map +1 -0
  9. package/dist/cjs/components/types.js +4 -0
  10. package/dist/cjs/components/types.js.map +1 -0
  11. package/dist/cjs/components/variants.js +19 -0
  12. package/dist/cjs/components/variants.js.map +1 -0
  13. package/dist/cjs/index.js +10 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/components/gallery.css +77 -0
  16. package/dist/esm/components/GalleryWrapper.js +59 -0
  17. package/dist/esm/components/GalleryWrapper.js.map +1 -0
  18. package/dist/esm/components/constants.js +10 -0
  19. package/dist/esm/components/constants.js.map +1 -0
  20. package/dist/esm/components/gallery.css +77 -0
  21. package/dist/esm/components/index.js +4 -0
  22. package/dist/esm/components/index.js.map +1 -0
  23. package/dist/esm/components/types.js +2 -0
  24. package/dist/esm/components/types.js.map +1 -0
  25. package/dist/esm/components/variants.js +15 -0
  26. package/dist/esm/components/variants.js.map +1 -0
  27. package/dist/esm/index.js +3 -0
  28. package/dist/esm/index.js.map +1 -0
  29. package/dist/types/components/GalleryWrapper.d.ts +5 -0
  30. package/dist/types/components/GalleryWrapper.d.ts.map +1 -0
  31. package/dist/types/components/constants.d.ts +10 -0
  32. package/dist/types/components/constants.d.ts.map +1 -0
  33. package/dist/types/components/index.d.ts +6 -0
  34. package/dist/types/components/index.d.ts.map +1 -0
  35. package/dist/types/components/types.d.ts +17 -0
  36. package/dist/types/components/types.d.ts.map +1 -0
  37. package/dist/types/components/variants.d.ts +6 -0
  38. package/dist/types/components/variants.d.ts.map +1 -0
  39. package/dist/types/index.d.ts +2 -0
  40. package/dist/types/index.d.ts.map +1 -0
  41. package/package.json +96 -0
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # @wix/fast-gallery-vibe
2
+
3
+ A generic, content-agnostic gallery component built on top of `@wix/fast-gallery-core` with multiple layout variants and shadCN UI patterns.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Multiple Layout Variants**: Grid, Alternating, Slider, Waterfall
8
+ - 🔧 **Generic & Content-Agnostic**: Works with any data type through intelligent data extraction
9
+ - 🎯 **Custom Item Renderers**: Flexible rendering for any component
10
+ - âš¡ **Performance Optimized**: React.useMemo and useCallback optimizations
11
+ - 🎨 **shadCN UI Patterns**: Follows shadCN component architecture with CVA
12
+ - 📱 **Responsive**: Mobile-first responsive design
13
+ - 🎯 **Simple API**: Single component with all functionality included
14
+ - 🔄 **Pure Layout System**: Works with any data type through flexible item rendering
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ yarn install @wix/fast-gallery-vibe
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Usage
25
+
26
+ ```tsx
27
+ import { GalleryWrapper } from '@wix/fast-gallery-vibe';
28
+
29
+ <GalleryWrapper
30
+ items={yourData}
31
+ variant="grid"
32
+ itemRenderer={(item, index) => (
33
+ <YourComponent item={item} index={index}>
34
+ {children}
35
+ </YourComponent>
36
+ )}
37
+ emptyState={<div>No items available</div>}
38
+ />;
39
+ ```
40
+
41
+ ### With Products
42
+
43
+ ```tsx
44
+ <GalleryWrapper
45
+ items={products}
46
+ variant="alternating"
47
+ itemRenderer={(product) => (
48
+ <Product.Root product={product}>
49
+ <Product.Name />
50
+ <Product.Price />
51
+ </Product.Root>
52
+ )}
53
+ />
54
+ ```
55
+
56
+ ### With Blog Posts
57
+
58
+ ```tsx
59
+ <GalleryWrapper
60
+ items={blogPosts}
61
+ variant="slider"
62
+ itemRenderer={(post) => (
63
+ <BlogPost.Root post={post}>
64
+ <BlogPost.Title />
65
+ <BlogPost.Excerpt />
66
+ </BlogPost.Root>
67
+ )}
68
+ />
69
+ ```
70
+
71
+ ### Using the Index Parameter
72
+
73
+ The `index` parameter is optional but useful for position-aware features:
74
+
75
+ ```tsx
76
+ <GalleryWrapper
77
+ items={products}
78
+ variant="grid"
79
+ itemRenderer={(product, index) => (
80
+ <Product.Root
81
+ product={product}
82
+ className={index === 0 ? 'featured' : ''}
83
+ data-position={index + 1}
84
+ >
85
+ {index === 0 && <Badge>Featured</Badge>}
86
+ <Product.Name />
87
+ <Product.Price />
88
+ </Product.Root>
89
+ )}
90
+ />
91
+ ```
92
+
93
+ ## Layout Variants
94
+
95
+ - **`grid`**: 3-column responsive grid layout
96
+ - **`alternating`**: 3-2-3-2 pattern (odd rows: 3 items, even rows: 2 items)
97
+ - **`slider`**: Horizontal scrolling carousel
98
+ - **`waterfall`**: Pinterest-style masonry layout
99
+
100
+ ## Pure Layout System
101
+
102
+ The gallery is a pure layout system that works with any data type. All content rendering is handled by the `itemRenderer` function, which receives the full original item and can access any fields it needs.
103
+
104
+ **Important**: The `itemRenderer` prop is effectively required. Without it, the gallery will render empty items. In development mode, a warning will be shown if no `itemRenderer` is provided.
105
+
106
+ ## API
107
+
108
+ ### GalleryWrapper Props
109
+
110
+ | Prop | Type | Default | Description |
111
+ | --------------- | --------------------------------------- | -------- | ------------------------------------------- |
112
+ | `items` | `T[]` | `[]` | Array of items to display |
113
+ | `variant` | `LayoutType` | `"grid"` | Layout variant |
114
+ | `itemRenderer` | `(item: T, index: number) => ReactNode` | - | Custom item renderer (effectively required) |
115
+ | `emptyState` | `ReactNode` | - | Content to show when no items |
116
+ | `className` | `string` | - | Additional CSS classes |
117
+ | `...otherProps` | `HTMLAttributes<HTMLDivElement>` | - | All other standard div attributes |
118
+
119
+ ### LayoutType
120
+
121
+ ```tsx
122
+ type LayoutType = 'grid' | 'alternating' | 'slider' | 'waterfall';
123
+ ```
124
+
125
+ ## CSS Classes
126
+
127
+ The gallery applies the following CSS classes:
128
+
129
+ - **Wrapper**: `w-full gallery-layout gallery-{variant}`
130
+ - **Data attribute**: `data-gallery-variant="{variant}"`
131
+
132
+ ## Dependencies
133
+
134
+ - `@wix/fast-gallery-core`: Core gallery rendering engine
135
+ - `clsx`: Class name utility
136
+ - `class-variance-authority`: Variant management
137
+ - `react`: ^18.3.1
138
+ - `react-dom`: ^18.3.1
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ exports.__esModule = true;
5
+ exports.GalleryWrapper = void 0;
6
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _fastGalleryCore = require("@wix/fast-gallery-core");
9
+ var _clsx = require("clsx");
10
+ var _variants = require("./variants.js");
11
+ require("./gallery.css");
12
+ var _jsxFileName = "/Users/arielh/Git/showcase/packages/fast-gallery-packages/fast-gallery-vibe/dist/cjs/components/GalleryWrapper.tsx";
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ const GalleryWrapper = exports.GalleryWrapper = /*#__PURE__*/React.forwardRef((props, ref) => {
15
+ const {
16
+ items = [],
17
+ variant = 'grid',
18
+ className,
19
+ itemRenderer,
20
+ emptyState,
21
+ children,
22
+ ...otherProps
23
+ } = props;
24
+ const hasItems = items.length > 0;
25
+
26
+ // Convert items to gallery format
27
+ const convertItemToGalleryItem = React.useCallback((item, index) => {
28
+ return {
29
+ id: item.id || item._id || `item-${index}`,
30
+ index: index.toString(),
31
+ mediaUrl: '',
32
+ type: _fastGalleryCore.MediaTypes.IMAGE,
33
+ metaData: {
34
+ width: 1,
35
+ // Minimal value for fast-gallery-core layout calculations
36
+ height: 1,
37
+ // Minimal value for fast-gallery-core layout calculations
38
+ title: '',
39
+ description: '',
40
+ alt: '',
41
+ link: {
42
+ url: '',
43
+ target: '_self'
44
+ }
45
+ }
46
+ };
47
+ }, []);
48
+ const galleryItems = React.useMemo(() => items.map((item, index) => convertItemToGalleryItem(item, index)), [items, convertItemToGalleryItem]);
49
+
50
+ // Create custom item renderer component
51
+ const ItemRendererComponent = React.useMemo(() => {
52
+ const Component = itemProps => {
53
+ if (itemRenderer) {
54
+ const originalItem = items[parseInt(itemProps.data.index, 10)];
55
+ if (originalItem) {
56
+ const rendered = itemRenderer(originalItem, parseInt(itemProps.data.index, 10));
57
+ return /*#__PURE__*/React.createElement(React.Fragment, null, rendered);
58
+ }
59
+ }
60
+
61
+ // Development warning if no itemRenderer is provided
62
+ if (process.env.NODE_ENV === 'development' && !itemRenderer) {
63
+ console.warn('GalleryWrapper: No itemRenderer provided. Gallery will render empty items. ' + 'Please provide an itemRenderer prop to render your content.');
64
+ }
65
+ return null;
66
+ };
67
+ return Component;
68
+ }, [itemRenderer, items]);
69
+ const customRenderers = React.useMemo(() => ({
70
+ itemRenderer: ItemRendererComponent
71
+ }), [ItemRendererComponent]);
72
+ const finalClassName = (0, _clsx.clsx)((0, _variants.galleryVariants)({
73
+ variant
74
+ }), className);
75
+
76
+ // Show empty state if no items
77
+ if (!hasItems) {
78
+ return emptyState || null;
79
+ }
80
+ return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({
81
+ ref: ref,
82
+ className: finalClassName,
83
+ "data-gallery-variant": variant
84
+ }, otherProps, {
85
+ __self: void 0,
86
+ __source: {
87
+ fileName: _jsxFileName,
88
+ lineNumber: 98,
89
+ columnNumber: 5
90
+ }
91
+ }), /*#__PURE__*/React.createElement(_fastGalleryCore.Gallery, {
92
+ dataList: galleryItems,
93
+ customRenderers: customRenderers,
94
+ options: {},
95
+ __self: void 0,
96
+ __source: {
97
+ fileName: _jsxFileName,
98
+ lineNumber: 104,
99
+ columnNumber: 7
100
+ }
101
+ }), children);
102
+ });
103
+ GalleryWrapper.displayName = 'GalleryWrapper';
104
+ //# sourceMappingURL=GalleryWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","_interopRequireWildcard","require","_fastGalleryCore","_clsx","_variants","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","GalleryWrapper","exports","forwardRef","props","ref","items","variant","className","itemRenderer","emptyState","children","otherProps","hasItems","length","convertItemToGalleryItem","useCallback","item","index","id","_id","toString","mediaUrl","type","MediaTypes","IMAGE","metaData","width","height","title","description","alt","link","url","target","galleryItems","useMemo","map","ItemRendererComponent","Component","itemProps","originalItem","parseInt","data","rendered","createElement","Fragment","process","env","NODE_ENV","console","warn","customRenderers","finalClassName","clsx","galleryVariants","_extends2","__self","__source","fileName","lineNumber","columnNumber","Gallery","dataList","options","displayName"],"sources":["../../../src/components/GalleryWrapper.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n Gallery,\n MediaTypes,\n ItemContentData,\n BaseMetaDataType,\n} from '@wix/fast-gallery-core';\nimport { clsx } from 'clsx';\nimport { galleryVariants } from './variants.js';\nimport type { GalleryWrapperProps, BaseItem } from './types.js';\nimport type { ItemRendererProps } from '@wix/fast-gallery-core';\nimport './gallery.css';\n\nexport const GalleryWrapper = React.forwardRef<\n HTMLDivElement,\n GalleryWrapperProps<BaseItem>\n>((props, ref) => {\n const {\n items = [],\n variant = 'grid',\n className,\n itemRenderer,\n emptyState,\n children,\n ...otherProps\n } = props;\n\n const hasItems = items.length > 0;\n\n // Convert items to gallery format\n const convertItemToGalleryItem = React.useCallback(\n (item: BaseItem, index: number): ItemContentData<BaseMetaDataType> => {\n return {\n id: item.id || item._id || `item-${index}`,\n index: index.toString(),\n mediaUrl: '',\n type: MediaTypes.IMAGE,\n metaData: {\n width: 1, // Minimal value for fast-gallery-core layout calculations\n height: 1, // Minimal value for fast-gallery-core layout calculations\n title: '',\n description: '',\n alt: '',\n link: { url: '', target: '_self' },\n },\n };\n },\n []\n );\n\n const galleryItems = React.useMemo(\n () => items.map((item, index) => convertItemToGalleryItem(item, index)),\n [items, convertItemToGalleryItem]\n );\n\n // Create custom item renderer component\n const ItemRendererComponent = React.useMemo(() => {\n const Component: React.FC<ItemRendererProps> = (itemProps) => {\n if (itemRenderer) {\n const originalItem = items[parseInt(itemProps.data.index, 10)];\n if (originalItem) {\n const rendered = itemRenderer(\n originalItem,\n parseInt(itemProps.data.index, 10)\n );\n return <>{rendered}</>;\n }\n }\n\n // Development warning if no itemRenderer is provided\n if (process.env.NODE_ENV === 'development' && !itemRenderer) {\n console.warn(\n 'GalleryWrapper: No itemRenderer provided. Gallery will render empty items. ' +\n 'Please provide an itemRenderer prop to render your content.'\n );\n }\n\n return null;\n };\n return Component;\n }, [itemRenderer, items]);\n\n const customRenderers = React.useMemo(\n () => ({\n itemRenderer: ItemRendererComponent,\n }),\n [ItemRendererComponent]\n );\n\n const finalClassName = clsx(galleryVariants({ variant }), className);\n\n // Show empty state if no items\n if (!hasItems) {\n return (emptyState as React.ReactElement) || null;\n }\n\n return (\n <div\n ref={ref}\n className={finalClassName}\n data-gallery-variant={variant}\n {...otherProps}\n >\n <Gallery\n dataList={galleryItems}\n customRenderers={customRenderers}\n options={{}}\n />\n {children}\n </div>\n );\n});\n\nGalleryWrapper.displayName = 'GalleryWrapper';\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.MEDIA_TYPES = exports.GALLERY_CONSTANTS = void 0;
5
+ const GALLERY_CONSTANTS = exports.GALLERY_CONSTANTS = {
6
+ SLIDER_ITEM_WIDTH: 280,
7
+ SLIDER_ITEM_WIDTH_MOBILE: 240,
8
+ BREAKPOINT_MOBILE: 640
9
+ };
10
+ const MEDIA_TYPES = exports.MEDIA_TYPES = {
11
+ IMAGE: 'image',
12
+ VIDEO: 'video'
13
+ };
14
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GALLERY_CONSTANTS","exports","SLIDER_ITEM_WIDTH","SLIDER_ITEM_WIDTH_MOBILE","BREAKPOINT_MOBILE","MEDIA_TYPES","IMAGE","VIDEO"],"sources":["../../../src/components/constants.ts"],"sourcesContent":["export const GALLERY_CONSTANTS = {\n SLIDER_ITEM_WIDTH: 280,\n SLIDER_ITEM_WIDTH_MOBILE: 240,\n BREAKPOINT_MOBILE: 640,\n} as const;\n\nexport const MEDIA_TYPES = {\n IMAGE: 'image',\n VIDEO: 'video',\n} as const;\n"],"mappings":";;;;AAAO,MAAMA,iBAAiB,GAAAC,OAAA,CAAAD,iBAAA,GAAG;EAC/BE,iBAAiB,EAAE,GAAG;EACtBC,wBAAwB,EAAE,GAAG;EAC7BC,iBAAiB,EAAE;AACrB,CAAU;AAEH,MAAMC,WAAW,GAAAJ,OAAA,CAAAI,WAAA,GAAG;EACzBC,KAAK,EAAE,OAAO;EACdC,KAAK,EAAE;AACT,CAAU","ignoreList":[]}
@@ -0,0 +1,77 @@
1
+ /* ShadCN Gallery Layouts - Static CSS */
2
+
3
+ /*
4
+ * IMPORTANT: This CSS relies on the DOM structure created by @wix/fast-gallery-core
5
+ * The gallery creates: .scroller > .container > .item elements
6
+ * Do not modify these class names as they are part of the fast-gallery-core API
7
+ */
8
+
9
+ /* Gallery Base Styles */
10
+ .gallery-layout {
11
+ width: 100%;
12
+ }
13
+
14
+ /* Grid Layout - 3 columns */
15
+ .gallery-layout.gallery-grid .scroller .container {
16
+ display: grid;
17
+ grid-template-columns: repeat(3, 1fr);
18
+ gap: 1rem;
19
+ }
20
+
21
+ /* Alternating Layout - 3-2-3-2 pattern */
22
+ .gallery-layout.gallery-alternating .scroller .container {
23
+ display: grid;
24
+ grid-template-columns: repeat(6, 1fr);
25
+ gap: 1rem;
26
+ }
27
+
28
+ /* Odd rows (1, 3, 5, ...): 3 items per row */
29
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+1),
30
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+2),
31
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+3) {
32
+ grid-column: span 2;
33
+ }
34
+
35
+ /* Even rows (2, 4, 6, ...): 2 items per row */
36
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+4),
37
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+5) {
38
+ grid-column: span 3;
39
+ }
40
+
41
+ /* Slider Layout - Horizontal scrolling */
42
+ .gallery-layout.gallery-slider .scroller .container {
43
+ display: flex;
44
+ flex-direction: row;
45
+ gap: 1rem;
46
+ overflow-x: auto;
47
+ scroll-snap-type: x mandatory;
48
+ padding-bottom: 0.5rem;
49
+ }
50
+
51
+ .gallery-layout.gallery-slider .scroller .container > .item {
52
+ flex-shrink: 0;
53
+ scroll-snap-align: start;
54
+ width: 280px;
55
+ max-width: 280px;
56
+ min-width: 280px;
57
+ }
58
+
59
+ /* Slider responsive sizing */
60
+ @media (max-width: 640px) {
61
+ .gallery-layout.gallery-slider .scroller .container > .item {
62
+ width: 240px;
63
+ max-width: 240px;
64
+ min-width: 240px;
65
+ }
66
+ }
67
+
68
+ /* Waterfall Layout - Masonry columns */
69
+ .gallery-layout.gallery-waterfall .scroller .container {
70
+ columns: 3;
71
+ column-gap: 1rem;
72
+ }
73
+
74
+ .gallery-layout.gallery-waterfall .scroller .container > .item {
75
+ break-inside: avoid;
76
+ margin-bottom: 1rem;
77
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.galleryVariants = exports.MEDIA_TYPES = exports.GalleryWrapper = exports.GALLERY_CONSTANTS = void 0;
5
+ var _GalleryWrapper = require("./GalleryWrapper.js");
6
+ exports.GalleryWrapper = _GalleryWrapper.GalleryWrapper;
7
+ var _constants = require("./constants.js");
8
+ exports.GALLERY_CONSTANTS = _constants.GALLERY_CONSTANTS;
9
+ exports.MEDIA_TYPES = _constants.MEDIA_TYPES;
10
+ var _variants = require("./variants.js");
11
+ exports.galleryVariants = _variants.galleryVariants;
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_GalleryWrapper","require","exports","GalleryWrapper","_constants","GALLERY_CONSTANTS","MEDIA_TYPES","_variants","galleryVariants"],"sources":["../../../src/components/index.ts"],"sourcesContent":["export { GalleryWrapper } from './GalleryWrapper.js';\n\nexport type { LayoutType, BaseItem, GalleryWrapperProps } from './types.js';\n\nexport { GALLERY_CONSTANTS, MEDIA_TYPES } from './constants.js';\n\nexport { galleryVariants } from './variants.js';\nexport type { GalleryVariant } from './variants.js';\n"],"mappings":";;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAAqDC,OAAA,CAAAC,cAAA,GAAAH,eAAA,CAAAG,cAAA;AAIrD,IAAAC,UAAA,GAAAH,OAAA;AAAgEC,OAAA,CAAAG,iBAAA,GAAAD,UAAA,CAAAC,iBAAA;AAAAH,OAAA,CAAAI,WAAA,GAAAF,UAAA,CAAAE,WAAA;AAEhE,IAAAC,SAAA,GAAAN,OAAA;AAAgDC,OAAA,CAAAM,eAAA,GAAAD,SAAA,CAAAC,eAAA","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["../../../src/components/types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type LayoutType = 'grid' | 'alternating' | 'slider' | 'waterfall';\n\nexport interface BaseItem {\n id?: string;\n _id?: string;\n width?: number;\n height?: number;\n}\n\nexport interface GalleryWrapperProps<T extends BaseItem = BaseItem>\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n items: T[];\n variant?: LayoutType;\n className?: string;\n itemRenderer?: (item: T, index: number) => React.ReactNode;\n emptyState?: React.ReactNode;\n children?: React.ReactNode;\n}\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.galleryVariants = void 0;
5
+ var _classVarianceAuthority = require("class-variance-authority");
6
+ const galleryVariants = exports.galleryVariants = (0, _classVarianceAuthority.cva)('w-full gallery-layout', {
7
+ variants: {
8
+ variant: {
9
+ grid: 'gallery-grid',
10
+ alternating: 'gallery-alternating',
11
+ slider: 'gallery-slider',
12
+ waterfall: 'gallery-waterfall'
13
+ }
14
+ },
15
+ defaultVariants: {
16
+ variant: 'grid'
17
+ }
18
+ });
19
+ //# sourceMappingURL=variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_classVarianceAuthority","require","galleryVariants","exports","cva","variants","variant","grid","alternating","slider","waterfall","defaultVariants"],"sources":["../../../src/components/variants.ts"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\n\nexport const galleryVariants = cva(\n 'w-full gallery-layout',\n {\n variants: {\n variant: {\n grid: 'gallery-grid',\n alternating: 'gallery-alternating',\n slider: 'gallery-slider',\n waterfall: 'gallery-waterfall',\n },\n },\n defaultVariants: {\n variant: 'grid',\n },\n },\n);\n\nexport type GalleryVariant = VariantProps<typeof galleryVariants>;\n"],"mappings":";;;;AAAA,IAAAA,uBAAA,GAAAC,OAAA;AAEO,MAAMC,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAG,IAAAE,2BAAG,EAChC,uBAAuB,EACvB;EACEC,QAAQ,EAAE;IACRC,OAAO,EAAE;MACPC,IAAI,EAAE,cAAc;MACpBC,WAAW,EAAE,qBAAqB;MAClCC,MAAM,EAAE,gBAAgB;MACxBC,SAAS,EAAE;IACb;EACF,CAAC;EACDC,eAAe,EAAE;IACfL,OAAO,EAAE;EACX;AACF,CACF,CAAC","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ var _index = require("./components/index.js");
5
+ Object.keys(_index).forEach(function (key) {
6
+ if (key === "default" || key === "__esModule") return;
7
+ if (key in exports && exports[key] === _index[key]) return;
8
+ exports[key] = _index[key];
9
+ });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_index","require","Object","keys","forEach","key","exports"],"sources":["../../src/index.ts"],"sourcesContent":["// Export all components\nexport * from './components/index.js';\n"],"mappings":";;;AACA,IAAAA,MAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,MAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,MAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,MAAA,CAAAK,GAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,77 @@
1
+ /* ShadCN Gallery Layouts - Static CSS */
2
+
3
+ /*
4
+ * IMPORTANT: This CSS relies on the DOM structure created by @wix/fast-gallery-core
5
+ * The gallery creates: .scroller > .container > .item elements
6
+ * Do not modify these class names as they are part of the fast-gallery-core API
7
+ */
8
+
9
+ /* Gallery Base Styles */
10
+ .gallery-layout {
11
+ width: 100%;
12
+ }
13
+
14
+ /* Grid Layout - 3 columns */
15
+ .gallery-layout.gallery-grid .scroller .container {
16
+ display: grid;
17
+ grid-template-columns: repeat(3, 1fr);
18
+ gap: 1rem;
19
+ }
20
+
21
+ /* Alternating Layout - 3-2-3-2 pattern */
22
+ .gallery-layout.gallery-alternating .scroller .container {
23
+ display: grid;
24
+ grid-template-columns: repeat(6, 1fr);
25
+ gap: 1rem;
26
+ }
27
+
28
+ /* Odd rows (1, 3, 5, ...): 3 items per row */
29
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+1),
30
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+2),
31
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+3) {
32
+ grid-column: span 2;
33
+ }
34
+
35
+ /* Even rows (2, 4, 6, ...): 2 items per row */
36
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+4),
37
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+5) {
38
+ grid-column: span 3;
39
+ }
40
+
41
+ /* Slider Layout - Horizontal scrolling */
42
+ .gallery-layout.gallery-slider .scroller .container {
43
+ display: flex;
44
+ flex-direction: row;
45
+ gap: 1rem;
46
+ overflow-x: auto;
47
+ scroll-snap-type: x mandatory;
48
+ padding-bottom: 0.5rem;
49
+ }
50
+
51
+ .gallery-layout.gallery-slider .scroller .container > .item {
52
+ flex-shrink: 0;
53
+ scroll-snap-align: start;
54
+ width: 280px;
55
+ max-width: 280px;
56
+ min-width: 280px;
57
+ }
58
+
59
+ /* Slider responsive sizing */
60
+ @media (max-width: 640px) {
61
+ .gallery-layout.gallery-slider .scroller .container > .item {
62
+ width: 240px;
63
+ max-width: 240px;
64
+ min-width: 240px;
65
+ }
66
+ }
67
+
68
+ /* Waterfall Layout - Masonry columns */
69
+ .gallery-layout.gallery-waterfall .scroller .container {
70
+ columns: 3;
71
+ column-gap: 1rem;
72
+ }
73
+
74
+ .gallery-layout.gallery-waterfall .scroller .container > .item {
75
+ break-inside: avoid;
76
+ margin-bottom: 1rem;
77
+ }
@@ -0,0 +1,59 @@
1
+ import * as React from 'react';
2
+ import { Gallery, MediaTypes, } from '@wix/fast-gallery-core';
3
+ import { clsx } from 'clsx';
4
+ import { galleryVariants } from './variants.js';
5
+ import './gallery.css';
6
+ export const GalleryWrapper = React.forwardRef((props, ref) => {
7
+ const { items = [], variant = 'grid', className, itemRenderer, emptyState, children, ...otherProps } = props;
8
+ const hasItems = items.length > 0;
9
+ // Convert items to gallery format
10
+ const convertItemToGalleryItem = React.useCallback((item, index) => {
11
+ return {
12
+ id: item.id || item._id || `item-${index}`,
13
+ index: index.toString(),
14
+ mediaUrl: '',
15
+ type: MediaTypes.IMAGE,
16
+ metaData: {
17
+ width: 1,
18
+ height: 1,
19
+ title: '',
20
+ description: '',
21
+ alt: '',
22
+ link: { url: '', target: '_self' },
23
+ },
24
+ };
25
+ }, []);
26
+ const galleryItems = React.useMemo(() => items.map((item, index) => convertItemToGalleryItem(item, index)), [items, convertItemToGalleryItem]);
27
+ // Create custom item renderer component
28
+ const ItemRendererComponent = React.useMemo(() => {
29
+ const Component = (itemProps) => {
30
+ if (itemRenderer) {
31
+ const originalItem = items[parseInt(itemProps.data.index, 10)];
32
+ if (originalItem) {
33
+ const rendered = itemRenderer(originalItem, parseInt(itemProps.data.index, 10));
34
+ return React.createElement(React.Fragment, null, rendered);
35
+ }
36
+ }
37
+ // Development warning if no itemRenderer is provided
38
+ if (process.env.NODE_ENV === 'development' && !itemRenderer) {
39
+ console.warn('GalleryWrapper: No itemRenderer provided. Gallery will render empty items. ' +
40
+ 'Please provide an itemRenderer prop to render your content.');
41
+ }
42
+ return null;
43
+ };
44
+ return Component;
45
+ }, [itemRenderer, items]);
46
+ const customRenderers = React.useMemo(() => ({
47
+ itemRenderer: ItemRendererComponent,
48
+ }), [ItemRendererComponent]);
49
+ const finalClassName = clsx(galleryVariants({ variant }), className);
50
+ // Show empty state if no items
51
+ if (!hasItems) {
52
+ return emptyState || null;
53
+ }
54
+ return (React.createElement("div", { ref: ref, className: finalClassName, "data-gallery-variant": variant, ...otherProps },
55
+ React.createElement(Gallery, { dataList: galleryItems, customRenderers: customRenderers, options: {} }),
56
+ children));
57
+ });
58
+ GalleryWrapper.displayName = 'GalleryWrapper';
59
+ //# sourceMappingURL=GalleryWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GalleryWrapper.js","sourceRoot":"","sources":["../../../src/components/GalleryWrapper.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export const GALLERY_CONSTANTS = {
2
+ SLIDER_ITEM_WIDTH: 280,
3
+ SLIDER_ITEM_WIDTH_MOBILE: 240,
4
+ BREAKPOINT_MOBILE: 640,
5
+ };
6
+ export const MEDIA_TYPES = {
7
+ IMAGE: 'image',
8
+ VIDEO: 'video',
9
+ };
10
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/components/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,iBAAiB,EAAE,GAAG;IACtB,wBAAwB,EAAE,GAAG;IAC7B,iBAAiB,EAAE,GAAG;CACd,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;CACN,CAAC"}
@@ -0,0 +1,77 @@
1
+ /* ShadCN Gallery Layouts - Static CSS */
2
+
3
+ /*
4
+ * IMPORTANT: This CSS relies on the DOM structure created by @wix/fast-gallery-core
5
+ * The gallery creates: .scroller > .container > .item elements
6
+ * Do not modify these class names as they are part of the fast-gallery-core API
7
+ */
8
+
9
+ /* Gallery Base Styles */
10
+ .gallery-layout {
11
+ width: 100%;
12
+ }
13
+
14
+ /* Grid Layout - 3 columns */
15
+ .gallery-layout.gallery-grid .scroller .container {
16
+ display: grid;
17
+ grid-template-columns: repeat(3, 1fr);
18
+ gap: 1rem;
19
+ }
20
+
21
+ /* Alternating Layout - 3-2-3-2 pattern */
22
+ .gallery-layout.gallery-alternating .scroller .container {
23
+ display: grid;
24
+ grid-template-columns: repeat(6, 1fr);
25
+ gap: 1rem;
26
+ }
27
+
28
+ /* Odd rows (1, 3, 5, ...): 3 items per row */
29
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+1),
30
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+2),
31
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+3) {
32
+ grid-column: span 2;
33
+ }
34
+
35
+ /* Even rows (2, 4, 6, ...): 2 items per row */
36
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+4),
37
+ .gallery-layout.gallery-alternating .scroller .container > .item:nth-child(5n+5) {
38
+ grid-column: span 3;
39
+ }
40
+
41
+ /* Slider Layout - Horizontal scrolling */
42
+ .gallery-layout.gallery-slider .scroller .container {
43
+ display: flex;
44
+ flex-direction: row;
45
+ gap: 1rem;
46
+ overflow-x: auto;
47
+ scroll-snap-type: x mandatory;
48
+ padding-bottom: 0.5rem;
49
+ }
50
+
51
+ .gallery-layout.gallery-slider .scroller .container > .item {
52
+ flex-shrink: 0;
53
+ scroll-snap-align: start;
54
+ width: 280px;
55
+ max-width: 280px;
56
+ min-width: 280px;
57
+ }
58
+
59
+ /* Slider responsive sizing */
60
+ @media (max-width: 640px) {
61
+ .gallery-layout.gallery-slider .scroller .container > .item {
62
+ width: 240px;
63
+ max-width: 240px;
64
+ min-width: 240px;
65
+ }
66
+ }
67
+
68
+ /* Waterfall Layout - Masonry columns */
69
+ .gallery-layout.gallery-waterfall .scroller .container {
70
+ columns: 3;
71
+ column-gap: 1rem;
72
+ }
73
+
74
+ .gallery-layout.gallery-waterfall .scroller .container > .item {
75
+ break-inside: avoid;
76
+ margin-bottom: 1rem;
77
+ }
@@ -0,0 +1,4 @@
1
+ export { GalleryWrapper } from './GalleryWrapper.js';
2
+ export { GALLERY_CONSTANTS, MEDIA_TYPES } from './constants.js';
3
+ export { galleryVariants } from './variants.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { cva } from 'class-variance-authority';
2
+ export const galleryVariants = cva('w-full gallery-layout', {
3
+ variants: {
4
+ variant: {
5
+ grid: 'gallery-grid',
6
+ alternating: 'gallery-alternating',
7
+ slider: 'gallery-slider',
8
+ waterfall: 'gallery-waterfall',
9
+ },
10
+ },
11
+ defaultVariants: {
12
+ variant: 'grid',
13
+ },
14
+ });
15
+ //# sourceMappingURL=variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variants.js","sourceRoot":"","sources":["../../../src/components/variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAElE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAChC,uBAAuB,EACvB;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,qBAAqB;YAClC,MAAM,EAAE,gBAAgB;YACxB,SAAS,EAAE,mBAAmB;SAC/B;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,MAAM;KAChB;CACF,CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Export all components
2
+ export * from './components/index.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import type { GalleryWrapperProps, BaseItem } from './types.js';
3
+ import './gallery.css';
4
+ export declare const GalleryWrapper: React.ForwardRefExoticComponent<GalleryWrapperProps<BaseItem> & React.RefAttributes<HTMLDivElement>>;
5
+ //# sourceMappingURL=GalleryWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GalleryWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/GalleryWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,eAAe,CAAC;AAEvB,eAAO,MAAM,cAAc,sGAkGzB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const GALLERY_CONSTANTS: {
2
+ readonly SLIDER_ITEM_WIDTH: 280;
3
+ readonly SLIDER_ITEM_WIDTH_MOBILE: 240;
4
+ readonly BREAKPOINT_MOBILE: 640;
5
+ };
6
+ export declare const MEDIA_TYPES: {
7
+ readonly IMAGE: "image";
8
+ readonly VIDEO: "video";
9
+ };
10
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/components/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX,eAAO,MAAM,WAAW;;;CAGd,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { GalleryWrapper } from './GalleryWrapper.js';
2
+ export type { LayoutType, BaseItem, GalleryWrapperProps } from './types.js';
3
+ export { GALLERY_CONSTANTS, MEDIA_TYPES } from './constants.js';
4
+ export { galleryVariants } from './variants.js';
5
+ export type { GalleryVariant } from './variants.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ export type LayoutType = 'grid' | 'alternating' | 'slider' | 'waterfall';
3
+ export interface BaseItem {
4
+ id?: string;
5
+ _id?: string;
6
+ width?: number;
7
+ height?: number;
8
+ }
9
+ export interface GalleryWrapperProps<T extends BaseItem = BaseItem> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
10
+ items: T[];
11
+ variant?: LayoutType;
12
+ className?: string;
13
+ itemRenderer?: (item: T, index: number) => React.ReactNode;
14
+ emptyState?: React.ReactNode;
15
+ children?: React.ReactNode;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEzE,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,CAChE,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC3D,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B"}
@@ -0,0 +1,6 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ export declare const galleryVariants: (props?: ({
3
+ variant?: "grid" | "alternating" | "slider" | "waterfall" | null | undefined;
4
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
5
+ export type GalleryVariant = VariantProps<typeof galleryVariants>;
6
+ //# sourceMappingURL=variants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variants.d.ts","sourceRoot":"","sources":["../../../src/components/variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,eAAe;;mFAe3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './components/index.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,uBAAuB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@wix/fast-gallery-vibe",
3
+ "version": "1.0.0",
4
+ "license": "UNLICENSED",
5
+ "author": {
6
+ "name": "gabrielab",
7
+ "email": "gabrielab@wix.com"
8
+ },
9
+ "main": "dist/cjs/index.js",
10
+ "module": "dist/esm/index.js",
11
+ "sideEffects": false,
12
+ "types": "dist/types/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/esm/index.js",
16
+ "require": "./dist/cjs/index.js",
17
+ "types": "./dist/types/index.d.ts"
18
+ },
19
+ "./components": {
20
+ "import": "./dist/esm/components/index.js",
21
+ "require": "./dist/cjs/components/index.js",
22
+ "types": "./dist/types/components/index.d.ts"
23
+ },
24
+ "./styles.css": "./dist/components/gallery.css"
25
+ },
26
+ "files": [
27
+ "dist/cjs",
28
+ "dist/esm",
29
+ "dist/types",
30
+ "dist/components/gallery.css"
31
+ ],
32
+ "scripts": {
33
+ "build": "yoshi-library build && npm run copy-css",
34
+ "copy-css": "mkdir -p dist/components && cp src/components/gallery.css dist/components/gallery.css",
35
+ "start": "yoshi-library start",
36
+ "test": "yoshi-library test",
37
+ "lint": "yoshi-library lint"
38
+ },
39
+ "lint-staged": {
40
+ "*.{js,ts}": "yarn lint"
41
+ },
42
+ "dependencies": {
43
+ "@babel/runtime": "^7.28.2",
44
+ "@wix/fast-gallery-core": "workspace:*",
45
+ "class-variance-authority": "^0.7.1",
46
+ "clsx": "^2.1.1"
47
+ },
48
+ "devDependencies": {
49
+ "@testing-library/react": "^14.3.1",
50
+ "@types/jest": "^27.5.2",
51
+ "@types/react": "^18.3.23",
52
+ "@types/react-dom": "^18.3.7",
53
+ "@wix/eslint-config-yoshi": "^6.156.0",
54
+ "@wix/jest-yoshi-preset": "^6.156.0",
55
+ "@wix/yoshi-flow-library": "^6.156.0",
56
+ "@wix/yoshi-style-dependencies": "^6.156.0",
57
+ "react": "^18.3.1",
58
+ "react-dom": "^18.3.1",
59
+ "ts-jest": "^27.1.5",
60
+ "typescript": "~4.7.0"
61
+ },
62
+ "peerDependencies": {
63
+ "react": "^18.3.1",
64
+ "react-dom": "^18.3.1"
65
+ },
66
+ "jest": {
67
+ "preset": "@wix/jest-yoshi-preset"
68
+ },
69
+ "yoshiFlowLibrary": {
70
+ "buildEsmWithBabel": false
71
+ },
72
+ "eslintConfig": {
73
+ "extends": "@wix/eslint-config-yoshi"
74
+ },
75
+ "wix": {
76
+ "artifact": {
77
+ "groupId": "com.wixpress",
78
+ "artifactId": "fast-gallery-vibe"
79
+ },
80
+ "validations": {
81
+ "postDependenciesBuild": [
82
+ "lint"
83
+ ],
84
+ "postBuild": [
85
+ "test"
86
+ ]
87
+ }
88
+ },
89
+ "wallaby": {
90
+ "autoDetect": true
91
+ },
92
+ "publishConfig": {
93
+ "registry": "https://registry.npmjs.org/",
94
+ "access": "public"
95
+ }
96
+ }