jfs-components 0.1.17 → 0.1.19
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 +15 -0
- package/lib/commonjs/components/AvatarGroup/AvatarGroup.js +41 -20
- package/lib/commonjs/components/Card/Card.js +29 -12
- package/lib/commonjs/components/CardFeedback/CardFeedback.js +16 -2
- package/lib/commonjs/components/CardInsight/CardInsight.js +34 -13
- package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +23 -3
- package/lib/commonjs/components/DebitCard/DebitCard.js +23 -3
- package/lib/commonjs/components/MediaCard/MediaCard.js +24 -7
- package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +64 -60
- package/lib/commonjs/components/RechargeCard/RechargeCard.js +34 -13
- package/lib/commonjs/components/TestimonialsCard/TestimonialsCard.js +23 -5
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/utils/GlassFill/GlassFill.js +69 -73
- package/lib/module/components/AvatarGroup/AvatarGroup.js +43 -21
- package/lib/module/components/Card/Card.js +31 -14
- package/lib/module/components/CardFeedback/CardFeedback.js +17 -3
- package/lib/module/components/CardInsight/CardInsight.js +36 -15
- package/lib/module/components/CardProviderInfo/CardProviderInfo.js +25 -5
- package/lib/module/components/DebitCard/DebitCard.js +25 -5
- package/lib/module/components/MediaCard/MediaCard.js +26 -9
- package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +66 -62
- package/lib/module/components/RechargeCard/RechargeCard.js +36 -15
- package/lib/module/components/TestimonialsCard/TestimonialsCard.js +25 -7
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/utils/GlassFill/GlassFill.js +69 -72
- package/lib/typescript/src/components/Card/Card.d.ts +10 -1
- package/lib/typescript/src/components/CardFeedback/CardFeedback.d.ts +10 -1
- package/lib/typescript/src/components/CardInsight/CardInsight.d.ts +10 -1
- package/lib/typescript/src/components/CardProviderInfo/CardProviderInfo.d.ts +10 -1
- package/lib/typescript/src/components/DebitCard/DebitCard.d.ts +10 -1
- package/lib/typescript/src/components/MediaCard/MediaCard.d.ts +10 -1
- package/lib/typescript/src/components/RechargeCard/RechargeCard.d.ts +10 -1
- package/lib/typescript/src/components/TestimonialsCard/TestimonialsCard.d.ts +8 -1
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/utils/GlassFill/GlassFill.d.ts +11 -4
- package/package.json +1 -2
- package/src/components/AvatarGroup/AvatarGroup.tsx +44 -18
- package/src/components/Card/Card.tsx +46 -15
- package/src/components/CardFeedback/CardFeedback.tsx +29 -4
- package/src/components/CardInsight/CardInsight.tsx +48 -17
- package/src/components/CardProviderInfo/CardProviderInfo.tsx +36 -3
- package/src/components/DebitCard/DebitCard.tsx +36 -3
- package/src/components/MediaCard/MediaCard.tsx +40 -9
- package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +76 -47
- package/src/components/RechargeCard/RechargeCard.tsx +48 -13
- package/src/components/TestimonialsCard/TestimonialsCard.tsx +37 -6
- package/src/icons/registry.ts +1 -1
- package/src/utils/GlassFill/GlassFill.tsx +59 -56
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React, { createContext, useContext } from 'react';
|
|
4
|
-
import { View, Text, StyleSheet } from 'react-native';
|
|
4
|
+
import { View, Text, Pressable, StyleSheet } from 'react-native';
|
|
5
5
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
6
|
import Image from '../Image/Image';
|
|
7
7
|
import GlassFill from '../../utils/GlassFill/GlassFill';
|
|
8
8
|
import { EMPTY_MODES } from '../../utils/react-utils';
|
|
9
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
10
|
const MediaCardContext = /*#__PURE__*/createContext({});
|
|
11
11
|
/**
|
|
12
12
|
* MediaCard component implementation from Figma node 1241:4140.
|
|
@@ -32,7 +32,10 @@ export function MediaCard({
|
|
|
32
32
|
media,
|
|
33
33
|
children,
|
|
34
34
|
modes = EMPTY_MODES,
|
|
35
|
-
style
|
|
35
|
+
style,
|
|
36
|
+
onPress,
|
|
37
|
+
disabled,
|
|
38
|
+
accessibilityLabel
|
|
36
39
|
}) {
|
|
37
40
|
const radius = parseFloat(getVariableByName('cardMedia/radius', modes));
|
|
38
41
|
const containerStyle = {
|
|
@@ -47,17 +50,31 @@ export function MediaCard({
|
|
|
47
50
|
accessibilityElementsHidden: true,
|
|
48
51
|
importantForAccessibility: "no"
|
|
49
52
|
}) : null);
|
|
53
|
+
const content = /*#__PURE__*/_jsxs(_Fragment, {
|
|
54
|
+
children: [background, children != null ? /*#__PURE__*/_jsx(View, {
|
|
55
|
+
style: StyleSheet.absoluteFill,
|
|
56
|
+
pointerEvents: "box-none",
|
|
57
|
+
children: children
|
|
58
|
+
}) : null]
|
|
59
|
+
});
|
|
50
60
|
return /*#__PURE__*/_jsx(MediaCardContext.Provider, {
|
|
51
61
|
value: {
|
|
52
62
|
modes
|
|
53
63
|
},
|
|
54
|
-
children: /*#__PURE__*/
|
|
64
|
+
children: onPress ? /*#__PURE__*/_jsx(Pressable, {
|
|
65
|
+
style: [containerStyle, style],
|
|
66
|
+
onPress: onPress,
|
|
67
|
+
disabled: disabled,
|
|
68
|
+
accessibilityRole: "button",
|
|
69
|
+
accessibilityLabel: accessibilityLabel,
|
|
70
|
+
accessibilityState: {
|
|
71
|
+
disabled: !!disabled
|
|
72
|
+
},
|
|
73
|
+
children: content
|
|
74
|
+
}) : /*#__PURE__*/_jsx(View, {
|
|
55
75
|
style: [containerStyle, style],
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
pointerEvents: "box-none",
|
|
59
|
-
children: children
|
|
60
|
-
}) : null]
|
|
76
|
+
accessibilityLabel: accessibilityLabel,
|
|
77
|
+
children: content
|
|
61
78
|
})
|
|
62
79
|
});
|
|
63
80
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React, { useId, useMemo } from 'react';
|
|
4
|
-
import { View, Text, Pressable, StyleSheet
|
|
5
|
-
import
|
|
6
|
-
import Svg, { Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
|
|
4
|
+
import { View, Text, Pressable, StyleSheet } from 'react-native';
|
|
5
|
+
import Svg, { Defs, LinearGradient, Stop, Rect, Mask, Filter, FeGaussianBlur, Image as SvgImage } from 'react-native-svg';
|
|
7
6
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
8
7
|
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
|
|
9
8
|
import Avatar from '../Avatar/Avatar';
|
|
@@ -65,7 +64,9 @@ function ProductMerchandisingCard({
|
|
|
65
64
|
const rawId = useId();
|
|
66
65
|
const safeId = rawId.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
67
66
|
const scrimId = `pmc-footer-scrim-${safeId}`;
|
|
67
|
+
const blurGradientId = `pmc-footer-blurgrad-${safeId}`;
|
|
68
68
|
const blurMaskId = `pmc-footer-blurmask-${safeId}`;
|
|
69
|
+
const blurFilterId = `pmc-footer-blurfilter-${safeId}`;
|
|
69
70
|
const normalizedImageSource = useMemo(() => normalizeImageSource(imageSource), [imageSource]);
|
|
70
71
|
const tokens = useMemo(() => resolveTokens(modes), [modes]);
|
|
71
72
|
const containerStyle = {
|
|
@@ -159,57 +160,63 @@ function ProductMerchandisingCard({
|
|
|
159
160
|
children: [normalizedImageSource != null ? /*#__PURE__*/_jsx(View, {
|
|
160
161
|
style: StyleSheet.absoluteFill,
|
|
161
162
|
pointerEvents: "none",
|
|
162
|
-
children: /*#__PURE__*/
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
163
|
+
children: /*#__PURE__*/_jsxs(Svg, {
|
|
164
|
+
width: "100%",
|
|
165
|
+
height: "100%",
|
|
166
|
+
children: [/*#__PURE__*/_jsxs(Defs, {
|
|
167
|
+
children: [/*#__PURE__*/_jsx(Filter, {
|
|
168
|
+
id: blurFilterId,
|
|
169
|
+
x: "-15%",
|
|
170
|
+
y: "-15%",
|
|
171
|
+
width: "130%",
|
|
172
|
+
height: "130%",
|
|
173
|
+
children: /*#__PURE__*/_jsx(FeGaussianBlur, {
|
|
174
|
+
stdDeviation: tokens.imageBlurStdDeviation,
|
|
175
|
+
edgeMode: "duplicate"
|
|
176
|
+
})
|
|
177
|
+
}), /*#__PURE__*/_jsxs(LinearGradient, {
|
|
178
|
+
id: blurGradientId,
|
|
179
|
+
x1: "0",
|
|
180
|
+
y1: "0",
|
|
181
|
+
x2: "0",
|
|
182
|
+
y2: "1",
|
|
183
|
+
children: [/*#__PURE__*/_jsx(Stop, {
|
|
184
|
+
offset: "0",
|
|
185
|
+
stopColor: "#ffffff",
|
|
186
|
+
stopOpacity: 0
|
|
187
|
+
}), /*#__PURE__*/_jsx(Stop, {
|
|
188
|
+
offset: "0.35",
|
|
189
|
+
stopColor: "#ffffff",
|
|
190
|
+
stopOpacity: 0.5
|
|
191
|
+
}), /*#__PURE__*/_jsx(Stop, {
|
|
192
|
+
offset: "0.7",
|
|
193
|
+
stopColor: "#ffffff",
|
|
194
|
+
stopOpacity: 0.92
|
|
195
|
+
}), /*#__PURE__*/_jsx(Stop, {
|
|
196
|
+
offset: "1",
|
|
197
|
+
stopColor: "#ffffff",
|
|
198
|
+
stopOpacity: 1
|
|
199
|
+
})]
|
|
200
|
+
}), /*#__PURE__*/_jsx(Mask, {
|
|
201
|
+
id: blurMaskId,
|
|
202
|
+
children: /*#__PURE__*/_jsx(Rect, {
|
|
203
|
+
x: "0",
|
|
204
|
+
y: "0",
|
|
205
|
+
width: "100%",
|
|
206
|
+
height: "100%",
|
|
207
|
+
fill: `url(#${blurGradientId})`
|
|
191
208
|
})
|
|
192
|
-
}), /*#__PURE__*/_jsx(Rect, {
|
|
193
|
-
x: "0",
|
|
194
|
-
y: "0",
|
|
195
|
-
width: "100%",
|
|
196
|
-
height: "100%",
|
|
197
|
-
fill: `url(#${blurMaskId})`
|
|
198
209
|
})]
|
|
199
|
-
}),
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
width: '100%',
|
|
210
|
-
height
|
|
211
|
-
}
|
|
212
|
-
})
|
|
210
|
+
}), /*#__PURE__*/_jsx(SvgImage, {
|
|
211
|
+
href: normalizedImageSource,
|
|
212
|
+
x: "0",
|
|
213
|
+
y: "0",
|
|
214
|
+
width: "100%",
|
|
215
|
+
height: "100%",
|
|
216
|
+
preserveAspectRatio: "xMidYMid slice",
|
|
217
|
+
filter: `url(#${blurFilterId})`,
|
|
218
|
+
mask: `url(#${blurMaskId})`
|
|
219
|
+
})]
|
|
213
220
|
})
|
|
214
221
|
}) : /*#__PURE__*/_jsx(GlassFill, {
|
|
215
222
|
tint: "dark",
|
|
@@ -328,19 +335,16 @@ function resolveTokens(modes) {
|
|
|
328
335
|
const sbFamily = asStr(getVariableByName('productMerchandisingcard/specialbadge/text/fontfamily', modes), 'JioType Var');
|
|
329
336
|
const sbWeight = asStr(getVariableByName('productMerchandisingcard/specialbadge/text/fontweight', modes), '500');
|
|
330
337
|
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
// "
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
android: Math.max(12, Math.round(blurRadius * 0.95)),
|
|
338
|
-
default: Math.max(8, Math.round(blurRadius * 0.6))
|
|
339
|
-
});
|
|
338
|
+
// SVG `<FeGaussianBlur stdDeviation>` is resolution-independent and renders
|
|
339
|
+
// an identical Gaussian on iOS, Android and web — so unlike the old
|
|
340
|
+
// `Image.blurRadius` path it needs no per-platform tuning. `stdDeviation` is
|
|
341
|
+
// roughly half a perceptual "blur radius", so we scale the `blur/minimal`
|
|
342
|
+
// token down to land on the same subtle frosted strength as the design.
|
|
343
|
+
const imageBlurStdDeviation = Math.max(4, Math.round(blurRadius * 0.35));
|
|
340
344
|
return {
|
|
341
345
|
radius,
|
|
342
346
|
blurIntensity: Math.max(0, Math.min(100, Math.round(blurRadius * BLUR_INTENSITY_FACTOR))),
|
|
343
|
-
|
|
347
|
+
imageBlurStdDeviation,
|
|
344
348
|
header: {
|
|
345
349
|
flexDirection: 'row',
|
|
346
350
|
alignItems: 'flex-start',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { View, Text } from 'react-native';
|
|
4
|
+
import { View, Text, Pressable } from 'react-native';
|
|
5
5
|
import ButtonGroup from '../ButtonGroup/ButtonGroup';
|
|
6
6
|
import AvatarGroup from '../AvatarGroup/AvatarGroup';
|
|
7
7
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
8
8
|
import { EMPTY_MODES } from '../../utils/react-utils';
|
|
9
9
|
import MoneyValue from '../MoneyValue/MoneyValue';
|
|
10
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
11
|
// Defaults applied to the inner ButtonGroup so the card matches Figma out of
|
|
12
12
|
// the box. They are spread *before* the caller's `modes` so any consumer can
|
|
13
13
|
// override an individual key (e.g. swap the size to "M").
|
|
@@ -36,7 +36,10 @@ export default function RechargeCard({
|
|
|
36
36
|
subscriptionContent,
|
|
37
37
|
actions,
|
|
38
38
|
modes = EMPTY_MODES,
|
|
39
|
-
style
|
|
39
|
+
style,
|
|
40
|
+
onPress,
|
|
41
|
+
disabled,
|
|
42
|
+
accessibilityLabel
|
|
40
43
|
}) {
|
|
41
44
|
// Container Tokens (defaults mirror Figma node 2235:937).
|
|
42
45
|
const backgroundColor = getVariableByName('rechargeCard/background', modes);
|
|
@@ -85,18 +88,18 @@ export default function RechargeCard({
|
|
|
85
88
|
// Pass modes to subscription children (e.g. AvatarGroup)
|
|
86
89
|
// Now encapsulated, so we just pass children to AvatarGroup
|
|
87
90
|
const hasSubscriptions = React.Children.count(subscriptionContent) > 0;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
91
|
+
const containerStyle = {
|
|
92
|
+
backgroundColor,
|
|
93
|
+
paddingHorizontal,
|
|
94
|
+
paddingVertical,
|
|
95
|
+
gap,
|
|
96
|
+
borderRadius: radius,
|
|
97
|
+
borderWidth: strokeWidth,
|
|
98
|
+
borderColor: strokeColor,
|
|
99
|
+
minWidth,
|
|
100
|
+
alignItems: 'flex-start'
|
|
101
|
+
};
|
|
102
|
+
const content = /*#__PURE__*/_jsxs(_Fragment, {
|
|
100
103
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
101
104
|
style: {
|
|
102
105
|
gap: headerGap,
|
|
@@ -212,4 +215,22 @@ export default function RechargeCard({
|
|
|
212
215
|
children: actions
|
|
213
216
|
})]
|
|
214
217
|
});
|
|
218
|
+
if (onPress) {
|
|
219
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
220
|
+
style: [containerStyle, style],
|
|
221
|
+
onPress: onPress,
|
|
222
|
+
disabled: disabled,
|
|
223
|
+
accessibilityRole: "button",
|
|
224
|
+
accessibilityLabel: accessibilityLabel ?? title,
|
|
225
|
+
accessibilityState: {
|
|
226
|
+
disabled: !!disabled
|
|
227
|
+
},
|
|
228
|
+
children: content
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return /*#__PURE__*/_jsx(View, {
|
|
232
|
+
style: [containerStyle, style],
|
|
233
|
+
accessibilityLabel: accessibilityLabel,
|
|
234
|
+
children: content
|
|
235
|
+
});
|
|
215
236
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { View, Text } from 'react-native';
|
|
4
|
+
import { View, Text, Pressable } from 'react-native';
|
|
5
5
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
6
|
import { EMPTY_MODES } from '../../utils/react-utils';
|
|
7
7
|
import Avatar from '../Avatar/Avatar';
|
|
8
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
9
9
|
/**
|
|
10
10
|
* TestimonialsCard renders a compact, fixed-width card with a circular avatar,
|
|
11
11
|
* a bold title, and a body paragraph. It is typically used inside a horizontal
|
|
@@ -28,7 +28,9 @@ function TestimonialsCard({
|
|
|
28
28
|
modes = EMPTY_MODES,
|
|
29
29
|
style,
|
|
30
30
|
avatarProps,
|
|
31
|
-
accessibilityLabel
|
|
31
|
+
accessibilityLabel,
|
|
32
|
+
onPress,
|
|
33
|
+
disabled
|
|
32
34
|
}) {
|
|
33
35
|
// Container tokens
|
|
34
36
|
const background = getVariableByName('testimonialsCard/background', modes) ?? '#ffffff';
|
|
@@ -84,10 +86,7 @@ function TestimonialsCard({
|
|
|
84
86
|
...(avatarProps?.modes || {})
|
|
85
87
|
};
|
|
86
88
|
const resolvedAccessibilityLabel = accessibilityLabel ?? `Testimonial${title ? ` from ${title}` : ''}${body ? `: ${body}` : ''}`;
|
|
87
|
-
|
|
88
|
-
style: [containerStyle, style],
|
|
89
|
-
accessibilityRole: "text",
|
|
90
|
-
accessibilityLabel: resolvedAccessibilityLabel,
|
|
89
|
+
const content = /*#__PURE__*/_jsxs(_Fragment, {
|
|
91
90
|
children: [/*#__PURE__*/_jsx(Avatar, {
|
|
92
91
|
style: "Image",
|
|
93
92
|
modes: avatarModes,
|
|
@@ -107,6 +106,25 @@ function TestimonialsCard({
|
|
|
107
106
|
})]
|
|
108
107
|
})]
|
|
109
108
|
});
|
|
109
|
+
if (onPress) {
|
|
110
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
111
|
+
style: [containerStyle, style],
|
|
112
|
+
onPress: onPress,
|
|
113
|
+
disabled: disabled,
|
|
114
|
+
accessibilityRole: "button",
|
|
115
|
+
accessibilityLabel: resolvedAccessibilityLabel,
|
|
116
|
+
accessibilityState: {
|
|
117
|
+
disabled: !!disabled
|
|
118
|
+
},
|
|
119
|
+
children: content
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return /*#__PURE__*/_jsx(View, {
|
|
123
|
+
style: [containerStyle, style],
|
|
124
|
+
accessibilityRole: "text",
|
|
125
|
+
accessibilityLabel: resolvedAccessibilityLabel,
|
|
126
|
+
children: content
|
|
127
|
+
});
|
|
110
128
|
}
|
|
111
129
|
const textContainerStyle = {
|
|
112
130
|
width: '100%',
|