@expokit/cli 0.0.0-stage → 0.2.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 (302) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -2
  3. package/bin/expo-kit.js +1204 -0
  4. package/bin/lib.mjs +343 -0
  5. package/bin/mcp.mjs +338 -0
  6. package/package.json +44 -4
  7. package/registry/_docs/accordion.json +99 -0
  8. package/registry/_docs/action-sheet.json +110 -0
  9. package/registry/_docs/alert.json +127 -0
  10. package/registry/_docs/avatar.json +203 -0
  11. package/registry/_docs/badge.json +117 -0
  12. package/registry/_docs/bottom-nav.json +119 -0
  13. package/registry/_docs/bottom-sheet.json +158 -0
  14. package/registry/_docs/bullet.json +24 -0
  15. package/registry/_docs/button-3d.json +122 -0
  16. package/registry/_docs/button.json +115 -0
  17. package/registry/_docs/calendar.json +182 -0
  18. package/registry/_docs/card-stack.json +108 -0
  19. package/registry/_docs/card.json +111 -0
  20. package/registry/_docs/carousel.json +102 -0
  21. package/registry/_docs/checkbox.json +93 -0
  22. package/registry/_docs/checkout.json +102 -0
  23. package/registry/_docs/chip-group.json +116 -0
  24. package/registry/_docs/color-swatch.json +66 -0
  25. package/registry/_docs/confetti.json +82 -0
  26. package/registry/_docs/coupon.json +176 -0
  27. package/registry/_docs/cube-pager.json +84 -0
  28. package/registry/_docs/dashboard.json +120 -0
  29. package/registry/_docs/date-picker.json +249 -0
  30. package/registry/_docs/dialog.json +162 -0
  31. package/registry/_docs/drawer.json +171 -0
  32. package/registry/_docs/fab.json +120 -0
  33. package/registry/_docs/flip-card.json +111 -0
  34. package/registry/_docs/floating-input.json +191 -0
  35. package/registry/_docs/gift-card.json +108 -0
  36. package/registry/_docs/glass-button.json +118 -0
  37. package/registry/_docs/glass-nav-bar.json +78 -0
  38. package/registry/_docs/glass-search-bar.json +90 -0
  39. package/registry/_docs/glass-segmented.json +66 -0
  40. package/registry/_docs/glass-sheet.json +108 -0
  41. package/registry/_docs/glass-tab-bar.json +76 -0
  42. package/registry/_docs/glass.json +78 -0
  43. package/registry/_docs/inbox.json +72 -0
  44. package/registry/_docs/isometric-bar.json +72 -0
  45. package/registry/_docs/kit.json +11 -0
  46. package/registry/_docs/kpi-card.json +11 -0
  47. package/registry/_docs/like-button.json +72 -0
  48. package/registry/_docs/liquidglass-tab.json +27 -0
  49. package/registry/_docs/list-item.json +200 -0
  50. package/registry/_docs/loyalty-card.json +108 -0
  51. package/registry/_docs/morph-button.json +108 -0
  52. package/registry/_docs/number-ticker.json +96 -0
  53. package/registry/_docs/offers.json +78 -0
  54. package/registry/_docs/onboarding.json +66 -0
  55. package/registry/_docs/otp-input.json +134 -0
  56. package/registry/_docs/pagination-dots.json +88 -0
  57. package/registry/_docs/parallax-layers.json +84 -0
  58. package/registry/_docs/parallax-scroll.json +186 -0
  59. package/registry/_docs/password-input.json +92 -0
  60. package/registry/_docs/payment-card.json +153 -0
  61. package/registry/_docs/pixel-bar.json +66 -0
  62. package/registry/_docs/polar-area.json +78 -0
  63. package/registry/_docs/profile.json +84 -0
  64. package/registry/_docs/progress-steps.json +92 -0
  65. package/registry/_docs/progress.json +132 -0
  66. package/registry/_docs/radio-group.json +92 -0
  67. package/registry/_docs/rating.json +90 -0
  68. package/registry/_docs/ring-carousel.json +102 -0
  69. package/registry/_docs/scratch-card.json +90 -0
  70. package/registry/_docs/search-bar.json +140 -0
  71. package/registry/_docs/search-results.json +120 -0
  72. package/registry/_docs/segmented-control.json +103 -0
  73. package/registry/_docs/select.json +252 -0
  74. package/registry/_docs/settings.json +72 -0
  75. package/registry/_docs/shimmer-button.json +78 -0
  76. package/registry/_docs/sign-in.json +198 -0
  77. package/registry/_docs/skeleton.json +142 -0
  78. package/registry/_docs/slide-to-confirm.json +84 -0
  79. package/registry/_docs/slider.json +157 -0
  80. package/registry/_docs/spin-wheel.json +114 -0
  81. package/registry/_docs/spinner.json +91 -0
  82. package/registry/_docs/stepper.json +168 -0
  83. package/registry/_docs/swipe-deck.json +102 -0
  84. package/registry/_docs/swipeable-row.json +72 -0
  85. package/registry/_docs/switch.json +104 -0
  86. package/registry/_docs/tabs.json +105 -0
  87. package/registry/_docs/tag-input.json +128 -0
  88. package/registry/_docs/textarea.json +175 -0
  89. package/registry/_docs/ticket-card.json +174 -0
  90. package/registry/_docs/ticket-shape.json +11 -0
  91. package/registry/_docs/tilt-card.json +141 -0
  92. package/registry/_docs/time-picker.json +253 -0
  93. package/registry/_docs/timeline-chart.json +30 -0
  94. package/registry/_docs/timeline.json +156 -0
  95. package/registry/_docs/toast.json +161 -0
  96. package/registry/_docs/treemap.json +30 -0
  97. package/registry/_docs/waterfall.json +36 -0
  98. package/registry/_docs/wheel-list.json +102 -0
  99. package/registry/accordion/files/src/components/ui/accordion.tsx +233 -0
  100. package/registry/accordion/files/src/lib/kit.tsx +219 -0
  101. package/registry/accordion.json +17 -0
  102. package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +580 -0
  103. package/registry/action-sheet/files/src/lib/kit.tsx +219 -0
  104. package/registry/action-sheet.json +18 -0
  105. package/registry/alert/files/src/components/ui/alert.tsx +654 -0
  106. package/registry/alert/files/src/components/ui/button.tsx +274 -0
  107. package/registry/alert/files/src/lib/kit.tsx +219 -0
  108. package/registry/alert.json +20 -0
  109. package/registry/avatar/files/src/components/ui/avatar.tsx +790 -0
  110. package/registry/avatar/files/src/lib/kit.tsx +219 -0
  111. package/registry/avatar.json +18 -0
  112. package/registry/badge/files/src/components/ui/badge.tsx +316 -0
  113. package/registry/badge/files/src/lib/kit.tsx +219 -0
  114. package/registry/badge.json +17 -0
  115. package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +1050 -0
  116. package/registry/bottom-nav/files/src/lib/kit.tsx +219 -0
  117. package/registry/bottom-nav.json +18 -0
  118. package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +585 -0
  119. package/registry/bottom-sheet/files/src/lib/kit.tsx +219 -0
  120. package/registry/bottom-sheet.json +17 -0
  121. package/registry/bullet.json +14 -0
  122. package/registry/button/files/src/components/ui/button.tsx +274 -0
  123. package/registry/button/files/src/lib/kit.tsx +219 -0
  124. package/registry/button-3d/files/src/components/ui/button-3d.tsx +212 -0
  125. package/registry/button-3d/files/src/lib/kit.tsx +219 -0
  126. package/registry/button-3d.json +18 -0
  127. package/registry/button.json +18 -0
  128. package/registry/calendar/files/src/components/ui/calendar.tsx +822 -0
  129. package/registry/calendar/files/src/lib/kit.tsx +219 -0
  130. package/registry/calendar.json +17 -0
  131. package/registry/card/files/src/components/ui/card.tsx +300 -0
  132. package/registry/card/files/src/lib/kit.tsx +219 -0
  133. package/registry/card-stack.json +15 -0
  134. package/registry/card.json +17 -0
  135. package/registry/carousel.json +15 -0
  136. package/registry/checkbox/files/src/components/ui/checkbox.tsx +150 -0
  137. package/registry/checkbox/files/src/lib/kit.tsx +219 -0
  138. package/registry/checkbox.json +17 -0
  139. package/registry/checkout.json +26 -0
  140. package/registry/chip-group/files/src/components/ui/chip-group.tsx +269 -0
  141. package/registry/chip-group/files/src/lib/kit.tsx +219 -0
  142. package/registry/chip-group.json +17 -0
  143. package/registry/color-swatch.json +17 -0
  144. package/registry/confetti/files/src/components/ui/confetti.tsx +222 -0
  145. package/registry/confetti/files/src/lib/kit.tsx +219 -0
  146. package/registry/confetti.json +15 -0
  147. package/registry/coupon/files/src/components/ui/coupon.tsx +698 -0
  148. package/registry/coupon/files/src/components/ui/flip-card.tsx +205 -0
  149. package/registry/coupon/files/src/components/ui/tilt-card.tsx +635 -0
  150. package/registry/coupon/files/src/lib/kit.tsx +219 -0
  151. package/registry/coupon/files/src/lib/ticket-shape.tsx +543 -0
  152. package/registry/coupon.json +23 -0
  153. package/registry/cube-pager.json +15 -0
  154. package/registry/dashboard.json +32 -0
  155. package/registry/date-picker/files/src/components/ui/calendar.tsx +822 -0
  156. package/registry/date-picker/files/src/components/ui/date-picker.tsx +796 -0
  157. package/registry/date-picker/files/src/lib/kit.tsx +219 -0
  158. package/registry/date-picker.json +19 -0
  159. package/registry/dialog/files/src/components/ui/dialog.tsx +759 -0
  160. package/registry/dialog/files/src/lib/kit.tsx +219 -0
  161. package/registry/dialog.json +18 -0
  162. package/registry/drawer/files/src/components/ui/drawer.tsx +1135 -0
  163. package/registry/drawer/files/src/lib/kit.tsx +219 -0
  164. package/registry/drawer.json +18 -0
  165. package/registry/fab.json +18 -0
  166. package/registry/flip-card/files/src/components/ui/flip-card.tsx +205 -0
  167. package/registry/flip-card/files/src/lib/kit.tsx +219 -0
  168. package/registry/flip-card.json +15 -0
  169. package/registry/floating-input/files/src/components/ui/floating-input.tsx +528 -0
  170. package/registry/floating-input/files/src/lib/kit.tsx +219 -0
  171. package/registry/floating-input.json +17 -0
  172. package/registry/gift-card.json +21 -0
  173. package/registry/glass-button.json +22 -0
  174. package/registry/glass-nav-bar.json +21 -0
  175. package/registry/glass-search-bar.json +21 -0
  176. package/registry/glass-segmented.json +22 -0
  177. package/registry/glass-sheet.json +22 -0
  178. package/registry/glass-tab-bar.json +22 -0
  179. package/registry/glass.json +19 -0
  180. package/registry/inbox.json +30 -0
  181. package/registry/isometric-bar.json +14 -0
  182. package/registry/kit/files/src/lib/kit.tsx +219 -0
  183. package/registry/kit.json +11 -0
  184. package/registry/kpi-card/files/src/components/charts/kpi-card.tsx +45 -0
  185. package/registry/kpi-card.json +14 -0
  186. package/registry/like-button.json +18 -0
  187. package/registry/liquidglass-tab/files/src/app/(tabs)/_layout.tsx +97 -0
  188. package/registry/liquidglass-tab/files/src/app/(tabs)/alerts.tsx +5 -0
  189. package/registry/liquidglass-tab/files/src/app/(tabs)/explore.tsx +5 -0
  190. package/registry/liquidglass-tab/files/src/app/(tabs)/index.tsx +5 -0
  191. package/registry/liquidglass-tab/files/src/app/(tabs)/profile.tsx +5 -0
  192. package/registry/liquidglass-tab/files/src/app/_layout.tsx +33 -0
  193. package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +259 -0
  194. package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +122 -0
  195. package/registry/liquidglass-tab/files/src/lib/tab-bar.ts +61 -0
  196. package/registry/liquidglass-tab/files/src/lib/tab-icons.ts +130 -0
  197. package/registry/liquidglass-tab/files/src/lib/tabs.ts +108 -0
  198. package/registry/liquidglass-tab.json +23 -0
  199. package/registry/list-item/files/src/components/ui/list-item.tsx +508 -0
  200. package/registry/list-item/files/src/lib/kit.tsx +219 -0
  201. package/registry/list-item.json +17 -0
  202. package/registry/loyalty-card.json +23 -0
  203. package/registry/morph-button.json +18 -0
  204. package/registry/number-ticker.json +15 -0
  205. package/registry/offers.json +24 -0
  206. package/registry/onboarding.json +17 -0
  207. package/registry/otp-input/files/src/components/ui/otp-input.tsx +380 -0
  208. package/registry/otp-input/files/src/lib/kit.tsx +219 -0
  209. package/registry/otp-input.json +17 -0
  210. package/registry/pagination-dots/files/src/components/ui/pagination-dots.tsx +262 -0
  211. package/registry/pagination-dots/files/src/lib/kit.tsx +219 -0
  212. package/registry/pagination-dots.json +15 -0
  213. package/registry/parallax-layers.json +15 -0
  214. package/registry/parallax-scroll.json +17 -0
  215. package/registry/password-input/files/src/components/ui/floating-input.tsx +528 -0
  216. package/registry/password-input/files/src/components/ui/password-input.tsx +271 -0
  217. package/registry/password-input/files/src/lib/kit.tsx +219 -0
  218. package/registry/password-input.json +19 -0
  219. package/registry/payment-card/files/src/components/ui/flip-card.tsx +205 -0
  220. package/registry/payment-card/files/src/components/ui/payment-card.tsx +385 -0
  221. package/registry/payment-card/files/src/components/ui/tilt-card.tsx +635 -0
  222. package/registry/payment-card/files/src/lib/kit.tsx +219 -0
  223. package/registry/payment-card.json +21 -0
  224. package/registry/pixel-bar.json +14 -0
  225. package/registry/polar-area.json +14 -0
  226. package/registry/profile.json +17 -0
  227. package/registry/progress/files/src/components/ui/progress.tsx +883 -0
  228. package/registry/progress/files/src/lib/kit.tsx +219 -0
  229. package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +559 -0
  230. package/registry/progress-steps/files/src/lib/kit.tsx +219 -0
  231. package/registry/progress-steps.json +18 -0
  232. package/registry/progress.json +17 -0
  233. package/registry/radio-group/files/src/components/ui/radio-group.tsx +327 -0
  234. package/registry/radio-group/files/src/lib/kit.tsx +219 -0
  235. package/registry/radio-group.json +18 -0
  236. package/registry/rating.json +18 -0
  237. package/registry/ring-carousel.json +15 -0
  238. package/registry/scratch-card.json +18 -0
  239. package/registry/search-bar/files/src/components/ui/search-bar.tsx +530 -0
  240. package/registry/search-bar/files/src/lib/kit.tsx +219 -0
  241. package/registry/search-bar.json +17 -0
  242. package/registry/search-results.json +30 -0
  243. package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +341 -0
  244. package/registry/segmented-control/files/src/lib/kit.tsx +219 -0
  245. package/registry/segmented-control.json +18 -0
  246. package/registry/select/files/src/components/ui/select.tsx +1398 -0
  247. package/registry/select/files/src/lib/kit.tsx +219 -0
  248. package/registry/select.json +17 -0
  249. package/registry/settings.json +26 -0
  250. package/registry/shimmer-button.json +17 -0
  251. package/registry/sign-in.json +26 -0
  252. package/registry/skeleton/files/src/components/ui/skeleton.tsx +799 -0
  253. package/registry/skeleton/files/src/lib/kit.tsx +219 -0
  254. package/registry/skeleton.json +17 -0
  255. package/registry/slide-to-confirm.json +18 -0
  256. package/registry/slider/files/src/components/ui/slider.tsx +716 -0
  257. package/registry/slider/files/src/lib/kit.tsx +219 -0
  258. package/registry/slider.json +17 -0
  259. package/registry/spin-wheel.json +18 -0
  260. package/registry/spinner/files/src/components/ui/spinner.tsx +335 -0
  261. package/registry/spinner/files/src/lib/kit.tsx +219 -0
  262. package/registry/spinner.json +17 -0
  263. package/registry/stepper/files/src/components/ui/stepper.tsx +646 -0
  264. package/registry/stepper/files/src/lib/kit.tsx +219 -0
  265. package/registry/stepper.json +17 -0
  266. package/registry/swipe-deck.json +15 -0
  267. package/registry/swipeable-row.json +15 -0
  268. package/registry/switch/files/src/components/ui/switch.tsx +344 -0
  269. package/registry/switch/files/src/lib/kit.tsx +219 -0
  270. package/registry/switch.json +18 -0
  271. package/registry/tabs/files/src/components/ui/tabs.tsx +539 -0
  272. package/registry/tabs/files/src/lib/kit.tsx +219 -0
  273. package/registry/tabs.json +17 -0
  274. package/registry/tag-input/files/src/components/ui/tag-input.tsx +720 -0
  275. package/registry/tag-input/files/src/lib/kit.tsx +219 -0
  276. package/registry/tag-input.json +17 -0
  277. package/registry/textarea/files/src/components/ui/textarea.tsx +553 -0
  278. package/registry/textarea/files/src/lib/kit.tsx +219 -0
  279. package/registry/textarea.json +17 -0
  280. package/registry/ticket-card.json +24 -0
  281. package/registry/ticket-shape/files/src/lib/kit.tsx +219 -0
  282. package/registry/ticket-shape/files/src/lib/ticket-shape.tsx +543 -0
  283. package/registry/ticket-shape.json +17 -0
  284. package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +635 -0
  285. package/registry/tilt-card/files/src/lib/kit.tsx +219 -0
  286. package/registry/tilt-card.json +17 -0
  287. package/registry/time-picker/files/src/components/ui/time-picker.tsx +1159 -0
  288. package/registry/time-picker/files/src/lib/kit.tsx +219 -0
  289. package/registry/time-picker.json +17 -0
  290. package/registry/timeline/files/src/components/ui/avatar.tsx +790 -0
  291. package/registry/timeline/files/src/components/ui/timeline.tsx +1059 -0
  292. package/registry/timeline/files/src/lib/kit.tsx +219 -0
  293. package/registry/timeline-chart.json +14 -0
  294. package/registry/timeline.json +20 -0
  295. package/registry/toast/files/src/components/ui/button.tsx +274 -0
  296. package/registry/toast/files/src/components/ui/toast.tsx +1284 -0
  297. package/registry/toast/files/src/lib/kit.tsx +219 -0
  298. package/registry/toast.json +20 -0
  299. package/registry/treemap.json +14 -0
  300. package/registry/waterfall.json +14 -0
  301. package/registry/wheel-list.json +17 -0
  302. package/schema/components.schema.json +13 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "liquidglass-tab",
3
+ "category": "Templates",
4
+ "aliases": [],
5
+ "exportName": null,
6
+ "files": [
7
+ "src/app/(tabs)/_layout.tsx",
8
+ "src/app/(tabs)/alerts.tsx",
9
+ "src/app/(tabs)/explore.tsx",
10
+ "src/app/(tabs)/index.tsx",
11
+ "src/app/(tabs)/profile.tsx",
12
+ "src/app/_layout.tsx",
13
+ "src/components/GlassTabBar.tsx",
14
+ "src/components/TabScreen.tsx",
15
+ "src/lib/tab-bar.ts",
16
+ "src/lib/tab-icons.ts",
17
+ "src/lib/tabs.ts"
18
+ ],
19
+ "props": [],
20
+ "examples": [
21
+ {
22
+ "name": "Preview",
23
+ "title": "Preview",
24
+ "code": "import React, { useEffect, useRef, useState } from 'react';\nimport { Animated, Image, Platform, Pressable, ScrollView, StyleSheet, Text, View, type LayoutChangeEvent, type NativeScrollEvent, type NativeSyntheticEvent } from 'react-native';\nimport { BlurView } from 'expo-blur';\nimport Svg, { Circle, Path } from 'react-native-svg';\nimport { useKit } from '@/lib/kit';\n\ntype TabKey = 'index' | 'explore' | 'alerts' | 'profile';\n\nconst TABS: { key: TabKey; title: string; badge?: string; icon: (c: string) => React.ReactNode }[] = [\n { key: 'index', title: 'Home', icon: (c) => <Path d=\"M3 10.5 12 3l9 7.5V20a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z\" stroke={c} strokeWidth={2} strokeLinejoin=\"round\" fill=\"none\" /> },\n {\n key: 'explore',\n title: 'Explore',\n icon: (c) => (\n <>\n <Circle cx={12} cy={12} r={9} stroke={c} strokeWidth={2} fill=\"none\" />\n <Path d=\"m15.5 8.5-2 5-5 2 2-5z\" stroke={c} strokeWidth={2} strokeLinejoin=\"round\" fill=\"none\" />\n </>\n ),\n },\n { key: 'alerts', title: 'Alerts', badge: '3', icon: (c) => <Path d=\"M6 8a6 6 0 1 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10 21h4\" stroke={c} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" fill=\"none\" /> },\n {\n key: 'profile',\n title: 'Profile',\n icon: (c) => (\n <>\n <Circle cx={12} cy={8} r={4} stroke={c} strokeWidth={2} fill=\"none\" />\n <Path d=\"M4 21c1.5-4 4.5-6 8-6s6.5 2 8 6\" stroke={c} strokeWidth={2} strokeLinecap=\"round\" fill=\"none\" />\n </>\n ),\n },\n];\n\nconst PHOTOS = [\n 'photo-1501785888041-af3ef285b470',\n 'photo-1469474968028-56623f02e42e',\n 'photo-1500530855697-b586d89ba3ee',\n 'photo-1470071459604-3b5ec3a7fe05',\n 'photo-1441974231531-c6227db76b6e',\n].map((id) => `https://images.unsplash.com/${id}?w=700&auto=format&fit=crop`);\n\nconst COPY: Record<TabKey, { title: string; sub: string }> = {\n index: { title: 'For you', sub: 'Places picked for this weekend' },\n explore: { title: 'Explore', sub: 'Trending trails near you' },\n alerts: { title: 'Alerts', sub: '3 new since yesterday' },\n profile: { title: 'Profile', sub: 'Trips, saves and settings' },\n};\n\nconst BAR_H = 64;\n\nfunction GlassBar({\n value,\n onChange,\n dark,\n collapsed,\n onExpand,\n}: {\n value: TabKey;\n onChange: (k: TabKey) => void;\n dark: boolean;\n collapsed: boolean;\n onExpand: () => void;\n}) {\n const [w, setW] = useState(0);\n // 0 = full bar, 1 = folded into a circle (JS driver: it animates the bar's width).\n const fold = useRef(new Animated.Value(0)).current;\n useEffect(() => {\n Animated.spring(fold, { toValue: collapsed ? 1 : 0, useNativeDriver: false, damping: 20, stiffness: 220, mass: 0.9 }).start();\n }, [collapsed, fold]);\n const width = fold.interpolate({ inputRange: [0, 1], outputRange: [w || 1, BAR_H] });\n const rowOpacity = fold.interpolate({ inputRange: [0, 0.45], outputRange: [1, 0], extrapolate: 'clamp' });\n const dotOpacity = fold.interpolate({ inputRange: [0.55, 1], outputRange: [0, 1], extrapolate: 'clamp' });\n const dotScale = fold.interpolate({ inputRange: [0.55, 1], outputRange: [0.6, 1], extrapolate: 'clamp' });\n const active = TABS.find((t) => t.key === value) ?? TABS[0];\n const x = useRef(new Animated.Value(0)).current;\n const stretch = useRef(new Animated.Value(1)).current;\n const index = TABS.findIndex((t) => t.key === value);\n const itemW = w ? (w - 8) / TABS.length : 0;\n const tint = dark ? '#0a84ff' : '#007aff';\n const inactive = dark ? 'rgba(235,235,245,0.6)' : 'rgba(60,60,67,0.6)';\n\n useEffect(() => {\n if (!itemW) return;\n Animated.parallel([\n Animated.spring(x, { toValue: index * itemW, useNativeDriver: true, damping: 18, stiffness: 220, mass: 0.9 }),\n Animated.sequence([\n Animated.timing(stretch, { toValue: 1.22, duration: 110, useNativeDriver: true }),\n Animated.spring(stretch, { toValue: 1, useNativeDriver: true, damping: 10, stiffness: 260 }),\n ]),\n ]).start();\n }, [index, itemW, x, stretch]);\n\n return (\n <View pointerEvents=\"box-none\" style={styles.host} onLayout={(e: LayoutChangeEvent) => setW(Math.round(e.nativeEvent.layout.width))}>\n <Animated.View style={[styles.shadow, dark ? styles.shadowDark : styles.shadowLight, w ? { width } : null]}>\n <View style={[styles.glass, { borderColor: dark ? 'rgba(255,255,255,0.14)' : 'rgba(255,255,255,0.8)' }]}>\n <BlurView intensity={Platform.OS === 'ios' ? 70 : 40} tint={dark ? 'dark' : 'light'} style={[StyleSheet.absoluteFill, styles.round]} />\n <View style={[StyleSheet.absoluteFill, { backgroundColor: dark ? 'rgba(28,28,34,0.5)' : 'rgba(255,255,255,0.55)' }]} />\n <View style={[styles.rim, { backgroundColor: dark ? 'rgba(255,255,255,0.18)' : 'rgba(255,255,255,0.95)' }]} />\n {itemW ? (\n <Animated.View\n style={[\n styles.bubble,\n {\n width: itemW,\n backgroundColor: dark ? 'rgba(255,255,255,0.14)' : 'rgba(0,0,0,0.06)',\n transform: [{ translateX: x }, { scaleX: stretch }, { scaleY: stretch.interpolate({ inputRange: [1, 1.22], outputRange: [1, 0.88] }) }],\n },\n ]}\n />\n ) : null}\n <Animated.View pointerEvents={collapsed ? 'none' : 'auto'} style={[styles.row, w ? { width: w } : null, { opacity: rowOpacity }]}>\n {TABS.map((t) => {\n const on = t.key === value;\n const c = on ? tint : inactive;\n return (\n <Pressable\n key={t.key}\n onPress={() => onChange(t.key)}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: on }}\n accessibilityLabel={t.title}\n style={styles.item}\n >\n <View>\n <Svg width={24} height={24} viewBox=\"0 0 24 24\">\n {t.icon(c)}\n </Svg>\n {t.badge ? (\n <View style={styles.badge}>\n <Text style={styles.badgeText}>{t.badge}</Text>\n </View>\n ) : null}\n </View>\n <Text style={[styles.label, { color: c }]}>{t.title}</Text>\n </Pressable>\n );\n })}\n </Animated.View>\n <Animated.View pointerEvents={collapsed ? 'auto' : 'none'} style={[styles.dot, { opacity: dotOpacity, transform: [{ scale: dotScale }] }]}>\n <Pressable onPress={onExpand} accessibilityRole=\"button\" accessibilityLabel={`${active.title}. Show tab bar`} style={styles.dotPress}>\n <Svg width={26} height={26} viewBox=\"0 0 24 24\">\n {active.icon(tint)}\n </Svg>\n </Pressable>\n </Animated.View>\n </View>\n </Animated.View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n root: { flex: 1 },\n feed: { paddingHorizontal: 16, paddingTop: 12, paddingBottom: 120, gap: 12 },\n large: { fontSize: 32, lineHeight: 38, letterSpacing: -0.8, fontWeight: '400' },\n sub: { fontSize: 15, marginTop: -6, marginBottom: 6 },\n card: { height: 190, borderRadius: 22, overflow: 'hidden', justifyContent: 'flex-end', padding: 16 },\n cardShade: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.18)' },\n cardTitle: { color: '#ffffff', fontSize: 20, fontWeight: '400', letterSpacing: -0.3 },\n host: { position: 'absolute', left: 20, right: 20, bottom: 24 },\n shadow: { height: BAR_H, borderRadius: BAR_H / 2 },\n shadowLight: { boxShadow: '0 10px 28px -8px rgba(0,0,0,0.22)' },\n shadowDark: { boxShadow: '0 10px 28px -8px rgba(0,0,0,0.7)' },\n glass: { flex: 1, borderRadius: 32, overflow: 'hidden', borderWidth: StyleSheet.hairlineWidth * 2 },\n round: { borderRadius: 32 },\n rim: { position: 'absolute', top: 0, left: 24, right: 24, height: 1 },\n bubble: { position: 'absolute', top: 4, bottom: 4, left: 4, borderRadius: 28 },\n row: { flex: 1, flexDirection: 'row', paddingHorizontal: 4 },\n dot: { position: 'absolute', top: 0, left: 0, width: BAR_H, height: BAR_H },\n dotPress: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n item: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 2 },\n label: { fontSize: 10.5, fontWeight: '400' },\n badge: { position: 'absolute', top: -4, right: -10, minWidth: 17, height: 17, borderRadius: 9, paddingHorizontal: 4, backgroundColor: '#ff3b30', alignItems: 'center', justifyContent: 'center' },\n badgeText: { color: '#ffffff', fontSize: 10.5, fontWeight: '400' },\n});\n\nexport default function Preview() {\n const { dark } = useKit();\n const [tab, setTab] = useState<TabKey>('index');\n const [collapsed, setCollapsed] = useState(false);\n const lastY = useRef(0);\n const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {\n const y = e.nativeEvent.contentOffset.y;\n const dy = y - lastY.current;\n lastY.current = y;\n if (y < 24) setCollapsed(false);\n else if (dy > 6) setCollapsed(true);\n else if (dy < -6) setCollapsed(false);\n };\n const fg = dark ? '#ffffff' : '#1c1c1e';\n const sub = dark ? 'rgba(235,235,245,0.6)' : 'rgba(60,60,67,0.6)';\n const offset = TABS.findIndex((t) => t.key === tab);\n const copy = COPY[tab];\n\n return (\n <View style={[styles.root, { backgroundColor: dark ? '#000000' : '#f2f2f7' }]}>\n <ScrollView contentContainerStyle={styles.feed} showsVerticalScrollIndicator={false} onScroll={onScroll} scrollEventThrottle={16}>\n <Text style={[styles.large, { color: fg }]}>{copy.title}</Text>\n <Text style={[styles.sub, { color: sub }]}>{copy.sub}</Text>\n {[0, 1, 2, 3, 4].map((i) => {\n const p = PHOTOS[(i + offset) % PHOTOS.length];\n return (\n <View key={`${tab}-${i}`} style={styles.card}>\n <Image source={{ uri: p }} alt=\"\" style={StyleSheet.absoluteFill} resizeMode=\"cover\" />\n <View style={styles.cardShade} />\n <Text style={styles.cardTitle}>{['Lake Braies', 'Dolomites', 'Valley trail', 'Blue ridge', 'Old forest'][(i + offset) % 5]}</Text>\n </View>\n );\n })}\n </ScrollView>\n <GlassBar value={tab} onChange={setTab} dark={dark} collapsed={collapsed} onExpand={() => setCollapsed(false)} />\n </View>\n );\n}\n"
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,200 @@
1
+ {
2
+ "name": "list-item",
3
+ "category": "Display",
4
+ "aliases": [],
5
+ "exportName": "ListItem",
6
+ "files": [
7
+ "src/components/ui/list-item.tsx"
8
+ ],
9
+ "props": [
10
+ [
11
+ "title",
12
+ "string",
13
+ "—",
14
+ "Main text (required)."
15
+ ],
16
+ [
17
+ "subtitle",
18
+ "string",
19
+ "—",
20
+ "One muted line under the title."
21
+ ],
22
+ [
23
+ "description",
24
+ "string",
25
+ "—",
26
+ "Longer muted text, clamped to numberOfLines."
27
+ ],
28
+ [
29
+ "numberOfLines",
30
+ "number",
31
+ "2",
32
+ "Lines of description shown."
33
+ ],
34
+ [
35
+ "meta",
36
+ "string",
37
+ "—",
38
+ "Small text at the end of the title row, e.g. a time."
39
+ ],
40
+ [
41
+ "icon",
42
+ "ListItemIconName | ({ color, size }) => ReactNode",
43
+ "—",
44
+ "Built-in glyph (user, bell, lock, shield, mail, card, help, logout, moon, globe, star, trash, settings, heart, phone, wifi) or your own, drawn in a rounded tile."
45
+ ],
46
+ [
47
+ "iconColor",
48
+ "string",
49
+ "accent",
50
+ "Tile colour (danger when destructive)."
51
+ ],
52
+ [
53
+ "iconVariant",
54
+ "\"filled\" | \"tinted\"",
55
+ "\"filled\"",
56
+ "White glyph on a solid tile, or coloured glyph on a soft tile."
57
+ ],
58
+ [
59
+ "avatar",
60
+ "{ src?, name?, color?, online? }",
61
+ "—",
62
+ "Round avatar with initials fallback and presence dot."
63
+ ],
64
+ [
65
+ "leading",
66
+ "ReactNode",
67
+ "—",
68
+ "Custom leading content (overrides icon / avatar)."
69
+ ],
70
+ [
71
+ "value",
72
+ "string",
73
+ "—",
74
+ "Muted value text on the right."
75
+ ],
76
+ [
77
+ "badge",
78
+ "boolean | number | string",
79
+ "—",
80
+ "Dot, count (99+) or short label pill."
81
+ ],
82
+ [
83
+ "checked",
84
+ "boolean",
85
+ "—",
86
+ "Accent check mark, for pickers."
87
+ ],
88
+ [
89
+ "chevron",
90
+ "boolean",
91
+ "pressable",
92
+ "Disclosure chevron; on by default for pressable rows without trailing / checked."
93
+ ],
94
+ [
95
+ "trailing",
96
+ "ReactNode",
97
+ "—",
98
+ "Any control on the right, e.g. a Switch."
99
+ ],
100
+ [
101
+ "onPress / onLongPress",
102
+ "() => void",
103
+ "—",
104
+ "Makes the row pressable with a fading highlight."
105
+ ],
106
+ [
107
+ "destructive",
108
+ "boolean",
109
+ "false",
110
+ "Red title, icon and highlight."
111
+ ],
112
+ [
113
+ "disabled",
114
+ "boolean",
115
+ "false",
116
+ "Dims and blocks presses."
117
+ ],
118
+ [
119
+ "size",
120
+ "\"sm\" | \"md\" | \"lg\"",
121
+ "\"md\"",
122
+ "44 / 52 / 68pt minimum height; icons and avatars scale."
123
+ ],
124
+ [
125
+ "divider",
126
+ "boolean",
127
+ "auto in groups",
128
+ "Hairline that starts past the leading slot."
129
+ ],
130
+ [
131
+ "accent",
132
+ "string",
133
+ "theme accent",
134
+ "Check, badge and default tile colour."
135
+ ],
136
+ [
137
+ "titleStyle",
138
+ "StyleProp<TextStyle>",
139
+ "—",
140
+ "E.g. bold for unread rows."
141
+ ],
142
+ [
143
+ "style",
144
+ "StyleProp<ViewStyle>",
145
+ "—",
146
+ "Style for the row; ListGroup / ListSection apply theirs to their root view."
147
+ ],
148
+ [
149
+ "ListGroup header / footer",
150
+ "string",
151
+ "—",
152
+ "Uppercase heading and muted note around the inset card."
153
+ ],
154
+ [
155
+ "ListGroup background",
156
+ "string",
157
+ "colors.card",
158
+ "Card colour."
159
+ ],
160
+ [
161
+ "ListSection header / footer",
162
+ "string",
163
+ "—",
164
+ "Plain, full-width section (contacts, inbox)."
165
+ ],
166
+ [
167
+ "ListSection dividerAfterLast",
168
+ "boolean",
169
+ "false",
170
+ "Draw the inset hairline under the last row too."
171
+ ]
172
+ ],
173
+ "examples": [
174
+ {
175
+ "name": "Settings",
176
+ "title": "Settings",
177
+ "code": "import React, { useState } from 'react';\nimport { View } from 'react-native';\nimport { ListGroup, ListItem, ListSection } from '@/components/ui/list-item';\nimport { Switch } from '@/components/ui/switch';\n\nexport default function Settings() {\n const [dark, setDark] = useState(true);\n return (\n <View style={{ gap: 22 }}>\n <ListGroup header=\"Account\">\n <ListItem icon=\"user\" title=\"Profile\" value=\"Amelia Hart\" onPress={() => {}} />\n <ListItem icon=\"bell\" iconColor=\"#ef4444\" title=\"Notifications\" value=\"Banners\" onPress={() => {}} />\n <ListItem icon=\"shield\" iconColor=\"#22c55e\" title=\"Privacy & security\" onPress={() => {}} />\n <ListItem\n icon=\"moon\"\n iconColor=\"#0ea5e9\"\n title=\"Dark mode\"\n trailing={<Switch size=\"sm\" value={dark} onValueChange={setDark} accessibilityLabel=\"Dark mode\" />}\n />\n </ListGroup>\n <ListGroup footer=\"You'll need your password to sign back in on this device.\">\n <ListItem icon=\"logout\" title=\"Sign out\" destructive chevron={false} onPress={() => {}} />\n </ListGroup>\n </View>\n );\n}\n"
178
+ },
179
+ {
180
+ "name": "Contacts",
181
+ "title": "Contacts",
182
+ "code": "import { View } from 'react-native';\nimport { ListGroup, ListItem, ListSection } from '@/components/ui/list-item';\n\nconst CONTACTS = [\n { name: 'Aisha Rahman', role: 'Product designer · Lisbon', src: 'https://i.pravatar.cc/120?img=47', online: true },\n { name: 'Alex Moreno', role: 'iOS engineer · Madrid' },\n { name: 'Ben Carter', role: 'Founder at Northwind', src: 'https://i.pravatar.cc/120?img=12' },\n { name: 'Bianca Rossi', role: 'Marketing lead · Milan', online: true },\n];\n\nexport default function Contacts() {\n return (\n <View>\n <ListSection header=\"A\">\n {CONTACTS.slice(0, 2).map((c) => (\n <ListItem key={c.name} avatar={{ src: c.src, name: c.name, online: c.online }} title={c.name} subtitle={c.role} onPress={() => {}} />\n ))}\n </ListSection>\n <ListSection header=\"B\">\n {CONTACTS.slice(2).map((c) => (\n <ListItem key={c.name} avatar={{ src: c.src, name: c.name, online: c.online }} title={c.name} subtitle={c.role} onPress={() => {}} />\n ))}\n </ListSection>\n </View>\n );\n}\n"
183
+ },
184
+ {
185
+ "name": "Inbox",
186
+ "title": "Inbox",
187
+ "code": "import { ListGroup, ListItem, ListSection } from '@/components/ui/list-item';\n\nconst MAIL = [\n { from: 'Maya Lin', subject: 'Q3 roadmap — final draft', body: 'Attached the updated plan with the launch moved to the 14th. Can you sign off by Friday?', time: '9:41', unread: 3 },\n { from: 'Stripe', subject: 'Your payout is on the way', body: '₹4,21,850 will arrive in your account ending 4432 on Wednesday.', time: '8:02', unread: 1, color: '#635bff' },\n { from: 'Jonas Weber', subject: 'Re: Dinner on Saturday?', body: \"Booked the Italian place for 7:30. I'll bring the wine.\", time: 'Tue' },\n];\n\nexport default function Inbox() {\n return (\n <ListGroup>\n {MAIL.map((m) => (\n <ListItem\n key={m.from}\n size=\"lg\"\n avatar={{ name: m.from, color: m.color }}\n title={m.from}\n titleStyle={m.unread ? { fontWeight: '400' } : null}\n meta={m.time}\n subtitle={m.subject}\n description={m.body}\n badge={m.unread}\n chevron={false}\n onPress={() => {}}\n />\n ))}\n </ListGroup>\n );\n}\n"
188
+ },
189
+ {
190
+ "name": "Picker",
191
+ "title": "Picker",
192
+ "code": "import React, { useState } from 'react';\nimport { ListGroup, ListItem, ListSection } from '@/components/ui/list-item';\n\nexport default function Picker() {\n const [lang, setLang] = useState('English');\n return (\n <ListGroup header=\"Language\" footer=\"Apps and websites will use the first language they support.\">\n {['English', 'Español', 'Deutsch', '日本語'].map((l) => (\n <ListItem key={l} size=\"sm\" title={l} checked={lang === l} onPress={() => setLang(l)} />\n ))}\n </ListGroup>\n );\n}\n"
193
+ },
194
+ {
195
+ "name": "Tinted",
196
+ "title": "Tinted",
197
+ "code": "import { ListGroup, ListItem, ListSection } from '@/components/ui/list-item';\n\nexport default function Tinted() {\n return (\n <ListGroup>\n <ListItem icon=\"wifi\" iconVariant=\"tinted\" iconColor=\"#0ea5e9\" title=\"Wi-Fi\" value=\"Home-5G\" onPress={() => {}} />\n <ListItem icon=\"card\" iconVariant=\"tinted\" iconColor=\"#f59e0b\" title=\"Payment methods\" description=\"Visa ending 4432 · Apple Pay\" onPress={() => {}} />\n <ListItem icon=\"star\" iconVariant=\"tinted\" title=\"Upgrade to Pro\" badge=\"New\" onPress={() => {}} />\n <ListItem icon=\"trash\" iconVariant=\"tinted\" title=\"Delete account\" destructive disabled onPress={() => {}} />\n </ListGroup>\n );\n}\n"
198
+ }
199
+ ]
200
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "loyalty-card",
3
+ "category": "3D",
4
+ "aliases": [],
5
+ "exportName": "LoyaltyCard",
6
+ "files": [
7
+ "src/components/ui/loyalty-card.tsx"
8
+ ],
9
+ "props": [
10
+ [
11
+ "brand",
12
+ "string",
13
+ "—",
14
+ "Programme name, top-left."
15
+ ],
16
+ [
17
+ "member",
18
+ "string",
19
+ "—",
20
+ "Member's name (bottom line)."
21
+ ],
22
+ [
23
+ "memberId",
24
+ "string",
25
+ "—",
26
+ "Shown on the back under the code."
27
+ ],
28
+ [
29
+ "tier",
30
+ "string",
31
+ "—",
32
+ "Tier pill, e.g. \"Gold\"."
33
+ ],
34
+ [
35
+ "points",
36
+ "number",
37
+ "—",
38
+ "Points balance (ignored with stamps)."
39
+ ],
40
+ [
41
+ "nextReward",
42
+ "{ at: number; label: string }",
43
+ "—",
44
+ "Draws progress toward the next reward."
45
+ ],
46
+ [
47
+ "stamps",
48
+ "{ filled: number; total: number; reward?: string }",
49
+ "—",
50
+ "Stamp card instead of points."
51
+ ],
52
+ [
53
+ "stampGlyph",
54
+ "string",
55
+ "\"✓\"",
56
+ "Glyph in a filled stamp (\"☕\")."
57
+ ],
58
+ [
59
+ "image",
60
+ "ImageSourcePropType",
61
+ "—",
62
+ "Card art — a photo of the shop, product or a texture."
63
+ ],
64
+ [
65
+ "renderCode",
66
+ "(memberId: string) => ReactNode",
67
+ "—",
68
+ "Draw a real scannable code on the back."
69
+ ],
70
+ [
71
+ "flipped / defaultFlipped / onFlip",
72
+ "boolean / boolean / (flipped) => void",
73
+ "— / false / —",
74
+ "Controlled or uncontrolled side."
75
+ ],
76
+ [
77
+ "tilt",
78
+ "boolean",
79
+ "true",
80
+ "Tilt toward the finger."
81
+ ],
82
+ [
83
+ "radius",
84
+ "number",
85
+ "18",
86
+ "Corner radius."
87
+ ],
88
+ [
89
+ "background",
90
+ "string",
91
+ "\"#2b1f17\"",
92
+ "Card colour when there is no image."
93
+ ],
94
+ [
95
+ "labels",
96
+ "{ ready?, more?, reward?, points?, toNext?, back? }",
97
+ "English",
98
+ "Every built-in string, for translation ({n} and {reward} are filled in)."
99
+ ],
100
+ [
101
+ "style",
102
+ "StyleProp<ViewStyle>",
103
+ "—",
104
+ "Style for the root."
105
+ ]
106
+ ],
107
+ "examples": []
108
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "morph-button",
3
+ "category": "Buttons",
4
+ "aliases": [],
5
+ "exportName": "MorphButton",
6
+ "files": [
7
+ "src/components/ui/morph-button.tsx"
8
+ ],
9
+ "props": [
10
+ [
11
+ "onPress",
12
+ "() => Promise<unknown>",
13
+ "—",
14
+ "Async work. Resolve → tick, reject → cross + shake."
15
+ ],
16
+ [
17
+ "variant",
18
+ "\"primary\" | \"accent\" | \"soft\" | \"outline\"",
19
+ "\"primary\"",
20
+ "Look while idle."
21
+ ],
22
+ [
23
+ "size",
24
+ "\"sm\" | \"md\" | \"lg\"",
25
+ "\"md\"",
26
+ "40 / 48 / 56pt tall."
27
+ ],
28
+ [
29
+ "color",
30
+ "string",
31
+ "theme accent",
32
+ "Brand colour for accent, soft and outline."
33
+ ],
34
+ [
35
+ "successColor / errorColor",
36
+ "string",
37
+ "theme success / danger",
38
+ "Colours of the result circle."
39
+ ],
40
+ [
41
+ "resetAfter",
42
+ "number",
43
+ "1300",
44
+ "ms the result stays before morphing back."
45
+ ],
46
+ [
47
+ "minLoading",
48
+ "number",
49
+ "600",
50
+ "Minimum ms the spinner is shown."
51
+ ],
52
+ [
53
+ "onSuccess / onError",
54
+ "(value) => void",
55
+ "—",
56
+ "Called with the resolved value or the thrown error."
57
+ ],
58
+ [
59
+ "onStatusChange",
60
+ "(status) => void",
61
+ "—",
62
+ "\"idle\" | \"loading\" | \"success\" | \"error\"."
63
+ ],
64
+ [
65
+ "pill",
66
+ "boolean",
67
+ "true",
68
+ "Fully rounded ends while idle."
69
+ ],
70
+ [
71
+ "block",
72
+ "boolean",
73
+ "false",
74
+ "Full width; shrinks to the centre while busy."
75
+ ],
76
+ [
77
+ "left",
78
+ "ReactNode",
79
+ "—",
80
+ "Icon before the label."
81
+ ],
82
+ [
83
+ "haptics",
84
+ "boolean",
85
+ "true",
86
+ "Taps on start, success and error."
87
+ ],
88
+ [
89
+ "disabled",
90
+ "boolean",
91
+ "false",
92
+ "Blocks presses."
93
+ ],
94
+ [
95
+ "textStyle",
96
+ "StyleProp<TextStyle>",
97
+ "—",
98
+ "Style for the idle label text."
99
+ ],
100
+ [
101
+ "style",
102
+ "StyleProp<ViewStyle>",
103
+ "—",
104
+ "Style for the outer animated wrapper (margins, alignment)."
105
+ ]
106
+ ],
107
+ "examples": []
108
+ }
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "number-ticker",
3
+ "category": "Motion",
4
+ "aliases": [],
5
+ "exportName": "NumberTicker",
6
+ "files": [
7
+ "src/components/ui/number-ticker.tsx"
8
+ ],
9
+ "props": [
10
+ [
11
+ "value",
12
+ "number",
13
+ "—",
14
+ "The number to show."
15
+ ],
16
+ [
17
+ "decimals",
18
+ "number",
19
+ "0",
20
+ "Digits after the decimal point."
21
+ ],
22
+ [
23
+ "prefix / suffix",
24
+ "string",
25
+ "—",
26
+ "Static text around the number (\"₹\", \"%\")."
27
+ ],
28
+ [
29
+ "separator",
30
+ "string | false",
31
+ "\",\"",
32
+ "Thousands separator."
33
+ ],
34
+ [
35
+ "grouping",
36
+ "'thousands' | 'indian'",
37
+ "'thousands'",
38
+ "Digit grouping: 1,234,567 or lakh / crore style 12,34,567."
39
+ ],
40
+ [
41
+ "decimalSeparator",
42
+ "string",
43
+ "\".\"",
44
+ "Decimal point."
45
+ ],
46
+ [
47
+ "size",
48
+ "\"sm\" | \"md\" | \"lg\" | \"xl\" | number",
49
+ "\"md\"",
50
+ "18 / 28 / 40 / 56pt, or a font size."
51
+ ],
52
+ [
53
+ "fontWeight",
54
+ "TextStyle['fontWeight']",
55
+ "\"500\"",
56
+ "Weight of the digits."
57
+ ],
58
+ [
59
+ "color",
60
+ "string",
61
+ "theme foreground",
62
+ "Text colour."
63
+ ],
64
+ [
65
+ "flash",
66
+ "boolean",
67
+ "true",
68
+ "Tint green on increase, red on decrease."
69
+ ],
70
+ [
71
+ "animateOnMount",
72
+ "boolean",
73
+ "true",
74
+ "Roll up from zero on first render."
75
+ ],
76
+ [
77
+ "stagger",
78
+ "number",
79
+ "35",
80
+ "Delay between columns in ms."
81
+ ],
82
+ [
83
+ "textStyle",
84
+ "StyleProp<TextStyle>",
85
+ "—",
86
+ "Extra glyph styles."
87
+ ],
88
+ [
89
+ "style",
90
+ "StyleProp<ViewStyle>",
91
+ "—",
92
+ "Style for the row of digits."
93
+ ]
94
+ ],
95
+ "examples": []
96
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "offers",
3
+ "category": "Blocks",
4
+ "aliases": [],
5
+ "exportName": "Offers",
6
+ "files": [
7
+ "src/components/blocks/offers.tsx"
8
+ ],
9
+ "props": [
10
+ [
11
+ "offers",
12
+ "Offer[]",
13
+ "sample food-delivery offers",
14
+ "Coupon props plus { id, category?, minOrder?, saves? } — saves is an amount or (total) => amount."
15
+ ],
16
+ [
17
+ "featuredId",
18
+ "string | null",
19
+ "first offer",
20
+ "The offer shown big at the top in 3D; null hides it."
21
+ ],
22
+ [
23
+ "cartTotal",
24
+ "number",
25
+ "549",
26
+ "Decides which coupons are locked and what you save."
27
+ ],
28
+ [
29
+ "appliedId / defaultAppliedId / onApply",
30
+ "string | null / string | null / (offer | null) => void",
31
+ "— / null / —",
32
+ "Controlled or uncontrolled applied coupon; null means removed."
33
+ ],
34
+ [
35
+ "onRedeemCode",
36
+ "(code) => Offer | null | Promise<…>",
37
+ "match by code",
38
+ "Look up a typed code (e.g. on your server)."
39
+ ],
40
+ [
41
+ "onCopy",
42
+ "(code) => void",
43
+ "—",
44
+ "Code chips — wire to expo-clipboard."
45
+ ],
46
+ [
47
+ "onBack",
48
+ "() => void",
49
+ "—",
50
+ "Shows the back button."
51
+ ],
52
+ [
53
+ "onDone",
54
+ "(offer | null) => void",
55
+ "—",
56
+ "Shows the To pay footer with a Done button."
57
+ ],
58
+ [
59
+ "currency / formatPrice",
60
+ "string / (amount) => string",
61
+ "'₹' / Indian grouping",
62
+ "Money formatting."
63
+ ],
64
+ [
65
+ "labels",
66
+ "Partial<OffersLabels>",
67
+ "English",
68
+ "Every string, with {code} and {amount} placeholders."
69
+ ],
70
+ [
71
+ "style",
72
+ "StyleProp<ViewStyle>",
73
+ "—",
74
+ "Root style."
75
+ ]
76
+ ],
77
+ "examples": []
78
+ }