jfs-components 0.0.61 → 0.0.63

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 (259) hide show
  1. package/CHANGELOG.md +36 -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 +2 -1
  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 +2 -3
  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 +268 -156
  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/JFSThemeProvider.js +2 -38
  79. package/lib/commonjs/design-tokens/figma-variables-resolver.js +21 -3
  80. package/lib/commonjs/icons/registry.js +1 -1
  81. package/lib/commonjs/utils/react-utils.js +26 -3
  82. package/lib/module/components/Accordion/Accordion.js +2 -2
  83. package/lib/module/components/ActionFooter/ActionFooter.js +2 -2
  84. package/lib/module/components/ActionTile/ActionTile.js +2 -1
  85. package/lib/module/components/AmountInput/AmountInput.js +2 -1
  86. package/lib/module/components/AppBar/AppBar.js +2 -2
  87. package/lib/module/components/Avatar/Avatar.js +184 -162
  88. package/lib/module/components/AvatarGroup/AvatarGroup.js +2 -2
  89. package/lib/module/components/Badge/Badge.js +2 -1
  90. package/lib/module/components/Balance/Balance.js +2 -1
  91. package/lib/module/components/BottomNav/BottomNav.js +2 -1
  92. package/lib/module/components/BottomNavItem/BottomNavItem.js +108 -88
  93. package/lib/module/components/Button/Button.js +192 -95
  94. package/lib/module/components/ButtonGroup/ButtonGroup.js +2 -2
  95. package/lib/module/components/Card/Card.js +2 -1
  96. package/lib/module/components/CardCTA/CardCTA.js +2 -2
  97. package/lib/module/components/CardProviderInfo/CardProviderInfo.js +2 -2
  98. package/lib/module/components/Carousel/Carousel.js +3 -2
  99. package/lib/module/components/Checkbox/Checkbox.js +2 -1
  100. package/lib/module/components/ChipGroup/ChipGroup.js +2 -2
  101. package/lib/module/components/ChipSelect/ChipSelect.js +2 -1
  102. package/lib/module/components/DebitCard/DebitCard.js +2 -2
  103. package/lib/module/components/Disclaimer/Disclaimer.js +2 -1
  104. package/lib/module/components/Divider/Divider.js +2 -1
  105. package/lib/module/components/Drawer/Drawer.js +2 -1
  106. package/lib/module/components/EmptyState/EmptyState.js +2 -1
  107. package/lib/module/components/FilterBar/FilterBar.js +2 -2
  108. package/lib/module/components/Form/Form.js +2 -1
  109. package/lib/module/components/FormField/FormField.js +3 -2
  110. package/lib/module/components/HStack/HStack.js +2 -2
  111. package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -1
  112. package/lib/module/components/IconButton/IconButton.js +120 -130
  113. package/lib/module/components/IconCapsule/IconCapsule.js +60 -57
  114. package/lib/module/components/InputSearch/InputSearch.js +7 -3
  115. package/lib/module/components/LazyList/LazyList.js +2 -2
  116. package/lib/module/components/LinearMeter/LinearMeter.js +3 -2
  117. package/lib/module/components/ListGroup/ListGroup.js +3 -4
  118. package/lib/module/components/ListItem/ListItem.js +194 -146
  119. package/lib/module/components/MediaCard/MediaCard.js +4 -2
  120. package/lib/module/components/MerchantProfile/MerchantProfile.js +2 -1
  121. package/lib/module/components/MoneyValue/MoneyValue.js +2 -1
  122. package/lib/module/components/NavArrow/NavArrow.js +82 -58
  123. package/lib/module/components/NoteInput/NoteInput.js +2 -1
  124. package/lib/module/components/Nudge/Nudge.js +2 -2
  125. package/lib/module/components/Numpad/Numpad.js +2 -1
  126. package/lib/module/components/OTP/OTP.js +2 -2
  127. package/lib/module/components/PaymentFeedback/PaymentFeedback.js +2 -1
  128. package/lib/module/components/Popup/Popup.js +2 -1
  129. package/lib/module/components/ProductLabel/ProductLabel.js +2 -1
  130. package/lib/module/components/ProgressBadge/ProgressBadge.js +2 -1
  131. package/lib/module/components/RadioButton/RadioButton.js +2 -1
  132. package/lib/module/components/RechargeCard/RechargeCard.js +2 -1
  133. package/lib/module/components/Screen/Screen.js +2 -2
  134. package/lib/module/components/Section/Section.js +271 -159
  135. package/lib/module/components/SegmentedControl/SegmentedControl.js +3 -2
  136. package/lib/module/components/StatItem/StatItem.js +2 -1
  137. package/lib/module/components/StatusHero/StatusHero.js +2 -1
  138. package/lib/module/components/Stepper/Step.js +2 -1
  139. package/lib/module/components/Stepper/StepLabel.js +2 -1
  140. package/lib/module/components/Stepper/Stepper.js +2 -1
  141. package/lib/module/components/SupportText/SupportText.js +2 -1
  142. package/lib/module/components/SupportText/SupportTextIcon.js +2 -1
  143. package/lib/module/components/SwappableAmount/SwappableAmount.js +2 -1
  144. package/lib/module/components/Tabs/TabItem.js +2 -1
  145. package/lib/module/components/Tabs/Tabs.js +2 -1
  146. package/lib/module/components/Text/Text.js +2 -1
  147. package/lib/module/components/TextInput/TextInput.js +3 -3
  148. package/lib/module/components/ThreadHero/ThreadHero.js +2 -1
  149. package/lib/module/components/Title/Title.js +2 -1
  150. package/lib/module/components/Toast/Toast.js +2 -1
  151. package/lib/module/components/Toggle/Toggle.js +2 -1
  152. package/lib/module/components/Tooltip/Tooltip.js +2 -1
  153. package/lib/module/components/TransactionBubble/TransactionBubble.js +2 -2
  154. package/lib/module/components/TransactionDetails/TransactionDetails.js +3 -3
  155. package/lib/module/components/TransactionStatus/TransactionStatus.js +3 -2
  156. package/lib/module/components/UpiHandle/UpiHandle.js +147 -113
  157. package/lib/module/components/VStack/VStack.js +2 -2
  158. package/lib/module/design-tokens/JFSThemeProvider.js +2 -35
  159. package/lib/module/design-tokens/figma-variables-resolver.js +21 -3
  160. package/lib/module/icons/registry.js +1 -1
  161. package/lib/module/utils/react-utils.js +25 -3
  162. package/lib/typescript/src/components/Avatar/Avatar.d.ts +11 -17
  163. package/lib/typescript/src/components/BottomNavItem/BottomNavItem.d.ts +12 -8
  164. package/lib/typescript/src/components/Button/Button.d.ts +18 -1
  165. package/lib/typescript/src/components/IconButton/IconButton.d.ts +12 -29
  166. package/lib/typescript/src/components/IconCapsule/IconCapsule.d.ts +10 -18
  167. package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +8 -3
  168. package/lib/typescript/src/components/ListItem/ListItem.d.ts +14 -1
  169. package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +12 -11
  170. package/lib/typescript/src/components/Section/Section.d.ts +2 -48
  171. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +13 -12
  172. package/lib/typescript/src/design-tokens/JFSThemeProvider.d.ts +0 -15
  173. package/lib/typescript/src/icons/registry.d.ts +1 -1
  174. package/lib/typescript/src/utils/react-utils.d.ts +15 -0
  175. package/package.json +4 -6
  176. package/src/components/Accordion/Accordion.tsx +2 -2
  177. package/src/components/ActionFooter/ActionFooter.tsx +2 -2
  178. package/src/components/ActionTile/ActionTile.tsx +2 -1
  179. package/src/components/AmountInput/AmountInput.tsx +2 -1
  180. package/src/components/AppBar/AppBar.tsx +2 -2
  181. package/src/components/Avatar/Avatar.tsx +229 -158
  182. package/src/components/AvatarGroup/AvatarGroup.tsx +2 -2
  183. package/src/components/Badge/Badge.tsx +2 -1
  184. package/src/components/Balance/Balance.tsx +2 -1
  185. package/src/components/BottomNav/BottomNav.tsx +2 -1
  186. package/src/components/BottomNavItem/BottomNavItem.tsx +159 -88
  187. package/src/components/Button/Button.tsx +228 -101
  188. package/src/components/ButtonGroup/ButtonGroup.tsx +2 -2
  189. package/src/components/Card/Card.tsx +2 -1
  190. package/src/components/CardCTA/CardCTA.tsx +2 -2
  191. package/src/components/CardProviderInfo/CardProviderInfo.tsx +2 -2
  192. package/src/components/Carousel/Carousel.tsx +3 -2
  193. package/src/components/Checkbox/Checkbox.tsx +2 -1
  194. package/src/components/ChipGroup/ChipGroup.tsx +2 -2
  195. package/src/components/ChipSelect/ChipSelect.tsx +2 -1
  196. package/src/components/DebitCard/DebitCard.tsx +2 -2
  197. package/src/components/Disclaimer/Disclaimer.tsx +2 -1
  198. package/src/components/Divider/Divider.tsx +2 -1
  199. package/src/components/Drawer/Drawer.tsx +2 -1
  200. package/src/components/EmptyState/EmptyState.tsx +2 -1
  201. package/src/components/FilterBar/FilterBar.tsx +2 -2
  202. package/src/components/Form/Form.tsx +2 -1
  203. package/src/components/FormField/FormField.tsx +3 -2
  204. package/src/components/HStack/HStack.tsx +2 -2
  205. package/src/components/HoldingsCard/HoldingsCard.tsx +2 -1
  206. package/src/components/IconButton/IconButton.tsx +154 -126
  207. package/src/components/IconCapsule/IconCapsule.tsx +73 -54
  208. package/src/components/InputSearch/InputSearch.tsx +19 -5
  209. package/src/components/LazyList/LazyList.tsx +2 -2
  210. package/src/components/LinearMeter/LinearMeter.tsx +3 -2
  211. package/src/components/ListGroup/ListGroup.tsx +4 -5
  212. package/src/components/ListItem/ListItem.tsx +257 -187
  213. package/src/components/MediaCard/MediaCard.tsx +2 -1
  214. package/src/components/MerchantProfile/MerchantProfile.tsx +2 -1
  215. package/src/components/MoneyValue/MoneyValue.tsx +2 -1
  216. package/src/components/NavArrow/NavArrow.tsx +91 -58
  217. package/src/components/NoteInput/NoteInput.tsx +2 -1
  218. package/src/components/Nudge/Nudge.tsx +2 -2
  219. package/src/components/Numpad/Numpad.tsx +2 -1
  220. package/src/components/OTP/OTP.tsx +2 -2
  221. package/src/components/PaymentFeedback/PaymentFeedback.tsx +2 -1
  222. package/src/components/Popup/Popup.tsx +2 -1
  223. package/src/components/ProductLabel/ProductLabel.tsx +2 -1
  224. package/src/components/ProgressBadge/ProgressBadge.tsx +2 -2
  225. package/src/components/RadioButton/RadioButton.tsx +2 -1
  226. package/src/components/RechargeCard/RechargeCard.tsx +2 -1
  227. package/src/components/Screen/Screen.tsx +2 -2
  228. package/src/components/Section/Section.tsx +323 -167
  229. package/src/components/SegmentedControl/SegmentedControl.tsx +3 -2
  230. package/src/components/StatItem/StatItem.tsx +2 -1
  231. package/src/components/StatusHero/StatusHero.tsx +2 -1
  232. package/src/components/Stepper/Step.tsx +2 -1
  233. package/src/components/Stepper/StepLabel.tsx +2 -1
  234. package/src/components/Stepper/Stepper.tsx +2 -1
  235. package/src/components/SupportText/SupportText.tsx +2 -1
  236. package/src/components/SupportText/SupportTextIcon.tsx +2 -1
  237. package/src/components/SwappableAmount/SwappableAmount.tsx +2 -1
  238. package/src/components/Tabs/TabItem.tsx +2 -1
  239. package/src/components/Tabs/Tabs.tsx +2 -1
  240. package/src/components/Text/Text.tsx +2 -1
  241. package/src/components/TextInput/TextInput.tsx +3 -3
  242. package/src/components/ThreadHero/ThreadHero.tsx +2 -1
  243. package/src/components/Title/Title.tsx +2 -1
  244. package/src/components/Toast/Toast.tsx +2 -1
  245. package/src/components/Toggle/Toggle.tsx +2 -1
  246. package/src/components/Tooltip/Tooltip.tsx +2 -1
  247. package/src/components/TransactionBubble/TransactionBubble.tsx +2 -2
  248. package/src/components/TransactionDetails/TransactionDetails.tsx +3 -3
  249. package/src/components/TransactionStatus/TransactionStatus.tsx +3 -2
  250. package/src/components/UpiHandle/UpiHandle.tsx +193 -125
  251. package/src/components/VStack/VStack.tsx +2 -2
  252. package/src/design-tokens/JFSThemeProvider.tsx +1 -37
  253. package/src/design-tokens/figma-variables-resolver.ts +21 -3
  254. package/src/icons/registry.ts +1 -1
  255. package/src/utils/react-utils.ts +29 -3
  256. package/lib/typescript/App.d.ts +0 -2
  257. package/lib/typescript/index.d.ts +0 -2
  258. package/lib/typescript/metro.config.d.ts +0 -78
  259. package/lib/typescript/react-native.config.d.ts +0 -4
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import ProductLabel from '../ProductLabel/ProductLabel';
7
- import { cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  /**
10
10
  * CardProviderInfo displays a product header (ProductLabel) followed by a
@@ -17,7 +17,7 @@ function CardProviderInfo({
17
17
  label = 'Gold',
18
18
  imageSource,
19
19
  children,
20
- modes = {},
20
+ modes = EMPTY_MODES,
21
21
  style
22
22
  }) {
23
23
  const background = getVariableByName('card/providerInfo/background', modes) ?? '#fef4e5';
@@ -3,13 +3,14 @@
3
3
  import React, { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo } from 'react';
4
4
  import { View, ScrollView, Animated, Pressable } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES } from '../../utils/react-utils';
6
7
 
7
8
  // ---------------------------------------------------------------------------
8
9
  // Context
9
10
  // ---------------------------------------------------------------------------
10
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
12
  const CarouselContext = /*#__PURE__*/createContext({
12
- modes: {},
13
+ modes: EMPTY_MODES,
13
14
  activeIndex: 0,
14
15
  totalItems: 0,
15
16
  goTo: () => {},
@@ -27,7 +28,7 @@ const CarouselContext = /*#__PURE__*/createContext({
27
28
 
28
29
  export function Carousel({
29
30
  children,
30
- modes = {},
31
+ modes = EMPTY_MODES,
31
32
  autoPlay = false,
32
33
  autoPlayInterval = 4000,
33
34
  showPagination = true,
@@ -4,6 +4,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
4
4
  import { Pressable, Platform } from 'react-native';
5
5
  import Svg, { Path } from 'react-native-svg';
6
6
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
 
8
9
  /**
9
10
  * Tracks whether the last user interaction was a keyboard event (Tab).
@@ -60,7 +61,7 @@ function Checkbox({
60
61
  defaultChecked = false,
61
62
  onValueChange,
62
63
  disabled = false,
63
- modes = {},
64
+ modes = EMPTY_MODES,
64
65
  style,
65
66
  accessibilityLabel
66
67
  }) {
@@ -3,7 +3,7 @@
3
3
  import React from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { flattenChildren } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, flattenChildren } from '../../utils/react-utils';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
8
  /**
9
9
  * ChipGroup component that handles layout and spacing for ChipSelect components.
@@ -11,7 +11,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
11
  */
12
12
  function ChipGroup({
13
13
  children,
14
- modes = {},
14
+ modes = EMPTY_MODES,
15
15
  style,
16
16
  testID
17
17
  }) {
@@ -3,6 +3,7 @@
3
3
  import React from 'react';
4
4
  import { Text, TouchableOpacity } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES } from '../../utils/react-utils';
6
7
  import Icon from '../../icons/Icon';
7
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  /**
@@ -13,7 +14,7 @@ function ChipSelect({
13
14
  label = 'Date',
14
15
  active = false,
15
16
  icon = 'ic_calendar_week',
16
- modes = {},
17
+ modes = EMPTY_MODES,
17
18
  style,
18
19
  labelSlot,
19
20
  onPress
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { View, Text, Image } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
- import { cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils';
8
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  const defaultCardArt = require('./cf64a67d5075caa8924d20b4e4e650d47b3ee08b.png');
10
10
  function DebitCard({
@@ -16,7 +16,7 @@ function DebitCard({
16
16
  cardArtSource = defaultCardArt,
17
17
  bankLogoSlot,
18
18
  providerLogoSlot,
19
- modes: propModes = {},
19
+ modes: propModes = EMPTY_MODES,
20
20
  style
21
21
  }) {
22
22
  const {
@@ -4,6 +4,7 @@ import React from 'react';
4
4
  import { View, Text } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
8
9
  /**
9
10
  * Disclaimer text block that mirrors the Figma "Disclaimer" component.
@@ -28,7 +29,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
28
29
  */
29
30
  function Disclaimer({
30
31
  disclaimer = 'All financial services are provided by Jio Payments Bank Pvt. Ltd.',
31
- modes: propModes = {},
32
+ modes: propModes = EMPTY_MODES,
32
33
  style,
33
34
  textStyle,
34
35
  accessibilityLabel,
@@ -3,6 +3,7 @@
3
3
  import React from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES } from '../../utils/react-utils';
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
7
8
  /**
8
9
  * Divider component that renders a horizontal or vertical separator line.
@@ -31,7 +32,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
31
32
  */
32
33
  function Divider({
33
34
  direction = 'horizontal',
34
- modes = {},
35
+ modes = EMPTY_MODES,
35
36
  style,
36
37
  accessibilityLabel = undefined
37
38
  }) {
@@ -5,6 +5,7 @@ import { Platform, StyleSheet, Text, useWindowDimensions, View } from 'react-nat
5
5
  import { Gesture, GestureDetector, GestureHandlerRootView, ScrollView } from 'react-native-gesture-handler';
6
6
  import Animated, { runOnJS, useAnimatedProps, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
7
7
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
8
+ import { EMPTY_MODES } from '../../utils/react-utils';
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
10
  const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);
10
11
 
@@ -44,7 +45,7 @@ function rubberBand(value, min, max, friction = 0.55) {
44
45
  * Uses react-native-gesture-handler and react-native-reanimated.
45
46
  */
46
47
  function Drawer({
47
- modes = {},
48
+ modes = EMPTY_MODES,
48
49
  style,
49
50
  title,
50
51
  header,
@@ -6,6 +6,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
7
  import IconCapsule from '../IconCapsule/IconCapsule';
8
8
  import Button from '../Button/Button';
9
+ import { EMPTY_MODES } from '../../utils/react-utils';
9
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  /**
11
12
  * EmptyState component that displays an icon, title, description and an action button.
@@ -18,7 +19,7 @@ function EmptyState({
18
19
  showDescription = true,
19
20
  iconSlot,
20
21
  buttonSlot,
21
- modes: propModes = {},
22
+ modes: propModes = EMPTY_MODES,
22
23
  style,
23
24
  testID
24
25
  }) {
@@ -4,7 +4,7 @@ import React, { useState } from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import TextInput from '../TextInput/TextInput';
7
- import { cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
9
  /**
10
10
  * FilterBar component that mirrors the Figma "filterBar" component.
@@ -31,7 +31,7 @@ function FilterBar({
31
31
  onChangeText,
32
32
  children,
33
33
  renderInput,
34
- modes = {},
34
+ modes = EMPTY_MODES,
35
35
  style,
36
36
  accessibilityLabel,
37
37
  accessibilityHint,
@@ -4,6 +4,7 @@ import React, { createContext, useContext, useState, useMemo, useCallback } from
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsx as _jsx } from "react/jsx-runtime";
8
9
  const FormContext = /*#__PURE__*/createContext(null);
9
10
  export function useFormContext() {
@@ -13,7 +14,7 @@ function Form({
13
14
  children,
14
15
  validationErrors: externalErrors,
15
16
  onSubmit,
16
- modes: propModes = {},
17
+ modes: propModes = EMPTY_MODES,
17
18
  style,
18
19
  accessibilityLabel,
19
20
  testID
@@ -3,6 +3,7 @@
3
3
  import React, { useState, useMemo, useCallback } from 'react';
4
4
  import { View, Text } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES } from '../../utils/react-utils';
6
7
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
8
  import TextInput from '../TextInput/TextInput';
8
9
  import SupportText from '../SupportText/SupportText';
@@ -14,7 +15,7 @@ function useFormField(props) {
14
15
  isInvalid = false,
15
16
  supportText,
16
17
  errorMessage,
17
- modes: propModes = {},
18
+ modes: propModes = EMPTY_MODES,
18
19
  onFocus,
19
20
  onBlur
20
21
  } = props;
@@ -140,7 +141,7 @@ function FormField({
140
141
  isInvalid = false,
141
142
  supportText,
142
143
  errorMessage,
143
- modes = {},
144
+ modes = EMPTY_MODES,
144
145
  style,
145
146
  onFocus,
146
147
  onBlur,
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
- import { cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
9
  /**
10
10
  * HStack component for horizontal layout using design token spacing.
@@ -16,7 +16,7 @@ export const HStack = ({
16
16
  wrap,
17
17
  reverse = false,
18
18
  as,
19
- modes: propModes = {},
19
+ modes: propModes = EMPTY_MODES,
20
20
  style,
21
21
  ...rest
22
22
  }) => {
@@ -4,6 +4,7 @@ import React from 'react';
4
4
  import { View, Text, Pressable, Image } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import RadioButton from '../RadioButton/RadioButton';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  const GRID_COLUMNS = 3;
9
10
  const GRID_COLUMN_GAP = 12;
@@ -31,7 +32,7 @@ export default function HoldingsCard({
31
32
  selected = false,
32
33
  disabled = false,
33
34
  onPress,
34
- modes = {},
35
+ modes = EMPTY_MODES,
35
36
  style,
36
37
  testID
37
38
  }) {
@@ -1,46 +1,80 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState } from 'react';
4
- import { Pressable } from 'react-native';
3
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
4
+ import { Platform, Pressable } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import Icon from '../../icons/Icon';
7
7
  import { usePressableWebSupport } from '../../utils/web-platform-utils';
8
+ import { EMPTY_MODES } from '../../utils/react-utils';
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
+ // ---------------------------------------------------------------------------
11
+ // Module-scope constants
12
+ // ---------------------------------------------------------------------------
13
+
14
+ const IS_WEB = Platform.OS === 'web';
15
+ const IS_IOS = Platform.OS === 'ios';
16
+ const PRESS_DELAY = IS_IOS ? 130 : 0;
17
+
18
+ // Pressed visual is applied through Pressable's style callback so the host
19
+ // view updates without scheduling a React render. Hover/focus stay mirrored
20
+ // in React state because they're sustained visual states (web only).
21
+ const pressedOverlayStyle = {
22
+ opacity: 0.7
23
+ };
24
+ const hoverOverlayStyle = {
25
+ opacity: 0.85
26
+ };
27
+ const focusOverlayStyle = {
28
+ borderWidth: 1,
29
+ borderColor: '#222'
30
+ };
31
+ function resolveIconButtonTokens(modes, disabled) {
32
+ const radiusRaw = getVariableByName('iconButton/radius', modes) ?? 9999;
33
+ const padding = getVariableByName('iconButton/padding', modes) ?? 12;
34
+ const backgroundColor = getVariableByName('iconButton/background', modes) ?? '#cfa159';
35
+ const borderColor = getVariableByName('iconButton/border/color', modes) ?? '#ffffff00';
36
+ const borderSize = getVariableByName('iconButton/border/size', modes) ?? 1;
37
+ const iconColor = getVariableByName('iconButton/icon/color', modes) ?? '#0f0d0a';
38
+ const iconSize = getVariableByName('iconButton/icon/size', modes) ?? 18;
39
+
40
+ // 9999 is the design-token sentinel for "perfect circle"
41
+ const buttonSize = padding * 2 + iconSize;
42
+ const borderRadius = radiusRaw === 9999 ? buttonSize / 2 : radiusRaw;
43
+ return {
44
+ baseContainerStyle: {
45
+ width: buttonSize,
46
+ height: buttonSize,
47
+ borderRadius,
48
+ borderWidth: borderSize,
49
+ borderColor,
50
+ backgroundColor,
51
+ overflow: 'hidden',
52
+ alignItems: 'center',
53
+ justifyContent: 'center',
54
+ padding,
55
+ opacity: disabled ? 0.5 : 1
56
+ },
57
+ iconColor,
58
+ iconSize
59
+ };
60
+ }
61
+
9
62
  /**
10
63
  * IconButton component that displays an icon within a pressable button container.
11
- *
12
- * This component displays an icon within a styled button container that can be pressed.
13
- * All styling values are resolved from Figma design tokens using the provided modes.
14
- *
15
- * @component
16
- * @param {Object} props - Component props
17
- * @param {string} [props.iconName="ic_card"] - The name of the icon to display from the icon registry
18
- * @param {Object} [props.modes={}] - Mode configuration for design tokens (e.g., {"Button / Size": "M", "Appearance": "high"})
19
- * @param {Function} [props.onPress] - Callback function called when the button is pressed
20
- * @param {boolean} [props.disabled=false] - Whether the button is disabled
21
- * @param {Object} [props.style] - Additional styles for the container
22
- * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, defaults to iconName
23
- * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
24
- * @param {Object} [props.accessibilityState] - Additional accessibility state information
25
- *
26
- * @example
27
- * ```jsx
28
- * // Default icon button
29
- * <IconButton modes={{}} />
30
- *
31
- * // Custom icon with size mode
32
- * <IconButton iconName="ic_rupee" modes={{"Button / Size": "M"}} />
33
- *
34
- * // With appearance mode
35
- * <IconButton modes={{"Appearance": "high"}} onPress={() => console.log('pressed')} />
36
- *
37
- * // With accessibility label
38
- * <IconButton iconName="ic_search" accessibilityLabel={undefined} accessibilityHint="Opens the search screen" />
39
- * ```
64
+ *
65
+ * Performance notes:
66
+ * - Token reads collapsed into a single `useMemo([modes, disabled, isToggle, isActive])`.
67
+ * - Press visual goes through Pressable's `({ pressed })` style callback so
68
+ * a scroll-cancelled touch never schedules a React render. iOS gets
69
+ * `unstable_pressDelay={130}`.
70
+ * - Hover and focus state are mirrored on web only (gated setters).
71
+ * - The previous version had a redundant `manualPressStyle` (a duplicate
72
+ * pressed transform mirrored via React state) removed.
73
+ * - Wrapped in `React.memo`.
40
74
  */
41
75
  function IconButton({
42
- iconName = "ic_card",
43
- modes = {},
76
+ iconName = 'ic_card',
77
+ modes = EMPTY_MODES,
44
78
  onPress,
45
79
  disabled = false,
46
80
  style,
@@ -54,63 +88,30 @@ function IconButton({
54
88
  isActive = false,
55
89
  ...rest
56
90
  }) {
91
+ // Merge explicit props with modes for token resolution. Memoize the merged
92
+ // object so its identity is stable when none of the inputs change — that
93
+ // keeps the resolver's WeakMap cache hot.
94
+ const componentModes = useMemo(() => ({
95
+ ...modes,
96
+ isToggle,
97
+ isActive
98
+ }), [modes, isToggle, isActive]);
99
+ const tokens = useMemo(() => resolveIconButtonTokens(componentModes, disabled), [componentModes, disabled]);
57
100
  const [isFocused, setIsFocused] = useState(false);
58
101
  const [isHovered, setIsHovered] = useState(false);
59
- const [isPressed, setIsPressed] = useState(false);
60
-
61
- // Merge explicit props with modes for token resolution
62
- // This allows the variable resolver to pick up isToggle and isActive specific tokens
63
- const componentModes = {
64
- ...modes,
65
- 'isToggle': isToggle,
66
- 'isActive': isActive
67
- };
68
-
69
- // Resolve design tokens using only the Figma-defined base tokens for Icon Button (node 72:14)
70
- const radius = getVariableByName('iconButton/radius', componentModes) ?? 9999;
71
- const padding = getVariableByName('iconButton/padding', componentModes) ?? 12;
72
- const backgroundColor = getVariableByName('iconButton/background', componentModes) ?? '#cfa159';
73
- const borderColor = getVariableByName('iconButton/border/color', componentModes) ?? '#ffffff00';
74
- const borderSize = getVariableByName('iconButton/border/size', componentModes) ?? 1;
75
- const iconColor = getVariableByName('iconButton/icon/color', componentModes) ?? '#0f0d0a';
76
- const iconSize = getVariableByName('iconButton/icon/size', componentModes) ?? 18;
102
+ const userHandlersRef = useRef({});
103
+ userHandlersRef.current.onPressIn = rest?.onPressIn;
104
+ userHandlersRef.current.onPressOut = rest?.onPressOut;
105
+ userHandlersRef.current.onFocus = rest?.onFocus;
106
+ userHandlersRef.current.onBlur = rest?.onBlur;
107
+ userHandlersRef.current.onHoverIn = rest?.onHoverIn;
108
+ userHandlersRef.current.onHoverOut = rest?.onHoverOut;
77
109
 
78
110
  // Determine which icon to display
79
- // If isToggle is yes, use active/inactive icons based on isActive state
80
- // Otherwise use standard iconName
81
- let finalIconName = iconName;
82
- if (isToggle) {
83
- if (isActive && activeIcon) {
84
- finalIconName = activeIcon;
85
- } else if (!isActive && inactiveIcon) {
86
- finalIconName = inactiveIcon;
87
- }
88
- }
89
-
90
- // Convert radius to React Native format (if 9999, use padding*2 for perfect circle)
91
- // For a button, the size is determined by padding, so radius should be padding*2 for a circle
92
- const buttonSize = padding * 2 + iconSize;
93
- const borderRadius = radius === 9999 ? buttonSize / 2 : radius;
94
-
95
- // Container base style
96
- const baseContainerStyle = {
97
- width: buttonSize,
98
- height: buttonSize,
99
- borderRadius: borderRadius,
100
- borderWidth: borderSize,
101
- borderColor: borderColor,
102
- backgroundColor: backgroundColor,
103
- overflow: 'hidden',
104
- alignItems: 'center',
105
- justifyContent: 'center',
106
- padding: padding,
107
- opacity: disabled ? 0.5 : 1
108
- };
111
+ const finalIconName = isToggle ? isActive && activeIcon ? activeIcon : !isActive && inactiveIcon ? inactiveIcon : iconName : iconName;
109
112
 
110
113
  // Generate default accessibility label from icon name if not provided
111
114
  const defaultAccessibilityLabel = accessibilityLabel || iconName.replace(/^ic_/, '').replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
112
-
113
- // Get web platform support props
114
115
  const webProps = usePressableWebSupport({
115
116
  restProps: rest,
116
117
  onPress: disabled ? undefined : onPress,
@@ -118,6 +119,31 @@ function IconButton({
118
119
  accessibilityLabel: defaultAccessibilityLabel,
119
120
  webAccessibilityProps
120
121
  });
122
+ const handlePressIn = useCallback(e => {
123
+ userHandlersRef.current.onPressIn?.(e);
124
+ }, []);
125
+ const handlePressOut = useCallback(e => {
126
+ userHandlersRef.current.onPressOut?.(e);
127
+ }, []);
128
+ const handleFocus = useCallback(e => {
129
+ if (IS_WEB) setIsFocused(true);
130
+ userHandlersRef.current.onFocus?.(e);
131
+ }, []);
132
+ const handleBlur = useCallback(e => {
133
+ if (IS_WEB) setIsFocused(false);
134
+ userHandlersRef.current.onBlur?.(e);
135
+ }, []);
136
+ const handleHoverIn = useCallback(e => {
137
+ if (IS_WEB) setIsHovered(true);
138
+ userHandlersRef.current.onHoverIn?.(e);
139
+ }, []);
140
+ const handleHoverOut = useCallback(e => {
141
+ if (IS_WEB) setIsHovered(false);
142
+ userHandlersRef.current.onHoverOut?.(e);
143
+ }, []);
144
+ const styleCallback = useCallback(({
145
+ pressed
146
+ }) => [tokens.baseContainerStyle, style, pressed && !disabled ? pressedOverlayStyle : null, isHovered && !disabled ? hoverOverlayStyle : null, isFocused && !disabled ? focusOverlayStyle : null], [tokens.baseContainerStyle, style, isHovered, isFocused, disabled]);
121
147
  return /*#__PURE__*/_jsx(Pressable, {
122
148
  accessibilityRole: "button",
123
149
  accessibilityLabel: undefined,
@@ -128,58 +154,22 @@ function IconButton({
128
154
  },
129
155
  onPress: onPress,
130
156
  disabled: disabled,
131
- onPressIn: e => {
132
- setIsPressed(true);
133
- rest?.onPressIn?.(e);
134
- },
135
- onPressOut: e => {
136
- setIsPressed(false);
137
- rest?.onPressOut?.(e);
138
- },
139
- onFocus: e => {
140
- setIsFocused(true);
141
- rest?.onFocus?.(e);
142
- },
143
- onBlur: e => {
144
- setIsFocused(false);
145
- rest?.onBlur?.(e);
146
- },
147
- onHoverIn: e => {
148
- setIsHovered(true);
149
- rest?.onHoverIn?.(e);
150
- },
151
- onHoverOut: e => {
152
- setIsHovered(false);
153
- rest?.onHoverOut?.(e);
154
- },
155
- style: ({
156
- pressed
157
- }) => {
158
- const pressedStyle = pressed && !disabled ? {
159
- opacity: 0.7
160
- } : null;
161
- const hoverStyle = isHovered && !disabled ? {
162
- opacity: 0.85
163
- } : null;
164
- const focusStyle = isFocused && !disabled ? {
165
- borderWidth: 1,
166
- borderColor: '#222'
167
- } : null;
168
- const manualPressStyle = isPressed && !disabled ? {
169
- transform: [{
170
- scale: 0.98
171
- }]
172
- } : null;
173
- return [baseContainerStyle, style, pressedStyle, hoverStyle, focusStyle, manualPressStyle];
174
- },
157
+ onPressIn: handlePressIn,
158
+ onPressOut: handlePressOut,
159
+ onFocus: handleFocus,
160
+ onBlur: handleBlur,
161
+ onHoverIn: handleHoverIn,
162
+ onHoverOut: handleHoverOut,
163
+ unstable_pressDelay: PRESS_DELAY,
164
+ style: styleCallback,
175
165
  ...webProps,
176
166
  children: /*#__PURE__*/_jsx(Icon, {
177
167
  name: finalIconName,
178
- size: iconSize,
179
- color: iconColor,
168
+ size: tokens.iconSize,
169
+ color: tokens.iconColor,
180
170
  accessibilityElementsHidden: true,
181
171
  importantForAccessibility: "no"
182
172
  })
183
173
  });
184
174
  }
185
- export default IconButton;
175
+ export default /*#__PURE__*/React.memo(IconButton);