@wyxos/vibe 2.2.5 → 3.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 (75) hide show
  1. package/README.md +451 -95
  2. package/lib/components/FullscreenHeader.vue.d.ts +25 -0
  3. package/lib/components/FullscreenMediaBar.vue.d.ts +14 -0
  4. package/lib/components/FullscreenSurface.vue.d.ts +46 -0
  5. package/lib/components/Layout.vue.d.ts +42 -0
  6. package/lib/components/ListCard.vue.d.ts +44 -0
  7. package/lib/components/ListSurface.vue.d.ts +64 -0
  8. package/lib/components/viewer-core/assetErrors.d.ts +30 -0
  9. package/lib/components/viewer-core/assetState.d.ts +12 -0
  10. package/lib/components/viewer-core/autoBuckets.d.ts +18 -0
  11. package/lib/components/viewer-core/autoResolveHelpers.d.ts +19 -0
  12. package/lib/components/viewer-core/autoResolveState.d.ts +50 -0
  13. package/lib/components/viewer-core/dom.d.ts +2 -0
  14. package/lib/components/viewer-core/fillDelay.d.ts +9 -0
  15. package/lib/components/viewer-core/format.d.ts +1 -0
  16. package/lib/components/viewer-core/itemIdentity.d.ts +6 -0
  17. package/lib/components/viewer-core/listCardAsset.d.ts +4 -0
  18. package/lib/components/viewer-core/listPreview.d.ts +10 -0
  19. package/lib/components/viewer-core/loadError.d.ts +4 -0
  20. package/lib/components/viewer-core/masonryLayout.d.ts +37 -0
  21. package/lib/components/viewer-core/masonryViewport.d.ts +7 -0
  22. package/lib/components/viewer-core/media.d.ts +4 -0
  23. package/lib/components/viewer-core/mediaPlayback.d.ts +1 -0
  24. package/lib/components/viewer-core/removalState.d.ts +50 -0
  25. package/lib/components/viewer-core/slotContent.d.ts +2 -0
  26. package/lib/components/viewer-core/surfaceSlots.d.ts +22 -0
  27. package/lib/components/viewer-core/theme.d.ts +3 -0
  28. package/lib/components/viewer-core/useActivation.d.ts +8 -0
  29. package/lib/components/viewer-core/useAssetLoadQueue.d.ts +22 -0
  30. package/lib/components/viewer-core/useAutoResolveSource.d.ts +51 -0
  31. package/lib/components/viewer-core/useController.d.ts +71 -0
  32. package/lib/components/viewer-core/useDataSource.d.ts +100 -0
  33. package/lib/components/viewer-core/useEdgeBoundary.d.ts +16 -0
  34. package/lib/components/viewer-core/useFullscreen.d.ts +1 -0
  35. package/lib/components/viewer-core/useMasonryList.d.ts +43 -0
  36. package/lib/components/viewer-core/useMasonryMotion.d.ts +29 -0
  37. package/lib/components/viewer-core/useMedia.d.ts +39 -0
  38. package/lib/components/viewer-core/useViewer.d.ts +61 -0
  39. package/lib/components/viewer-core/virtualization.d.ts +14 -0
  40. package/lib/components/viewer.d.ts +16 -0
  41. package/lib/index.cjs +1 -1
  42. package/lib/index.d.ts +58 -5
  43. package/lib/index.js +3196 -1486
  44. package/lib/style.css +3 -0
  45. package/package.json +86 -83
  46. package/lib/App.vue.d.ts +0 -3
  47. package/lib/apple-touch-icon-114x114.png +0 -0
  48. package/lib/apple-touch-icon-120x120.png +0 -0
  49. package/lib/apple-touch-icon-144x144.png +0 -0
  50. package/lib/apple-touch-icon-152x152.png +0 -0
  51. package/lib/apple-touch-icon-180x180.png +0 -0
  52. package/lib/apple-touch-icon-57x57.png +0 -0
  53. package/lib/apple-touch-icon-60x60.png +0 -0
  54. package/lib/apple-touch-icon-72x72.png +0 -0
  55. package/lib/apple-touch-icon-76x76.png +0 -0
  56. package/lib/components/Masonry.vue.d.ts +0 -68
  57. package/lib/components/MasonryItem.vue.d.ts +0 -3
  58. package/lib/components/MasonryLoader.vue.d.ts +0 -27
  59. package/lib/components/MasonryVideoControls.vue.d.ts +0 -30
  60. package/lib/components/masonryItemRegistry.d.ts +0 -24
  61. package/lib/favicon-128x128.png +0 -0
  62. package/lib/favicon-16x16.png +0 -0
  63. package/lib/favicon-256x256.png +0 -0
  64. package/lib/favicon-32x32.png +0 -0
  65. package/lib/favicon-48x48.png +0 -0
  66. package/lib/favicon-64x64.png +0 -0
  67. package/lib/favicon.ico +0 -0
  68. package/lib/logo-dark.svg +0 -36
  69. package/lib/logo-light.svg +0 -29
  70. package/lib/logo.svg +0 -32
  71. package/lib/manifest.json +0 -41
  72. package/lib/masonry/backfill.d.ts +0 -53
  73. package/lib/masonry/layout.d.ts +0 -13
  74. package/lib/masonry/layoutEngine.d.ts +0 -33
  75. package/lib/masonry/types.d.ts +0 -95
package/README.md CHANGED
@@ -1,95 +1,451 @@
1
- <p align="center">
2
- <img src="public/logo.svg" width="120" alt="VIBE logo" />
3
- </p>
4
- <h1 align="center">VIBE</h1>
5
- <p align="center">
6
- <img src="demo.webp" alt="VIBE demo" />
7
- </p>
8
-
9
- VIBE (Vue Infinite Block Engine) is a high-performance masonry feed component for Vue 3.
10
-
11
- It’s built for large, scroll-heavy media feeds and aims to stay smooth with thousands of items.
12
-
13
- ## Highlights
14
-
15
- - Virtualized rendering (keeps DOM small)
16
- - Infinite loading via an async `getContent(pageToken) => { items, nextPage }`
17
- - Optional backfill mode to reach a target `pageSize`
18
- - Smooth removal + reorder transitions, with `remove` / `undo` / `restore`
19
- - Preserves a single DOM sequence (no column re-parenting)
20
- - Item templates via `<MasonryItem>` with `#header` / `#default` / `#footer`
21
-
22
- ## Demo
23
-
24
- - Local: `npm run dev`
25
- - Live: https://vibe.wyxos.com/
26
-
27
- ## Install
28
-
29
- ```bash
30
- npm i @wyxos/vibe
31
- ```
32
-
33
- ## Simple integration (minimal)
34
-
35
- Minimal example with the required scrolling container CSS and a simple `getContent(page)`.
36
-
37
- ```vue
38
- <script setup lang="ts">
39
- import { ref } from 'vue'
40
- import { Masonry, MasonryItem } from '@wyxos/vibe'
41
-
42
- type Item = { id: string; width: number; height: number }
43
-
44
- const items = ref<Item[]>([])
45
-
46
- async function getContent(page: number) {
47
- // Replace with your server/API call.
48
- const pageSize = 20
49
- const newItems: Item[] = Array.from({ length: pageSize }, (_, i) => ({
50
- id: `${page}-${i}`,
51
- width: 640,
52
- height: 480,
53
- }))
54
-
55
- return {
56
- items: newItems,
57
- nextPage: page + 1,
58
- }
59
- }
60
- </script>
61
-
62
- <template>
63
- <div class="app">
64
- <Masonry class="masonry" v-model:items="items" :get-content="getContent" :page="1">
65
- <MasonryItem>
66
- <template #default="{ item }">
67
- <div>{{ item.id }}</div>
68
- </template>
69
- </MasonryItem>
70
- </Masonry>
71
- </div>
72
- </template>
73
-
74
- <style>
75
- .app {
76
- height: 100vh;
77
- display: flex;
78
- flex-direction: column;
79
- }
80
-
81
- /* Required: gives the Masonry internal scroll viewport a real height */
82
- .masonry {
83
- flex: 1 1 auto;
84
- min-height: 0;
85
- }
86
- </style>
87
- ```
88
-
89
- > **Warning**
90
- > Each item must include `{ id, width, height }` so the layout can be calculated.
91
-
92
- ## Local library build
93
-
94
- - JS bundles: `npm run build:lib`
95
- - Types: `npm run build:types`
1
+ # Vibe
2
+
3
+ Vibe is a Vue 3 media viewer for large feeds of mixed image, video, audio, and other items.
4
+
5
+ It ships two built-in surfaces:
6
+
7
+ - Desktop: a virtualized masonry grid that opens into fullscreen
8
+ - Mobile and tablet: fullscreen only
9
+
10
+ The current `3.0.0` rebuild focuses on a strict item contract, library-owned loading, strong demo coverage, and a small customization surface.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm i @wyxos/vibe
16
+ ```
17
+
18
+ Import the bundled stylesheet once:
19
+
20
+ ```ts
21
+ import '@wyxos/vibe/style.css'
22
+ ```
23
+
24
+ Tailwind scanning is not required for the package UI.
25
+
26
+ ## Plugin install
27
+
28
+ The default export is the plugin:
29
+
30
+ ```ts
31
+ import { createApp } from 'vue'
32
+ import App from './App.vue'
33
+
34
+ import Vibe from '@wyxos/vibe'
35
+ import '@wyxos/vibe/style.css'
36
+
37
+ createApp(App)
38
+ .use(Vibe)
39
+ .mount('#app')
40
+ ```
41
+
42
+ That registers the global component as `VibeLayout`.
43
+
44
+ ## Direct import
45
+
46
+ If you prefer local registration, import `VibeLayout` directly:
47
+
48
+ ```vue
49
+ <script setup lang="ts">
50
+ import {
51
+ VibeLayout,
52
+ type VibeResolveParams,
53
+ type VibeResolveResult,
54
+ } from '@wyxos/vibe'
55
+ import '@wyxos/vibe/style.css'
56
+
57
+ async function resolve({ cursor, pageSize }: VibeResolveParams): Promise<VibeResolveResult> {
58
+ const response = await fetch(`/api/feed?cursor=${cursor ?? ''}&pageSize=${pageSize}`)
59
+ return await response.json()
60
+ }
61
+ </script>
62
+
63
+ <template>
64
+ <VibeLayout :resolve="resolve" />
65
+ </template>
66
+ ```
67
+
68
+ Optional auto-mode pacing props:
69
+
70
+ ```vue
71
+ <VibeLayout
72
+ :resolve="resolve"
73
+ :fill-delay-ms="1000"
74
+ :fill-delay-step-ms="250"
75
+ />
76
+ ```
77
+
78
+ - `fill-delay-ms`: base delay before the first chained fill request
79
+ - `fill-delay-step-ms`: extra delay added for each additional chained fill request in the same fill cycle
80
+
81
+ Optional auto-mode feed strategy:
82
+
83
+ ```vue
84
+ <VibeLayout
85
+ :resolve="resolve"
86
+ mode="dynamic"
87
+ />
88
+ ```
89
+
90
+ - `dynamic` is the default
91
+ - `static` reloads the current boundary cursor before advancing when the currently visible boundary page is underfilled
92
+
93
+ ## What Vibe does
94
+
95
+ - Desktop masonry list with virtualization and staged page growth
96
+ - Fullscreen viewer with swipe, wheel, keyboard, and custom media controls
97
+ - Auto-loading mode with internal pagination ownership
98
+ - Controlled mode for advanced/manual integrations
99
+ - Remove, restore, and undo by item `id`
100
+ - Grid customization through slots for icons, overlays, and footer UI
101
+ - Built-in loading and preload error states, including explicit `404` when known
102
+ - Built-in retry UI for non-404 asset failures in grid and fullscreen
103
+
104
+ ## Item contract
105
+
106
+ Vibe only requires a minimal item shape:
107
+
108
+ ```ts
109
+ type VibeViewerItem = {
110
+ id: string
111
+ type: 'image' | 'video' | 'audio' | 'other'
112
+ title?: string
113
+ url: string
114
+ width?: number
115
+ height?: number
116
+ preview?: {
117
+ url: string
118
+ width?: number
119
+ height?: number
120
+ }
121
+ [key: string]: unknown
122
+ }
123
+ ```
124
+
125
+ Notes:
126
+
127
+ - Grid mode prefers `preview.url`, then falls back to `url`
128
+ - Fullscreen mode uses `url`
129
+ - Grid layout prefers `preview.width/height`, then root `width/height`, then a square fallback tile
130
+ - `other` is intentionally broad so the consuming app can layer its own subtypes and icon logic on top
131
+
132
+ ## Loading modes
133
+
134
+ ### Auto mode
135
+
136
+ Use `resolve` when you want Vibe to own the paging loop:
137
+
138
+ ```ts
139
+ type VibeResolveParams = {
140
+ cursor: string | null
141
+ pageSize: number
142
+ }
143
+
144
+ type VibeResolveResult = {
145
+ items: VibeViewerItem[]
146
+ nextPage: string | null
147
+ previousPage?: string | null
148
+ }
149
+ ```
150
+
151
+ ```vue
152
+ <script setup lang="ts">
153
+ import {
154
+ VibeLayout,
155
+ type VibeResolveParams,
156
+ type VibeResolveResult,
157
+ } from '@wyxos/vibe'
158
+
159
+ async function resolve({ cursor, pageSize }: VibeResolveParams): Promise<VibeResolveResult> {
160
+ const response = await fetch(`/api/feed?cursor=${cursor ?? ''}&pageSize=${pageSize}`)
161
+ return await response.json()
162
+ }
163
+ </script>
164
+
165
+ <template>
166
+ <VibeLayout :resolve="resolve" />
167
+ </template>
168
+ ```
169
+
170
+ In this mode, Vibe owns:
171
+
172
+ - loaded items
173
+ - active index
174
+ - next-page prefetch
175
+ - optional previous-page loading
176
+ - duplicate cursor protection
177
+ - initial retry state
178
+
179
+ Auto mode also supports two feed strategies:
180
+
181
+ - `dynamic`:
182
+ - default behavior
183
+ - if a resolve returns fewer items than `pageSize`, Vibe enters a fill loop
184
+ - it waits `fillDelayMs`, then `fillDelayMs + fillDelayStepMs`, and so on for each chained request
185
+ - it keeps accumulating results until the collected count reaches `pageSize` or there is no further cursor
186
+ - then it commits that batch into the layout once
187
+ - `static`:
188
+ - before advancing at the bottom or top, Vibe checks whether the current boundary page is underfilled after local removals
189
+ - if it is, Vibe reloads that same cursor in place first
190
+ - only once that boundary page is full again will the next edge hit advance to the next or previous cursor
191
+
192
+ ### Controlled mode
193
+
194
+ Use controlled mode when the app needs to own item aggregation or paging policy:
195
+
196
+ ```vue
197
+ <script setup lang="ts">
198
+ import { ref } from 'vue'
199
+ import { VibeLayout, type VibeViewerItem } from '@wyxos/vibe'
200
+
201
+ const items = ref<VibeViewerItem[]>([])
202
+ const activeIndex = ref(0)
203
+ const loading = ref(false)
204
+ const hasNextPage = ref(true)
205
+ const hasPreviousPage = ref(false)
206
+
207
+ async function requestNextPage() {
208
+ // app-owned fetch and append
209
+ }
210
+
211
+ async function requestPreviousPage() {
212
+ // app-owned fetch and prepend
213
+ }
214
+ </script>
215
+
216
+ <template>
217
+ <VibeLayout
218
+ :items="items"
219
+ :active-index="activeIndex"
220
+ :loading="loading"
221
+ :has-next-page="hasNextPage"
222
+ :has-previous-page="hasPreviousPage"
223
+ pagination-detail="P10-12 · V11"
224
+ :request-next-page="requestNextPage"
225
+ :request-previous-page="requestPreviousPage"
226
+ @update:active-index="activeIndex = $event"
227
+ />
228
+ </template>
229
+ ```
230
+
231
+ ## Slots
232
+
233
+ `VibeLayout` exposes three customization slots:
234
+
235
+ ### `#item-icon`
236
+
237
+ Lets the app replace the fallback icon, especially useful for `other` items.
238
+
239
+ Slot props:
240
+
241
+ - `item`
242
+ - `icon`
243
+
244
+ ```vue
245
+ <VibeLayout :resolve="resolve">
246
+ <template #item-icon="{ item, icon }">
247
+ <component :is="item.type === 'other' ? MyCustomIcon : icon" />
248
+ </template>
249
+ </VibeLayout>
250
+ ```
251
+
252
+ ### `#grid-item-overlay`
253
+
254
+ Desktop grid-only overlay content for reactions, menus, badges, and similar controls.
255
+
256
+ Slot props:
257
+
258
+ - `item`
259
+ - `index`
260
+ - `active`
261
+ - `hovered`
262
+ - `focused`
263
+ - `openFullscreen`
264
+
265
+ ```vue
266
+ <VibeLayout :resolve="resolve">
267
+ <template #grid-item-overlay="{ item, hovered }">
268
+ <div v-if="hovered" class="absolute inset-x-0 bottom-0 p-3">
269
+ <div class="pointer-events-auto bg-black/45 px-3 py-2 backdrop-blur">
270
+ {{ item.title }}
271
+ </div>
272
+ </div>
273
+ </template>
274
+ </VibeLayout>
275
+ ```
276
+
277
+ ### `#grid-footer`
278
+
279
+ Desktop grid-only footer surface for app-owned status bars or controls.
280
+
281
+ ```vue
282
+ <VibeLayout :resolve="resolve">
283
+ <template #grid-footer>
284
+ <div class="bg-black/55 px-4 py-3 backdrop-blur">
285
+ Custom footer UI
286
+ </div>
287
+ </template>
288
+ </VibeLayout>
289
+ ```
290
+
291
+ ## Exposed handle
292
+
293
+ Get a component ref and use `VibeHandle`:
294
+
295
+ ```ts
296
+ import { ref } from 'vue'
297
+ import type { VibeHandle } from '@wyxos/vibe'
298
+
299
+ const vibe = ref<VibeHandle | null>(null)
300
+ ```
301
+
302
+ ```vue
303
+ <VibeLayout ref="vibe" :resolve="resolve" />
304
+ ```
305
+
306
+ Available methods:
307
+
308
+ - `remove(ids)`
309
+ - `restore(ids)`
310
+ - `undo()`
311
+ - `getRemovedIds()`
312
+ - `clearRemoved()`
313
+
314
+ Available state:
315
+
316
+ ```ts
317
+ type VibeStatus = {
318
+ activeIndex: number
319
+ currentCursor: string | null
320
+ errorMessage: string | null
321
+ fillCollectedCount: number | null
322
+ fillDelayRemainingMs: number | null
323
+ fillTargetCount: number | null
324
+ hasNextPage: boolean
325
+ hasPreviousPage: boolean
326
+ isAutoMode: boolean
327
+ itemCount: number
328
+ loadState: 'failed' | 'loaded' | 'loading'
329
+ mode: 'dynamic' | 'static' | null
330
+ nextCursor: string | null
331
+ phase: 'failed' | 'filling' | 'idle' | 'loading' | 'reloading'
332
+ previousCursor: string | null
333
+ removedCount: number
334
+ surfaceMode: 'fullscreen' | 'list'
335
+ }
336
+ ```
337
+
338
+ Example:
339
+
340
+ ```ts
341
+ vibe.value?.remove(['item-2', 'item-5'])
342
+ vibe.value?.undo()
343
+ console.log(vibe.value?.status.itemCount)
344
+ ```
345
+
346
+ ## Events
347
+
348
+ `VibeLayout` emits:
349
+
350
+ - `update:activeIndex`
351
+ - `asset-loads`
352
+ - `asset-errors`
353
+
354
+ `asset-loads` is micro-batched and emits an array payload:
355
+
356
+ ```ts
357
+ type VibeAssetLoadEvent = {
358
+ item: VibeViewerItem
359
+ occurrenceKey: string
360
+ url: string
361
+ surface: 'grid' | 'fullscreen'
362
+ }
363
+ ```
364
+
365
+ `asset-errors` is micro-batched and emits an array payload:
366
+
367
+ ```ts
368
+ type VibeAssetErrorEvent = {
369
+ item: VibeViewerItem
370
+ occurrenceKey: string
371
+ url: string
372
+ kind: 'generic' | 'not-found'
373
+ surface: 'grid' | 'fullscreen'
374
+ }
375
+ ```
376
+
377
+ Example:
378
+
379
+ ```vue
380
+ <script setup lang="ts">
381
+ import type { VibeAssetErrorEvent, VibeAssetLoadEvent } from '@wyxos/vibe'
382
+
383
+ function onAssetLoads(loads: VibeAssetLoadEvent[]) {
384
+ console.log(loads)
385
+ }
386
+
387
+ function onAssetErrors(errors: VibeAssetErrorEvent[]) {
388
+ console.log(errors)
389
+ }
390
+ </script>
391
+
392
+ <template>
393
+ <VibeLayout
394
+ :resolve="resolve"
395
+ @asset-loads="onAssetLoads"
396
+ @asset-errors="onAssetErrors"
397
+ />
398
+ </template>
399
+ ```
400
+
401
+ Notes:
402
+
403
+ - successful loads that happen close together are batched into one event
404
+ - grid load events usually report `preview.url` when a preview exists
405
+ - fullscreen load events report `item.url`
406
+ - multiple failures that happen close together are batched into one event
407
+ - identical failures are deduped inside the same batch
408
+ - if the same item fails again later, it can emit again in a later batch
409
+ - built-in Vibe error surfaces allow retrying `generic` failures, but not `not-found`
410
+
411
+ ## Surface behavior
412
+
413
+ - Desktop starts in the masonry grid
414
+ - Clicking a grid tile opens fullscreen
415
+ - `Escape` returns from fullscreen to grid on desktop
416
+ - Mobile and tablet always force fullscreen
417
+ - Grid uses preview assets and in-view loading
418
+ - Fullscreen uses the original asset and shows a spinner until ready
419
+
420
+ ## Local demo routes
421
+
422
+ Run:
423
+
424
+ ```bash
425
+ npm run dev
426
+ ```
427
+
428
+ Routes:
429
+
430
+ - `/` – clean default demo
431
+ - `/documentation` – in-app documentation
432
+ - `/demo/dynamic-feed` – dynamic feed fill-loop demo
433
+ - `/demo/advanced-integration` – advanced static integration demo
434
+ - `/debug/fake-server` – fake-server inspection route
435
+
436
+ ## Local development
437
+
438
+ ```bash
439
+ npm run check
440
+ npm run build
441
+ npm run build:lib
442
+ npm run build:types
443
+ npm run test:unit
444
+ npm run test:e2e
445
+ ```
446
+
447
+ ## Notes
448
+
449
+ - `lib/` is generated output
450
+ - Source of truth is under `src/`
451
+ - The package ships compiled CSS at `@wyxos/vibe/style.css`
@@ -0,0 +1,25 @@
1
+ type __VLS_Props = {
2
+ currentIndex: number;
3
+ paginationDetail?: string | null;
4
+ showBackToList?: boolean;
5
+ showEndBadge?: boolean;
6
+ title?: string | null;
7
+ total: number;
8
+ };
9
+ declare var __VLS_6: {};
10
+ type __VLS_Slots = {} & {
11
+ actions?: (props: typeof __VLS_6) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ "back-to-list": () => any;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ "onBack-to-list"?: (() => any) | undefined;
17
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };
@@ -0,0 +1,14 @@
1
+ type __VLS_Props = {
2
+ currentTime: number;
3
+ currentTimeLabel: string;
4
+ duration: number;
5
+ durationLabel: string;
6
+ progress: number;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "seek-input": (event: Event) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ "onSeek-input"?: ((event: Event) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,46 @@
1
+ import type { Component } from 'vue';
2
+ import type { VibeViewerItem } from './viewer';
3
+ import type { VibeAssetErrorReporter, VibeAssetLoadReporter } from './viewer-core/assetErrors';
4
+ import type { VibeFullscreenStatusSlotProps, VibeSurfaceSlotProps } from './viewer-core/surfaceSlots';
5
+ import type { VibeControlledProps } from './viewer-core/useViewer';
6
+ import './viewer-core/fullscreenMediaBar.css';
7
+ type __VLS_Props = VibeControlledProps & {
8
+ active?: boolean;
9
+ reportAssetError?: VibeAssetErrorReporter | null;
10
+ reportAssetLoad?: VibeAssetLoadReporter | null;
11
+ showBackToList?: boolean;
12
+ };
13
+ type __VLS_Slots = {
14
+ 'fullscreen-aside'?: (props: VibeSurfaceSlotProps) => unknown;
15
+ 'fullscreen-header-actions'?: (props: VibeSurfaceSlotProps) => unknown;
16
+ 'fullscreen-overlay'?: (props: VibeSurfaceSlotProps) => unknown;
17
+ 'fullscreen-status'?: (props: VibeFullscreenStatusSlotProps) => unknown;
18
+ 'item-icon'?: (props: {
19
+ icon: Component;
20
+ item: VibeViewerItem;
21
+ }) => unknown;
22
+ };
23
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
24
+ "update:activeIndex": (value: number) => any;
25
+ "back-to-list": () => any;
26
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
27
+ "onUpdate:activeIndex"?: ((value: number) => any) | undefined;
28
+ "onBack-to-list"?: (() => any) | undefined;
29
+ }>, {
30
+ loading: boolean;
31
+ activeIndex: number;
32
+ hasNextPage: boolean;
33
+ paginationDetail: string | null;
34
+ showBackToList: boolean;
35
+ active: boolean;
36
+ reportAssetError: VibeAssetErrorReporter | null;
37
+ reportAssetLoad: VibeAssetLoadReporter | null;
38
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
39
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
40
+ declare const _default: typeof __VLS_export;
41
+ export default _default;
42
+ type __VLS_WithSlots<T, S> = T & {
43
+ new (): {
44
+ $slots: S;
45
+ };
46
+ };
@@ -0,0 +1,42 @@
1
+ import { type Component } from 'vue';
2
+ import type { VibeViewerItem } from './viewer';
3
+ import { type VibeAssetErrorEvent, type VibeAssetLoadEvent } from './viewer-core/assetErrors';
4
+ import type { VibeFullscreenStatusSlotProps, VibeGridStatusSlotProps, VibeSurfaceSlotProps } from './viewer-core/surfaceSlots';
5
+ import type { VibeHandle } from './viewer-core/useViewer';
6
+ type __VLS_Slots = {
7
+ 'fullscreen-aside'?: (props: VibeSurfaceSlotProps) => unknown;
8
+ 'fullscreen-header-actions'?: (props: VibeSurfaceSlotProps) => unknown;
9
+ 'fullscreen-overlay'?: (props: VibeSurfaceSlotProps) => unknown;
10
+ 'fullscreen-status'?: (props: VibeFullscreenStatusSlotProps) => unknown;
11
+ 'grid-footer'?: () => unknown;
12
+ 'grid-item-overlay'?: (props: {
13
+ active: boolean;
14
+ focused: boolean;
15
+ hovered: boolean;
16
+ index: number;
17
+ item: VibeViewerItem;
18
+ openFullscreen: () => void;
19
+ }) => unknown;
20
+ 'grid-status'?: (props: VibeGridStatusSlotProps) => unknown;
21
+ 'item-icon'?: (props: {
22
+ icon: Component;
23
+ item: VibeViewerItem;
24
+ }) => unknown;
25
+ };
26
+ declare const __VLS_base: import("vue").DefineComponent<import("..").VibeControlledProps | import("..").VibeAutoProps, VibeHandle, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ "update:activeIndex": (value: number) => any;
28
+ "asset-errors": (errors: VibeAssetErrorEvent[]) => any;
29
+ "asset-loads": (loads: VibeAssetLoadEvent[]) => any;
30
+ }, string, import("vue").PublicProps, Readonly<import("..").VibeControlledProps | import("..").VibeAutoProps> & Readonly<{
31
+ "onUpdate:activeIndex"?: ((value: number) => any) | undefined;
32
+ "onAsset-errors"?: ((errors: VibeAssetErrorEvent[]) => any) | undefined;
33
+ "onAsset-loads"?: ((loads: VibeAssetLoadEvent[]) => any) | undefined;
34
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
36
+ declare const _default: typeof __VLS_export;
37
+ export default _default;
38
+ type __VLS_WithSlots<T, S> = T & {
39
+ new (): {
40
+ $slots: S;
41
+ };
42
+ };