jfs-components 0.0.44 → 0.0.47

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 (125) hide show
  1. package/lib/commonjs/components/AmountInput/AmountInput.js +82 -0
  2. package/lib/commonjs/components/AmountInput/index.js +13 -0
  3. package/lib/commonjs/components/Button/Button.js +31 -28
  4. package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +76 -0
  5. package/lib/commonjs/components/ChipSelect/ChipSelect.js +1 -2
  6. package/lib/commonjs/components/Drawer/demo.xml +18 -0
  7. package/lib/commonjs/components/EmptyState/EmptyState.js +2 -1
  8. package/lib/commonjs/components/FormField/FormField.js +1 -0
  9. package/lib/commonjs/components/NoteInput/NoteInput.js +1 -2
  10. package/lib/commonjs/components/Nudge/Nudge.js +143 -0
  11. package/lib/commonjs/components/OTP/OTP.js +242 -0
  12. package/lib/commonjs/components/PaymentFeedback/PaymentFeedback.js +148 -0
  13. package/lib/commonjs/components/PortfolioHero/PortfolioHero.js +78 -0
  14. package/lib/commonjs/components/ProductLabel/ProductLabel.js +50 -0
  15. package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +130 -0
  16. package/lib/commonjs/components/ProgressBadge/index.js +25 -0
  17. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +131 -0
  18. package/lib/commonjs/components/StatItem/StatItem.js +61 -0
  19. package/lib/commonjs/components/SupportText/SupportTextIcon.js +2 -3
  20. package/lib/commonjs/components/SwappableAmount/SwappableAmount.js +71 -0
  21. package/lib/commonjs/components/Text/Text.js +44 -0
  22. package/lib/commonjs/components/{PageTitle/PageTitle.js → Title/Title.js} +21 -20
  23. package/lib/commonjs/components/Toggle/Toggle.js +102 -0
  24. package/lib/commonjs/components/UpiHandle/UpiHandle.js +5 -2
  25. package/lib/commonjs/components/index.js +115 -3
  26. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -0
  27. package/lib/commonjs/design-tokens/figma-variables-resolver.js +1 -1
  28. package/lib/commonjs/icons/registry.js +1 -1
  29. package/lib/commonjs/index.js +12 -0
  30. package/lib/commonjs/utils/index.js +18 -0
  31. package/lib/module/components/AmountInput/AmountInput.js +77 -0
  32. package/lib/module/components/AmountInput/index.js +3 -0
  33. package/lib/module/components/Button/Button.js +31 -28
  34. package/lib/module/components/CardProviderInfo/CardProviderInfo.js +71 -0
  35. package/lib/module/components/ChipSelect/ChipSelect.js +1 -2
  36. package/lib/module/components/Drawer/demo.xml +18 -0
  37. package/lib/module/components/EmptyState/EmptyState.js +2 -1
  38. package/lib/module/components/FormField/FormField.js +1 -0
  39. package/lib/module/components/NoteInput/NoteInput.js +1 -2
  40. package/lib/module/components/Nudge/Nudge.js +138 -0
  41. package/lib/module/components/OTP/OTP.js +236 -0
  42. package/lib/module/components/PaymentFeedback/PaymentFeedback.js +142 -0
  43. package/lib/module/components/PortfolioHero/PortfolioHero.js +73 -0
  44. package/lib/module/components/ProductLabel/ProductLabel.js +45 -0
  45. package/lib/module/components/ProgressBadge/ProgressBadge.js +125 -0
  46. package/lib/module/components/ProgressBadge/index.js +4 -0
  47. package/lib/module/components/SegmentedControl/SegmentedControl.js +126 -0
  48. package/lib/module/components/StatItem/StatItem.js +56 -0
  49. package/lib/module/components/SupportText/SupportTextIcon.js +2 -3
  50. package/lib/module/components/SwappableAmount/SwappableAmount.js +66 -0
  51. package/lib/module/components/Text/Text.js +39 -0
  52. package/lib/module/components/{PageTitle/PageTitle.js → Title/Title.js} +21 -20
  53. package/lib/module/components/Toggle/Toggle.js +97 -0
  54. package/lib/module/components/UpiHandle/UpiHandle.js +5 -2
  55. package/lib/module/components/index.js +18 -2
  56. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -0
  57. package/lib/module/design-tokens/figma-variables-resolver.js +1 -1
  58. package/lib/module/icons/registry.js +1 -1
  59. package/lib/module/index.js +2 -1
  60. package/lib/module/utils/index.js +3 -0
  61. package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +23 -0
  62. package/lib/typescript/src/components/AmountInput/index.d.ts +3 -0
  63. package/lib/typescript/src/components/CardProviderInfo/CardProviderInfo.d.ts +24 -0
  64. package/lib/typescript/src/components/ChipSelect/ChipSelect.d.ts +1 -6
  65. package/lib/typescript/src/components/EmptyState/EmptyState.d.ts +6 -1
  66. package/lib/typescript/src/components/LinearMeter/LinearMeter.d.ts +1 -1
  67. package/lib/typescript/src/components/Nudge/Nudge.d.ts +31 -0
  68. package/lib/typescript/src/components/OTP/OTP.d.ts +36 -0
  69. package/lib/typescript/src/components/PaymentFeedback/PaymentFeedback.d.ts +23 -0
  70. package/lib/typescript/src/components/PortfolioHero/PortfolioHero.d.ts +21 -0
  71. package/lib/typescript/src/components/ProductLabel/ProductLabel.d.ts +14 -0
  72. package/lib/typescript/src/components/ProgressBadge/ProgressBadge.d.ts +36 -0
  73. package/lib/typescript/src/components/ProgressBadge/index.d.ts +3 -0
  74. package/lib/typescript/src/components/RechargeCard/RechargeCard.d.ts +1 -2
  75. package/lib/typescript/src/components/SegmentedControl/SegmentedControl.d.ts +49 -0
  76. package/lib/typescript/src/components/StatItem/StatItem.d.ts +21 -0
  77. package/lib/typescript/src/components/SupportText/SupportText.d.ts +1 -1
  78. package/lib/typescript/src/components/SupportText/SupportTextIcon.d.ts +1 -1
  79. package/lib/typescript/src/components/SwappableAmount/SwappableAmount.d.ts +22 -0
  80. package/lib/typescript/src/components/Text/Text.d.ts +16 -0
  81. package/lib/typescript/src/components/Title/Title.d.ts +16 -0
  82. package/lib/typescript/src/components/Toggle/Toggle.d.ts +29 -0
  83. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +3 -1
  84. package/lib/typescript/src/components/index.d.ts +22 -5
  85. package/lib/typescript/src/icons/registry.d.ts +1 -1
  86. package/lib/typescript/src/index.d.ts +1 -0
  87. package/lib/typescript/src/utils/index.d.ts +2 -0
  88. package/package.json +2 -2
  89. package/src/components/AmountInput/AmountInput.tsx +81 -0
  90. package/src/components/AmountInput/index.ts +2 -0
  91. package/src/components/Button/Button.tsx +27 -20
  92. package/src/components/CardProviderInfo/CardProviderInfo.tsx +81 -0
  93. package/src/components/ChipSelect/ChipSelect.tsx +1 -8
  94. package/src/components/Drawer/demo.xml +18 -0
  95. package/src/components/EmptyState/EmptyState.tsx +7 -1
  96. package/src/components/FormField/FormField.tsx +1 -0
  97. package/src/components/LinearMeter/LinearMeter.tsx +1 -1
  98. package/src/components/NoteInput/NoteInput.tsx +1 -1
  99. package/src/components/Nudge/Nudge.tsx +150 -0
  100. package/src/components/OTP/OTP.tsx +275 -0
  101. package/src/components/PaymentFeedback/PaymentFeedback.tsx +168 -0
  102. package/src/components/PortfolioHero/PortfolioHero.tsx +91 -0
  103. package/src/components/ProductLabel/ProductLabel.tsx +58 -0
  104. package/src/components/ProgressBadge/ProgressBadge.tsx +172 -0
  105. package/src/components/ProgressBadge/index.ts +2 -0
  106. package/src/components/RechargeCard/RechargeCard.tsx +1 -1
  107. package/src/components/SegmentedControl/SegmentedControl.tsx +168 -0
  108. package/src/components/StatItem/StatItem.tsx +71 -0
  109. package/src/components/SupportText/SupportText.tsx +1 -1
  110. package/src/components/SupportText/SupportTextIcon.tsx +4 -3
  111. package/src/components/SwappableAmount/SwappableAmount.tsx +92 -0
  112. package/src/components/Text/Text.tsx +57 -0
  113. package/src/components/{PageTitle/PageTitle.tsx → Title/Title.tsx} +25 -19
  114. package/src/components/Toggle/Toggle.tsx +122 -0
  115. package/src/components/UpiHandle/UpiHandle.tsx +6 -2
  116. package/src/components/index.ts +22 -5
  117. package/src/design-tokens/Coin Variables-variables-full.json +1 -0
  118. package/src/design-tokens/figma-variables-resolver.ts +1 -1
  119. package/src/icons/registry.ts +1 -1
  120. package/src/index.ts +1 -0
  121. package/src/utils/index.ts +1 -0
  122. package/lib/commonjs/design-tokens/JFS Variables-variables-full.json +0 -1
  123. package/lib/module/design-tokens/JFS Variables-variables-full.json +0 -1
  124. package/lib/typescript/src/components/PageTitle/PageTitle.d.ts +0 -29
  125. package/src/design-tokens/JFS Variables-variables-full.json +0 -1
@@ -0,0 +1,172 @@
1
+ import React from 'react'
2
+ import {
3
+ View,
4
+ Text,
5
+ type StyleProp,
6
+ type ViewStyle,
7
+ type TextStyle,
8
+ } from 'react-native'
9
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
10
+ import Icon from '../../icons/Icon'
11
+ import { cloneChildrenWithModes } from '../../utils/react-utils'
12
+
13
+ export type ProgressBadgeProps = {
14
+ /** The text displayed in the badge (e.g. "Live price...") */
15
+ taskName?: string
16
+ /** The icon name to display to the left of the text */
17
+ iconName?: string
18
+ /** The progress value between 0 and 100 */
19
+ value?: number
20
+ /** Modes object passed to `getVariableByName` for design token resolution */
21
+ modes?: Record<string, any>
22
+ /** Optional container style overrides */
23
+ style?: StyleProp<ViewStyle>
24
+ /** Optional text style overrides */
25
+ textStyle?: StyleProp<TextStyle>
26
+ /** Accessibility label for screen readers */
27
+ accessibilityLabel?: string
28
+ } & React.ComponentProps<typeof View>
29
+
30
+ /**
31
+ * ProgressBadge component that displays an icon, text, and an internal progress bar.
32
+ *
33
+ * All visual attributes resolve from Figma tokens via `getVariableByName` using the provided `modes`.
34
+ *
35
+ * @component
36
+ * @param {Object} props
37
+ * @param {string} [props.taskName="Live price: [price] (00:43)"] - The text displayed.
38
+ * @param {string} [props.iconName="ic_live"] - Icon name from the registry.
39
+ * @param {number} [props.value=0] - The progress value between 0 and 100.
40
+ * @param {Object} [props.modes={}] - Modes object passed to `getVariableByName` for design tokens.
41
+ * @param {Object} [props.style] - Optional container style overrides.
42
+ * @param {Object} [props.textStyle] - Optional text style overrides.
43
+ * @param {string} [props.accessibilityLabel] - Accessibility label.
44
+ */
45
+ function ProgressBadge({
46
+ taskName = 'Live price: [price] (00:43)',
47
+ iconName = 'ic_live',
48
+ value = 0,
49
+ modes = {},
50
+ style,
51
+ textStyle: textStyleOverride,
52
+ accessibilityLabel,
53
+ ...rest
54
+ }: ProgressBadgeProps) {
55
+ // Resolve layout tokens
56
+ const backgroundColor =
57
+ getVariableByName('progressBadge/background', modes) || '#ffffff'
58
+ const progressColor =
59
+ getVariableByName('progressBadge/progress/color', modes) || '#ebebed'
60
+ const gap = getVariableByName('progressBadge/gap', modes) ?? 12
61
+ const paddingHorizontal =
62
+ getVariableByName('progressBadge/padding/horizontal', modes) ?? 16
63
+ const paddingVertical =
64
+ getVariableByName('progressBadge/padding/vertical', modes) ?? 6
65
+ const borderRadius = getVariableByName('progressBadge/radius', modes) ?? 999
66
+ const descriptionGap =
67
+ getVariableByName('progressBadge/description/gap', modes) ?? 8
68
+
69
+ // Resolve typography tokens
70
+ const fontFamily =
71
+ getVariableByName('progressBadge/fontFamily', modes) || 'JioType_Var:Medium'
72
+ const fontWeightRaw = getVariableByName('progressBadge/fontWeight', modes) ?? 500
73
+ const fontWeight =
74
+ typeof fontWeightRaw === 'number'
75
+ ? fontWeightRaw.toString()
76
+ : fontWeightRaw
77
+ const fontSize = getVariableByName('progressBadge/fontSize', modes) ?? 14
78
+ const lineHeight = getVariableByName('progressBadge/lineHeight', modes) ?? 17
79
+ const textColor =
80
+ getVariableByName('progressBadge/foreground', modes) || '#000000'
81
+
82
+ // Resolve icon tokens
83
+ const iconColor =
84
+ getVariableByName('progressBadge/icon/color', modes) || '#f50030'
85
+ const iconSize = getVariableByName('progressBadge/icon/size', modes) ?? 18
86
+
87
+ const containerStyle: ViewStyle = {
88
+ backgroundColor,
89
+ flexDirection: 'row',
90
+ alignItems: 'center',
91
+ gap,
92
+ paddingHorizontal,
93
+ paddingVertical,
94
+ borderRadius,
95
+ overflow: 'hidden',
96
+ position: 'relative',
97
+ flexWrap: 'wrap',
98
+ }
99
+
100
+ const descriptionContainerStyle: ViewStyle = {
101
+ flexDirection: 'row',
102
+ alignItems: 'center',
103
+ justifyContent: 'center',
104
+ gap: descriptionGap,
105
+ flex: 1,
106
+ paddingVertical: 0,
107
+ minHeight: 1,
108
+ minWidth: 1,
109
+ position: 'relative',
110
+ }
111
+
112
+ const textStyle: TextStyle = {
113
+ fontFamily,
114
+ fontWeight,
115
+ fontSize,
116
+ lineHeight,
117
+ color: textColor,
118
+ textAlign: 'center',
119
+ overflow: 'hidden',
120
+ flexShrink: 0,
121
+ }
122
+
123
+ // Ensure value is between 0 and 100
124
+ const clampedValue = Math.max(0, Math.min(100, value))
125
+
126
+ const progressStyle: ViewStyle = {
127
+ position: 'absolute',
128
+ left: 0,
129
+ top: 0,
130
+ bottom: 0,
131
+ width: `${clampedValue}%`,
132
+ backgroundColor: progressColor,
133
+ }
134
+
135
+ const defaultAccessibilityLabel = accessibilityLabel || taskName
136
+
137
+ return (
138
+ <View
139
+ style={[containerStyle, style]}
140
+ accessibilityRole="text"
141
+ accessibilityLabel={defaultAccessibilityLabel}
142
+ {...rest}
143
+ >
144
+ {/* Background Progress Bar */}
145
+ <View style={progressStyle} pointerEvents="none" />
146
+
147
+ {/* Description Header */}
148
+ <View style={descriptionContainerStyle}>
149
+ {iconName ? (
150
+ <Icon
151
+ name={iconName}
152
+ size={iconSize}
153
+ color={iconColor}
154
+ accessibilityElementsHidden={true}
155
+ importantForAccessibility="no"
156
+ />
157
+ ) : null}
158
+ <Text
159
+ style={[textStyle, textStyleOverride]}
160
+ numberOfLines={1}
161
+ ellipsizeMode="tail"
162
+ accessibilityElementsHidden={true}
163
+ importantForAccessibility="no"
164
+ >
165
+ {taskName}
166
+ </Text>
167
+ </View>
168
+ </View>
169
+ )
170
+ }
171
+
172
+ export default ProgressBadge
@@ -0,0 +1,2 @@
1
+ export { default } from './ProgressBadge'
2
+ export * from './ProgressBadge'
@@ -7,7 +7,7 @@ import MoneyValue from '../MoneyValue/MoneyValue';
7
7
  import Button from '../Button/Button';
8
8
 
9
9
 
10
- type RechargeCardProps = {
10
+ export type RechargeCardProps = {
11
11
  /**
12
12
  * Title of the card.
13
13
  * Default: "Unlimited 5G"
@@ -0,0 +1,168 @@
1
+ import React, { useState, useCallback } from 'react'
2
+ import {
3
+ View,
4
+ Pressable,
5
+ Text,
6
+ type StyleProp,
7
+ type ViewStyle,
8
+ type TextStyle,
9
+ } from 'react-native'
10
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
11
+
12
+ export type SegmentedControlItem = {
13
+ key: React.Key
14
+ label: string
15
+ }
16
+
17
+ export type SegmentedControlProps = {
18
+ /** The items to display as segments */
19
+ items: SegmentedControlItem[]
20
+ /** The currently selected key (controlled) */
21
+ selectedKey?: React.Key
22
+ /** The initially selected key (uncontrolled). Defaults to the first item's key. */
23
+ defaultSelectedKey?: React.Key
24
+ /** Callback fired when the selected segment changes */
25
+ onSelectionChange?: (key: React.Key) => void
26
+ /** Design token modes for theming */
27
+ modes?: Record<string, any>
28
+ /** Override container styles */
29
+ style?: StyleProp<ViewStyle>
30
+ }
31
+
32
+ function SegmentedControlSegment({
33
+ label,
34
+ active,
35
+ onPress,
36
+ modes = {},
37
+ }: {
38
+ label: string
39
+ active: boolean
40
+ onPress: () => void
41
+ modes: Record<string, any>
42
+ }) {
43
+ const resolvedModes = {
44
+ ...modes,
45
+ 'SegmentedControl/Segment': active ? 'Active' : 'Idle',
46
+ }
47
+
48
+ const paddingHorizontal = (getVariableByName('segment/padding/horizontal', resolvedModes) ?? 16) as number
49
+ const paddingVertical = (getVariableByName('segment/padding/vertical', resolvedModes) ?? 12) as number
50
+ const radius = (getVariableByName('segment/radius', resolvedModes) ?? 20) as number
51
+ const background = (getVariableByName('segment/background', resolvedModes) ?? (active ? '#5d00b5' : 'transparent')) as string
52
+ const foreground = (getVariableByName('segment/foreground', resolvedModes) ?? (active ? '#ffffff' : '#0c0d10')) as string
53
+ const fontSize = (getVariableByName('segment/fontSize', resolvedModes) ?? 16) as number
54
+ const fontFamily = (getVariableByName('segment/fontFamily', resolvedModes) ?? 'JioType Var') as string
55
+ const lineHeight = (getVariableByName('segment/lineHeight', resolvedModes) ?? 19) as number
56
+ const fontWeight = (getVariableByName('segment/fontWeight', resolvedModes) ?? '500') as string
57
+
58
+ const segmentStyle: ViewStyle = {
59
+ flex: 1,
60
+ alignItems: 'center',
61
+ justifyContent: 'center',
62
+ paddingHorizontal,
63
+ paddingVertical,
64
+ borderRadius: radius,
65
+ backgroundColor: background,
66
+ }
67
+
68
+ const textStyle: TextStyle = {
69
+ color: foreground,
70
+ fontFamily,
71
+ fontSize,
72
+ lineHeight,
73
+ fontWeight: fontWeight as TextStyle['fontWeight'],
74
+ }
75
+
76
+ return (
77
+ <Pressable
78
+ style={({ pressed }) => [segmentStyle, pressed && { opacity: 0.8 }]}
79
+ onPress={onPress}
80
+ accessibilityRole="tab"
81
+ accessibilityState={{ selected: active }}
82
+ accessibilityLabel={label}
83
+ >
84
+ <Text style={textStyle}>{label}</Text>
85
+ </Pressable>
86
+ )
87
+ }
88
+
89
+ /**
90
+ * SegmentedControl component backed by Figma design tokens.
91
+ *
92
+ * Provides a horizontal row of mutually exclusive segments.
93
+ * Supports controlled (`selectedKey` + `onSelectionChange`) and
94
+ * uncontrolled (`defaultSelectedKey`) usage patterns.
95
+ *
96
+ * @component
97
+ * @param {SegmentedControlProps} props
98
+ *
99
+ * @example
100
+ * ```tsx
101
+ * const [selected, setSelected] = useState<React.Key>('daily');
102
+ *
103
+ * <SegmentedControl
104
+ * items={[
105
+ * { key: 'daily', label: 'Daily' },
106
+ * { key: 'weekly', label: 'Weekly' },
107
+ * { key: 'monthly', label: 'Monthly' },
108
+ * ]}
109
+ * selectedKey={selected}
110
+ * onSelectionChange={setSelected}
111
+ * modes={{ 'Color Mode': 'Light' }}
112
+ * />
113
+ * ```
114
+ */
115
+ function SegmentedControl({
116
+ items,
117
+ selectedKey: controlledSelectedKey,
118
+ defaultSelectedKey,
119
+ onSelectionChange,
120
+ modes = {},
121
+ style,
122
+ }: SegmentedControlProps) {
123
+ const isControlled = controlledSelectedKey !== undefined
124
+ const [internalSelectedKey, setInternalSelectedKey] = useState<React.Key | undefined>(
125
+ defaultSelectedKey ?? items[0]?.key
126
+ )
127
+
128
+ const currentSelectedKey = isControlled ? controlledSelectedKey : internalSelectedKey
129
+
130
+ const handlePress = useCallback(
131
+ (key: React.Key) => {
132
+ if (!isControlled) {
133
+ setInternalSelectedKey(key)
134
+ }
135
+ onSelectionChange?.(key)
136
+ },
137
+ [isControlled, onSelectionChange]
138
+ )
139
+
140
+ const gap = (getVariableByName('segmentedControl/gap', modes) ?? 8) as number
141
+ const background = (getVariableByName('segmentedControl/background', modes) ?? '#f6f3ff') as string
142
+ const radius = (getVariableByName('segmentedControl/radius', modes) ?? 24) as number
143
+
144
+ const containerStyle: ViewStyle = {
145
+ flexDirection: 'row',
146
+ alignItems: 'center',
147
+ backgroundColor: background,
148
+ borderRadius: radius,
149
+ gap,
150
+ overflow: 'hidden',
151
+ }
152
+
153
+ return (
154
+ <View style={[containerStyle, style]} accessibilityRole="tablist">
155
+ {items.map((item) => (
156
+ <SegmentedControlSegment
157
+ key={String(item.key)}
158
+ label={item.label}
159
+ active={item.key === currentSelectedKey}
160
+ onPress={() => handlePress(item.key)}
161
+ modes={modes}
162
+ />
163
+ ))}
164
+ </View>
165
+ )
166
+ }
167
+
168
+ export default SegmentedControl
@@ -0,0 +1,71 @@
1
+ import React from 'react'
2
+ import { View, Text, type StyleProp, type ViewStyle } from 'react-native'
3
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
+
5
+ export type StatItemProps = {
6
+ /** The small descriptive label above the value. */
7
+ label?: string
8
+ /** The large prominent value to display. */
9
+ value?: string
10
+ /** Design token modes for theming. */
11
+ modes?: Record<string, any>
12
+ /** Override container styles. */
13
+ style?: StyleProp<ViewStyle>
14
+ }
15
+
16
+ /**
17
+ * StatItem displays a label/value pair with the value in a large, bold style.
18
+ * Useful for metrics, product stats, or KPI callouts.
19
+ *
20
+ * @component
21
+ * @param {StatItemProps} props
22
+ */
23
+ function StatItem({
24
+ label = 'Purity verified by NABL',
25
+ value = '99.99%',
26
+ modes = {},
27
+ style,
28
+ }: StatItemProps) {
29
+ const gap = getVariableByName('statItem/gap', modes) ?? 2
30
+
31
+ const labelForeground = getVariableByName('statItem/label/foreground', modes) ?? '#1a1c1f'
32
+ const labelFontFamily = getVariableByName('statItem/label/fontFamily', modes) ?? 'JioType Var'
33
+ const labelFontSize = getVariableByName('statItem/label/fontSize', modes) ?? 12
34
+ const labelFontWeight = getVariableByName('statItem/label/fontWeight', modes) ?? '500'
35
+ const labelLineHeight = getVariableByName('statItem/label/lineHeight', modes) ?? 16
36
+
37
+ const valueForeground = getVariableByName('statItem/value/foreground', modes) ?? '#0d0d0f'
38
+ const valueFontFamily = getVariableByName('statItem/value/fontFamily', modes) ?? 'JioType Var'
39
+ const valueFontSize = getVariableByName('statItem/value/fontSize', modes) ?? 26
40
+ const valueFontWeight = getVariableByName('statItem/value/fontWeight', modes) ?? '900'
41
+ const valueLineHeight = getVariableByName('statItem/value/lineHeight', modes) ?? 26
42
+
43
+ return (
44
+ <View style={[{ gap: gap as number }, style]}>
45
+ <Text
46
+ style={{
47
+ color: labelForeground as string,
48
+ fontFamily: labelFontFamily as string,
49
+ fontSize: labelFontSize as number,
50
+ fontWeight: String(labelFontWeight) as any,
51
+ lineHeight: labelLineHeight as number,
52
+ }}
53
+ >
54
+ {label}
55
+ </Text>
56
+ <Text
57
+ style={{
58
+ color: valueForeground as string,
59
+ fontFamily: valueFontFamily as string,
60
+ fontSize: valueFontSize as number,
61
+ fontWeight: String(valueFontWeight) as any,
62
+ lineHeight: valueLineHeight as number,
63
+ }}
64
+ >
65
+ {value}
66
+ </Text>
67
+ </View>
68
+ )
69
+ }
70
+
71
+ export default StatItem
@@ -10,7 +10,7 @@ export type SupportTextProps = {
10
10
  */
11
11
  label?: string;
12
12
  /**
13
- * Status of the support text (Neutral, Warning, Error, Success)
13
+ * Status of the support text (Neutral, Warning, Error, Success, Loading)
14
14
  */
15
15
  status?: SupportTextStatus;
16
16
  /**
@@ -3,7 +3,7 @@ import { View, type ViewStyle } from 'react-native';
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
4
4
  import Icon from '../../icons/Icon';
5
5
 
6
- export type SupportTextStatus = 'Neutral' | 'Warning' | 'Error' | 'Success';
6
+ export type SupportTextStatus = 'Neutral' | 'Warning' | 'Error' | 'Success' | 'Loading';
7
7
 
8
8
  export type SupportTextIconProps = {
9
9
  status?: SupportTextStatus;
@@ -13,9 +13,10 @@ export type SupportTextIconProps = {
13
13
 
14
14
  const STATUS_ICON_MAP: Record<SupportTextStatus, string> = {
15
15
  Neutral: 'ic_info',
16
- Warning: 'ic_warning', // Using ic_warning for Warning
17
- Error: 'ic_warning', // Using ic_warning for Error
16
+ Warning: 'ic_warning',
17
+ Error: 'ic_warning',
18
18
  Success: 'ic_status_successful',
19
+ Loading: 'ic_time',
19
20
  };
20
21
 
21
22
  function SupportTextIcon({
@@ -0,0 +1,92 @@
1
+ import React from 'react'
2
+ import { View, Text, type ViewStyle, type TextStyle } from 'react-native'
3
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
+ import Button from '../Button/Button'
5
+
6
+ export type SwappableAmountProps = {
7
+ /** Large display value (e.g. "49g"). */
8
+ value?: string
9
+ /** Whether to show the schedule button above the value. */
10
+ schedule?: boolean
11
+ /** Label text for the schedule button (e.g. "Weekly on Mondays"). */
12
+ scheduleLabel?: string
13
+ /** Label text for the amount/swap button (e.g. "₹5100"). */
14
+ amountLabel?: string
15
+ /** Callback when the schedule button is pressed. */
16
+ onSchedulePress?: () => void
17
+ /** Callback when the amount/swap button is pressed. */
18
+ onAmountPress?: () => void
19
+ /** Modes configuration for design token resolution. */
20
+ modes?: Record<string, any>
21
+ /** Container style override. */
22
+ style?: ViewStyle
23
+ }
24
+
25
+ function SwappableAmount({
26
+ value = '49g',
27
+ schedule = false,
28
+ scheduleLabel = 'Weekly on Mondays',
29
+ amountLabel = '₹5100',
30
+ onSchedulePress,
31
+ onAmountPress,
32
+ modes = {},
33
+ style,
34
+ }: SwappableAmountProps) {
35
+ const gap = getVariableByName('swappableAmount/gap', modes) ?? 24
36
+ const padding = getVariableByName('swappableAmount/padding', modes) ?? 8
37
+
38
+ const foreground = getVariableByName('swappableAmount/foreground', modes) ?? '#0d0d0f'
39
+ const fontSize = getVariableByName('swappableAmount/fontSize', modes) ?? 56
40
+ const fontFamily = getVariableByName('swappableAmount/fontFamily', modes) ?? 'System'
41
+ const fontWeight = getVariableByName('swappableAmount/fontWeight', modes) ?? 900
42
+ const lineHeight = getVariableByName('swappableAmount/lineHeight', modes) ?? 56
43
+
44
+ const containerStyle: ViewStyle = {
45
+ flexDirection: 'column',
46
+ alignItems: 'center',
47
+ justifyContent: 'center',
48
+ gap: gap as number,
49
+ padding: padding as number,
50
+ }
51
+
52
+ const valueTextStyle: TextStyle = {
53
+ color: foreground as string,
54
+ fontSize: fontSize as number,
55
+ fontFamily: fontFamily as string,
56
+ fontWeight: String(fontWeight) as TextStyle['fontWeight'],
57
+ lineHeight: lineHeight as number,
58
+ }
59
+
60
+ return (
61
+ <View style={[containerStyle, style]}>
62
+ {schedule && (
63
+ <Button
64
+ label={scheduleLabel}
65
+ icon="ic_calendar_week"
66
+ onPress={onSchedulePress}
67
+ modes={{
68
+ ...modes,
69
+ AppearanceBrand: 'Neutral',
70
+ Emphasis: 'Low',
71
+ 'Button / Size': 'S',
72
+ }}
73
+ />
74
+ )}
75
+
76
+ <Text style={valueTextStyle}>{value}</Text>
77
+
78
+ <Button
79
+ label={amountLabel}
80
+ icon="ic_data_in_out"
81
+ onPress={onAmountPress}
82
+ modes={{
83
+ ...modes,
84
+ Emphasis: 'Medium',
85
+ AppearanceBrand: 'Secondary',
86
+ }}
87
+ />
88
+ </View>
89
+ )
90
+ }
91
+
92
+ export default SwappableAmount
@@ -0,0 +1,57 @@
1
+ import React from 'react'
2
+ import { Text as RNText, type TextStyle, type StyleProp } from 'react-native'
3
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
+
5
+ export type TextProps = {
6
+ /** The text content to display. */
7
+ text?: string
8
+ /** Horizontal alignment of the text. */
9
+ textAlign?: 'Left' | 'Center'
10
+ /** Modes configuration for design token resolution. */
11
+ modes?: Record<string, any>
12
+ /** Style override for the text. */
13
+ style?: StyleProp<TextStyle>
14
+ /** Number of lines to limit the text to. */
15
+ numberOfLines?: number
16
+ }
17
+
18
+ const TEXT_ALIGN_MAP: Record<NonNullable<TextProps['textAlign']>, TextStyle['textAlign']> = {
19
+ Left: 'left',
20
+ Center: 'center',
21
+ }
22
+
23
+ function Text({
24
+ text = 'Korem ipsum ',
25
+ textAlign = 'Left',
26
+ modes = {},
27
+ style,
28
+ numberOfLines,
29
+ }: TextProps) {
30
+ const foreground = getVariableByName('text/foreground', modes) ?? '#000000'
31
+ const fontFamily = getVariableByName('text/fontFamily', modes) ?? 'JioType'
32
+ const fontSize = getVariableByName('text/fontSize', modes) ?? 14
33
+ const fontWeight = getVariableByName('text/fontWeight', modes) ?? '500'
34
+ const lineHeight = getVariableByName('text/lineHeight', modes) ?? 20
35
+ const letterSpacing = getVariableByName('text/letterSpacing', modes) ?? -0.5
36
+
37
+ const textStyle: TextStyle = {
38
+ color: foreground as string,
39
+ fontFamily: fontFamily as string,
40
+ fontSize: fontSize as number,
41
+ fontWeight: String(fontWeight) as TextStyle['fontWeight'],
42
+ lineHeight: lineHeight as number,
43
+ letterSpacing: letterSpacing as number,
44
+ textAlign: TEXT_ALIGN_MAP[textAlign],
45
+ }
46
+
47
+ return (
48
+ <RNText
49
+ style={[textStyle, style]}
50
+ numberOfLines={numberOfLines}
51
+ >
52
+ {text}
53
+ </RNText>
54
+ )
55
+ }
56
+
57
+ export default Text