jfs-components 0.1.2 → 0.1.8

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 (107) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/lib/commonjs/components/AmountInput/AmountInput.js +8 -5
  3. package/lib/commonjs/components/BenefitCard/BenefitCard.js +231 -0
  4. package/lib/commonjs/components/CcCard/CcCard.js +470 -0
  5. package/lib/commonjs/components/Checkbox/Checkbox.js +4 -3
  6. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +4 -3
  7. package/lib/commonjs/components/CompareTable/CompareTable.js +372 -0
  8. package/lib/commonjs/components/ComparisonBar/ComparisonBar.js +266 -0
  9. package/lib/commonjs/components/DropdownInput/DropdownInput.js +35 -3
  10. package/lib/commonjs/components/FormField/FormField.js +4 -3
  11. package/lib/commonjs/components/InputSearch/InputSearch.js +6 -4
  12. package/lib/commonjs/components/NoteInput/NoteInput.js +6 -5
  13. package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +273 -0
  14. package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.js +263 -0
  15. package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.web.js +116 -0
  16. package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +353 -0
  17. package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +161 -0
  18. package/lib/commonjs/components/Radio/Radio.js +5 -5
  19. package/lib/commonjs/components/Slider/Slider.js +473 -0
  20. package/lib/commonjs/components/TextInput/TextInput.js +13 -8
  21. package/lib/commonjs/components/TextSegment/TextSegment.js +118 -0
  22. package/lib/commonjs/components/index.js +63 -0
  23. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  24. package/lib/commonjs/design-tokens/figma-modes.generated.js +38 -9
  25. package/lib/commonjs/icons/registry.js +1 -1
  26. package/lib/commonjs/utils/react-utils.js +22 -0
  27. package/lib/module/components/AmountInput/AmountInput.js +6 -4
  28. package/lib/module/components/BenefitCard/BenefitCard.js +225 -0
  29. package/lib/module/components/CcCard/CcCard.js +464 -0
  30. package/lib/module/components/Checkbox/Checkbox.js +5 -4
  31. package/lib/module/components/CheckboxItem/CheckboxItem.js +5 -4
  32. package/lib/module/components/CompareTable/CompareTable.js +367 -0
  33. package/lib/module/components/ComparisonBar/ComparisonBar.js +260 -0
  34. package/lib/module/components/DropdownInput/DropdownInput.js +36 -4
  35. package/lib/module/components/FormField/FormField.js +5 -4
  36. package/lib/module/components/InputSearch/InputSearch.js +6 -4
  37. package/lib/module/components/NoteInput/NoteInput.js +7 -6
  38. package/lib/module/components/PdpCcCard/PdpCcCard.js +267 -0
  39. package/lib/module/components/ProductMerchandisingCard/GlassFill.js +257 -0
  40. package/lib/module/components/ProductMerchandisingCard/GlassFill.web.js +111 -0
  41. package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +347 -0
  42. package/lib/module/components/ProjectionMarker/ProjectionMarker.js +156 -0
  43. package/lib/module/components/Radio/Radio.js +5 -4
  44. package/lib/module/components/Slider/Slider.js +468 -0
  45. package/lib/module/components/TextInput/TextInput.js +15 -10
  46. package/lib/module/components/TextSegment/TextSegment.js +113 -0
  47. package/lib/module/components/index.js +9 -0
  48. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  49. package/lib/module/design-tokens/figma-modes.generated.js +38 -9
  50. package/lib/module/icons/registry.js +1 -1
  51. package/lib/module/utils/react-utils.js +21 -0
  52. package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +3 -2
  53. package/lib/typescript/src/components/BenefitCard/BenefitCard.d.ts +93 -0
  54. package/lib/typescript/src/components/CcCard/CcCard.d.ts +137 -0
  55. package/lib/typescript/src/components/Checkbox/Checkbox.d.ts +3 -2
  56. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +2 -2
  57. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +88 -0
  58. package/lib/typescript/src/components/ComparisonBar/ComparisonBar.d.ts +118 -0
  59. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +20 -1
  60. package/lib/typescript/src/components/FormField/FormField.d.ts +2 -2
  61. package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +23 -2
  62. package/lib/typescript/src/components/NoteInput/NoteInput.d.ts +19 -2
  63. package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +84 -0
  64. package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.d.ts +56 -0
  65. package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.web.d.ts +27 -0
  66. package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +81 -0
  67. package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +82 -0
  68. package/lib/typescript/src/components/Radio/Radio.d.ts +3 -2
  69. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +2 -2
  70. package/lib/typescript/src/components/Slider/Slider.d.ts +99 -0
  71. package/lib/typescript/src/components/TextInput/TextInput.d.ts +9 -29
  72. package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +100 -0
  73. package/lib/typescript/src/components/index.d.ts +10 -1
  74. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +22 -2
  75. package/lib/typescript/src/icons/registry.d.ts +1 -1
  76. package/lib/typescript/src/utils/react-utils.d.ts +10 -0
  77. package/package.json +2 -1
  78. package/src/components/AmountInput/AmountInput.tsx +7 -5
  79. package/src/components/BenefitCard/BenefitCard.tsx +309 -0
  80. package/src/components/CcCard/CcCard.tsx +598 -0
  81. package/src/components/Checkbox/Checkbox.tsx +5 -4
  82. package/src/components/CheckboxItem/CheckboxItem.tsx +5 -4
  83. package/src/components/CompareTable/CompareTable.tsx +477 -0
  84. package/src/components/ComparisonBar/ComparisonBar.tsx +356 -0
  85. package/src/components/DropdownInput/DropdownInput.tsx +55 -3
  86. package/src/components/FormField/FormField.tsx +5 -4
  87. package/src/components/InputSearch/InputSearch.tsx +8 -5
  88. package/src/components/NoteInput/NoteInput.tsx +8 -6
  89. package/src/components/PdpCcCard/PdpCcCard.tsx +356 -0
  90. package/src/components/ProductMerchandisingCard/GlassFill.tsx +276 -0
  91. package/src/components/ProductMerchandisingCard/GlassFill.web.tsx +127 -0
  92. package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +423 -0
  93. package/src/components/ProjectionMarker/ProjectionMarker.tsx +277 -0
  94. package/src/components/Radio/Radio.tsx +5 -4
  95. package/src/components/Slider/Slider.tsx +628 -0
  96. package/src/components/TextInput/TextInput.tsx +15 -11
  97. package/src/components/TextSegment/TextSegment.tsx +166 -0
  98. package/src/components/index.ts +10 -1
  99. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  100. package/src/design-tokens/figma-modes.generated.ts +38 -9
  101. package/src/icons/registry.ts +1 -1
  102. package/src/utils/react-utils.ts +23 -0
  103. package/lib/typescript/scripts/extract-component-tokens.d.ts +0 -9
  104. package/lib/typescript/scripts/generate-component-docs.d.ts +0 -9
  105. package/lib/typescript/scripts/generate-icon-registry.d.ts +0 -3
  106. package/lib/typescript/scripts/generate-mode-types.d.ts +0 -2
  107. package/lib/typescript/scripts/retype-modes.d.cts +0 -2
@@ -0,0 +1,277 @@
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 { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
11
+ import type { Modes } from '../../design-tokens'
12
+ import Divider from '../Divider/Divider'
13
+
14
+ /**
15
+ * A value rendered at either end of the marker. A `string`/`number` is rendered
16
+ * with the built-in title typography; any other `ReactNode` (e.g. a
17
+ * `MoneyValue`) is rendered as-is so consumers can fully control presentation.
18
+ */
19
+ type ProjectionMarkerEndValue = React.ReactNode
20
+
21
+ export type ProjectionMarkerProps = {
22
+ /**
23
+ * Value shown on the leading (left) end of the marker — typically the
24
+ * invested/starting amount. Accepts a string for the default styling or any
25
+ * `ReactNode` (e.g. `MoneyValue`) for custom rendering.
26
+ */
27
+ startValue?: ProjectionMarkerEndValue
28
+ /**
29
+ * Value shown on the trailing (right) end of the marker — typically the
30
+ * projected/ending amount.
31
+ */
32
+ endValue?: ProjectionMarkerEndValue
33
+ /**
34
+ * Primary line inside the center badge — typically the duration
35
+ * (e.g. `"1Y 10M"`).
36
+ */
37
+ duration?: React.ReactNode
38
+ /**
39
+ * Secondary line inside the center badge — typically the rate
40
+ * (e.g. `"@ 8.25 %"`).
41
+ */
42
+ rate?: React.ReactNode
43
+ /**
44
+ * Whether to render the connector lines between the end values and the
45
+ * center badge. Defaults to `true`.
46
+ */
47
+ showConnectors?: boolean
48
+ /** Design token modes for theming. */
49
+ modes?: Modes
50
+ /** Override the root container styles. */
51
+ style?: StyleProp<ViewStyle>
52
+ /** Override the leading value text styles (only applies to string values). */
53
+ startValueStyle?: StyleProp<TextStyle>
54
+ /** Override the trailing value text styles (only applies to string values). */
55
+ endValueStyle?: StyleProp<TextStyle>
56
+ /** Override the center badge container styles. */
57
+ badgeStyle?: StyleProp<ViewStyle>
58
+ /** Override the duration text styles. */
59
+ durationStyle?: StyleProp<TextStyle>
60
+ /** Override the rate text styles. */
61
+ rateStyle?: StyleProp<TextStyle>
62
+ /** Accessibility label for the whole marker. */
63
+ accessibilityLabel?: string
64
+ }
65
+
66
+ const isTextValue = (value: React.ReactNode): value is string | number =>
67
+ typeof value === 'string' || typeof value === 'number'
68
+
69
+ /**
70
+ * ProjectionMarker renders a start value and an end value connected to a
71
+ * centered badge that summarizes the projection (e.g. a tenure and interest
72
+ * rate). It mirrors the Figma `projectionMarker` component and is commonly used
73
+ * inside "Potential returns" style cards.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * <ProjectionMarker
78
+ * startValue="₹1,00,000"
79
+ * endValue="₹1,25,101"
80
+ * duration="1Y 10M"
81
+ * rate="@ 8.25 %"
82
+ * />
83
+ * ```
84
+ *
85
+ * @example Custom end values via MoneyValue
86
+ * ```tsx
87
+ * <ProjectionMarker
88
+ * startValue={<MoneyValue value="1,00,000" />}
89
+ * endValue={<MoneyValue value="1,25,101" />}
90
+ * duration="1Y 10M"
91
+ * rate="@ 8.25 %"
92
+ * />
93
+ * ```
94
+ */
95
+ function ProjectionMarker({
96
+ startValue = '₹1,00,000',
97
+ endValue = '₹1,25,101',
98
+ duration = '1Y 10M',
99
+ rate = '@ 8.25 %',
100
+ showConnectors = true,
101
+ modes = EMPTY_MODES,
102
+ style,
103
+ startValueStyle,
104
+ endValueStyle,
105
+ badgeStyle,
106
+ durationStyle,
107
+ rateStyle,
108
+ accessibilityLabel,
109
+ }: ProjectionMarkerProps) {
110
+ const titleColor =
111
+ (getVariableByName('projectionMarker/title/color', modes) as string | null) ?? '#000000'
112
+ const titleFontFamily =
113
+ (getVariableByName('projectionMarker/title/fontfamily', modes) as string | null) ??
114
+ 'JioType Var'
115
+ const titleFontSize =
116
+ (getVariableByName('projectionMarker/title/fontsize', modes) as number | null) ?? 14
117
+ const titleFontWeight = String(
118
+ getVariableByName('projectionMarker/title/fontweight', modes) ?? 600
119
+ ) as TextStyle['fontWeight']
120
+
121
+ const durationColor =
122
+ (getVariableByName('projectionMarker/duration/color', modes) as string | null) ?? '#000000'
123
+ const durationFontFamily =
124
+ (getVariableByName('projectionMarker/duration/fontfamily', modes) as string | null) ??
125
+ 'JioType Var'
126
+ const durationFontSize =
127
+ (getVariableByName('projectionMarker/duration/fontsize', modes) as number | null) ?? 12
128
+ const durationFontWeight = String(
129
+ getVariableByName('projectionMarker/duration/fontweight', modes) ?? 500
130
+ ) as TextStyle['fontWeight']
131
+
132
+ const rateColor =
133
+ (getVariableByName('projectionMarker/rate/color', modes) as string | null) ?? '#6b6b6b'
134
+ const rateFontFamily =
135
+ (getVariableByName('metricdata/rate/fontfamily', modes) as string | null) ?? 'JioType Var'
136
+ const rateFontSize =
137
+ (getVariableByName('metricdata/rate/fontsize', modes) as number | null) ?? 11
138
+ const rateFontWeight = String(
139
+ getVariableByName('metricdata/rate/fontweight', modes) ?? 400
140
+ ) as TextStyle['fontWeight']
141
+
142
+ const badgeBg =
143
+ (getVariableByName('projectionMarker/durationWrap/bg/color', modes) as string | null) ??
144
+ '#f5f5f5'
145
+ const badgeBorderColor =
146
+ (getVariableByName('projectionMarker/durationWrap/border/color', modes) as string | null) ??
147
+ '#ebebed'
148
+ const badgeBorderWidth =
149
+ (getVariableByName('metricdata/durationWrap/stroke', modes) as number | null) ?? 1
150
+ const badgeRadius =
151
+ (getVariableByName('metricdata/durationWrap/radius', modes) as number | null) ?? 8
152
+ const badgePaddingHorizontal =
153
+ (getVariableByName('metricdata/durationWrap/padding/horizontal', modes) as number | null) ?? 16
154
+ const badgePaddingVertical =
155
+ (getVariableByName('metricdata/durationWrap/padding/vertical', modes) as number | null) ?? 8
156
+
157
+ const titleTextStyle: TextStyle = {
158
+ color: titleColor,
159
+ fontFamily: titleFontFamily,
160
+ fontSize: titleFontSize,
161
+ fontWeight: titleFontWeight,
162
+ lineHeight: titleFontSize * 1.3,
163
+ }
164
+
165
+ const renderEndValue = (
166
+ value: React.ReactNode,
167
+ overrideStyle: StyleProp<TextStyle>
168
+ ): React.ReactNode => {
169
+ if (value === null || value === undefined) return null
170
+ if (isTextValue(value)) {
171
+ return (
172
+ <Text style={[titleTextStyle, overrideStyle]} numberOfLines={1}>
173
+ {value}
174
+ </Text>
175
+ )
176
+ }
177
+ return cloneChildrenWithModes(value, modes)
178
+ }
179
+
180
+ return (
181
+ <View
182
+ style={[styles.container, style]}
183
+ accessibilityRole="summary"
184
+ accessibilityLabel={accessibilityLabel}
185
+ >
186
+ {renderEndValue(startValue, startValueStyle)}
187
+
188
+ {showConnectors && (
189
+ <Divider direction="horizontal" modes={modes} style={styles.connector} />
190
+ )}
191
+
192
+ <View
193
+ style={[
194
+ styles.badge,
195
+ {
196
+ backgroundColor: badgeBg,
197
+ borderColor: badgeBorderColor,
198
+ borderWidth: badgeBorderWidth,
199
+ borderRadius: badgeRadius,
200
+ paddingHorizontal: badgePaddingHorizontal,
201
+ paddingVertical: badgePaddingVertical,
202
+ },
203
+ badgeStyle,
204
+ ]}
205
+ >
206
+ {duration !== null && duration !== undefined
207
+ ? isTextValue(duration)
208
+ ? (
209
+ <Text
210
+ style={[
211
+ {
212
+ color: durationColor,
213
+ fontFamily: durationFontFamily,
214
+ fontSize: durationFontSize,
215
+ fontWeight: durationFontWeight,
216
+ lineHeight: durationFontSize * 1.2,
217
+ textAlign: 'center',
218
+ },
219
+ durationStyle,
220
+ ]}
221
+ >
222
+ {duration}
223
+ </Text>
224
+ )
225
+ : cloneChildrenWithModes(duration, modes)
226
+ : null}
227
+ {rate !== null && rate !== undefined
228
+ ? isTextValue(rate)
229
+ ? (
230
+ <Text
231
+ style={[
232
+ {
233
+ color: rateColor,
234
+ fontFamily: rateFontFamily,
235
+ fontSize: rateFontSize,
236
+ fontWeight: rateFontWeight,
237
+ lineHeight: rateFontSize * 1.3,
238
+ textAlign: 'center',
239
+ },
240
+ rateStyle,
241
+ ]}
242
+ >
243
+ {rate}
244
+ </Text>
245
+ )
246
+ : cloneChildrenWithModes(rate, modes)
247
+ : null}
248
+ </View>
249
+
250
+ {showConnectors && (
251
+ <Divider direction="horizontal" modes={modes} style={styles.connector} />
252
+ )}
253
+
254
+ {renderEndValue(endValue, endValueStyle)}
255
+ </View>
256
+ )
257
+ }
258
+
259
+ const styles = {
260
+ container: {
261
+ flexDirection: 'row',
262
+ alignItems: 'center',
263
+ width: '100%',
264
+ } as ViewStyle,
265
+ connector: {
266
+ flex: 1,
267
+ alignSelf: 'center',
268
+ marginHorizontal: 16,
269
+ } as ViewStyle,
270
+ badge: {
271
+ flexDirection: 'column',
272
+ alignItems: 'center',
273
+ justifyContent: 'center',
274
+ } as ViewStyle,
275
+ }
276
+
277
+ export default ProjectionMarker
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useState } from 'react'
1
+ import React, { forwardRef, useState } from 'react'
2
2
  import {
3
3
  Pressable,
4
4
  View,
@@ -47,14 +47,14 @@ export interface RadioProps {
47
47
  // Radio
48
48
  // ---------------------------------------------------------------------------
49
49
 
50
- export function Radio({
50
+ export const Radio = forwardRef<View, RadioProps>(function Radio({
51
51
  selected = false,
52
52
  disabled = false,
53
53
  onPress,
54
54
  modes = EMPTY_MODES,
55
55
  style,
56
56
  testID,
57
- }: RadioProps) {
57
+ }: RadioProps, ref: React.Ref<View>) {
58
58
  // ---- Refs & State ----
59
59
  const [hovered, setHovered] = useState(false)
60
60
  const [focused, setFocused] = useState(false)
@@ -206,6 +206,7 @@ export function Radio({
206
206
 
207
207
  return (
208
208
  <Pressable
209
+ ref={ref}
209
210
  testID={testID}
210
211
  disabled={disabled}
211
212
  onPress={onPress}
@@ -223,6 +224,6 @@ export function Radio({
223
224
  <View style={selectorStyle} />
224
225
  </Pressable>
225
226
  )
226
- }
227
+ })
227
228
 
228
229
  export default Radio