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
@@ -5,6 +5,7 @@ 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
7
  import SupportTextIcon from './SupportTextIcon';
8
+ import { EMPTY_MODES } from '../../utils/react-utils';
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
10
  /**
10
11
  * SupportText component displaying a status icon and label.
@@ -14,7 +15,7 @@ function SupportText({
14
15
  status = 'Neutral',
15
16
  iconSlot,
16
17
  textSlot,
17
- modes: propModes = {},
18
+ modes: propModes = EMPTY_MODES,
18
19
  style
19
20
  }) {
20
21
  const {
@@ -4,6 +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 Icon from '../../icons/Icon';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsx as _jsx } from "react/jsx-runtime";
8
9
  const STATUS_ICON_MAP = {
9
10
  Neutral: 'ic_info',
@@ -14,7 +15,7 @@ const STATUS_ICON_MAP = {
14
15
  };
15
16
  function SupportTextIcon({
16
17
  status = 'Neutral',
17
- modes = {},
18
+ modes = EMPTY_MODES,
18
19
  style
19
20
  }) {
20
21
  const iconName = STATUS_ICON_MAP[status] || 'ic_info';
@@ -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 Button from '../Button/Button';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  function SwappableAmount({
9
10
  value = '49g',
@@ -12,7 +13,7 @@ function SwappableAmount({
12
13
  amountLabel = '₹5100',
13
14
  onSchedulePress,
14
15
  onAmountPress,
15
- modes = {},
16
+ modes = EMPTY_MODES,
16
17
  style
17
18
  }) {
18
19
  const gap = getVariableByName('swappableAmount/gap', modes) ?? 24;
@@ -3,6 +3,7 @@
3
3
  import React from 'react';
4
4
  import { Pressable, Text, 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, jsxs as _jsxs } from "react/jsx-runtime";
7
8
  /**
8
9
  * Individual tab item used inside the Tabs container.
@@ -17,7 +18,7 @@ function TabItem({
17
18
  label = 'Tab item',
18
19
  active = false,
19
20
  onPress,
20
- modes = {},
21
+ modes = EMPTY_MODES,
21
22
  style,
22
23
  labelStyle,
23
24
  accessibilityLabel
@@ -4,6 +4,7 @@ import React from 'react';
4
4
  import { ScrollView, View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import TabItem from './TabItem';
7
+ import { EMPTY_MODES } from '../../utils/react-utils';
7
8
  import { jsx as _jsx } from "react/jsx-runtime";
8
9
  /**
9
10
  * Tabs container component that lays out TabItem children horizontally.
@@ -28,7 +29,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
28
29
  */
29
30
  function Tabs({
30
31
  children,
31
- modes = {},
32
+ modes = EMPTY_MODES,
32
33
  scrollable = false,
33
34
  style
34
35
  }) {
@@ -3,6 +3,7 @@
3
3
  import React from 'react';
4
4
  import { Text as RNText } 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
  const TEXT_ALIGN_MAP = {
8
9
  Left: 'left',
@@ -11,7 +12,7 @@ const TEXT_ALIGN_MAP = {
11
12
  function Text({
12
13
  text = 'Korem ipsum ',
13
14
  textAlign = 'Left',
14
- modes = {},
15
+ modes = EMPTY_MODES,
15
16
  style,
16
17
  numberOfLines
17
18
  }) {
@@ -4,7 +4,7 @@ import React, { useState } from 'react';
4
4
  import { Pressable, View, TextInput as RNTextInput } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import Icon from '../../icons/Icon';
7
- import { cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
8
 
9
9
  /**
10
10
  * TextInput component that mirrors the Figma "textInput" component.
@@ -102,7 +102,7 @@ function TextInput({
102
102
  leadingIconName = 'ic_search',
103
103
  leading,
104
104
  trailing,
105
- modes = {},
105
+ modes = EMPTY_MODES,
106
106
  style,
107
107
  inputStyle,
108
108
  onFocus,
@@ -256,7 +256,7 @@ function TextInputSearch({
256
256
  value = '',
257
257
  onChangeText,
258
258
  leading,
259
- modes = {},
259
+ modes = EMPTY_MODES,
260
260
  style,
261
261
  inputStyle,
262
262
  accessibilityLabel,
@@ -3,6 +3,7 @@
3
3
  import React, { isValidElement, cloneElement } 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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
8
  /**
8
9
  * ThreadHero component displaying a central identity with avatar, title, subtitle, and caption.
@@ -12,7 +13,7 @@ export default function ThreadHero({
12
13
  subtitle = 'Banking name: SHIVASHANKAR RAJAN',
13
14
  caption,
14
15
  renderAvatar,
15
- modes = {},
16
+ modes = EMPTY_MODES,
16
17
  style
17
18
  }) {
18
19
  // Container Gaps
@@ -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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  const TEXT_ALIGN_MAP = {
9
10
  Left: 'left',
@@ -13,7 +14,7 @@ function Title({
13
14
  title = 'Title',
14
15
  subtitle,
15
16
  textAlign = 'Left',
16
- modes: propModes = {},
17
+ modes: propModes = EMPTY_MODES,
17
18
  style,
18
19
  textStyle,
19
20
  subtitleStyle,
@@ -5,6 +5,7 @@ import { StyleSheet, Text } from 'react-native';
5
5
  import Animated, { FadeOut, SlideInDown, SlideInUp } from 'react-native-reanimated';
6
6
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
7
7
  import { closeToast } from './useToast';
8
+ import { EMPTY_MODES } from '../../utils/react-utils';
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
9
10
  const ANIMATION_DURATION = 250;
10
11
  function Toast({
@@ -12,7 +13,7 @@ function Toast({
12
13
  title,
13
14
  timeout = 4000,
14
15
  onClose,
15
- modes = {},
16
+ modes = EMPTY_MODES,
16
17
  placement = 'bottom',
17
18
  style
18
19
  }) {
@@ -3,6 +3,7 @@
3
3
  import React, { useCallback, useState } from 'react';
4
4
  import { Pressable, View, Platform } 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
  * Toggle (switch) component that maps directly to the Figma design using design tokens.
@@ -18,7 +19,7 @@ function Toggle({
18
19
  defaultValue = false,
19
20
  onValueChange,
20
21
  disabled = false,
21
- modes = {},
22
+ modes = EMPTY_MODES,
22
23
  style,
23
24
  accessibilityLabel
24
25
  }) {
@@ -5,6 +5,7 @@ import { View, Text, Modal, Pressable, Platform, StyleSheet, Dimensions } from '
5
5
  import Svg, { Path } from 'react-native-svg';
6
6
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
7
7
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
8
+ import { EMPTY_MODES } from '../../utils/react-utils';
8
9
 
9
10
  // --- Types ---
10
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -23,7 +24,7 @@ function useTooltipContext() {
23
24
 
24
25
  export function Tooltip({
25
26
  children,
26
- modes = {},
27
+ modes = EMPTY_MODES,
27
28
  open,
28
29
  onOpenChange,
29
30
  defaultOpen = false,
@@ -6,7 +6,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
6
6
  import MoneyValue from '../MoneyValue/MoneyValue';
7
7
  import TransactionStatus from '../TransactionStatus/TransactionStatus';
8
8
  import NavArrow from '../NavArrow/NavArrow';
9
- import { cloneChildrenWithModes } from '../../utils/react-utils';
9
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
10
10
  import { usePressableWebSupport } from '../../utils/web-platform-utils';
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
12
  /**
@@ -34,7 +34,7 @@ function TransactionBubble({
34
34
  date = '20 Mar 2025',
35
35
  statusSlot,
36
36
  children,
37
- modes = {},
37
+ modes = EMPTY_MODES,
38
38
  onPress,
39
39
  style,
40
40
  accessibilityLabel,
@@ -3,7 +3,7 @@
3
3
  import React from 'react';
4
4
  import { View, Text } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { cloneChildrenWithModes } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
7
7
 
8
8
  // ===== Item Subcomponent =====
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -24,7 +24,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
24
  function Item({
25
25
  label = 'Label',
26
26
  value = 'Value',
27
- modes = {},
27
+ modes = EMPTY_MODES,
28
28
  style,
29
29
  labelStyle,
30
30
  valueStyle,
@@ -116,7 +116,7 @@ function Item({
116
116
  */
117
117
  function TransactionDetails({
118
118
  children,
119
- modes = {},
119
+ modes = EMPTY_MODES,
120
120
  style,
121
121
  accessibilityLabel,
122
122
  ...rest
@@ -4,11 +4,12 @@ import React from 'react';
4
4
  import { View, Text } 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
  // --- Internal Icon Component ---
9
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  const StatusIcon = ({
11
- modes = {},
12
+ modes = EMPTY_MODES,
12
13
  width = 15,
13
14
  height = 15,
14
15
  color
@@ -35,7 +36,7 @@ const StatusIcon = ({
35
36
  export default function TransactionStatus({
36
37
  status = 'Expired',
37
38
  date = '20 Mar 2025',
38
- modes = {},
39
+ modes = EMPTY_MODES,
39
40
  style
40
41
  }) {
41
42
  const gap = Number(getVariableByName('transactionBubble/statusWrap/gap', modes)) || 4;
@@ -1,158 +1,163 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState } from 'react';
4
- import { Pressable, View, Text, Image } from 'react-native';
3
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
4
+ import { Pressable, View, Text, Image, Platform } 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 Icon from '../../icons/Icon';
8
9
 
9
10
  // Default static asset from the component folder.
10
11
  // Consumers can override the image via the `avatarSource` prop if needed.
11
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
12
13
  const DEFAULT_AVATAR_IMAGE = require('./Image.png');
14
+ const IS_WEB = Platform.OS === 'web';
15
+ const IS_IOS = Platform.OS === 'ios';
16
+ const PRESS_DELAY = IS_IOS ? 130 : 0;
17
+ const pressedOverlayStyle = {
18
+ transform: [{
19
+ scale: 0.98
20
+ }]
21
+ };
22
+ const focusOverlayStyle = {
23
+ borderWidth: 1,
24
+ borderColor: '#222'
25
+ };
26
+ function resolveUpiHandleTokens(modes) {
27
+ const backgroundColor = getVariableByName('upiHandle/background', modes) || '#f5f5f5';
28
+ const radius = getVariableByName('upiHandle/radius', modes) || 99999;
29
+ const paddingLeft = getVariableByName('upiHandle/padding/left', modes) || 4;
30
+ const paddingRight = getVariableByName('upiHandle/padding/right', modes) || 14;
31
+ const paddingVertical = getVariableByName('upiHandle/padding/vertical', modes) || 3;
32
+ const gap = getVariableByName('upiHandle/gap', modes) || 6;
33
+ const avatarSize = getVariableByName('upiHandle/image/size', modes) || 23;
34
+ const avatarRadius = getVariableByName('upiHandle/image/radius', modes) || 99999;
35
+ const labelColor = getVariableByName('upiHandle/label/color', modes) || '#0d0d0f';
36
+ const labelFontSize = getVariableByName('upiHandle/label/fontSize', modes) || 12;
37
+ const labelLineHeight = getVariableByName('upiHandle/label/lineHeight', modes) || 23;
38
+ const labelFontFamily = getVariableByName('upiHandle/label/fontFamily', modes) || 'System';
39
+ const labelFontWeightRaw = getVariableByName('upiHandle/label/fontWeight', modes) || 500;
40
+ const labelFontWeight = typeof labelFontWeightRaw === 'number' ? labelFontWeightRaw.toString() : labelFontWeightRaw;
41
+ const iconColor = getVariableByName('upiHandle/icon/color', modes) || '#0d0d0f';
42
+ const iconSize = getVariableByName('upiHandle/icon/size', modes) || 12;
43
+ return {
44
+ containerStyle: {
45
+ flexDirection: 'row',
46
+ alignItems: 'center',
47
+ justifyContent: 'center',
48
+ backgroundColor,
49
+ paddingLeft,
50
+ paddingRight,
51
+ paddingVertical,
52
+ borderRadius: radius,
53
+ gap
54
+ },
55
+ avatarStyle: {
56
+ width: avatarSize,
57
+ height: avatarSize,
58
+ borderRadius: avatarRadius,
59
+ overflow: 'hidden'
60
+ },
61
+ labelStyle: {
62
+ color: labelColor,
63
+ fontSize: labelFontSize,
64
+ lineHeight: labelLineHeight,
65
+ fontFamily: labelFontFamily,
66
+ fontWeight: labelFontWeight
67
+ },
68
+ iconColor,
69
+ iconSize,
70
+ iconPlaceholderStyle: {
71
+ width: iconSize,
72
+ height: iconSize
73
+ }
74
+ };
75
+ }
76
+
13
77
  /**
14
78
  * UpiHandle pill that mirrors the Figma "UPI Handle" component.
15
79
  *
16
- * Layout:
17
- * - Circular image/avatar on the left
18
- * - Label text in the center
19
- * - Optional QR-code style icon on the right
20
- *
21
- * All visual styling is resolved from Figma variables via `getVariableByName`
22
- * using a `modes` configuration object, matching the rest of this library.
23
- *
24
80
  * @component
25
81
  * @param {Object} props
26
82
  * @param {string} [props.label="Label"] - UPI handle text to display.
27
83
  * @param {Object} [props.modes={}] - Modes object passed directly to `getVariableByName`.
28
84
  * @param {boolean} [props.showIcon=true] - Toggles the trailing icon visibility.
29
- * @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set (e.g. 'ic_qr_code', 'ic_scan_qr_code').
85
+ * @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set.
30
86
  * @param {ImageSourcePropType} [props.avatarSource] - Optional custom image source for the avatar.
31
87
  * @param {Function} [props.onClick] - Click/tap handler. Works as an alias for `onPress`.
32
- * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, uses label
88
+ * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
33
89
  * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
90
+ *
91
+ * Performance notes:
92
+ * - Token reads collapsed into a single `useMemo([modes])`.
93
+ * - Press visual goes through Pressable's `({ pressed })` style callback so
94
+ * a scroll-cancelled touch never schedules a React render. iOS gets
95
+ * `unstable_pressDelay={130}` for additional safety inside scrollables.
96
+ * - Focus state is mirrored on web only (gated setter).
97
+ * - Wrapped in `React.memo`.
34
98
  */
35
99
  function UpiHandle({
36
100
  label = 'Label',
37
- modes: propModes = {},
101
+ modes: propModes = EMPTY_MODES,
38
102
  showIcon = true,
39
103
  iconName = 'ic_scan_qr_code',
40
104
  avatarSource,
41
105
  onPress,
42
106
  onClick,
43
107
  disabled,
44
- accessibilityLabel,
108
+ // accessibilityLabel is accepted on the type for API back-compat; the
109
+ // wrapper renders `accessibilityLabel={undefined}` because the inner Text
110
+ // already carries the label.
111
+ accessibilityLabel: _accessibilityLabel,
45
112
  accessibilityHint,
46
113
  ...rest
47
114
  }) {
48
115
  const {
49
116
  modes: globalModes
50
117
  } = useTokens();
51
- const modes = {
118
+ const modes = useMemo(() => globalModes === EMPTY_MODES && propModes === EMPTY_MODES ? EMPTY_MODES : {
52
119
  ...globalModes,
53
120
  ...propModes
54
- };
55
- // Token‑driven container styling
56
- const backgroundColor = getVariableByName('upiHandle/background', modes) || '#f5f5f5';
57
- const radius = getVariableByName('upiHandle/radius', modes) || 99999;
58
- const paddingLeft = getVariableByName('upiHandle/padding/left', modes) || 4;
59
- const paddingRight = getVariableByName('upiHandle/padding/right', modes) || 14;
60
- const paddingVertical = getVariableByName('upiHandle/padding/vertical', modes) || 3;
61
- const gap = getVariableByName('upiHandle/gap', modes) || 6;
62
-
63
- // Avatar
64
- const avatarSize = getVariableByName('upiHandle/image/size', modes) || 23;
65
- const avatarRadius = getVariableByName('upiHandle/image/radius', modes) || 99999;
66
-
67
- // Label typography
68
- const labelColor = getVariableByName('upiHandle/label/color', modes) || '#0d0d0f';
69
- const labelFontSize = getVariableByName('upiHandle/label/fontSize', modes) || 12;
70
- const labelLineHeight = getVariableByName('upiHandle/label/lineHeight', modes) || 23;
71
- const labelFontFamily = getVariableByName('upiHandle/label/fontFamily', modes) || 'System';
72
- const labelFontWeightRaw = getVariableByName('upiHandle/label/fontWeight', modes) || 500;
73
- const labelFontWeight = typeof labelFontWeightRaw === 'number' ? labelFontWeightRaw.toString() : labelFontWeightRaw;
121
+ }, [globalModes, propModes]);
122
+ const tokens = useMemo(() => resolveUpiHandleTokens(modes), [modes]);
74
123
 
75
- // Icon sizing
76
- const iconColor = getVariableByName('upiHandle/icon/color', modes) || '#0d0d0f';
77
- const iconSize = getVariableByName('upiHandle/icon/size', modes) || 12;
78
- const containerStyle = {
79
- flexDirection: 'row',
80
- alignItems: 'center',
81
- justifyContent: 'center',
82
- backgroundColor,
83
- paddingLeft,
84
- paddingRight,
85
- paddingVertical,
86
- borderRadius: radius,
87
- gap
88
- };
89
- const avatarBaseStyle = {
90
- width: avatarSize,
91
- height: avatarSize,
92
- borderRadius: avatarRadius,
93
- overflow: 'hidden'
94
- };
95
- const labelBaseStyle = {
96
- color: labelColor,
97
- fontSize: labelFontSize,
98
- lineHeight: labelLineHeight,
99
- fontFamily: labelFontFamily,
100
- fontWeight: labelFontWeight
101
- };
102
- const iconPlaceholderStyle = {
103
- width: iconSize,
104
- height: iconSize
105
- };
106
-
107
- // Use provided accessibilityLabel or fall back to label
108
- const defaultAccessibilityLabel = accessibilityLabel || `UPI handle ${label}`;
109
- const [isPressed, setIsPressed] = useState(false);
124
+ // Focus is a sustained visible state (web-only). Setter is gated so it
125
+ // never fires on native.
110
126
  const [isFocused, setIsFocused] = useState(false);
111
- const pressedStyle = isPressed ? {
112
- transform: [{
113
- scale: 0.98
114
- }]
115
- } : null;
116
- const focusStyle = isFocused ? {
117
- borderWidth: 1,
118
- borderColor: '#222'
119
- } : null;
127
+ const userHandlersRef = useRef({});
128
+ userHandlersRef.current.onPressIn = rest?.onPressIn;
129
+ userHandlersRef.current.onPressOut = rest?.onPressOut;
130
+ userHandlersRef.current.onFocus = rest?.onFocus;
131
+ userHandlersRef.current.onBlur = rest?.onBlur;
132
+ const handlePressIn = useCallback(e => {
133
+ userHandlersRef.current.onPressIn?.(e);
134
+ }, []);
135
+ const handlePressOut = useCallback(e => {
136
+ userHandlersRef.current.onPressOut?.(e);
137
+ }, []);
138
+ const handleFocus = useCallback(e => {
139
+ if (IS_WEB) setIsFocused(true);
140
+ userHandlersRef.current.onFocus?.(e);
141
+ }, []);
142
+ const handleBlur = useCallback(e => {
143
+ if (IS_WEB) setIsFocused(false);
144
+ userHandlersRef.current.onBlur?.(e);
145
+ }, []);
120
146
  const handlePress = onPress || onClick;
121
- const Wrapper = rest?.onPress || handlePress ? Pressable : View;
122
- return /*#__PURE__*/_jsxs(Wrapper, {
123
- style: [containerStyle, pressedStyle, focusStyle],
124
- accessibilityRole: "text",
125
- accessibilityLabel: undefined,
126
- ...(accessibilityHint !== undefined ? {
127
- accessibilityHint
128
- } : {}),
129
- onPress: handlePress,
130
- disabled: rest?.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
- ...rest,
147
+ const isPressable = !!(rest?.onPress || handlePress);
148
+ const pressableStyle = useCallback(({
149
+ pressed
150
+ }) => [tokens.containerStyle, pressed ? pressedOverlayStyle : null, isFocused ? focusOverlayStyle : null], [tokens.containerStyle, isFocused]);
151
+ const staticContainerStyle = useMemo(() => [tokens.containerStyle, isFocused ? focusOverlayStyle : null], [tokens.containerStyle, isFocused]);
152
+ const innerContent = /*#__PURE__*/_jsxs(_Fragment, {
148
153
  children: [/*#__PURE__*/_jsx(Image, {
149
154
  source: avatarSource || DEFAULT_AVATAR_IMAGE,
150
- style: avatarBaseStyle,
155
+ style: tokens.avatarStyle,
151
156
  resizeMode: "cover",
152
157
  accessibilityElementsHidden: true,
153
158
  importantForAccessibility: "no"
154
159
  }), /*#__PURE__*/_jsx(Text, {
155
- style: labelBaseStyle,
160
+ style: tokens.labelStyle,
156
161
  numberOfLines: 1,
157
162
  ellipsizeMode: "tail",
158
163
  accessibilityElementsHidden: true,
@@ -160,12 +165,41 @@ function UpiHandle({
160
165
  children: label
161
166
  }), showIcon && /*#__PURE__*/_jsx(Icon, {
162
167
  name: iconName,
163
- size: iconSize,
164
- color: iconColor,
165
- style: iconPlaceholderStyle,
168
+ size: tokens.iconSize,
169
+ color: tokens.iconColor,
170
+ style: tokens.iconPlaceholderStyle,
166
171
  accessibilityElementsHidden: true,
167
172
  importantForAccessibility: "no"
168
173
  })]
169
174
  });
175
+ if (isPressable) {
176
+ return /*#__PURE__*/_jsx(Pressable, {
177
+ style: pressableStyle,
178
+ accessibilityRole: "text",
179
+ accessibilityLabel: undefined,
180
+ ...(accessibilityHint !== undefined ? {
181
+ accessibilityHint
182
+ } : {}),
183
+ onPress: handlePress,
184
+ disabled: rest?.disabled ?? disabled,
185
+ onPressIn: handlePressIn,
186
+ onPressOut: handlePressOut,
187
+ onFocus: handleFocus,
188
+ onBlur: handleBlur,
189
+ unstable_pressDelay: PRESS_DELAY,
190
+ ...rest,
191
+ children: innerContent
192
+ });
193
+ }
194
+ return /*#__PURE__*/_jsx(View, {
195
+ style: staticContainerStyle,
196
+ accessibilityRole: "text",
197
+ accessibilityLabel: undefined,
198
+ ...(accessibilityHint !== undefined ? {
199
+ accessibilityHint
200
+ } : {}),
201
+ ...rest,
202
+ children: innerContent
203
+ });
170
204
  }
171
- export default UpiHandle;
205
+ export default /*#__PURE__*/React.memo(UpiHandle);
@@ -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
  * VStack component for vertical layout using design token spacing.
@@ -16,7 +16,7 @@ export const VStack = ({
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
  }) => {