@wyxos/vibe 5.0.2 → 5.0.3

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
@@ -125,6 +125,8 @@ 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.
128
130
 
129
131
  ## Reel URLs with Vue Router
130
132
 
@@ -504,6 +506,9 @@ vibe.previousReelMediaItem()
504
506
  // Posts within the reel (vertical reel navigation).
505
507
  vibe.nextReelPost()
506
508
  vibe.previousReelPost()
509
+
510
+ // An exact loaded post/media pair by stable identity.
511
+ vibe.navigateToReelItem({ postId: 'post-42', mediaId: 'asset-101' })
507
512
  ```
508
513
 
509
514
  Each navigation method returns `true` when it accepted a navigation and `false`
@@ -520,6 +525,13 @@ Successful navigation updates `state.activeReelPostId`, the selected media item,
520
525
  card-region props, route synchronization, and an open information sheet's
521
526
  consumer context through the same handlers used by gestures and keyboard input.
522
527
 
528
+ `navigateToReelItem()` returns `navigated` when both identities resolve,
529
+ including when the requested media is already active. It returns `not-found`
530
+ when the loaded post or media is missing, and `reel-inactive` before mount,
531
+ after destroy, during initial loading, or while only masonry is visible. The
532
+ method does not load, insert, or fall back to another item. Every targetable
533
+ parent or nested `VibeMediaAsset` must provide its stable `mediaId`.
534
+
523
535
  ## Reel information sheet
524
536
 
525
537
  Provide an application-owned Vue component when a reel should offer a
@@ -584,6 +596,11 @@ reel still updates this requested state; the sheet becomes visible when a valid
584
596
  reel context exists. This preserves the existing persistent sheet-state
585
597
  behavior across masonry viewer closes.
586
598
 
599
+ When a sheet contains another Vibe instance, Escape is owned by the topmost
600
+ active reel. A nested masonry-origin reel therefore closes back to its nested
601
+ feed without also closing the parent sheet or reel. Single-instance Escape
602
+ behavior is unchanged.
603
+
587
604
  ## Custom feed footer
588
605
 
589
606
  Set `feedFooter.component` to replace the built-in `GalleryFooter`. Consumers
@@ -692,6 +709,7 @@ vibe.nextReelMediaItem()
692
709
  vibe.previousReelMediaItem()
693
710
  vibe.nextReelPost()
694
711
  vibe.previousReelPost()
712
+ vibe.navigateToReelItem({ postId: 'post-42', mediaId: 'asset-101' })
695
713
  vibe.setAutoScroll(true, 80)
696
714
  vibe.pauseAutoScroll()
697
715
  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, 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>;
@@ -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 {};
@@ -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,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;