@vvedantb/native-ui 0.17.2 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/dist/AlertDialog.jsx +123 -0
  2. package/dist/AmbientBackground.jsx +73 -0
  3. package/dist/ArtifactList.jsx +59 -0
  4. package/dist/Avatar.jsx +285 -0
  5. package/dist/Badge.jsx +154 -0
  6. package/dist/BottomSheetContainer.jsx +208 -0
  7. package/dist/BulkActionBar.jsx +717 -0
  8. package/dist/Button.jsx +344 -0
  9. package/dist/CaptureButton.jsx +104 -0
  10. package/dist/Card.jsx +371 -0
  11. package/dist/Checkbox.jsx +177 -0
  12. package/dist/Chip.jsx +79 -0
  13. package/dist/ColorSwatches.jsx +159 -0
  14. package/dist/ConfirmDialog.jsx +157 -0
  15. package/dist/DateTimeField.jsx +204 -0
  16. package/dist/Dialog.jsx +614 -0
  17. package/dist/DividedList.jsx +120 -0
  18. package/dist/DropdownMenu.jsx +849 -0
  19. package/dist/EmptyState.jsx +434 -0
  20. package/dist/ExpoWebRoot.jsx +134 -0
  21. package/dist/FloatingFAB.jsx +95 -0
  22. package/dist/FloatingSurface.jsx +226 -0
  23. package/dist/FloatingTabBar.jsx +403 -0
  24. package/dist/HeaderIconButton.jsx +53 -0
  25. package/dist/IconButton.jsx +157 -0
  26. package/dist/Input.jsx +96 -0
  27. package/dist/Label.jsx +96 -0
  28. package/dist/LabeledSwitchRow.jsx +170 -0
  29. package/dist/LiquidGlass.jsx +2 -0
  30. package/dist/ListRow.jsx +281 -0
  31. package/dist/LoadingState.jsx +205 -0
  32. package/dist/PageIndicator.jsx +128 -0
  33. package/dist/PageTitle.jsx +205 -0
  34. package/dist/Pager.jsx +105 -0
  35. package/dist/PasswordInput.jsx +120 -0
  36. package/dist/PillTabs.jsx +300 -0
  37. package/dist/PinnedBotTile.jsx +212 -0
  38. package/dist/Progress.jsx +147 -0
  39. package/dist/SafeAreaContainer.jsx +38 -0
  40. package/dist/ScreenContainer.jsx +117 -0
  41. package/dist/SearchInput.jsx +150 -0
  42. package/dist/SectionLabel.jsx +128 -0
  43. package/dist/Select.jsx +223 -0
  44. package/dist/Separator.jsx +95 -0
  45. package/dist/Sheet.jsx +343 -0
  46. package/dist/SheetRow.jsx +198 -0
  47. package/dist/Skeleton.jsx +311 -0
  48. package/dist/Spinner.jsx +195 -0
  49. package/dist/StackPageHeader.jsx +160 -0
  50. package/dist/StatGrid.jsx +74 -0
  51. package/dist/StatusDot.jsx +129 -0
  52. package/dist/SurfaceRow.jsx +143 -0
  53. package/dist/SwipeableRow.jsx +50 -0
  54. package/dist/Switch.jsx +130 -0
  55. package/dist/Tabs.jsx +385 -0
  56. package/dist/Textarea.jsx +103 -0
  57. package/dist/ThemeToggle.jsx +78 -0
  58. package/dist/Toast.jsx +396 -0
  59. package/dist/ai/activity-step-detail.jsx +179 -0
  60. package/dist/ai/activity-step-label.js +816 -0
  61. package/dist/ai/activity-step-types.js +14 -0
  62. package/dist/ai/activity-step.jsx +98 -0
  63. package/dist/ai/activity-tasks-utils.js +172 -0
  64. package/dist/ai/activity-timeline.js +47 -0
  65. package/dist/ai/attachments.jsx +258 -0
  66. package/dist/ai/card-button.jsx +188 -0
  67. package/dist/ai/chain-of-thought.jsx +459 -0
  68. package/dist/ai/chat-jump-rail.jsx +57 -0
  69. package/dist/ai/chat-text.js +44 -0
  70. package/dist/ai/chat-thread.jsx +135 -0
  71. package/dist/ai/choice-question.jsx +925 -0
  72. package/dist/ai/code-block.jsx +574 -0
  73. package/dist/ai/collapsible.jsx +275 -0
  74. package/dist/ai/conversation.jsx +723 -0
  75. package/dist/ai/file-chip.jsx +198 -0
  76. package/dist/ai/icon-button.jsx +179 -0
  77. package/dist/ai/index.js +37 -0
  78. package/dist/ai/message-action-sheet.jsx +408 -0
  79. package/dist/ai/message-quote.jsx +241 -0
  80. package/dist/ai/message.jsx +739 -0
  81. package/dist/ai/prompt-input-menu.jsx +365 -0
  82. package/dist/ai/prompt-input.jsx +626 -0
  83. package/dist/ai/reasoning.jsx +446 -0
  84. package/dist/ai/reply-quote-chip.jsx +278 -0
  85. package/dist/ai/response-text.jsx +130 -0
  86. package/dist/ai/shimmer.jsx +149 -0
  87. package/dist/ai/sources.jsx +260 -0
  88. package/dist/ai/subagent-cards.jsx +645 -0
  89. package/dist/ai/suggestion.jsx +186 -0
  90. package/dist/ai/tool-approval-card.jsx +359 -0
  91. package/dist/ai/trace.jsx +728 -0
  92. package/dist/ai/unified-diff.jsx +280 -0
  93. package/dist/ai/use-streaming-disclosure.js +70 -0
  94. package/dist/auth/AuthProviders.jsx +27 -0
  95. package/dist/auth/AuthScreen.jsx +292 -0
  96. package/dist/auth/GoogleSignInButton.jsx +188 -0
  97. package/dist/auth/SecondFactorScreen.jsx +133 -0
  98. package/dist/auth/SignInScreen.jsx +482 -0
  99. package/dist/auth/authErrors.js +131 -0
  100. package/dist/auth/index.js +11 -0
  101. package/dist/auth/totp.js +378 -0
  102. package/dist/blur.js +36 -0
  103. package/dist/brand/AppIcons.jsx +118 -0
  104. package/dist/brand/AppMark.jsx +128 -0
  105. package/dist/brand/AppWordmark.jsx +138 -0
  106. package/dist/brand/GoogleMark.jsx +71 -0
  107. package/dist/brand/ProviderIcon.jsx +192 -0
  108. package/dist/brand/familyApps.js +33 -0
  109. package/dist/brand/index.js +11 -0
  110. package/dist/brand/svg.js +252 -0
  111. package/dist/brand/vProAppBenefits.js +19 -0
  112. package/dist/cn.js +5 -0
  113. package/dist/colors.js +15 -0
  114. package/dist/configureTheme.js +72 -0
  115. package/dist/controlStyles.js +520 -0
  116. package/dist/definiteSize.js +12 -0
  117. package/dist/dialogLayout.js +18 -0
  118. package/dist/entries/ai.js +4 -0
  119. package/dist/entries/ambient.js +3 -0
  120. package/dist/entries/auth.js +5 -0
  121. package/dist/entries/bottom-sheet.js +2 -0
  122. package/dist/entries/brand.js +2 -0
  123. package/dist/entries/button.js +2 -0
  124. package/dist/entries/date-time.js +3 -0
  125. package/dist/entries/expo-router.js +4 -0
  126. package/dist/entries/expo-web-root.js +3 -0
  127. package/dist/entries/floating.js +7 -0
  128. package/dist/entries/gesture-handler.js +4 -0
  129. package/dist/entries/keyboard-controller.js +4 -0
  130. package/dist/entries/layout.js +16 -0
  131. package/dist/entries/markdown.js +4 -0
  132. package/dist/entries/marketing.js +3 -0
  133. package/dist/entries/page-title.js +7 -0
  134. package/dist/entries/password-input.js +3 -0
  135. package/dist/entries/primitives.js +57 -0
  136. package/dist/entries/search-input.js +3 -0
  137. package/dist/entries/tab-bar.js +4 -0
  138. package/dist/entries/theme.js +7 -0
  139. package/dist/entries/toast.js +5 -0
  140. package/dist/entries/video.js +3 -0
  141. package/dist/entries/webview.js +4 -0
  142. package/dist/examples/AiChatGallery.jsx +509 -0
  143. package/dist/examples/ParityGallery.jsx +1307 -0
  144. package/dist/floating.js +62 -0
  145. package/dist/glassBlur.jsx +145 -0
  146. package/dist/gradient.js +17 -0
  147. package/dist/haptics.js +44 -0
  148. package/dist/highlight.js +382 -0
  149. package/dist/index.js +85 -0
  150. package/dist/initials.js +4 -0
  151. package/dist/loadingGrid.js +81 -0
  152. package/dist/markdown/Markdown.jsx +515 -0
  153. package/dist/markdown/MarkdownTable.jsx +443 -0
  154. package/dist/markdown/tableText.js +68 -0
  155. package/dist/marketing/PricingModal.jsx +608 -0
  156. package/dist/marketing/UpgradeToProCard.jsx +164 -0
  157. package/dist/marketing/pricing.js +34 -0
  158. package/dist/media/ImageGallery.jsx +580 -0
  159. package/dist/media/MediaCard.jsx +162 -0
  160. package/dist/media/imageGrid.js +54 -0
  161. package/dist/motion.js +33 -0
  162. package/dist/pagerSwipe.js +104 -0
  163. package/dist/palette.js +104 -0
  164. package/dist/primitives/button.jsx +127 -0
  165. package/dist/primitives/card.jsx +249 -0
  166. package/dist/primitives/icon.jsx +37 -0
  167. package/dist/primitives/input.jsx +56 -0
  168. package/dist/primitives/keyboard-controller.jsx +207 -0
  169. package/dist/primitives/keyboard-parts.jsx +75 -0
  170. package/dist/primitives/native-only-animated-view.jsx +68 -0
  171. package/dist/primitives/overlay.jsx +391 -0
  172. package/dist/primitives/pager-gesture.jsx +131 -0
  173. package/dist/primitives/select-host.jsx +103 -0
  174. package/dist/primitives/select.jsx +555 -0
  175. package/dist/primitives/sheet-drag.jsx +420 -0
  176. package/dist/primitives/sheet-gesture.jsx +219 -0
  177. package/dist/primitives/swipe-row-gesture.jsx +341 -0
  178. package/dist/primitives/switch.jsx +105 -0
  179. package/dist/primitives/text.jsx +145 -0
  180. package/dist/primitives/toast-drag-gesture.jsx +94 -0
  181. package/dist/primitives/use-controllable-state.js +40 -0
  182. package/dist/primitives/web-click-guard.js +69 -0
  183. package/dist/push.js +166 -0
  184. package/dist/relativeTime.js +70 -0
  185. package/dist/router/RouterStackPageHeader.jsx +53 -0
  186. package/dist/selectA11y.js +32 -0
  187. package/dist/settings/MoreFromProjectV.jsx +168 -0
  188. package/dist/settings/SettingsEmptyState.jsx +102 -0
  189. package/dist/settings/SettingsField.jsx +49 -0
  190. package/dist/settings/SettingsSection.jsx +101 -0
  191. package/dist/settings/SettingsStack.jsx +17 -0
  192. package/dist/settings/SettingsToggleRow.jsx +163 -0
  193. package/dist/settings/projectVMobileApps.js +126 -0
  194. package/dist/settings/relaxedSizeStyle.js +11 -0
  195. package/dist/sheetDrag.js +76 -0
  196. package/dist/svgA11y.js +46 -0
  197. package/dist/swipeRow.js +161 -0
  198. package/dist/tabBarRoutes.js +41 -0
  199. package/dist/tabIndicator.js +139 -0
  200. package/dist/tailwind-preset.cjs +255 -0
  201. package/dist/tailwind-preset.d.cts +55 -0
  202. package/dist/theme.jsx +62 -0
  203. package/dist/toastChrome.js +110 -0
  204. package/dist/toastDrag.js +51 -0
  205. package/dist/toastStore.js +54 -0
  206. package/dist/tokens.js +70 -0
  207. package/dist/typography.js +40 -0
  208. package/dist/useReduceMotion.js +32 -0
  209. package/dist/useReduceTransparency.js +27 -0
  210. package/dist/useScheme.js +15 -0
  211. package/dist/video/InlineVideo.jsx +115 -0
  212. package/dist/webview/HtmlView.jsx +169 -0
  213. package/dist/webview/HtmlView.web.jsx +63 -0
  214. package/dist/webview/htmlView.js +43 -0
  215. package/package.json +70 -33
  216. package/src/DropdownMenu.tsx +28 -16
  217. package/src/FloatingTabBar.tsx +78 -41
  218. package/src/ai/conversation.tsx +12 -8
  219. package/src/glassBlur.tsx +47 -22
  220. package/src/primitives/swipe-row-gesture.tsx +11 -2
@@ -0,0 +1,57 @@
1
+ // `@vvedantb/native-ui/primitives`: fields, display, tabs, overlays and
2
+ // toasts. `BottomSheetContainer`, `DateTimeField` and `AmbientBackground` are
3
+ // not here; they have their own entries. `Text` and `TextClassContext` are the
4
+ // `primitives/text` variants (from 0.5.0); they are not on the root entry.
5
+ export { Text, TextClassContext } from "../primitives/text";
6
+ export { Button } from "../Button";
7
+ export { Input } from "../Input";
8
+ export { SearchInput } from "../SearchInput";
9
+ export { PasswordInput } from "../PasswordInput";
10
+ export { Textarea } from "../Textarea";
11
+ export { Label } from "../Label";
12
+ export { Select } from "../Select";
13
+ export { Switch } from "../Switch";
14
+ export { LabeledSwitchRow } from "../LabeledSwitchRow";
15
+ export { Checkbox } from "../Checkbox";
16
+ export { Badge } from "../Badge";
17
+ export { StatusDot } from "../StatusDot";
18
+ export { ColorSwatches } from "../ColorSwatches";
19
+ export { StatGrid } from "../StatGrid";
20
+ export { SectionLabel } from "../SectionLabel";
21
+ export { SheetRow } from "../SheetRow";
22
+ export { PageIndicator } from "../PageIndicator";
23
+ export { IconButton } from "../IconButton";
24
+ export { CaptureButton } from "../CaptureButton";
25
+ export { Separator } from "../Separator";
26
+ export { KeyboardAvoidingView } from "../primitives/keyboard-parts";
27
+ export { Progress } from "../Progress";
28
+ export { Spinner, CenteredSpinner } from "../Spinner";
29
+ export { LoadingState } from "../LoadingState";
30
+ export { Avatar, AvatarImage, AvatarFallback } from "../Avatar";
31
+ export { initials } from "../initials";
32
+ export { formatCompactRelativeTime } from "../relativeTime";
33
+ export { Chip } from "../Chip";
34
+ export { PillTabs } from "../PillTabs";
35
+ export { Pager } from "../Pager";
36
+ export { Tabs, TabsList, TabsTrigger, TabsContent } from "../Tabs";
37
+ export { ListRow } from "../ListRow";
38
+ export { DividedList, ListDivider } from "../DividedList";
39
+ export { SwipeableRow } from "../SwipeableRow";
40
+ export { closeSwipeRows, swipeActionsAccessibility } from "../swipeRow";
41
+ export { ImageGallery, ImageViewer } from "../media/ImageGallery";
42
+ export { MediaCard } from "../media/MediaCard";
43
+ export { imageAspect, imageGridTiles, imageViewerPage, MEDIA } from "../media/imageGrid";
44
+ export { SurfaceRow, SURFACE_ROW } from "../SurfaceRow";
45
+ export { HeaderIconButton } from "../HeaderIconButton";
46
+ export { ThemeToggle } from "../ThemeToggle";
47
+ export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "../Card";
48
+ export { Skeleton, CardSkeleton, SkeletonList, SkeletonRow } from "../Skeleton";
49
+ export { EmptyState } from "../EmptyState";
50
+ export { Dialog, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter } from "../Dialog";
51
+ export { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogAction, AlertDialogCancel } from "../AlertDialog";
52
+ export { ConfirmDialog } from "../ConfirmDialog";
53
+ export { BulkActionBar, BULK_BAR_LABEL_MIN_WIDTH } from "../BulkActionBar";
54
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuRadioItem, DropdownMenuSeparator } from "../DropdownMenu";
55
+ export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHandle, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter } from "../Sheet";
56
+ export { Toaster } from "../Toast";
57
+ export { toast } from "../toastStore";
@@ -0,0 +1,3 @@
1
+ // `@vvedantb/native-ui/search-input`: `SearchInput` on its own. Reaches no
2
+ // optional peer, not even a loader.
3
+ export { SearchInput } from "../SearchInput";
@@ -0,0 +1,4 @@
1
+ // `@vvedantb/native-ui/tab-bar`. Does not import `expo-router`; reaches
2
+ // `expo-blur` and `expo-haptics` only through their optional-peer loaders.
3
+ export { FloatingTabBar } from "../FloatingTabBar";
4
+ export { FLOATING_INSET, FLOATING_TAB_BAR_HEIGHT, FLOATING_TAB_BAR_HEIGHT_LARGE, tabBarReserve } from "../floating";
@@ -0,0 +1,7 @@
1
+ // `@vvedantb/native-ui/theme`: the provider, tokens and colour helpers.
2
+ export { cn } from "../cn";
3
+ export { tokens, NativeUiProvider, useNativeUi, useLargerText, useAccentColor, DEFAULT_ACCENT } from "../theme";
4
+ export { palette, withAlpha } from "../palette";
5
+ export { configureTheme } from "../configureTheme";
6
+ export { fontClass, fontFamily } from "../typography";
7
+ export { PINK_50, PINK_100, PINK_600, PINK_700, NEUTRAL_100, NEUTRAL_500, NEUTRAL_900, Colors } from "../colors";
@@ -0,0 +1,5 @@
1
+ // `@vvedantb/native-ui/toast`: `toast()` and `<Toaster />`. Reaches no heavy
2
+ // optional peer, not even a loader (the toast surface is flat from 0.3.12): no
3
+ // `expo-blur`, bottom sheet, date picker, `dayjs` or `expo-router`.
4
+ export { Toaster } from "../Toast";
5
+ export { toast } from "../toastStore";
@@ -0,0 +1,3 @@
1
+ // `@vvedantb/native-ui/video`. Imports `expo-video` (an optional peer): the
2
+ // only entry that does, so an app without it bundles no video player.
3
+ export { InlineVideo, INLINE_VIDEO_ASPECT } from "../video/InlineVideo";
@@ -0,0 +1,4 @@
1
+ // `@vvedantb/native-ui/webview`. Imports `react-native-webview` (an optional
2
+ // peer): the only entry that does, so an app without it bundles no WebView.
3
+ export { HtmlView } from "../webview/HtmlView";
4
+ export { HTML_VIEW_HEIGHT_SCRIPT, htmlViewNavigation, htmlViewPostScript, parseHtmlViewHeight } from "../webview/htmlView";
@@ -0,0 +1,509 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ // Reference screen for the AI chat parts (`@vvedantb/native-ui/ai`). Render
3
+ // `AiChatGallery` in a full-screen Expo route, with the same NativeWind setup
4
+ // as the rest of the package and a `SafeAreaProvider` above it. The thread is
5
+ // fixed sample text, not a model. It follows the app's larger-text setting.
6
+ // `ParityGallery` shows `AiChatSamples` in its "AI chat" section.
7
+ import { useState } from "react";
8
+ import { View } from "react-native";
9
+ import { IconFileText, IconPaperclip, IconSearch } from "@tabler/icons-react-native";
10
+ import { ActivityStep, AgentTrace, AgentTraceCollapsible, AgentTraceCollapsibleContent, AgentTraceCollapsibleTrigger, AgentTraceDescription, AgentTraceIcon, AgentTraceLine, AgentTraceTitle, Attachment, Attachments, CodeBlock, Conversation, ConversationContent, ConversationScrollButton, FileChip, Message, MessageAction, MessageActionsBar, MessageContent, PromptInput, PromptInputButton, Reasoning, ReasoningContent, ReasoningTrigger, ResponseText, Source, Sources, SourcesContent, SourcesTrigger, Suggestion, Suggestions, SubagentResultCard, SubagentRunCard, ToolApprovalCard, ToolDraftCard, formatElapsed, useStreamingDisclosure } from "../ai";
11
+ const SUGGESTIONS = ["Summarise this thread", "Draft a reply", "List the next steps", "Explain it more simply"];
12
+ const SAMPLE_ATTACHMENTS = [{
13
+ id: "notes",
14
+ filename: "meeting-notes.pdf",
15
+ mediaType: "application/pdf"
16
+ }, {
17
+ id: "sketch",
18
+ filename: "sketch.png",
19
+ mediaType: "image/png"
20
+ }];
21
+ const FINISHED_REASONING = "The question is how to keep one list the same on two devices.\nCompare a shared server copy with device-to-device sync, then suggest the simpler one.";
22
+ const FINISHED_REPLY = "Keep one copy of the list on a server and have each device read and write it.\n\nWhen a device changes an item, it sends the change with a timestamp. The other device fetches changes it has not seen.";
23
+ const SAMPLE_CODE = `type Change = {\n itemId: string;\n updatedAt: number;\n};`;
24
+ const STREAMING_REASONING = "Offline edits need to wait in a queue on the device.\nWhen the connection returns, send the queue in order and merge by timestamp…";
25
+
26
+ /**
27
+ * The sample thread: a user message, a finished assistant message (folded
28
+ * reasoning and trace, reply, code, sources and actions), a second user
29
+ * message, and an assistant message that is still working while `streaming`.
30
+ */
31
+ const DRAFT_FIELDS = [{
32
+ key: "to",
33
+ role: "to",
34
+ value: "team@example.com"
35
+ }, {
36
+ key: "subject",
37
+ role: "subject",
38
+ value: "Weekly plan"
39
+ }, {
40
+ key: "body",
41
+ role: "body",
42
+ value: "Here is the plan for next week."
43
+ }];
44
+ const RUN_STATUSES = ["queued", "running", "done", "failed", "cancelled", "timed_out"];
45
+
46
+ /** Tool approval, draft and subagent cards, with testIDs for E2E. */
47
+ export function AiCardSamples() {
48
+ const $ = _c(13);
49
+ const [decision, setDecision] = useState("none");
50
+ const [cancelled, setCancelled] = useState(false);
51
+ let t0;
52
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
53
+ t0 = name => (choice, edits) => setDecision(`${name}:${choice}${edits ? `:${JSON.stringify(edits)}` : ""}`);
54
+ $[0] = t0;
55
+ } else {
56
+ t0 = $[0];
57
+ }
58
+ const decide = t0;
59
+ const t1 = `Last decision: ${decision}`;
60
+ let t2;
61
+ if ($[1] !== t1) {
62
+ t2 = <ResponseText>{t1}</ResponseText>;
63
+ $[1] = t1;
64
+ $[2] = t2;
65
+ } else {
66
+ t2 = $[2];
67
+ }
68
+ let t3;
69
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
70
+ t3 = {
71
+ title: "Review plan"
72
+ };
73
+ $[3] = t3;
74
+ } else {
75
+ t3 = $[3];
76
+ }
77
+ let t4;
78
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
79
+ t4 = <ToolApprovalCard testID="gallery-approval" toolName="create_task" args={t3} server="tasks" routineMode={true} expiresLabel="tomorrow" target="Project board" onDecide={decide("approval")} />;
80
+ $[4] = t4;
81
+ } else {
82
+ t4 = $[4];
83
+ }
84
+ let t5;
85
+ let t6;
86
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
87
+ t5 = <ToolDraftCard testID="gallery-draft" toolName="send_message" fields={DRAFT_FIELDS} server="mail" expiresLabel="in 2 hours" approveLabel="Send" denyLabel="Discard" onDecide={decide("draft")} />;
88
+ t6 = RUN_STATUSES.map(status => <SubagentRunCard key={status} testID={`gallery-run-${status}`} title="Research" status={status} elapsedSeconds={65} statusLine={status === "running" ? "Step 2 of 4" : undefined} error={status === "failed" ? "The source could not be reached." : undefined} onCancel={() => setCancelled(true)} />);
89
+ $[5] = t5;
90
+ $[6] = t6;
91
+ } else {
92
+ t5 = $[5];
93
+ t6 = $[6];
94
+ }
95
+ const t7 = `Cancelled: ${cancelled ? "yes" : "no"}`;
96
+ let t8;
97
+ if ($[7] !== t7) {
98
+ t8 = <ResponseText>{t7}</ResponseText>;
99
+ $[7] = t7;
100
+ $[8] = t8;
101
+ } else {
102
+ t8 = $[8];
103
+ }
104
+ let t9;
105
+ if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
106
+ t9 = <SubagentResultCard testID="gallery-result" title="Research" summary="Three sources found." approvalPending={true} approvalPendingIn="Planner" handoffs={[{
107
+ toolName: "create_task",
108
+ server: "tasks",
109
+ argsSummary: "{\"title\":\"Review plan\"}"
110
+ }]} />;
111
+ $[9] = t9;
112
+ } else {
113
+ t9 = $[9];
114
+ }
115
+ let t10;
116
+ if ($[10] !== t2 || $[11] !== t8) {
117
+ t10 = <>{t2}{t4}{t5}{t6}{t8}{t9}</>;
118
+ $[10] = t2;
119
+ $[11] = t8;
120
+ $[12] = t10;
121
+ } else {
122
+ t10 = $[12];
123
+ }
124
+ return t10;
125
+ }
126
+ export function AiChatSamples(t0) {
127
+ const $ = _c(58);
128
+ const {
129
+ streaming: t1
130
+ } = t0;
131
+ const streaming = t1 === undefined ? true : t1;
132
+ const [feedback, setFeedback] = useState(null);
133
+ const searchFold = useStreamingDisclosure(streaming);
134
+ let t2;
135
+ if ($[0] !== feedback) {
136
+ t2 = kind => setFeedback(feedback === kind ? null : kind);
137
+ $[0] = feedback;
138
+ $[1] = t2;
139
+ } else {
140
+ t2 = $[1];
141
+ }
142
+ const toggle = t2;
143
+ let t3;
144
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
145
+ t3 = <Message from="user"><MessageContent>How do I keep a list in sync across two devices?</MessageContent></Message>;
146
+ $[2] = t3;
147
+ } else {
148
+ t3 = $[2];
149
+ }
150
+ let t4;
151
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
152
+ t4 = <Reasoning duration={8}><ReasoningTrigger /><ReasoningContent>{FINISHED_REASONING}</ReasoningContent></Reasoning>;
153
+ $[3] = t4;
154
+ } else {
155
+ t4 = $[3];
156
+ }
157
+ let t5;
158
+ let t6;
159
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
160
+ t5 = <AgentTraceIcon icon={IconSearch} />;
161
+ t6 = <AgentTraceTitle>Used 2 tools</AgentTraceTitle>;
162
+ $[4] = t5;
163
+ $[5] = t6;
164
+ } else {
165
+ t5 = $[4];
166
+ t6 = $[5];
167
+ }
168
+ let t7;
169
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
170
+ t7 = <AgentTraceCollapsibleTrigger><AgentTraceLine>{t5}{t6}<AgentTraceDescription>{`Worked for ${formatElapsed(14)}`}</AgentTraceDescription></AgentTraceLine></AgentTraceCollapsibleTrigger>;
171
+ $[6] = t7;
172
+ } else {
173
+ t7 = $[6];
174
+ }
175
+ let t8;
176
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
177
+ t8 = <ActivityStep icon={IconSearch} label="Searched the web" description="5 results" />;
178
+ $[7] = t8;
179
+ } else {
180
+ t8 = $[7];
181
+ }
182
+ let t10;
183
+ let t11;
184
+ let t9;
185
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
186
+ t9 = <AgentTraceCollapsible>{t7}<AgentTraceCollapsibleContent><AgentTrace>{t8}<AgentTraceLine><AgentTraceIcon icon={IconFileText} /><AgentTraceTitle>Read</AgentTraceTitle><FileChip name="sync-notes.md" /></AgentTraceLine></AgentTrace></AgentTraceCollapsibleContent></AgentTraceCollapsible>;
187
+ t10 = <ResponseText>{FINISHED_REPLY}</ResponseText>;
188
+ t11 = <CodeBlock language="ts" code={SAMPLE_CODE} onCopy={_temp} />;
189
+ $[8] = t10;
190
+ $[9] = t11;
191
+ $[10] = t9;
192
+ } else {
193
+ t10 = $[8];
194
+ t11 = $[9];
195
+ t9 = $[10];
196
+ }
197
+ let t12;
198
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
199
+ t12 = <SourcesTrigger count={2} />;
200
+ $[11] = t12;
201
+ } else {
202
+ t12 = $[11];
203
+ }
204
+ let t13;
205
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
206
+ t13 = <MessageContent>{t4}{t9}{t10}{t11}<Sources>{t12}<SourcesContent><Source href="https://example.com/sync" title="Syncing data between devices" /><Source href="https://example.com/timestamps" title="Merging changes by timestamp" /></SourcesContent></Sources></MessageContent>;
207
+ $[12] = t13;
208
+ } else {
209
+ t13 = $[12];
210
+ }
211
+ let t14;
212
+ let t15;
213
+ if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
214
+ t14 = <MessageAction kind="copy" />;
215
+ t15 = <MessageAction kind="retry" />;
216
+ $[13] = t14;
217
+ $[14] = t15;
218
+ } else {
219
+ t14 = $[13];
220
+ t15 = $[14];
221
+ }
222
+ const t16 = feedback === "like";
223
+ let t17;
224
+ if ($[15] !== toggle) {
225
+ t17 = () => toggle("like");
226
+ $[15] = toggle;
227
+ $[16] = t17;
228
+ } else {
229
+ t17 = $[16];
230
+ }
231
+ let t18;
232
+ if ($[17] !== t16 || $[18] !== t17) {
233
+ t18 = <MessageAction kind="like" selected={t16} onPress={t17} />;
234
+ $[17] = t16;
235
+ $[18] = t17;
236
+ $[19] = t18;
237
+ } else {
238
+ t18 = $[19];
239
+ }
240
+ const t19 = feedback === "dislike";
241
+ let t20;
242
+ if ($[20] !== toggle) {
243
+ t20 = () => toggle("dislike");
244
+ $[20] = toggle;
245
+ $[21] = t20;
246
+ } else {
247
+ t20 = $[21];
248
+ }
249
+ let t21;
250
+ if ($[22] !== t19 || $[23] !== t20) {
251
+ t21 = <MessageAction kind="dislike" selected={t19} onPress={t20} />;
252
+ $[22] = t19;
253
+ $[23] = t20;
254
+ $[24] = t21;
255
+ } else {
256
+ t21 = $[24];
257
+ }
258
+ let t22;
259
+ if ($[25] !== t18 || $[26] !== t21) {
260
+ t22 = <Message from="assistant">{t13}<MessageActionsBar>{t14}{t15}{t18}{t21}</MessageActionsBar></Message>;
261
+ $[25] = t18;
262
+ $[26] = t21;
263
+ $[27] = t22;
264
+ } else {
265
+ t22 = $[27];
266
+ }
267
+ let t23;
268
+ if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
269
+ t23 = <Message from="user"><MessageContent>And when one device is offline?</MessageContent></Message>;
270
+ $[28] = t23;
271
+ } else {
272
+ t23 = $[28];
273
+ }
274
+ let t24;
275
+ let t25;
276
+ if ($[29] === Symbol.for("react.memo_cache_sentinel")) {
277
+ t24 = <ReasoningTrigger />;
278
+ t25 = <ReasoningContent>{STREAMING_REASONING}</ReasoningContent>;
279
+ $[29] = t24;
280
+ $[30] = t25;
281
+ } else {
282
+ t24 = $[29];
283
+ t25 = $[30];
284
+ }
285
+ let t26;
286
+ if ($[31] !== streaming) {
287
+ t26 = <Reasoning isStreaming={streaming}>{t24}{t25}</Reasoning>;
288
+ $[31] = streaming;
289
+ $[32] = t26;
290
+ } else {
291
+ t26 = $[32];
292
+ }
293
+ let t27;
294
+ if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
295
+ t27 = <AgentTraceIcon icon={IconSearch} />;
296
+ $[33] = t27;
297
+ } else {
298
+ t27 = $[33];
299
+ }
300
+ const t28 = streaming ? "Searching for offline sync" : "Searched for offline sync";
301
+ let t29;
302
+ if ($[34] !== streaming || $[35] !== t28) {
303
+ t29 = <AgentTraceCollapsibleTrigger><AgentTraceLine>{t27}<AgentTraceTitle shimmer={streaming}>{t28}</AgentTraceTitle></AgentTraceLine></AgentTraceCollapsibleTrigger>;
304
+ $[34] = streaming;
305
+ $[35] = t28;
306
+ $[36] = t29;
307
+ } else {
308
+ t29 = $[36];
309
+ }
310
+ let t30;
311
+ if ($[37] === Symbol.for("react.memo_cache_sentinel")) {
312
+ t30 = <AgentTraceCollapsibleContent>Offline-first sync, change queues, conflict handling</AgentTraceCollapsibleContent>;
313
+ $[37] = t30;
314
+ } else {
315
+ t30 = $[37];
316
+ }
317
+ let t31;
318
+ if ($[38] !== searchFold || $[39] !== t29) {
319
+ t31 = <AgentTraceCollapsible {...searchFold}>{t29}{t30}</AgentTraceCollapsible>;
320
+ $[38] = searchFold;
321
+ $[39] = t29;
322
+ $[40] = t31;
323
+ } else {
324
+ t31 = $[40];
325
+ }
326
+ const t32 = streaming ? "Reading sync-notes.md" : "Read sync-notes.md";
327
+ const t33 = streaming ? "running" : "complete";
328
+ let t34;
329
+ if ($[41] !== streaming) {
330
+ t34 = streaming ? undefined : `Worked for ${formatElapsed(6)}`;
331
+ $[41] = streaming;
332
+ $[42] = t34;
333
+ } else {
334
+ t34 = $[42];
335
+ }
336
+ let t35;
337
+ if ($[43] !== t32 || $[44] !== t33 || $[45] !== t34) {
338
+ t35 = <ActivityStep icon={IconFileText} label={t32} status={t33} description={t34} />;
339
+ $[43] = t32;
340
+ $[44] = t33;
341
+ $[45] = t34;
342
+ $[46] = t35;
343
+ } else {
344
+ t35 = $[46];
345
+ }
346
+ let t36;
347
+ if ($[47] !== streaming) {
348
+ t36 = streaming ? null : <ResponseText>{"Queue each change on the device while it is offline.\n\nWhen it reconnects, send the queue in order. If both devices changed the same item, keep the newer change."}</ResponseText>;
349
+ $[47] = streaming;
350
+ $[48] = t36;
351
+ } else {
352
+ t36 = $[48];
353
+ }
354
+ let t37;
355
+ if ($[49] !== t26 || $[50] !== t31 || $[51] !== t35 || $[52] !== t36) {
356
+ t37 = <Message from="assistant"><MessageContent>{t26}{t31}{t35}{t36}</MessageContent></Message>;
357
+ $[49] = t26;
358
+ $[50] = t31;
359
+ $[51] = t35;
360
+ $[52] = t36;
361
+ $[53] = t37;
362
+ } else {
363
+ t37 = $[53];
364
+ }
365
+ let t38;
366
+ if ($[54] === Symbol.for("react.memo_cache_sentinel")) {
367
+ t38 = <AiCardSamples />;
368
+ $[54] = t38;
369
+ } else {
370
+ t38 = $[54];
371
+ }
372
+ let t39;
373
+ if ($[55] !== t22 || $[56] !== t37) {
374
+ t39 = <>{t3}{t22}{t23}{t37}{t38}</>;
375
+ $[55] = t22;
376
+ $[56] = t37;
377
+ $[57] = t39;
378
+ } else {
379
+ t39 = $[57];
380
+ }
381
+ return t39;
382
+ }
383
+
384
+ /**
385
+ * A full chat screen: the sample thread in a `Conversation` with its scroll
386
+ * button, suggestions, and the composer with sample attachments and an
387
+ * attach tool. The last message streams until Stop is pressed; then sent
388
+ * messages are added to the thread.
389
+ */
390
+ function _temp() {}
391
+ export function AiChatGallery() {
392
+ const $ = _c(26);
393
+ const [status, setStatus] = useState("streaming");
394
+ const [draft, setDraft] = useState("");
395
+ let t0;
396
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
397
+ t0 = [];
398
+ $[0] = t0;
399
+ } else {
400
+ t0 = $[0];
401
+ }
402
+ const [sent, setSent] = useState(t0);
403
+ const [attachments, setAttachments] = useState(SAMPLE_ATTACHMENTS);
404
+ const t1 = status === "streaming";
405
+ let t2;
406
+ if ($[1] !== t1) {
407
+ t2 = <AiChatSamples streaming={t1} />;
408
+ $[1] = t1;
409
+ $[2] = t2;
410
+ } else {
411
+ t2 = $[2];
412
+ }
413
+ let t3;
414
+ if ($[3] !== sent) {
415
+ t3 = sent.map(_temp2);
416
+ $[3] = sent;
417
+ $[4] = t3;
418
+ } else {
419
+ t3 = $[4];
420
+ }
421
+ let t4;
422
+ if ($[5] !== t2 || $[6] !== t3) {
423
+ t4 = <ConversationContent>{t2}{t3}</ConversationContent>;
424
+ $[5] = t2;
425
+ $[6] = t3;
426
+ $[7] = t4;
427
+ } else {
428
+ t4 = $[7];
429
+ }
430
+ let t5;
431
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
432
+ t5 = <ConversationScrollButton />;
433
+ $[8] = t5;
434
+ } else {
435
+ t5 = $[8];
436
+ }
437
+ let t6;
438
+ if ($[9] !== t4) {
439
+ t6 = <Conversation>{t4}{t5}</Conversation>;
440
+ $[9] = t4;
441
+ $[10] = t6;
442
+ } else {
443
+ t6 = $[10];
444
+ }
445
+ let t7;
446
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
447
+ t7 = <Suggestions className="pt-2" contentContainerClassName="px-3">{SUGGESTIONS.map(suggestion => <Suggestion key={suggestion} suggestion={suggestion} onPress={setDraft} />)}</Suggestions>;
448
+ $[11] = t7;
449
+ } else {
450
+ t7 = $[11];
451
+ }
452
+ let t8;
453
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
454
+ t8 = () => setStatus("ready");
455
+ $[12] = t8;
456
+ } else {
457
+ t8 = $[12];
458
+ }
459
+ let t9;
460
+ if ($[13] !== sent) {
461
+ t9 = text_0 => {
462
+ setSent([...sent, text_0]);
463
+ setAttachments([]);
464
+ };
465
+ $[13] = sent;
466
+ $[14] = t9;
467
+ } else {
468
+ t9 = $[14];
469
+ }
470
+ let t10;
471
+ if ($[15] !== attachments) {
472
+ t10 = attachments.length > 0 ? <Attachments>{attachments.map(attachment => <Attachment key={attachment.id} data={attachment} onRemove={() => setAttachments(attachments.filter(item => item.id !== attachment.id))} />)}</Attachments> : null;
473
+ $[15] = attachments;
474
+ $[16] = t10;
475
+ } else {
476
+ t10 = $[16];
477
+ }
478
+ let t11;
479
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
480
+ t11 = <PromptInputButton icon={IconPaperclip} label="Attach files" onPress={() => setAttachments(SAMPLE_ATTACHMENTS)} />;
481
+ $[17] = t11;
482
+ } else {
483
+ t11 = $[17];
484
+ }
485
+ let t12;
486
+ if ($[18] !== draft || $[19] !== status || $[20] !== t10 || $[21] !== t9) {
487
+ t12 = <PromptInput value={draft} onChangeText={setDraft} status={status} onStop={t8} onSubmit={t9} header={t10} toolbar={t11} />;
488
+ $[18] = draft;
489
+ $[19] = status;
490
+ $[20] = t10;
491
+ $[21] = t9;
492
+ $[22] = t12;
493
+ } else {
494
+ t12 = $[22];
495
+ }
496
+ let t13;
497
+ if ($[23] !== t12 || $[24] !== t6) {
498
+ t13 = <View className="flex-1">{t6}{t7}{t12}</View>;
499
+ $[23] = t12;
500
+ $[24] = t6;
501
+ $[25] = t13;
502
+ } else {
503
+ t13 = $[25];
504
+ }
505
+ return t13;
506
+ }
507
+ function _temp2(text, index) {
508
+ return <Message key={`${index}-${text}`} from="user"><MessageContent>{text}</MessageContent></Message>;
509
+ }