jfs-components 0.1.30 → 0.1.33

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 (46) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/D2C.md +118 -0
  3. package/lib/commonjs/components/CategoryCard/CategoryCard.js +264 -0
  4. package/lib/commonjs/components/CompareTable/CompareTable.js +140 -84
  5. package/lib/commonjs/components/ContentSheet/ContentSheet.js +28 -5
  6. package/lib/commonjs/components/CounterBadge/CounterBadge.js +78 -0
  7. package/lib/commonjs/components/FavoriteToggle/FavoriteToggle.js +180 -0
  8. package/lib/commonjs/components/HelloJioInput/HelloJioInput.js +287 -0
  9. package/lib/commonjs/components/ValueBackMetric/ValueBackMetric.js +219 -0
  10. package/lib/commonjs/components/index.js +35 -0
  11. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +40095 -1
  12. package/lib/commonjs/design-tokens/figma-modes.generated.js +3 -0
  13. package/lib/commonjs/icons/registry.js +1 -1
  14. package/lib/module/components/CategoryCard/CategoryCard.js +258 -0
  15. package/lib/module/components/CompareTable/CompareTable.js +140 -84
  16. package/lib/module/components/ContentSheet/ContentSheet.js +29 -6
  17. package/lib/module/components/CounterBadge/CounterBadge.js +73 -0
  18. package/lib/module/components/FavoriteToggle/FavoriteToggle.js +174 -0
  19. package/lib/module/components/HelloJioInput/HelloJioInput.js +281 -0
  20. package/lib/module/components/ValueBackMetric/ValueBackMetric.js +214 -0
  21. package/lib/module/components/index.js +6 -1
  22. package/lib/module/design-tokens/Coin Variables-variables-full.json +40095 -1
  23. package/lib/module/design-tokens/figma-modes.generated.js +3 -0
  24. package/lib/module/icons/registry.js +1 -1
  25. package/lib/typescript/src/components/CategoryCard/CategoryCard.d.ts +72 -0
  26. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +16 -1
  27. package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +7 -1
  28. package/lib/typescript/src/components/CounterBadge/CounterBadge.d.ts +19 -0
  29. package/lib/typescript/src/components/FavoriteToggle/FavoriteToggle.d.ts +66 -0
  30. package/lib/typescript/src/components/HelloJioInput/HelloJioInput.d.ts +111 -0
  31. package/lib/typescript/src/components/ValueBackMetric/ValueBackMetric.d.ts +86 -0
  32. package/lib/typescript/src/components/index.d.ts +5 -0
  33. package/lib/typescript/src/icons/registry.d.ts +1 -1
  34. package/package.json +7 -1
  35. package/scripts/extract-figma-modes.js +359 -0
  36. package/src/components/CategoryCard/CategoryCard.tsx +404 -0
  37. package/src/components/CompareTable/CompareTable.tsx +201 -101
  38. package/src/components/ContentSheet/ContentSheet.tsx +40 -11
  39. package/src/components/CounterBadge/CounterBadge.tsx +95 -0
  40. package/src/components/FavoriteToggle/FavoriteToggle.tsx +243 -0
  41. package/src/components/HelloJioInput/HelloJioInput.tsx +513 -0
  42. package/src/components/ValueBackMetric/ValueBackMetric.tsx +298 -0
  43. package/src/components/index.ts +5 -0
  44. package/src/design-tokens/Coin Variables-variables-full.json +40095 -1
  45. package/src/design-tokens/figma-modes.generated.ts +3 -0
  46. package/src/icons/registry.ts +1 -1
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+
3
+ import React from 'react';
4
+ import { View, Text, Pressable } 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 Link from '../Link/Link';
9
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
10
+ const TITLE_LINE_HEIGHT_RATIO = 1.2;
11
+ const VALUE_LINE_HEIGHT_RATIO = 1.2;
12
+ const CAPTION_LINE_HEIGHT_RATIO = 1.5;
13
+
14
+ // The Figma node binds the header-icon size and the per-part font sizes/weights
15
+ // to `valueBackMetric/*` variables, but those tokens are NOT in the committed
16
+ // variables snapshot (`npm run tokens -- find valueBackMetric` → no matches).
17
+ // They also intentionally differ from the `metricdata/*` typography defaults
18
+ // (e.g. `metricdata/value` resolves to 20px/700, whereas this component's value
19
+ // is 16px/500). So the sizes/weights below are encoded as literal constants
20
+ // matching the Figma design exactly. Colours, gaps and padding DO exist as real
21
+ // `metricdata/*` tokens (and match the design), so those resolve through
22
+ // `getVariableByName` and stay themeable.
23
+ const TITLE_FONT_SIZE = 12;
24
+ const TITLE_FONT_WEIGHT = '500';
25
+ const VALUE_FONT_SIZE = 16;
26
+ const VALUE_FONT_WEIGHT = '500';
27
+ const CAPTION_FONT_SIZE = 12;
28
+ const CAPTION_FONT_WEIGHT = '400';
29
+ const FONT_FAMILY = 'JioType Var';
30
+ const CARD_BACKGROUND = '#ffffff';
31
+ const CARD_MIN_HEIGHT = 82;
32
+ const ICON_SIZE = 18;
33
+ // Figma renders the header glyph flush (all `icon/padding/*` tokens are 0); the
34
+ // shared Icon pulls padding from those tokens, so mirror MetricData and zero it
35
+ // explicitly to keep the icon flush against the title.
36
+ const ICON_PADDING_RESET = {
37
+ paddingLeft: 0,
38
+ paddingRight: 0,
39
+ paddingTop: 0,
40
+ paddingBottom: 0
41
+ };
42
+ /**
43
+ * ValueBackMetric — a compact, left-aligned "value back" card.
44
+ *
45
+ * Stacks a branded header row (icon + `title`, e.g. "JioPoints"), a prominent
46
+ * `value`, a muted `caption`, and an optional bottom `linkLabel` (e.g. "Earn").
47
+ * `value`, `caption` and `linkLabel` each render only when provided; the header
48
+ * (icon + title) always shows.
49
+ *
50
+ * Colours, gaps and padding resolve from the `metricdata/*` tokens; the header
51
+ * glyph from the `icon/*` tokens (default 18px gold); the link entirely from
52
+ * the `link/*` + `text/foreground` tokens via the shared {@link Link}, with
53
+ * `Text Appearance: Secondary` and `Text Sizes: Small` seeded so it renders
54
+ * purple at 12px like the design (caller `modes` win). The per-part font
55
+ * sizes/weights come from the Figma `valueBackMetric/*` variables, which are
56
+ * not yet in the committed token snapshot, so they are encoded as constants
57
+ * matching the design.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * <ValueBackMetric
62
+ * title="JioPoints"
63
+ * value="Value"
64
+ * caption="Earn 10 point with UPI"
65
+ * linkLabel="Earn"
66
+ * onPress={() => navigation.navigate('ValueBack')}
67
+ * onLinkPress={() => navigation.navigate('EarnPoints')}
68
+ * />
69
+ * ```
70
+ */
71
+ function ValueBackMetric({
72
+ icon = 'ic_rupee_coin',
73
+ title = 'JioPoints',
74
+ value,
75
+ caption,
76
+ linkLabel,
77
+ onLinkPress,
78
+ onPress,
79
+ disabled,
80
+ modes = EMPTY_MODES,
81
+ style,
82
+ titleStyle,
83
+ valueStyle,
84
+ captionStyle,
85
+ accessibilityLabel
86
+ }) {
87
+ const titleColor = getVariableByName('metricdata/title/color', modes) ?? '#000000';
88
+ const valueColor = getVariableByName('metricdata/value/color', modes) ?? '#000000';
89
+ const captionColor = getVariableByName('metricdata/caption/color', modes) ?? '#777777';
90
+ // The design's link is purple (`text/foreground` under `Text Appearance:
91
+ // Secondary`) at 12px (`link/fontSize` under `Text Sizes: Small`), while the
92
+ // header icon keeps the default gold `icon/color`. Seed only the link's
93
+ // modes; caller-supplied modes win.
94
+ const linkModes = React.useMemo(() => ({
95
+ 'Text Appearance': 'Secondary',
96
+ 'Text Sizes': 'Small',
97
+ ...modes
98
+ }), [modes]);
99
+
100
+ // The header glyph is token-driven: `icon/color` (gold by default, retinted
101
+ // via `AppearanceBrand`) and `icon/size` (18px). Passing them explicitly — as
102
+ // MetricData does — makes the glyph deterministic instead of relying on the
103
+ // shared Icon's internal token lookups.
104
+ const iconColor = getVariableByName('icon/color', modes) ?? '#ad8444';
105
+ const iconSize = getVariableByName('icon/size', modes) ?? ICON_SIZE;
106
+ const gap = getVariableByName('metricdata/gap', modes) ?? 4;
107
+ const valueWrapGap = getVariableByName('metricdata/valueWrap/gap', modes) ?? 4;
108
+ const paddingHorizontal = getVariableByName('metricdata/padding/horizontal', modes) ?? 10;
109
+ const paddingVertical = getVariableByName('metricdata/padding/vertical', modes) ?? 10;
110
+ const containerStyle = {
111
+ flexDirection: 'column',
112
+ alignItems: 'flex-start',
113
+ justifyContent: 'center',
114
+ gap,
115
+ paddingHorizontal,
116
+ paddingVertical,
117
+ minHeight: CARD_MIN_HEIGHT,
118
+ backgroundColor: CARD_BACKGROUND
119
+ };
120
+ const titleTextStyle = {
121
+ color: titleColor,
122
+ fontFamily: FONT_FAMILY,
123
+ fontSize: TITLE_FONT_SIZE,
124
+ fontWeight: TITLE_FONT_WEIGHT,
125
+ lineHeight: TITLE_FONT_SIZE * TITLE_LINE_HEIGHT_RATIO
126
+ };
127
+ const valueTextStyle = {
128
+ color: valueColor,
129
+ fontFamily: FONT_FAMILY,
130
+ fontSize: VALUE_FONT_SIZE,
131
+ fontWeight: VALUE_FONT_WEIGHT,
132
+ lineHeight: VALUE_FONT_SIZE * VALUE_LINE_HEIGHT_RATIO
133
+ };
134
+ const captionTextStyle = {
135
+ color: captionColor,
136
+ fontFamily: FONT_FAMILY,
137
+ fontSize: CAPTION_FONT_SIZE,
138
+ fontWeight: CAPTION_FONT_WEIGHT,
139
+ lineHeight: CAPTION_FONT_SIZE * CAPTION_LINE_HEIGHT_RATIO
140
+ };
141
+
142
+ // Mirrors the Figma swap slot, whose preferred instances are `Icon` and
143
+ // `Image`. A registry name renders the token-driven `Icon` (18px, gold,
144
+ // flush — all from the `icon/*` tokens); a custom node (`<Icon/>`,
145
+ // `<Image/>`, anything) renders as-is with `modes` cascaded into it, so an
146
+ // Icon instance follows the icon tokens while an Image keeps its own sizing.
147
+ const iconNode = icon == null ? null : typeof icon === 'string' ? /*#__PURE__*/_jsx(Icon, {
148
+ iconName: icon,
149
+ size: iconSize,
150
+ color: iconColor,
151
+ modes: modes,
152
+ style: ICON_PADDING_RESET
153
+ }) : cloneChildrenWithModes(icon, modes);
154
+ const hasValue = value !== undefined && value !== null && value !== '';
155
+ const hasCaption = caption !== undefined && caption !== '';
156
+ const resolvedLabel = accessibilityLabel ?? ([title, typeof value === 'string' ? value : undefined, caption, linkLabel].filter(Boolean).join(', ') || undefined);
157
+ const content = /*#__PURE__*/_jsxs(_Fragment, {
158
+ children: [/*#__PURE__*/_jsxs(View, {
159
+ style: {
160
+ flexDirection: 'row',
161
+ alignItems: 'center',
162
+ gap: valueWrapGap
163
+ },
164
+ children: [iconNode, title !== undefined && title !== '' ? /*#__PURE__*/_jsx(Text, {
165
+ style: [titleTextStyle, titleStyle],
166
+ children: title
167
+ }) : null]
168
+ }), hasValue || hasCaption ? /*#__PURE__*/_jsxs(View, {
169
+ style: {
170
+ flexDirection: 'column',
171
+ alignItems: 'flex-start',
172
+ gap: 4
173
+ },
174
+ children: [hasValue ? typeof value === 'string' ? /*#__PURE__*/_jsx(Text, {
175
+ style: [valueTextStyle, valueStyle],
176
+ children: value
177
+ }) : value : null, hasCaption ? /*#__PURE__*/_jsx(Text, {
178
+ style: [captionTextStyle, captionStyle],
179
+ children: caption
180
+ }) : null]
181
+ }) : null, linkLabel ? /*#__PURE__*/_jsx(Link, {
182
+ text: linkLabel,
183
+ autolayout: "Hug",
184
+ modes: linkModes,
185
+ ...(onLinkPress ? {
186
+ onPress: onLinkPress
187
+ } : null)
188
+ }) : null]
189
+ });
190
+ if (onPress) {
191
+ return /*#__PURE__*/_jsx(Pressable, {
192
+ style: [containerStyle, style],
193
+ onPress: onPress,
194
+ disabled: disabled,
195
+ accessibilityRole: "button",
196
+ ...(resolvedLabel !== undefined ? {
197
+ accessibilityLabel: resolvedLabel
198
+ } : null),
199
+ accessibilityState: {
200
+ disabled: !!disabled
201
+ },
202
+ children: content
203
+ });
204
+ }
205
+ return /*#__PURE__*/_jsx(View, {
206
+ style: [containerStyle, style],
207
+ accessible: true,
208
+ ...(resolvedLabel !== undefined ? {
209
+ accessibilityLabel: resolvedLabel
210
+ } : null),
211
+ children: content
212
+ });
213
+ }
214
+ export default /*#__PURE__*/React.memo(ValueBackMetric);
@@ -24,6 +24,7 @@ export { default as CardFeedback } from './CardFeedback/CardFeedback';
24
24
  export { default as CardFinancialCondition } from './CardFinancialCondition/CardFinancialCondition';
25
25
  export { default as CardInsight } from './CardInsight/CardInsight';
26
26
  export { default as CcCard } from './CcCard/CcCard';
27
+ export { default as CategoryCard } from './CategoryCard/CategoryCard';
27
28
  export { default as Disclaimer } from './Disclaimer/Disclaimer';
28
29
  export { default as Divider } from './Divider/Divider';
29
30
  export { default as Drawer } from './Drawer/Drawer';
@@ -51,6 +52,7 @@ export { default as AllocationComparisonChart } from './AllocationComparisonChar
51
52
  export { default as MonthlyStatusGrid, CalendarGlyph } from './MonthlyStatusGrid/MonthlyStatusGrid';
52
53
  export { default as Gauge } from './Gauge/Gauge';
53
54
  export { default as HeroSection } from './HeroSection/HeroSection';
55
+ export { default as HelloJioInput } from './HelloJioInput/HelloJioInput';
54
56
  export { default as HoldingsCard } from './HoldingsCard/HoldingsCard';
55
57
  export { default as HStack } from './HStack/HStack';
56
58
  export { default as Icon } from './Icon/Icon';
@@ -157,4 +159,7 @@ export { default as TextSegment } from './TextSegment/TextSegment';
157
159
  export { default as SegmentedControl } from './SegmentedControl/SegmentedControl';
158
160
  export { default as Toggle } from './Toggle/Toggle';
159
161
  export { default as AutoplayControl } from './AutoplayControl/AutoplayControl';
160
- export { default as NumberPagination } from './NumberPagination/NumberPagination';
162
+ export { default as NumberPagination } from './NumberPagination/NumberPagination';
163
+ export { default as CounterBadge } from './CounterBadge/CounterBadge';
164
+ export { default as FavoriteToggle } from './FavoriteToggle/FavoriteToggle';
165
+ export { default as ValueBackMetric } from './ValueBackMetric/ValueBackMetric';