@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,226 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { Platform, StyleSheet, View } from "react-native";
3
+ import { glassMode, loadBlur } from "./blur";
4
+ import { cn } from "./cn";
5
+ import { hasDefiniteHeight } from "./definiteSize";
6
+ import { floatingFill, floatingHairline, floatingShadow, floatingSolidFill, FLOATING_RADIUS } from "./floating";
7
+ import { useGlassBlurTarget } from "./glassBlur";
8
+ import { useReduceTransparency } from "./useReduceTransparency";
9
+ import { useScheme } from "./useScheme";
10
+ export function FloatingSurface(t0) {
11
+ const $ = _c(50);
12
+ let children;
13
+ let className;
14
+ let props;
15
+ let style;
16
+ let t1;
17
+ let t2;
18
+ let t3;
19
+ if ($[0] !== t0) {
20
+ ({
21
+ className,
22
+ style,
23
+ children,
24
+ radius: t1,
25
+ blur: t2,
26
+ elevated: t3,
27
+ ...props
28
+ } = t0);
29
+ $[0] = t0;
30
+ $[1] = children;
31
+ $[2] = className;
32
+ $[3] = props;
33
+ $[4] = style;
34
+ $[5] = t1;
35
+ $[6] = t2;
36
+ $[7] = t3;
37
+ } else {
38
+ children = $[1];
39
+ className = $[2];
40
+ props = $[3];
41
+ style = $[4];
42
+ t1 = $[5];
43
+ t2 = $[6];
44
+ t3 = $[7];
45
+ }
46
+ const radius = t1 === undefined ? FLOATING_RADIUS : t1;
47
+ const blur = t2 === undefined ? true : t2;
48
+ const elevated = t3 === undefined ? true : t3;
49
+ const colorScheme = useScheme();
50
+ const reduceTransparency = useReduceTransparency();
51
+ const blurTarget = useGlassBlurTarget();
52
+ const BlurView = loadBlur()?.BlurView;
53
+ let t4;
54
+ if ($[8] !== blur || $[9] !== reduceTransparency) {
55
+ t4 = glassMode({
56
+ os: Platform.OS,
57
+ blur,
58
+ reduceTransparency,
59
+ hasBlurView: BlurView != null
60
+ });
61
+ $[8] = blur;
62
+ $[9] = reduceTransparency;
63
+ $[10] = t4;
64
+ } else {
65
+ t4 = $[10];
66
+ }
67
+ const mode = t4;
68
+ const isDark = colorScheme === "dark";
69
+ const opaqueFill = isDark ? floatingSolidFill.dark : floatingSolidFill.light;
70
+ const translucentFill = isDark ? floatingFill.dark : floatingFill.light;
71
+ const border = isDark ? floatingHairline.dark : floatingHairline.light;
72
+ const fill = mode === "solid" ? opaqueFill : translucentFill;
73
+ let t5;
74
+ if ($[11] !== className) {
75
+ t5 = cn(className);
76
+ $[11] = className;
77
+ $[12] = t5;
78
+ } else {
79
+ t5 = $[12];
80
+ }
81
+ let t6;
82
+ if ($[13] !== radius) {
83
+ t6 = {
84
+ borderRadius: radius
85
+ };
86
+ $[13] = radius;
87
+ $[14] = t6;
88
+ } else {
89
+ t6 = $[14];
90
+ }
91
+ const t7 = elevated ? floatingShadow : null;
92
+ let t8;
93
+ if ($[15] !== fill) {
94
+ t8 = {
95
+ backgroundColor: fill
96
+ };
97
+ $[15] = fill;
98
+ $[16] = t8;
99
+ } else {
100
+ t8 = $[16];
101
+ }
102
+ let t9;
103
+ if ($[17] !== style || $[18] !== t6 || $[19] !== t7 || $[20] !== t8) {
104
+ t9 = [t6, t7, style, t8];
105
+ $[17] = style;
106
+ $[18] = t6;
107
+ $[19] = t7;
108
+ $[20] = t8;
109
+ $[21] = t9;
110
+ } else {
111
+ t9 = $[21];
112
+ }
113
+ const t10 = mode === "blur" ? "transparent" : fill;
114
+ let t11;
115
+ if ($[22] !== border || $[23] !== radius || $[24] !== t10) {
116
+ t11 = {
117
+ borderRadius: radius,
118
+ borderWidth: StyleSheet.hairlineWidth,
119
+ borderColor: border,
120
+ backgroundColor: t10
121
+ };
122
+ $[22] = border;
123
+ $[23] = radius;
124
+ $[24] = t10;
125
+ $[25] = t11;
126
+ } else {
127
+ t11 = $[25];
128
+ }
129
+ const t12 = hasDefiniteHeight(style) ? styles.fill : null;
130
+ let t13;
131
+ if ($[26] !== t11 || $[27] !== t12) {
132
+ t13 = [styles.clip, t11, Platform.OS === "ios" ? styles.continuous : null, t12];
133
+ $[26] = t11;
134
+ $[27] = t12;
135
+ $[28] = t13;
136
+ } else {
137
+ t13 = $[28];
138
+ }
139
+ let t14;
140
+ if ($[29] !== blurTarget || $[30] !== isDark || $[31] !== mode) {
141
+ t14 = mode === "blur" && BlurView ? <BlurView pointerEvents="none" tint={isDark ? "systemMaterialDark" : "systemMaterialLight"} intensity={70} experimentalBlurMethod={Platform.OS === "android" ? "dimezisBlurView" : undefined} blurMethod="dimezisBlurView" blurReductionFactor={3} blurTarget={blurTarget ?? undefined} style={StyleSheet.absoluteFill} /> : null;
142
+ $[29] = blurTarget;
143
+ $[30] = isDark;
144
+ $[31] = mode;
145
+ $[32] = t14;
146
+ } else {
147
+ t14 = $[32];
148
+ }
149
+ let t15;
150
+ if ($[33] !== mode || $[34] !== translucentFill) {
151
+ t15 = mode === "blur" && Platform.OS === "android" ? <View pointerEvents="none" style={[StyleSheet.absoluteFill, {
152
+ backgroundColor: translucentFill
153
+ }]} /> : null;
154
+ $[33] = mode;
155
+ $[34] = translucentFill;
156
+ $[35] = t15;
157
+ } else {
158
+ t15 = $[35];
159
+ }
160
+ let t16;
161
+ if ($[36] !== mode || $[37] !== translucentFill) {
162
+ t16 = mode === "backdrop" ? <View pointerEvents="none" className="absolute inset-0 backdrop-blur-xl" style={{
163
+ backgroundColor: translucentFill
164
+ }} /> : null;
165
+ $[36] = mode;
166
+ $[37] = translucentFill;
167
+ $[38] = t16;
168
+ } else {
169
+ t16 = $[38];
170
+ }
171
+ let t17;
172
+ if ($[39] !== children || $[40] !== t13 || $[41] !== t14 || $[42] !== t15 || $[43] !== t16) {
173
+ t17 = <View style={t13}>{t14}{t15}{t16}{children}</View>;
174
+ $[39] = children;
175
+ $[40] = t13;
176
+ $[41] = t14;
177
+ $[42] = t15;
178
+ $[43] = t16;
179
+ $[44] = t17;
180
+ } else {
181
+ t17 = $[44];
182
+ }
183
+ let t18;
184
+ if ($[45] !== props || $[46] !== t17 || $[47] !== t5 || $[48] !== t9) {
185
+ t18 = <View className={t5} {...props} style={t9}>{t17}</View>;
186
+ $[45] = props;
187
+ $[46] = t17;
188
+ $[47] = t5;
189
+ $[48] = t9;
190
+ $[49] = t18;
191
+ } else {
192
+ t18 = $[49];
193
+ }
194
+ return t18;
195
+ }
196
+ export function GlassSheetBackground(t0) {
197
+ const $ = _c(3);
198
+ const {
199
+ style,
200
+ pointerEvents
201
+ } = t0;
202
+ let t1;
203
+ if ($[0] !== pointerEvents || $[1] !== style) {
204
+ t1 = <FloatingSurface style={style} pointerEvents={pointerEvents} radius={20} className="rounded-t-[20px]" />;
205
+ $[0] = pointerEvents;
206
+ $[1] = style;
207
+ $[2] = t1;
208
+ } else {
209
+ t1 = $[2];
210
+ }
211
+ return t1;
212
+ }
213
+ const styles = StyleSheet.create({
214
+ clip: {
215
+ overflow: "hidden",
216
+ // A surface held shorter than its content (a sheet in a short window)
217
+ // shrinks the clip with it, so a scroll view inside can scroll.
218
+ flexShrink: 1
219
+ },
220
+ fill: {
221
+ flex: 1
222
+ },
223
+ continuous: {
224
+ borderCurve: "continuous"
225
+ }
226
+ });
@@ -0,0 +1,403 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { memo, useEffect } from "react";
3
+ import { Pressable, Text, View } from "react-native";
4
+ import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
5
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
6
+ import { floatingTabPillColors, tabColors, typeStyle } from "./controlStyles";
7
+ import { selectionHaptic } from "./haptics";
8
+ import { FloatingSurface } from "./FloatingSurface";
9
+ import { isTabBarHidden, isTabBarRouteVisible } from "./tabBarRoutes";
10
+ import { useLargerText } from "./theme";
11
+ import { useReduceMotion } from "./useReduceMotion";
12
+ import { useScheme } from "./useScheme";
13
+ import { FLOATING_PILL_RADIUS, tabBarHeight, tabBarSlotStyle } from "./floating";
14
+
15
+ /**
16
+ * Space between the bar edge and the tabs, on every side of the active pill,
17
+ * in points. The same all round, so the pill follows the bar's curve.
18
+ */
19
+ const TAB_BAR_PADDING = 4;
20
+
21
+ /** The web `--tabs-dur` (200ms) and `--tabs-ease` (`tokens.css`). */
22
+ const PILL_SLIDE = {
23
+ duration: 200,
24
+ easing: Easing.bezier(0.22, 1, 0.36, 1)
25
+ };
26
+
27
+ /**
28
+ * The fields this bar reads from the props Expo Router's `Tabs` passes to
29
+ * `tabBar` (React Navigation's `BottomTabBarProps`, Expo SDK 57). Declared
30
+ * here so the tab bar does not import `expo-router`.
31
+ */
32
+
33
+ /**
34
+ * The floating pill tab bar, for the `tabBar` prop of Expo Router's `Tabs`.
35
+ * The focused tab sits on a pill (`floatingTabPillColors`), with the
36
+ * foreground label; the others are muted. A route's
37
+ * `tabBarActiveTintColor` and `tabBarInactiveTintColor` override the label
38
+ * and icon colours. Hide a tab with `options={{ href: null }}` on its
39
+ * `Tabs.Screen`: the bar draws no tab for it (`isTabBarRouteVisible`), and
40
+ * the other tabs keep their focus and navigation. The focused route hides the
41
+ * whole bar with `tabBarStyle: { display: "none" }` (`isTabBarHidden`).
42
+ */
43
+ export function FloatingTabBar(t0) {
44
+ const $ = _c(40);
45
+ const {
46
+ state,
47
+ descriptors,
48
+ navigation
49
+ } = t0;
50
+ const insets = useSafeAreaInsets();
51
+ const largerText = useLargerText();
52
+ const scheme = useScheme();
53
+ let t1;
54
+ if ($[0] !== largerText) {
55
+ t1 = tabBarHeight(largerText);
56
+ $[0] = largerText;
57
+ $[1] = t1;
58
+ } else {
59
+ t1 = $[1];
60
+ }
61
+ const height = t1;
62
+ const focusedRoute = state.routes[state.index];
63
+ if (focusedRoute && isTabBarHidden(descriptors[focusedRoute.key]?.options)) {
64
+ return null;
65
+ }
66
+ let t2;
67
+ let visible;
68
+ if ($[2] !== descriptors || $[3] !== focusedRoute?.key || $[4] !== state.routes) {
69
+ let t3;
70
+ if ($[7] !== descriptors) {
71
+ t3 = route => isTabBarRouteVisible(descriptors[route.key]?.options);
72
+ $[7] = descriptors;
73
+ $[8] = t3;
74
+ } else {
75
+ t3 = $[8];
76
+ }
77
+ visible = state.routes.filter(t3);
78
+ let t4;
79
+ if ($[9] !== focusedRoute?.key) {
80
+ t4 = route_0 => route_0.key === focusedRoute?.key;
81
+ $[9] = focusedRoute?.key;
82
+ $[10] = t4;
83
+ } else {
84
+ t4 = $[10];
85
+ }
86
+ t2 = visible.findIndex(t4);
87
+ $[2] = descriptors;
88
+ $[3] = focusedRoute?.key;
89
+ $[4] = state.routes;
90
+ $[5] = t2;
91
+ $[6] = visible;
92
+ } else {
93
+ t2 = $[5];
94
+ visible = $[6];
95
+ }
96
+ const active = t2;
97
+ let t3;
98
+ if ($[11] !== insets) {
99
+ t3 = tabBarSlotStyle(insets);
100
+ $[11] = insets;
101
+ $[12] = t3;
102
+ } else {
103
+ t3 = $[12];
104
+ }
105
+ let t4;
106
+ if ($[13] !== active || $[14] !== visible) {
107
+ t4 = active >= 0 ? <ActiveTabPill index={active} count={visible.length} /> : null;
108
+ $[13] = active;
109
+ $[14] = visible;
110
+ $[15] = t4;
111
+ } else {
112
+ t4 = $[15];
113
+ }
114
+ let t5;
115
+ if ($[16] !== height) {
116
+ t5 = {
117
+ height,
118
+ paddingHorizontal: TAB_BAR_PADDING
119
+ };
120
+ $[16] = height;
121
+ $[17] = t5;
122
+ } else {
123
+ t5 = $[17];
124
+ }
125
+ let t6;
126
+ if ($[18] !== descriptors || $[19] !== largerText || $[20] !== navigation || $[21] !== scheme || $[22] !== state.index || $[23] !== state.routes) {
127
+ let t7;
128
+ if ($[25] !== descriptors || $[26] !== largerText || $[27] !== navigation || $[28] !== scheme || $[29] !== state.index) {
129
+ t7 = (route_1, index) => {
130
+ const options = descriptors[route_1.key]?.options;
131
+ if (!isTabBarRouteVisible(options)) {
132
+ return null;
133
+ }
134
+ const focused = state.index === index;
135
+ const label = typeof options.tabBarLabel === "string" ? options.tabBarLabel : typeof options.title === "string" ? options.title : route_1.name;
136
+ const color = (focused ? options.tabBarActiveTintColor : options.tabBarInactiveTintColor) ?? tabColors("segmented", focused, scheme).color;
137
+ return <TabBarItem key={route_1.key} route={route_1} navigation={navigation} focused={focused} label={label} color={color} largerText={largerText} renderIcon={options.tabBarIcon} testID={options.tabBarButtonTestID} accessibilityLabel={options.tabBarAccessibilityLabel ?? label} />;
138
+ };
139
+ $[25] = descriptors;
140
+ $[26] = largerText;
141
+ $[27] = navigation;
142
+ $[28] = scheme;
143
+ $[29] = state.index;
144
+ $[30] = t7;
145
+ } else {
146
+ t7 = $[30];
147
+ }
148
+ t6 = state.routes.map(t7);
149
+ $[18] = descriptors;
150
+ $[19] = largerText;
151
+ $[20] = navigation;
152
+ $[21] = scheme;
153
+ $[22] = state.index;
154
+ $[23] = state.routes;
155
+ $[24] = t6;
156
+ } else {
157
+ t6 = $[24];
158
+ }
159
+ let t7;
160
+ if ($[31] !== t5 || $[32] !== t6) {
161
+ t7 = <View className="flex-row items-center justify-around" style={t5} accessibilityRole="tablist">{t6}</View>;
162
+ $[31] = t5;
163
+ $[32] = t6;
164
+ $[33] = t7;
165
+ } else {
166
+ t7 = $[33];
167
+ }
168
+ let t8;
169
+ if ($[34] !== t4 || $[35] !== t7) {
170
+ t8 = <FloatingSurface radius={FLOATING_PILL_RADIUS}>{t4}{t7}</FloatingSurface>;
171
+ $[34] = t4;
172
+ $[35] = t7;
173
+ $[36] = t8;
174
+ } else {
175
+ t8 = $[36];
176
+ }
177
+ let t9;
178
+ if ($[37] !== t3 || $[38] !== t8) {
179
+ t9 = <View pointerEvents="box-none" style={t3}>{t8}</View>;
180
+ $[37] = t3;
181
+ $[38] = t8;
182
+ $[39] = t9;
183
+ } else {
184
+ t9 = $[39];
185
+ }
186
+ return t9;
187
+ }
188
+ /**
189
+ * One tab. Memoised: a switch re-renders the bar, and without it every tab
190
+ * and its SVG icon re-rendered too (the kit is not built with React
191
+ * Compiler). Now only the two tabs whose focus changed render. The props are
192
+ * stable between switches: `route` and `navigation` keep their identity, and
193
+ * `tabBarIcon` is the caller's function.
194
+ */
195
+ const TabBarItem = memo(function TabBarItem(t0) {
196
+ const $ = _c(29);
197
+ const {
198
+ route,
199
+ navigation,
200
+ focused,
201
+ label,
202
+ color,
203
+ largerText,
204
+ renderIcon,
205
+ testID,
206
+ accessibilityLabel
207
+ } = t0;
208
+ let t1;
209
+ if ($[0] !== focused || $[1] !== navigation || $[2] !== route.key || $[3] !== route.name || $[4] !== route.params) {
210
+ t1 = () => {
211
+ const event = navigation.emit({
212
+ type: "tabPress",
213
+ target: route.key,
214
+ canPreventDefault: true
215
+ });
216
+ if (!focused && !event.defaultPrevented) {
217
+ selectionHaptic();
218
+ navigation.navigate(route.name, route.params);
219
+ }
220
+ };
221
+ $[0] = focused;
222
+ $[1] = navigation;
223
+ $[2] = route.key;
224
+ $[3] = route.name;
225
+ $[4] = route.params;
226
+ $[5] = t1;
227
+ } else {
228
+ t1 = $[5];
229
+ }
230
+ const onPress = t1;
231
+ let t2;
232
+ if ($[6] !== focused) {
233
+ t2 = {
234
+ selected: focused
235
+ };
236
+ $[6] = focused;
237
+ $[7] = t2;
238
+ } else {
239
+ t2 = $[7];
240
+ }
241
+ let t3;
242
+ if ($[8] !== color || $[9] !== focused || $[10] !== largerText || $[11] !== renderIcon) {
243
+ t3 = renderIcon ? renderIcon({
244
+ focused,
245
+ color,
246
+ size: largerText ? 28 : 24
247
+ }) : null;
248
+ $[8] = color;
249
+ $[9] = focused;
250
+ $[10] = largerText;
251
+ $[11] = renderIcon;
252
+ $[12] = t3;
253
+ } else {
254
+ t3 = $[12];
255
+ }
256
+ const t4 = `font-instrument-sans-semibold ${largerText ? "text-base" : "text-sm"}`;
257
+ let t5;
258
+ if ($[13] !== color) {
259
+ t5 = {
260
+ color
261
+ };
262
+ $[13] = color;
263
+ $[14] = t5;
264
+ } else {
265
+ t5 = $[14];
266
+ }
267
+ let t6;
268
+ if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
269
+ t6 = typeStyle("semibold");
270
+ $[15] = t6;
271
+ } else {
272
+ t6 = $[15];
273
+ }
274
+ let t7;
275
+ if ($[16] !== t5) {
276
+ t7 = [t5, t6];
277
+ $[16] = t5;
278
+ $[17] = t7;
279
+ } else {
280
+ t7 = $[17];
281
+ }
282
+ let t8;
283
+ if ($[18] !== label || $[19] !== t4 || $[20] !== t7) {
284
+ t8 = <Text numberOfLines={1} maxFontSizeMultiplier={1.5} className={t4} style={t7}>{label}</Text>;
285
+ $[18] = label;
286
+ $[19] = t4;
287
+ $[20] = t7;
288
+ $[21] = t8;
289
+ } else {
290
+ t8 = $[21];
291
+ }
292
+ let t9;
293
+ if ($[22] !== accessibilityLabel || $[23] !== onPress || $[24] !== t2 || $[25] !== t3 || $[26] !== t8 || $[27] !== testID) {
294
+ t9 = <Pressable testID={testID} accessibilityRole="tab" accessibilityState={t2} accessibilityLabel={accessibilityLabel} onPress={onPress} className="min-h-12 min-w-12 flex-1 items-center justify-center gap-1" style={_temp}>{t3}{t8}</Pressable>;
295
+ $[22] = accessibilityLabel;
296
+ $[23] = onPress;
297
+ $[24] = t2;
298
+ $[25] = t3;
299
+ $[26] = t8;
300
+ $[27] = testID;
301
+ $[28] = t9;
302
+ } else {
303
+ t9 = $[28];
304
+ }
305
+ return t9;
306
+ });
307
+
308
+ /**
309
+ * The pill behind tab `index` of `count` drawn tabs: one tab wide (they share
310
+ * the row equally), `TAB_BAR_PADDING` inside the bar, in
311
+ * `floatingTabPillColors` (the muted `--default` in light, `--segment` in
312
+ * dark, so it shows on the glass bar) and the `TabsTrigger` pills outline.
313
+ * It slides to a newly focused tab, as the web segmented pill does,
314
+ * and moves at once with Reduce Motion. Behind the tablist, so assistive tech
315
+ * reads only the tabs.
316
+ */
317
+ function ActiveTabPill(t0) {
318
+ const $ = _c(14);
319
+ const {
320
+ index,
321
+ count
322
+ } = t0;
323
+ const scheme = useScheme();
324
+ const reduceMotion = useReduceMotion();
325
+ const left = 100 * index / count;
326
+ const offset = useSharedValue(left);
327
+ let t1;
328
+ let t2;
329
+ if ($[0] !== left || $[1] !== offset || $[2] !== reduceMotion) {
330
+ t1 = () => {
331
+ offset.set(reduceMotion ? left : withTiming(left, PILL_SLIDE));
332
+ };
333
+ t2 = [left, reduceMotion, offset];
334
+ $[0] = left;
335
+ $[1] = offset;
336
+ $[2] = reduceMotion;
337
+ $[3] = t1;
338
+ $[4] = t2;
339
+ } else {
340
+ t1 = $[3];
341
+ t2 = $[4];
342
+ }
343
+ useEffect(t1, t2);
344
+ const slide = useAnimatedStyle(() => ({
345
+ left: `${offset.get()}%`
346
+ }));
347
+ let t3;
348
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
349
+ t3 = {
350
+ position: "absolute",
351
+ top: TAB_BAR_PADDING,
352
+ bottom: TAB_BAR_PADDING,
353
+ left: TAB_BAR_PADDING,
354
+ right: TAB_BAR_PADDING
355
+ };
356
+ $[5] = t3;
357
+ } else {
358
+ t3 = $[5];
359
+ }
360
+ const t4 = `${100 / count}%`;
361
+ let t5;
362
+ if ($[6] !== scheme) {
363
+ t5 = floatingTabPillColors(scheme);
364
+ $[6] = scheme;
365
+ $[7] = t5;
366
+ } else {
367
+ t5 = $[7];
368
+ }
369
+ let t6;
370
+ if ($[8] !== t4 || $[9] !== t5.backgroundColor) {
371
+ t6 = {
372
+ position: "absolute",
373
+ top: 0,
374
+ bottom: 0,
375
+ width: t4,
376
+ borderRadius: FLOATING_PILL_RADIUS,
377
+ backgroundColor: t5.backgroundColor
378
+ };
379
+ $[8] = t4;
380
+ $[9] = t5.backgroundColor;
381
+ $[10] = t6;
382
+ } else {
383
+ t6 = $[10];
384
+ }
385
+ let t7;
386
+ if ($[11] !== slide || $[12] !== t6) {
387
+ t7 = <View pointerEvents="none" style={t3}><Animated.View className="border border-white/40 dark:border-white/10" style={[t6, slide]} /></View>;
388
+ $[11] = slide;
389
+ $[12] = t6;
390
+ $[13] = t7;
391
+ } else {
392
+ t7 = $[13];
393
+ }
394
+ return t7;
395
+ }
396
+ function _temp(t0) {
397
+ const {
398
+ pressed
399
+ } = t0;
400
+ return {
401
+ opacity: pressed ? 0.7 : 1
402
+ };
403
+ }
@@ -0,0 +1,53 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { TouchableOpacity } from "react-native";
3
+ import { withAlpha } from "./palette";
4
+ import { useLargerText } from "./theme";
5
+ import { tokens } from "./tokens";
6
+ import { useScheme } from "./useScheme";
7
+
8
+ /**
9
+ * Fill and border of `HeaderIconButton`: the surface with a white hairline
10
+ * (40%) in light and, in dark, the glass `tokens.color.hairline` of the
11
+ * floating tab bar, so `configureTheme` sets both. Styles, not `bg-surface`,
12
+ * which an app theme that nests `dark` under `surface` keeps white in dark mode.
13
+ */
14
+ export function headerIconButtonColors(scheme) {
15
+ return {
16
+ backgroundColor: tokens.color.surface[scheme],
17
+ borderColor: scheme === "dark" ? tokens.color.hairline.dark : withAlpha(tokens.color.white, 0.4)
18
+ };
19
+ }
20
+ export function HeaderIconButton(t0) {
21
+ const $ = _c(9);
22
+ const {
23
+ onPress,
24
+ label,
25
+ testID,
26
+ children
27
+ } = t0;
28
+ const largerText = useLargerText();
29
+ const scheme = useScheme();
30
+ const t1 = `${largerText ? "h-14 w-14" : "h-12 w-12"} items-center justify-center rounded-full border`;
31
+ let t2;
32
+ if ($[0] !== scheme) {
33
+ t2 = headerIconButtonColors(scheme);
34
+ $[0] = scheme;
35
+ $[1] = t2;
36
+ } else {
37
+ t2 = $[1];
38
+ }
39
+ let t3;
40
+ if ($[2] !== children || $[3] !== label || $[4] !== onPress || $[5] !== t1 || $[6] !== t2 || $[7] !== testID) {
41
+ t3 = <TouchableOpacity testID={testID} className={t1} style={t2} onPress={onPress} accessibilityRole="button" accessibilityLabel={label} hitSlop={8} activeOpacity={0.7}>{children}</TouchableOpacity>;
42
+ $[2] = children;
43
+ $[3] = label;
44
+ $[4] = onPress;
45
+ $[5] = t1;
46
+ $[6] = t2;
47
+ $[7] = testID;
48
+ $[8] = t3;
49
+ } else {
50
+ t3 = $[8];
51
+ }
52
+ return t3;
53
+ }