jfs-components 0.1.28 → 0.1.32
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 +28 -2
- package/lib/commonjs/components/CategoryCard/CategoryCard.js +264 -0
- package/lib/commonjs/components/CompareTable/CompareTable.js +247 -25
- package/lib/commonjs/components/ContentSheet/ContentSheet.js +91 -8
- package/lib/commonjs/components/CounterBadge/CounterBadge.js +78 -0
- package/lib/commonjs/components/FavoriteToggle/FavoriteToggle.js +180 -0
- package/lib/commonjs/components/HelloJioInput/HelloJioInput.js +287 -0
- package/lib/commonjs/components/MoneyValue/MoneyValue.js +179 -54
- package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +7 -1
- package/lib/commonjs/components/Table/Table.js +27 -7
- package/lib/commonjs/components/ValueBackMetric/ValueBackMetric.js +219 -0
- package/lib/commonjs/components/index.js +35 -0
- package/lib/commonjs/design-tokens/figma-modes.generated.js +3 -0
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/module/components/CategoryCard/CategoryCard.js +258 -0
- package/lib/module/components/CompareTable/CompareTable.js +247 -26
- package/lib/module/components/ContentSheet/ContentSheet.js +94 -11
- package/lib/module/components/CounterBadge/CounterBadge.js +73 -0
- package/lib/module/components/FavoriteToggle/FavoriteToggle.js +174 -0
- package/lib/module/components/HelloJioInput/HelloJioInput.js +281 -0
- package/lib/module/components/MoneyValue/MoneyValue.js +182 -57
- package/lib/module/components/PdpCcCard/PdpCcCard.js +7 -1
- package/lib/module/components/Table/Table.js +27 -7
- package/lib/module/components/ValueBackMetric/ValueBackMetric.js +214 -0
- package/lib/module/components/index.js +6 -1
- package/lib/module/design-tokens/figma-modes.generated.js +3 -0
- package/lib/module/icons/registry.js +1 -1
- package/lib/typescript/src/components/CategoryCard/CategoryCard.d.ts +72 -0
- package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +36 -1
- package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +20 -1
- package/lib/typescript/src/components/CounterBadge/CounterBadge.d.ts +19 -0
- package/lib/typescript/src/components/FavoriteToggle/FavoriteToggle.d.ts +66 -0
- package/lib/typescript/src/components/HelloJioInput/HelloJioInput.d.ts +111 -0
- package/lib/typescript/src/components/MoneyValue/MoneyValue.d.ts +10 -1
- package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +25 -1
- package/lib/typescript/src/components/Table/Table.d.ts +9 -1
- package/lib/typescript/src/components/ValueBackMetric/ValueBackMetric.d.ts +86 -0
- package/lib/typescript/src/components/index.d.ts +5 -0
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/CategoryCard/CategoryCard.tsx +404 -0
- package/src/components/CompareTable/CompareTable.tsx +324 -30
- package/src/components/ContentSheet/ContentSheet.tsx +120 -11
- package/src/components/CounterBadge/CounterBadge.tsx +95 -0
- package/src/components/FavoriteToggle/FavoriteToggle.tsx +243 -0
- package/src/components/HelloJioInput/HelloJioInput.tsx +513 -0
- package/src/components/MoneyValue/MoneyValue.tsx +216 -65
- package/src/components/PdpCcCard/PdpCcCard.tsx +36 -1
- package/src/components/Table/Table.tsx +29 -4
- package/src/components/ValueBackMetric/ValueBackMetric.tsx +298 -0
- package/src/components/index.ts +5 -0
- package/src/design-tokens/figma-modes.generated.ts +3 -0
- 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';
|
|
@@ -321,6 +321,7 @@ export const FIGMA_COMPONENT_MODES = {
|
|
|
321
321
|
"CardProviderInfo": ["AppearanceBrand", "Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
|
|
322
322
|
"Carousel": ["peekOffset"],
|
|
323
323
|
"CarouselCardAccounts": ["peekOffset"],
|
|
324
|
+
"CategoryCard": ["AppearanceBrand", "Badge Size", "Color Mode", "Emphasis", "Radius"],
|
|
324
325
|
"CcCard": ["AppearanceBrand", "AppearanceSystem", "Avatar Size", "Badge Size", "Button / Size", "Button / State", "Color Mode", "Context", "context 10", "context 8", "Context2", "Context4", "context5", "context7", "Emphasis", "List Item Style", "ListItem State", "NavArrow Direction", "Page type", "Profile Card Appearance", "Radius", "Selectable", "Semantic Intent", "Text Appearance", "Text Sizes", "Weight"],
|
|
325
326
|
"Checkbox": ["Color Mode"],
|
|
326
327
|
"CheckboxGroup": ["Color Mode"],
|
|
@@ -350,6 +351,7 @@ export const FIGMA_COMPONENT_MODES = {
|
|
|
350
351
|
"FullscreenModal": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Color Mode", "Context", "context 10", "context5", "Emphasis", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
|
|
351
352
|
"Gauge": ["AppearanceBrand", "AppearanceSystem", "Color Mode", "FormField States", "Semantic Intent", "Status"],
|
|
352
353
|
"Grid": ["Background", "Color Mode", "Context", "Padding", "Page type", "Slot gap"],
|
|
354
|
+
"HelloJioInput": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "Emphasis"],
|
|
353
355
|
"HeroSection": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "context 9", "context7", "Emphasis", "FormField States", "InputState", "Page type", "Status"],
|
|
354
356
|
"HoldingsCard": ["AppearanceBrand", "Color Mode"],
|
|
355
357
|
"HStack": ["Context", "Padding", "Page type", "Slot gap"],
|
|
@@ -418,6 +420,7 @@ export const FIGMA_COMPONENT_MODES = {
|
|
|
418
420
|
"TransactionBubble": ["Color Mode", "context 10", "Context2", "Context3", "context5", "List Item Style", "NavArrow Direction", "Page type", "Profile Card Appearance", "Transaction Status"],
|
|
419
421
|
"TransactionStatus": ["Transaction Status"],
|
|
420
422
|
"UpiHandle": ["Color Mode", "context 10", "Profile Card Appearance", "UPI Handle Image"],
|
|
423
|
+
"ValueBackMetric": ["AppearanceBrand", "Badge Size", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Profile Card Appearance", "Text Appearance", "Text Sizes", "Weight"],
|
|
421
424
|
"VStack": ["Context", "Padding", "Page type", "Slot gap"]
|
|
422
425
|
};
|
|
423
426
|
|