@vinaverse/react-native 0.1.0-alpha.3 → 0.1.0-alpha.4

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/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { Pressable, ActivityIndicator, Text, View, Image, TextInput, AccessibilityInfo, useColorScheme, AppState, Platform, KeyboardAvoidingView } from 'react-native';
1
+ import { FlashList } from '@shopify/flash-list';
2
+ import { useCopy, useConversationSelector, useStreamingText, formatMoney, formatTimeRange, formatDate, bannedWordsIn, CopyProvider } from '@vinaverse/react';
3
+ import { Pressable, ActivityIndicator, Text, View, Image, TextInput, AccessibilityInfo, Linking, useColorScheme, useWindowDimensions, AppState, Platform, KeyboardAvoidingView } from 'react-native';
2
4
  import { createContext, memo, useCallback, useState, useRef, useMemo, useEffect, useContext } from 'react';
3
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
6
  import { contrastRatio, colors, size, motion, radius, space, font, contrastProblems } from '@vinaverse/tokens';
5
- import { useCopy, useConversationSelector, useStreamingText, formatTimeRange, formatMoney, formatDate, bannedWordsIn, CopyProvider } from '@vinaverse/react';
6
7
  import { codePoints, MAX_TEXT, answerProblem } from '@vinaverse/client/conversation';
7
- import { FlashList } from '@shopify/flash-list';
8
8
 
9
- // src/cards/CardFrame.tsx
9
+ // src/cards/CardCarousel.tsx
10
10
  var ChatContext = createContext(null);
11
11
  function ChatContextProvider(props) {
12
12
  return /* @__PURE__ */ jsx(ChatContext.Provider, { value: props.value, children: props.children });
@@ -55,6 +55,61 @@ function ThemeProvider(props) {
55
55
  function useTheme() {
56
56
  return useContext(ThemeContext);
57
57
  }
58
+ var Button = memo(function Button2(props) {
59
+ const { colors: colors2, radius: radius2, space: space2, size: size3, font: font2 } = useTheme();
60
+ const variant = props.variant ?? "secondary";
61
+ const inactive = props.disabled === true || props.busy === true;
62
+ const filled = variant === "primary" || props.selected === true;
63
+ const background = filled ? colors2.primary : variant === "secondary" ? colors2.surface : "transparent";
64
+ const foreground = filled ? colors2.onPrimary : colors2.primary;
65
+ const checkable = props.role === "radio" || props.role === "checkbox";
66
+ return /* @__PURE__ */ jsxs(
67
+ Pressable,
68
+ {
69
+ accessibilityRole: props.role ?? "button",
70
+ accessibilityLabel: props.label,
71
+ ...props.hint ? { accessibilityHint: props.hint } : {},
72
+ accessibilityState: {
73
+ disabled: inactive,
74
+ busy: props.busy === true,
75
+ ...checkable ? props.role === "radio" ? { selected: props.selected === true } : { checked: props.selected === true } : {}
76
+ },
77
+ disabled: inactive,
78
+ onPress: props.onPress,
79
+ ...props.testID ? { testID: props.testID } : {},
80
+ style: ({ pressed }) => ({
81
+ minHeight: size3.touchTarget,
82
+ minWidth: size3.touchTarget,
83
+ paddingHorizontal: space2.md,
84
+ paddingVertical: space2.sm,
85
+ borderRadius: radius2.md,
86
+ borderWidth: variant === "text" ? 0 : 1,
87
+ borderColor: filled ? colors2.primary : colors2.border,
88
+ backgroundColor: background,
89
+ opacity: inactive ? 0.55 : pressed ? 0.8 : 1,
90
+ alignItems: "center",
91
+ justifyContent: "center",
92
+ flexDirection: "row",
93
+ gap: space2.xs
94
+ }),
95
+ children: [
96
+ props.busy ? /* @__PURE__ */ jsx(ActivityIndicator, { color: foreground }) : null,
97
+ props.children ?? /* @__PURE__ */ jsx(
98
+ Text,
99
+ {
100
+ style: {
101
+ color: foreground,
102
+ fontSize: font2.size.md,
103
+ fontWeight: "500",
104
+ ...font2.family ? { fontFamily: font2.family } : {}
105
+ },
106
+ children: props.label
107
+ }
108
+ )
109
+ ]
110
+ }
111
+ );
112
+ });
58
113
  function cardOf(held) {
59
114
  return held.card;
60
115
  }
@@ -123,64 +178,20 @@ function useLink(link, held) {
123
178
  if (!link || !store.checkLink(link)) return null;
124
179
  return () => handlers.current?.onOpenLink?.(link, held);
125
180
  }
181
+ function ratingText(valuePpm, locale) {
182
+ const value = valuePpm / 1e6;
183
+ try {
184
+ return new Intl.NumberFormat(locale, {
185
+ minimumFractionDigits: 1,
186
+ maximumFractionDigits: 1
187
+ }).format(value);
188
+ } catch {
189
+ return value.toFixed(1);
190
+ }
191
+ }
126
192
  function safeImage(url) {
127
193
  return url && /^https:\/\//i.test(url) ? url : null;
128
194
  }
129
- var Button = memo(function Button2(props) {
130
- const { colors: colors2, radius: radius2, space: space2, size: size3, font: font2 } = useTheme();
131
- const variant = props.variant ?? "secondary";
132
- const inactive = props.disabled === true || props.busy === true;
133
- const filled = variant === "primary" || props.selected === true;
134
- const background = filled ? colors2.primary : variant === "secondary" ? colors2.surface : "transparent";
135
- const foreground = filled ? colors2.onPrimary : colors2.primary;
136
- const checkable = props.role === "radio" || props.role === "checkbox";
137
- return /* @__PURE__ */ jsxs(
138
- Pressable,
139
- {
140
- accessibilityRole: props.role ?? "button",
141
- accessibilityLabel: props.label,
142
- ...props.hint ? { accessibilityHint: props.hint } : {},
143
- accessibilityState: {
144
- disabled: inactive,
145
- busy: props.busy === true,
146
- ...checkable ? props.role === "radio" ? { selected: props.selected === true } : { checked: props.selected === true } : {}
147
- },
148
- disabled: inactive,
149
- onPress: props.onPress,
150
- ...props.testID ? { testID: props.testID } : {},
151
- style: ({ pressed }) => ({
152
- minHeight: size3.touchTarget,
153
- minWidth: size3.touchTarget,
154
- paddingHorizontal: space2.md,
155
- paddingVertical: space2.sm,
156
- borderRadius: radius2.md,
157
- borderWidth: variant === "text" ? 0 : 1,
158
- borderColor: filled ? colors2.primary : colors2.border,
159
- backgroundColor: background,
160
- opacity: inactive ? 0.55 : pressed ? 0.8 : 1,
161
- alignItems: "center",
162
- justifyContent: "center",
163
- flexDirection: "row",
164
- gap: space2.xs
165
- }),
166
- children: [
167
- props.busy ? /* @__PURE__ */ jsx(ActivityIndicator, { color: foreground }) : null,
168
- props.children ?? /* @__PURE__ */ jsx(
169
- Text,
170
- {
171
- style: {
172
- color: foreground,
173
- fontSize: font2.size.md,
174
- fontWeight: "500",
175
- ...font2.family ? { fontFamily: font2.family } : {}
176
- },
177
- children: props.label
178
- }
179
- )
180
- ]
181
- }
182
- );
183
- });
184
195
  function InfoCard(props) {
185
196
  const card = cardOf(props.card);
186
197
  const { locale, t } = useCopy();
@@ -189,7 +200,7 @@ function InfoCard(props) {
189
200
  const image = safeImage(card.image_url);
190
201
  const Img = slots.Image ?? Image;
191
202
  const money = card.price ?? card.price_from;
192
- const rating = card.rating ? (card.rating.value_ppm / 1e6).toFixed(1) : null;
203
+ const rating = card.rating ? ratingText(card.rating.value_ppm, locale) : null;
193
204
  const amount = money ? formatMoney(money.amount, money.currency, locale) : null;
194
205
  const price = amount && !card.price ? t("priceFrom", { price: amount }) : amount;
195
206
  const when = card.starts_at ? formatTimeRange(card.starts_at, void 0, locale, timeZone) : null;
@@ -232,27 +243,32 @@ function InfoCard(props) {
232
243
  ] })
233
244
  ] }),
234
245
  card.body ? /* @__PURE__ */ jsx(Body, { children: card.body }) : null,
235
- card.badges?.length ? /* @__PURE__ */ jsx(View, { style: { flexDirection: "row", flexWrap: "wrap", gap: space2.xs }, children: card.badges.map((b) => /* @__PURE__ */ jsx(
236
- Text,
237
- {
238
- style: {
239
- color: colors2.text,
240
- backgroundColor: colors2.surface,
241
- borderRadius: radius2.pill,
242
- paddingHorizontal: space2.sm,
243
- paddingVertical: space2.xxs,
244
- fontSize: font2.size.xs
245
- },
246
- children: b
247
- },
248
- b
249
- )) }) : null,
250
- props.restored ? null : /* @__PURE__ */ jsx(Actions, { ...props })
246
+ /* @__PURE__ */ jsx(Badges, { badges: card.badges }),
247
+ props.restored ? null : /* @__PURE__ */ jsx(CardActions, { ...props })
251
248
  ]
252
249
  }
253
250
  );
254
251
  }
255
- function Actions(props) {
252
+ function Badges(props) {
253
+ const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
254
+ if (!props.badges?.length) return null;
255
+ return /* @__PURE__ */ jsx(View, { style: { flexDirection: "row", flexWrap: "wrap", gap: space2.xs }, children: props.badges.map((b) => /* @__PURE__ */ jsx(
256
+ Text,
257
+ {
258
+ style: {
259
+ color: colors2.text,
260
+ backgroundColor: colors2.surface,
261
+ borderRadius: radius2.pill,
262
+ paddingHorizontal: space2.sm,
263
+ paddingVertical: space2.xxs,
264
+ fontSize: font2.size.xs
265
+ },
266
+ children: b
267
+ },
268
+ b
269
+ )) });
270
+ }
271
+ function CardActions(props) {
256
272
  const card = cardOf(props.card);
257
273
  const { space: space2 } = useTheme();
258
274
  if (!card.actions?.length) return null;
@@ -284,6 +300,120 @@ function Action(props) {
284
300
  }
285
301
  );
286
302
  }
303
+ function LinksCard(props) {
304
+ const card = cardOf(props.card);
305
+ const { store, handlers } = useChat();
306
+ const links = (card.links ?? []).filter(
307
+ (l) => /^https:\/\//i.test(l.url) || store.checkLink(l.url)
308
+ );
309
+ return /* @__PURE__ */ jsxs(
310
+ CardFrame,
311
+ {
312
+ label: [card.title, ...links.map((l) => l.label)].join(", "),
313
+ restored: props.restored,
314
+ testID: `vinaverse-card-${card.id}`,
315
+ children: [
316
+ /* @__PURE__ */ jsx(Title, { children: card.title }),
317
+ links.map((l) => /* @__PURE__ */ jsx(
318
+ Button,
319
+ {
320
+ label: l.label,
321
+ role: "link",
322
+ variant: "secondary",
323
+ disabled: props.restored,
324
+ onPress: () => {
325
+ const open = handlers.current?.onOpenLink;
326
+ if (open) open(l.url, props.card);
327
+ else void Linking.openURL(l.url);
328
+ }
329
+ },
330
+ l.url
331
+ ))
332
+ ]
333
+ }
334
+ );
335
+ }
336
+ function ListingCard(props) {
337
+ const card = cardOf(props.card);
338
+ const { locale, t } = useCopy();
339
+ const { slots, timeZone } = useChat();
340
+ const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
341
+ const [failed, setFailed] = useState(null);
342
+ const photoUrl = safeImage(card.images?.[0]?.url ?? card.image_url);
343
+ const hero = photoUrl === failed ? null : photoUrl;
344
+ const Img = slots.Image ?? Image;
345
+ const rating = card.rating ? `\u2605 ${ratingText(card.rating.value_ppm, locale)} (${card.rating.count})` : null;
346
+ const price = card.price_from ? t("priceFrom", {
347
+ price: formatMoney(
348
+ card.price_from.amount,
349
+ card.price_from.currency,
350
+ locale
351
+ )
352
+ }) : null;
353
+ const next = card.next_available ? t("nextAvailable", {
354
+ time: formatTimeRange(card.next_available, void 0, locale, timeZone)
355
+ }) : null;
356
+ const photo = {
357
+ width: "100%",
358
+ aspectRatio: 1.6,
359
+ borderRadius: radius2.md
360
+ };
361
+ return /* @__PURE__ */ jsxs(
362
+ CardFrame,
363
+ {
364
+ label: [card.title, card.subtitle, rating, price, next].filter(Boolean).join(", "),
365
+ restored: props.restored,
366
+ testID: `vinaverse-card-${card.id}`,
367
+ children: [
368
+ hero ? /* @__PURE__ */ jsx(
369
+ Img,
370
+ {
371
+ source: { uri: hero },
372
+ onError: () => setFailed(hero),
373
+ style: { ...photo, backgroundColor: colors2.surface },
374
+ accessible: false,
375
+ testID: `vinaverse-photo-${card.id}`
376
+ }
377
+ ) : /* @__PURE__ */ jsx(
378
+ View,
379
+ {
380
+ accessible: false,
381
+ importantForAccessibility: "no-hide-descendants",
382
+ testID: `vinaverse-monogram-${card.id}`,
383
+ style: {
384
+ ...photo,
385
+ backgroundColor: colors2.surface,
386
+ alignItems: "center",
387
+ justifyContent: "center"
388
+ },
389
+ children: /* @__PURE__ */ jsx(
390
+ Text,
391
+ {
392
+ style: {
393
+ color: colors2.textMuted,
394
+ fontSize: font2.size.xl,
395
+ fontWeight: "600"
396
+ },
397
+ children: monogram(card.title)
398
+ }
399
+ )
400
+ }
401
+ ),
402
+ /* @__PURE__ */ jsxs(View, { style: { gap: space2.xxs }, children: [
403
+ /* @__PURE__ */ jsx(Title, { numberOfLines: 2, children: card.title }),
404
+ card.subtitle ? /* @__PURE__ */ jsx(Body, { muted: true, children: card.subtitle }) : null,
405
+ rating || price ? /* @__PURE__ */ jsx(Body, { muted: true, children: [rating, price].filter(Boolean).join(" \xB7 ") }) : null
406
+ ] }),
407
+ card.body ? /* @__PURE__ */ jsx(Body, { children: card.body }) : null,
408
+ /* @__PURE__ */ jsx(Badges, { badges: next ? [next, ...card.badges ?? []] : card.badges }),
409
+ props.restored ? null : /* @__PURE__ */ jsx(CardActions, { ...props })
410
+ ]
411
+ }
412
+ );
413
+ }
414
+ function monogram(title) {
415
+ return title.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => [...w][0]?.toUpperCase() ?? "").join("");
416
+ }
287
417
  function NextStepCard(props) {
288
418
  const card = cardOf(props.card);
289
419
  const action = card.actions?.[0];
@@ -1152,7 +1282,10 @@ var DEFAULTS = {
1152
1282
  proposal: ProposalCard,
1153
1283
  question: QuestionCard,
1154
1284
  next_step: NextStepCard,
1155
- time_slots: TimeSlotsCard
1285
+ time_slots: TimeSlotsCard,
1286
+ professional: ListingCard,
1287
+ workspace: ListingCard,
1288
+ links: LinksCard
1156
1289
  };
1157
1290
  function defaultCard(kind) {
1158
1291
  return DEFAULTS[kind] ?? InfoCard;
@@ -1165,6 +1298,35 @@ var CardView = memo(function CardView2(props) {
1165
1298
  const own = { card, busy, restored: props.item.restored === true };
1166
1299
  return Custom ? /* @__PURE__ */ jsx(Custom, { ...own, Default }) : /* @__PURE__ */ jsx(Default, { ...own });
1167
1300
  });
1301
+ var keyOf = (item) => item.key;
1302
+ var kindOf = (item) => item.card.kind;
1303
+ function CardCarousel(props) {
1304
+ const { width } = useWindowDimensions();
1305
+ const { t } = useCopy();
1306
+ const size3 = Math.min(Math.round(width * 0.8), 360);
1307
+ return /* @__PURE__ */ jsx(
1308
+ View,
1309
+ {
1310
+ accessibilityRole: "list",
1311
+ accessibilityLabel: t("cardsInRow", {
1312
+ count: String(props.items.length)
1313
+ }),
1314
+ children: /* @__PURE__ */ jsx(
1315
+ FlashList,
1316
+ {
1317
+ horizontal: true,
1318
+ data: props.items,
1319
+ keyExtractor: keyOf,
1320
+ getItemType: kindOf,
1321
+ renderItem: ({ item }) => /* @__PURE__ */ jsx(View, { style: { width: size3 }, children: /* @__PURE__ */ jsx(CardView, { item }) }),
1322
+ snapToInterval: size3,
1323
+ decelerationRate: "fast",
1324
+ showsHorizontalScrollIndicator: false
1325
+ }
1326
+ )
1327
+ }
1328
+ );
1329
+ }
1168
1330
  var ActivityLine = memo(function ActivityLine2() {
1169
1331
  const { store } = useChat();
1170
1332
  const { t } = useCopy();
@@ -1722,7 +1884,44 @@ function Line(props) {
1722
1884
  }
1723
1885
  );
1724
1886
  }
1725
- var keyOf = (item) => item.key;
1887
+ var Welcome = memo(function Welcome2(props) {
1888
+ const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
1889
+ return /* @__PURE__ */ jsxs(
1890
+ View,
1891
+ {
1892
+ style: { padding: space2.lg, gap: space2.md },
1893
+ testID: "vinaverse-welcome",
1894
+ children: [
1895
+ /* @__PURE__ */ jsx(
1896
+ Text,
1897
+ {
1898
+ style: {
1899
+ alignSelf: "flex-start",
1900
+ maxWidth: "85%",
1901
+ color: colors2.agentText,
1902
+ backgroundColor: colors2.agentBubble,
1903
+ borderRadius: radius2.lg,
1904
+ paddingHorizontal: space2.md,
1905
+ paddingVertical: space2.sm,
1906
+ fontSize: font2.size.md,
1907
+ lineHeight: font2.size.md * font2.lineHeight
1908
+ },
1909
+ children: props.welcome.text
1910
+ }
1911
+ ),
1912
+ props.welcome.chips.length ? /* @__PURE__ */ jsx(View, { style: { flexDirection: "row", flexWrap: "wrap", gap: space2.sm }, children: props.welcome.chips.map((chip) => /* @__PURE__ */ jsx(
1913
+ Button,
1914
+ {
1915
+ label: chip.label,
1916
+ onPress: () => props.onChip(chip.message)
1917
+ },
1918
+ chip.label
1919
+ )) }) : null
1920
+ ]
1921
+ }
1922
+ );
1923
+ });
1924
+ var keyOf2 = (item) => item.key;
1726
1925
  function itemType(item) {
1727
1926
  if (item.type === "card") return `card:${item.card.kind}`;
1728
1927
  if (item.type === "message")
@@ -1732,8 +1931,39 @@ function itemType(item) {
1732
1931
  function authorOf(item) {
1733
1932
  return item?.type === "message" ? item.role : null;
1734
1933
  }
1934
+ function carousels(items, previous) {
1935
+ const runs = /* @__PURE__ */ new Map();
1936
+ const inside = /* @__PURE__ */ new Set();
1937
+ const groupOf = (item) => {
1938
+ if (item?.type !== "card") return null;
1939
+ const group = item.card.card.group;
1940
+ return group?.layout === "carousel" && typeof group.id === "string" ? group.id : null;
1941
+ };
1942
+ for (let i = 0; i < items.length; i++) {
1943
+ const id = groupOf(items[i]);
1944
+ if (id === null) continue;
1945
+ let end = i + 1;
1946
+ while (end < items.length && groupOf(items[end]) === id) end++;
1947
+ if (end - i > 1) {
1948
+ const run = items.slice(i, end);
1949
+ const key = run[0]?.key;
1950
+ const before = previous.get(key);
1951
+ runs.set(
1952
+ key,
1953
+ before && before.length === run.length && before.every((c, n) => c === run[n]) ? before : run
1954
+ );
1955
+ for (const card of run.slice(1)) inside.add(card.key);
1956
+ }
1957
+ i = end - 1;
1958
+ }
1959
+ return { runs, inside };
1960
+ }
1735
1961
  var Row = memo(function Row2(props) {
1736
1962
  const { item } = props;
1963
+ const { slots } = useChat();
1964
+ const Group = slots.CardGroup;
1965
+ if (props.inside) return null;
1966
+ if (props.run && Group) return /* @__PURE__ */ jsx(Group, { items: props.run });
1737
1967
  if (item.type === "card") return /* @__PURE__ */ jsx(CardView, { item });
1738
1968
  if (item.type === "system") return /* @__PURE__ */ jsx(SystemRow, { item });
1739
1969
  return item.state === "streaming" ? /* @__PURE__ */ jsx(StreamingBubble, { item, showAuthor: props.showAuthor }) : /* @__PURE__ */ jsx(MessageBubble, { item, showAuthor: props.showAuthor });
@@ -1749,26 +1979,49 @@ var MessageList = memo(function MessageList2() {
1749
1979
  (v) => v.status === "starting" || v.status === "connecting"
1750
1980
  );
1751
1981
  const agentName = useConversationSelector(store, (v) => v.agent.name);
1982
+ const welcome = useConversationSelector(store, (v) => v.welcome);
1752
1983
  useAnnounceReplies(items);
1984
+ const Group = slots.CardGroup;
1985
+ const runsRef = useRef(/* @__PURE__ */ new Map());
1986
+ const grouping = useMemo(
1987
+ () => Group ? carousels(items, runsRef.current) : null,
1988
+ [items, Group]
1989
+ );
1990
+ runsRef.current = grouping?.runs ?? /* @__PURE__ */ new Map();
1753
1991
  const itemsRef = useRef(items);
1754
1992
  itemsRef.current = items;
1993
+ const groupingRef = useRef(grouping);
1994
+ groupingRef.current = grouping;
1755
1995
  const renderItem = useCallback(
1756
1996
  ({ item, index }) => /* @__PURE__ */ jsx(
1757
1997
  Row,
1758
1998
  {
1759
1999
  item,
1760
- showAuthor: authorOf(item) !== authorOf(itemsRef.current[index - 1])
2000
+ showAuthor: authorOf(item) !== authorOf(itemsRef.current[index - 1]),
2001
+ run: groupingRef.current?.runs.get(item.key),
2002
+ inside: groupingRef.current?.inside.has(item.key) === true
1761
2003
  }
1762
2004
  ),
1763
2005
  []
1764
2006
  );
2007
+ const onChip = useCallback(
2008
+ (message) => void store.send(message),
2009
+ [store]
2010
+ );
1765
2011
  const Empty = slots.EmptyState;
1766
- const empty = opening ? /* @__PURE__ */ jsx(ChatSkeleton, {}) : Empty ? /* @__PURE__ */ jsx(Empty, { agentName: agentName ?? t("agentFallbackName") }) : null;
2012
+ const empty = opening ? /* @__PURE__ */ jsx(ChatSkeleton, {}) : Empty ? /* @__PURE__ */ jsx(
2013
+ Empty,
2014
+ {
2015
+ agentName: agentName ?? t("agentFallbackName"),
2016
+ welcome,
2017
+ onChip
2018
+ }
2019
+ ) : welcome ? /* @__PURE__ */ jsx(Welcome, { welcome, onChip }) : null;
1767
2020
  const props = useMemo(
1768
2021
  () => ({
1769
2022
  data: items,
1770
2023
  renderItem,
1771
- keyExtractor: keyOf,
2024
+ keyExtractor: keyOf2,
1772
2025
  getItemType: itemType,
1773
2026
  maintainVisibleContentPosition: {
1774
2027
  startRenderingFromBottom: true,
@@ -1998,6 +2251,6 @@ function sameSlots(a, b) {
1998
2251
  return true;
1999
2252
  }
2000
2253
 
2001
- export { ActivityLine, Avatar, Button, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DisclosureBar, FailureActionButton, InfoCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeProvider, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, announce, answerText, createTheme, defaultCard, fieldText, itemType, themeProblems, useChat, useNativeLifecycle, useReducedMotion, useTheme };
2254
+ export { ActivityLine, Avatar, Button, CardActions, CardCarousel, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DisclosureBar, FailureActionButton, InfoCard, LinksCard, ListingCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeProvider, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, Welcome, announce, answerText, carousels, createTheme, defaultCard, fieldText, itemType, monogram, ratingText, themeProblems, useChat, useNativeLifecycle, useReducedMotion, useTheme };
2002
2255
  //# sourceMappingURL=index.js.map
2003
2256
  //# sourceMappingURL=index.js.map