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,9 +1,11 @@
1
- import React, { useState } from 'react'
1
+ import React, { useCallback, useMemo, useRef, useState } from 'react'
2
2
  import {
3
+ Platform,
3
4
  Pressable,
4
5
  Text,
5
6
  View,
6
7
  type AccessibilityState,
8
+ type PressableStateCallbackType,
7
9
  type StyleProp,
8
10
  type TextStyle,
9
11
  type ViewStyle,
@@ -12,6 +14,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
12
14
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
13
15
  import Icon from '../../icons/Icon'
14
16
  import { usePressableWebSupport, type SafePressableProps, type WebAccessibilityProps } from '../../utils/web-platform-utils'
17
+ import { EMPTY_MODES } from '../../utils/react-utils'
15
18
 
16
19
  type BottomNavItemProps = SafePressableProps & {
17
20
  iconName?: string;
@@ -32,21 +35,80 @@ type BottomNavItemProps = SafePressableProps & {
32
35
  webAccessibilityProps?: WebAccessibilityProps;
33
36
  };
34
37
 
38
+ const IS_WEB = Platform.OS === 'web'
39
+ const IS_IOS = Platform.OS === 'ios'
40
+ const PRESS_DELAY = IS_IOS ? 130 : 0
41
+
42
+ const pressedOverlayStyle: ViewStyle = { opacity: 0.7 }
43
+ const hoverOverlayStyle: ViewStyle = { opacity: 0.85 }
44
+ const focusOverlayStyle: ViewStyle = { borderBottomWidth: 2, borderBottomColor: '#222' }
45
+
46
+ interface BottomNavItemTokens {
47
+ baseContainerStyle: ViewStyle;
48
+ textStyle: TextStyle;
49
+ iconColor: string;
50
+ iconSize: number;
51
+ }
52
+
53
+ function resolveBottomNavItemTokens(
54
+ modes: Record<string, any>,
55
+ disabled: boolean,
56
+ iconColorOverride?: string,
57
+ iconSizeOverride?: number,
58
+ ): BottomNavItemTokens {
59
+ const gap = (getVariableByName('bottomNavItem/gap', modes) ?? 6) as number
60
+
61
+ const fontFamily =
62
+ (getVariableByName('bottomNavItem/fontFamily', modes) || 'JioType_Var:Medium') as string
63
+ const fontWeightRaw = getVariableByName('bottomNavItem/fontWeight', modes) ?? 500
64
+ const fontWeight =
65
+ typeof fontWeightRaw === 'number' ? fontWeightRaw.toString() : fontWeightRaw
66
+ const fontSize = (getVariableByName('bottomNavItem/fontSize', modes) ?? 11) as number
67
+ const lineHeight = (getVariableByName('bottomNavItem/lineHeight', modes) ?? 14) as number
68
+
69
+ const labelColor = (getVariableByName('bottomNavItem/label/color', modes) || '#0d0d0f') as string
70
+
71
+ const resolvedIconColor =
72
+ iconColorOverride || (getVariableByName('bottomNavItem/icon/color', modes) || '#ad8545') as string
73
+ const resolvedIconSize =
74
+ iconSizeOverride ?? (getVariableByName('bottomNavItem/icon/size', modes) ?? 24) as number
75
+
76
+ return {
77
+ baseContainerStyle: {
78
+ alignItems: 'center',
79
+ opacity: disabled ? 0.5 : 1,
80
+ },
81
+ textStyle: {
82
+ color: labelColor,
83
+ fontFamily,
84
+ fontWeight: fontWeight as TextStyle['fontWeight'],
85
+ fontSize,
86
+ lineHeight,
87
+ textAlign: 'center',
88
+ marginTop: gap,
89
+ },
90
+ iconColor: resolvedIconColor,
91
+ iconSize: resolvedIconSize,
92
+ }
93
+ }
94
+
35
95
  /**
36
96
  * Bottom navigation item with icon and label stacked vertically.
37
97
  *
38
- * All visual attributes resolve from Figma tokens via `getVariableByName`,
39
- * with the `modes` object passed straight through.
40
- *
41
- * @component
42
- * @param {Object} props
43
- * @param {string} [props.iconName="ic_home"] - Icon name from the registry.
44
- * ...
98
+ * Performance notes:
99
+ * - Token reads collapsed into a single `useMemo([modes, disabled, iconColor, iconSize])`.
100
+ * - Press visual via Pressable's `({ pressed })` style callback.
101
+ * - Hover and focus state are mirrored on web only (gated setters).
102
+ * - The previous version had no-op `onPressIn`/`onPressOut` handlers that
103
+ * forwarded to user callbacks but did nothing else they were still
104
+ * creating fresh closures every render and forcing Pressable to re-bind.
105
+ * Now stable via a ref-backed wrapper.
106
+ * - Wrapped in `React.memo`.
45
107
  */
46
108
  function BottomNavItem({
47
109
  iconName = 'ic_home',
48
110
  label = 'Home',
49
- modes: propModes = {},
111
+ modes: propModes = EMPTY_MODES,
50
112
  onPress,
51
113
  disabled = false,
52
114
  style,
@@ -60,50 +122,39 @@ function BottomNavItem({
60
122
  ...rest
61
123
  }: BottomNavItemProps) {
62
124
  const { modes: globalModes } = useTokens()
63
- const modes = { ...globalModes, ...propModes }
64
- const [isFocused, setIsFocused] = useState(false)
65
- const [isHovered, setIsHovered] = useState(false)
66
- const pressedStyle = { opacity: 0.7 }
67
- const focusStyle = { borderBottomWidth: 2, borderBottomColor: '#222' }
68
- const hoverStyle = { opacity: 0.85 }
69
- // Resolve spacing and typography
70
- const gap = getVariableByName('bottomNavItem/gap', modes) ?? 6
71
-
72
- const fontFamily =
73
- getVariableByName('bottomNavItem/fontFamily', modes) || 'JioType_Var:Medium'
74
- const fontWeightRaw = getVariableByName('bottomNavItem/fontWeight', modes) ?? 500
75
- const fontWeight = typeof fontWeightRaw === 'number' ? fontWeightRaw.toString() : fontWeightRaw
76
- const fontSize = getVariableByName('bottomNavItem/fontSize', modes) ?? 11
77
- const lineHeight = getVariableByName('bottomNavItem/lineHeight', modes) ?? 14
78
-
79
- // Resolve Label Color
80
- const labelColor = getVariableByName('bottomNavItem/label/color', modes) || '#0d0d0f'
81
125
 
82
- // Resolve icon appearance
83
- const resolvedIconColor =
84
- iconColorOverride || getVariableByName('bottomNavItem/icon/color', modes) || '#ad8545'
126
+ const modes = useMemo(
127
+ () => (globalModes === EMPTY_MODES && propModes === EMPTY_MODES
128
+ ? EMPTY_MODES
129
+ : { ...globalModes, ...propModes }),
130
+ [globalModes, propModes]
131
+ )
85
132
 
86
- const resolvedIconSize = iconSizeOverride ?? getVariableByName('bottomNavItem/icon/size', modes) ?? 24
133
+ const tokens = useMemo(
134
+ () => resolveBottomNavItemTokens(modes, disabled, iconColorOverride, iconSizeOverride),
135
+ [modes, disabled, iconColorOverride, iconSizeOverride]
136
+ )
87
137
 
88
- const baseContainerStyle: ViewStyle = {
89
- alignItems: 'center',
90
- opacity: disabled ? 0.5 : 1,
91
- }
138
+ const [isFocused, setIsFocused] = useState(false)
139
+ const [isHovered, setIsHovered] = useState(false)
92
140
 
93
- const textStyle: TextStyle = {
94
- color: labelColor,
95
- fontFamily,
96
- fontWeight,
97
- fontSize,
98
- lineHeight,
99
- textAlign: 'center',
100
- marginTop: gap,
101
- }
141
+ const userHandlersRef = useRef<{
142
+ onPressIn?: (e: any) => void
143
+ onPressOut?: (e: any) => void
144
+ onFocus?: (e: any) => void
145
+ onBlur?: (e: any) => void
146
+ onHoverIn?: (e: any) => void
147
+ onHoverOut?: (e: any) => void
148
+ }>({})
149
+ userHandlersRef.current.onPressIn = (rest as any)?.onPressIn
150
+ userHandlersRef.current.onPressOut = (rest as any)?.onPressOut
151
+ userHandlersRef.current.onFocus = (rest as any)?.onFocus
152
+ userHandlersRef.current.onBlur = (rest as any)?.onBlur
153
+ userHandlersRef.current.onHoverIn = (rest as any)?.onHoverIn
154
+ userHandlersRef.current.onHoverOut = (rest as any)?.onHoverOut
102
155
 
103
- // Use provided accessibilityLabel or fall back to label
104
156
  const defaultAccessibilityLabel = accessibilityLabel || label
105
157
 
106
- // Get web platform support props (only used when onPress is defined)
107
158
  const webProps = usePressableWebSupport({
108
159
  restProps: rest,
109
160
  onPress: disabled ? undefined : onPress,
@@ -112,17 +163,22 @@ function BottomNavItem({
112
163
  webAccessibilityProps,
113
164
  })
114
165
 
115
- const renderContent = () => (
166
+ const composedTextStyle = useMemo<StyleProp<TextStyle>>(
167
+ () => (labelStyle ? [tokens.textStyle, labelStyle] : tokens.textStyle),
168
+ [tokens.textStyle, labelStyle]
169
+ )
170
+
171
+ const renderContent = (
116
172
  <>
117
173
  <Icon
118
174
  name={iconName}
119
- size={resolvedIconSize}
120
- color={resolvedIconColor}
175
+ size={tokens.iconSize}
176
+ color={tokens.iconColor}
121
177
  accessibilityElementsHidden={true}
122
178
  importantForAccessibility="no"
123
179
  />
124
180
  <Text
125
- style={[textStyle, labelStyle]}
181
+ style={composedTextStyle}
126
182
  accessibilityElementsHidden={true}
127
183
  importantForAccessibility="no"
128
184
  >
@@ -131,20 +187,59 @@ function BottomNavItem({
131
187
  </>
132
188
  )
133
189
 
190
+ const staticContainerStyle = useMemo<StyleProp<ViewStyle>>(
191
+ () => (style ? [tokens.baseContainerStyle, style] : tokens.baseContainerStyle),
192
+ [tokens.baseContainerStyle, style]
193
+ )
194
+
195
+ const handlePressIn = useCallback((e: any) => {
196
+ userHandlersRef.current.onPressIn?.(e)
197
+ }, [])
198
+ const handlePressOut = useCallback((e: any) => {
199
+ userHandlersRef.current.onPressOut?.(e)
200
+ }, [])
201
+ const handleFocus = useCallback((e: any) => {
202
+ if (IS_WEB) setIsFocused(true)
203
+ userHandlersRef.current.onFocus?.(e)
204
+ }, [])
205
+ const handleBlur = useCallback((e: any) => {
206
+ if (IS_WEB) setIsFocused(false)
207
+ userHandlersRef.current.onBlur?.(e)
208
+ }, [])
209
+ const handleHoverIn = useCallback((e: any) => {
210
+ if (IS_WEB) setIsHovered(true)
211
+ userHandlersRef.current.onHoverIn?.(e)
212
+ }, [])
213
+ const handleHoverOut = useCallback((e: any) => {
214
+ if (IS_WEB) setIsHovered(false)
215
+ userHandlersRef.current.onHoverOut?.(e)
216
+ }, [])
217
+
218
+ const pressableStyle = useCallback(
219
+ ({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => [
220
+ tokens.baseContainerStyle,
221
+ style,
222
+ pressed && !disabled ? pressedOverlayStyle : null,
223
+ isHovered && !disabled ? hoverOverlayStyle : null,
224
+ isFocused && !disabled ? focusOverlayStyle : null,
225
+ ],
226
+ [tokens.baseContainerStyle, style, isHovered, isFocused, disabled]
227
+ )
228
+
134
229
  if (!onPress) {
135
230
  return (
136
231
  <View
137
- style={[baseContainerStyle, style]}
232
+ style={staticContainerStyle}
138
233
  accessibilityRole="tab"
139
234
  accessibilityLabel={undefined}
140
235
  accessibilityHint={accessibilityHint}
141
236
  accessibilityState={{
142
237
  disabled,
143
- ...accessibilityState
238
+ ...accessibilityState,
144
239
  }}
145
240
  {...rest}
146
241
  >
147
- {renderContent()}
242
+ {renderContent}
148
243
  </View>
149
244
  )
150
245
  }
@@ -157,47 +252,23 @@ function BottomNavItem({
157
252
  accessibilityState={{
158
253
  disabled,
159
254
  selected: accessibilityState?.selected,
160
- ...accessibilityState
255
+ ...accessibilityState,
161
256
  }}
162
257
  onPress={onPress}
163
258
  disabled={disabled}
164
- onPressIn={(e: any) => {
165
- ; (rest as any)?.onPressIn?.(e)
166
- }}
167
- onPressOut={(e: any) => {
168
- ; (rest as any)?.onPressOut?.(e)
169
- }}
170
- onFocus={(e: any) => {
171
- setIsFocused(true)
172
- ; (rest as any)?.onFocus?.(e)
173
- }}
174
- onBlur={(e: any) => {
175
- setIsFocused(false)
176
- ; (rest as any)?.onBlur?.(e)
177
- }}
178
- onHoverIn={(e: any) => {
179
- setIsHovered(true)
180
- ; (rest as any)?.onHoverIn?.(e)
181
- }}
182
- onHoverOut={(e: any) => {
183
- setIsHovered(false)
184
- ; (rest as any)?.onHoverOut?.(e)
185
- }}
186
- style={({ pressed }) =>
187
- [
188
- baseContainerStyle,
189
- style,
190
- pressed && !disabled ? pressedStyle : null,
191
- isHovered && !disabled ? hoverStyle : null,
192
- isFocused && !disabled ? focusStyle : null,
193
- ] as StyleProp<ViewStyle>
194
- }
259
+ onPressIn={handlePressIn}
260
+ onPressOut={handlePressOut}
261
+ onFocus={handleFocus}
262
+ onBlur={handleBlur}
263
+ onHoverIn={handleHoverIn}
264
+ onHoverOut={handleHoverOut}
265
+ unstable_pressDelay={PRESS_DELAY}
266
+ style={pressableStyle}
195
267
  {...webProps}
196
268
  >
197
- {renderContent()}
269
+ {renderContent}
198
270
  </Pressable>
199
271
  )
200
272
  }
201
273
 
202
- export default BottomNavItem
203
-
274
+ export default React.memo(BottomNavItem)