@vinaverse/react-native 0.1.0-alpha.6 → 0.1.0-alpha.8

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 (47) hide show
  1. package/README.md +36 -17
  2. package/dist/ask.cjs +9 -5
  3. package/dist/ask.d.cts +16 -3
  4. package/dist/ask.d.ts +16 -3
  5. package/dist/ask.js +3 -3
  6. package/dist/chat.cjs +76 -73
  7. package/dist/chat.d.cts +31 -8
  8. package/dist/chat.d.ts +31 -8
  9. package/dist/chat.js +2 -3
  10. package/dist/{chunk-OWUKWVEZ.cjs → chunk-6QYDPGRS.cjs} +46 -2
  11. package/dist/chunk-6QYDPGRS.cjs.map +1 -0
  12. package/dist/{chunk-Y7P7DDHD.js → chunk-7KPCO443.js} +13 -12
  13. package/dist/chunk-7KPCO443.js.map +1 -0
  14. package/dist/chunk-EFEXTVIT.js +88 -0
  15. package/dist/chunk-EFEXTVIT.js.map +1 -0
  16. package/dist/{chunk-H2Y2YW2Q.cjs → chunk-EXN5TNLU.cjs} +85 -80
  17. package/dist/chunk-EXN5TNLU.cjs.map +1 -0
  18. package/dist/{chunk-OGPMGGYS.cjs → chunk-MG32E4JI.cjs} +20 -13
  19. package/dist/chunk-MG32E4JI.cjs.map +1 -0
  20. package/dist/{chunk-643GOUTG.cjs → chunk-NMKJ7LIJ.cjs} +14 -13
  21. package/dist/chunk-NMKJ7LIJ.cjs.map +1 -0
  22. package/dist/{chunk-SF6LJTVJ.js → chunk-NXGLI4Y7.js} +39 -38
  23. package/dist/chunk-NXGLI4Y7.js.map +1 -0
  24. package/dist/{chunk-NJWRZ55G.js → chunk-POJP52GE.js} +16 -9
  25. package/dist/chunk-POJP52GE.js.map +1 -0
  26. package/dist/index.cjs +86 -83
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +4 -5
  30. package/dist/launcher.cjs +14 -11
  31. package/dist/launcher.d.cts +4 -3
  32. package/dist/launcher.d.ts +4 -3
  33. package/dist/launcher.js +3 -4
  34. package/package.json +22 -5
  35. package/dist/chunk-643GOUTG.cjs.map +0 -1
  36. package/dist/chunk-H2Y2YW2Q.cjs.map +0 -1
  37. package/dist/chunk-NJWRZ55G.js.map +0 -1
  38. package/dist/chunk-OGPMGGYS.cjs.map +0 -1
  39. package/dist/chunk-OWUKWVEZ.cjs.map +0 -1
  40. package/dist/chunk-PRXHS57U.js +0 -40
  41. package/dist/chunk-PRXHS57U.js.map +0 -1
  42. package/dist/chunk-PYPO6F7L.cjs +0 -44
  43. package/dist/chunk-PYPO6F7L.cjs.map +0 -1
  44. package/dist/chunk-SF6LJTVJ.js.map +0 -1
  45. package/dist/chunk-WKRCCPSN.js +0 -48
  46. package/dist/chunk-WKRCCPSN.js.map +0 -1
  47. package/dist/chunk-Y7P7DDHD.js.map +0 -1
package/dist/chat.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- export { AgentRuntimeProvider, GreetingStorage, UseAgentConversation, UseAgentLauncher, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
1
+ export { AgentRuntimeProvider, GreetingStorage, UseAgentConversation, UseAgentLauncher, forgetGreeting, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
2
2
  import * as react from 'react';
3
3
  import { ComponentType, ReactElement, ReactNode, RefObject } from 'react';
4
4
  import * as _vinaverse_client_conversation from '@vinaverse/client/conversation';
5
5
  import { MessageItem, Welcome as Welcome$1, TimelineItem, CardItem, HeldCard, Question, ProposalOutcome, ConversationStore, SystemItem } from '@vinaverse/client/conversation';
6
- import { ReadCard, AgentCardTarget, AgentKey, AgentPlace, AgentFailureReason, AgentRating } from '@vinaverse/client/agent';
6
+ import { ReadCard, AgentCardTarget, AgentKey, AgentPlace, AgentEntryPoint, AgentFailureReason, AgentRating } from '@vinaverse/client/agent';
7
7
  import { ImageProps, StyleProp, ViewStyle } from 'react-native';
8
8
  import { CopyOverrides } from '@vinaverse/react';
9
9
  import { a as ThemeOverrides, C as ColorSchemeSetting } from './theme-BhiEGv64.cjs';
@@ -142,6 +142,10 @@ declare const ActivityLine: react.NamedExoticComponent<object>;
142
142
 
143
143
  type ProposalDecision = 'confirm' | 'decline';
144
144
  /** What the kit asks of the tenant's app. Only `onProposal` and `onOpenLink` are needed for the cards that use them. */
145
+ /** What a chat warning is about. */
146
+ interface ChatWarning {
147
+ readonly code: 'theme' | 'copy' | 'send_failed' | 'answer_failed' | 'proposal_failed' | 'photo_failed';
148
+ }
145
149
  interface ChatHandlers {
146
150
  /**
147
151
  * The person confirmed or declined a proposal: call your backend with the person's own token, then say what
@@ -164,8 +168,11 @@ interface ChatHandlers {
164
168
  * drawn by the kit's own parts when no `components.Error` or `components.Unavailable` replaces them.
165
169
  */
166
170
  readonly failureAction?: FailureAction;
167
- /** Development warnings: a theme that is hard to read, copy that says "assistant". */
168
- readonly onWarning?: (message: string) => void;
171
+ /**
172
+ * Warnings for the app's logger: a theme that is hard to read, copy that says "assistant", a send, an answer, a
173
+ * proposal or a photo pick that failed. `warning.code` says which, so a logger counts them without the text.
174
+ */
175
+ readonly onWarning?: (message: string, warning: ChatWarning) => void;
169
176
  /**
170
177
  * The person tapped a card about something of yours (its `ref`: a professional, a space, a booking): open its page
171
178
  * with your router. Without it, only the card's own actions open anything.
@@ -184,9 +191,13 @@ interface ImagePolicy {
184
191
  readonly hosts?: readonly string[];
185
192
  /** Width / height of a listing's photo frame. Default 1.6 (16:10). */
186
193
  readonly aspectRatio?: number;
187
- /** What stands in for a missing, refused or failed photo. Default the name's monogram. */
194
+ /**
195
+ * What stands in for a missing, refused or failed photo, by the card's `kind` (a person's tile, a space's tile).
196
+ * Default the name's monogram.
197
+ */
188
198
  readonly Placeholder?: ComponentType<{
189
199
  readonly title: string;
200
+ readonly kind: string;
190
201
  }>;
191
202
  }
192
203
  /** Parts a tenant can replace. Each gets the default's props and the default itself (`Default`), to wrap it. */
@@ -269,10 +280,19 @@ declare function VinaverseChatProvider(props: Omit<VinaverseChatProps, 'hideHead
269
280
  }): ReactNode;
270
281
  declare function VinaverseChat(props: VinaverseChatProps): ReactNode;
271
282
 
283
+ /**
284
+ * The full-screen states (`Ended`, `Unreachable`, `UnavailableScreen`) are slots: each gets everything its screen
285
+ * needs (why, the actions, a person to contact) and the kit's own part as `Default`, so an app replaces the layout and
286
+ * the words entirely, or only the words through `copy`.
287
+ */
272
288
  interface AgentEndedProps {
273
289
  readonly onStartNew: () => void;
290
+ /** Why: `ended`, `not_found`, `expired`, `mismatch`, `completed`. */
291
+ readonly reason: AgentFailureReason | null;
274
292
  /** The API's code (`conversation_not_found`, `conversation_expired`), when it gave one. */
275
293
  readonly code: string | null;
294
+ /** A person instead (the chat's `onContact`); absent when the app gave none. */
295
+ readonly onContact: (() => void) | undefined;
276
296
  }
277
297
  /** No agent here: switched off for this tenant, mode or person, or the backend refused the session. */
278
298
  interface AgentUnavailableScreenProps {
@@ -288,13 +308,15 @@ interface AgentUnreachableProps {
288
308
  readonly onRetry: () => void;
289
309
  /** Why: `network`, `server`, `rate_limited`, … */
290
310
  readonly reason: AgentFailureReason | null;
311
+ /** A person instead (the chat's `onContact`); absent when the app gave none. */
312
+ readonly onContact: (() => void) | undefined;
291
313
  }
292
314
  /** A slot gets the kit's own part as `Default`, to wrap rather than rewrite. */
293
315
  type Slot<P> = ComponentType<P & {
294
316
  readonly Default: ComponentType<P>;
295
317
  }>;
296
318
  interface AgentFooterProps {
297
- /** The newest whole reply's turn, to rate; null when there is none. */
319
+ /** The newest whole reply's turn, to rate; null when there is none or it was restored from before. */
298
320
  readonly turnId: string | null;
299
321
  readonly rating: AgentRating | undefined;
300
322
  readonly onRate: (rating: AgentRating) => void;
@@ -316,7 +338,8 @@ interface AgentChatProps extends Omit<VinaverseChatProps, 'conversation' | 'comp
316
338
  readonly agentKey: AgentKey;
317
339
  /** Where the person asks from, told to the agent as a session opens. */
318
340
  readonly place?: AgentPlace | null;
319
- readonly entryPoint?: string | null;
341
+ /** How the person came in: `launcher` and `ask` from the kit's parts, `deep_link`, or the app's own words. */
342
+ readonly entryPoint?: AgentEntryPoint | null;
320
343
  /** The question about this place, offered when the session was told another one (`moved`). */
321
344
  readonly askAbout?: string | null;
322
345
  /** A person: offered on a failed turn, "couldn't connect" and no agent. */
@@ -446,4 +469,4 @@ declare function useReducedMotion(): boolean;
446
469
  /** Reads a line to a screen reader, without moving focus. */
447
470
  declare function announce(text: string): void;
448
471
 
449
- export { ActivityLine, AgentChat, type AgentChatProps, type AgentChatSlots, type AgentEndedProps, AgentFooter, type AgentFooterProps, type AgentUnavailableScreenProps, type AgentUnreachableProps, Avatar, Button, type ButtonProps, CardActions, CardCarousel, CardFrame, type CardGroupProps, type CardProps, CardView, type ChatHandlers, ChatHeader, ChatSkeleton, type ChatSlots, type Chip, ColorSchemeSetting, Composer, type ComposerProps, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, type EmptyStateProps, type FailureAction, FailureActionButton, type FailureProps, type FailureState, type HeaderProps, type ImagePolicy, InfoCard, type LifecycleTarget, LinksCard, type ListProps, ListingCard, MessageBubble, type MessageBubbleProps, MessageList, NextStepCard, ProposalCard, type ProposalDecision, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeOverrides, TimeSlotsCard, VinaverseChat, type VinaverseChatProps, VinaverseChatProvider, Welcome, allowedImage, announce, answerText, carousels, defaultCard, fieldText, itemType, monogram, newestWholeReply, ratingText, useChat, useNativeLifecycle, useReducedMotion };
472
+ export { ActivityLine, AgentChat, type AgentChatProps, type AgentChatSlots, type AgentEndedProps, AgentFooter, type AgentFooterProps, type AgentUnavailableScreenProps, type AgentUnreachableProps, Avatar, Button, type ButtonProps, CardActions, CardCarousel, CardFrame, type CardGroupProps, type CardProps, CardView, type ChatHandlers, ChatHeader, ChatSkeleton, type ChatSlots, type ChatWarning, type Chip, ColorSchemeSetting, Composer, type ComposerProps, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, type EmptyStateProps, type FailureAction, FailureActionButton, type FailureProps, type FailureState, type HeaderProps, type ImagePolicy, InfoCard, type LifecycleTarget, LinksCard, type ListProps, ListingCard, MessageBubble, type MessageBubbleProps, MessageList, NextStepCard, ProposalCard, type ProposalDecision, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeOverrides, TimeSlotsCard, VinaverseChat, type VinaverseChatProps, VinaverseChatProvider, Welcome, allowedImage, announce, answerText, carousels, defaultCard, fieldText, itemType, monogram, newestWholeReply, ratingText, useChat, useNativeLifecycle, useReducedMotion };
package/dist/chat.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- export { AgentRuntimeProvider, GreetingStorage, UseAgentConversation, UseAgentLauncher, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
1
+ export { AgentRuntimeProvider, GreetingStorage, UseAgentConversation, UseAgentLauncher, forgetGreeting, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
2
2
  import * as react from 'react';
3
3
  import { ComponentType, ReactElement, ReactNode, RefObject } from 'react';
4
4
  import * as _vinaverse_client_conversation from '@vinaverse/client/conversation';
5
5
  import { MessageItem, Welcome as Welcome$1, TimelineItem, CardItem, HeldCard, Question, ProposalOutcome, ConversationStore, SystemItem } from '@vinaverse/client/conversation';
6
- import { ReadCard, AgentCardTarget, AgentKey, AgentPlace, AgentFailureReason, AgentRating } from '@vinaverse/client/agent';
6
+ import { ReadCard, AgentCardTarget, AgentKey, AgentPlace, AgentEntryPoint, AgentFailureReason, AgentRating } from '@vinaverse/client/agent';
7
7
  import { ImageProps, StyleProp, ViewStyle } from 'react-native';
8
8
  import { CopyOverrides } from '@vinaverse/react';
9
9
  import { a as ThemeOverrides, C as ColorSchemeSetting } from './theme-BhiEGv64.js';
@@ -142,6 +142,10 @@ declare const ActivityLine: react.NamedExoticComponent<object>;
142
142
 
143
143
  type ProposalDecision = 'confirm' | 'decline';
144
144
  /** What the kit asks of the tenant's app. Only `onProposal` and `onOpenLink` are needed for the cards that use them. */
145
+ /** What a chat warning is about. */
146
+ interface ChatWarning {
147
+ readonly code: 'theme' | 'copy' | 'send_failed' | 'answer_failed' | 'proposal_failed' | 'photo_failed';
148
+ }
145
149
  interface ChatHandlers {
146
150
  /**
147
151
  * The person confirmed or declined a proposal: call your backend with the person's own token, then say what
@@ -164,8 +168,11 @@ interface ChatHandlers {
164
168
  * drawn by the kit's own parts when no `components.Error` or `components.Unavailable` replaces them.
165
169
  */
166
170
  readonly failureAction?: FailureAction;
167
- /** Development warnings: a theme that is hard to read, copy that says "assistant". */
168
- readonly onWarning?: (message: string) => void;
171
+ /**
172
+ * Warnings for the app's logger: a theme that is hard to read, copy that says "assistant", a send, an answer, a
173
+ * proposal or a photo pick that failed. `warning.code` says which, so a logger counts them without the text.
174
+ */
175
+ readonly onWarning?: (message: string, warning: ChatWarning) => void;
169
176
  /**
170
177
  * The person tapped a card about something of yours (its `ref`: a professional, a space, a booking): open its page
171
178
  * with your router. Without it, only the card's own actions open anything.
@@ -184,9 +191,13 @@ interface ImagePolicy {
184
191
  readonly hosts?: readonly string[];
185
192
  /** Width / height of a listing's photo frame. Default 1.6 (16:10). */
186
193
  readonly aspectRatio?: number;
187
- /** What stands in for a missing, refused or failed photo. Default the name's monogram. */
194
+ /**
195
+ * What stands in for a missing, refused or failed photo, by the card's `kind` (a person's tile, a space's tile).
196
+ * Default the name's monogram.
197
+ */
188
198
  readonly Placeholder?: ComponentType<{
189
199
  readonly title: string;
200
+ readonly kind: string;
190
201
  }>;
191
202
  }
192
203
  /** Parts a tenant can replace. Each gets the default's props and the default itself (`Default`), to wrap it. */
@@ -269,10 +280,19 @@ declare function VinaverseChatProvider(props: Omit<VinaverseChatProps, 'hideHead
269
280
  }): ReactNode;
270
281
  declare function VinaverseChat(props: VinaverseChatProps): ReactNode;
271
282
 
283
+ /**
284
+ * The full-screen states (`Ended`, `Unreachable`, `UnavailableScreen`) are slots: each gets everything its screen
285
+ * needs (why, the actions, a person to contact) and the kit's own part as `Default`, so an app replaces the layout and
286
+ * the words entirely, or only the words through `copy`.
287
+ */
272
288
  interface AgentEndedProps {
273
289
  readonly onStartNew: () => void;
290
+ /** Why: `ended`, `not_found`, `expired`, `mismatch`, `completed`. */
291
+ readonly reason: AgentFailureReason | null;
274
292
  /** The API's code (`conversation_not_found`, `conversation_expired`), when it gave one. */
275
293
  readonly code: string | null;
294
+ /** A person instead (the chat's `onContact`); absent when the app gave none. */
295
+ readonly onContact: (() => void) | undefined;
276
296
  }
277
297
  /** No agent here: switched off for this tenant, mode or person, or the backend refused the session. */
278
298
  interface AgentUnavailableScreenProps {
@@ -288,13 +308,15 @@ interface AgentUnreachableProps {
288
308
  readonly onRetry: () => void;
289
309
  /** Why: `network`, `server`, `rate_limited`, … */
290
310
  readonly reason: AgentFailureReason | null;
311
+ /** A person instead (the chat's `onContact`); absent when the app gave none. */
312
+ readonly onContact: (() => void) | undefined;
291
313
  }
292
314
  /** A slot gets the kit's own part as `Default`, to wrap rather than rewrite. */
293
315
  type Slot<P> = ComponentType<P & {
294
316
  readonly Default: ComponentType<P>;
295
317
  }>;
296
318
  interface AgentFooterProps {
297
- /** The newest whole reply's turn, to rate; null when there is none. */
319
+ /** The newest whole reply's turn, to rate; null when there is none or it was restored from before. */
298
320
  readonly turnId: string | null;
299
321
  readonly rating: AgentRating | undefined;
300
322
  readonly onRate: (rating: AgentRating) => void;
@@ -316,7 +338,8 @@ interface AgentChatProps extends Omit<VinaverseChatProps, 'conversation' | 'comp
316
338
  readonly agentKey: AgentKey;
317
339
  /** Where the person asks from, told to the agent as a session opens. */
318
340
  readonly place?: AgentPlace | null;
319
- readonly entryPoint?: string | null;
341
+ /** How the person came in: `launcher` and `ask` from the kit's parts, `deep_link`, or the app's own words. */
342
+ readonly entryPoint?: AgentEntryPoint | null;
320
343
  /** The question about this place, offered when the session was told another one (`moved`). */
321
344
  readonly askAbout?: string | null;
322
345
  /** A person: offered on a failed turn, "couldn't connect" and no agent. */
@@ -446,4 +469,4 @@ declare function useReducedMotion(): boolean;
446
469
  /** Reads a line to a screen reader, without moving focus. */
447
470
  declare function announce(text: string): void;
448
471
 
449
- export { ActivityLine, AgentChat, type AgentChatProps, type AgentChatSlots, type AgentEndedProps, AgentFooter, type AgentFooterProps, type AgentUnavailableScreenProps, type AgentUnreachableProps, Avatar, Button, type ButtonProps, CardActions, CardCarousel, CardFrame, type CardGroupProps, type CardProps, CardView, type ChatHandlers, ChatHeader, ChatSkeleton, type ChatSlots, type Chip, ColorSchemeSetting, Composer, type ComposerProps, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, type EmptyStateProps, type FailureAction, FailureActionButton, type FailureProps, type FailureState, type HeaderProps, type ImagePolicy, InfoCard, type LifecycleTarget, LinksCard, type ListProps, ListingCard, MessageBubble, type MessageBubbleProps, MessageList, NextStepCard, ProposalCard, type ProposalDecision, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeOverrides, TimeSlotsCard, VinaverseChat, type VinaverseChatProps, VinaverseChatProvider, Welcome, allowedImage, announce, answerText, carousels, defaultCard, fieldText, itemType, monogram, newestWholeReply, ratingText, useChat, useNativeLifecycle, useReducedMotion };
472
+ export { ActivityLine, AgentChat, type AgentChatProps, type AgentChatSlots, type AgentEndedProps, AgentFooter, type AgentFooterProps, type AgentUnavailableScreenProps, type AgentUnreachableProps, Avatar, Button, type ButtonProps, CardActions, CardCarousel, CardFrame, type CardGroupProps, type CardProps, CardView, type ChatHandlers, ChatHeader, ChatSkeleton, type ChatSlots, type ChatWarning, type Chip, ColorSchemeSetting, Composer, type ComposerProps, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, type EmptyStateProps, type FailureAction, FailureActionButton, type FailureProps, type FailureState, type HeaderProps, type ImagePolicy, InfoCard, type LifecycleTarget, LinksCard, type ListProps, ListingCard, MessageBubble, type MessageBubbleProps, MessageList, NextStepCard, ProposalCard, type ProposalDecision, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeOverrides, TimeSlotsCard, VinaverseChat, type VinaverseChatProps, VinaverseChatProvider, Welcome, allowedImage, announce, answerText, carousels, defaultCard, fieldText, itemType, monogram, newestWholeReply, ratingText, useChat, useNativeLifecycle, useReducedMotion };
package/dist/chat.js CHANGED
@@ -1,5 +1,4 @@
1
- export { ActivityLine, AgentChat, AgentFooter, AgentRuntimeProvider, Avatar, Button, CardActions, CardCarousel, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, FailureActionButton, InfoCard, LinksCard, ListingCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, Welcome, allowedImage, answerText, carousels, defaultCard, fieldText, greetedKey, itemType, monogram, newestWholeReply, ratingText, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus, useChat } from './chunk-SF6LJTVJ.js';
2
- export { announce, useNativeLifecycle, useReducedMotion } from './chunk-PRXHS57U.js';
3
- export { ThemeProvider, createTheme, themeProblems, useTheme } from './chunk-WKRCCPSN.js';
1
+ export { ActivityLine, AgentChat, AgentFooter, AgentRuntimeProvider, Avatar, Button, CardActions, CardCarousel, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, FailureActionButton, InfoCard, LinksCard, ListingCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, Welcome, allowedImage, answerText, carousels, defaultCard, fieldText, forgetGreeting, greetedKey, itemType, monogram, newestWholeReply, ratingText, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus, useChat } from './chunk-NXGLI4Y7.js';
2
+ export { ThemeProvider, announce, createTheme, themeProblems, useNativeLifecycle, useReducedMotion, useTheme } from './chunk-EFEXTVIT.js';
4
3
  //# sourceMappingURL=chat.js.map
5
4
  //# sourceMappingURL=chat.js.map
@@ -44,10 +44,54 @@ function ThemeProvider(props) {
44
44
  function useTheme() {
45
45
  return react.useContext(ThemeContext);
46
46
  }
47
+ function useAgentSweep(runtime) {
48
+ react.useEffect(() => {
49
+ const subscription = reactNative.AppState.addEventListener("change", (state) => {
50
+ if (state === "active") runtime.sweep();
51
+ });
52
+ return () => subscription.remove();
53
+ }, [runtime]);
54
+ }
55
+ function useNativeLifecycle(store) {
56
+ react.useEffect(() => {
57
+ const apply = (state) => store.setForeground(state === "active");
58
+ apply(reactNative.AppState.currentState);
59
+ const subscription = reactNative.AppState.addEventListener("change", apply);
60
+ return () => subscription.remove();
61
+ }, [store]);
62
+ }
63
+ function useReducedMotion() {
64
+ const [reduced, setReduced] = react.useState(false);
65
+ react.useEffect(() => {
66
+ let live = true;
67
+ reactNative.AccessibilityInfo.isReduceMotionEnabled().then(
68
+ (value) => {
69
+ if (live) setReduced(value);
70
+ },
71
+ () => void 0
72
+ );
73
+ const subscription = reactNative.AccessibilityInfo.addEventListener(
74
+ "reduceMotionChanged",
75
+ setReduced
76
+ );
77
+ return () => {
78
+ live = false;
79
+ subscription.remove();
80
+ };
81
+ }, []);
82
+ return reduced;
83
+ }
84
+ function announce(text) {
85
+ if (text) reactNative.AccessibilityInfo.announceForAccessibility(text);
86
+ }
47
87
 
48
88
  exports.ThemeProvider = ThemeProvider;
89
+ exports.announce = announce;
49
90
  exports.createTheme = createTheme;
50
91
  exports.themeProblems = themeProblems;
92
+ exports.useAgentSweep = useAgentSweep;
93
+ exports.useNativeLifecycle = useNativeLifecycle;
94
+ exports.useReducedMotion = useReducedMotion;
51
95
  exports.useTheme = useTheme;
52
- //# sourceMappingURL=chunk-OWUKWVEZ.cjs.map
53
- //# sourceMappingURL=chunk-OWUKWVEZ.cjs.map
96
+ //# sourceMappingURL=chunk-6QYDPGRS.cjs.map
97
+ //# sourceMappingURL=chunk-6QYDPGRS.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme.tsx","../src/platform.ts"],"names":["colors","font","space","radius","motion","size","contrastProblems","createContext","useColorScheme","useMemo","useContext","useEffect","AppState","useState","AccessibilityInfo"],"mappings":"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","file":"chunk-6QYDPGRS.cjs","sourcesContent":["// The theme: the shared design tokens, a tenant's brand on top, light and dark. A tenant changes colors, fonts, radii\n// and spacing; the disclosure bar keeps a legible pair whatever the tenant's colors (see DisclosureBar).\nimport {\n type ColorScheme,\n type Colors,\n colors,\n contrastProblems,\n font,\n motion,\n radius,\n size,\n space,\n} from '@vinaverse/tokens';\nimport { createContext, type ReactNode, useContext, useMemo } from 'react';\nimport { useColorScheme } from 'react-native';\n\nexport interface Theme {\n readonly scheme: ColorScheme;\n readonly colors: Colors;\n readonly font: typeof font & { readonly family?: string };\n readonly space: typeof space;\n readonly radius: typeof radius;\n readonly motion: typeof motion;\n readonly size: typeof size;\n}\n\n/** A tenant's brand: colors per scheme, a font family, radii. Anything left out keeps the Vinaverse default. */\nexport interface ThemeOverrides {\n readonly light?: Partial<Colors>;\n readonly dark?: Partial<Colors>;\n readonly fontFamily?: string;\n readonly radius?: Partial<typeof radius>;\n readonly space?: Partial<typeof space>;\n}\n\nexport type ColorSchemeSetting = 'system' | 'light' | 'dark';\n\n/** The theme for a scheme, with the tenant's overrides on top. */\nexport function createTheme(\n scheme: ColorScheme,\n overrides: ThemeOverrides = {},\n): Theme {\n return {\n scheme,\n colors: { ...colors(scheme), ...overrides[scheme] },\n font: {\n ...font,\n ...(overrides.fontFamily ? { family: overrides.fontFamily } : {}),\n },\n space: { ...space, ...overrides.space },\n radius: { ...radius, ...overrides.radius },\n motion,\n size,\n };\n}\n\n/** The pairs a tenant's colors made hard to read, in either scheme, as messages for a development warning. */\nexport function themeProblems(overrides: ThemeOverrides = {}): string[] {\n return (['light', 'dark'] as const).flatMap((scheme) =>\n contrastProblems(createTheme(scheme, overrides).colors).map(\n (p) =>\n `${scheme}: ${p.foreground} on ${p.background} is ${p.ratio.toFixed(2)}:1, below ${p.minimum}:1`,\n ),\n );\n}\n\nconst ThemeContext = /* @__PURE__ */ createContext<Theme>(\n /* @__PURE__ */ createTheme('light'),\n);\n\nexport function ThemeProvider(props: {\n readonly theme?: ThemeOverrides | undefined;\n readonly colorScheme?: ColorSchemeSetting | undefined;\n readonly children?: ReactNode;\n}): ReactNode {\n const system = useColorScheme();\n const setting = props.colorScheme ?? 'system';\n const scheme: ColorScheme =\n setting === 'system' ? (system === 'dark' ? 'dark' : 'light') : setting;\n const overrides = props.theme;\n const value = useMemo(\n () => createTheme(scheme, overrides),\n [scheme, overrides],\n );\n return (\n <ThemeContext.Provider value={value}>\n {props.children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme(): Theme {\n return useContext(ThemeContext);\n}\n","// The React Native platform adapter: what the conversation store learns from the app (foreground, background) and\n// what the kit asks of the platform (reduced motion, screen reader announcements).\nimport { useEffect, useState } from 'react';\nimport { AccessibilityInfo, AppState, type AppStateStatus } from 'react-native';\n\n/** The part of the conversation store the adapter drives. */\nexport interface LifecycleTarget {\n setForeground(foreground: boolean): void;\n}\n\n/**\n * When the app comes back to the foreground, the agent runtime ends the conversations no view shows that are past\n * their session's end (timers do not run in the background). Every agent part calls it; once is enough.\n */\nexport function useAgentSweep(runtime: { sweep(): void }): void {\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n if (state === 'active') runtime.sweep();\n });\n return () => subscription.remove();\n }, [runtime]);\n}\n\n/** Tells the store when the app comes to the foreground or goes to the background (it pings only in the foreground). */\nexport function useNativeLifecycle(store: LifecycleTarget): void {\n useEffect(() => {\n const apply = (state: AppStateStatus) =>\n store.setForeground(state === 'active');\n apply(AppState.currentState);\n const subscription = AppState.addEventListener('change', apply);\n return () => subscription.remove();\n }, [store]);\n}\n\n/** Whether the person asked for reduced motion: animations and animated scrolling stay off. */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n let live = true;\n AccessibilityInfo.isReduceMotionEnabled().then(\n (value) => {\n if (live) setReduced(value);\n },\n () => undefined,\n );\n const subscription = AccessibilityInfo.addEventListener(\n 'reduceMotionChanged',\n setReduced,\n );\n return () => {\n live = false;\n subscription.remove();\n };\n }, []);\n return reduced;\n}\n\n/** Reads a line to a screen reader, without moving focus. */\nexport function announce(text: string): void {\n if (text) AccessibilityInfo.announceForAccessibility(text);\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { ThemeProvider, useTheme } from './chunk-WKRCCPSN.js';
1
+ import { ThemeProvider, useTheme, useAgentSweep } from './chunk-EFEXTVIT.js';
2
2
  import { CopyProvider, useCopy } from '@vinaverse/react';
3
- import { useAgentName, useAgentFeatures } from '@vinaverse/react/agent';
3
+ import { useAgentName, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
4
4
  import { useState } from 'react';
5
5
  import { Pressable, View, Text } from 'react-native';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -12,27 +12,28 @@ function Row(props) {
12
12
  const { t } = useCopy();
13
13
  const { colors, radius, space, font } = useTheme();
14
14
  const name = useAgentName(t("agentFallbackName"));
15
- const { available } = useAgentFeatures();
16
- const [shows, setShows] = useState(null);
17
- if (shows === null && available) setShows(true);
15
+ const runtime = useAgentRuntime();
16
+ useAgentStatus();
17
+ useAgentSweep(runtime);
18
+ const [shows] = useState(() => !!runtime.getStatus()?.available);
18
19
  if (!shows) return null;
19
- const { Mark } = props;
20
+ const { Mark, appearance: look } = props;
20
21
  return /* @__PURE__ */ jsxs(
21
22
  Pressable,
22
23
  {
23
24
  accessibilityRole: "button",
24
25
  accessibilityLabel: props.body ? `${props.title}. ${props.body}` : props.title,
25
- onPress: props.onPress,
26
+ onPress: () => props.onPress({ entryPoint: "ask" }),
26
27
  style: ({ pressed }) => ({
27
28
  flexDirection: "row",
28
29
  alignItems: "center",
29
30
  gap: space.md,
30
31
  padding: space.md,
31
32
  borderRadius: radius.lg,
32
- backgroundColor: colors.surface,
33
+ backgroundColor: look?.background ?? colors.surface,
33
34
  opacity: pressed ? 0.85 : 1
34
35
  }),
35
- testID: "vinaverse-ask-about",
36
+ testID: props.testID ?? "vinaverse-ask-about",
36
37
  children: [
37
38
  /* @__PURE__ */ jsx(
38
39
  View,
@@ -62,12 +63,12 @@ function Row(props) {
62
63
  ),
63
64
  props.body ? /* @__PURE__ */ jsx(Text, { style: { color: colors.textMuted, fontSize: font.size.sm }, children: props.body }) : null
64
65
  ] }),
65
- /* @__PURE__ */ jsx(Text, { style: { color: colors.textMuted, fontSize: font.size.lg }, children: "\u203A" })
66
+ look?.chevron === false ? null : /* @__PURE__ */ jsx(Text, { style: { color: colors.textMuted, fontSize: font.size.lg }, children: "\u203A" })
66
67
  ]
67
68
  }
68
69
  );
69
70
  }
70
71
 
71
72
  export { AskAboutRow };
72
- //# sourceMappingURL=chunk-Y7P7DDHD.js.map
73
- //# sourceMappingURL=chunk-Y7P7DDHD.js.map
73
+ //# sourceMappingURL=chunk-7KPCO443.js.map
74
+ //# sourceMappingURL=chunk-7KPCO443.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AskAboutRow.tsx"],"names":[],"mappings":";;;;;;;AA+CO,SAAS,YAAY,KAAA,EAAoC;AAC9D,EAAA,uBACE,GAAA,CAAC,gBAAa,MAAA,EAAQ,KAAA,CAAM,QAAQ,IAAA,EAAM,KAAA,CAAM,MAC9C,QAAA,kBAAA,GAAA,CAAC,aAAA,EAAA,EAAc,OAAO,KAAA,CAAM,KAAA,EAAO,aAAa,KAAA,CAAM,WAAA,EACpD,8BAAC,GAAA,EAAA,EAAK,GAAG,KAAA,EAAO,CAAA,EAClB,CAAA,EACF,CAAA;AAEJ;AAEA,SAAS,IAAI,KAAA,EAAoC;AAC/C,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,OAAA,EAAQ;AACtB,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,IAAA,KAAS,QAAA,EAAS;AACjD,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,CAAA,CAAE,mBAAmB,CAAC,CAAA;AAChD,EAAA,MAAM,UAAU,eAAA,EAAgB;AAChC,EAAA,cAAA,EAAe;AACf,EAAA,aAAA,CAAc,OAAO,CAAA;AAGrB,EAAA,MAAM,CAAC,KAAK,CAAA,GAAI,QAAA,CAAS,MAAM,CAAC,CAAC,OAAA,CAAQ,SAAA,EAAU,EAAG,SAAS,CAAA;AAC/D,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAK,GAAI,KAAA;AACnC,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,iBAAA,EAAkB,QAAA;AAAA,MAClB,kBAAA,EACE,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,IAAI,CAAA,CAAA,GAAK,KAAA,CAAM,KAAA;AAAA,MAEvD,SAAS,MAAM,KAAA,CAAM,QAAQ,EAAE,UAAA,EAAY,OAAO,CAAA;AAAA,MAClD,KAAA,EAAO,CAAC,EAAE,OAAA,EAAQ,MAAO;AAAA,QACvB,aAAA,EAAe,KAAA;AAAA,QACf,UAAA,EAAY,QAAA;AAAA,QACZ,KAAK,KAAA,CAAM,EAAA;AAAA,QACX,SAAS,KAAA,CAAM,EAAA;AAAA,QACf,cAAc,MAAA,CAAO,EAAA;AAAA,QACrB,eAAA,EAAiB,IAAA,EAAM,UAAA,IAAc,MAAA,CAAO,OAAA;AAAA,QAC5C,OAAA,EAAS,UAAU,IAAA,GAAO;AAAA,OAC5B,CAAA;AAAA,MACA,MAAA,EAAQ,MAAM,MAAA,IAAU,qBAAA;AAAA,MAExB,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO;AAAA,cACL,KAAA,EAAO,EAAA;AAAA,cACP,MAAA,EAAQ,EAAA;AAAA,cACR,YAAA,EAAc,EAAA;AAAA,cACd,UAAA,EAAY,QAAA;AAAA,cACZ,cAAA,EAAgB,QAAA;AAAA,cAChB,iBAAiB,MAAA,CAAO;AAAA,aAC1B;AAAA,YAEC,QAAA,EAAA,IAAA,mBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,MAAA,CAAO,SAAA,EAAW,CAAA,mBAEzC,GAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAO,EAAE,OAAO,MAAA,CAAO,SAAA,EAAW,UAAA,EAAY,KAAA,EAAM,EACtD,QAAA,EAAA,CAAA,IAAA,CAAK,IAAA,EAAK,CAAE,CAAC,CAAA,IAAK,GAAA,EAAK,WAAA,EAAY,EACvC;AAAA;AAAA,SAEJ;AAAA,wBACA,IAAA,CAAC,QAAK,KAAA,EAAO,EAAE,MAAM,CAAA,EAAG,GAAA,EAAK,KAAA,CAAM,GAAA,EAAI,EACrC,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO;AAAA,gBACL,OAAO,MAAA,CAAO,IAAA;AAAA,gBACd,QAAA,EAAU,KAAK,IAAA,CAAK,EAAA;AAAA,gBACpB,UAAA,EAAY;AAAA,eACd;AAAA,cAEC,QAAA,EAAA,KAAA,CAAM;AAAA;AAAA,WACT;AAAA,UACC,MAAM,IAAA,mBACL,GAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,CAAO,SAAA,EAAW,QAAA,EAAU,KAAK,IAAA,CAAK,EAAA,EAAG,EAC5D,QAAA,EAAA,KAAA,CAAM,MACT,CAAA,GACE;AAAA,SAAA,EACN,CAAA;AAAA,QACC,MAAM,OAAA,KAAY,KAAA,GAAQ,IAAA,mBACzB,GAAA,CAAC,QAAK,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,CAAO,WAAW,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,EAAA,IAAM,QAAA,EAAA,QAAA,EAElE;AAAA;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-7KPCO443.js","sourcesContent":["// \"Ask the agent about this\" on one of the app's own pages (a professional's, a space's, a booking's): a row that opens\n// the agent told the place. It shows only when the agent is available, decided once as the page draws, from the status\n// already read, so it never appears or disappears under content the person is reading.\nimport { type CopyOverrides, CopyProvider, useCopy } from '@vinaverse/react';\nimport {\n useAgentName,\n useAgentRuntime,\n useAgentStatus,\n} from '@vinaverse/react/agent';\nimport { type ComponentType, type ReactNode, useState } from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { useAgentSweep } from '../platform.js';\nimport {\n type ColorSchemeSetting,\n type ThemeOverrides,\n ThemeProvider,\n useTheme,\n} from '../theme.js';\n\n/** The row's look beyond the theme. */\nexport interface AskAboutRowAppearance {\n /** A tint behind the row; default the theme's `surface`. */\n readonly background?: string;\n /** The chevron at the row's end. Default true. */\n readonly chevron?: boolean;\n}\n\nexport interface AskAboutRowProps {\n /** \"Ask Example Agent about Riley Sample\". */\n readonly title: string;\n readonly body?: string;\n /** The person asks: open the chat with `entryPoint` (`ask`), so the session says where it was opened from. */\n readonly onPress: (from: { readonly entryPoint: 'ask' }) => void;\n /** The app's brand mark at the row's start; default the agent name's first letter. */\n readonly Mark?: ComponentType<{\n readonly size: number;\n readonly color: string;\n }>;\n readonly appearance?: AskAboutRowAppearance;\n readonly locale?: string;\n readonly copy?: CopyOverrides;\n readonly theme?: ThemeOverrides;\n readonly colorScheme?: ColorSchemeSetting;\n /** The row's test id. Default `vinaverse-ask-about`. */\n readonly testID?: string;\n}\n\nexport function AskAboutRow(props: AskAboutRowProps): ReactNode {\n return (\n <CopyProvider locale={props.locale} copy={props.copy}>\n <ThemeProvider theme={props.theme} colorScheme={props.colorScheme}>\n <Row {...props} />\n </ThemeProvider>\n </CopyProvider>\n );\n}\n\nfunction Row(props: AskAboutRowProps): ReactNode {\n const { t } = useCopy();\n const { colors, radius, space, font } = useTheme();\n const name = useAgentName(t('agentFallbackName'));\n const runtime = useAgentRuntime();\n useAgentStatus(); // reads the status when none is held, for the pages after this one\n useAgentSweep(runtime);\n // Decided once, as the page draws, from the status already read: an agent unknown or unavailable then stays away for\n // the visit, and the row is never added under content the person is reading.\n const [shows] = useState(() => !!runtime.getStatus()?.available);\n if (!shows) return null;\n const { Mark, appearance: look } = props;\n return (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={\n props.body ? `${props.title}. ${props.body}` : props.title\n }\n onPress={() => props.onPress({ entryPoint: 'ask' })}\n style={({ pressed }) => ({\n flexDirection: 'row',\n alignItems: 'center',\n gap: space.md,\n padding: space.md,\n borderRadius: radius.lg,\n backgroundColor: look?.background ?? colors.surface,\n opacity: pressed ? 0.85 : 1,\n })}\n testID={props.testID ?? 'vinaverse-ask-about'}\n >\n <View\n style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.primary,\n }}\n >\n {Mark ? (\n <Mark size={22} color={colors.onPrimary} />\n ) : (\n <Text style={{ color: colors.onPrimary, fontWeight: '600' }}>\n {(name.trim()[0] ?? '?').toUpperCase()}\n </Text>\n )}\n </View>\n <View style={{ flex: 1, gap: space.xxs }}>\n <Text\n style={{\n color: colors.text,\n fontSize: font.size.md,\n fontWeight: '600',\n }}\n >\n {props.title}\n </Text>\n {props.body ? (\n <Text style={{ color: colors.textMuted, fontSize: font.size.sm }}>\n {props.body}\n </Text>\n ) : null}\n </View>\n {look?.chevron === false ? null : (\n <Text style={{ color: colors.textMuted, fontSize: font.size.lg }}>\n ›\n </Text>\n )}\n </Pressable>\n );\n}\n"]}
@@ -0,0 +1,88 @@
1
+ import { size, motion, radius, space, font, colors, contrastProblems } from '@vinaverse/tokens';
2
+ import { useMemo, useContext, useEffect, useState, createContext } from 'react';
3
+ import { useColorScheme, AppState, AccessibilityInfo } from 'react-native';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // src/theme.tsx
7
+ function createTheme(scheme, overrides = {}) {
8
+ return {
9
+ scheme,
10
+ colors: { ...colors(scheme), ...overrides[scheme] },
11
+ font: {
12
+ ...font,
13
+ ...overrides.fontFamily ? { family: overrides.fontFamily } : {}
14
+ },
15
+ space: { ...space, ...overrides.space },
16
+ radius: { ...radius, ...overrides.radius },
17
+ motion,
18
+ size
19
+ };
20
+ }
21
+ function themeProblems(overrides = {}) {
22
+ return ["light", "dark"].flatMap(
23
+ (scheme) => contrastProblems(createTheme(scheme, overrides).colors).map(
24
+ (p) => `${scheme}: ${p.foreground} on ${p.background} is ${p.ratio.toFixed(2)}:1, below ${p.minimum}:1`
25
+ )
26
+ );
27
+ }
28
+ var ThemeContext = /* @__PURE__ */ createContext(
29
+ /* @__PURE__ */ createTheme("light")
30
+ );
31
+ function ThemeProvider(props) {
32
+ const system = useColorScheme();
33
+ const setting = props.colorScheme ?? "system";
34
+ const scheme = setting === "system" ? system === "dark" ? "dark" : "light" : setting;
35
+ const overrides = props.theme;
36
+ const value = useMemo(
37
+ () => createTheme(scheme, overrides),
38
+ [scheme, overrides]
39
+ );
40
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children: props.children });
41
+ }
42
+ function useTheme() {
43
+ return useContext(ThemeContext);
44
+ }
45
+ function useAgentSweep(runtime) {
46
+ useEffect(() => {
47
+ const subscription = AppState.addEventListener("change", (state) => {
48
+ if (state === "active") runtime.sweep();
49
+ });
50
+ return () => subscription.remove();
51
+ }, [runtime]);
52
+ }
53
+ function useNativeLifecycle(store) {
54
+ useEffect(() => {
55
+ const apply = (state) => store.setForeground(state === "active");
56
+ apply(AppState.currentState);
57
+ const subscription = AppState.addEventListener("change", apply);
58
+ return () => subscription.remove();
59
+ }, [store]);
60
+ }
61
+ function useReducedMotion() {
62
+ const [reduced, setReduced] = useState(false);
63
+ useEffect(() => {
64
+ let live = true;
65
+ AccessibilityInfo.isReduceMotionEnabled().then(
66
+ (value) => {
67
+ if (live) setReduced(value);
68
+ },
69
+ () => void 0
70
+ );
71
+ const subscription = AccessibilityInfo.addEventListener(
72
+ "reduceMotionChanged",
73
+ setReduced
74
+ );
75
+ return () => {
76
+ live = false;
77
+ subscription.remove();
78
+ };
79
+ }, []);
80
+ return reduced;
81
+ }
82
+ function announce(text) {
83
+ if (text) AccessibilityInfo.announceForAccessibility(text);
84
+ }
85
+
86
+ export { ThemeProvider, announce, createTheme, themeProblems, useAgentSweep, useNativeLifecycle, useReducedMotion, useTheme };
87
+ //# sourceMappingURL=chunk-EFEXTVIT.js.map
88
+ //# sourceMappingURL=chunk-EFEXTVIT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme.tsx","../src/platform.ts"],"names":[],"mappings":"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","file":"chunk-EFEXTVIT.js","sourcesContent":["// The theme: the shared design tokens, a tenant's brand on top, light and dark. A tenant changes colors, fonts, radii\n// and spacing; the disclosure bar keeps a legible pair whatever the tenant's colors (see DisclosureBar).\nimport {\n type ColorScheme,\n type Colors,\n colors,\n contrastProblems,\n font,\n motion,\n radius,\n size,\n space,\n} from '@vinaverse/tokens';\nimport { createContext, type ReactNode, useContext, useMemo } from 'react';\nimport { useColorScheme } from 'react-native';\n\nexport interface Theme {\n readonly scheme: ColorScheme;\n readonly colors: Colors;\n readonly font: typeof font & { readonly family?: string };\n readonly space: typeof space;\n readonly radius: typeof radius;\n readonly motion: typeof motion;\n readonly size: typeof size;\n}\n\n/** A tenant's brand: colors per scheme, a font family, radii. Anything left out keeps the Vinaverse default. */\nexport interface ThemeOverrides {\n readonly light?: Partial<Colors>;\n readonly dark?: Partial<Colors>;\n readonly fontFamily?: string;\n readonly radius?: Partial<typeof radius>;\n readonly space?: Partial<typeof space>;\n}\n\nexport type ColorSchemeSetting = 'system' | 'light' | 'dark';\n\n/** The theme for a scheme, with the tenant's overrides on top. */\nexport function createTheme(\n scheme: ColorScheme,\n overrides: ThemeOverrides = {},\n): Theme {\n return {\n scheme,\n colors: { ...colors(scheme), ...overrides[scheme] },\n font: {\n ...font,\n ...(overrides.fontFamily ? { family: overrides.fontFamily } : {}),\n },\n space: { ...space, ...overrides.space },\n radius: { ...radius, ...overrides.radius },\n motion,\n size,\n };\n}\n\n/** The pairs a tenant's colors made hard to read, in either scheme, as messages for a development warning. */\nexport function themeProblems(overrides: ThemeOverrides = {}): string[] {\n return (['light', 'dark'] as const).flatMap((scheme) =>\n contrastProblems(createTheme(scheme, overrides).colors).map(\n (p) =>\n `${scheme}: ${p.foreground} on ${p.background} is ${p.ratio.toFixed(2)}:1, below ${p.minimum}:1`,\n ),\n );\n}\n\nconst ThemeContext = /* @__PURE__ */ createContext<Theme>(\n /* @__PURE__ */ createTheme('light'),\n);\n\nexport function ThemeProvider(props: {\n readonly theme?: ThemeOverrides | undefined;\n readonly colorScheme?: ColorSchemeSetting | undefined;\n readonly children?: ReactNode;\n}): ReactNode {\n const system = useColorScheme();\n const setting = props.colorScheme ?? 'system';\n const scheme: ColorScheme =\n setting === 'system' ? (system === 'dark' ? 'dark' : 'light') : setting;\n const overrides = props.theme;\n const value = useMemo(\n () => createTheme(scheme, overrides),\n [scheme, overrides],\n );\n return (\n <ThemeContext.Provider value={value}>\n {props.children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme(): Theme {\n return useContext(ThemeContext);\n}\n","// The React Native platform adapter: what the conversation store learns from the app (foreground, background) and\n// what the kit asks of the platform (reduced motion, screen reader announcements).\nimport { useEffect, useState } from 'react';\nimport { AccessibilityInfo, AppState, type AppStateStatus } from 'react-native';\n\n/** The part of the conversation store the adapter drives. */\nexport interface LifecycleTarget {\n setForeground(foreground: boolean): void;\n}\n\n/**\n * When the app comes back to the foreground, the agent runtime ends the conversations no view shows that are past\n * their session's end (timers do not run in the background). Every agent part calls it; once is enough.\n */\nexport function useAgentSweep(runtime: { sweep(): void }): void {\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n if (state === 'active') runtime.sweep();\n });\n return () => subscription.remove();\n }, [runtime]);\n}\n\n/** Tells the store when the app comes to the foreground or goes to the background (it pings only in the foreground). */\nexport function useNativeLifecycle(store: LifecycleTarget): void {\n useEffect(() => {\n const apply = (state: AppStateStatus) =>\n store.setForeground(state === 'active');\n apply(AppState.currentState);\n const subscription = AppState.addEventListener('change', apply);\n return () => subscription.remove();\n }, [store]);\n}\n\n/** Whether the person asked for reduced motion: animations and animated scrolling stay off. */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n let live = true;\n AccessibilityInfo.isReduceMotionEnabled().then(\n (value) => {\n if (live) setReduced(value);\n },\n () => undefined,\n );\n const subscription = AccessibilityInfo.addEventListener(\n 'reduceMotionChanged',\n setReduced,\n );\n return () => {\n live = false;\n subscription.remove();\n };\n }, []);\n return reduced;\n}\n\n/** Reads a line to a screen reader, without moving focus. */\nexport function announce(text: string): void {\n if (text) AccessibilityInfo.announceForAccessibility(text);\n}\n"]}