@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,130 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { createContext, useContext } from "react";
3
+ import { Text } from "react-native";
4
+ import { cn } from "../cn";
5
+ import { sizeStyle, textStyle } from "../controlStyles";
6
+ import { useLargerText } from "../theme";
7
+ import { useScheme } from "../useScheme";
8
+ import { chatTextSize } from "./chat-text";
9
+
10
+ // Markdown stub. The web renders replies with Streamdown; native-ui has no
11
+ // markdown peer, so `ResponseText` draws the text as it is, newlines kept.
12
+ // An app that wants markdown can render one of these in its place:
13
+ // `react-native-markdown-display`, `@ronradtke/react-native-markdown-display`
14
+ // (a maintained fork) or `react-native-marked`.
15
+
16
+ /**
17
+ * The text colour `MessageContent` hands down: React Native text does not
18
+ * inherit a colour from its parent view, as web text does from `color`.
19
+ */
20
+ export const ChatTextColorContext = createContext(undefined);
21
+ /** Plain reply text, selectable, newlines kept. The markdown placeholder. */
22
+ export function ResponseText(t0) {
23
+ const $ = _c(35);
24
+ let children;
25
+ let className;
26
+ let props;
27
+ let style;
28
+ let t1;
29
+ let t2;
30
+ let tone;
31
+ if ($[0] !== t0) {
32
+ ({
33
+ children,
34
+ tone,
35
+ size: t1,
36
+ selectable: t2,
37
+ className,
38
+ style,
39
+ ...props
40
+ } = t0);
41
+ $[0] = t0;
42
+ $[1] = children;
43
+ $[2] = className;
44
+ $[3] = props;
45
+ $[4] = style;
46
+ $[5] = t1;
47
+ $[6] = t2;
48
+ $[7] = tone;
49
+ } else {
50
+ children = $[1];
51
+ className = $[2];
52
+ props = $[3];
53
+ style = $[4];
54
+ t1 = $[5];
55
+ t2 = $[6];
56
+ tone = $[7];
57
+ }
58
+ const size = t1 === undefined ? "body" : t1;
59
+ const selectable = t2 === undefined ? true : t2;
60
+ const scheme = useScheme();
61
+ const largerText = useLargerText();
62
+ const inherited = useContext(ChatTextColorContext);
63
+ let T0;
64
+ let color;
65
+ let t3;
66
+ let t4;
67
+ let t5;
68
+ if ($[8] !== className || $[9] !== inherited || $[10] !== largerText || $[11] !== scheme || $[12] !== selectable || $[13] !== size || $[14] !== tone) {
69
+ const textSize = chatTextSize(size, largerText);
70
+ let t6;
71
+ if ($[20] !== inherited || $[21] !== scheme || $[22] !== tone) {
72
+ t6 = tone || !inherited ? textStyle(tone ?? "foreground", scheme) : {
73
+ color: inherited
74
+ };
75
+ $[20] = inherited;
76
+ $[21] = scheme;
77
+ $[22] = tone;
78
+ $[23] = t6;
79
+ } else {
80
+ t6 = $[23];
81
+ }
82
+ color = t6;
83
+ T0 = Text;
84
+ t4 = selectable;
85
+ t5 = cn(textSize, "font-instrument-sans", className);
86
+ t3 = sizeStyle(textSize);
87
+ $[8] = className;
88
+ $[9] = inherited;
89
+ $[10] = largerText;
90
+ $[11] = scheme;
91
+ $[12] = selectable;
92
+ $[13] = size;
93
+ $[14] = tone;
94
+ $[15] = T0;
95
+ $[16] = color;
96
+ $[17] = t3;
97
+ $[18] = t4;
98
+ $[19] = t5;
99
+ } else {
100
+ T0 = $[15];
101
+ color = $[16];
102
+ t3 = $[17];
103
+ t4 = $[18];
104
+ t5 = $[19];
105
+ }
106
+ let t6;
107
+ if ($[24] !== color || $[25] !== style || $[26] !== t3) {
108
+ t6 = [t3, color, style];
109
+ $[24] = color;
110
+ $[25] = style;
111
+ $[26] = t3;
112
+ $[27] = t6;
113
+ } else {
114
+ t6 = $[27];
115
+ }
116
+ let t7;
117
+ if ($[28] !== T0 || $[29] !== children || $[30] !== props || $[31] !== t4 || $[32] !== t5 || $[33] !== t6) {
118
+ t7 = <T0 selectable={t4} className={t5} style={t6} {...props}>{children}</T0>;
119
+ $[28] = T0;
120
+ $[29] = children;
121
+ $[30] = props;
122
+ $[31] = t4;
123
+ $[32] = t5;
124
+ $[33] = t6;
125
+ $[34] = t7;
126
+ } else {
127
+ t7 = $[34];
128
+ }
129
+ return t7;
130
+ }
@@ -0,0 +1,149 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useEffect } from "react";
3
+ import { Text } from "react-native";
4
+ import Animated, { cancelAnimation, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
5
+ import { cn } from "../cn";
6
+ import { sizeStyle, textStyle } from "../controlStyles";
7
+ import { useLargerText } from "../theme";
8
+ import { useReduceMotion } from "../useReduceMotion";
9
+ import { useScheme } from "../useScheme";
10
+ import { chatTextSize } from "./chat-text";
11
+
12
+ /**
13
+ * Lowest opacity of the pulse. The foreground at 0.45 on the page is close to
14
+ * the muted colour, the far end of the web sweep.
15
+ */
16
+ export const SHIMMER_LOW_OPACITY = 0.45;
17
+ /**
18
+ * "Live" text, such as "Thinking…". The web sweeps a foreground band across
19
+ * muted text (`bg-clip-text`), which React Native cannot clip to the glyphs
20
+ * without a masked view. Here the foreground text fades to
21
+ * `SHIMMER_LOW_OPACITY` and back once per `duration`, on the UI thread with
22
+ * Reanimated. With Reduce Motion it holds still in the muted colour.
23
+ */
24
+ export function Shimmer(t0) {
25
+ const $ = _c(35);
26
+ const {
27
+ children,
28
+ duration: t1,
29
+ size: t2,
30
+ numberOfLines,
31
+ className,
32
+ style
33
+ } = t0;
34
+ const duration = t1 === undefined ? 2 : t1;
35
+ const size = t2 === undefined ? "small" : t2;
36
+ const scheme = useScheme();
37
+ const largerText = useLargerText();
38
+ const reduceMotion = useReduceMotion();
39
+ const opacity = useSharedValue(1);
40
+ let t3;
41
+ let t4;
42
+ if ($[0] !== duration || $[1] !== opacity || $[2] !== reduceMotion) {
43
+ t3 = () => {
44
+ if (reduceMotion) {
45
+ cancelAnimation(opacity);
46
+ opacity.set(1);
47
+ return;
48
+ }
49
+ opacity.set(withRepeat(withTiming(SHIMMER_LOW_OPACITY, {
50
+ duration: duration * 1000 / 2
51
+ }), -1, true));
52
+ return () => cancelAnimation(opacity);
53
+ };
54
+ t4 = [opacity, reduceMotion, duration];
55
+ $[0] = duration;
56
+ $[1] = opacity;
57
+ $[2] = reduceMotion;
58
+ $[3] = t3;
59
+ $[4] = t4;
60
+ } else {
61
+ t3 = $[3];
62
+ t4 = $[4];
63
+ }
64
+ useEffect(t3, t4);
65
+ const animatedStyle = useAnimatedStyle(() => ({
66
+ opacity: opacity.get()
67
+ }));
68
+ let T0;
69
+ let T1;
70
+ let t5;
71
+ let t6;
72
+ let t7;
73
+ let t8;
74
+ let t9;
75
+ if ($[5] !== animatedStyle || $[6] !== className || $[7] !== largerText || $[8] !== numberOfLines || $[9] !== size) {
76
+ const textSize = chatTextSize(size, largerText);
77
+ T1 = Animated.View;
78
+ t8 = "min-w-0 shrink";
79
+ t9 = animatedStyle;
80
+ T0 = Text;
81
+ t6 = numberOfLines;
82
+ t7 = cn(textSize, "font-instrument-sans", className);
83
+ t5 = sizeStyle(textSize);
84
+ $[5] = animatedStyle;
85
+ $[6] = className;
86
+ $[7] = largerText;
87
+ $[8] = numberOfLines;
88
+ $[9] = size;
89
+ $[10] = T0;
90
+ $[11] = T1;
91
+ $[12] = t5;
92
+ $[13] = t6;
93
+ $[14] = t7;
94
+ $[15] = t8;
95
+ $[16] = t9;
96
+ } else {
97
+ T0 = $[10];
98
+ T1 = $[11];
99
+ t5 = $[12];
100
+ t6 = $[13];
101
+ t7 = $[14];
102
+ t8 = $[15];
103
+ t9 = $[16];
104
+ }
105
+ const t10 = reduceMotion ? "muted" : "foreground";
106
+ let t11;
107
+ if ($[17] !== scheme || $[18] !== t10) {
108
+ t11 = textStyle(t10, scheme);
109
+ $[17] = scheme;
110
+ $[18] = t10;
111
+ $[19] = t11;
112
+ } else {
113
+ t11 = $[19];
114
+ }
115
+ let t12;
116
+ if ($[20] !== style || $[21] !== t11 || $[22] !== t5) {
117
+ t12 = [t5, t11, style];
118
+ $[20] = style;
119
+ $[21] = t11;
120
+ $[22] = t5;
121
+ $[23] = t12;
122
+ } else {
123
+ t12 = $[23];
124
+ }
125
+ let t13;
126
+ if ($[24] !== T0 || $[25] !== children || $[26] !== t12 || $[27] !== t6 || $[28] !== t7) {
127
+ t13 = <T0 numberOfLines={t6} className={t7} style={t12}>{children}</T0>;
128
+ $[24] = T0;
129
+ $[25] = children;
130
+ $[26] = t12;
131
+ $[27] = t6;
132
+ $[28] = t7;
133
+ $[29] = t13;
134
+ } else {
135
+ t13 = $[29];
136
+ }
137
+ let t14;
138
+ if ($[30] !== T1 || $[31] !== t13 || $[32] !== t8 || $[33] !== t9) {
139
+ t14 = <T1 className={t8} style={t9}>{t13}</T1>;
140
+ $[30] = T1;
141
+ $[31] = t13;
142
+ $[32] = t8;
143
+ $[33] = t9;
144
+ $[34] = t14;
145
+ } else {
146
+ t14 = $[34];
147
+ }
148
+ return t14;
149
+ }
@@ -0,0 +1,260 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { Linking, Pressable } from "react-native";
3
+ import { IconBook } from "@tabler/icons-react-native";
4
+ import { cn } from "../cn";
5
+ import { MIN_TOUCH_TARGET, touchSlop } from "../controlStyles";
6
+ import { useLargerText } from "../theme";
7
+ import { tokens } from "../tokens";
8
+ import { useScheme } from "../useScheme";
9
+ import { Collapsible, CollapsibleChevron, CollapsibleContent, CollapsibleTrigger, useCollapsible } from "./collapsible";
10
+ import { ResponseText } from "./response-text";
11
+
12
+ /** The sources a reply used, folded (default closed). */
13
+ export function Sources(t0) {
14
+ const $ = _c(8);
15
+ let className;
16
+ let props;
17
+ if ($[0] !== t0) {
18
+ ({
19
+ className,
20
+ ...props
21
+ } = t0);
22
+ $[0] = t0;
23
+ $[1] = className;
24
+ $[2] = props;
25
+ } else {
26
+ className = $[1];
27
+ props = $[2];
28
+ }
29
+ let t1;
30
+ if ($[3] !== className) {
31
+ t1 = cn("w-full", className);
32
+ $[3] = className;
33
+ $[4] = t1;
34
+ } else {
35
+ t1 = $[4];
36
+ }
37
+ let t2;
38
+ if ($[5] !== props || $[6] !== t1) {
39
+ t2 = <Collapsible className={t1} {...props} />;
40
+ $[5] = props;
41
+ $[6] = t1;
42
+ $[7] = t2;
43
+ } else {
44
+ t2 = $[7];
45
+ }
46
+ return t2;
47
+ }
48
+
49
+ /** "Used 1 source", "Used 3 sources". */
50
+ export function sourcesLabel(count) {
51
+ return `Used ${count} ${count === 1 ? "source" : "sources"}`;
52
+ }
53
+ /** Book icon, "Used 3 sources" and a chevron, muted (web `text-xs`, here `text-sm`). */
54
+ export function SourcesTrigger(t0) {
55
+ const $ = _c(24);
56
+ let className;
57
+ let count;
58
+ let props;
59
+ if ($[0] !== t0) {
60
+ ({
61
+ count,
62
+ className,
63
+ ...props
64
+ } = t0);
65
+ $[0] = t0;
66
+ $[1] = className;
67
+ $[2] = count;
68
+ $[3] = props;
69
+ } else {
70
+ className = $[1];
71
+ count = $[2];
72
+ props = $[3];
73
+ }
74
+ const {
75
+ open
76
+ } = useCollapsible();
77
+ const scheme = useScheme();
78
+ const largerText = useLargerText();
79
+ const muted = tokens.color.muted[scheme];
80
+ const iconSize = largerText ? 18 : 14;
81
+ let t1;
82
+ if ($[4] !== count) {
83
+ t1 = sourcesLabel(count);
84
+ $[4] = count;
85
+ $[5] = t1;
86
+ } else {
87
+ t1 = $[5];
88
+ }
89
+ const label = t1;
90
+ let t2;
91
+ if ($[6] !== className) {
92
+ t2 = cn("flex-row items-center gap-1.5 self-start", className);
93
+ $[6] = className;
94
+ $[7] = t2;
95
+ } else {
96
+ t2 = $[7];
97
+ }
98
+ let t3;
99
+ if ($[8] !== iconSize || $[9] !== muted) {
100
+ t3 = <IconBook size={iconSize} color={muted} strokeWidth={1.5} />;
101
+ $[8] = iconSize;
102
+ $[9] = muted;
103
+ $[10] = t3;
104
+ } else {
105
+ t3 = $[10];
106
+ }
107
+ let t4;
108
+ if ($[11] !== label) {
109
+ t4 = <ResponseText size="small" tone="muted" selectable={false}>{label}</ResponseText>;
110
+ $[11] = label;
111
+ $[12] = t4;
112
+ } else {
113
+ t4 = $[12];
114
+ }
115
+ let t5;
116
+ if ($[13] !== iconSize || $[14] !== muted || $[15] !== open) {
117
+ t5 = <CollapsibleChevron open={open} size={iconSize} color={muted} />;
118
+ $[13] = iconSize;
119
+ $[14] = muted;
120
+ $[15] = open;
121
+ $[16] = t5;
122
+ } else {
123
+ t5 = $[16];
124
+ }
125
+ let t6;
126
+ if ($[17] !== label || $[18] !== props || $[19] !== t2 || $[20] !== t3 || $[21] !== t4 || $[22] !== t5) {
127
+ t6 = <CollapsibleTrigger accessibilityLabel={label} className={t2} {...props}>{t3}{t4}{t5}</CollapsibleTrigger>;
128
+ $[17] = label;
129
+ $[18] = props;
130
+ $[19] = t2;
131
+ $[20] = t3;
132
+ $[21] = t4;
133
+ $[22] = t5;
134
+ $[23] = t6;
135
+ } else {
136
+ t6 = $[23];
137
+ }
138
+ return t6;
139
+ }
140
+
141
+ /** The list of `Source` rows, shown while open (web `mt-2 space-y-2`). */
142
+ export function SourcesContent(t0) {
143
+ const $ = _c(8);
144
+ let className;
145
+ let props;
146
+ if ($[0] !== t0) {
147
+ ({
148
+ className,
149
+ ...props
150
+ } = t0);
151
+ $[0] = t0;
152
+ $[1] = className;
153
+ $[2] = props;
154
+ } else {
155
+ className = $[1];
156
+ props = $[2];
157
+ }
158
+ let t1;
159
+ if ($[3] !== className) {
160
+ t1 = cn("mt-2 gap-2", className);
161
+ $[3] = className;
162
+ $[4] = t1;
163
+ } else {
164
+ t1 = $[4];
165
+ }
166
+ let t2;
167
+ if ($[5] !== props || $[6] !== t1) {
168
+ t2 = <CollapsibleContent className={t1} {...props} />;
169
+ $[5] = props;
170
+ $[6] = t1;
171
+ $[7] = t2;
172
+ } else {
173
+ t2 = $[7];
174
+ }
175
+ return t2;
176
+ }
177
+ /** A `text-sm` line with the web `py-2`: 36 high. The slop brings it to 44. */
178
+ const ROW_HEIGHT = 36;
179
+
180
+ /**
181
+ * One source as a link row: title (or address) on one line and a book icon.
182
+ * Pressed, it takes the web hover fill (`bg-surface-secondary`).
183
+ */
184
+ export function Source(t0) {
185
+ const $ = _c(18);
186
+ const {
187
+ href,
188
+ title,
189
+ onPress,
190
+ testID
191
+ } = t0;
192
+ const scheme = useScheme();
193
+ const largerText = useLargerText();
194
+ const label = title ?? href;
195
+ let t1;
196
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
197
+ t1 = touchSlop(MIN_TOUCH_TARGET, ROW_HEIGHT);
198
+ $[0] = t1;
199
+ } else {
200
+ t1 = $[0];
201
+ }
202
+ let t2;
203
+ if ($[1] !== href || $[2] !== onPress) {
204
+ t2 = () => onPress ? onPress(href) : void Linking.openURL(href);
205
+ $[1] = href;
206
+ $[2] = onPress;
207
+ $[3] = t2;
208
+ } else {
209
+ t2 = $[3];
210
+ }
211
+ let t3;
212
+ if ($[4] !== scheme) {
213
+ t3 = t4 => {
214
+ const {
215
+ pressed
216
+ } = t4;
217
+ return {
218
+ borderRadius: tokens.radius.md,
219
+ backgroundColor: pressed ? tokens.color.surfaceSecondary[scheme] : "transparent"
220
+ };
221
+ };
222
+ $[4] = scheme;
223
+ $[5] = t3;
224
+ } else {
225
+ t3 = $[5];
226
+ }
227
+ let t4;
228
+ if ($[6] !== label) {
229
+ t4 = <ResponseText size="small" tone="muted" selectable={false} numberOfLines={1} className="shrink">{label}</ResponseText>;
230
+ $[6] = label;
231
+ $[7] = t4;
232
+ } else {
233
+ t4 = $[7];
234
+ }
235
+ const t5 = largerText ? 18 : 14;
236
+ const t6 = tokens.color.muted[scheme];
237
+ let t7;
238
+ if ($[8] !== t5 || $[9] !== t6) {
239
+ t7 = <IconBook size={t5} color={t6} strokeWidth={1.5} />;
240
+ $[8] = t5;
241
+ $[9] = t6;
242
+ $[10] = t7;
243
+ } else {
244
+ t7 = $[10];
245
+ }
246
+ let t8;
247
+ if ($[11] !== label || $[12] !== t2 || $[13] !== t3 || $[14] !== t4 || $[15] !== t7 || $[16] !== testID) {
248
+ t8 = <Pressable testID={testID} accessibilityRole="link" accessibilityLabel={label} hitSlop={t1} onPress={t2} className="flex-row items-center justify-between gap-2 px-3 py-2" style={t3}>{t4}{t7}</Pressable>;
249
+ $[11] = label;
250
+ $[12] = t2;
251
+ $[13] = t3;
252
+ $[14] = t4;
253
+ $[15] = t7;
254
+ $[16] = testID;
255
+ $[17] = t8;
256
+ } else {
257
+ t8 = $[17];
258
+ }
259
+ return t8;
260
+ }