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
@@ -2,6 +2,22 @@
2
2
 
3
3
  import React from 'react';
4
4
 
5
+ /**
6
+ * A shared, frozen empty modes object.
7
+ *
8
+ * Components that accept a `modes` prop should use this as the default value
9
+ * instead of the inline `{}` literal. The literal allocates a new object on
10
+ * every render, which:
11
+ * 1. Forces `React.memo` shallow comparisons to fail.
12
+ * 2. Forces `useMemo`/`useEffect` deps that include `modes` to re-run.
13
+ * 3. Forces the design-token resolver to re-serialize the modes object on
14
+ * every call (see `serializeModes` in `figma-variables-resolver.ts`).
15
+ *
16
+ * Sharing a single frozen object across the tree makes all of those checks
17
+ * O(1) identity comparisons in the common "no modes provided" path.
18
+ */
19
+ export const EMPTY_MODES = Object.freeze({});
20
+
5
21
  /**
6
22
  * Helper function to recursively clone children and pass modes prop to components that accept it.
7
23
  * This ensures that all child components in slots receive the modes prop from the parent.
@@ -3,12 +3,6 @@ import { View, type ImageSourcePropType } from 'react-native';
3
3
  /**
4
4
  * Avatar component that displays either an image or a monogram.
5
5
  *
6
- * This component supports two styles:
7
- * - Image: Displays a user's profile picture
8
- * - Monogram: Displays user initials in a circular background
9
- *
10
- * All styling values are resolved from Figma design tokens using the provided modes.
11
- *
12
6
  * @component
13
7
  * @param {Object} props - Component props
14
8
  * @param {string} [props.monogram="MS"] - The initials to display when style is "Monogram"
@@ -17,24 +11,24 @@ import { View, type ImageSourcePropType } from 'react-native';
17
11
  * @param {string} [props.imageSource] - Optional image source for Image style (defaults to built-in image)
18
12
  * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, uses monogram or "User avatar"
19
13
  *
20
- * @example
21
- * ```jsx
22
- * // Image style
23
- * <Avatar style="Image" modes={{"Avatar Size": "M"}} />
24
- *
25
- * // Monogram style
26
- * <Avatar style="Monogram" monogram="JD" modes={{"Avatar Size": "L"}} />
27
- * ```
14
+ * Performance notes:
15
+ * - All token reads are folded into a single `useMemo([modes, isMonogram])`.
16
+ * - Press visual goes through Pressable's `({ pressed })` style callback so
17
+ * a scroll-cancelled touch never schedules a React render. iOS gets
18
+ * `unstable_pressDelay={130}` for additional safety inside scrollables.
19
+ * - Focus state stays in React (it's a sustained visual) but the setter is
20
+ * gated to web only, where focus events actually fire.
28
21
  */
29
22
  export type AvatarProps = {
30
23
  monogram?: string;
31
- style?: "Image" | "Monogram";
24
+ style?: 'Image' | 'Monogram';
32
25
  modes?: Record<string, any>;
33
26
  imageSource?: ImageSourcePropType | string;
34
27
  accessibilityLabel?: string;
35
28
  onPress?: () => void;
36
29
  disabled?: boolean;
37
30
  } & Omit<React.ComponentProps<typeof View>, 'style' | 'accessibilityRole' | 'accessibilityLabel'>;
38
- declare function Avatar({ monogram, style, modes, imageSource, accessibilityLabel, ...rest }: AvatarProps): import("react/jsx-runtime").JSX.Element;
39
- export default Avatar;
31
+ declare function Avatar({ monogram, style, modes, imageSource, accessibilityLabel: _accessibilityLabel, ...rest }: AvatarProps): import("react/jsx-runtime").JSX.Element;
32
+ declare const _default: React.MemoExoticComponent<typeof Avatar>;
33
+ export default _default;
40
34
  //# sourceMappingURL=Avatar.d.ts.map
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { type AccessibilityState, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
2
3
  import { type SafePressableProps, type WebAccessibilityProps } from '../../utils/web-platform-utils';
3
4
  type BottomNavItemProps = SafePressableProps & {
@@ -21,14 +22,17 @@ type BottomNavItemProps = SafePressableProps & {
21
22
  /**
22
23
  * Bottom navigation item with icon and label stacked vertically.
23
24
  *
24
- * All visual attributes resolve from Figma tokens via `getVariableByName`,
25
- * with the `modes` object passed straight through.
26
- *
27
- * @component
28
- * @param {Object} props
29
- * @param {string} [props.iconName="ic_home"] - Icon name from the registry.
30
- * ...
25
+ * Performance notes:
26
+ * - Token reads collapsed into a single `useMemo([modes, disabled, iconColor, iconSize])`.
27
+ * - Press visual via Pressable's `({ pressed })` style callback.
28
+ * - Hover and focus state are mirrored on web only (gated setters).
29
+ * - The previous version had no-op `onPressIn`/`onPressOut` handlers that
30
+ * forwarded to user callbacks but did nothing else they were still
31
+ * creating fresh closures every render and forcing Pressable to re-bind.
32
+ * Now stable via a ref-backed wrapper.
33
+ * - Wrapped in `React.memo`.
31
34
  */
32
35
  declare function BottomNavItem({ iconName, label, modes: propModes, onPress, disabled, style, labelStyle, iconColor: iconColorOverride, iconSize: iconSizeOverride, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: BottomNavItemProps): import("react/jsx-runtime").JSX.Element;
33
- export default BottomNavItem;
36
+ declare const _default: React.MemoExoticComponent<typeof BottomNavItem>;
37
+ export default _default;
34
38
  //# sourceMappingURL=BottomNavItem.d.ts.map
@@ -59,7 +59,24 @@ export type ButtonProps = SafePressableProps & {
59
59
  * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, uses label or children text
60
60
  * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
61
61
  * @param {Object} [props.accessibilityState] - Additional accessibility state information
62
+ *
63
+ * Performance notes:
64
+ * - The pressed visual (background/border swap) is applied through the
65
+ * Pressable `style` callback, NOT a mirrored React state. This avoids the
66
+ * flicker that scrolling parents previously caused: when a ScrollView
67
+ * cancels a touch the host view simply reverts its style without React
68
+ * rendering. On iOS we additionally use `unstable_pressDelay` so the
69
+ * pressed visual is never even applied during a scroll-cancelled touch.
70
+ * - Hover state is only mirrored into React state on web (where hover events
71
+ * fire). On native the setter call is gated out so the component never
72
+ * re-renders due to hover.
73
+ * - All design-token reads are folded into a single `useMemo` keyed on
74
+ * `(modes, disabled)`.
75
+ * - The component is wrapped in `React.memo`. Callers that want to take
76
+ * advantage of this should pass stable `modes` (the default `EMPTY_MODES`
77
+ * is already stable) and stable callback props.
62
78
  */
63
- declare function Button({ label, children, renderContent, leading, trailing, icon, modes, onPress, disabled, style, labelStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
79
+ declare function ButtonImpl({ label, children, renderContent, leading, trailing, icon, modes, onPress, disabled, style, labelStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
80
+ declare const Button: React.MemoExoticComponent<typeof ButtonImpl>;
64
81
  export default Button;
65
82
  //# sourceMappingURL=Button.d.ts.map
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { type AccessibilityState, type StyleProp, type ViewStyle } from 'react-native';
2
3
  import { type SafePressableProps, type WebAccessibilityProps } from '../../utils/web-platform-utils';
3
4
  type IconButtonProps = SafePressableProps & {
@@ -33,35 +34,17 @@ type IconButtonProps = SafePressableProps & {
33
34
  /**
34
35
  * IconButton component that displays an icon within a pressable button container.
35
36
  *
36
- * This component displays an icon within a styled button container that can be pressed.
37
- * All styling values are resolved from Figma design tokens using the provided modes.
38
- *
39
- * @component
40
- * @param {Object} props - Component props
41
- * @param {string} [props.iconName="ic_card"] - The name of the icon to display from the icon registry
42
- * @param {Object} [props.modes={}] - Mode configuration for design tokens (e.g., {"Button / Size": "M", "Appearance": "high"})
43
- * @param {Function} [props.onPress] - Callback function called when the button is pressed
44
- * @param {boolean} [props.disabled=false] - Whether the button is disabled
45
- * @param {Object} [props.style] - Additional styles for the container
46
- * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, defaults to iconName
47
- * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
48
- * @param {Object} [props.accessibilityState] - Additional accessibility state information
49
- *
50
- * @example
51
- * ```jsx
52
- * // Default icon button
53
- * <IconButton modes={{}} />
54
- *
55
- * // Custom icon with size mode
56
- * <IconButton iconName="ic_rupee" modes={{"Button / Size": "M"}} />
57
- *
58
- * // With appearance mode
59
- * <IconButton modes={{"Appearance": "high"}} onPress={() => console.log('pressed')} />
60
- *
61
- * // With accessibility label
62
- * <IconButton iconName="ic_search" accessibilityLabel={undefined} accessibilityHint="Opens the search screen" />
63
- * ```
37
+ * Performance notes:
38
+ * - Token reads collapsed into a single `useMemo([modes, disabled, isToggle, isActive])`.
39
+ * - Press visual goes through Pressable's `({ pressed })` style callback so
40
+ * a scroll-cancelled touch never schedules a React render. iOS gets
41
+ * `unstable_pressDelay={130}`.
42
+ * - Hover and focus state are mirrored on web only (gated setters).
43
+ * - The previous version had a redundant `manualPressStyle` (a duplicate
44
+ * pressed transform mirrored via React state) removed.
45
+ * - Wrapped in `React.memo`.
64
46
  */
65
47
  declare function IconButton({ iconName, modes, onPress, disabled, style, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, isToggle, activeIcon, inactiveIcon, isActive, ...rest }: IconButtonProps): import("react/jsx-runtime").JSX.Element;
66
- export default IconButton;
48
+ declare const _default: React.MemoExoticComponent<typeof IconButton>;
49
+ export default _default;
67
50
  //# sourceMappingURL=IconButton.d.ts.map
@@ -9,31 +9,23 @@ type IconCapsuleProps = {
9
9
  /**
10
10
  * IconCapsule component that displays an icon within a circular or rounded container.
11
11
  *
12
- * This component displays an icon (default: ic_card) within a styled capsule container.
13
12
  * All styling values are resolved from Figma design tokens using the provided modes.
14
13
  *
15
14
  * @component
16
15
  * @param {Object} props - Component props
17
16
  * @param {string} [props.iconName="ic_card"] - The name of the icon to display from the icon registry
18
17
  * @param {Object} [props.modes={}] - Mode configuration for design tokens (e.g., {"Appearance": "Primary"})
19
- * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, defaults to iconName
18
+ * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
20
19
  * @param {string} [props.accessibilityRole] - Accessibility role (defaults to "image" for decorative icons)
21
20
  *
22
- * @example
23
- * ```jsx
24
- * // Default icon (ic_card)
25
- * <IconCapsule modes={{}} />
26
- *
27
- * // Custom icon
28
- * <IconCapsule iconName="ic_rupee" modes={{}} />
29
- *
30
- * // With appearance mode
31
- * <IconCapsule modes={{"Appearance": "Secondary"}} />
32
- *
33
- * // With accessibility label
34
- * <IconCapsule iconName="ic_card" accessibilityLabel={undefined} />
35
- * ```
21
+ * Performance notes:
22
+ * - All token reads collapsed into a single `useMemo([modes])`. The merged
23
+ * `(globalModes + propModes)` object is also memoized so downstream
24
+ * `getVariableByName` calls hit the resolver's per-modes-object cache.
25
+ * - Wrapped in `React.memo`; with the shared `EMPTY_MODES` default the
26
+ * common path benefits from full memoization.
36
27
  */
37
- declare function IconCapsule({ iconName, modes: propModes, accessibilityLabel, accessibilityRole, ...rest }: IconCapsuleProps): import("react/jsx-runtime").JSX.Element;
38
- export default IconCapsule;
28
+ declare function IconCapsule({ iconName, modes: propModes, accessibilityLabel: _accessibilityLabel, accessibilityRole, style: styleProp, ...rest }: IconCapsuleProps): import("react/jsx-runtime").JSX.Element;
29
+ declare const _default: React.MemoExoticComponent<typeof IconCapsule>;
30
+ export default _default;
39
31
  //# sourceMappingURL=IconCapsule.d.ts.map
@@ -1,8 +1,13 @@
1
1
  import React from 'react';
2
- import { type StyleProp, type ViewStyle, type TextStyle } from 'react-native';
2
+ import { type StyleProp, type ViewStyle, type TextStyle, type TextInputProps as RNTextInputProps } from 'react-native';
3
3
  export type InputSearchProps = {
4
4
  supportText?: boolean;
5
5
  supportTextLabel?: string;
6
+ /**
7
+ * Icon name from the icon registry to render inside the support text
8
+ * (e.g. 'ic_info', 'ic_cart'). Defaults to 'ic_info'.
9
+ */
10
+ supportTextIcon?: string;
6
11
  modes?: Record<string, any>;
7
12
  containerStyle?: StyleProp<ViewStyle>;
8
13
  placeholder?: string;
@@ -15,6 +20,6 @@ export type InputSearchProps = {
15
20
  inputStyle?: StyleProp<TextStyle>;
16
21
  accessibilityLabel?: string;
17
22
  accessibilityHint?: string;
18
- };
19
- export default function InputSearch({ supportText, supportTextLabel, modes, containerStyle, placeholder, value, onChangeText, onFocus, onBlur, leading, trailing, inputStyle, ...rest }: InputSearchProps): import("react/jsx-runtime").JSX.Element;
23
+ } & Omit<RNTextInputProps, 'style' | 'onChangeText' | 'onFocus' | 'onBlur' | 'placeholder' | 'value'>;
24
+ export default function InputSearch({ supportText, supportTextLabel, supportTextIcon, modes, containerStyle, placeholder, value, onChangeText, onFocus, onBlur, leading, trailing, inputStyle, ...rest }: InputSearchProps): import("react/jsx-runtime").JSX.Element;
20
25
  //# sourceMappingURL=InputSearch.d.ts.map
@@ -54,7 +54,20 @@ type ListItemProps = {
54
54
  * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, uses title and supportText
55
55
  * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
56
56
  * @param {Object} [props.accessibilityState] - Additional accessibility state information
57
+ *
58
+ * Performance notes:
59
+ * - All token reads are folded into a single `useMemo([modes])`.
60
+ * - The pressed visual is applied via Pressable's `style={({pressed}) => ...}`
61
+ * callback so RN updates the host view directly — no React render is
62
+ * scheduled by a touch. On iOS the touch is additionally delayed via
63
+ * `unstable_pressDelay={130}` so a scroll-cancelled tap never even
64
+ * transiently applies the pressed style. This is the fix for the
65
+ * "People / Setup card flicker during scroll" report.
66
+ * - User-supplied event handlers are read through a ref so the wrapper
67
+ * handlers stay referentially stable across renders.
68
+ * - The component is wrapped in `React.memo`.
57
69
  */
58
- declare function ListItem({ layout, title, supportText, showSupportText, leading, supportSlot, endSlot, navArrow, modes, onPress, style, contentStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: ListItemProps): import("react/jsx-runtime").JSX.Element;
70
+ declare function ListItemImpl({ layout, title, supportText, showSupportText, leading, supportSlot, endSlot, navArrow, modes, onPress, style, contentStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: ListItemProps): import("react/jsx-runtime").JSX.Element;
71
+ declare const ListItem: React.MemoExoticComponent<typeof ListItemImpl>;
59
72
  export default ListItem;
60
73
  //# sourceMappingURL=ListItem.d.ts.map
@@ -15,16 +15,17 @@ type NavArrowProps = {
15
15
  * NavArrow component that displays a chevron arrow for navigation.
16
16
  *
17
17
  * Renders a stroked SVG chevron whose dimensions and thickness are
18
- * fully driven by design tokens:
19
- * - navArrow/icon/color - chevron stroke color
20
- * - navArrow/icon/width - chevron arm width (horizontal spread)
21
- * - navArrow/icon/height - chevron arm height (vertical spread)
22
- * - navArrow/icon/strokeWeight - stroke thickness
23
- * - navArrow/width - container width
24
- * - navArrow/height - container height
25
- * - navArrow/radius - border radius
26
- * - navArrow/background - background color
18
+ * fully driven by design tokens.
19
+ *
20
+ * Performance notes:
21
+ * - Token reads collapsed into a single `useMemo([modes])` so a parent
22
+ * re-render (e.g. from a Section header press) doesn't re-do ~9 token
23
+ * lookups per chevron.
24
+ * - Container + SVG layout values are derived in a second `useMemo` keyed
25
+ * on (tokens, direction, style).
26
+ * - Wrapped in `React.memo`.
27
27
  */
28
- export default function NavArrow({ direction, modes, style, accessibilityLabel, ...rest }: NavArrowProps): import("react/jsx-runtime").JSX.Element;
29
- export {};
28
+ declare function NavArrow({ direction, modes, style, accessibilityLabel, ...rest }: NavArrowProps): import("react/jsx-runtime").JSX.Element;
29
+ declare const _default: React.MemoExoticComponent<typeof NavArrow>;
30
+ export default _default;
30
31
  //# sourceMappingURL=NavArrow.d.ts.map
@@ -18,34 +18,14 @@ type SectionProps = {
18
18
  */
19
19
  webAccessibilityProps?: WebAccessibilityProps;
20
20
  } & React.ComponentProps<typeof View>;
21
- /**
22
- * Section component that mirrors the Figma "Section" component.
23
- *
24
- * This component supports:
25
- * - **header** with title, support text, and optional chevron icon
26
- * - **slot** for custom content (typically ListItem components)
27
- * - **design-token driven styling** via `getVariableByName` and `modes`
28
- *
29
- * Wherever the Figma layer name contains "Slot", this component exposes a
30
- * dedicated React "slot" prop:
31
- * - Slot "slot" → `slot`
32
- *
33
- * @component
34
- * @param {Object} props
35
- * @param {string} [props.title='Section title'] - Section title text
36
- * @param {string} [props.supportText='Section support text'] - Section support text
37
- * @param {boolean} [props.showSupportText=true] - Toggles rendering of the support text
38
- * @param {React.ReactNode} [props.slot] - Optional custom slot for content area (Figma Slot "slot")
39
- * @param {Object} [props.modes={}] - Modes object passed to `getVariableByName` for all design tokens
40
- * @param {Function} [props.onPress] - Callback function called when the header is pressed
41
- * @param {Object} [props.style] - Optional container style overrides
42
- * @param {string} [props.accessibilityLabel] - Accessibility label for the section. If not provided, uses title
43
- * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
44
- */
45
- declare function Section({ title, supportText, showSupportText, slot, slotDirection, modes, onPress, style, accessibilityLabel, accessibilityHint, webAccessibilityProps, ...rest }: SectionProps): import("react/jsx-runtime").JSX.Element;
21
+ declare function Section({ title, supportText, showSupportText, slot, slotDirection, modes, onPress, style, accessibilityLabel: _accessibilityLabel, accessibilityHint, webAccessibilityProps, ...rest }: SectionProps): import("react/jsx-runtime").JSX.Element;
46
22
  declare namespace Section {
47
23
  var Bento: typeof SectionBento;
48
24
  }
25
+ type BentoToggleRenderState = {
26
+ expanded: boolean;
27
+ toggle: () => void;
28
+ };
49
29
  type SectionBentoProps = {
50
30
  navSlot?: React.ReactNode;
51
31
  upiSlot?: React.ReactNode;
@@ -57,29 +37,44 @@ type SectionBentoProps = {
57
37
  * Web-specific accessibility props (only used on web platform)
58
38
  */
59
39
  webAccessibilityProps?: WebAccessibilityProps;
40
+ /**
41
+ * Total cell count visible when collapsed (real items + the toggle cell).
42
+ * Defaults to {@link SLOT_GRID_MAX_COLUMNS} (4) so the collapsed state fills
43
+ * exactly one row. When `navSlot.length <= collapsedCount`, expansion is
44
+ * disabled (no toggle injected, no animation wrappers — identical to the
45
+ * legacy behavior for back-compat).
46
+ */
47
+ collapsedCount?: number;
48
+ /**
49
+ * Uncontrolled initial expanded state. Ignored when `expanded` is provided.
50
+ * Defaults to `false`.
51
+ */
52
+ defaultExpanded?: boolean;
53
+ /**
54
+ * Controlled expanded state. When provided, `onExpandedChange` should also
55
+ * be provided so the component can request changes.
56
+ */
57
+ expanded?: boolean;
58
+ /**
59
+ * Called when the user taps the toggle. Required in controlled mode; ignored
60
+ * in uncontrolled mode unless you want to observe the change.
61
+ */
62
+ onExpandedChange?: (next: boolean) => void;
63
+ /** Label shown on the toggle cell when collapsed. Default `'More'`. */
64
+ toggleMoreLabel?: string;
65
+ /** Label shown on the toggle cell when expanded. Default `'Less'`. */
66
+ toggleLessLabel?: string;
67
+ /** Icon name shown on the toggle when collapsed. Default `'ic_chevron_down'`. */
68
+ toggleMoreIcon?: string;
69
+ /** Icon name shown on the toggle when expanded. Default `'ic_chevron_up'`. */
70
+ toggleLessIcon?: string;
71
+ /**
72
+ * Escape hatch: render a custom toggle cell instead of the default ListItem.
73
+ * The provided node is rendered in the toggle's grid slot. Wire `toggle()` to
74
+ * any tap interaction inside it. Height + per-cell animations still apply.
75
+ */
76
+ renderToggle?: (state: BentoToggleRenderState) => React.ReactNode;
60
77
  } & React.ComponentProps<typeof View>;
61
- /**
62
- * Section.Bento component that mirrors the Figma "Section.Bento" component.
63
- *
64
- * This component supports:
65
- * - **navSlot** for navigation items (typically ListItem components in vertical layout)
66
- * - **upiSlot** for UPI handles (typically UpiHandle components)
67
- * - **design-token driven styling** via `getVariableByName` and `modes`
68
- *
69
- * Wherever the Figma layer name contains "Slot", this component exposes a
70
- * dedicated React "slot" prop:
71
- * - Slot "Nav wrap" → `navSlot`
72
- * - Slot "UPI wrap" → `upiSlot`
73
- *
74
- * @component
75
- * @param {Object} props
76
- * @param {React.ReactNode} [props.navSlot] - Optional custom slot for navigation items (Figma Slot "Nav wrap")
77
- * @param {React.ReactNode} [props.upiSlot] - Optional custom slot for UPI handles (Figma Slot "UPI wrap")
78
- * @param {Object} [props.modes={}] - Modes object passed to `getVariableByName` for all design tokens
79
- * @param {Object} [props.style] - Optional container style overrides
80
- * @param {string} [props.accessibilityLabel] - Accessibility label for the section
81
- * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
82
- */
83
- declare function SectionBento({ navSlot, upiSlot, modes, style, accessibilityLabel, accessibilityHint, ...rest }: SectionBentoProps): import("react/jsx-runtime").JSX.Element;
78
+ declare function SectionBento({ navSlot, upiSlot, modes, style, accessibilityLabel: _accessibilityLabel, accessibilityHint, collapsedCount, defaultExpanded, expanded: controlledExpanded, onExpandedChange, toggleMoreLabel, toggleLessLabel, toggleMoreIcon, toggleLessIcon, renderToggle, ...rest }: SectionBentoProps): import("react/jsx-runtime").JSX.Element;
84
79
  export default Section;
85
80
  //# sourceMappingURL=Section.d.ts.map
@@ -15,25 +15,26 @@ type UpiHandleProps = {
15
15
  /**
16
16
  * UpiHandle pill that mirrors the Figma "UPI Handle" component.
17
17
  *
18
- * Layout:
19
- * - Circular image/avatar on the left
20
- * - Label text in the center
21
- * - Optional QR-code style icon on the right
22
- *
23
- * All visual styling is resolved from Figma variables via `getVariableByName`
24
- * using a `modes` configuration object, matching the rest of this library.
25
- *
26
18
  * @component
27
19
  * @param {Object} props
28
20
  * @param {string} [props.label="Label"] - UPI handle text to display.
29
21
  * @param {Object} [props.modes={}] - Modes object passed directly to `getVariableByName`.
30
22
  * @param {boolean} [props.showIcon=true] - Toggles the trailing icon visibility.
31
- * @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set (e.g. 'ic_qr_code', 'ic_scan_qr_code').
23
+ * @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set.
32
24
  * @param {ImageSourcePropType} [props.avatarSource] - Optional custom image source for the avatar.
33
25
  * @param {Function} [props.onClick] - Click/tap handler. Works as an alias for `onPress`.
34
- * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers. If not provided, uses label
26
+ * @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
35
27
  * @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
28
+ *
29
+ * Performance notes:
30
+ * - Token reads collapsed into a single `useMemo([modes])`.
31
+ * - Press visual goes through Pressable's `({ pressed })` style callback so
32
+ * a scroll-cancelled touch never schedules a React render. iOS gets
33
+ * `unstable_pressDelay={130}` for additional safety inside scrollables.
34
+ * - Focus state is mirrored on web only (gated setter).
35
+ * - Wrapped in `React.memo`.
36
36
  */
37
- declare function UpiHandle({ label, modes: propModes, showIcon, iconName, avatarSource, onPress, onClick, disabled, accessibilityLabel, accessibilityHint, ...rest }: UpiHandleProps): import("react/jsx-runtime").JSX.Element;
38
- export default UpiHandle;
37
+ declare function UpiHandle({ label, modes: propModes, showIcon, iconName, avatarSource, onPress, onClick, disabled, accessibilityLabel: _accessibilityLabel, accessibilityHint, ...rest }: UpiHandleProps): import("react/jsx-runtime").JSX.Element;
38
+ declare const _default: React.MemoExoticComponent<typeof UpiHandle>;
39
+ export default _default;
39
40
  //# sourceMappingURL=UpiHandle.d.ts.map
@@ -4,7 +4,7 @@
4
4
  * Auto-generated from SVG files in src/icons/
5
5
  * DO NOT EDIT MANUALLY - Run "npm run icons:generate" to regenerate
6
6
  *
7
- * Generated: 2026-04-15T11:47:37.104Z
7
+ * Generated: 2026-04-20T20:41:14.535Z
8
8
  */
9
9
  export declare const iconRegistry: Record<string, {
10
10
  path: string;
@@ -1,4 +1,19 @@
1
1
  import React from 'react';
2
+ /**
3
+ * A shared, frozen empty modes object.
4
+ *
5
+ * Components that accept a `modes` prop should use this as the default value
6
+ * instead of the inline `{}` literal. The literal allocates a new object on
7
+ * every render, which:
8
+ * 1. Forces `React.memo` shallow comparisons to fail.
9
+ * 2. Forces `useMemo`/`useEffect` deps that include `modes` to re-run.
10
+ * 3. Forces the design-token resolver to re-serialize the modes object on
11
+ * every call (see `serializeModes` in `figma-variables-resolver.ts`).
12
+ *
13
+ * Sharing a single frozen object across the tree makes all of those checks
14
+ * O(1) identity comparisons in the common "no modes provided" path.
15
+ */
16
+ export declare const EMPTY_MODES: Readonly<Record<string, any>>;
2
17
  /**
3
18
  * Helper function to recursively clone children and pass modes prop to components that accept it.
4
19
  * This ensures that all child components in slots receive the modes prop from the parent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfs-components",
3
- "version": "0.0.62",
3
+ "version": "0.0.64",
4
4
  "description": "React Native Jio Finance Components Library",
5
5
  "author": "sunshuaiqi@gmail.com",
6
6
  "license": "MIT",
@@ -13,6 +13,7 @@
13
13
  "files": [
14
14
  "src",
15
15
  "lib",
16
+ "CHANGELOG.md",
16
17
  "!**/__tests__",
17
18
  "!**/*.stories.*",
18
19
  "!**/test-setup.*",
@@ -25,13 +26,8 @@
25
26
  "!**/.token-metadata.json"
26
27
  ],
27
28
  "scripts": {
28
- "android": "yarn run prestorybook && react-native run-android",
29
- "ios": "yarn run prestorybook && react-native run-ios",
30
- "start": "react-native start",
31
29
  "test": "jest",
32
30
  "lint": "eslint .",
33
- "prestorybook": "rnstl",
34
- "storybook": "echo 'React Native Storybook is embedded in the app. Run: yarn ios or yarn android'",
35
31
  "build-react": "webpack --mode production",
36
32
  "start-react": "webpack-dev-server --config ./webpack.config.js --mode development",
37
33
  "extract-tokens": "node scripts/extract-component-tokens.js",
@@ -40,6 +36,8 @@
40
36
  "storybook-web": "storybook dev -p 6006",
41
37
  "build:storybook-web": "storybook build",
42
38
  "deploy:storybook": "vercel --prod",
39
+ "example": "yarn --cwd example start",
40
+ "example:install": "yarn --cwd example install",
43
41
  "postinstall": "patch-package",
44
42
  "icons:generate": "node scripts/generate-icon-registry.js",
45
43
  "prepare": "bob build",
@@ -14,7 +14,7 @@ import {
14
14
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
15
15
  import Icon from '../../icons/Icon'
16
16
  import { usePressableWebSupport, type WebAccessibilityProps } from '../../utils/web-platform-utils'
17
- import { cloneChildrenWithModes } from '../../utils/react-utils'
17
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
18
18
 
19
19
  // Enable LayoutAnimation on Android
20
20
  if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
@@ -81,7 +81,7 @@ function Accordion({
81
81
  onExpandedChange,
82
82
  disabled = false,
83
83
  children,
84
- modes = {},
84
+ modes = EMPTY_MODES,
85
85
  style,
86
86
  accessibilityLabel,
87
87
  accessibilityHint,
@@ -6,7 +6,7 @@ import {
6
6
  Platform,
7
7
  } from 'react-native'
8
8
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
9
- import { cloneChildrenWithModes, flattenChildren } from '../../utils/react-utils'
9
+ import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren } from '../../utils/react-utils'
10
10
  import IconButton from '../IconButton/IconButton'
11
11
 
12
12
  export type ActionFooterProps = {
@@ -59,7 +59,7 @@ export type ActionFooterProps = {
59
59
  */
60
60
  function ActionFooter({
61
61
  children,
62
- modes = {},
62
+ modes = EMPTY_MODES,
63
63
  style,
64
64
  accessibilityLabel = undefined,
65
65
  }: ActionFooterProps) {
@@ -3,6 +3,7 @@ import { View, Text, type ViewStyle, type TextStyle, TouchableOpacity } from 're
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
  import IconCapsule from '../IconCapsule/IconCapsule'
6
+ import { EMPTY_MODES } from '../../utils/react-utils'
6
7
 
7
8
  export type ActionTileProps = {
8
9
  /** Label text, e.g. "Cards" */
@@ -30,7 +31,7 @@ export type ActionTileProps = {
30
31
  export default function ActionTile({
31
32
  label = 'Cards',
32
33
  icon,
33
- modes: propModes = {},
34
+ modes: propModes = EMPTY_MODES,
34
35
  style,
35
36
  onPress,
36
37
  }: ActionTileProps) {
@@ -4,6 +4,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
  import MoneyValue from '../MoneyValue/MoneyValue'
6
6
  import NoteInput from '../NoteInput/NoteInput'
7
+ import { EMPTY_MODES } from '../../utils/react-utils'
7
8
 
8
9
  export type AmountInputProps = {
9
10
  /**
@@ -28,7 +29,7 @@ export type AmountInputProps = {
28
29
  export default function AmountInput({
29
30
  moneyValueSlot,
30
31
  noteInputSlot,
31
- modes: propModes = {},
32
+ modes: propModes = EMPTY_MODES,
32
33
  style,
33
34
  }: AmountInputProps) {
34
35
  const { modes: globalModes } = useTokens()
@@ -4,7 +4,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
 
6
6
  import NavArrow from '../NavArrow/NavArrow'
7
- import { cloneChildrenWithModes } from '../../utils/react-utils'
7
+ import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils'
8
8
 
9
9
  type AppBarType = 'MainPage' | 'SubPage'
10
10
 
@@ -53,7 +53,7 @@ export default function AppBar({
53
53
  leadingSlot,
54
54
  middleSlot,
55
55
  actionsSlot,
56
- modes: propModes = {},
56
+ modes: propModes = EMPTY_MODES,
57
57
  onLeadingPress,
58
58
  style,
59
59
  accessibilityLabel,