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
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.EMPTY_MODES = void 0;
7
7
  exports.cloneChildrenWithModes = cloneChildrenWithModes;
8
8
  exports.flattenChildren = flattenChildren;
9
+ exports.mergeRefs = mergeRefs;
9
10
  var _react = _interopRequireDefault(require("react"));
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
12
  /**
@@ -79,6 +80,27 @@ function cloneChildrenWithModes(children, modes, forcedModes) {
79
80
  return _react.default.Children.toArray(result);
80
81
  }
81
82
 
83
+ /**
84
+ * Combines several refs (object refs and/or callback refs) into a single
85
+ * callback ref. Useful when a component needs to keep its own internal ref to a
86
+ * node while still honouring a ref forwarded by the consumer.
87
+ *
88
+ * @example
89
+ * const inputRef = useRef<RNTextInput>(null)
90
+ * <RNTextInput ref={mergeRefs(inputRef, forwardedRef)} />
91
+ */
92
+ function mergeRefs(...refs) {
93
+ return value => {
94
+ refs.forEach(ref => {
95
+ if (typeof ref === 'function') {
96
+ ref(value);
97
+ } else if (ref != null) {
98
+ ref.current = value;
99
+ }
100
+ });
101
+ };
102
+ }
103
+
82
104
  /**
83
105
  * Flattens React children, extracting them from Fragments.
84
106
  * Useful for Group components that need to process individual items (e.g., for layout or styling)
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import React from 'react';
3
+ import React, { forwardRef } from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
@@ -13,12 +13,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  *
14
14
  * @component
15
15
  */
16
- export default function AmountInput({
16
+ const AmountInput = /*#__PURE__*/forwardRef(function AmountInput({
17
17
  moneyValueSlot,
18
18
  noteInputSlot,
19
19
  modes: propModes = EMPTY_MODES,
20
20
  style
21
- }) {
21
+ }, ref) {
22
22
  const {
23
23
  modes: globalModes
24
24
  } = useTokens();
@@ -72,7 +72,9 @@ export default function AmountInput({
72
72
  return noteInputSlot;
73
73
  };
74
74
  return /*#__PURE__*/_jsxs(View, {
75
+ ref: ref,
75
76
  style: containerStyle,
76
77
  children: [renderMoneyValueSlot(), renderNoteInputSlot()]
77
78
  });
78
- }
79
+ });
80
+ export default AmountInput;
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { View, Text as RNText, Pressable, StyleSheet } from 'react-native';
5
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import Icon from '../Icon/Icon';
8
+ import Text from '../Text/Text';
9
+ import ListItem from '../ListItem/ListItem';
10
+ import Divider from '../Divider/Divider';
11
+ import Button from '../Button/Button';
12
+
13
+ /**
14
+ * A single benefit row rendered with the shared `ListItem` primitive: a
15
+ * leading icon, a title and an optional right-aligned trailing value.
16
+ */
17
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
+ /**
19
+ * BenefitCard — Figma node 5352:1077 ("Benefit Card").
20
+ *
21
+ * A white, rounded card that summarises the rewards a user will earn. It is
22
+ * composed entirely from the shared design-system primitives so it stays in
23
+ * sync with the rest of the library:
24
+ *
25
+ * - **Header** — a section title + a single highlighted {@link ListItem}
26
+ * (leading `Icon`, title, right-aligned trailing value) followed by a
27
+ * `Divider`.
28
+ * - **Body** — a section title + a column of benefit {@link ListItem}s. The
29
+ * list is a real slot: pass `children` to fully control it, or `items` for
30
+ * the declarative path.
31
+ * - **CTA** — a small {@link Button} (Figma `Button / Size = S`).
32
+ *
33
+ * The list rows resolve through the `List Item Style: Minimal` mode (12px /
34
+ * regular title, 4px gap, no padding) and the leading icons use the
35
+ * `AppearanceBrand: Secondary` brand color, exactly matching the design. All
36
+ * three defaults can be overridden via `modes`.
37
+ */
38
+ function BenefitCard({
39
+ headerTitle = 'You will earn',
40
+ headerItem,
41
+ showHeader = true,
42
+ bodyTitle = 'Upgrade to JioFinance+ and earn more',
43
+ items,
44
+ children,
45
+ buttonLabel = 'Upgrade',
46
+ onButtonPress,
47
+ button,
48
+ showButton = true,
49
+ onPress,
50
+ width = 344,
51
+ modes = EMPTY_MODES,
52
+ style,
53
+ accessibilityLabel
54
+ }) {
55
+ const tokens = useMemo(() => resolveTokens(modes), [modes]);
56
+
57
+ // Sub-component modes. Consumer-supplied `modes` always win via spread order.
58
+ const listItemModes = useMemo(() => ({
59
+ 'List Item Style': 'Minimal',
60
+ ...modes
61
+ }), [modes]);
62
+ const iconModes = useMemo(() => ({
63
+ AppearanceBrand: 'Secondary',
64
+ ...modes
65
+ }), [modes]);
66
+ const trailingTextModes = useMemo(() => ({
67
+ 'Text Sizes': 'Small',
68
+ Weight: 'Regular',
69
+ ...modes
70
+ }), [modes]);
71
+ const ctaModes = useMemo(() => ({
72
+ 'Button / Size': 'S',
73
+ ...modes
74
+ }), [modes]);
75
+ const renderItem = (item, key) => {
76
+ const leading = item.leading ?? (item.icon != null ? /*#__PURE__*/_jsx(Icon, {
77
+ iconName: item.icon,
78
+ color: item.iconColor,
79
+ modes: iconModes
80
+ }) : null);
81
+ const trailing = item.trailing ?? (item.trailingText != null ? /*#__PURE__*/_jsx(Text, {
82
+ modes: trailingTextModes,
83
+ children: item.trailingText
84
+ }) : undefined);
85
+ return /*#__PURE__*/_jsx(ListItem, {
86
+ layout: "Horizontal",
87
+ navArrow: false,
88
+ showSupportText: false,
89
+ title: item.title,
90
+ leading: leading,
91
+ trailing: trailing,
92
+ onPress: item.onPress,
93
+ modes: listItemModes
94
+ }, key);
95
+ };
96
+ const headerNode = showHeader && (headerTitle != null || headerItem != null) ? /*#__PURE__*/_jsxs(View, {
97
+ style: styles.section,
98
+ children: [/*#__PURE__*/_jsxs(View, {
99
+ style: styles.cardHeader,
100
+ children: [headerTitle != null ? /*#__PURE__*/_jsx(RNText, {
101
+ style: tokens.title,
102
+ children: headerTitle
103
+ }) : null, headerItem != null ? renderItem(headerItem, 'header-item') : null]
104
+ }), /*#__PURE__*/_jsx(Divider, {
105
+ modes: modes
106
+ })]
107
+ }) : null;
108
+ const bodyList = children ? cloneChildrenWithModes(children, listItemModes) : (items ?? DEFAULT_ITEMS).map((item, index) => renderItem(item, index));
109
+ const ctaNode = button ?? /*#__PURE__*/_jsx(Button, {
110
+ label: buttonLabel,
111
+ modes: ctaModes,
112
+ onPress: onButtonPress
113
+ });
114
+ const containerStyle = useMemo(() => ({
115
+ ...tokens.container,
116
+ width
117
+ }), [tokens.container, width]);
118
+ const content = /*#__PURE__*/_jsxs(_Fragment, {
119
+ children: [headerNode, /*#__PURE__*/_jsxs(View, {
120
+ style: tokens.body,
121
+ children: [bodyTitle != null ? /*#__PURE__*/_jsx(RNText, {
122
+ style: tokens.title,
123
+ children: bodyTitle
124
+ }) : null, /*#__PURE__*/_jsx(View, {
125
+ style: tokens.listWrap,
126
+ children: bodyList
127
+ })]
128
+ }), showButton ? ctaNode : null]
129
+ });
130
+ if (onPress) {
131
+ return /*#__PURE__*/_jsx(Pressable, {
132
+ style: ({
133
+ pressed
134
+ }) => [containerStyle, pressed ? styles.pressed : null, style],
135
+ accessibilityRole: "button",
136
+ accessibilityLabel: accessibilityLabel ?? headerTitle ?? bodyTitle,
137
+ onPress: onPress,
138
+ children: content
139
+ });
140
+ }
141
+ return /*#__PURE__*/_jsx(View, {
142
+ style: [containerStyle, style],
143
+ accessibilityLabel: accessibilityLabel,
144
+ children: content
145
+ });
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Tokens / static styles
150
+ // ---------------------------------------------------------------------------
151
+
152
+ // The "card header" inner gap (title -> highlighted item) is a fixed 4px in
153
+ // the Figma node and has no dedicated token.
154
+ const CARD_HEADER_GAP = 4;
155
+ function asNum(raw, fallback) {
156
+ const n = typeof raw === 'number' ? raw : parseFloat(raw);
157
+ return Number.isFinite(n) ? n : fallback;
158
+ }
159
+ function asStr(raw, fallback) {
160
+ return raw != null ? String(raw) : fallback;
161
+ }
162
+ function resolveTokens(modes) {
163
+ // NOTE: token names are passed as string literals DIRECTLY to
164
+ // getVariableByName so the `extract-component-tokens` script can statically
165
+ // collect them for the generated docs. Do not refactor these into a helper
166
+ // that receives the name as a variable.
167
+ const background = asStr(getVariableByName('benefitCard/background', modes), '#ffffff');
168
+ const paddingHorizontal = asNum(getVariableByName('benefitCard/padding/horizontal', modes), 12);
169
+ const paddingVertical = asNum(getVariableByName('benefitCard/padding/vertical', modes), 12);
170
+ const radius = asNum(getVariableByName('benefitCard/radius', modes), 12);
171
+ const gap = asNum(getVariableByName('benefitCard/gap', modes), 8);
172
+ const titleColor = asStr(getVariableByName('benefitCard/title/foreground', modes), '#000000');
173
+ const titleSize = asNum(getVariableByName('benefitCard/title/fontsize', modes), 14);
174
+ const titleFamily = asStr(getVariableByName('benefitCard/title/fontFamily', modes), 'JioType Var');
175
+ const titleWeight = asStr(getVariableByName('benefitCard/title/fontWeight', modes), '500');
176
+ return {
177
+ container: {
178
+ backgroundColor: background,
179
+ paddingHorizontal,
180
+ paddingVertical,
181
+ borderRadius: radius,
182
+ gap,
183
+ flexDirection: 'column',
184
+ alignItems: 'flex-start'
185
+ },
186
+ body: {
187
+ alignSelf: 'stretch',
188
+ gap
189
+ },
190
+ listWrap: {
191
+ alignSelf: 'stretch',
192
+ gap
193
+ },
194
+ title: {
195
+ color: titleColor,
196
+ fontSize: titleSize,
197
+ fontFamily: titleFamily,
198
+ fontWeight: titleWeight,
199
+ lineHeight: 20,
200
+ letterSpacing: -0.5,
201
+ includeFontPadding: false
202
+ }
203
+ };
204
+ }
205
+ const DEFAULT_ITEMS = [{
206
+ icon: 'ic_card',
207
+ title: 'Up to ₹5000 cashback'
208
+ }, {
209
+ icon: 'ic_card',
210
+ title: '25% extra JioPoints'
211
+ }];
212
+ const styles = StyleSheet.create({
213
+ section: {
214
+ alignSelf: 'stretch',
215
+ gap: 8
216
+ },
217
+ cardHeader: {
218
+ alignSelf: 'stretch',
219
+ gap: CARD_HEADER_GAP
220
+ },
221
+ pressed: {
222
+ opacity: 0.92
223
+ }
224
+ });
225
+ export default BenefitCard;