jfs-components 0.0.73 → 0.0.77

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 (134) hide show
  1. package/CHANGELOG.md +115 -6
  2. package/lib/commonjs/components/AccountCard/AccountCard.js +247 -0
  3. package/lib/commonjs/components/ActionFooter/ActionFooter.js +147 -82
  4. package/lib/commonjs/components/AppBar/AppBar.js +17 -11
  5. package/lib/commonjs/components/Avatar/Avatar.js +20 -0
  6. package/lib/commonjs/components/Badge/Badge.js +23 -0
  7. package/lib/commonjs/components/Button/Button.js +37 -0
  8. package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +18 -2
  9. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +40 -25
  10. package/lib/commonjs/components/Dropdown/Dropdown.js +214 -0
  11. package/lib/commonjs/components/DropdownInput/DropdownInput.js +542 -0
  12. package/lib/commonjs/components/FormField/FormField.js +328 -178
  13. package/lib/commonjs/components/IconButton/IconButton.js +20 -0
  14. package/lib/commonjs/components/Image/Image.js +26 -1
  15. package/lib/commonjs/components/LottieIntroBlock/LottieIntroBlock.js +150 -0
  16. package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
  17. package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
  18. package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
  19. package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
  20. package/lib/commonjs/components/PageHero/PageHero.js +189 -0
  21. package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +135 -0
  22. package/lib/commonjs/components/PoweredByLabel/finvu.png +0 -0
  23. package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
  24. package/lib/commonjs/components/Text/Text.js +40 -3
  25. package/lib/commonjs/components/Tooltip/Tooltip.js +34 -27
  26. package/lib/commonjs/components/index.js +67 -0
  27. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  28. package/lib/commonjs/icons/Icon.js +16 -0
  29. package/lib/commonjs/icons/registry.js +1 -1
  30. package/lib/commonjs/index.js +12 -0
  31. package/lib/commonjs/skeleton/Skeleton.js +234 -0
  32. package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
  33. package/lib/commonjs/skeleton/index.js +58 -0
  34. package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
  35. package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
  36. package/lib/module/components/AccountCard/AccountCard.js +241 -0
  37. package/lib/module/components/ActionFooter/ActionFooter.js +146 -82
  38. package/lib/module/components/AppBar/AppBar.js +17 -11
  39. package/lib/module/components/Avatar/Avatar.js +19 -0
  40. package/lib/module/components/Badge/Badge.js +23 -0
  41. package/lib/module/components/Button/Button.js +37 -0
  42. package/lib/module/components/CardBankAccount/CardBankAccount.js +17 -2
  43. package/lib/module/components/CheckboxItem/CheckboxItem.js +41 -26
  44. package/lib/module/components/Dropdown/Dropdown.js +206 -0
  45. package/lib/module/components/DropdownInput/DropdownInput.js +536 -0
  46. package/lib/module/components/FormField/FormField.js +330 -180
  47. package/lib/module/components/IconButton/IconButton.js +20 -0
  48. package/lib/module/components/Image/Image.js +25 -1
  49. package/lib/module/components/LottieIntroBlock/LottieIntroBlock.js +144 -0
  50. package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
  51. package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
  52. package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
  53. package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
  54. package/lib/module/components/PageHero/PageHero.js +183 -0
  55. package/lib/module/components/PoweredByLabel/PoweredByLabel.js +130 -0
  56. package/lib/module/components/PoweredByLabel/finvu.png +0 -0
  57. package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
  58. package/lib/module/components/Text/Text.js +40 -3
  59. package/lib/module/components/Tooltip/Tooltip.js +34 -27
  60. package/lib/module/components/index.js +8 -1
  61. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  62. package/lib/module/icons/Icon.js +16 -0
  63. package/lib/module/icons/registry.js +1 -1
  64. package/lib/module/index.js +2 -1
  65. package/lib/module/skeleton/Skeleton.js +229 -0
  66. package/lib/module/skeleton/SkeletonGroup.js +133 -0
  67. package/lib/module/skeleton/index.js +6 -0
  68. package/lib/module/skeleton/shimmer-tokens.js +181 -0
  69. package/lib/module/skeleton/useReducedMotion.js +61 -0
  70. package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +81 -0
  71. package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
  72. package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
  73. package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
  74. package/lib/typescript/src/components/Button/Button.d.ts +8 -1
  75. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +9 -2
  76. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +18 -2
  77. package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +62 -0
  78. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +107 -0
  79. package/lib/typescript/src/components/FormField/FormField.d.ts +76 -19
  80. package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
  81. package/lib/typescript/src/components/Image/Image.d.ts +8 -1
  82. package/lib/typescript/src/components/LottieIntroBlock/LottieIntroBlock.d.ts +58 -0
  83. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
  84. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
  85. package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
  86. package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
  87. package/lib/typescript/src/components/PageHero/PageHero.d.ts +79 -0
  88. package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +70 -0
  89. package/lib/typescript/src/components/Text/Text.d.ts +31 -2
  90. package/lib/typescript/src/components/Tooltip/Tooltip.d.ts +13 -2
  91. package/lib/typescript/src/components/index.d.ts +8 -1
  92. package/lib/typescript/src/icons/Icon.d.ts +7 -1
  93. package/lib/typescript/src/icons/registry.d.ts +1 -1
  94. package/lib/typescript/src/index.d.ts +1 -0
  95. package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
  96. package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
  97. package/lib/typescript/src/skeleton/index.d.ts +5 -0
  98. package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
  99. package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
  100. package/package.json +11 -3
  101. package/src/components/AccountCard/AccountCard.tsx +376 -0
  102. package/src/components/ActionFooter/ActionFooter.tsx +152 -86
  103. package/src/components/AppBar/AppBar.tsx +25 -14
  104. package/src/components/Avatar/Avatar.tsx +26 -0
  105. package/src/components/Badge/Badge.tsx +27 -0
  106. package/src/components/Button/Button.tsx +40 -0
  107. package/src/components/CardBankAccount/CardBankAccount.tsx +29 -3
  108. package/src/components/CheckboxItem/CheckboxItem.tsx +65 -30
  109. package/src/components/Dropdown/Dropdown.tsx +331 -0
  110. package/src/components/DropdownInput/DropdownInput.tsx +819 -0
  111. package/src/components/FormField/FormField.tsx +542 -215
  112. package/src/components/IconButton/IconButton.tsx +27 -0
  113. package/src/components/Image/Image.tsx +25 -0
  114. package/src/components/LottieIntroBlock/LottieIntroBlock.tsx +202 -0
  115. package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
  116. package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
  117. package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
  118. package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
  119. package/src/components/PageHero/PageHero.tsx +257 -0
  120. package/src/components/PoweredByLabel/PoweredByLabel.tsx +221 -0
  121. package/src/components/PoweredByLabel/finvu.png +0 -0
  122. package/src/components/RechargeCard/RechargeCard.tsx +32 -24
  123. package/src/components/Text/Text.tsx +78 -3
  124. package/src/components/Tooltip/Tooltip.tsx +50 -25
  125. package/src/components/index.ts +16 -1
  126. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  127. package/src/icons/Icon.tsx +17 -0
  128. package/src/icons/registry.ts +1 -1
  129. package/src/index.ts +1 -0
  130. package/src/skeleton/Skeleton.tsx +298 -0
  131. package/src/skeleton/SkeletonGroup.tsx +193 -0
  132. package/src/skeleton/index.ts +10 -0
  133. package/src/skeleton/shimmer-tokens.ts +221 -0
  134. package/src/skeleton/useReducedMotion.ts +72 -0
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _Button = _interopRequireDefault(require("../Button/Button"));
12
+ var _reactUtils = require("../../utils/react-utils");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
16
+ const DEFAULT_MEDIA_SIZE = 117;
17
+ /**
18
+ * LottieIntroBlock displays a centered onboarding/intro block composed of a
19
+ * media slot (typically a Lottie animation or illustration) above a title,
20
+ * an optional supportive paragraph, and an optional action button.
21
+ *
22
+ * All visual values are resolved from Figma design tokens via
23
+ * `getVariableByName`. Slots cascade the active `modes` to their children
24
+ * through `cloneChildrenWithModes`.
25
+ *
26
+ * @component
27
+ * @example
28
+ * ```tsx
29
+ * <LottieIntroBlock
30
+ * title="Let's get to know how your financial health is doing"
31
+ * supportText="From assets to taxes, stay on top of everything in one simple view."
32
+ * buttonLabel="Get started"
33
+ * onButtonPress={() => navigate('NextScreen')}
34
+ * media={<MyLottiePlayer source={animationSource} />}
35
+ * />
36
+ * ```
37
+ */
38
+ function LottieIntroBlock({
39
+ title = "Let's get to know how your financial health is doing",
40
+ showSupportText = true,
41
+ supportText = 'From assets to taxes, stay on top of everything in one simple view.',
42
+ showButton = true,
43
+ buttonLabel = 'Button',
44
+ onButtonPress,
45
+ media,
46
+ buttonSlot,
47
+ modes: propModes = _reactUtils.EMPTY_MODES,
48
+ style,
49
+ testID
50
+ }) {
51
+ const {
52
+ modes: globalModes
53
+ } = (0, _JFSThemeProvider.useTokens)();
54
+ const modes = (0, _react.useMemo)(() => ({
55
+ ...globalModes,
56
+ ...propModes
57
+ }), [globalModes, propModes]);
58
+
59
+ // Container
60
+ const gap = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/gap', modes)) || 36;
61
+ const paddingHorizontal = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/padding/horizontal', modes)) || 0;
62
+ const paddingVertical = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/padding/vertical', modes)) || 16;
63
+
64
+ // Text wrap
65
+ const textWrapGap = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/textWrap/gap', modes)) || 16;
66
+
67
+ // Title
68
+ const titleColor = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/title/foreground', modes) || '#0d0d0f';
69
+ const titleFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/title/fontSize', modes)) || 23;
70
+ const titleFontFamily = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/title/fontFamily', modes) || 'System';
71
+ const titleLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/title/lineHeight', modes)) || 23;
72
+ const titleFontWeight = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/title/fontWeight', modes) || 900;
73
+
74
+ // Support text
75
+ const supportColor = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/supportText/foreground', modes) || '#0d0d0f';
76
+ const supportFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/supportText/fontSize', modes)) || 14;
77
+ const supportFontFamily = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/supportText/fontFamily', modes) || 'System';
78
+ const supportLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/supportText/lineHeight', modes)) || 18;
79
+ const supportFontWeight = (0, _figmaVariablesResolver.getVariableByName)('lottieIntroBlock/supportText/fontWeight', modes) || 400;
80
+ const containerStyle = {
81
+ flexDirection: 'column',
82
+ alignItems: 'center',
83
+ paddingHorizontal,
84
+ paddingVertical,
85
+ gap
86
+ };
87
+ const textWrapStyle = {
88
+ flexDirection: 'column',
89
+ alignItems: 'center',
90
+ gap: textWrapGap,
91
+ width: '100%'
92
+ };
93
+ const titleStyle = {
94
+ color: titleColor,
95
+ fontSize: titleFontSize,
96
+ fontFamily: titleFontFamily,
97
+ lineHeight: titleLineHeight,
98
+ fontWeight: String(titleFontWeight),
99
+ textAlign: 'center'
100
+ };
101
+ const supportTextStyle = {
102
+ color: supportColor,
103
+ fontSize: supportFontSize,
104
+ fontFamily: supportFontFamily,
105
+ lineHeight: supportLineHeight,
106
+ fontWeight: String(supportFontWeight),
107
+ textAlign: 'center'
108
+ };
109
+ const mediaContent = (0, _react.useMemo)(() => {
110
+ if (media === undefined || media === null) {
111
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
112
+ style: {
113
+ width: DEFAULT_MEDIA_SIZE,
114
+ height: DEFAULT_MEDIA_SIZE
115
+ },
116
+ accessibilityElementsHidden: true,
117
+ importantForAccessibility: "no-hide-descendants"
118
+ });
119
+ }
120
+ return (0, _reactUtils.cloneChildrenWithModes)(media, modes);
121
+ }, [media, modes]);
122
+ const buttonContent = (0, _react.useMemo)(() => {
123
+ if (buttonSlot !== undefined && buttonSlot !== null) {
124
+ return (0, _reactUtils.cloneChildrenWithModes)(buttonSlot, modes);
125
+ }
126
+ if (!showButton) {
127
+ return null;
128
+ }
129
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
130
+ label: buttonLabel,
131
+ onPress: onButtonPress,
132
+ modes: modes
133
+ });
134
+ }, [buttonSlot, showButton, buttonLabel, onButtonPress, modes]);
135
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
136
+ style: [containerStyle, style],
137
+ testID: testID,
138
+ children: [mediaContent, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
139
+ style: textWrapStyle,
140
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
141
+ style: titleStyle,
142
+ children: title
143
+ }), showSupportText && supportText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
144
+ style: supportTextStyle,
145
+ children: supportText
146
+ }) : null, buttonContent]
147
+ })]
148
+ });
149
+ }
150
+ var _default = exports.default = LottieIntroBlock;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _reactUtils = require("../../utils/react-utils");
12
+ var _loadNativeLottieView = require("./loadNativeLottieView");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
+ /**
16
+ * A parsed Lottie animation. The JSON object you get from
17
+ * `require('./animation.json')` or `fetch().then(r => r.json())`. We keep the
18
+ * type intentionally loose because both `lottie-react-native` and `lottie-react`
19
+ * accept slightly different shapes — `LottiePlayer` narrows back to the
20
+ * platform-specific type internally.
21
+ */
22
+
23
+ const DEFAULT_SIZE = 117;
24
+ function resolveSize(size, modes) {
25
+ if (typeof size === 'number') return {
26
+ width: size,
27
+ height: size
28
+ };
29
+ if (size && typeof size === 'object') return size;
30
+ const width = Number((0, _figmaVariablesResolver.getVariableByName)('media/width', modes)) || DEFAULT_SIZE;
31
+ const height = Number((0, _figmaVariablesResolver.getVariableByName)('media/height', modes)) || DEFAULT_SIZE;
32
+ return {
33
+ width,
34
+ height
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Renders a Lottie animation using the consumer's installed
40
+ * `lottie-react-native` (native) or `lottie-react` (web) — both are declared
41
+ * as **optional peer dependencies** of `jfs-components`, so installing the
42
+ * library does not pull them in. Add the relevant package to your app only
43
+ * if you actually use `LottiePlayer`:
44
+ *
45
+ * ```sh
46
+ * # React Native (iOS / Android)
47
+ * npm install lottie-react-native
48
+ * cd ios && pod install
49
+ *
50
+ * # Web (or react-native-web)
51
+ * npm install lottie-react
52
+ * ```
53
+ *
54
+ * The web build (`LottiePlayer.web.tsx`) is picked automatically by Metro /
55
+ * webpack via platform extensions — same pattern as `MediaCard/GlassFill`.
56
+ *
57
+ * Token-driven sizing: when `size` is omitted, `LottiePlayer` reads
58
+ * `media/width` and `media/height` from the Figma variables resolver, so the
59
+ * animation matches the surrounding component's `Media / Output` mode
60
+ * automatically. This is the same sizing contract `PageHero` and
61
+ * `LottieIntroBlock` use for their `media` slots.
62
+ *
63
+ * @component
64
+ * @example
65
+ * ```tsx
66
+ * import animation from './assets/loader.json';
67
+ *
68
+ * <LottiePlayer source={animation} /> // 117 × 117 (default)
69
+ * <LottiePlayer source={animation} size={70} /> // 70 × 70
70
+ * <LottiePlayer source={animation} modes={{ 'Media / Output': 'S' }} /> // 20 × 20
71
+ * <PageHero media={<LottiePlayer source={animation} />} />
72
+ * ```
73
+ */
74
+ function LottiePlayer({
75
+ source,
76
+ size,
77
+ autoPlay = true,
78
+ loop = true,
79
+ modes: propModes = _reactUtils.EMPTY_MODES,
80
+ style,
81
+ accessibilityLabel,
82
+ testID
83
+ }) {
84
+ const {
85
+ modes: globalModes
86
+ } = (0, _JFSThemeProvider.useTokens)();
87
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
88
+ ...globalModes,
89
+ ...propModes
90
+ }, [globalModes, propModes]);
91
+ const {
92
+ width,
93
+ height
94
+ } = (0, _react.useMemo)(() => resolveSize(size, modes), [size, modes]);
95
+ const NativeLottieView = (0, _react.useMemo)(() => (0, _loadNativeLottieView.getNativeLottieView)(), []);
96
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
97
+ style: [{
98
+ width,
99
+ height
100
+ }, style],
101
+ testID: testID,
102
+ accessibilityLabel: accessibilityLabel,
103
+ accessibilityElementsHidden: accessibilityLabel ? undefined : true,
104
+ importantForAccessibility: accessibilityLabel ? 'auto' : 'no',
105
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(NativeLottieView, {
106
+ source: source,
107
+ autoPlay: autoPlay,
108
+ loop: loop,
109
+ style: {
110
+ width: '100%',
111
+ height: '100%'
112
+ }
113
+ })
114
+ });
115
+ }
116
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(LottiePlayer);
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
9
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
10
+ var _reactUtils = require("../../utils/react-utils");
11
+ var _loadWebLottieView = require("./loadWebLottieView");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ const DEFAULT_SIZE = 117;
15
+ function resolveSize(size, modes) {
16
+ if (typeof size === 'number') return {
17
+ width: size,
18
+ height: size
19
+ };
20
+ if (size && typeof size === 'object') return size;
21
+ const width = Number((0, _figmaVariablesResolver.getVariableByName)('media/width', modes)) || DEFAULT_SIZE;
22
+ const height = Number((0, _figmaVariablesResolver.getVariableByName)('media/height', modes)) || DEFAULT_SIZE;
23
+ return {
24
+ width,
25
+ height
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Web build of `LottiePlayer` — picked automatically by webpack /
31
+ * Metro-for-web via the `.web.tsx` platform extension. Uses `lottie-react`
32
+ * (which wraps `lottie-web`) and renders a plain DOM container.
33
+ *
34
+ * Public API mirrors `LottiePlayer.tsx` (native). See that file for the
35
+ * documented prop reference and usage patterns.
36
+ */
37
+ function LottiePlayer({
38
+ source,
39
+ size,
40
+ autoPlay = true,
41
+ loop = true,
42
+ modes: propModes = _reactUtils.EMPTY_MODES,
43
+ style,
44
+ accessibilityLabel,
45
+ testID
46
+ }) {
47
+ const {
48
+ modes: globalModes
49
+ } = (0, _JFSThemeProvider.useTokens)();
50
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
51
+ ...globalModes,
52
+ ...propModes
53
+ }, [globalModes, propModes]);
54
+ const {
55
+ width,
56
+ height
57
+ } = (0, _react.useMemo)(() => resolveSize(size, modes), [size, modes]);
58
+ const WebLottieView = (0, _react.useMemo)(() => (0, _loadWebLottieView.getWebLottieView)(), []);
59
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
60
+ style: {
61
+ width,
62
+ height,
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ justifyContent: 'center',
66
+ ...style
67
+ },
68
+ "data-testid": testID,
69
+ "aria-label": accessibilityLabel,
70
+ "aria-hidden": accessibilityLabel ? undefined : true,
71
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(WebLottieView, {
72
+ animationData: source,
73
+ autoplay: autoPlay,
74
+ loop: loop,
75
+ style: {
76
+ width: '100%',
77
+ height: '100%'
78
+ }
79
+ })
80
+ });
81
+ }
82
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(LottiePlayer);
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getNativeLottieView = getNativeLottieView;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /** Props we forward to the underlying native Lottie view. */
12
+
13
+ const INSTALL_HINT = 'LottiePlayer requires lottie-react-native in your app.\n' + ' npm install lottie-react-native\n' + ' cd ios && pod install';
14
+
15
+ /**
16
+ * Metro resolves `require('lottie-react-native')` at bundle time even inside
17
+ * try/catch, which breaks apps that import `jfs-components` without having
18
+ * the optional peer installed. Splitting the module id into a runtime string
19
+ * keeps Metro from statically linking it — the native module is loaded only
20
+ * when present in the consumer's node_modules.
21
+ */
22
+ function resolveNativeLottieModuleName() {
23
+ return ['lottie', '-react', '-native'].join('');
24
+ }
25
+ function LottieUnavailableView({
26
+ style
27
+ }) {
28
+ if (__DEV__) {
29
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
30
+ style: [style, {
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ backgroundColor: 'rgba(255, 196, 0, 0.12)',
34
+ borderWidth: 1,
35
+ borderColor: 'rgba(255, 196, 0, 0.45)',
36
+ borderRadius: 8,
37
+ padding: 8
38
+ }],
39
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
40
+ style: {
41
+ color: '#8a6d00',
42
+ fontSize: 11,
43
+ textAlign: 'center',
44
+ lineHeight: 15
45
+ },
46
+ children: INSTALL_HINT
47
+ })
48
+ });
49
+ }
50
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
51
+ style: style
52
+ });
53
+ }
54
+ function LottieUnavailable(props) {
55
+ _react.default.useEffect(() => {
56
+ if (__DEV__) {
57
+ console.warn(`[jfs-components/LottiePlayer] ${INSTALL_HINT}`);
58
+ }
59
+ }, []);
60
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(LottieUnavailableView, {
61
+ style: props.style
62
+ });
63
+ }
64
+ let cachedView;
65
+ function getNativeLottieView() {
66
+ if (cachedView !== undefined) return cachedView;
67
+ try {
68
+ const mod = require(resolveNativeLottieModuleName());
69
+ cachedView = mod.default ?? LottieUnavailable;
70
+ } catch {
71
+ cachedView = LottieUnavailable;
72
+ }
73
+ return cachedView;
74
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getWebLottieView = getWebLottieView;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ /** Props we forward to the underlying web Lottie view. */
11
+
12
+ const INSTALL_HINT = 'LottiePlayer requires lottie-react in your app.\n' + ' npm install lottie-react';
13
+ function resolveWebLottieModuleName() {
14
+ return ['lottie', '-react'].join('');
15
+ }
16
+ function LottieUnavailable(props) {
17
+ _react.default.useEffect(() => {
18
+ if (typeof __DEV__ !== 'undefined' && __DEV__) {
19
+ console.warn(`[jfs-components/LottiePlayer] ${INSTALL_HINT}`);
20
+ }
21
+ }, []);
22
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
23
+ style: {
24
+ ...props.style,
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ justifyContent: 'center',
28
+ backgroundColor: 'rgba(255, 196, 0, 0.12)',
29
+ border: '1px solid rgba(255, 196, 0, 0.45)',
30
+ borderRadius: 8,
31
+ padding: 8,
32
+ color: '#8a6d00',
33
+ fontSize: 11,
34
+ textAlign: 'center',
35
+ lineHeight: '15px'
36
+ },
37
+ children: typeof __DEV__ !== 'undefined' && __DEV__ ? INSTALL_HINT : null
38
+ });
39
+ }
40
+ let cachedView;
41
+ function getWebLottieView() {
42
+ if (cachedView !== undefined) return cachedView;
43
+ try {
44
+ const mod = require(resolveWebLottieModuleName());
45
+ cachedView = mod.default ?? LottieUnavailable;
46
+ } catch {
47
+ cachedView = LottieUnavailable;
48
+ }
49
+ return cachedView;
50
+ }
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _Button = _interopRequireDefault(require("../Button/Button"));
12
+ var _reactUtils = require("../../utils/react-utils");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
16
+ /**
17
+ * PageHero displays a centered hero block typically used at the top of a page
18
+ * or feature screen. It contains an optional media slot (illustration / image
19
+ * / Lottie / SVG / video — consumer's choice), an eyebrow line, a large
20
+ * headline, an optional supporting line (e.g. price / timeline), and an
21
+ * optional action button.
22
+ *
23
+ * All visual values are resolved from Figma design tokens via
24
+ * `getVariableByName`. Slots cascade the active `modes` to their children
25
+ * through `cloneChildrenWithModes`.
26
+ *
27
+ * @component
28
+ * @example
29
+ * ```tsx
30
+ * <PageHero
31
+ * eyebrow="Upgrade to JioFinance+"
32
+ * headline="Resume earning cashback, extra points, and 1% gold"
33
+ * supportingText="₹999/year · ₹0 until 2027"
34
+ * buttonLabel="Renew for free"
35
+ * onButtonPress={() => navigate('Upgrade')}
36
+ * media={
37
+ * <Image
38
+ * imageSource={require('./assets/upgrade.png')}
39
+ * width={117}
40
+ * height={117}
41
+ * />
42
+ * }
43
+ * />
44
+ * ```
45
+ */
46
+ function PageHero({
47
+ eyebrow = 'Upgrade to JioFinance+',
48
+ headline = 'Resume earning cashback, extra points, and 1% gold',
49
+ supportingText = '₹999/year · ₹0 until 2027',
50
+ showSupportingText = true,
51
+ buttonLabel = 'Renew for free',
52
+ onButtonPress,
53
+ showButton = true,
54
+ buttonSlot,
55
+ media,
56
+ modes: propModes = _reactUtils.EMPTY_MODES,
57
+ style,
58
+ testID
59
+ }) {
60
+ const {
61
+ modes: globalModes
62
+ } = (0, _JFSThemeProvider.useTokens)();
63
+ const modes = (0, _react.useMemo)(() => ({
64
+ ...globalModes,
65
+ ...propModes
66
+ }), [globalModes, propModes]);
67
+ const gap = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/gap', modes)) || 16;
68
+ const paddingHorizontal = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/padding/horizontal', modes)) || 0;
69
+ const textWrapGap = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/textWrap/gap', modes)) || 8;
70
+
71
+ // Media slot box — matches the 117×117 frame in Figma (node 4540:7845).
72
+ // Tokens fall back to 117 when not defined in the variables collection,
73
+ // so the layout stays stable on consumers that haven't tokenized this yet.
74
+ const mediaWidth = Number((0, _figmaVariablesResolver.getVariableByName)('media/width', modes)) || 117;
75
+ const mediaHeight = Number((0, _figmaVariablesResolver.getVariableByName)('media/height', modes)) || 117;
76
+ const eyebrowColor = (0, _figmaVariablesResolver.getVariableByName)('PageHero/eyebrow/color', modes) || '#ffffff';
77
+ const eyebrowFontFamily = (0, _figmaVariablesResolver.getVariableByName)('PageHero/eyebrow/fontFamily', modes) || 'System';
78
+ const eyebrowFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/eyebrow/fontSize', modes)) || 18;
79
+ const eyebrowFontWeight = (0, _figmaVariablesResolver.getVariableByName)('PageHero/eyebrow/fontWeight', modes) || 700;
80
+ const eyebrowLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/eyebrow/lineHeight', modes)) || 20;
81
+ const headlineColor = (0, _figmaVariablesResolver.getVariableByName)('PageHero/headline/color', modes) || '#ffffff';
82
+ const headlineFontFamily = (0, _figmaVariablesResolver.getVariableByName)('PageHero/headline/fontFamily', modes) || 'System';
83
+ const headlineFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/headline/fontSize', modes)) || 29;
84
+ const headlineFontWeight = (0, _figmaVariablesResolver.getVariableByName)('PageHero/headline/fontWeight', modes) || 900;
85
+ const headlineLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/headline/lineHeight', modes)) || 29;
86
+
87
+ // Only `lineHeight` is tokenized for the supporting text in the Figma source.
88
+ // Color, font size and weight are inline literals in the design (12px medium
89
+ // white) — we mirror that here so the visual stays faithful when no token
90
+ // exists.
91
+ const supportingTextLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('PageHero/supportingText/lineHeight', modes)) || 16;
92
+ const containerStyle = {
93
+ flexDirection: 'column',
94
+ alignItems: 'center',
95
+ paddingHorizontal,
96
+ gap,
97
+ width: '100%'
98
+ };
99
+ const textWrapStyle = {
100
+ flexDirection: 'column',
101
+ alignItems: 'center',
102
+ gap: textWrapGap,
103
+ width: '100%'
104
+ };
105
+ const eyebrowStyle = {
106
+ color: eyebrowColor,
107
+ fontFamily: eyebrowFontFamily,
108
+ fontSize: eyebrowFontSize,
109
+ fontWeight: String(eyebrowFontWeight),
110
+ lineHeight: eyebrowLineHeight,
111
+ textAlign: 'center'
112
+ };
113
+ const headlineStyle = {
114
+ color: headlineColor,
115
+ fontFamily: headlineFontFamily,
116
+ fontSize: headlineFontSize,
117
+ fontWeight: String(headlineFontWeight),
118
+ lineHeight: headlineLineHeight,
119
+ textAlign: 'center',
120
+ width: '100%'
121
+ };
122
+ const supportingTextStyle = {
123
+ color: '#ffffff',
124
+ fontFamily: 'System',
125
+ fontSize: 12,
126
+ fontWeight: '500',
127
+ lineHeight: supportingTextLineHeight,
128
+ textAlign: 'center'
129
+ };
130
+ const buttonWrapStyle = {
131
+ width: '100%'
132
+ };
133
+ const buttonContent = (0, _react.useMemo)(() => {
134
+ if (buttonSlot !== undefined && buttonSlot !== null) {
135
+ return (0, _reactUtils.cloneChildrenWithModes)(buttonSlot, modes);
136
+ }
137
+ if (!showButton) {
138
+ return null;
139
+ }
140
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
141
+ label: buttonLabel,
142
+ onPress: onButtonPress,
143
+ modes: modes,
144
+ style: buttonWrapStyle
145
+ });
146
+ // buttonWrapStyle is a literal object created above; it is intentionally
147
+ // omitted from deps because its identity changes on every render but its
148
+ // shape never does.
149
+ // eslint-disable-next-line react-hooks/exhaustive-deps
150
+ }, [buttonSlot, showButton, buttonLabel, onButtonPress, modes]);
151
+
152
+ // Sized container for the media slot. Always rendered when `media` is
153
+ // provided, so the slot has a predictable box (matches Figma frame
154
+ // 4540:7845 — 117×117 by default) even if the inner element omits its
155
+ // own width/height. `overflow: 'hidden'` mirrors the Figma frame's
156
+ // `clipsContent` so a slightly oversized illustration doesn't break
157
+ // the centered layout.
158
+ const mediaContent = (0, _react.useMemo)(() => {
159
+ if (media === undefined || media === null) return null;
160
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
161
+ style: {
162
+ width: mediaWidth,
163
+ height: mediaHeight,
164
+ alignItems: 'center',
165
+ justifyContent: 'center',
166
+ overflow: 'hidden'
167
+ },
168
+ children: (0, _reactUtils.cloneChildrenWithModes)(media, modes)
169
+ });
170
+ }, [media, mediaWidth, mediaHeight, modes]);
171
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
172
+ style: [containerStyle, style],
173
+ testID: testID,
174
+ children: [mediaContent, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
175
+ style: textWrapStyle,
176
+ children: [eyebrow ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
177
+ style: eyebrowStyle,
178
+ children: eyebrow
179
+ }) : null, headline ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
180
+ style: headlineStyle,
181
+ children: headline
182
+ }) : null]
183
+ }), showSupportingText && supportingText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
184
+ style: supportingTextStyle,
185
+ children: supportingText
186
+ }) : null, buttonContent]
187
+ });
188
+ }
189
+ var _default = exports.default = PageHero;