jfs-components 0.0.44 → 0.0.45
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.
- package/lib/commonjs/components/AmountInput/AmountInput.js +82 -0
- package/lib/commonjs/components/AmountInput/index.js +13 -0
- package/lib/commonjs/components/Button/Button.js +31 -28
- package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +76 -0
- package/lib/commonjs/components/EmptyState/EmptyState.js +2 -1
- package/lib/commonjs/components/OTP/OTP.js +242 -0
- package/lib/commonjs/components/PortfolioHero/PortfolioHero.js +78 -0
- package/lib/commonjs/components/ProductLabel/ProductLabel.js +50 -0
- package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +130 -0
- package/lib/commonjs/components/ProgressBadge/index.js +25 -0
- package/lib/commonjs/components/StatItem/StatItem.js +61 -0
- package/lib/commonjs/components/SwappableAmount/SwappableAmount.js +71 -0
- package/lib/commonjs/components/Text/Text.js +38 -0
- package/lib/commonjs/components/Toggle/Toggle.js +102 -0
- package/lib/commonjs/components/index.js +63 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -0
- package/lib/commonjs/design-tokens/figma-variables-resolver.js +1 -1
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/module/components/AmountInput/AmountInput.js +77 -0
- package/lib/module/components/AmountInput/index.js +3 -0
- package/lib/module/components/Button/Button.js +31 -28
- package/lib/module/components/CardProviderInfo/CardProviderInfo.js +71 -0
- package/lib/module/components/EmptyState/EmptyState.js +2 -1
- package/lib/module/components/OTP/OTP.js +236 -0
- package/lib/module/components/PortfolioHero/PortfolioHero.js +73 -0
- package/lib/module/components/ProductLabel/ProductLabel.js +45 -0
- package/lib/module/components/ProgressBadge/ProgressBadge.js +125 -0
- package/lib/module/components/ProgressBadge/index.js +4 -0
- package/lib/module/components/StatItem/StatItem.js +56 -0
- package/lib/module/components/SwappableAmount/SwappableAmount.js +66 -0
- package/lib/module/components/Text/Text.js +33 -0
- package/lib/module/components/Toggle/Toggle.js +97 -0
- package/lib/module/components/index.js +10 -1
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -0
- package/lib/module/design-tokens/figma-variables-resolver.js +1 -1
- package/lib/module/icons/registry.js +1 -1
- package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +23 -0
- package/lib/typescript/src/components/AmountInput/index.d.ts +3 -0
- package/lib/typescript/src/components/CardProviderInfo/CardProviderInfo.d.ts +24 -0
- package/lib/typescript/src/components/EmptyState/EmptyState.d.ts +6 -1
- package/lib/typescript/src/components/OTP/OTP.d.ts +36 -0
- package/lib/typescript/src/components/PortfolioHero/PortfolioHero.d.ts +21 -0
- package/lib/typescript/src/components/ProductLabel/ProductLabel.d.ts +14 -0
- package/lib/typescript/src/components/ProgressBadge/ProgressBadge.d.ts +36 -0
- package/lib/typescript/src/components/ProgressBadge/index.d.ts +3 -0
- package/lib/typescript/src/components/StatItem/StatItem.d.ts +21 -0
- package/lib/typescript/src/components/SwappableAmount/SwappableAmount.d.ts +22 -0
- package/lib/typescript/src/components/Text/Text.d.ts +14 -0
- package/lib/typescript/src/components/Toggle/Toggle.d.ts +29 -0
- package/lib/typescript/src/components/index.d.ts +9 -0
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/AmountInput/AmountInput.tsx +81 -0
- package/src/components/AmountInput/index.ts +2 -0
- package/src/components/Button/Button.tsx +27 -20
- package/src/components/CardProviderInfo/CardProviderInfo.tsx +81 -0
- package/src/components/EmptyState/EmptyState.tsx +7 -1
- package/src/components/OTP/OTP.tsx +275 -0
- package/src/components/PortfolioHero/PortfolioHero.tsx +91 -0
- package/src/components/ProductLabel/ProductLabel.tsx +58 -0
- package/src/components/ProgressBadge/ProgressBadge.tsx +172 -0
- package/src/components/ProgressBadge/index.ts +2 -0
- package/src/components/StatItem/StatItem.tsx +71 -0
- package/src/components/SwappableAmount/SwappableAmount.tsx +92 -0
- package/src/components/Text/Text.tsx +48 -0
- package/src/components/Toggle/Toggle.tsx +122 -0
- package/src/components/index.ts +9 -0
- package/src/design-tokens/Coin Variables-variables-full.json +1 -0
- package/src/design-tokens/figma-variables-resolver.ts +1 -1
- package/src/icons/registry.ts +1 -1
- package/lib/commonjs/design-tokens/JFS Variables-variables-full.json +0 -1
- package/lib/module/design-tokens/JFS Variables-variables-full.json +0 -1
- package/src/design-tokens/JFS Variables-variables-full.json +0 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = AmountInput;
|
|
7
|
+
var _react = _interopRequireDefault(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 _MoneyValue = _interopRequireDefault(require("../MoneyValue/MoneyValue"));
|
|
12
|
+
var _NoteInput = _interopRequireDefault(require("../NoteInput/NoteInput"));
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
/**
|
|
16
|
+
* AmountInput component that combines MoneyValue and NoteInput from Figma design.
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
*/
|
|
20
|
+
function AmountInput({
|
|
21
|
+
moneyValueSlot,
|
|
22
|
+
noteInputSlot,
|
|
23
|
+
modes: propModes = {},
|
|
24
|
+
style
|
|
25
|
+
}) {
|
|
26
|
+
const {
|
|
27
|
+
modes: globalModes
|
|
28
|
+
} = (0, _JFSThemeProvider.useTokens)();
|
|
29
|
+
const modes = {
|
|
30
|
+
...globalModes,
|
|
31
|
+
...propModes
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Resolve tokens
|
|
35
|
+
const gap = Number((0, _figmaVariablesResolver.getVariableByName)('amountInput/gap', modes)) || 16;
|
|
36
|
+
const paddingHorizontal = Number((0, _figmaVariablesResolver.getVariableByName)('amountInput/padding/horizontal', modes)) || 0;
|
|
37
|
+
const paddingVertical = Number((0, _figmaVariablesResolver.getVariableByName)('amountInput/padding/vertical', modes)) || 0;
|
|
38
|
+
const containerStyle = {
|
|
39
|
+
flexDirection: 'column',
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
gap,
|
|
42
|
+
paddingHorizontal,
|
|
43
|
+
paddingVertical,
|
|
44
|
+
...style
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Handle MoneyValue Slot
|
|
48
|
+
const renderMoneyValueSlot = () => {
|
|
49
|
+
if (/*#__PURE__*/_react.default.isValidElement(moneyValueSlot)) {
|
|
50
|
+
return /*#__PURE__*/_react.default.cloneElement(moneyValueSlot, {
|
|
51
|
+
modes
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Default fallback if no slot prop is provided
|
|
55
|
+
if (!moneyValueSlot) {
|
|
56
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoneyValue.default, {
|
|
57
|
+
modes: modes
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return moneyValueSlot;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Handle NoteInput Slot
|
|
64
|
+
const renderNoteInputSlot = () => {
|
|
65
|
+
if (/*#__PURE__*/_react.default.isValidElement(noteInputSlot)) {
|
|
66
|
+
return /*#__PURE__*/_react.default.cloneElement(noteInputSlot, {
|
|
67
|
+
modes
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Default fallback if no slot prop is provided
|
|
71
|
+
if (!noteInputSlot) {
|
|
72
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_NoteInput.default, {
|
|
73
|
+
modes: modes
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return noteInputSlot;
|
|
77
|
+
};
|
|
78
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
79
|
+
style: containerStyle,
|
|
80
|
+
children: [renderMoneyValueSlot(), renderNoteInputSlot()]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "default", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _AmountInput.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _AmountInput = _interopRequireDefault(require("./AmountInput"));
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -65,8 +65,28 @@ function Button({
|
|
|
65
65
|
const textColor = (0, _figmaVariablesResolver.getVariableByName)('button/foreground', modes) || '#0f0d0a';
|
|
66
66
|
const iconColor = (0, _figmaVariablesResolver.getVariableByName)('button/icon/color', modes) ?? textColor;
|
|
67
67
|
const iconSize = (0, _figmaVariablesResolver.getVariableByName)('button/icon/size', modes) ?? 18;
|
|
68
|
+
const [isHovered, setIsHovered] = (0, _react.useState)(false);
|
|
69
|
+
const [isPressed, setIsPressed] = (0, _react.useState)(false);
|
|
70
|
+
const hoverModes = {
|
|
71
|
+
...modes,
|
|
72
|
+
"Button / State": "Hover"
|
|
73
|
+
};
|
|
74
|
+
const hoverBg = (0, _figmaVariablesResolver.getVariableByName)('button/background', hoverModes) || backgroundColor;
|
|
75
|
+
const hoverBorderColor = (0, _figmaVariablesResolver.getVariableByName)('button/border/color', hoverModes) || borderColor;
|
|
76
|
+
const hoverTextColor = (0, _figmaVariablesResolver.getVariableByName)('button/foreground', hoverModes) || textColor;
|
|
77
|
+
const hoverIconColor = (0, _figmaVariablesResolver.getVariableByName)('button/icon/color', hoverModes) ?? hoverTextColor;
|
|
78
|
+
const pressedModes = {
|
|
79
|
+
...modes,
|
|
80
|
+
"Button / State": "Pressed"
|
|
81
|
+
};
|
|
82
|
+
const pressedBg = (0, _figmaVariablesResolver.getVariableByName)('button/background', pressedModes) || backgroundColor;
|
|
83
|
+
const pressedBorderColor = (0, _figmaVariablesResolver.getVariableByName)('button/border/color', pressedModes) || borderColor;
|
|
84
|
+
const pressedTextColor = (0, _figmaVariablesResolver.getVariableByName)('button/foreground', pressedModes) || textColor;
|
|
85
|
+
const pressedIconColor = (0, _figmaVariablesResolver.getVariableByName)('button/icon/color', pressedModes) ?? pressedTextColor;
|
|
86
|
+
const activeTextColor = isPressed && !disabled ? pressedTextColor : isHovered && !disabled ? hoverTextColor : textColor;
|
|
87
|
+
const activeIconColor = isPressed && !disabled ? pressedIconColor : isHovered && !disabled ? hoverIconColor : iconColor;
|
|
68
88
|
const baseLabelTextStyle = {
|
|
69
|
-
color:
|
|
89
|
+
color: activeTextColor,
|
|
70
90
|
fontFamily,
|
|
71
91
|
fontWeight,
|
|
72
92
|
fontSize,
|
|
@@ -120,22 +140,13 @@ function Button({
|
|
|
120
140
|
accessibilityLabel: defaultAccessibilityLabel,
|
|
121
141
|
webAccessibilityProps
|
|
122
142
|
});
|
|
123
|
-
|
|
124
|
-
// Interaction states (placeholders for visuals; tweak later)
|
|
125
|
-
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
126
|
-
const [isHovered, setIsHovered] = (0, _react.useState)(false);
|
|
127
|
-
const pressedStyle = {
|
|
128
|
-
transform: [{
|
|
129
|
-
scale: 0.995
|
|
130
|
-
}],
|
|
131
|
-
backgroundColor: '#b88940'
|
|
132
|
-
};
|
|
133
|
-
const focusStyle = {
|
|
134
|
-
borderWidth: 1,
|
|
135
|
-
borderColor: '#222'
|
|
136
|
-
};
|
|
137
143
|
const hoverStyle = {
|
|
138
|
-
|
|
144
|
+
backgroundColor: hoverBg,
|
|
145
|
+
borderColor: hoverBorderColor
|
|
146
|
+
};
|
|
147
|
+
const pressedStyle = {
|
|
148
|
+
backgroundColor: pressedBg,
|
|
149
|
+
borderColor: pressedBorderColor
|
|
139
150
|
};
|
|
140
151
|
if (__DEV__) {
|
|
141
152
|
if (children && labelStyle) {
|
|
@@ -160,21 +171,13 @@ function Button({
|
|
|
160
171
|
onPress
|
|
161
172
|
} : {}),
|
|
162
173
|
onPressIn: e => {
|
|
163
|
-
;
|
|
174
|
+
setIsPressed(true);
|
|
164
175
|
rest?.onPressIn?.(e);
|
|
165
176
|
},
|
|
166
177
|
onPressOut: e => {
|
|
167
|
-
;
|
|
178
|
+
setIsPressed(false);
|
|
168
179
|
rest?.onPressOut?.(e);
|
|
169
180
|
},
|
|
170
|
-
onFocus: e => {
|
|
171
|
-
setIsFocused(true);
|
|
172
|
-
rest?.onFocus?.(e);
|
|
173
|
-
},
|
|
174
|
-
onBlur: e => {
|
|
175
|
-
setIsFocused(false);
|
|
176
|
-
rest?.onBlur?.(e);
|
|
177
|
-
},
|
|
178
181
|
onHoverIn: e => {
|
|
179
182
|
setIsHovered(true);
|
|
180
183
|
rest?.onHoverIn?.(e);
|
|
@@ -185,7 +188,7 @@ function Button({
|
|
|
185
188
|
},
|
|
186
189
|
style: ({
|
|
187
190
|
pressed
|
|
188
|
-
}) => [containerBaseStyle,
|
|
191
|
+
}) => [containerBaseStyle, isHovered && !disabled ? hoverStyle : null, (pressed || isPressed) && !disabled ? pressedStyle : null, style],
|
|
189
192
|
...webProps,
|
|
190
193
|
children: [leading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
191
194
|
style: leadingAccessoryStyle,
|
|
@@ -195,7 +198,7 @@ function Button({
|
|
|
195
198
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
|
|
196
199
|
name: icon,
|
|
197
200
|
size: iconSize,
|
|
198
|
-
color:
|
|
201
|
+
color: activeIconColor,
|
|
199
202
|
accessibilityElementsHidden: true,
|
|
200
203
|
importantForAccessibility: "no"
|
|
201
204
|
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
|
+
var _ProductLabel = _interopRequireDefault(require("../ProductLabel/ProductLabel"));
|
|
11
|
+
var _reactUtils = require("../../utils/react-utils");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
/**
|
|
15
|
+
* CardProviderInfo displays a product header (ProductLabel) followed by a
|
|
16
|
+
* 2-column grid of children (typically StatItem instances).
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
* @param {CardProviderInfoProps} props
|
|
20
|
+
*/
|
|
21
|
+
function CardProviderInfo({
|
|
22
|
+
label = 'Gold',
|
|
23
|
+
imageSource,
|
|
24
|
+
children,
|
|
25
|
+
modes = {},
|
|
26
|
+
style
|
|
27
|
+
}) {
|
|
28
|
+
const background = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/background', modes) ?? '#fef4e5';
|
|
29
|
+
const border = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/border', modes) ?? '#fef4e5';
|
|
30
|
+
const borderWidthVal = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/borderWidth', modes) ?? 1;
|
|
31
|
+
const padding = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/padding', modes) ?? 20;
|
|
32
|
+
const gap = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/gap', modes) ?? 20;
|
|
33
|
+
const radius = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/radius', modes) ?? 16;
|
|
34
|
+
const gridGap = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/grid/gap', modes) ?? 8;
|
|
35
|
+
const containerStyle = {
|
|
36
|
+
backgroundColor: background,
|
|
37
|
+
borderColor: border,
|
|
38
|
+
borderWidth: borderWidthVal,
|
|
39
|
+
borderStyle: 'solid',
|
|
40
|
+
padding: padding,
|
|
41
|
+
gap: gap,
|
|
42
|
+
borderRadius: radius
|
|
43
|
+
};
|
|
44
|
+
const gridGapNum = gridGap;
|
|
45
|
+
const clonedChildren = children ? (0, _reactUtils.cloneChildrenWithModes)(children, modes) : [];
|
|
46
|
+
const childArray = _react.default.Children.toArray(clonedChildren);
|
|
47
|
+
const rows = [];
|
|
48
|
+
for (let i = 0; i < childArray.length; i += 2) {
|
|
49
|
+
rows.push(childArray.slice(i, i + 2));
|
|
50
|
+
}
|
|
51
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
52
|
+
style: [containerStyle, style],
|
|
53
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ProductLabel.default, {
|
|
54
|
+
label: label,
|
|
55
|
+
imageSource: imageSource,
|
|
56
|
+
modes: modes
|
|
57
|
+
}), childArray.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
58
|
+
style: {
|
|
59
|
+
rowGap: gridGapNum
|
|
60
|
+
},
|
|
61
|
+
children: rows.map((row, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
62
|
+
style: {
|
|
63
|
+
flexDirection: 'row',
|
|
64
|
+
columnGap: gridGapNum
|
|
65
|
+
},
|
|
66
|
+
children: row.map((child, j) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
67
|
+
style: {
|
|
68
|
+
flex: 1
|
|
69
|
+
},
|
|
70
|
+
children: child
|
|
71
|
+
}, j))
|
|
72
|
+
}, i))
|
|
73
|
+
})]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
var _default = exports.default = CardProviderInfo;
|
|
@@ -21,6 +21,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
21
21
|
function EmptyState({
|
|
22
22
|
title = "No payments to show",
|
|
23
23
|
description = "Start by paying bills, recharge or your friends",
|
|
24
|
+
showDescription = true,
|
|
24
25
|
iconSlot,
|
|
25
26
|
buttonSlot,
|
|
26
27
|
modes: propModes = {},
|
|
@@ -116,7 +117,7 @@ function EmptyState({
|
|
|
116
117
|
children: [iconContent, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
117
118
|
style: titleStyle,
|
|
118
119
|
children: title
|
|
119
|
-
}), description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
120
|
+
}), showDescription && description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
120
121
|
style: bodyStyle,
|
|
121
122
|
children: description
|
|
122
123
|
}) : null]
|
|
@@ -0,0 +1,242 @@
|
|
|
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 _SupportText = _interopRequireDefault(require("../SupportText/SupportText"));
|
|
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 DIGITS_ONLY = /^\d*$/;
|
|
17
|
+
function OTP({
|
|
18
|
+
length = 6,
|
|
19
|
+
value: controlledValue,
|
|
20
|
+
defaultValue = '',
|
|
21
|
+
onChange,
|
|
22
|
+
onValueChange,
|
|
23
|
+
onComplete,
|
|
24
|
+
isDisabled = false,
|
|
25
|
+
isInvalid = false,
|
|
26
|
+
allowedPattern = DIGITS_ONLY,
|
|
27
|
+
autoFocus = false,
|
|
28
|
+
modes: propModes = {},
|
|
29
|
+
style,
|
|
30
|
+
supportText,
|
|
31
|
+
supportTextStatus
|
|
32
|
+
}) {
|
|
33
|
+
const {
|
|
34
|
+
modes: globalModes
|
|
35
|
+
} = (0, _JFSThemeProvider.useTokens)();
|
|
36
|
+
const modes = {
|
|
37
|
+
...globalModes,
|
|
38
|
+
...propModes
|
|
39
|
+
};
|
|
40
|
+
const isControlled = controlledValue !== undefined;
|
|
41
|
+
const [internalValue, setInternalValue] = (0, _react.useState)(defaultValue);
|
|
42
|
+
const currentValue = isControlled ? controlledValue : internalValue;
|
|
43
|
+
const inputRef = (0, _react.useRef)(null);
|
|
44
|
+
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
45
|
+
const caretAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
46
|
+
(0, _react.useEffect)(() => {
|
|
47
|
+
if (!isFocused) return;
|
|
48
|
+
const blink = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(caretAnim, {
|
|
49
|
+
toValue: 0,
|
|
50
|
+
duration: 400,
|
|
51
|
+
useNativeDriver: true
|
|
52
|
+
}), _reactNative.Animated.timing(caretAnim, {
|
|
53
|
+
toValue: 1,
|
|
54
|
+
duration: 400,
|
|
55
|
+
useNativeDriver: true
|
|
56
|
+
})]));
|
|
57
|
+
blink.start();
|
|
58
|
+
return () => blink.stop();
|
|
59
|
+
}, [isFocused, caretAnim]);
|
|
60
|
+
const prevCompleteRef = (0, _react.useRef)(false);
|
|
61
|
+
const setValue = (0, _react.useCallback)(next => {
|
|
62
|
+
const clamped = next.slice(0, length);
|
|
63
|
+
if (!isControlled) setInternalValue(clamped);
|
|
64
|
+
onChange?.(clamped);
|
|
65
|
+
onValueChange?.(clamped);
|
|
66
|
+
if (clamped.length === length && !prevCompleteRef.current) {
|
|
67
|
+
prevCompleteRef.current = true;
|
|
68
|
+
onComplete?.(clamped);
|
|
69
|
+
}
|
|
70
|
+
if (clamped.length < length) {
|
|
71
|
+
prevCompleteRef.current = false;
|
|
72
|
+
}
|
|
73
|
+
}, [length, isControlled, onChange, onValueChange, onComplete]);
|
|
74
|
+
const handleChangeText = (0, _react.useCallback)(text => {
|
|
75
|
+
if (isDisabled) return;
|
|
76
|
+
if (!allowedPattern.test(text)) return;
|
|
77
|
+
setValue(text);
|
|
78
|
+
}, [isDisabled, allowedPattern, setValue]);
|
|
79
|
+
const handlePress = (0, _react.useCallback)(() => {
|
|
80
|
+
if (isDisabled) return;
|
|
81
|
+
inputRef.current?.focus();
|
|
82
|
+
}, [isDisabled]);
|
|
83
|
+
|
|
84
|
+
// --- Token resolution (state-independent tokens resolved once) ---
|
|
85
|
+
const otpGap = Number((0, _figmaVariablesResolver.getVariableByName)('otp/gap', modes)) || 36;
|
|
86
|
+
const otpPaddingH = Number((0, _figmaVariablesResolver.getVariableByName)('otp/padding/horizontal', modes)) || 8;
|
|
87
|
+
const otpPaddingV = Number((0, _figmaVariablesResolver.getVariableByName)('otp/padding/vertical', modes)) || 8;
|
|
88
|
+
const slotWidth = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/width', modes)) || 48;
|
|
89
|
+
const slotGap = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/gap', modes)) || 8;
|
|
90
|
+
// digit/color has no state variants in Figma — resolved once from the Output collection
|
|
91
|
+
const digitColor = (0, _figmaVariablesResolver.getVariableByName)('pinSlot/digit/color', modes) || '#000000';
|
|
92
|
+
const digitFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/digit/fontSize', modes)) || 24;
|
|
93
|
+
const digitFontFamily = (0, _figmaVariablesResolver.getVariableByName)('pinSlot/digit/fontFamily', modes) || 'JioType Var';
|
|
94
|
+
const digitLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/digit/lineHeight', modes)) || 29;
|
|
95
|
+
const digitFontWeight = (0, _figmaVariablesResolver.getVariableByName)('pinSlot/digit/fontWeight', modes) || '500';
|
|
96
|
+
const underlineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/underline/height', modes)) || 2;
|
|
97
|
+
const underlineRadius = Number((0, _figmaVariablesResolver.getVariableByName)('pinSlot/underline/radius', modes)) || 1;
|
|
98
|
+
|
|
99
|
+
// --- State-driven slot modes ---
|
|
100
|
+
// Collection name in Figma is "Input/PINSlot States" (double space before States).
|
|
101
|
+
// Only PinSlot/underline/color (capital P/S) lives in this collection with Idle/Active/Error modes.
|
|
102
|
+
// isInvalid takes priority over active focus; the component maps semantic state → token mode
|
|
103
|
+
// internally so consumers never need to know the collection key name.
|
|
104
|
+
const getSlotModes = isActiveSlot => {
|
|
105
|
+
if (isInvalid) return {
|
|
106
|
+
...modes,
|
|
107
|
+
'Input/PINSlot States': 'Error'
|
|
108
|
+
};
|
|
109
|
+
if (isActiveSlot && isFocused) return {
|
|
110
|
+
...modes,
|
|
111
|
+
'Input/PINSlot States': 'Active'
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
...modes,
|
|
115
|
+
'Input/PINSlot States': 'Idle'
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// --- Styles ---
|
|
120
|
+
const containerStyle = {
|
|
121
|
+
flexDirection: 'column',
|
|
122
|
+
alignItems: 'flex-end',
|
|
123
|
+
gap: otpGap,
|
|
124
|
+
paddingHorizontal: otpPaddingH,
|
|
125
|
+
paddingVertical: otpPaddingV
|
|
126
|
+
};
|
|
127
|
+
const slotWrapStyle = {
|
|
128
|
+
flexDirection: 'row',
|
|
129
|
+
gap: 8,
|
|
130
|
+
alignItems: 'flex-start',
|
|
131
|
+
alignSelf: 'stretch'
|
|
132
|
+
};
|
|
133
|
+
const renderSlot = index => {
|
|
134
|
+
const char = currentValue[index];
|
|
135
|
+
const isActiveSlot = index === currentValue.length && currentValue.length < length;
|
|
136
|
+
const isFilled = char !== undefined;
|
|
137
|
+
|
|
138
|
+
// Underline color is the only state-sensitive token (lives in "Input/PINSlot States" collection).
|
|
139
|
+
// Note: token name is "PinSlot/underline/color" (capital P/S) — different from the static
|
|
140
|
+
// "pinSlot/underline/color" in the Output collection.
|
|
141
|
+
const slotModes = getSlotModes(isActiveSlot);
|
|
142
|
+
const underlineColor = (0, _figmaVariablesResolver.getVariableByName)('PinSlot/underline/color', slotModes) || '#303338';
|
|
143
|
+
const slotStyle = {
|
|
144
|
+
width: slotWidth,
|
|
145
|
+
flexDirection: 'column',
|
|
146
|
+
alignItems: 'center',
|
|
147
|
+
justifyContent: 'flex-end',
|
|
148
|
+
gap: slotGap
|
|
149
|
+
};
|
|
150
|
+
const digitStyle = {
|
|
151
|
+
fontFamily: digitFontFamily,
|
|
152
|
+
fontWeight: digitFontWeight,
|
|
153
|
+
fontSize: digitFontSize,
|
|
154
|
+
lineHeight: digitLineHeight,
|
|
155
|
+
color: digitColor,
|
|
156
|
+
textAlign: 'center',
|
|
157
|
+
minWidth: '100%'
|
|
158
|
+
};
|
|
159
|
+
const underlineStyle = {
|
|
160
|
+
width: slotWidth,
|
|
161
|
+
height: underlineHeight,
|
|
162
|
+
borderRadius: underlineRadius,
|
|
163
|
+
backgroundColor: underlineColor
|
|
164
|
+
};
|
|
165
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
166
|
+
style: slotStyle,
|
|
167
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
168
|
+
style: {
|
|
169
|
+
minHeight: digitLineHeight,
|
|
170
|
+
justifyContent: 'center',
|
|
171
|
+
alignItems: 'center',
|
|
172
|
+
width: '100%'
|
|
173
|
+
},
|
|
174
|
+
children: isFilled ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
175
|
+
style: digitStyle,
|
|
176
|
+
children: char
|
|
177
|
+
}) : isActiveSlot && isFocused ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
178
|
+
style: {
|
|
179
|
+
width: 2,
|
|
180
|
+
height: digitFontSize,
|
|
181
|
+
backgroundColor: digitColor,
|
|
182
|
+
opacity: caretAnim
|
|
183
|
+
}
|
|
184
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
185
|
+
style: [digitStyle, {
|
|
186
|
+
color: 'transparent'
|
|
187
|
+
}],
|
|
188
|
+
children: '\u00A0'
|
|
189
|
+
})
|
|
190
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
191
|
+
style: underlineStyle
|
|
192
|
+
})]
|
|
193
|
+
}, index);
|
|
194
|
+
};
|
|
195
|
+
const renderSupportText = () => {
|
|
196
|
+
if (!supportText) return null;
|
|
197
|
+
if (typeof supportText === 'string') {
|
|
198
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SupportText.default, {
|
|
199
|
+
label: supportText,
|
|
200
|
+
status: supportTextStatus ?? (isInvalid ? 'Error' : 'Neutral'),
|
|
201
|
+
modes: modes
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
205
|
+
children: (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(supportText), modes)
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
209
|
+
style: [containerStyle, isDisabled && {
|
|
210
|
+
opacity: 0.4
|
|
211
|
+
}, style],
|
|
212
|
+
onPress: handlePress,
|
|
213
|
+
disabled: isDisabled,
|
|
214
|
+
accessibilityRole: "none",
|
|
215
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
216
|
+
ref: inputRef,
|
|
217
|
+
value: currentValue,
|
|
218
|
+
onChangeText: handleChangeText,
|
|
219
|
+
maxLength: length,
|
|
220
|
+
keyboardType: "number-pad",
|
|
221
|
+
autoFocus: autoFocus,
|
|
222
|
+
editable: !isDisabled,
|
|
223
|
+
onFocus: () => setIsFocused(true),
|
|
224
|
+
onBlur: () => setIsFocused(false),
|
|
225
|
+
caretHidden: true,
|
|
226
|
+
style: {
|
|
227
|
+
position: 'absolute',
|
|
228
|
+
width: 1,
|
|
229
|
+
height: 1,
|
|
230
|
+
opacity: 0
|
|
231
|
+
},
|
|
232
|
+
accessibilityLabel: `OTP input, ${length} digits`,
|
|
233
|
+
accessibilityHint: "Enter your verification code"
|
|
234
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
235
|
+
style: slotWrapStyle,
|
|
236
|
+
children: Array.from({
|
|
237
|
+
length
|
|
238
|
+
}, (_, i) => renderSlot(i))
|
|
239
|
+
}), renderSupportText()]
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
var _default = exports.default = OTP;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
|
+
var _reactUtils = require("../../utils/react-utils");
|
|
11
|
+
var _Avatar = _interopRequireDefault(require("../Avatar/Avatar"));
|
|
12
|
+
var _MoneyValue = _interopRequireDefault(require("../MoneyValue/MoneyValue"));
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
function PortfolioHero({
|
|
16
|
+
label = 'Gold',
|
|
17
|
+
imageSource,
|
|
18
|
+
value = '12,000.11',
|
|
19
|
+
currency = '₹',
|
|
20
|
+
modes = {
|
|
21
|
+
Context3: 'Balance'
|
|
22
|
+
},
|
|
23
|
+
children,
|
|
24
|
+
style
|
|
25
|
+
}) {
|
|
26
|
+
const gap = (0, _figmaVariablesResolver.getVariableByName)('portfolioHero/gap', modes) ?? 16;
|
|
27
|
+
const padding = (0, _figmaVariablesResolver.getVariableByName)('portfolioHero/padding', modes) ?? 8;
|
|
28
|
+
const slotWrapGap = (0, _figmaVariablesResolver.getVariableByName)('portfolioHero/slotWrap/gap', modes) ?? 8;
|
|
29
|
+
const containerStyle = {
|
|
30
|
+
flexDirection: 'column',
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
gap: gap,
|
|
34
|
+
padding: padding
|
|
35
|
+
};
|
|
36
|
+
const productLabelStyle = {
|
|
37
|
+
flexDirection: 'row',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
gap: 8
|
|
40
|
+
};
|
|
41
|
+
const labelTextStyle = {
|
|
42
|
+
fontFamily: 'System',
|
|
43
|
+
fontWeight: '700',
|
|
44
|
+
fontSize: 16,
|
|
45
|
+
lineHeight: 16 * 1.3,
|
|
46
|
+
color: '#0d0d0f',
|
|
47
|
+
textAlign: 'center'
|
|
48
|
+
};
|
|
49
|
+
const slotWrapStyle = {
|
|
50
|
+
flexDirection: 'column',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
gap: slotWrapGap
|
|
53
|
+
};
|
|
54
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
55
|
+
style: [containerStyle, style],
|
|
56
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
57
|
+
style: productLabelStyle,
|
|
58
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar.default, {
|
|
59
|
+
style: "Image",
|
|
60
|
+
...(imageSource != null && {
|
|
61
|
+
imageSource
|
|
62
|
+
}),
|
|
63
|
+
modes: modes
|
|
64
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
65
|
+
style: labelTextStyle,
|
|
66
|
+
children: label
|
|
67
|
+
})]
|
|
68
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoneyValue.default, {
|
|
69
|
+
value: value,
|
|
70
|
+
currency: currency,
|
|
71
|
+
modes: modes
|
|
72
|
+
}), children && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
73
|
+
style: slotWrapStyle,
|
|
74
|
+
children: (0, _reactUtils.cloneChildrenWithModes)(children, modes)
|
|
75
|
+
})]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
var _default = exports.default = PortfolioHero;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
|
+
var _Avatar = _interopRequireDefault(require("../Avatar/Avatar"));
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
function ProductLabel({
|
|
14
|
+
label = 'Gold',
|
|
15
|
+
imageSource,
|
|
16
|
+
modes = {},
|
|
17
|
+
style
|
|
18
|
+
}) {
|
|
19
|
+
const gap = (0, _figmaVariablesResolver.getVariableByName)('productLabel/gap', modes) ?? 8;
|
|
20
|
+
const textColor = (0, _figmaVariablesResolver.getVariableByName)('productLabel/text/color', modes) ?? '#000000';
|
|
21
|
+
const textFontSize = (0, _figmaVariablesResolver.getVariableByName)('productLabel/text/fontSize', modes) ?? 16;
|
|
22
|
+
const textFontFamily = (0, _figmaVariablesResolver.getVariableByName)('productLabel/text/fontFamily', modes) ?? 'JioType Var';
|
|
23
|
+
const textFontWeight = (0, _figmaVariablesResolver.getVariableByName)('productLabel/text/fontWeight', modes) ?? 700;
|
|
24
|
+
const textLineHeight = (0, _figmaVariablesResolver.getVariableByName)('productLabel/text/lineHeight', modes) ?? 21;
|
|
25
|
+
const containerStyle = {
|
|
26
|
+
flexDirection: 'row',
|
|
27
|
+
alignItems: 'center',
|
|
28
|
+
gap: gap
|
|
29
|
+
};
|
|
30
|
+
const labelTextStyle = {
|
|
31
|
+
color: textColor,
|
|
32
|
+
fontSize: textFontSize,
|
|
33
|
+
fontFamily: textFontFamily,
|
|
34
|
+
fontWeight: String(textFontWeight),
|
|
35
|
+
lineHeight: textLineHeight,
|
|
36
|
+
textAlign: 'center'
|
|
37
|
+
};
|
|
38
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
39
|
+
style: [containerStyle, style],
|
|
40
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar.default, {
|
|
41
|
+
style: "Image",
|
|
42
|
+
imageSource: imageSource,
|
|
43
|
+
modes: modes
|
|
44
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
45
|
+
style: labelTextStyle,
|
|
46
|
+
children: label
|
|
47
|
+
})]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var _default = exports.default = ProductLabel;
|