@wyxos/vibe 5.0.2 → 5.1.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.
- package/README.md +45 -0
- package/lib/components/ReelFeed.vue.d.ts +2 -0
- package/lib/components/ReelLayout.vue.d.ts +2 -0
- package/lib/components/VibeSurface.vue.d.ts +7 -1
- package/lib/components/useReelKeyboard.d.ts +12 -0
- package/lib/core/feed.d.ts +3 -1
- package/lib/core/mediaLifecycle.d.ts +4 -0
- package/lib/core/reelEscapeStack.d.ts +6 -0
- package/lib/index.cjs +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +615 -517
- package/lib/types.d.ts +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,6 +125,35 @@ show looping previous/next controls on hover or keyboard focus. Reel layout
|
|
|
125
125
|
keeps those controls visible and supports native horizontal-wheel or touch-swipe
|
|
126
126
|
navigation through grouped media. Media changes use a directional horizontal
|
|
127
127
|
transition, while vertical reel scrolling continues to move between posts.
|
|
128
|
+
Media assets may include a stable `mediaId` (`string | number`) when consumers
|
|
129
|
+
need to select exact grouped media independently of its array position.
|
|
130
|
+
|
|
131
|
+
## Media lifecycle hooks
|
|
132
|
+
|
|
133
|
+
Use `onMediaReady` when an image has loaded or a video has enough metadata for
|
|
134
|
+
Vibe to render it, and `onReelMediaChange` when a reel first selects media or
|
|
135
|
+
moves to another parent, nested, or single-item post:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const vibe = createVibe({
|
|
139
|
+
target: '#gallery',
|
|
140
|
+
loadPage,
|
|
141
|
+
onMediaReady: ({ postId, mediaId, layout, origin }) => {
|
|
142
|
+
recordMediaReady({ postId, mediaId, layout, origin })
|
|
143
|
+
},
|
|
144
|
+
onReelMediaChange: ({ postId, mediaId, postIndex, mediaIndex }) => {
|
|
145
|
+
updateActiveMedia({ postId, mediaId, postIndex, mediaIndex })
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Both optional callbacks receive `VibeMediaLifecycleContext`: stable `postId`
|
|
151
|
+
and `mediaId` identity, zero-based `postIndex` and `mediaIndex`, the complete
|
|
152
|
+
`item` and selected `media`, the rendered `layout`, and `origin`. `mediaId` is
|
|
153
|
+
`null` when the source asset does not define one. `origin` is `null` for the
|
|
154
|
+
masonry grid, `reel` for the base reel, and `masonry` for a reel opened from a
|
|
155
|
+
masonry card. The readiness hook may run again if media remounts and becomes
|
|
156
|
+
ready again; reel-change events describe selection changes, not load state.
|
|
128
157
|
|
|
129
158
|
## Reel URLs with Vue Router
|
|
130
159
|
|
|
@@ -504,6 +533,9 @@ vibe.previousReelMediaItem()
|
|
|
504
533
|
// Posts within the reel (vertical reel navigation).
|
|
505
534
|
vibe.nextReelPost()
|
|
506
535
|
vibe.previousReelPost()
|
|
536
|
+
|
|
537
|
+
// An exact loaded post/media pair by stable identity.
|
|
538
|
+
vibe.navigateToReelItem({ postId: 'post-42', mediaId: 'asset-101' })
|
|
507
539
|
```
|
|
508
540
|
|
|
509
541
|
Each navigation method returns `true` when it accepted a navigation and `false`
|
|
@@ -520,6 +552,13 @@ Successful navigation updates `state.activeReelPostId`, the selected media item,
|
|
|
520
552
|
card-region props, route synchronization, and an open information sheet's
|
|
521
553
|
consumer context through the same handlers used by gestures and keyboard input.
|
|
522
554
|
|
|
555
|
+
`navigateToReelItem()` returns `navigated` when both identities resolve,
|
|
556
|
+
including when the requested media is already active. It returns `not-found`
|
|
557
|
+
when the loaded post or media is missing, and `reel-inactive` before mount,
|
|
558
|
+
after destroy, during initial loading, or while only masonry is visible. The
|
|
559
|
+
method does not load, insert, or fall back to another item. Every targetable
|
|
560
|
+
parent or nested `VibeMediaAsset` must provide its stable `mediaId`.
|
|
561
|
+
|
|
523
562
|
## Reel information sheet
|
|
524
563
|
|
|
525
564
|
Provide an application-owned Vue component when a reel should offer a
|
|
@@ -584,6 +623,11 @@ reel still updates this requested state; the sheet becomes visible when a valid
|
|
|
584
623
|
reel context exists. This preserves the existing persistent sheet-state
|
|
585
624
|
behavior across masonry viewer closes.
|
|
586
625
|
|
|
626
|
+
When a sheet contains another Vibe instance, Escape is owned by the topmost
|
|
627
|
+
active reel. A nested masonry-origin reel therefore closes back to its nested
|
|
628
|
+
feed without also closing the parent sheet or reel. Single-instance Escape
|
|
629
|
+
behavior is unchanged.
|
|
630
|
+
|
|
587
631
|
## Custom feed footer
|
|
588
632
|
|
|
589
633
|
Set `feedFooter.component` to replace the built-in `GalleryFooter`. Consumers
|
|
@@ -692,6 +736,7 @@ vibe.nextReelMediaItem()
|
|
|
692
736
|
vibe.previousReelMediaItem()
|
|
693
737
|
vibe.nextReelPost()
|
|
694
738
|
vibe.previousReelPost()
|
|
739
|
+
vibe.navigateToReelItem({ postId: 'post-42', mediaId: 'asset-101' })
|
|
695
740
|
vibe.setAutoScroll(true, 80)
|
|
696
741
|
vibe.pauseAutoScroll()
|
|
697
742
|
vibe.resumeAutoScroll()
|
|
@@ -3,6 +3,7 @@ import type { VibeItemId } from '../types';
|
|
|
3
3
|
declare function loadIfNearBottom(): void;
|
|
4
4
|
declare function changeActiveMedia(direction: -1 | 1): boolean;
|
|
5
5
|
declare function moveActivePost(direction: -1 | 1): boolean;
|
|
6
|
+
declare function navigateToItem(postId: VibeItemId, mediaIndex: number): boolean;
|
|
6
7
|
declare function transitionActivePost(postId: VibeItemId): Promise<boolean>;
|
|
7
8
|
declare function transitionActiveMedia(direction: -1 | 1): Promise<boolean>;
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<ReelFeedProps, {
|
|
@@ -11,6 +12,7 @@ declare const __VLS_export: import("vue").DefineComponent<ReelFeedProps, {
|
|
|
11
12
|
changeActiveMedia: typeof changeActiveMedia;
|
|
12
13
|
loadIfNearBottom: typeof loadIfNearBottom;
|
|
13
14
|
moveActivePost: typeof moveActivePost;
|
|
15
|
+
navigateToItem: typeof navigateToItem;
|
|
14
16
|
transitionActiveMedia: typeof transitionActiveMedia;
|
|
15
17
|
transitionActivePost: typeof transitionActivePost;
|
|
16
18
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -3,12 +3,14 @@ import type { VibeItemId } from '../types';
|
|
|
3
3
|
declare function changeActiveMedia(direction: -1 | 1): boolean;
|
|
4
4
|
declare function loadIfNearBottom(): void;
|
|
5
5
|
declare function moveActivePost(direction: -1 | 1): boolean;
|
|
6
|
+
declare function navigateToItem(postId: VibeItemId, mediaIndex: number): boolean;
|
|
6
7
|
declare function transitionActiveMedia(direction: -1 | 1): Promise<boolean>;
|
|
7
8
|
declare function transitionActivePost(postId: VibeItemId): Promise<boolean>;
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<ReelLayoutProps, {
|
|
9
10
|
changeActiveMedia: typeof changeActiveMedia;
|
|
10
11
|
loadIfNearBottom: typeof loadIfNearBottom;
|
|
11
12
|
moveActivePost: typeof moveActivePost;
|
|
13
|
+
navigateToItem: typeof navigateToItem;
|
|
12
14
|
transitionActiveMedia: typeof transitionActiveMedia;
|
|
13
15
|
transitionActivePost: typeof transitionActivePost;
|
|
14
16
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type VibeRuntimeState } from '../core/runtime';
|
|
2
|
-
import type { VibeCardRegion, VibeFeedFooter, VibeFeedFooterActions, VibeItemId, VibeMediaCardOptions, VibeReelInfoSheetOptions } from '../types';
|
|
2
|
+
import type { VibeCardRegion, VibeFeedFooter, VibeFeedFooterActions, VibeItemId, VibeMediaCardOptions, VibeMediaLifecycleContext, VibeReelInfoSheetOptions, VibeReelItemTarget, VibeReelNavigationResult } from '../types';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
canRetryEnd: boolean;
|
|
5
5
|
cardFooter?: VibeCardRegion;
|
|
@@ -13,6 +13,7 @@ type __VLS_Props = {
|
|
|
13
13
|
declare function loadIfNearBottom(): Promise<void>;
|
|
14
14
|
declare function changeActiveReelMedia(direction: -1 | 1): boolean;
|
|
15
15
|
declare function moveActiveReelPost(direction: -1 | 1): boolean;
|
|
16
|
+
declare function navigateToReelItem(target: VibeReelItemTarget): VibeReelNavigationResult;
|
|
16
17
|
declare function getAutoScrollElement(): HTMLElement | null;
|
|
17
18
|
declare function startItemRemoval(postIds: readonly VibeItemId[]): number;
|
|
18
19
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
@@ -20,6 +21,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
20
21
|
getAutoScrollElement: typeof getAutoScrollElement;
|
|
21
22
|
loadIfNearBottom: typeof loadIfNearBottom;
|
|
22
23
|
moveActiveReelPost: typeof moveActiveReelPost;
|
|
24
|
+
navigateToReelItem: typeof navigateToReelItem;
|
|
23
25
|
startItemRemoval: typeof startItemRemoval;
|
|
24
26
|
transitionActiveReelMedia: (direction: -1 | 1) => Promise<boolean>;
|
|
25
27
|
transitionActiveReelPost: (postId: VibeItemId) => Promise<boolean>;
|
|
@@ -29,7 +31,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
29
31
|
retryForward: () => any;
|
|
30
32
|
activeReelChange: (postId: VibeItemId) => any;
|
|
31
33
|
closeReel: () => any;
|
|
34
|
+
mediaReady: (context: VibeMediaLifecycleContext) => any;
|
|
32
35
|
openReel: (postId: VibeItemId) => any;
|
|
36
|
+
reelMediaChange: (context: VibeMediaLifecycleContext) => any;
|
|
33
37
|
reelInfoSheetChange: (enabled: boolean) => any;
|
|
34
38
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
35
39
|
onLoadMore?: (() => any) | undefined;
|
|
@@ -37,7 +41,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
37
41
|
onRetryForward?: (() => any) | undefined;
|
|
38
42
|
onActiveReelChange?: ((postId: VibeItemId) => any) | undefined;
|
|
39
43
|
onCloseReel?: (() => any) | undefined;
|
|
44
|
+
onMediaReady?: ((context: VibeMediaLifecycleContext) => any) | undefined;
|
|
40
45
|
onOpenReel?: ((postId: VibeItemId) => any) | undefined;
|
|
46
|
+
onReelMediaChange?: ((context: VibeMediaLifecycleContext) => any) | undefined;
|
|
41
47
|
onReelInfoSheetChange?: ((enabled: boolean) => any) | undefined;
|
|
42
48
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
43
49
|
declare const _default: typeof __VLS_export;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FeedRendererExpose } from '../core/feed';
|
|
2
|
+
import type { VibeRuntimeState } from '../core/runtime';
|
|
3
|
+
interface ReelKeyboardOptions {
|
|
4
|
+
closeMasonryReel: () => void;
|
|
5
|
+
element: () => HTMLElement | null;
|
|
6
|
+
isReelLeaving: () => boolean;
|
|
7
|
+
reelRenderer: () => FeedRendererExpose | null;
|
|
8
|
+
setReelInfoSheet: (enabled: boolean) => void;
|
|
9
|
+
state: VibeRuntimeState;
|
|
10
|
+
}
|
|
11
|
+
export declare function useReelKeyboard(options: ReelKeyboardOptions): void;
|
|
12
|
+
export {};
|
package/lib/core/feed.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VibeCardRegion, VibeFeedFooter, VibeFeedFooterActions, VibeItem, VibeItemId, VibeMediaSource, VibeMediaCardOptions, VibeReelAutoAdvanceState, VibeReelForwardState, VibeReelInfoSheetOptions, VibeReelOrigin, VibeState } from '../types';
|
|
1
|
+
import type { VibeCardRegion, VibeFeedFooter, VibeFeedFooterActions, VibeItem, VibeItemId, VibeMediaSource, VibeMediaCardOptions, VibeReelAutoAdvanceState, VibeReelForwardState, VibeReelInfoSheetOptions, VibeReelItemTarget, VibeReelNavigationResult, VibeReelOrigin, VibeState } from '../types';
|
|
2
2
|
import type { MediaPreviewState } from './mediaPreview';
|
|
3
3
|
export interface FeedRendererProps {
|
|
4
4
|
canRetryEnd: boolean;
|
|
@@ -30,6 +30,7 @@ export interface FeedRendererExpose {
|
|
|
30
30
|
getScrollElement?: () => HTMLElement | null;
|
|
31
31
|
loadIfNearBottom: () => void;
|
|
32
32
|
moveActivePost?: (direction: -1 | 1) => boolean;
|
|
33
|
+
navigateToItem?: (postId: VibeItemId, mediaIndex: number) => boolean;
|
|
33
34
|
transitionActiveMedia?: (direction: -1 | 1) => Promise<boolean>;
|
|
34
35
|
transitionActivePost?: (postId: VibeItemId) => Promise<boolean>;
|
|
35
36
|
}
|
|
@@ -52,6 +53,7 @@ export interface VibeSurfaceExpose {
|
|
|
52
53
|
getAutoScrollElement: () => HTMLElement | null;
|
|
53
54
|
loadIfNearBottom: () => Promise<void>;
|
|
54
55
|
moveActiveReelPost: (direction: -1 | 1) => boolean;
|
|
56
|
+
navigateToReelItem: (target: VibeReelItemTarget) => VibeReelNavigationResult;
|
|
55
57
|
startItemRemoval: (postIds: readonly VibeItemId[]) => number;
|
|
56
58
|
transitionActiveReelMedia: (direction: -1 | 1) => Promise<boolean>;
|
|
57
59
|
transitionActiveReelPost: (postId: VibeItemId) => Promise<boolean>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { VibeRuntimeState } from './runtime';
|
|
2
|
+
import type { VibeItemId, VibeLayout, VibeMediaLifecycleContext, VibeReelOrigin } from '../types';
|
|
3
|
+
export declare function mediaLifecycleContext(state: VibeRuntimeState, postId: VibeItemId, mediaIndex: number, layout: VibeLayout, origin: VibeReelOrigin | null): VibeMediaLifecycleContext | null;
|
|
4
|
+
export declare function useReelMediaChangeLifecycle(state: VibeRuntimeState, onChange: (context: VibeMediaLifecycleContext) => void): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface ReelEscapeParticipant {
|
|
2
|
+
element: () => HTMLElement | null;
|
|
3
|
+
isActive: () => boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function registerReelEscapeParticipant(participant: ReelEscapeParticipant): () => void;
|
|
6
|
+
export declare function isTopmostActiveReel(participant: ReelEscapeParticipant): boolean;
|