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.
- package/CHANGELOG.md +59 -0
- package/lib/commonjs/components/Accordion/Accordion.js +1 -1
- package/lib/commonjs/components/ActionFooter/ActionFooter.js +1 -1
- package/lib/commonjs/components/ActionTile/ActionTile.js +2 -1
- package/lib/commonjs/components/AmountInput/AmountInput.js +2 -1
- package/lib/commonjs/components/AppBar/AppBar.js +1 -1
- package/lib/commonjs/components/Avatar/Avatar.js +184 -162
- package/lib/commonjs/components/AvatarGroup/AvatarGroup.js +1 -1
- package/lib/commonjs/components/Badge/Badge.js +2 -1
- package/lib/commonjs/components/Balance/Balance.js +2 -1
- package/lib/commonjs/components/BottomNav/BottomNav.js +2 -1
- package/lib/commonjs/components/BottomNavItem/BottomNavItem.js +106 -86
- package/lib/commonjs/components/Button/Button.js +190 -93
- package/lib/commonjs/components/ButtonGroup/ButtonGroup.js +1 -1
- package/lib/commonjs/components/Card/Card.js +2 -1
- package/lib/commonjs/components/CardCTA/CardCTA.js +1 -1
- package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +1 -1
- package/lib/commonjs/components/Carousel/Carousel.js +3 -2
- package/lib/commonjs/components/Checkbox/Checkbox.js +2 -1
- package/lib/commonjs/components/ChipGroup/ChipGroup.js +1 -1
- package/lib/commonjs/components/ChipSelect/ChipSelect.js +2 -1
- package/lib/commonjs/components/DebitCard/DebitCard.js +1 -1
- package/lib/commonjs/components/Disclaimer/Disclaimer.js +2 -1
- package/lib/commonjs/components/Divider/Divider.js +2 -1
- package/lib/commonjs/components/Drawer/Drawer.js +109 -48
- package/lib/commonjs/components/EmptyState/EmptyState.js +2 -1
- package/lib/commonjs/components/FilterBar/FilterBar.js +1 -1
- package/lib/commonjs/components/Form/Form.js +2 -1
- package/lib/commonjs/components/FormField/FormField.js +3 -2
- package/lib/commonjs/components/HStack/HStack.js +1 -1
- package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -1
- package/lib/commonjs/components/IconButton/IconButton.js +118 -128
- package/lib/commonjs/components/IconCapsule/IconCapsule.js +61 -57
- package/lib/commonjs/components/InputSearch/InputSearch.js +7 -3
- package/lib/commonjs/components/LazyList/LazyList.js +1 -1
- package/lib/commonjs/components/LinearMeter/LinearMeter.js +3 -2
- package/lib/commonjs/components/ListGroup/ListGroup.js +1 -1
- package/lib/commonjs/components/ListItem/ListItem.js +190 -142
- package/lib/commonjs/components/MediaCard/MediaCard.js +3 -3
- package/lib/commonjs/components/MerchantProfile/MerchantProfile.js +2 -1
- package/lib/commonjs/components/MoneyValue/MoneyValue.js +2 -1
- package/lib/commonjs/components/NavArrow/NavArrow.js +82 -59
- package/lib/commonjs/components/NoteInput/NoteInput.js +2 -1
- package/lib/commonjs/components/Nudge/Nudge.js +1 -1
- package/lib/commonjs/components/Numpad/Numpad.js +2 -1
- package/lib/commonjs/components/OTP/OTP.js +1 -1
- package/lib/commonjs/components/PaymentFeedback/PaymentFeedback.js +2 -1
- package/lib/commonjs/components/Popup/Popup.js +2 -1
- package/lib/commonjs/components/ProductLabel/ProductLabel.js +2 -1
- package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +2 -1
- package/lib/commonjs/components/RadioButton/RadioButton.js +2 -1
- package/lib/commonjs/components/RechargeCard/RechargeCard.js +2 -1
- package/lib/commonjs/components/Screen/Screen.js +1 -1
- package/lib/commonjs/components/Section/Section.js +500 -166
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +3 -2
- package/lib/commonjs/components/StatItem/StatItem.js +2 -1
- package/lib/commonjs/components/StatusHero/StatusHero.js +2 -1
- package/lib/commonjs/components/Stepper/Step.js +2 -1
- package/lib/commonjs/components/Stepper/StepLabel.js +2 -1
- package/lib/commonjs/components/Stepper/Stepper.js +2 -1
- package/lib/commonjs/components/SupportText/SupportText.js +2 -1
- package/lib/commonjs/components/SupportText/SupportTextIcon.js +2 -1
- package/lib/commonjs/components/SwappableAmount/SwappableAmount.js +2 -1
- package/lib/commonjs/components/Tabs/TabItem.js +2 -1
- package/lib/commonjs/components/Tabs/Tabs.js +2 -1
- package/lib/commonjs/components/Text/Text.js +2 -1
- package/lib/commonjs/components/TextInput/TextInput.js +2 -2
- package/lib/commonjs/components/ThreadHero/ThreadHero.js +2 -1
- package/lib/commonjs/components/Title/Title.js +2 -1
- package/lib/commonjs/components/Toast/Toast.js +2 -1
- package/lib/commonjs/components/Toggle/Toggle.js +2 -1
- package/lib/commonjs/components/Tooltip/Tooltip.js +2 -1
- package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +1 -1
- package/lib/commonjs/components/TransactionDetails/TransactionDetails.js +2 -2
- package/lib/commonjs/components/TransactionStatus/TransactionStatus.js +3 -2
- package/lib/commonjs/components/UpiHandle/UpiHandle.js +144 -110
- package/lib/commonjs/components/VStack/VStack.js +1 -1
- package/lib/commonjs/design-tokens/figma-variables-resolver.js +21 -3
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/utils/react-utils.js +17 -0
- package/lib/module/components/Accordion/Accordion.js +2 -2
- package/lib/module/components/ActionFooter/ActionFooter.js +2 -2
- package/lib/module/components/ActionTile/ActionTile.js +2 -1
- package/lib/module/components/AmountInput/AmountInput.js +2 -1
- package/lib/module/components/AppBar/AppBar.js +2 -2
- package/lib/module/components/Avatar/Avatar.js +184 -162
- package/lib/module/components/AvatarGroup/AvatarGroup.js +2 -2
- package/lib/module/components/Badge/Badge.js +2 -1
- package/lib/module/components/Balance/Balance.js +2 -1
- package/lib/module/components/BottomNav/BottomNav.js +2 -1
- package/lib/module/components/BottomNavItem/BottomNavItem.js +108 -88
- package/lib/module/components/Button/Button.js +192 -95
- package/lib/module/components/ButtonGroup/ButtonGroup.js +2 -2
- package/lib/module/components/Card/Card.js +2 -1
- package/lib/module/components/CardCTA/CardCTA.js +2 -2
- package/lib/module/components/CardProviderInfo/CardProviderInfo.js +2 -2
- package/lib/module/components/Carousel/Carousel.js +3 -2
- package/lib/module/components/Checkbox/Checkbox.js +2 -1
- package/lib/module/components/ChipGroup/ChipGroup.js +2 -2
- package/lib/module/components/ChipSelect/ChipSelect.js +2 -1
- package/lib/module/components/DebitCard/DebitCard.js +2 -2
- package/lib/module/components/Disclaimer/Disclaimer.js +2 -1
- package/lib/module/components/Divider/Divider.js +2 -1
- package/lib/module/components/Drawer/Drawer.js +109 -48
- package/lib/module/components/EmptyState/EmptyState.js +2 -1
- package/lib/module/components/FilterBar/FilterBar.js +2 -2
- package/lib/module/components/Form/Form.js +2 -1
- package/lib/module/components/FormField/FormField.js +3 -2
- package/lib/module/components/HStack/HStack.js +2 -2
- package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -1
- package/lib/module/components/IconButton/IconButton.js +120 -130
- package/lib/module/components/IconCapsule/IconCapsule.js +60 -57
- package/lib/module/components/InputSearch/InputSearch.js +7 -3
- package/lib/module/components/LazyList/LazyList.js +2 -2
- package/lib/module/components/LinearMeter/LinearMeter.js +3 -2
- package/lib/module/components/ListGroup/ListGroup.js +2 -2
- package/lib/module/components/ListItem/ListItem.js +194 -146
- package/lib/module/components/MediaCard/MediaCard.js +4 -2
- package/lib/module/components/MerchantProfile/MerchantProfile.js +2 -1
- package/lib/module/components/MoneyValue/MoneyValue.js +2 -1
- package/lib/module/components/NavArrow/NavArrow.js +82 -58
- package/lib/module/components/NoteInput/NoteInput.js +2 -1
- package/lib/module/components/Nudge/Nudge.js +2 -2
- package/lib/module/components/Numpad/Numpad.js +2 -1
- package/lib/module/components/OTP/OTP.js +2 -2
- package/lib/module/components/PaymentFeedback/PaymentFeedback.js +2 -1
- package/lib/module/components/Popup/Popup.js +2 -1
- package/lib/module/components/ProductLabel/ProductLabel.js +2 -1
- package/lib/module/components/ProgressBadge/ProgressBadge.js +2 -1
- package/lib/module/components/RadioButton/RadioButton.js +2 -1
- package/lib/module/components/RechargeCard/RechargeCard.js +2 -1
- package/lib/module/components/Screen/Screen.js +2 -2
- package/lib/module/components/Section/Section.js +503 -169
- package/lib/module/components/SegmentedControl/SegmentedControl.js +3 -2
- package/lib/module/components/StatItem/StatItem.js +2 -1
- package/lib/module/components/StatusHero/StatusHero.js +2 -1
- package/lib/module/components/Stepper/Step.js +2 -1
- package/lib/module/components/Stepper/StepLabel.js +2 -1
- package/lib/module/components/Stepper/Stepper.js +2 -1
- package/lib/module/components/SupportText/SupportText.js +2 -1
- package/lib/module/components/SupportText/SupportTextIcon.js +2 -1
- package/lib/module/components/SwappableAmount/SwappableAmount.js +2 -1
- package/lib/module/components/Tabs/TabItem.js +2 -1
- package/lib/module/components/Tabs/Tabs.js +2 -1
- package/lib/module/components/Text/Text.js +2 -1
- package/lib/module/components/TextInput/TextInput.js +3 -3
- package/lib/module/components/ThreadHero/ThreadHero.js +2 -1
- package/lib/module/components/Title/Title.js +2 -1
- package/lib/module/components/Toast/Toast.js +2 -1
- package/lib/module/components/Toggle/Toggle.js +2 -1
- package/lib/module/components/Tooltip/Tooltip.js +2 -1
- package/lib/module/components/TransactionBubble/TransactionBubble.js +2 -2
- package/lib/module/components/TransactionDetails/TransactionDetails.js +3 -3
- package/lib/module/components/TransactionStatus/TransactionStatus.js +3 -2
- package/lib/module/components/UpiHandle/UpiHandle.js +147 -113
- package/lib/module/components/VStack/VStack.js +2 -2
- package/lib/module/design-tokens/figma-variables-resolver.js +21 -3
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/utils/react-utils.js +16 -0
- package/lib/typescript/src/components/Avatar/Avatar.d.ts +11 -17
- package/lib/typescript/src/components/BottomNavItem/BottomNavItem.d.ts +12 -8
- package/lib/typescript/src/components/Button/Button.d.ts +18 -1
- package/lib/typescript/src/components/IconButton/IconButton.d.ts +12 -29
- package/lib/typescript/src/components/IconCapsule/IconCapsule.d.ts +10 -18
- package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +8 -3
- package/lib/typescript/src/components/ListItem/ListItem.d.ts +14 -1
- package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +12 -11
- package/lib/typescript/src/components/Section/Section.d.ts +43 -48
- package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +13 -12
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/utils/react-utils.d.ts +15 -0
- package/package.json +4 -6
- package/src/components/Accordion/Accordion.tsx +2 -2
- package/src/components/ActionFooter/ActionFooter.tsx +2 -2
- package/src/components/ActionTile/ActionTile.tsx +2 -1
- package/src/components/AmountInput/AmountInput.tsx +2 -1
- package/src/components/AppBar/AppBar.tsx +2 -2
- package/src/components/Avatar/Avatar.tsx +229 -158
- package/src/components/AvatarGroup/AvatarGroup.tsx +2 -2
- package/src/components/Badge/Badge.tsx +2 -1
- package/src/components/Balance/Balance.tsx +2 -1
- package/src/components/BottomNav/BottomNav.tsx +2 -1
- package/src/components/BottomNavItem/BottomNavItem.tsx +159 -88
- package/src/components/Button/Button.tsx +228 -101
- package/src/components/ButtonGroup/ButtonGroup.tsx +2 -2
- package/src/components/Card/Card.tsx +2 -1
- package/src/components/CardCTA/CardCTA.tsx +2 -2
- package/src/components/CardProviderInfo/CardProviderInfo.tsx +2 -2
- package/src/components/Carousel/Carousel.tsx +3 -2
- package/src/components/Checkbox/Checkbox.tsx +2 -1
- package/src/components/ChipGroup/ChipGroup.tsx +2 -2
- package/src/components/ChipSelect/ChipSelect.tsx +2 -1
- package/src/components/DebitCard/DebitCard.tsx +2 -2
- package/src/components/Disclaimer/Disclaimer.tsx +2 -1
- package/src/components/Divider/Divider.tsx +2 -1
- package/src/components/Drawer/Drawer.tsx +124 -58
- package/src/components/EmptyState/EmptyState.tsx +2 -1
- package/src/components/FilterBar/FilterBar.tsx +2 -2
- package/src/components/Form/Form.tsx +2 -1
- package/src/components/FormField/FormField.tsx +3 -2
- package/src/components/HStack/HStack.tsx +2 -2
- package/src/components/HoldingsCard/HoldingsCard.tsx +2 -1
- package/src/components/IconButton/IconButton.tsx +154 -126
- package/src/components/IconCapsule/IconCapsule.tsx +73 -54
- package/src/components/InputSearch/InputSearch.tsx +19 -5
- package/src/components/LazyList/LazyList.tsx +2 -2
- package/src/components/LinearMeter/LinearMeter.tsx +3 -2
- package/src/components/ListGroup/ListGroup.tsx +2 -2
- package/src/components/ListItem/ListItem.tsx +257 -187
- package/src/components/MediaCard/MediaCard.tsx +2 -1
- package/src/components/MerchantProfile/MerchantProfile.tsx +2 -1
- package/src/components/MoneyValue/MoneyValue.tsx +2 -1
- package/src/components/NavArrow/NavArrow.tsx +91 -58
- package/src/components/NoteInput/NoteInput.tsx +2 -1
- package/src/components/Nudge/Nudge.tsx +2 -2
- package/src/components/Numpad/Numpad.tsx +2 -1
- package/src/components/OTP/OTP.tsx +2 -2
- package/src/components/PaymentFeedback/PaymentFeedback.tsx +2 -1
- package/src/components/Popup/Popup.tsx +2 -1
- package/src/components/ProductLabel/ProductLabel.tsx +2 -1
- package/src/components/ProgressBadge/ProgressBadge.tsx +2 -2
- package/src/components/RadioButton/RadioButton.tsx +2 -1
- package/src/components/RechargeCard/RechargeCard.tsx +2 -1
- package/src/components/Screen/Screen.tsx +2 -2
- package/src/components/Section/Section.tsx +672 -176
- package/src/components/SegmentedControl/SegmentedControl.tsx +3 -2
- package/src/components/StatItem/StatItem.tsx +2 -1
- package/src/components/StatusHero/StatusHero.tsx +2 -1
- package/src/components/Stepper/Step.tsx +2 -1
- package/src/components/Stepper/StepLabel.tsx +2 -1
- package/src/components/Stepper/Stepper.tsx +2 -1
- package/src/components/SupportText/SupportText.tsx +2 -1
- package/src/components/SupportText/SupportTextIcon.tsx +2 -1
- package/src/components/SwappableAmount/SwappableAmount.tsx +2 -1
- package/src/components/Tabs/TabItem.tsx +2 -1
- package/src/components/Tabs/Tabs.tsx +2 -1
- package/src/components/Text/Text.tsx +2 -1
- package/src/components/TextInput/TextInput.tsx +3 -3
- package/src/components/ThreadHero/ThreadHero.tsx +2 -1
- package/src/components/Title/Title.tsx +2 -1
- package/src/components/Toast/Toast.tsx +2 -1
- package/src/components/Toggle/Toggle.tsx +2 -1
- package/src/components/Tooltip/Tooltip.tsx +2 -1
- package/src/components/TransactionBubble/TransactionBubble.tsx +2 -2
- package/src/components/TransactionDetails/TransactionDetails.tsx +3 -3
- package/src/components/TransactionStatus/TransactionStatus.tsx +3 -2
- package/src/components/UpiHandle/UpiHandle.tsx +193 -125
- package/src/components/VStack/VStack.tsx +2 -2
- package/src/design-tokens/figma-variables-resolver.ts +21 -3
- package/src/icons/registry.ts +1 -1
- package/src/utils/react-utils.ts +16 -0
- package/lib/typescript/App.d.ts +0 -2
- package/lib/typescript/index.d.ts +0 -2
- package/lib/typescript/metro.config.d.ts +0 -78
- package/lib/typescript/react-native.config.d.ts +0 -4
|
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
10
|
var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
|
|
11
|
+
var _reactUtils = require("../../utils/react-utils");
|
|
11
12
|
var _Icon = _interopRequireDefault(require("../../icons/Icon"));
|
|
12
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -15,149 +16,153 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
15
16
|
// Default static asset from the component folder.
|
|
16
17
|
// Consumers can override the image via the `avatarSource` prop if needed.
|
|
17
18
|
const DEFAULT_AVATAR_IMAGE = require('./Image.png');
|
|
19
|
+
const IS_WEB = _reactNative.Platform.OS === 'web';
|
|
20
|
+
const IS_IOS = _reactNative.Platform.OS === 'ios';
|
|
21
|
+
const PRESS_DELAY = IS_IOS ? 130 : 0;
|
|
22
|
+
const pressedOverlayStyle = {
|
|
23
|
+
transform: [{
|
|
24
|
+
scale: 0.98
|
|
25
|
+
}]
|
|
26
|
+
};
|
|
27
|
+
const focusOverlayStyle = {
|
|
28
|
+
borderWidth: 1,
|
|
29
|
+
borderColor: '#222'
|
|
30
|
+
};
|
|
31
|
+
function resolveUpiHandleTokens(modes) {
|
|
32
|
+
const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/background', modes) || '#f5f5f5';
|
|
33
|
+
const radius = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/radius', modes) || 99999;
|
|
34
|
+
const paddingLeft = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/left', modes) || 4;
|
|
35
|
+
const paddingRight = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/right', modes) || 14;
|
|
36
|
+
const paddingVertical = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/vertical', modes) || 3;
|
|
37
|
+
const gap = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/gap', modes) || 6;
|
|
38
|
+
const avatarSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/image/size', modes) || 23;
|
|
39
|
+
const avatarRadius = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/image/radius', modes) || 99999;
|
|
40
|
+
const labelColor = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/color', modes) || '#0d0d0f';
|
|
41
|
+
const labelFontSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontSize', modes) || 12;
|
|
42
|
+
const labelLineHeight = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/lineHeight', modes) || 23;
|
|
43
|
+
const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontFamily', modes) || 'System';
|
|
44
|
+
const labelFontWeightRaw = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontWeight', modes) || 500;
|
|
45
|
+
const labelFontWeight = typeof labelFontWeightRaw === 'number' ? labelFontWeightRaw.toString() : labelFontWeightRaw;
|
|
46
|
+
const iconColor = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/icon/color', modes) || '#0d0d0f';
|
|
47
|
+
const iconSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/icon/size', modes) || 12;
|
|
48
|
+
return {
|
|
49
|
+
containerStyle: {
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
justifyContent: 'center',
|
|
53
|
+
backgroundColor,
|
|
54
|
+
paddingLeft,
|
|
55
|
+
paddingRight,
|
|
56
|
+
paddingVertical,
|
|
57
|
+
borderRadius: radius,
|
|
58
|
+
gap
|
|
59
|
+
},
|
|
60
|
+
avatarStyle: {
|
|
61
|
+
width: avatarSize,
|
|
62
|
+
height: avatarSize,
|
|
63
|
+
borderRadius: avatarRadius,
|
|
64
|
+
overflow: 'hidden'
|
|
65
|
+
},
|
|
66
|
+
labelStyle: {
|
|
67
|
+
color: labelColor,
|
|
68
|
+
fontSize: labelFontSize,
|
|
69
|
+
lineHeight: labelLineHeight,
|
|
70
|
+
fontFamily: labelFontFamily,
|
|
71
|
+
fontWeight: labelFontWeight
|
|
72
|
+
},
|
|
73
|
+
iconColor,
|
|
74
|
+
iconSize,
|
|
75
|
+
iconPlaceholderStyle: {
|
|
76
|
+
width: iconSize,
|
|
77
|
+
height: iconSize
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
18
82
|
/**
|
|
19
83
|
* UpiHandle pill that mirrors the Figma "UPI Handle" component.
|
|
20
84
|
*
|
|
21
|
-
* Layout:
|
|
22
|
-
* - Circular image/avatar on the left
|
|
23
|
-
* - Label text in the center
|
|
24
|
-
* - Optional QR-code style icon on the right
|
|
25
|
-
*
|
|
26
|
-
* All visual styling is resolved from Figma variables via `getVariableByName`
|
|
27
|
-
* using a `modes` configuration object, matching the rest of this library.
|
|
28
|
-
*
|
|
29
85
|
* @component
|
|
30
86
|
* @param {Object} props
|
|
31
87
|
* @param {string} [props.label="Label"] - UPI handle text to display.
|
|
32
88
|
* @param {Object} [props.modes={}] - Modes object passed directly to `getVariableByName`.
|
|
33
89
|
* @param {boolean} [props.showIcon=true] - Toggles the trailing icon visibility.
|
|
34
|
-
* @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set
|
|
90
|
+
* @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set.
|
|
35
91
|
* @param {ImageSourcePropType} [props.avatarSource] - Optional custom image source for the avatar.
|
|
36
92
|
* @param {Function} [props.onClick] - Click/tap handler. Works as an alias for `onPress`.
|
|
37
|
-
* @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
|
|
93
|
+
* @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
|
|
38
94
|
* @param {string} [props.accessibilityHint] - Additional accessibility hint for screen readers
|
|
95
|
+
*
|
|
96
|
+
* Performance notes:
|
|
97
|
+
* - Token reads collapsed into a single `useMemo([modes])`.
|
|
98
|
+
* - Press visual goes through Pressable's `({ pressed })` style callback so
|
|
99
|
+
* a scroll-cancelled touch never schedules a React render. iOS gets
|
|
100
|
+
* `unstable_pressDelay={130}` for additional safety inside scrollables.
|
|
101
|
+
* - Focus state is mirrored on web only (gated setter).
|
|
102
|
+
* - Wrapped in `React.memo`.
|
|
39
103
|
*/
|
|
40
104
|
function UpiHandle({
|
|
41
105
|
label = 'Label',
|
|
42
|
-
modes: propModes =
|
|
106
|
+
modes: propModes = _reactUtils.EMPTY_MODES,
|
|
43
107
|
showIcon = true,
|
|
44
108
|
iconName = 'ic_scan_qr_code',
|
|
45
109
|
avatarSource,
|
|
46
110
|
onPress,
|
|
47
111
|
onClick,
|
|
48
112
|
disabled,
|
|
49
|
-
accessibilityLabel
|
|
113
|
+
// accessibilityLabel is accepted on the type for API back-compat; the
|
|
114
|
+
// wrapper renders `accessibilityLabel={undefined}` because the inner Text
|
|
115
|
+
// already carries the label.
|
|
116
|
+
accessibilityLabel: _accessibilityLabel,
|
|
50
117
|
accessibilityHint,
|
|
51
118
|
...rest
|
|
52
119
|
}) {
|
|
53
120
|
const {
|
|
54
121
|
modes: globalModes
|
|
55
122
|
} = (0, _JFSThemeProvider.useTokens)();
|
|
56
|
-
const modes = {
|
|
123
|
+
const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
|
|
57
124
|
...globalModes,
|
|
58
125
|
...propModes
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/background', modes) || '#f5f5f5';
|
|
62
|
-
const radius = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/radius', modes) || 99999;
|
|
63
|
-
const paddingLeft = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/left', modes) || 4;
|
|
64
|
-
const paddingRight = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/right', modes) || 14;
|
|
65
|
-
const paddingVertical = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/padding/vertical', modes) || 3;
|
|
66
|
-
const gap = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/gap', modes) || 6;
|
|
67
|
-
|
|
68
|
-
// Avatar
|
|
69
|
-
const avatarSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/image/size', modes) || 23;
|
|
70
|
-
const avatarRadius = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/image/radius', modes) || 99999;
|
|
71
|
-
|
|
72
|
-
// Label typography
|
|
73
|
-
const labelColor = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/color', modes) || '#0d0d0f';
|
|
74
|
-
const labelFontSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontSize', modes) || 12;
|
|
75
|
-
const labelLineHeight = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/lineHeight', modes) || 23;
|
|
76
|
-
const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontFamily', modes) || 'System';
|
|
77
|
-
const labelFontWeightRaw = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/label/fontWeight', modes) || 500;
|
|
78
|
-
const labelFontWeight = typeof labelFontWeightRaw === 'number' ? labelFontWeightRaw.toString() : labelFontWeightRaw;
|
|
126
|
+
}, [globalModes, propModes]);
|
|
127
|
+
const tokens = (0, _react.useMemo)(() => resolveUpiHandleTokens(modes), [modes]);
|
|
79
128
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
const iconSize = (0, _figmaVariablesResolver.getVariableByName)('upiHandle/icon/size', modes) || 12;
|
|
83
|
-
const containerStyle = {
|
|
84
|
-
flexDirection: 'row',
|
|
85
|
-
alignItems: 'center',
|
|
86
|
-
justifyContent: 'center',
|
|
87
|
-
backgroundColor,
|
|
88
|
-
paddingLeft,
|
|
89
|
-
paddingRight,
|
|
90
|
-
paddingVertical,
|
|
91
|
-
borderRadius: radius,
|
|
92
|
-
gap
|
|
93
|
-
};
|
|
94
|
-
const avatarBaseStyle = {
|
|
95
|
-
width: avatarSize,
|
|
96
|
-
height: avatarSize,
|
|
97
|
-
borderRadius: avatarRadius,
|
|
98
|
-
overflow: 'hidden'
|
|
99
|
-
};
|
|
100
|
-
const labelBaseStyle = {
|
|
101
|
-
color: labelColor,
|
|
102
|
-
fontSize: labelFontSize,
|
|
103
|
-
lineHeight: labelLineHeight,
|
|
104
|
-
fontFamily: labelFontFamily,
|
|
105
|
-
fontWeight: labelFontWeight
|
|
106
|
-
};
|
|
107
|
-
const iconPlaceholderStyle = {
|
|
108
|
-
width: iconSize,
|
|
109
|
-
height: iconSize
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// Use provided accessibilityLabel or fall back to label
|
|
113
|
-
const defaultAccessibilityLabel = accessibilityLabel || `UPI handle ${label}`;
|
|
114
|
-
const [isPressed, setIsPressed] = (0, _react.useState)(false);
|
|
129
|
+
// Focus is a sustained visible state (web-only). Setter is gated so it
|
|
130
|
+
// never fires on native.
|
|
115
131
|
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
const userHandlersRef = (0, _react.useRef)({});
|
|
133
|
+
userHandlersRef.current.onPressIn = rest?.onPressIn;
|
|
134
|
+
userHandlersRef.current.onPressOut = rest?.onPressOut;
|
|
135
|
+
userHandlersRef.current.onFocus = rest?.onFocus;
|
|
136
|
+
userHandlersRef.current.onBlur = rest?.onBlur;
|
|
137
|
+
const handlePressIn = (0, _react.useCallback)(e => {
|
|
138
|
+
userHandlersRef.current.onPressIn?.(e);
|
|
139
|
+
}, []);
|
|
140
|
+
const handlePressOut = (0, _react.useCallback)(e => {
|
|
141
|
+
userHandlersRef.current.onPressOut?.(e);
|
|
142
|
+
}, []);
|
|
143
|
+
const handleFocus = (0, _react.useCallback)(e => {
|
|
144
|
+
if (IS_WEB) setIsFocused(true);
|
|
145
|
+
userHandlersRef.current.onFocus?.(e);
|
|
146
|
+
}, []);
|
|
147
|
+
const handleBlur = (0, _react.useCallback)(e => {
|
|
148
|
+
if (IS_WEB) setIsFocused(false);
|
|
149
|
+
userHandlersRef.current.onBlur?.(e);
|
|
150
|
+
}, []);
|
|
125
151
|
const handlePress = onPress || onClick;
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
accessibilityHint
|
|
133
|
-
} : {}),
|
|
134
|
-
onPress: handlePress,
|
|
135
|
-
disabled: rest?.disabled ?? disabled,
|
|
136
|
-
onPressIn: e => {
|
|
137
|
-
setIsPressed(true);
|
|
138
|
-
rest?.onPressIn?.(e);
|
|
139
|
-
},
|
|
140
|
-
onPressOut: e => {
|
|
141
|
-
setIsPressed(false);
|
|
142
|
-
rest?.onPressOut?.(e);
|
|
143
|
-
},
|
|
144
|
-
onFocus: e => {
|
|
145
|
-
setIsFocused(true);
|
|
146
|
-
rest?.onFocus?.(e);
|
|
147
|
-
},
|
|
148
|
-
onBlur: e => {
|
|
149
|
-
setIsFocused(false);
|
|
150
|
-
rest?.onBlur?.(e);
|
|
151
|
-
},
|
|
152
|
-
...rest,
|
|
152
|
+
const isPressable = !!(rest?.onPress || handlePress);
|
|
153
|
+
const pressableStyle = (0, _react.useCallback)(({
|
|
154
|
+
pressed
|
|
155
|
+
}) => [tokens.containerStyle, pressed ? pressedOverlayStyle : null, isFocused ? focusOverlayStyle : null], [tokens.containerStyle, isFocused]);
|
|
156
|
+
const staticContainerStyle = (0, _react.useMemo)(() => [tokens.containerStyle, isFocused ? focusOverlayStyle : null], [tokens.containerStyle, isFocused]);
|
|
157
|
+
const innerContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
153
158
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
154
159
|
source: avatarSource || DEFAULT_AVATAR_IMAGE,
|
|
155
|
-
style:
|
|
160
|
+
style: tokens.avatarStyle,
|
|
156
161
|
resizeMode: "cover",
|
|
157
162
|
accessibilityElementsHidden: true,
|
|
158
163
|
importantForAccessibility: "no"
|
|
159
164
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
160
|
-
style:
|
|
165
|
+
style: tokens.labelStyle,
|
|
161
166
|
numberOfLines: 1,
|
|
162
167
|
ellipsizeMode: "tail",
|
|
163
168
|
accessibilityElementsHidden: true,
|
|
@@ -165,12 +170,41 @@ function UpiHandle({
|
|
|
165
170
|
children: label
|
|
166
171
|
}), showIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
|
|
167
172
|
name: iconName,
|
|
168
|
-
size: iconSize,
|
|
169
|
-
color: iconColor,
|
|
170
|
-
style: iconPlaceholderStyle,
|
|
173
|
+
size: tokens.iconSize,
|
|
174
|
+
color: tokens.iconColor,
|
|
175
|
+
style: tokens.iconPlaceholderStyle,
|
|
171
176
|
accessibilityElementsHidden: true,
|
|
172
177
|
importantForAccessibility: "no"
|
|
173
178
|
})]
|
|
174
179
|
});
|
|
180
|
+
if (isPressable) {
|
|
181
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
182
|
+
style: pressableStyle,
|
|
183
|
+
accessibilityRole: "text",
|
|
184
|
+
accessibilityLabel: undefined,
|
|
185
|
+
...(accessibilityHint !== undefined ? {
|
|
186
|
+
accessibilityHint
|
|
187
|
+
} : {}),
|
|
188
|
+
onPress: handlePress,
|
|
189
|
+
disabled: rest?.disabled ?? disabled,
|
|
190
|
+
onPressIn: handlePressIn,
|
|
191
|
+
onPressOut: handlePressOut,
|
|
192
|
+
onFocus: handleFocus,
|
|
193
|
+
onBlur: handleBlur,
|
|
194
|
+
unstable_pressDelay: PRESS_DELAY,
|
|
195
|
+
...rest,
|
|
196
|
+
children: innerContent
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
200
|
+
style: staticContainerStyle,
|
|
201
|
+
accessibilityRole: "text",
|
|
202
|
+
accessibilityLabel: undefined,
|
|
203
|
+
...(accessibilityHint !== undefined ? {
|
|
204
|
+
accessibilityHint
|
|
205
|
+
} : {}),
|
|
206
|
+
...rest,
|
|
207
|
+
children: innerContent
|
|
208
|
+
});
|
|
175
209
|
}
|
|
176
|
-
var _default = exports.default = UpiHandle;
|
|
210
|
+
var _default = exports.default = /*#__PURE__*/_react.default.memo(UpiHandle);
|
|
@@ -198,14 +198,32 @@ function resolveVariable(variableId, modesByCollectionName = {}) {
|
|
|
198
198
|
return value;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
// Per-object serialization cache. Most callers pass the same `modes` object
|
|
202
|
+
// many times in a single render (e.g. one Button does ~21 token lookups with
|
|
203
|
+
// the same `modes`); with a stable identity from the caller (see
|
|
204
|
+
// `EMPTY_MODES` in `utils/react-utils.ts`) this collapses to a single
|
|
205
|
+
// sort+join per modes object across the whole app.
|
|
206
|
+
const serializedModesCache = new WeakMap();
|
|
207
|
+
|
|
201
208
|
// Serialize modes object to create a stable cache key
|
|
202
209
|
function serializeModes(modes) {
|
|
203
|
-
if (!modes ||
|
|
210
|
+
if (!modes || typeof modes !== 'object') {
|
|
211
|
+
return '';
|
|
212
|
+
}
|
|
213
|
+
const cached = serializedModesCache.get(modes);
|
|
214
|
+
if (cached !== undefined) {
|
|
215
|
+
return cached;
|
|
216
|
+
}
|
|
217
|
+
const keys = Object.keys(modes);
|
|
218
|
+
if (keys.length === 0) {
|
|
219
|
+
serializedModesCache.set(modes, '');
|
|
204
220
|
return '';
|
|
205
221
|
}
|
|
206
222
|
// Sort keys for consistent serialization
|
|
207
|
-
|
|
208
|
-
|
|
223
|
+
keys.sort();
|
|
224
|
+
const result = keys.map(key => `${key}:${modes[key]}`).join('|');
|
|
225
|
+
serializedModesCache.set(modes, result);
|
|
226
|
+
return result;
|
|
209
227
|
}
|
|
210
228
|
|
|
211
229
|
// Get variable by name with dynamic mode resolution (optimized with O(1) lookup)
|