jfs-components 0.0.62 → 0.0.64

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 (255) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/lib/commonjs/components/Accordion/Accordion.js +1 -1
  3. package/lib/commonjs/components/ActionFooter/ActionFooter.js +1 -1
  4. package/lib/commonjs/components/ActionTile/ActionTile.js +2 -1
  5. package/lib/commonjs/components/AmountInput/AmountInput.js +2 -1
  6. package/lib/commonjs/components/AppBar/AppBar.js +1 -1
  7. package/lib/commonjs/components/Avatar/Avatar.js +184 -162
  8. package/lib/commonjs/components/AvatarGroup/AvatarGroup.js +1 -1
  9. package/lib/commonjs/components/Badge/Badge.js +2 -1
  10. package/lib/commonjs/components/Balance/Balance.js +2 -1
  11. package/lib/commonjs/components/BottomNav/BottomNav.js +2 -1
  12. package/lib/commonjs/components/BottomNavItem/BottomNavItem.js +106 -86
  13. package/lib/commonjs/components/Button/Button.js +190 -93
  14. package/lib/commonjs/components/ButtonGroup/ButtonGroup.js +1 -1
  15. package/lib/commonjs/components/Card/Card.js +2 -1
  16. package/lib/commonjs/components/CardCTA/CardCTA.js +1 -1
  17. package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +1 -1
  18. package/lib/commonjs/components/Carousel/Carousel.js +3 -2
  19. package/lib/commonjs/components/Checkbox/Checkbox.js +2 -1
  20. package/lib/commonjs/components/ChipGroup/ChipGroup.js +1 -1
  21. package/lib/commonjs/components/ChipSelect/ChipSelect.js +2 -1
  22. package/lib/commonjs/components/DebitCard/DebitCard.js +1 -1
  23. package/lib/commonjs/components/Disclaimer/Disclaimer.js +2 -1
  24. package/lib/commonjs/components/Divider/Divider.js +2 -1
  25. package/lib/commonjs/components/Drawer/Drawer.js +109 -48
  26. package/lib/commonjs/components/EmptyState/EmptyState.js +2 -1
  27. package/lib/commonjs/components/FilterBar/FilterBar.js +1 -1
  28. package/lib/commonjs/components/Form/Form.js +2 -1
  29. package/lib/commonjs/components/FormField/FormField.js +3 -2
  30. package/lib/commonjs/components/HStack/HStack.js +1 -1
  31. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -1
  32. package/lib/commonjs/components/IconButton/IconButton.js +118 -128
  33. package/lib/commonjs/components/IconCapsule/IconCapsule.js +61 -57
  34. package/lib/commonjs/components/InputSearch/InputSearch.js +7 -3
  35. package/lib/commonjs/components/LazyList/LazyList.js +1 -1
  36. package/lib/commonjs/components/LinearMeter/LinearMeter.js +3 -2
  37. package/lib/commonjs/components/ListGroup/ListGroup.js +1 -1
  38. package/lib/commonjs/components/ListItem/ListItem.js +190 -142
  39. package/lib/commonjs/components/MediaCard/MediaCard.js +3 -3
  40. package/lib/commonjs/components/MerchantProfile/MerchantProfile.js +2 -1
  41. package/lib/commonjs/components/MoneyValue/MoneyValue.js +2 -1
  42. package/lib/commonjs/components/NavArrow/NavArrow.js +82 -59
  43. package/lib/commonjs/components/NoteInput/NoteInput.js +2 -1
  44. package/lib/commonjs/components/Nudge/Nudge.js +1 -1
  45. package/lib/commonjs/components/Numpad/Numpad.js +2 -1
  46. package/lib/commonjs/components/OTP/OTP.js +1 -1
  47. package/lib/commonjs/components/PaymentFeedback/PaymentFeedback.js +2 -1
  48. package/lib/commonjs/components/Popup/Popup.js +2 -1
  49. package/lib/commonjs/components/ProductLabel/ProductLabel.js +2 -1
  50. package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +2 -1
  51. package/lib/commonjs/components/RadioButton/RadioButton.js +2 -1
  52. package/lib/commonjs/components/RechargeCard/RechargeCard.js +2 -1
  53. package/lib/commonjs/components/Screen/Screen.js +1 -1
  54. package/lib/commonjs/components/Section/Section.js +500 -166
  55. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +3 -2
  56. package/lib/commonjs/components/StatItem/StatItem.js +2 -1
  57. package/lib/commonjs/components/StatusHero/StatusHero.js +2 -1
  58. package/lib/commonjs/components/Stepper/Step.js +2 -1
  59. package/lib/commonjs/components/Stepper/StepLabel.js +2 -1
  60. package/lib/commonjs/components/Stepper/Stepper.js +2 -1
  61. package/lib/commonjs/components/SupportText/SupportText.js +2 -1
  62. package/lib/commonjs/components/SupportText/SupportTextIcon.js +2 -1
  63. package/lib/commonjs/components/SwappableAmount/SwappableAmount.js +2 -1
  64. package/lib/commonjs/components/Tabs/TabItem.js +2 -1
  65. package/lib/commonjs/components/Tabs/Tabs.js +2 -1
  66. package/lib/commonjs/components/Text/Text.js +2 -1
  67. package/lib/commonjs/components/TextInput/TextInput.js +2 -2
  68. package/lib/commonjs/components/ThreadHero/ThreadHero.js +2 -1
  69. package/lib/commonjs/components/Title/Title.js +2 -1
  70. package/lib/commonjs/components/Toast/Toast.js +2 -1
  71. package/lib/commonjs/components/Toggle/Toggle.js +2 -1
  72. package/lib/commonjs/components/Tooltip/Tooltip.js +2 -1
  73. package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +1 -1
  74. package/lib/commonjs/components/TransactionDetails/TransactionDetails.js +2 -2
  75. package/lib/commonjs/components/TransactionStatus/TransactionStatus.js +3 -2
  76. package/lib/commonjs/components/UpiHandle/UpiHandle.js +144 -110
  77. package/lib/commonjs/components/VStack/VStack.js +1 -1
  78. package/lib/commonjs/design-tokens/figma-variables-resolver.js +21 -3
  79. package/lib/commonjs/icons/registry.js +1 -1
  80. package/lib/commonjs/utils/react-utils.js +17 -0
  81. package/lib/module/components/Accordion/Accordion.js +2 -2
  82. package/lib/module/components/ActionFooter/ActionFooter.js +2 -2
  83. package/lib/module/components/ActionTile/ActionTile.js +2 -1
  84. package/lib/module/components/AmountInput/AmountInput.js +2 -1
  85. package/lib/module/components/AppBar/AppBar.js +2 -2
  86. package/lib/module/components/Avatar/Avatar.js +184 -162
  87. package/lib/module/components/AvatarGroup/AvatarGroup.js +2 -2
  88. package/lib/module/components/Badge/Badge.js +2 -1
  89. package/lib/module/components/Balance/Balance.js +2 -1
  90. package/lib/module/components/BottomNav/BottomNav.js +2 -1
  91. package/lib/module/components/BottomNavItem/BottomNavItem.js +108 -88
  92. package/lib/module/components/Button/Button.js +192 -95
  93. package/lib/module/components/ButtonGroup/ButtonGroup.js +2 -2
  94. package/lib/module/components/Card/Card.js +2 -1
  95. package/lib/module/components/CardCTA/CardCTA.js +2 -2
  96. package/lib/module/components/CardProviderInfo/CardProviderInfo.js +2 -2
  97. package/lib/module/components/Carousel/Carousel.js +3 -2
  98. package/lib/module/components/Checkbox/Checkbox.js +2 -1
  99. package/lib/module/components/ChipGroup/ChipGroup.js +2 -2
  100. package/lib/module/components/ChipSelect/ChipSelect.js +2 -1
  101. package/lib/module/components/DebitCard/DebitCard.js +2 -2
  102. package/lib/module/components/Disclaimer/Disclaimer.js +2 -1
  103. package/lib/module/components/Divider/Divider.js +2 -1
  104. package/lib/module/components/Drawer/Drawer.js +109 -48
  105. package/lib/module/components/EmptyState/EmptyState.js +2 -1
  106. package/lib/module/components/FilterBar/FilterBar.js +2 -2
  107. package/lib/module/components/Form/Form.js +2 -1
  108. package/lib/module/components/FormField/FormField.js +3 -2
  109. package/lib/module/components/HStack/HStack.js +2 -2
  110. package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -1
  111. package/lib/module/components/IconButton/IconButton.js +120 -130
  112. package/lib/module/components/IconCapsule/IconCapsule.js +60 -57
  113. package/lib/module/components/InputSearch/InputSearch.js +7 -3
  114. package/lib/module/components/LazyList/LazyList.js +2 -2
  115. package/lib/module/components/LinearMeter/LinearMeter.js +3 -2
  116. package/lib/module/components/ListGroup/ListGroup.js +2 -2
  117. package/lib/module/components/ListItem/ListItem.js +194 -146
  118. package/lib/module/components/MediaCard/MediaCard.js +4 -2
  119. package/lib/module/components/MerchantProfile/MerchantProfile.js +2 -1
  120. package/lib/module/components/MoneyValue/MoneyValue.js +2 -1
  121. package/lib/module/components/NavArrow/NavArrow.js +82 -58
  122. package/lib/module/components/NoteInput/NoteInput.js +2 -1
  123. package/lib/module/components/Nudge/Nudge.js +2 -2
  124. package/lib/module/components/Numpad/Numpad.js +2 -1
  125. package/lib/module/components/OTP/OTP.js +2 -2
  126. package/lib/module/components/PaymentFeedback/PaymentFeedback.js +2 -1
  127. package/lib/module/components/Popup/Popup.js +2 -1
  128. package/lib/module/components/ProductLabel/ProductLabel.js +2 -1
  129. package/lib/module/components/ProgressBadge/ProgressBadge.js +2 -1
  130. package/lib/module/components/RadioButton/RadioButton.js +2 -1
  131. package/lib/module/components/RechargeCard/RechargeCard.js +2 -1
  132. package/lib/module/components/Screen/Screen.js +2 -2
  133. package/lib/module/components/Section/Section.js +503 -169
  134. package/lib/module/components/SegmentedControl/SegmentedControl.js +3 -2
  135. package/lib/module/components/StatItem/StatItem.js +2 -1
  136. package/lib/module/components/StatusHero/StatusHero.js +2 -1
  137. package/lib/module/components/Stepper/Step.js +2 -1
  138. package/lib/module/components/Stepper/StepLabel.js +2 -1
  139. package/lib/module/components/Stepper/Stepper.js +2 -1
  140. package/lib/module/components/SupportText/SupportText.js +2 -1
  141. package/lib/module/components/SupportText/SupportTextIcon.js +2 -1
  142. package/lib/module/components/SwappableAmount/SwappableAmount.js +2 -1
  143. package/lib/module/components/Tabs/TabItem.js +2 -1
  144. package/lib/module/components/Tabs/Tabs.js +2 -1
  145. package/lib/module/components/Text/Text.js +2 -1
  146. package/lib/module/components/TextInput/TextInput.js +3 -3
  147. package/lib/module/components/ThreadHero/ThreadHero.js +2 -1
  148. package/lib/module/components/Title/Title.js +2 -1
  149. package/lib/module/components/Toast/Toast.js +2 -1
  150. package/lib/module/components/Toggle/Toggle.js +2 -1
  151. package/lib/module/components/Tooltip/Tooltip.js +2 -1
  152. package/lib/module/components/TransactionBubble/TransactionBubble.js +2 -2
  153. package/lib/module/components/TransactionDetails/TransactionDetails.js +3 -3
  154. package/lib/module/components/TransactionStatus/TransactionStatus.js +3 -2
  155. package/lib/module/components/UpiHandle/UpiHandle.js +147 -113
  156. package/lib/module/components/VStack/VStack.js +2 -2
  157. package/lib/module/design-tokens/figma-variables-resolver.js +21 -3
  158. package/lib/module/icons/registry.js +1 -1
  159. package/lib/module/utils/react-utils.js +16 -0
  160. package/lib/typescript/src/components/Avatar/Avatar.d.ts +11 -17
  161. package/lib/typescript/src/components/BottomNavItem/BottomNavItem.d.ts +12 -8
  162. package/lib/typescript/src/components/Button/Button.d.ts +18 -1
  163. package/lib/typescript/src/components/IconButton/IconButton.d.ts +12 -29
  164. package/lib/typescript/src/components/IconCapsule/IconCapsule.d.ts +10 -18
  165. package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +8 -3
  166. package/lib/typescript/src/components/ListItem/ListItem.d.ts +14 -1
  167. package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +12 -11
  168. package/lib/typescript/src/components/Section/Section.d.ts +43 -48
  169. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +13 -12
  170. package/lib/typescript/src/icons/registry.d.ts +1 -1
  171. package/lib/typescript/src/utils/react-utils.d.ts +15 -0
  172. package/package.json +4 -6
  173. package/src/components/Accordion/Accordion.tsx +2 -2
  174. package/src/components/ActionFooter/ActionFooter.tsx +2 -2
  175. package/src/components/ActionTile/ActionTile.tsx +2 -1
  176. package/src/components/AmountInput/AmountInput.tsx +2 -1
  177. package/src/components/AppBar/AppBar.tsx +2 -2
  178. package/src/components/Avatar/Avatar.tsx +229 -158
  179. package/src/components/AvatarGroup/AvatarGroup.tsx +2 -2
  180. package/src/components/Badge/Badge.tsx +2 -1
  181. package/src/components/Balance/Balance.tsx +2 -1
  182. package/src/components/BottomNav/BottomNav.tsx +2 -1
  183. package/src/components/BottomNavItem/BottomNavItem.tsx +159 -88
  184. package/src/components/Button/Button.tsx +228 -101
  185. package/src/components/ButtonGroup/ButtonGroup.tsx +2 -2
  186. package/src/components/Card/Card.tsx +2 -1
  187. package/src/components/CardCTA/CardCTA.tsx +2 -2
  188. package/src/components/CardProviderInfo/CardProviderInfo.tsx +2 -2
  189. package/src/components/Carousel/Carousel.tsx +3 -2
  190. package/src/components/Checkbox/Checkbox.tsx +2 -1
  191. package/src/components/ChipGroup/ChipGroup.tsx +2 -2
  192. package/src/components/ChipSelect/ChipSelect.tsx +2 -1
  193. package/src/components/DebitCard/DebitCard.tsx +2 -2
  194. package/src/components/Disclaimer/Disclaimer.tsx +2 -1
  195. package/src/components/Divider/Divider.tsx +2 -1
  196. package/src/components/Drawer/Drawer.tsx +124 -58
  197. package/src/components/EmptyState/EmptyState.tsx +2 -1
  198. package/src/components/FilterBar/FilterBar.tsx +2 -2
  199. package/src/components/Form/Form.tsx +2 -1
  200. package/src/components/FormField/FormField.tsx +3 -2
  201. package/src/components/HStack/HStack.tsx +2 -2
  202. package/src/components/HoldingsCard/HoldingsCard.tsx +2 -1
  203. package/src/components/IconButton/IconButton.tsx +154 -126
  204. package/src/components/IconCapsule/IconCapsule.tsx +73 -54
  205. package/src/components/InputSearch/InputSearch.tsx +19 -5
  206. package/src/components/LazyList/LazyList.tsx +2 -2
  207. package/src/components/LinearMeter/LinearMeter.tsx +3 -2
  208. package/src/components/ListGroup/ListGroup.tsx +2 -2
  209. package/src/components/ListItem/ListItem.tsx +257 -187
  210. package/src/components/MediaCard/MediaCard.tsx +2 -1
  211. package/src/components/MerchantProfile/MerchantProfile.tsx +2 -1
  212. package/src/components/MoneyValue/MoneyValue.tsx +2 -1
  213. package/src/components/NavArrow/NavArrow.tsx +91 -58
  214. package/src/components/NoteInput/NoteInput.tsx +2 -1
  215. package/src/components/Nudge/Nudge.tsx +2 -2
  216. package/src/components/Numpad/Numpad.tsx +2 -1
  217. package/src/components/OTP/OTP.tsx +2 -2
  218. package/src/components/PaymentFeedback/PaymentFeedback.tsx +2 -1
  219. package/src/components/Popup/Popup.tsx +2 -1
  220. package/src/components/ProductLabel/ProductLabel.tsx +2 -1
  221. package/src/components/ProgressBadge/ProgressBadge.tsx +2 -2
  222. package/src/components/RadioButton/RadioButton.tsx +2 -1
  223. package/src/components/RechargeCard/RechargeCard.tsx +2 -1
  224. package/src/components/Screen/Screen.tsx +2 -2
  225. package/src/components/Section/Section.tsx +672 -176
  226. package/src/components/SegmentedControl/SegmentedControl.tsx +3 -2
  227. package/src/components/StatItem/StatItem.tsx +2 -1
  228. package/src/components/StatusHero/StatusHero.tsx +2 -1
  229. package/src/components/Stepper/Step.tsx +2 -1
  230. package/src/components/Stepper/StepLabel.tsx +2 -1
  231. package/src/components/Stepper/Stepper.tsx +2 -1
  232. package/src/components/SupportText/SupportText.tsx +2 -1
  233. package/src/components/SupportText/SupportTextIcon.tsx +2 -1
  234. package/src/components/SwappableAmount/SwappableAmount.tsx +2 -1
  235. package/src/components/Tabs/TabItem.tsx +2 -1
  236. package/src/components/Tabs/Tabs.tsx +2 -1
  237. package/src/components/Text/Text.tsx +2 -1
  238. package/src/components/TextInput/TextInput.tsx +3 -3
  239. package/src/components/ThreadHero/ThreadHero.tsx +2 -1
  240. package/src/components/Title/Title.tsx +2 -1
  241. package/src/components/Toast/Toast.tsx +2 -1
  242. package/src/components/Toggle/Toggle.tsx +2 -1
  243. package/src/components/Tooltip/Tooltip.tsx +2 -1
  244. package/src/components/TransactionBubble/TransactionBubble.tsx +2 -2
  245. package/src/components/TransactionDetails/TransactionDetails.tsx +3 -3
  246. package/src/components/TransactionStatus/TransactionStatus.tsx +3 -2
  247. package/src/components/UpiHandle/UpiHandle.tsx +193 -125
  248. package/src/components/VStack/VStack.tsx +2 -2
  249. package/src/design-tokens/figma-variables-resolver.ts +21 -3
  250. package/src/icons/registry.ts +1 -1
  251. package/src/utils/react-utils.ts +16 -0
  252. package/lib/typescript/App.d.ts +0 -2
  253. package/lib/typescript/index.d.ts +0 -2
  254. package/lib/typescript/metro.config.d.ts +0 -78
  255. package/lib/typescript/react-native.config.d.ts +0 -4
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useEffect, useState, useRef } from 'react'
2
- import { Platform, StyleSheet, Text, useWindowDimensions, View } from 'react-native'
2
+ import { Platform, StyleSheet, Text, useWindowDimensions, View, ViewStyle } from 'react-native'
3
3
  import {
4
4
  Gesture,
5
5
  GestureDetector,
@@ -15,6 +15,7 @@ import Animated, {
15
15
  withSpring,
16
16
  } from 'react-native-reanimated'
17
17
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
18
+ import { EMPTY_MODES } from '../../utils/react-utils'
18
19
 
19
20
 
20
21
  const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView)
@@ -86,7 +87,7 @@ type DrawerProps = {
86
87
  */
87
88
  function Drawer({
88
89
 
89
- modes = {},
90
+ modes = EMPTY_MODES,
90
91
  style,
91
92
  title,
92
93
  header,
@@ -166,10 +167,19 @@ function Drawer({
166
167
  setMode(newMode)
167
168
  }, [])
168
169
 
170
+ // Gesture policy:
171
+ // • activeOffsetY: require a clear *vertical* drag (10px) before this
172
+ // pan claims the gesture. Matches typical iOS scroll activation feel.
173
+ // • failOffsetX: if the finger crosses ~16px horizontally *before* we
174
+ // activate, surrender the gesture entirely so any horizontal child
175
+ // (FlatList horizontal, swiper, slider, etc.) can scroll cleanly
176
+ // without the drawer also translating on Y.
177
+ // • simultaneousWithExternalGesture(scrollRef): cooperate with the
178
+ // drawer's own internal vertical ScrollView for nested scrolling.
169
179
  const gesture = Gesture.Pan()
170
180
  .simultaneousWithExternalGesture(scrollRef)
171
- .activeOffsetY([-5, 5])
172
- .activeOffsetX([-5, 5])
181
+ .activeOffsetY([-10, 10])
182
+ .failOffsetX([-16, 16])
173
183
  .onStart(() => {
174
184
  context.value = { y: translateY.value }
175
185
  isDrawerActive.value = true
@@ -178,6 +188,16 @@ function Drawer({
178
188
  scrollTopTranslationOffset.value = 0
179
189
  })
180
190
  .onUpdate((event) => {
191
+ // Defense-in-depth: even after vertical activation, if the *current*
192
+ // motion is dominantly horizontal (e.g., the user activated with a
193
+ // small Y nudge and then curved into a horizontal swipe on a child
194
+ // carousel), don't translate the drawer this frame. failOffsetX
195
+ // already prevents activation in pure-horizontal swipes; this guards
196
+ // the diagonal-then-horizontal case.
197
+ if (Math.abs(event.translationX) > Math.abs(event.translationY) * 1.5) {
198
+ return
199
+ }
200
+
181
201
  // Logic for nested scrolling:
182
202
  // If we are at the expanded position (minTranslateY) AND content is
183
203
  // scrolled down (scrollY > 0), let the ScrollView handle the gesture.
@@ -298,6 +318,36 @@ function Drawer({
298
318
  const titleLineHeight = getVariableByName('drawer/title/lineHeight', modes) || 17
299
319
  const titlePaddingBottom = getVariableByName('drawer/titleWrap/padding/bottom', modes) || 8
300
320
 
321
+ // Drop shadow — Figma layers two shadows (primary + secondary) sharing
322
+ // the same offsetY/blur but with their own offsetX and color.
323
+ const shadowPrimaryOffsetX = (getVariableByName('drawer/shadow/primary/offsetX', modes) ?? 0) as number
324
+ const shadowPrimaryOffsetY = (getVariableByName('drawer/shadow/primary/offsetY', modes) ?? 16) as number
325
+ const shadowPrimaryBlur = (getVariableByName('drawer/shadow/primary/blur', modes) ?? 48) as number
326
+ const shadowPrimaryColor = (getVariableByName('drawer/shadow/primary/color', modes) ?? 'rgba(12, 13, 16, 0.16)') as string
327
+ const shadowSecondaryOffsetX = (getVariableByName('drawer/shadow/secondary/offsetX', modes) ?? 0) as number
328
+ const shadowSecondaryColor = (getVariableByName('drawer/shadow/secondary/color', modes) ?? 'rgba(12, 13, 16, 0.12)') as string
329
+
330
+ // Cross-platform shadow style. Web supports stacking two shadows via
331
+ // boxShadow. iOS only supports a single native shadow per view, so we
332
+ // apply the more prominent (primary) one. Android uses elevation.
333
+ const shadowStyle: ViewStyle = Platform.select({
334
+ web: {
335
+ boxShadow:
336
+ `${shadowSecondaryOffsetX}px ${shadowPrimaryOffsetY}px ${shadowPrimaryBlur}px 0px ${shadowSecondaryColor}, ` +
337
+ `${shadowPrimaryOffsetX}px ${shadowPrimaryOffsetY}px ${shadowPrimaryBlur}px 0px ${shadowPrimaryColor}`,
338
+ } as ViewStyle,
339
+ ios: {
340
+ shadowColor: shadowPrimaryColor,
341
+ shadowOffset: { width: shadowPrimaryOffsetX, height: shadowPrimaryOffsetY },
342
+ shadowOpacity: 1,
343
+ shadowRadius: shadowPrimaryBlur / 2,
344
+ },
345
+ android: {
346
+ elevation: 16,
347
+ },
348
+ default: {},
349
+ }) as ViewStyle
350
+
301
351
  const defaultAccessibilityLabel = accessibilityLabel || title || 'Drawer'
302
352
 
303
353
  return (
@@ -313,11 +363,8 @@ function Drawer({
313
363
  backgroundColor,
314
364
  borderTopLeftRadius: radius,
315
365
  borderTopRightRadius: radius,
316
- paddingLeft,
317
- paddingRight,
318
- paddingBottom,
319
- rowGap: drawerGap,
320
366
  },
367
+ shadowStyle,
321
368
  sheetStyle,
322
369
  animatedStyle,
323
370
  ]}
@@ -326,57 +373,73 @@ function Drawer({
326
373
  accessibilityLabel={undefined}
327
374
  accessibilityHint={accessibilityHint || 'Swipe up to expand, swipe down to collapse'}
328
375
  >
329
- {/* Handle Area */}
330
- <View style={[styles.handleArea, (!title && !header) && { paddingBottom: 0 }]}>
331
- <View
332
- style={[
333
- {
334
- backgroundColor: handleColor,
335
- width: handleWidth,
336
- height: handleHeight,
337
- borderRadius: handleRadius
338
- },
339
- ]}
340
- />
341
- </View>
342
-
343
- {/* Custom Header Slot */}
344
- {header}
345
-
346
- {/* Title (Legacy/Simple Mode) */}
347
- {title && (
348
- <Text
349
- style={[
350
- {
351
- color: titleColor,
352
- fontSize: titleSize,
353
- fontWeight: titleWeight as any,
354
- lineHeight: titleLineHeight,
355
- marginBottom: titlePaddingBottom,
356
- }
357
- ]}
358
- >
359
- {title}
360
- </Text>
361
- )}
362
-
363
- {/* Scrollable Content */}
364
- <AnimatedScrollView
365
- ref={scrollRef}
366
- style={[styles.content, contentStyle]}
367
- contentContainerStyle={[{ paddingBottom: paddingBottom + bottomInset, gap: drawerGap, flexDirection: 'column', alignItems: 'stretch' }, contentContainerStyle]}
368
- showsVerticalScrollIndicator={showsVerticalScrollIndicator}
369
- animatedProps={animatedScrollProps}
370
- alwaysBounceVertical={false}
371
- overScrollMode="always"
372
- onScroll={useAnimatedScrollHandler((event) => {
373
- scrollY.value = event.contentOffset.y
374
- })}
375
- scrollEventThrottle={16}
376
+ {/* Inner clip layer — keeps overflow:'hidden' off the shadow-carrying
377
+ outer view so iOS doesn't clip the drop shadow. */}
378
+ <View
379
+ style={[
380
+ styles.sheetInner,
381
+ {
382
+ borderTopLeftRadius: radius,
383
+ borderTopRightRadius: radius,
384
+ paddingLeft,
385
+ paddingRight,
386
+ paddingBottom,
387
+ rowGap: drawerGap,
388
+ },
389
+ ]}
376
390
  >
377
- {/* Prevent touch propagation for text selection if needed */}
378
- {children}
379
- </AnimatedScrollView>
391
+ {/* Handle Area */}
392
+ <View style={[styles.handleArea, (!title && !header) && { paddingBottom: 0 }]}>
393
+ <View
394
+ style={[
395
+ {
396
+ backgroundColor: handleColor,
397
+ width: handleWidth,
398
+ height: handleHeight,
399
+ borderRadius: handleRadius
400
+ },
401
+ ]}
402
+ />
403
+ </View>
404
+
405
+ {/* Custom Header Slot */}
406
+ {header}
407
+
408
+ {/* Title (Legacy/Simple Mode) */}
409
+ {title && (
410
+ <Text
411
+ style={[
412
+ {
413
+ color: titleColor,
414
+ fontSize: titleSize,
415
+ fontWeight: titleWeight as any,
416
+ lineHeight: titleLineHeight,
417
+ marginBottom: titlePaddingBottom,
418
+ }
419
+ ]}
420
+ >
421
+ {title}
422
+ </Text>
423
+ )}
424
+
425
+ {/* Scrollable Content */}
426
+ <AnimatedScrollView
427
+ ref={scrollRef}
428
+ style={[styles.content, contentStyle]}
429
+ contentContainerStyle={[{ paddingBottom: paddingBottom + bottomInset, gap: drawerGap, flexDirection: 'column', alignItems: 'stretch' }, contentContainerStyle]}
430
+ showsVerticalScrollIndicator={showsVerticalScrollIndicator}
431
+ animatedProps={animatedScrollProps}
432
+ alwaysBounceVertical={false}
433
+ overScrollMode="always"
434
+ onScroll={useAnimatedScrollHandler((event) => {
435
+ scrollY.value = event.contentOffset.y
436
+ })}
437
+ scrollEventThrottle={16}
438
+ >
439
+ {/* Prevent touch propagation for text selection if needed */}
440
+ {children}
441
+ </AnimatedScrollView>
442
+ </View>
380
443
  </Animated.View>
381
444
  </GestureDetector>
382
445
  </GestureHandlerRootView>
@@ -398,6 +461,9 @@ const styles = StyleSheet.create({
398
461
  width: '100%',
399
462
  position: 'absolute',
400
463
  top: 0,
464
+ },
465
+ sheetInner: {
466
+ flex: 1,
401
467
  overflow: 'hidden',
402
468
  },
403
469
  handleArea: {
@@ -4,6 +4,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
  import IconCapsule from '../IconCapsule/IconCapsule'
6
6
  import Button from '../Button/Button'
7
+ import { EMPTY_MODES } from '../../utils/react-utils'
7
8
 
8
9
  export type EmptyStateProps = {
9
10
  /**
@@ -50,7 +51,7 @@ function EmptyState({
50
51
  showDescription = true,
51
52
  iconSlot,
52
53
  buttonSlot,
53
- modes: propModes = {},
54
+ modes: propModes = EMPTY_MODES,
54
55
  style,
55
56
  testID,
56
57
  }: EmptyStateProps) {
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
2
2
  import { View, type StyleProp, type ViewStyle } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import TextInput from '../TextInput/TextInput'
5
- import { cloneChildrenWithModes } from '../../utils/react-utils'
5
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
6
6
 
7
7
  type RenderInputArgs = {
8
8
  placeholder: string;
@@ -61,7 +61,7 @@ function FilterBar({
61
61
  onChangeText,
62
62
  children,
63
63
  renderInput,
64
- modes = {},
64
+ modes = EMPTY_MODES,
65
65
  style,
66
66
  accessibilityLabel,
67
67
  accessibilityHint,
@@ -2,6 +2,7 @@ import React, { createContext, useContext, useState, useMemo, useCallback } from
2
2
  import { View, type StyleProp, type ViewStyle } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
+ import { EMPTY_MODES } from '../../utils/react-utils'
5
6
 
6
7
  type FormContextValue = {
7
8
  validationErrors: Record<string, string | string[]>;
@@ -28,7 +29,7 @@ function Form({
28
29
  children,
29
30
  validationErrors: externalErrors,
30
31
  onSubmit,
31
- modes: propModes = {},
32
+ modes: propModes = EMPTY_MODES,
32
33
  style,
33
34
  accessibilityLabel,
34
35
  testID,
@@ -1,6 +1,7 @@
1
1
  import React, { useState, useMemo, useCallback } from 'react'
2
2
  import { View, Text, type StyleProp, type ViewStyle, type TextStyle } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
+ import { EMPTY_MODES } from '../../utils/react-utils'
4
5
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
6
  import TextInput from '../TextInput/TextInput'
6
7
  import SupportText from '../SupportText/SupportText'
@@ -42,7 +43,7 @@ function useFormField(props: FormFieldProps) {
42
43
  isInvalid = false,
43
44
  supportText,
44
45
  errorMessage,
45
- modes: propModes = {},
46
+ modes: propModes = EMPTY_MODES,
46
47
  onFocus,
47
48
  onBlur,
48
49
  } = props
@@ -178,7 +179,7 @@ function FormField({
178
179
  isInvalid = false,
179
180
  supportText,
180
181
  errorMessage,
181
- modes = {},
182
+ modes = EMPTY_MODES,
182
183
  style,
183
184
  onFocus,
184
185
  onBlur,
@@ -2,7 +2,7 @@ import React from 'react'
2
2
  import { View, StyleProp, ViewStyle, ViewProps } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
- import { cloneChildrenWithModes } from '../../utils/react-utils'
5
+ import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils'
6
6
 
7
7
  export interface HStackProps extends ViewProps {
8
8
  /**
@@ -48,7 +48,7 @@ export const HStack = ({
48
48
  wrap,
49
49
  reverse = false,
50
50
  as,
51
- modes: propModes = {},
51
+ modes: propModes = EMPTY_MODES,
52
52
  style,
53
53
  ...rest
54
54
  }: HStackProps) => {
@@ -10,6 +10,7 @@ import {
10
10
  } from 'react-native'
11
11
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
12
12
  import RadioButton from '../RadioButton/RadioButton'
13
+ import { EMPTY_MODES } from '../../utils/react-utils'
13
14
 
14
15
  export interface HoldingsCardDetailItem {
15
16
  label: string
@@ -57,7 +58,7 @@ export default function HoldingsCard({
57
58
  selected = false,
58
59
  disabled = false,
59
60
  onPress,
60
- modes = {},
61
+ modes = EMPTY_MODES,
61
62
  style,
62
63
  testID,
63
64
  }: HoldingsCardProps) {