@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,626 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useContext, useState } from "react";
3
+ import { Platform, Pressable, Text, View, useWindowDimensions } from "react-native";
4
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
5
+ import { IconArrowUp, IconChevronDown, IconPlayerStopFilled } from "@tabler/icons-react-native";
6
+ import { cn } from "../cn";
7
+ import { MIN_TOUCH_TARGET, fieldStyle, fieldTextStyle, sizeStyle, touchSlop, typeStyle } from "../controlStyles";
8
+ import { withAlpha } from "../palette";
9
+ import { tokens } from "../tokens";
10
+ import { Input as FieldInput } from "../primitives/input";
11
+ import { COMPOSER_INPUT_ID, KeyboardAvoidingView, KeyboardLiftContext } from "../primitives/keyboard-parts";
12
+ import { usePressFeedback } from "../motion";
13
+ import { useControllableState } from "../primitives/use-controllable-state";
14
+ import { useLargerText } from "../theme";
15
+ import { useScheme } from "../useScheme";
16
+ import { ChatIconButton } from "./icon-button";
17
+
18
+ /** The `ai` SDK chat status the web `PromptInputSubmit` takes. */
19
+
20
+ /** Whether the AI is answering: `submitted` (waiting) or `streaming`. */
21
+ export function isGenerating(status) {
22
+ return status === "submitted" || status === "streaming";
23
+ }
24
+ // The web `PromptInputSubmit` and `PromptInputButton` keep `shape="rounded"`
25
+ // (`rounded-lg`, 16) as field addons. At the 32 `icon-sm` size 16 is half the
26
+ // side, so the web draws a circle. These stay pills: the same circle at 32, and
27
+ // still a circle at 44 with larger text, where 16 would draw a rounded square.
28
+
29
+ /**
30
+ * Send, or stop while the AI answers: the web `default` `icon-sm` button
31
+ * (32, round, slop to 44). Send is an up arrow on the primary fill, faded by
32
+ * the disabled `Button` with nothing to send, as the web send button. While
33
+ * `status` is `submitted` or `streaming` it is a filled square labelled
34
+ * "Stop" that calls `onStop` (disabled without one).
35
+ */
36
+ export function PromptInputSubmit(t0) {
37
+ const $ = _c(10);
38
+ const {
39
+ status,
40
+ onSubmit,
41
+ onStop,
42
+ canSubmit: t1,
43
+ size,
44
+ testID
45
+ } = t0;
46
+ const canSubmit = t1 === undefined ? true : t1;
47
+ if (isGenerating(status)) {
48
+ const t2 = !onStop;
49
+ let t3;
50
+ if ($[0] !== onStop || $[1] !== size || $[2] !== t2 || $[3] !== testID) {
51
+ t3 = <ChatIconButton icon={IconPlayerStopFilled} label="Stop" variant="primary" size={size} onPress={onStop} disabled={t2} testID={testID} />;
52
+ $[0] = onStop;
53
+ $[1] = size;
54
+ $[2] = t2;
55
+ $[3] = testID;
56
+ $[4] = t3;
57
+ } else {
58
+ t3 = $[4];
59
+ }
60
+ return t3;
61
+ }
62
+ const t2 = !canSubmit;
63
+ let t3;
64
+ if ($[5] !== onSubmit || $[6] !== size || $[7] !== t2 || $[8] !== testID) {
65
+ t3 = <ChatIconButton icon={IconArrowUp} label="Send" variant="primary" size={size} onPress={onSubmit} disabled={t2} testID={testID} />;
66
+ $[5] = onSubmit;
67
+ $[6] = size;
68
+ $[7] = t2;
69
+ $[8] = testID;
70
+ $[9] = t3;
71
+ } else {
72
+ t3 = $[9];
73
+ }
74
+ return t3;
75
+ }
76
+ /** A ghost tool button for the composer `toolbar`, such as attach (web `PromptInputButton`). Give it `icon` and `label`. */
77
+ export function PromptInputButton(props) {
78
+ const $ = _c(2);
79
+ let t0;
80
+ if ($[0] !== props) {
81
+ t0 = <ChatIconButton variant="ghost" {...props} />;
82
+ $[0] = props;
83
+ $[1] = t0;
84
+ } else {
85
+ t0 = $[1];
86
+ }
87
+ return t0;
88
+ }
89
+
90
+ /**
91
+ * The web `ModelPicker` trigger (`model-picker.tsx` `TRIGGER_CLASS`), the
92
+ * chip a composer footer holds: `h-7 gap-1.5 rounded-md px-2`, a 14 icon, the
93
+ * suffix at `/70` after " · ", and a 12 chevron at `opacity-60`. The label is
94
+ * `text-sm` (14), the phone floor for tappable text (the web is `text-xs`).
95
+ */
96
+ export const PROMPT_INPUT_CHIP = {
97
+ height: 28,
98
+ paddingX: 8,
99
+ gap: 6,
100
+ radius: tokens.radius.md,
101
+ iconSize: 14,
102
+ chevronSize: 12,
103
+ chevronOpacity: 0.6,
104
+ suffixOpacity: 0.7,
105
+ /** The narrowest label worth drawing: about two characters and the ellipsis at `text-sm` (2em). */
106
+ labelMinWidth: 28,
107
+ /** `size="touch"`: 36 on screen, 4 slop above and below, so a 44 bar holds its whole target. */
108
+ touchHeight: 36
109
+ };
110
+ /**
111
+ * A chip for the composer `footer`, the web `ModelPicker` trigger: 28 high on
112
+ * screen (36 with `size="touch"`), slop to 44 above and below. The label shrinks and truncates, so a
113
+ * long model name gives up width to the chips beside it, as the web
114
+ * `max-sm:truncate`; the icon and chevron keep their size. Below
115
+ * `labelMinWidth` (scaled by the system font size) the label hides, so a
116
+ * squeezed chip is its icon and chevron, as the web at 390, not a sliver of a
117
+ * letter. Disabled dims to 50%, as the web `disabled:opacity-50`.
118
+ */
119
+ export function PromptInputChip(t0) {
120
+ const $ = _c(60);
121
+ const {
122
+ icon,
123
+ label,
124
+ suffix,
125
+ count,
126
+ chevron: t1,
127
+ weight: t2,
128
+ color,
129
+ accessibilityLabel,
130
+ expanded,
131
+ disabled: t3,
132
+ size: t4,
133
+ onPress,
134
+ testID
135
+ } = t0;
136
+ const chevron = t1 === undefined ? true : t1;
137
+ const weight = t2 === undefined ? "medium" : t2;
138
+ const disabled = t3 === undefined ? false : t3;
139
+ const size = t4 === undefined ? "sm" : t4;
140
+ const height = size === "touch" ? PROMPT_INPUT_CHIP.touchHeight : PROMPT_INPUT_CHIP.height;
141
+ const scheme = useScheme();
142
+ const pressed = usePressFeedback();
143
+ const {
144
+ fontScale
145
+ } = useWindowDimensions();
146
+ const [readable, setReadable] = useState(true);
147
+ const tint = color ?? tokens.color.muted[scheme];
148
+ let t5;
149
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
150
+ t5 = sizeStyle("text-sm");
151
+ $[0] = t5;
152
+ } else {
153
+ t5 = $[0];
154
+ }
155
+ let t6;
156
+ if ($[1] !== tint) {
157
+ t6 = [t5, {
158
+ color: tint
159
+ }];
160
+ $[1] = tint;
161
+ $[2] = t6;
162
+ } else {
163
+ t6 = $[2];
164
+ }
165
+ const text = t6;
166
+ let t7;
167
+ if ($[3] !== accessibilityLabel || $[4] !== count || $[5] !== label || $[6] !== suffix) {
168
+ t7 = accessibilityLabel ?? [label, suffix, count].filter(_temp).join(", ");
169
+ $[3] = accessibilityLabel;
170
+ $[4] = count;
171
+ $[5] = label;
172
+ $[6] = suffix;
173
+ $[7] = t7;
174
+ } else {
175
+ t7 = $[7];
176
+ }
177
+ const name = t7;
178
+ let t8;
179
+ if ($[8] !== disabled || $[9] !== expanded) {
180
+ t8 = {
181
+ disabled,
182
+ expanded
183
+ };
184
+ $[8] = disabled;
185
+ $[9] = expanded;
186
+ $[10] = t8;
187
+ } else {
188
+ t8 = $[10];
189
+ }
190
+ let t9;
191
+ if ($[11] !== height) {
192
+ t9 = touchSlop(MIN_TOUCH_TARGET, height);
193
+ $[11] = height;
194
+ $[12] = t9;
195
+ } else {
196
+ t9 = $[12];
197
+ }
198
+ const t10 = disabled && "opacity-50";
199
+ let t11;
200
+ if ($[13] !== pressed || $[14] !== t10) {
201
+ t11 = cn("min-w-0 shrink flex-row items-center", pressed, t10);
202
+ $[13] = pressed;
203
+ $[14] = t10;
204
+ $[15] = t11;
205
+ } else {
206
+ t11 = $[15];
207
+ }
208
+ let t12;
209
+ if ($[16] !== height) {
210
+ t12 = {
211
+ minHeight: height,
212
+ paddingHorizontal: PROMPT_INPUT_CHIP.paddingX,
213
+ gap: PROMPT_INPUT_CHIP.gap,
214
+ borderRadius: PROMPT_INPUT_CHIP.radius
215
+ };
216
+ $[16] = height;
217
+ $[17] = t12;
218
+ } else {
219
+ t12 = $[17];
220
+ }
221
+ let t13;
222
+ if ($[18] !== icon) {
223
+ t13 = icon ? <View className="shrink-0">{icon}</View> : null;
224
+ $[18] = icon;
225
+ $[19] = t13;
226
+ } else {
227
+ t13 = $[19];
228
+ }
229
+ let t14;
230
+ if ($[20] !== fontScale) {
231
+ t14 = event => setReadable(event.nativeEvent.layout.width >= PROMPT_INPUT_CHIP.labelMinWidth * Math.max(1, fontScale));
232
+ $[20] = fontScale;
233
+ $[21] = t14;
234
+ } else {
235
+ t14 = $[21];
236
+ }
237
+ const t15 = weight === "medium" ? "font-instrument-sans-medium" : "font-instrument-sans";
238
+ let t16;
239
+ if ($[22] !== t15) {
240
+ t16 = cn("min-w-0 shrink text-sm", t15);
241
+ $[22] = t15;
242
+ $[23] = t16;
243
+ } else {
244
+ t16 = $[23];
245
+ }
246
+ let t17;
247
+ if ($[24] !== weight) {
248
+ t17 = weight === "medium" ? typeStyle("medium") : null;
249
+ $[24] = weight;
250
+ $[25] = t17;
251
+ } else {
252
+ t17 = $[25];
253
+ }
254
+ let t18;
255
+ if ($[26] !== readable) {
256
+ t18 = readable ? null : {
257
+ opacity: 0
258
+ };
259
+ $[26] = readable;
260
+ $[27] = t18;
261
+ } else {
262
+ t18 = $[27];
263
+ }
264
+ let t19;
265
+ if ($[28] !== t17 || $[29] !== t18 || $[30] !== text) {
266
+ t19 = [...text, t17, t18];
267
+ $[28] = t17;
268
+ $[29] = t18;
269
+ $[30] = text;
270
+ $[31] = t19;
271
+ } else {
272
+ t19 = $[31];
273
+ }
274
+ let t20;
275
+ if ($[32] !== suffix || $[33] !== tint) {
276
+ t20 = suffix ? <Text style={{
277
+ color: withAlpha(tint, PROMPT_INPUT_CHIP.suffixOpacity)
278
+ }}>{` · ${suffix}`}</Text> : null;
279
+ $[32] = suffix;
280
+ $[33] = tint;
281
+ $[34] = t20;
282
+ } else {
283
+ t20 = $[34];
284
+ }
285
+ let t21;
286
+ if ($[35] !== label || $[36] !== t14 || $[37] !== t16 || $[38] !== t19 || $[39] !== t20) {
287
+ t21 = <Text numberOfLines={1} onLayout={t14} className={t16} style={t19}>{label}{t20}</Text>;
288
+ $[35] = label;
289
+ $[36] = t14;
290
+ $[37] = t16;
291
+ $[38] = t19;
292
+ $[39] = t20;
293
+ $[40] = t21;
294
+ } else {
295
+ t21 = $[40];
296
+ }
297
+ let t22;
298
+ if ($[41] !== count || $[42] !== text) {
299
+ t22 = count !== undefined ? <Text className="font-instrument-sans-medium text-sm" style={[...text, typeStyle("medium"), {
300
+ fontVariant: ["tabular-nums"]
301
+ }]}>{count}</Text> : null;
302
+ $[41] = count;
303
+ $[42] = text;
304
+ $[43] = t22;
305
+ } else {
306
+ t22 = $[43];
307
+ }
308
+ let t23;
309
+ if ($[44] !== chevron || $[45] !== tint) {
310
+ t23 = chevron ? <View style={{
311
+ opacity: PROMPT_INPUT_CHIP.chevronOpacity
312
+ }}><IconChevronDown size={PROMPT_INPUT_CHIP.chevronSize} color={tint} /></View> : null;
313
+ $[44] = chevron;
314
+ $[45] = tint;
315
+ $[46] = t23;
316
+ } else {
317
+ t23 = $[46];
318
+ }
319
+ let t24;
320
+ if ($[47] !== disabled || $[48] !== name || $[49] !== onPress || $[50] !== t11 || $[51] !== t12 || $[52] !== t13 || $[53] !== t21 || $[54] !== t22 || $[55] !== t23 || $[56] !== t8 || $[57] !== t9 || $[58] !== testID) {
321
+ t24 = <Pressable testID={testID} accessibilityRole="button" accessibilityLabel={name} accessibilityState={t8} disabled={disabled} onPress={onPress} hitSlop={t9} className={t11} style={t12}>{t13}{t21}{t22}{t23}</Pressable>;
322
+ $[47] = disabled;
323
+ $[48] = name;
324
+ $[49] = onPress;
325
+ $[50] = t11;
326
+ $[51] = t12;
327
+ $[52] = t13;
328
+ $[53] = t21;
329
+ $[54] = t22;
330
+ $[55] = t23;
331
+ $[56] = t8;
332
+ $[57] = t9;
333
+ $[58] = testID;
334
+ $[59] = t24;
335
+ } else {
336
+ t24 = $[59];
337
+ }
338
+ return t24;
339
+ }
340
+ function _temp(part) {
341
+ return part !== undefined;
342
+ }
343
+ /** The web `Composer` inline radius, `rounded-[1.25rem]`. */
344
+ const INLINE_RADIUS = 20;
345
+
346
+ /**
347
+ * Eva's `pill` composer: 48 high on one line (border 1, then 5 around a 36
348
+ * field: the web `h-12 py-1` centres the 36 field and send button in 38),
349
+ * `pl-1.5` / `pr-1.5`, and radius 24 (`rounded-full` at 48). Its placeholder
350
+ * is the muted colour at 90% (`data-empty:before:text-muted-foreground/90`).
351
+ */
352
+ const PILL = {
353
+ radius: 24,
354
+ paddingY: 5,
355
+ paddingX: 6,
356
+ lineHeight: 36,
357
+ placeholderAlpha: 0.9
358
+ };
359
+
360
+ /** The field grows to this height, then scrolls: about 6 lines of 24 (with `py-2.5`), and about 8 of `text-xl` with larger text. */
361
+ const MAX_FIELD_HEIGHT = {
362
+ regular: 160,
363
+ larger: 240
364
+ };
365
+
366
+ /**
367
+ * React Native Web draws a multiline field as a `textarea` with the HTML
368
+ * default of 2 rows, and the auto-grow keeps that height. One row there; on
369
+ * native, `numberOfLines` would lock the line count on Android, so none.
370
+ */
371
+ const ONE_ROW = Platform.OS === "web" ? 1 : undefined;
372
+
373
+ /**
374
+ * The chat composer: the web `PromptInput` field (`rounded-field border
375
+ * bg-field-background`, `fieldStyle`) with an optional `header` row, a
376
+ * multiline field that grows from one line, and a footer of `toolbar` tools
377
+ * and the send / stop button. It sits in a `KeyboardAvoidingView` (padding,
378
+ * on iOS and Android; frame by frame with `KeyboardControllerProvider`) and
379
+ * pads the safe-area insets, so put it last in a full-height column, under the
380
+ * `Conversation`. Inside a part that lifts it already (`ConversationDock`
381
+ * with `KeyboardControllerProvider`, `ChatThread`) it adds no lift of its own.
382
+ */
383
+ export function PromptInput(t0) {
384
+ const $ = _c(65);
385
+ const {
386
+ value,
387
+ defaultValue: t1,
388
+ onChangeText,
389
+ onSubmit,
390
+ status,
391
+ onStop,
392
+ placeholder: t2,
393
+ accessibilityLabel: t3,
394
+ replyTo,
395
+ header,
396
+ toolbar,
397
+ footer,
398
+ menu,
399
+ layout: t4,
400
+ shape: t5,
401
+ leading,
402
+ disabled: t6,
403
+ safeBottom: t7,
404
+ keyboardVerticalOffset: t8,
405
+ className,
406
+ testID
407
+ } = t0;
408
+ const defaultValue = t1 === undefined ? "" : t1;
409
+ const placeholder = t2 === undefined ? "What would you like to know?" : t2;
410
+ const accessibilityLabel = t3 === undefined ? "Message" : t3;
411
+ const layout = t4 === undefined ? "stacked" : t4;
412
+ const shape = t5 === undefined ? "rounded" : t5;
413
+ const disabled = t6 === undefined ? false : t6;
414
+ const safeBottom = t7 === undefined ? true : t7;
415
+ const keyboardVerticalOffset = t8 === undefined ? 0 : t8;
416
+ const scheme = useScheme();
417
+ const largerText = useLargerText();
418
+ const insets = useSafeAreaInsets();
419
+ const lifted = useContext(KeyboardLiftContext);
420
+ let t9;
421
+ if ($[0] !== defaultValue || $[1] !== onChangeText || $[2] !== value) {
422
+ t9 = {
423
+ value,
424
+ defaultValue,
425
+ onChange: onChangeText
426
+ };
427
+ $[0] = defaultValue;
428
+ $[1] = onChangeText;
429
+ $[2] = value;
430
+ $[3] = t9;
431
+ } else {
432
+ t9 = $[3];
433
+ }
434
+ const [text, setText] = useControllableState(t9);
435
+ let t10;
436
+ if ($[4] !== text) {
437
+ t10 = text.trim();
438
+ $[4] = text;
439
+ $[5] = t10;
440
+ } else {
441
+ t10 = $[5];
442
+ }
443
+ const message = t10;
444
+ let t11;
445
+ if ($[6] !== disabled || $[7] !== message.length || $[8] !== status) {
446
+ t11 = message.length > 0 && !disabled && !isGenerating(status);
447
+ $[6] = disabled;
448
+ $[7] = message.length;
449
+ $[8] = status;
450
+ $[9] = t11;
451
+ } else {
452
+ t11 = $[9];
453
+ }
454
+ const canSubmit = t11;
455
+ const bottom = safeBottom ? insets.bottom : 0;
456
+ const [contentHeight, setContentHeight] = useState(0);
457
+ const maxHeight = largerText ? MAX_FIELD_HEIGHT.larger : MAX_FIELD_HEIGHT.regular;
458
+ let t12;
459
+ if ($[10] !== contentHeight || $[11] !== maxHeight) {
460
+ t12 = contentHeight > 0 ? {
461
+ height: Math.min(contentHeight, maxHeight)
462
+ } : null;
463
+ $[10] = contentHeight;
464
+ $[11] = maxHeight;
465
+ $[12] = t12;
466
+ } else {
467
+ t12 = $[12];
468
+ }
469
+ const growStyle = t12;
470
+ const scrollEnabled = contentHeight > maxHeight;
471
+ const pill = layout === "inline" && shape === "pill";
472
+ let t13;
473
+ if ($[13] !== largerText || $[14] !== layout || $[15] !== pill) {
474
+ t13 = largerText ? sizeStyle("text-xl") : layout === "inline" ? {
475
+ fontSize: 14,
476
+ lineHeight: pill ? 20 : 24
477
+ } : sizeStyle("text-base");
478
+ $[13] = largerText;
479
+ $[14] = layout;
480
+ $[15] = pill;
481
+ $[16] = t13;
482
+ } else {
483
+ t13 = $[16];
484
+ }
485
+ const fieldText = t13;
486
+ let t14;
487
+ if ($[17] !== setText) {
488
+ t14 = next => {
489
+ setText(next);
490
+ if (next === "") {
491
+ setContentHeight(0);
492
+ }
493
+ };
494
+ $[17] = setText;
495
+ $[18] = t14;
496
+ } else {
497
+ t14 = $[18];
498
+ }
499
+ const changeText = t14;
500
+ let t15;
501
+ if ($[19] !== canSubmit || $[20] !== message || $[21] !== onSubmit || $[22] !== setText) {
502
+ t15 = () => {
503
+ if (!canSubmit) {
504
+ return;
505
+ }
506
+ onSubmit(message);
507
+ setText("");
508
+ setContentHeight(0);
509
+ };
510
+ $[19] = canSubmit;
511
+ $[20] = message;
512
+ $[21] = onSubmit;
513
+ $[22] = setText;
514
+ $[23] = t15;
515
+ } else {
516
+ t15 = $[23];
517
+ }
518
+ const submit = t15;
519
+ let t16;
520
+ if ($[24] !== className) {
521
+ t16 = cn("pt-2", className);
522
+ $[24] = className;
523
+ $[25] = t16;
524
+ } else {
525
+ t16 = $[25];
526
+ }
527
+ const t17 = bottom + 8;
528
+ const t18 = insets.left + 12;
529
+ const t19 = insets.right + 12;
530
+ let t20;
531
+ if ($[26] !== t17 || $[27] !== t18 || $[28] !== t19) {
532
+ t20 = {
533
+ paddingBottom: t17,
534
+ paddingLeft: t18,
535
+ paddingRight: t19
536
+ };
537
+ $[26] = t17;
538
+ $[27] = t18;
539
+ $[28] = t19;
540
+ $[29] = t20;
541
+ } else {
542
+ t20 = $[29];
543
+ }
544
+ let t21;
545
+ if ($[30] !== menu) {
546
+ t21 = menu ? <View className="mb-1.5">{menu}</View> : null;
547
+ $[30] = menu;
548
+ $[31] = t21;
549
+ } else {
550
+ t21 = $[31];
551
+ }
552
+ let t22;
553
+ if ($[32] !== accessibilityLabel || $[33] !== canSubmit || $[34] !== changeText || $[35] !== disabled || $[36] !== fieldText || $[37] !== growStyle || $[38] !== header || $[39] !== largerText || $[40] !== layout || $[41] !== leading || $[42] !== maxHeight || $[43] !== onStop || $[44] !== pill || $[45] !== placeholder || $[46] !== replyTo || $[47] !== scheme || $[48] !== scrollEnabled || $[49] !== status || $[50] !== submit || $[51] !== testID || $[52] !== text || $[53] !== toolbar) {
554
+ t22 = layout === "inline" ? <View className="border" style={[fieldStyle(scheme), {
555
+ borderRadius: pill ? PILL.radius : INLINE_RADIUS
556
+ }]}>{replyTo ? <View className="px-1.5 pt-1.5">{replyTo}</View> : null}{header ? <View className="flex-row flex-wrap gap-1 px-1.5 pt-1.5">{header}</View> : null}<View className={cn("flex-row items-end gap-1", !pill && "p-1.5")} style={pill ? {
557
+ paddingVertical: PILL.paddingY,
558
+ paddingHorizontal: PILL.paddingX
559
+ } : null}>{leading ? <View className="shrink-0 flex-row items-center gap-1" style={pill ? {
560
+ minHeight: PILL.lineHeight
561
+ } : null}>{leading}</View> : null}<FieldInput testID={testID ? `${testID}-input` : undefined} nativeID={COMPOSER_INPUT_ID} multiline={true} numberOfLines={ONE_ROW} value={text} onChangeText={changeText} placeholder={placeholder} placeholderTextColor={pill ? withAlpha(tokens.color.muted[scheme], PILL.placeholderAlpha) : undefined} accessibilityLabel={accessibilityLabel} editable={!disabled} textAlignVertical="center" scrollEnabled={scrollEnabled} onContentSizeChange={e => setContentHeight(e.nativeEvent.contentSize.height)} className={cn("flex-1 border-0 text-sm font-instrument-sans", pill ? "min-h-9 px-1 py-2" : "min-h-8 px-2 py-1", largerText && "min-h-11 py-2 text-xl font-instrument-sans-medium")} style={[fieldTextStyle(scheme), fieldText, largerText ? typeStyle("medium") : null, {
562
+ backgroundColor: "transparent",
563
+ maxHeight,
564
+ ...growStyle
565
+ }]} /><View className="shrink-0 flex-row items-center gap-1" style={pill ? {
566
+ minHeight: PILL.lineHeight
567
+ } : null}>{toolbar}<PromptInputSubmit status={status} onSubmit={submit} onStop={onStop} canSubmit={canSubmit} size={pill ? "md" : undefined} /></View></View></View> : <View className="border" style={fieldStyle(scheme)}>{replyTo ? <View className="px-2 pt-2">{replyTo}</View> : null}{header ? <View className="flex-row flex-wrap gap-1 px-2 pt-2">{header}</View> : null}<FieldInput testID={testID ? `${testID}-input` : undefined} nativeID={COMPOSER_INPUT_ID} multiline={true} numberOfLines={ONE_ROW} value={text} onChangeText={changeText} placeholder={placeholder} accessibilityLabel={accessibilityLabel} editable={!disabled} textAlignVertical="top" scrollEnabled={scrollEnabled} onContentSizeChange={e_0 => setContentHeight(e_0.nativeEvent.contentSize.height)} className={cn("min-h-11 border-0 px-3.5 py-2.5 text-base font-instrument-sans", largerText && "min-h-14 px-4 py-3 text-xl font-instrument-sans-medium")} style={[fieldTextStyle(scheme), fieldText, largerText ? typeStyle("medium") : null, {
568
+ backgroundColor: "transparent",
569
+ maxHeight,
570
+ ...growStyle
571
+ }]} /><View className="flex-row items-center justify-between gap-1 px-2 pb-2"><View className="min-w-0 shrink flex-row items-center gap-1">{toolbar}</View><PromptInputSubmit status={status} onSubmit={submit} onStop={onStop} canSubmit={canSubmit} /></View></View>;
572
+ $[32] = accessibilityLabel;
573
+ $[33] = canSubmit;
574
+ $[34] = changeText;
575
+ $[35] = disabled;
576
+ $[36] = fieldText;
577
+ $[37] = growStyle;
578
+ $[38] = header;
579
+ $[39] = largerText;
580
+ $[40] = layout;
581
+ $[41] = leading;
582
+ $[42] = maxHeight;
583
+ $[43] = onStop;
584
+ $[44] = pill;
585
+ $[45] = placeholder;
586
+ $[46] = replyTo;
587
+ $[47] = scheme;
588
+ $[48] = scrollEnabled;
589
+ $[49] = status;
590
+ $[50] = submit;
591
+ $[51] = testID;
592
+ $[52] = text;
593
+ $[53] = toolbar;
594
+ $[54] = t22;
595
+ } else {
596
+ t22 = $[54];
597
+ }
598
+ let t23;
599
+ if ($[55] !== footer || $[56] !== t16 || $[57] !== t20 || $[58] !== t21 || $[59] !== t22 || $[60] !== testID) {
600
+ t23 = <View testID={testID} className={t16} style={t20}>{t21}{t22}{footer}</View>;
601
+ $[55] = footer;
602
+ $[56] = t16;
603
+ $[57] = t20;
604
+ $[58] = t21;
605
+ $[59] = t22;
606
+ $[60] = testID;
607
+ $[61] = t23;
608
+ } else {
609
+ t23 = $[61];
610
+ }
611
+ const composer = t23;
612
+ if (lifted) {
613
+ return composer;
614
+ }
615
+ const t24 = keyboardVerticalOffset - bottom;
616
+ let t25;
617
+ if ($[62] !== composer || $[63] !== t24) {
618
+ t25 = <KeyboardAvoidingView keyboardVerticalOffset={t24}>{composer}</KeyboardAvoidingView>;
619
+ $[62] = composer;
620
+ $[63] = t24;
621
+ $[64] = t25;
622
+ } else {
623
+ t25 = $[64];
624
+ }
625
+ return t25;
626
+ }