@wyxos/vibe 1.6.26 → 1.6.27

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/README.md CHANGED
@@ -1,254 +1,287 @@
1
- # VIBE — Vue Infinite Block Engine
2
-
3
- [![npm](https://img.shields.io/npm/v/@wyxos/vibe?color=%2300c58e&label=npm)](https://www.npmjs.com/package/@wyxos/vibe)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Demo](https://img.shields.io/badge/Demo-Live%20Preview-blue?logo=githubpages)](https://wyxos.github.io/vibe/)
6
-
7
- A high-performance, responsive masonry layout engine for Vue 3 with built-in infinite scrolling and virtualization.
8
-
9
- VIBE (Vue Infinite Block Engine) is designed for applications that need to display large datasets in a masonry grid without compromising performance. Unlike other masonry libraries, VIBE leverages virtualization to render only what is visible on the screen, ensuring smooth scrolling even with thousands of items.
10
-
11
- ![VIBE Demo](demo.webp)
12
-
13
- ---
14
-
15
- ## Features
16
-
17
- - **High Performance Virtualization**: Efficiently renders thousands of items by only mounting elements currently in the viewport.
18
- - **Responsive Masonry Layout**: Automatically adjusts column counts and layout based on screen width and breakpoints.
19
- - **Mobile Swipe Feed**: Automatically switches to a vertical swipe feed on mobile devices for optimal mobile UX.
20
- - **Infinite Scrolling**: Seamlessly loads more content as the user scrolls, with built-in support for async data fetching.
21
- - **Dynamic Updates**: Supports adding, removing, and reflowing items with smooth FLIP animations.
22
- - **Scroll Position Maintenance**: Keeps the user's scroll position stable when new items are loaded or the layout changes.
23
- - **Built-in Item Component**: Includes a production-ready `MasonryItem` with lazy loading, image/video support, error handling, and hover effects.
24
- - **Customizable Rendering**: Full control over item markup via scoped slots.
25
-
26
- ---
27
-
28
- ## Installation
29
-
30
- ```bash
31
- npm install @wyxos/vibe
32
- ```
33
-
34
- ---
35
-
36
- ## Usage
37
-
38
- ### Basic Usage (Default Item)
39
-
40
- By default, VIBE uses the built-in `MasonryItem` component, which handles image loading and provides a clean UI. On mobile devices (screen width < 768px by default), it automatically switches to a vertical swipe feed mode where users can swipe through items one at a time.
41
-
42
- ```vue
43
- <script setup>
44
- import { ref } from 'vue'
45
- import { Masonry } from '@wyxos/vibe'
46
-
47
- const items = ref([])
48
-
49
- // Layout configuration
50
- const layout = {
51
- gutterX: 12,
52
- gutterY: 12,
53
- sizes: { base: 1, sm: 2, md: 3, lg: 4 }
54
- }
55
-
56
- async function getNextPage(page) {
57
- const response = await fetch(`/api/items?page=${page}`)
58
- const data = await response.json()
59
- // Items must have a 'src' property for the default MasonryItem
60
- // Optional: include 'type' ('image' or 'video') and 'notFound' (boolean)
61
- return {
62
- items: data.items,
63
- nextPage: page + 1
64
- }
65
- }
66
- </script>
67
-
68
- <template>
69
- <Masonry
70
- v-model:items="items"
71
- :get-next-page="getNextPage"
72
- :layout="layout"
73
- layout-mode="auto"
74
- :mobile-breakpoint="768"
75
- />
76
- </template>
77
- ```
78
-
79
- ### Layout Modes
80
-
81
- VIBE supports three layout modes:
82
-
83
- - **`'auto'`** (default): Automatically switches between masonry grid (desktop) and swipe feed (mobile) based on screen width
84
- - **`'masonry'`**: Always use masonry grid layout regardless of screen size
85
- - **`'swipe'`**: Always use swipe feed layout regardless of screen size
86
-
87
- ```vue
88
- <!-- Force masonry layout on all devices -->
89
- <Masonry layout-mode="masonry" ... />
90
-
91
- <!-- Force swipe feed on all devices -->
92
- <Masonry layout-mode="swipe" ... />
93
-
94
- <!-- Custom breakpoint (use Tailwind breakpoint name) -->
95
- <Masonry layout-mode="auto" mobile-breakpoint="lg" ... />
96
-
97
- <!-- Custom breakpoint (use pixel value) -->
98
- <Masonry layout-mode="auto" :mobile-breakpoint="1024" ... />
99
- ```
100
-
101
- ### Custom Item Rendering
102
-
103
- You can fully customize the item rendering using the `#item` slot. You can also import and use `MasonryItem` inside the slot if you want to wrap it or extend it.
104
-
105
- ```vue
106
- <script setup>
107
- import { Masonry, MasonryItem } from '@wyxos/vibe'
108
- // ... setup code ...
109
- </script>
110
-
111
- <template>
112
- <Masonry
113
- v-model:items="items"
114
- :get-next-page="getNextPage"
115
- :layout="layout"
116
- >
117
- <template #item="{ item, remove }">
118
- <!-- Custom container -->
119
- <div class="custom-card">
120
- <!-- You can use the built-in item or your own -->
121
- <MasonryItem :item="item" :remove="remove">
122
- <!-- Optional: MasonryItem also has a default slot for overlays -->
123
- <div class="absolute bottom-0 p-2 text-white">
124
- {{ item.title }}
125
- </div>
126
- </MasonryItem>
127
- </div>
128
- </template>
129
- </Masonry>
130
- </template>
131
- ```
132
-
133
- ### Item Data Structure
134
-
135
- Items can include the following properties:
136
-
137
- ```javascript
138
- {
139
- id: 'unique-id', // Required: unique identifier
140
- width: 300, // Required: original width
141
- height: 200, // Required: original height
142
- src: 'https://...', // Required: media source URL
143
- type: 'image' | 'video', // Optional: media type (defaults to 'image')
144
- notFound: false, // Optional: show "Not Found" state
145
- // ... any other custom properties
146
- }
147
- ```
148
-
149
- ### Slot Props
150
-
151
- The `MasonryItem` component exposes the following props to its default slot:
152
-
153
- - `item`: The item object
154
- - `remove`: The remove callback function
155
- - `imageLoaded`: Boolean indicating if image has loaded
156
- - `imageError`: Boolean indicating if image failed to load
157
- - `videoLoaded`: Boolean indicating if video has loaded
158
- - `videoError`: Boolean indicating if video failed to load
159
- - `showNotFound`: Boolean indicating if item is in "not found" state
160
- - `isLoading`: Boolean indicating if media is currently loading
161
- - `mediaType`: String indicating the media type ('image' or 'video')
162
-
163
- ---
164
-
165
- ## Props
166
-
167
- | Prop | Type | Required | Description |
168
- |------|------|----------|-------------|
169
- | `items` | `Array` | Yes | Two-way bound item array. Each item must include `width`, `height`, and `id`. |
170
- | `getNextPage` | `Function(page: Number)` | Yes | Async function to load the next page. Must return `{ items, nextPage }`. |
171
- | `layout` | `Object` | No | Configuration object for layout, including sizes and gutters. |
172
- | `loadAtPage` | `Number` | No | The starting page number (default: `1`). |
173
- | `paginationType` | `String` | No | `'page'` or `'cursor'` (default: `'page'`). |
174
- | `pageSize` | `Number` | No | Number of items per page, used for backfilling (default: `40`). |
175
- | `layoutMode` | `String` | No | Layout mode: `'auto'` (detect from screen size), `'masonry'`, or `'swipe'` (default: `'auto'`). |
176
- | `mobileBreakpoint` | `Number \| String` | No | Breakpoint for switching to swipe mode in pixels or Tailwind breakpoint name (default: `768`). |
177
-
178
- ### Layout Configuration Example
179
-
180
- ```js
181
- {
182
- gutterX: 10,
183
- gutterY: 10,
184
- sizes: {
185
- base: 1,
186
- sm: 2,
187
- md: 3,
188
- lg: 4,
189
- xl: 5,
190
- '2xl': 6
191
- }
192
- }
193
- ```
194
-
195
- ---
196
-
197
- ## MasonryItem Component
198
-
199
- The built-in `MasonryItem` component is available for use within the `#item` slot or as a standalone component. It provides intelligent lazy loading, media type detection, and comprehensive error handling.
200
-
201
- ### Props
202
-
203
- | Prop | Type | Description |
204
- |------|------|-------------|
205
- | `item` | `Object` | The item object. Must contain `src` for media loading. Can include `type` (`'image'` or `'video'`), `notFound` (boolean), and other custom properties. |
206
- | `remove` | `Function` | Optional callback to remove the item. If provided, a remove button is shown on hover. |
207
- | `type` | `'image' \| 'video'` | Optional. Overrides `item.type`. Defaults to `'image'`. |
208
- | `notFound` | `Boolean` | Optional. Overrides `item.notFound`. When `true`, displays a "Not Found" state instead of loading media. |
209
-
210
- ### Features
211
-
212
- - **Lazy Loading with Intersection Observer**: Only starts preloading media when the item comes into view (50%+ visible), significantly improving initial page load performance.
213
- - **Image & Video Support**: Automatically handles both images and videos with appropriate loading strategies.
214
- - **Media Type Indicator**: Shows a badge icon (image/video) on hover to indicate the media type.
215
- - **Smart Spinner**: Displays a loading spinner underneath the media (not covering it) during preload.
216
- - **Error Handling**: Displays user-friendly error states if media fails to load.
217
- - **Not Found State**: Special visual state for items that cannot be located.
218
- - **Hover Effects**: Includes subtle zoom, overlay gradient, and smooth transitions.
219
- - **Performance Optimized**: Properly cleans up Intersection Observers to prevent memory leaks.
220
-
221
- ---
222
-
223
- ## Slots
224
-
225
- | Slot Name | Props | Description |
226
- |-----------|-------|-------------|
227
- | `item` | `{ item, remove }` | Scoped slot for custom rendering of each masonry block. |
228
-
229
- ---
230
-
231
- ## Run Locally
232
-
233
- To run the demo project locally:
234
-
235
- ```bash
236
- git clone https://github.com/wyxos/vibe
237
- cd vibe
238
- npm install
239
- npm run dev
240
- ```
241
-
242
- Visit `http://localhost:5173` to view the demo.
243
-
244
- ---
245
-
246
- ## Live Demo
247
-
248
- [View Live Demo on GitHub Pages](https://wyxos.github.io/vibe/)
249
-
250
- ---
251
-
252
- ## License
253
-
254
- MIT © [@wyxos](https://github.com/wyxos)
1
+ # VIBE — Vue Infinite Block Engine
2
+
3
+ [![npm](https://img.shields.io/npm/v/@wyxos/vibe?color=%2300c58e&label=npm)](https://www.npmjs.com/package/@wyxos/vibe)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Demo](https://img.shields.io/badge/Demo-Live%20Preview-blue?logo=githubpages)](https://wyxos.github.io/vibe/)
6
+
7
+ A high-performance, responsive masonry layout engine for Vue 3 with built-in infinite scrolling and virtualization.
8
+
9
+ VIBE (Vue Infinite Block Engine) is designed for applications that need to display large datasets in a masonry grid without compromising performance. Unlike other masonry libraries, VIBE leverages virtualization to render only what is visible on the screen, ensuring smooth scrolling even with thousands of items.
10
+
11
+ ![VIBE Demo](demo.webp)
12
+
13
+ ---
14
+
15
+ ## Features
16
+
17
+ - **High Performance Virtualization**: Efficiently renders thousands of items by only mounting elements currently in the viewport.
18
+ - **Responsive Masonry Layout**: Automatically adjusts column counts and layout based on screen width and breakpoints.
19
+ - **Mobile Swipe Feed**: Automatically switches to a vertical swipe feed on mobile devices for optimal mobile UX.
20
+ - **Infinite Scrolling**: Seamlessly loads more content as the user scrolls, with built-in support for async data fetching.
21
+ - **Dynamic Updates**: Supports adding, removing, and reflowing items with smooth FLIP animations.
22
+ - **Scroll Position Maintenance**: Keeps the user's scroll position stable when new items are loaded or the layout changes.
23
+ - **Built-in Item Component**: Includes a production-ready `MasonryItem` with lazy loading, image/video support, error handling, and hover effects.
24
+ - **Customizable Rendering**: Full control over item markup via scoped slots.
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install @wyxos/vibe
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Usage
37
+
38
+ ### Basic Usage (Default Item)
39
+
40
+ By default, VIBE uses the built-in `MasonryItem` component, which handles image loading and provides a clean UI. On mobile devices (screen width < 768px by default), it automatically switches to a vertical swipe feed mode where users can swipe through items one at a time.
41
+
42
+ ```vue
43
+ <script setup>
44
+ import { ref } from 'vue'
45
+ import { Masonry } from '@wyxos/vibe'
46
+
47
+ const items = ref([])
48
+
49
+ // Layout configuration
50
+ const layout = {
51
+ gutterX: 12,
52
+ gutterY: 12,
53
+ sizes: { base: 1, sm: 2, md: 3, lg: 4 }
54
+ }
55
+
56
+ async function getPage(page) {
57
+ const response = await fetch(`/api/items?page=${page}`)
58
+ const data = await response.json()
59
+ // Items must have a 'src' property for the default MasonryItem
60
+ // Optional: include 'type' ('image' or 'video') and 'notFound' (boolean)
61
+ return {
62
+ items: data.items,
63
+ nextPage: page + 1
64
+ }
65
+ }
66
+ </script>
67
+
68
+ <template>
69
+ <Masonry
70
+ v-model:items="items"
71
+ :get-page="getPage"
72
+ :layout="layout"
73
+ layout-mode="auto"
74
+ :mobile-breakpoint="768"
75
+ />
76
+ </template>
77
+ ```
78
+
79
+ ### Initialization Modes
80
+
81
+ VIBE supports two initialization modes:
82
+
83
+ - **`'auto'`**: Automatically calls `loadPage` on mount to fetch the first page. Use this when you want the component to start loading immediately.
84
+ - **`'manual'`**: Does nothing on mount. You must manually call `initialize()` to initialize the component with items. Use this when you need to restore items from saved state or have more control over when loading begins.
85
+
86
+ ```vue
87
+ <!-- Auto mode: loads first page automatically -->
88
+ <Masonry
89
+ v-model:items="items"
90
+ :get-page="getPage"
91
+ init="auto"
92
+ :load-at-page="1"
93
+ />
94
+
95
+ <!-- Manual mode: you control when to initialize -->
96
+ <Masonry
97
+ ref="masonry"
98
+ v-model:items="items"
99
+ :get-page="getPage"
100
+ init="manual"
101
+ />
102
+ <script setup>
103
+ const masonry = ref(null)
104
+
105
+ // Later, initialize manually
106
+ masonry.value.items = []
107
+ masonry.value.initialize(savedItems, savedPage, savedNextPage)
108
+ </script>
109
+ ```
110
+
111
+ ### Layout Modes
112
+
113
+ VIBE supports three layout modes:
114
+
115
+ - **`'auto'`** (default): Automatically switches between masonry grid (desktop) and swipe feed (mobile) based on screen width
116
+ - **`'masonry'`**: Always use masonry grid layout regardless of screen size
117
+ - **`'swipe'`**: Always use swipe feed layout regardless of screen size
118
+
119
+ ```vue
120
+ <!-- Force masonry layout on all devices -->
121
+ <Masonry layout-mode="masonry" ... />
122
+
123
+ <!-- Force swipe feed on all devices -->
124
+ <Masonry layout-mode="swipe" ... />
125
+
126
+ <!-- Custom breakpoint (use Tailwind breakpoint name) -->
127
+ <Masonry layout-mode="auto" mobile-breakpoint="lg" ... />
128
+
129
+ <!-- Custom breakpoint (use pixel value) -->
130
+ <Masonry layout-mode="auto" :mobile-breakpoint="1024" ... />
131
+ ```
132
+
133
+ ### Custom Item Rendering
134
+
135
+ You can fully customize the item rendering using the `#item` slot. You can also import and use `MasonryItem` inside the slot if you want to wrap it or extend it.
136
+
137
+ ```vue
138
+ <script setup>
139
+ import { Masonry, MasonryItem } from '@wyxos/vibe'
140
+ // ... setup code ...
141
+ </script>
142
+
143
+ <template>
144
+ <Masonry
145
+ v-model:items="items"
146
+ :get-page="getPage"
147
+ :layout="layout"
148
+ >
149
+ <template #item="{ item, remove }">
150
+ <!-- Custom container -->
151
+ <div class="custom-card">
152
+ <!-- You can use the built-in item or your own -->
153
+ <MasonryItem :item="item" :remove="remove">
154
+ <!-- Optional: MasonryItem also has a default slot for overlays -->
155
+ <div class="absolute bottom-0 p-2 text-white">
156
+ {{ item.title }}
157
+ </div>
158
+ </MasonryItem>
159
+ </div>
160
+ </template>
161
+ </Masonry>
162
+ </template>
163
+ ```
164
+
165
+ ### Item Data Structure
166
+
167
+ Items can include the following properties:
168
+
169
+ ```javascript
170
+ {
171
+ id: 'unique-id', // Required: unique identifier
172
+ width: 300, // Required: original width
173
+ height: 200, // Required: original height
174
+ src: 'https://...', // Required: media source URL
175
+ type: 'image' | 'video', // Optional: media type (defaults to 'image')
176
+ notFound: false, // Optional: show "Not Found" state
177
+ // ... any other custom properties
178
+ }
179
+ ```
180
+
181
+ ### Slot Props
182
+
183
+ The `MasonryItem` component exposes the following props to its default slot:
184
+
185
+ - `item`: The item object
186
+ - `remove`: The remove callback function
187
+ - `imageLoaded`: Boolean indicating if image has loaded
188
+ - `imageError`: Boolean indicating if image failed to load
189
+ - `videoLoaded`: Boolean indicating if video has loaded
190
+ - `videoError`: Boolean indicating if video failed to load
191
+ - `showNotFound`: Boolean indicating if item is in "not found" state
192
+ - `isLoading`: Boolean indicating if media is currently loading
193
+ - `mediaType`: String indicating the media type ('image' or 'video')
194
+
195
+ ---
196
+
197
+ ## Props
198
+
199
+ | Prop | Type | Required | Description |
200
+ |------|------|----------|-------------|
201
+ | `items` | `Array` | Yes | Two-way bound item array. Each item must include `width`, `height`, and `id`. |
202
+ | `getPage` | `Function(page: Number)` | Yes | Async function to load a page. Must return `{ items, nextPage }`. |
203
+ | `layout` | `Object` | No | Configuration object for layout, including sizes and gutters. |
204
+ | `loadAtPage` | `Number` | No | The starting page number (default: `1`). |
205
+ | `init` | `String` | No | Initialization mode: `'auto'` (automatically loads first page on mount) or `'manual'` (user must call `initialize()` manually) (default: `'manual'`). |
206
+ | `paginationType` | `String` | No | `'page'` or `'cursor'` (default: `'page'`). |
207
+ | `pageSize` | `Number` | No | Number of items per page, used for backfilling (default: `40`). |
208
+ | `layoutMode` | `String` | No | Layout mode: `'auto'` (detect from screen size), `'masonry'`, or `'swipe'` (default: `'auto'`). |
209
+ | `mobileBreakpoint` | `Number \| String` | No | Breakpoint for switching to swipe mode in pixels or Tailwind breakpoint name (default: `768`). |
210
+
211
+ ### Layout Configuration Example
212
+
213
+ ```js
214
+ {
215
+ gutterX: 10,
216
+ gutterY: 10,
217
+ sizes: {
218
+ base: 1,
219
+ sm: 2,
220
+ md: 3,
221
+ lg: 4,
222
+ xl: 5,
223
+ '2xl': 6
224
+ }
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## MasonryItem Component
231
+
232
+ The built-in `MasonryItem` component is available for use within the `#item` slot or as a standalone component. It provides intelligent lazy loading, media type detection, and comprehensive error handling.
233
+
234
+ ### Props
235
+
236
+ | Prop | Type | Description |
237
+ |------|------|-------------|
238
+ | `item` | `Object` | The item object. Must contain `src` for media loading. Can include `type` (`'image'` or `'video'`), `notFound` (boolean), and other custom properties. |
239
+ | `remove` | `Function` | Optional callback to remove the item. If provided, a remove button is shown on hover. |
240
+ | `type` | `'image' \| 'video'` | Optional. Overrides `item.type`. Defaults to `'image'`. |
241
+ | `notFound` | `Boolean` | Optional. Overrides `item.notFound`. When `true`, displays a "Not Found" state instead of loading media. |
242
+
243
+ ### Features
244
+
245
+ - **Lazy Loading with Intersection Observer**: Only starts preloading media when the item comes into view (50%+ visible), significantly improving initial page load performance.
246
+ - **Image & Video Support**: Automatically handles both images and videos with appropriate loading strategies.
247
+ - **Media Type Indicator**: Shows a badge icon (image/video) on hover to indicate the media type.
248
+ - **Smart Spinner**: Displays a loading spinner underneath the media (not covering it) during preload.
249
+ - **Error Handling**: Displays user-friendly error states if media fails to load.
250
+ - **Not Found State**: Special visual state for items that cannot be located.
251
+ - **Hover Effects**: Includes subtle zoom, overlay gradient, and smooth transitions.
252
+ - **Performance Optimized**: Properly cleans up Intersection Observers to prevent memory leaks.
253
+
254
+ ---
255
+
256
+ ## Slots
257
+
258
+ | Slot Name | Props | Description |
259
+ |-----------|-------|-------------|
260
+ | `item` | `{ item, remove }` | Scoped slot for custom rendering of each masonry block. |
261
+
262
+ ---
263
+
264
+ ## Run Locally
265
+
266
+ To run the demo project locally:
267
+
268
+ ```bash
269
+ git clone https://github.com/wyxos/vibe
270
+ cd vibe
271
+ npm install
272
+ npm run dev
273
+ ```
274
+
275
+ Visit `http://localhost:5173` to view the demo.
276
+
277
+ ---
278
+
279
+ ## Live Demo
280
+
281
+ [View Live Demo on GitHub Pages](https://wyxos.github.io/vibe/)
282
+
283
+ ---
284
+
285
+ ## License
286
+
287
+ MIT © [@wyxos](https://github.com/wyxos)