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
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import React, { useId } from 'react';
|
|
4
4
|
import { View, StyleSheet, Platform, UIManager } from 'react-native';
|
|
5
5
|
import { BlurView } from '@react-native-community/blur';
|
|
6
|
-
import MaskedView from '@react-native-masked-view/masked-view';
|
|
7
6
|
import Svg, { Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
|
|
8
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
8
|
const DEFAULT_FALLBACK_DARK = '#1414174a';
|
|
@@ -14,32 +13,30 @@ const DEFAULT_FALLBACK_LIGHT = '#ffffff66';
|
|
|
14
13
|
const NATIVE_BLUR_NAME = Platform.OS === 'android' ? 'AndroidBlurView' : 'BlurView';
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
* Alpha stop on
|
|
18
|
-
* position (0 = top of the surface, 1 = bottom); `opacity` is the
|
|
19
|
-
* there (0 =
|
|
16
|
+
* Alpha stop on the no-native-blur fallback gradient. `offset` is the vertical
|
|
17
|
+
* position (0 = top of the surface, 1 = bottom); `opacity` is the tint alpha
|
|
18
|
+
* there (0 = fully clear, 1 = full fallback color).
|
|
20
19
|
*
|
|
21
|
-
* Using several stops (rather than a single linear 0 → 1 ramp)
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* "glass" feel rather than a flat translucent panel.
|
|
20
|
+
* Using several stops (rather than a single linear 0 → 1 ramp) eases the tint
|
|
21
|
+
* in, so it swells smoothly toward the bottom instead of along a hard seam —
|
|
22
|
+
* the soft S-curve that gives the surface its "glass" feel.
|
|
25
23
|
*/
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
|
-
* A single
|
|
29
|
-
* - `
|
|
30
|
-
*
|
|
26
|
+
* A single bottom-anchored band of the progressive blur stack.
|
|
27
|
+
* - `start` is where the band begins, as a fraction from the top (0 = covers
|
|
28
|
+
* the whole surface, 0.8 = only the bottom 20%). Each band runs from `start`
|
|
29
|
+
* to the bottom.
|
|
30
|
+
* - `amount` is the band's own blur strength as a share (0–1) of the peak.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* heavy block), while still giving a genuine variable-radius result — the blur
|
|
37
|
-
* radius grows toward the bottom where the two layers overlap.
|
|
32
|
+
* Because each `BlurView` re-blurs everything rendered behind it, the bands
|
|
33
|
+
* COMPOUND where they overlap (toward the bottom), so the effective radius grows
|
|
34
|
+
* downward without any masking. The top region is covered only by the first,
|
|
35
|
+
* faint band; the bottom is covered by all of them.
|
|
38
36
|
*/
|
|
39
37
|
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
// snapping clear. Also reused for the no-native-blur fallback scrim.
|
|
38
|
+
// Eased tint ramp for the no-native-blur fallback scrim. A faint trace begins
|
|
39
|
+
// near the very top and grows steadily downward.
|
|
43
40
|
const BASE_MASK_STOPS = [{
|
|
44
41
|
offset: 0.0,
|
|
45
42
|
opacity: 0
|
|
@@ -56,26 +53,26 @@ const BASE_MASK_STOPS = [{
|
|
|
56
53
|
offset: 1.0,
|
|
57
54
|
opacity: 1
|
|
58
55
|
}];
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
|
|
57
|
+
// Bottom-anchored blur bands (top → bottom). The first band is faint and covers
|
|
58
|
+
// the whole surface so the top reads as barely-there glass; each subsequent band
|
|
59
|
+
// starts lower and adds strength, compounding toward the bottom for a smooth
|
|
60
|
+
// variable-radius result. Quadrature of these shares lands the bottom at ~peak.
|
|
61
|
+
const PROGRESSIVE_BANDS = [{
|
|
62
|
+
start: 0.0,
|
|
63
|
+
amount: 0.18
|
|
64
|
+
}, {
|
|
65
|
+
start: 0.3,
|
|
66
|
+
amount: 0.28
|
|
67
|
+
}, {
|
|
68
|
+
start: 0.52,
|
|
69
|
+
amount: 0.38
|
|
70
|
+
}, {
|
|
71
|
+
start: 0.7,
|
|
72
|
+
amount: 0.5
|
|
73
|
+
}, {
|
|
74
|
+
start: 0.84,
|
|
75
|
+
amount: 0.6
|
|
79
76
|
}];
|
|
80
77
|
|
|
81
78
|
/**
|
|
@@ -108,13 +105,14 @@ const NATIVE_BLUR_SUPPORTED = (() => {
|
|
|
108
105
|
})();
|
|
109
106
|
|
|
110
107
|
/**
|
|
111
|
-
* Vertical
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
108
|
+
* Vertical color-gradient scrim drawn with `react-native-svg` — used as the
|
|
109
|
+
* no-native-blur fallback. Paints `color` at the eased per-stop alpha so the
|
|
110
|
+
* tint swells smoothly from clear (top) to full (bottom), exactly mirroring the
|
|
111
|
+
* old `MaskedView`-over-solid-color fallback but with no native-view masking.
|
|
115
112
|
*/
|
|
116
|
-
function
|
|
113
|
+
function GradientScrim({
|
|
117
114
|
id,
|
|
115
|
+
color,
|
|
118
116
|
stops
|
|
119
117
|
}) {
|
|
120
118
|
return /*#__PURE__*/_jsxs(Svg, {
|
|
@@ -129,7 +127,7 @@ function GradientMask({
|
|
|
129
127
|
y2: "1",
|
|
130
128
|
children: stops.map((s, i) => /*#__PURE__*/_jsx(Stop, {
|
|
131
129
|
offset: s.offset,
|
|
132
|
-
stopColor:
|
|
130
|
+
stopColor: color,
|
|
133
131
|
stopOpacity: s.opacity
|
|
134
132
|
}, i))
|
|
135
133
|
})
|
|
@@ -194,38 +192,37 @@ function GlassFill({
|
|
|
194
192
|
return /*#__PURE__*/_jsx(View, {
|
|
195
193
|
style: [StyleSheet.absoluteFill, style],
|
|
196
194
|
pointerEvents: "none",
|
|
197
|
-
children: /*#__PURE__*/_jsx(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
stops: BASE_MASK_STOPS
|
|
202
|
-
}),
|
|
203
|
-
children: /*#__PURE__*/_jsx(View, {
|
|
204
|
-
style: [StyleSheet.absoluteFill, {
|
|
205
|
-
backgroundColor: fallbackColor
|
|
206
|
-
}]
|
|
207
|
-
})
|
|
195
|
+
children: /*#__PURE__*/_jsx(GradientScrim, {
|
|
196
|
+
id: `${maskId}-fb`,
|
|
197
|
+
color: fallbackColor,
|
|
198
|
+
stops: BASE_MASK_STOPS
|
|
208
199
|
})
|
|
209
200
|
});
|
|
210
201
|
}
|
|
211
202
|
return /*#__PURE__*/_jsx(View, {
|
|
212
203
|
style: [StyleSheet.absoluteFill, style],
|
|
213
204
|
pointerEvents: "none",
|
|
214
|
-
children:
|
|
215
|
-
const amount = Math.max(1, Math.round(peakBlur *
|
|
216
|
-
return
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
205
|
+
children: PROGRESSIVE_BANDS.map((band, i) => {
|
|
206
|
+
const amount = Math.max(1, Math.round(peakBlur * band.amount));
|
|
207
|
+
return (
|
|
208
|
+
/*#__PURE__*/
|
|
209
|
+
// Each band is clipped to start at `band.start` and run to
|
|
210
|
+
// the bottom; its `BlurView` blurs the content (and any
|
|
211
|
+
// lower bands) behind it, so the radius compounds downward.
|
|
212
|
+
_jsx(View, {
|
|
213
|
+
style: [StyleSheet.absoluteFill, {
|
|
214
|
+
top: `${band.start * 100}%`,
|
|
215
|
+
overflow: 'hidden'
|
|
216
|
+
}],
|
|
217
|
+
pointerEvents: "none",
|
|
218
|
+
children: /*#__PURE__*/_jsx(BlurView, {
|
|
219
|
+
style: StyleSheet.absoluteFill,
|
|
220
|
+
blurType: blurType,
|
|
221
|
+
blurAmount: amount,
|
|
222
|
+
reducedTransparencyFallbackColor: fallbackColor
|
|
223
|
+
})
|
|
224
|
+
}, i)
|
|
225
|
+
);
|
|
229
226
|
})
|
|
230
227
|
});
|
|
231
228
|
}
|
|
@@ -29,6 +29,15 @@ export interface CardProps {
|
|
|
29
29
|
* Style overrides for the card container.
|
|
30
30
|
*/
|
|
31
31
|
style?: StyleProp<ViewStyle>;
|
|
32
|
+
/**
|
|
33
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
34
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
35
|
+
*/
|
|
36
|
+
onPress?: () => void;
|
|
37
|
+
/** Disable interaction when `onPress` is set. */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** Accessibility label forwarded to the pressable wrapper. */
|
|
40
|
+
accessibilityLabel?: string;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
43
|
* Card component implementation from Figma node 765:6186.
|
|
@@ -45,7 +54,7 @@ export interface CardProps {
|
|
|
45
54
|
* </Card>
|
|
46
55
|
* ```
|
|
47
56
|
*/
|
|
48
|
-
export declare function Card({ header, media, children, modes, mediaAspectRatio, style, }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
export declare function Card({ header, media, children, modes, mediaAspectRatio, style, onPress, disabled, accessibilityLabel, }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
49
58
|
export declare namespace Card {
|
|
50
59
|
var Title: ({ children, style, modes: propModes }: CardTextProps) => import("react/jsx-runtime").JSX.Element;
|
|
51
60
|
var SupportText: ({ children, style, modes: propModes }: CardTextProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,13 +14,22 @@ export interface CardFeedbackProps {
|
|
|
14
14
|
* Style overrides for the card container.
|
|
15
15
|
*/
|
|
16
16
|
style?: StyleProp<ViewStyle>;
|
|
17
|
+
/**
|
|
18
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
19
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
20
|
+
*/
|
|
21
|
+
onPress?: () => void;
|
|
22
|
+
/** Disable interaction when `onPress` is set. */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Accessibility label forwarded to the pressable wrapper. */
|
|
25
|
+
accessibilityLabel?: string;
|
|
17
26
|
}
|
|
18
27
|
/**
|
|
19
28
|
* CardFeedback component from Figma node 1280:4481.
|
|
20
29
|
*
|
|
21
30
|
* Used for status updates, warnings, or feedback.
|
|
22
31
|
*/
|
|
23
|
-
export declare function CardFeedback({ children, modes: propModes, style, }: CardFeedbackProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export declare function CardFeedback({ children, modes: propModes, style, onPress, disabled, accessibilityLabel, }: CardFeedbackProps): import("react/jsx-runtime").JSX.Element;
|
|
24
33
|
export declare namespace CardFeedback {
|
|
25
34
|
var Icon: typeof import("./CardFeedback").Icon;
|
|
26
35
|
var Content: typeof import("./CardFeedback").Content;
|
|
@@ -32,6 +32,15 @@ export type CardInsightProps = {
|
|
|
32
32
|
modes?: Modes;
|
|
33
33
|
/** Override container styles. */
|
|
34
34
|
style?: StyleProp<ViewStyle>;
|
|
35
|
+
/**
|
|
36
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
37
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
38
|
+
*/
|
|
39
|
+
onPress?: () => void;
|
|
40
|
+
/** Disable interaction when `onPress` is set. */
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
/** Accessibility label forwarded to the pressable wrapper (defaults to `title`). */
|
|
43
|
+
accessibilityLabel?: string;
|
|
35
44
|
};
|
|
36
45
|
/**
|
|
37
46
|
* `CardInsight` renders a single insight card composed of:
|
|
@@ -44,6 +53,6 @@ export type CardInsightProps = {
|
|
|
44
53
|
* @component
|
|
45
54
|
* @param {CardInsightProps} props
|
|
46
55
|
*/
|
|
47
|
-
declare function CardInsight({ title, subtitle, badge, children, footer, divider, modes, style, }: CardInsightProps): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
declare function CardInsight({ title, subtitle, badge, children, footer, divider, modes, style, onPress, disabled, accessibilityLabel, }: CardInsightProps): import("react/jsx-runtime").JSX.Element;
|
|
48
57
|
export default CardInsight;
|
|
49
58
|
//# sourceMappingURL=CardInsight.d.ts.map
|
|
@@ -12,6 +12,15 @@ export type CardProviderInfoProps = {
|
|
|
12
12
|
modes?: Modes;
|
|
13
13
|
/** Override container styles. */
|
|
14
14
|
style?: StyleProp<ViewStyle>;
|
|
15
|
+
/**
|
|
16
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
17
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
18
|
+
*/
|
|
19
|
+
onPress?: () => void;
|
|
20
|
+
/** Disable interaction when `onPress` is set. */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Accessibility label forwarded to the pressable wrapper (defaults to `label`). */
|
|
23
|
+
accessibilityLabel?: string;
|
|
15
24
|
};
|
|
16
25
|
/**
|
|
17
26
|
* CardProviderInfo displays a product header (ProductLabel) followed by a
|
|
@@ -20,6 +29,6 @@ export type CardProviderInfoProps = {
|
|
|
20
29
|
* @component
|
|
21
30
|
* @param {CardProviderInfoProps} props
|
|
22
31
|
*/
|
|
23
|
-
declare function CardProviderInfo({ label, imageSource, children, modes, style, }: CardProviderInfoProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
declare function CardProviderInfo({ label, imageSource, children, modes, style, onPress, disabled, accessibilityLabel, }: CardProviderInfoProps): import("react/jsx-runtime").JSX.Element;
|
|
24
33
|
export default CardProviderInfo;
|
|
25
34
|
//# sourceMappingURL=CardProviderInfo.d.ts.map
|
|
@@ -22,7 +22,16 @@ export type DebitCardProps = {
|
|
|
22
22
|
modes?: Modes;
|
|
23
23
|
/** Container style overrides */
|
|
24
24
|
style?: StyleProp<ViewStyle>;
|
|
25
|
+
/**
|
|
26
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
27
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
28
|
+
*/
|
|
29
|
+
onPress?: () => void;
|
|
30
|
+
/** Disable interaction when `onPress` is set. */
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
/** Accessibility label forwarded to the pressable wrapper. */
|
|
33
|
+
accessibilityLabel?: string;
|
|
25
34
|
};
|
|
26
|
-
declare function DebitCard({ cardholderName, cardNumber, expireDate, bankName, cardType, cardArtSource, bankLogoSlot, providerLogoSlot, modes: propModes, style, }: DebitCardProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
declare function DebitCard({ cardholderName, cardNumber, expireDate, bankName, cardType, cardArtSource, bankLogoSlot, providerLogoSlot, modes: propModes, style, onPress, disabled, accessibilityLabel, }: DebitCardProps): import("react/jsx-runtime").JSX.Element;
|
|
27
36
|
export default DebitCard;
|
|
28
37
|
//# sourceMappingURL=DebitCard.d.ts.map
|
|
@@ -33,6 +33,15 @@ export interface MediaCardProps {
|
|
|
33
33
|
* Style overrides for the card container.
|
|
34
34
|
*/
|
|
35
35
|
style?: StyleProp<ViewStyle>;
|
|
36
|
+
/**
|
|
37
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
38
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
39
|
+
*/
|
|
40
|
+
onPress?: () => void;
|
|
41
|
+
/** Disable interaction when `onPress` is set. */
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
/** Accessibility label forwarded to the pressable wrapper. */
|
|
44
|
+
accessibilityLabel?: string;
|
|
36
45
|
}
|
|
37
46
|
/**
|
|
38
47
|
* MediaCard component implementation from Figma node 1241:4140.
|
|
@@ -52,7 +61,7 @@ export interface MediaCardProps {
|
|
|
52
61
|
* interactive elements inside the overlays without the wrapper itself
|
|
53
62
|
* capturing them.
|
|
54
63
|
*/
|
|
55
|
-
export declare function MediaCard({ imageSource, ratio, media, children, modes, style, }: MediaCardProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
export declare function MediaCard({ imageSource, ratio, media, children, modes, style, onPress, disabled, accessibilityLabel, }: MediaCardProps): import("react/jsx-runtime").JSX.Element;
|
|
56
65
|
export declare namespace MediaCard {
|
|
57
66
|
var Header: typeof import("./MediaCard").Header;
|
|
58
67
|
var Title: typeof import("./MediaCard").Title;
|
|
@@ -42,10 +42,19 @@ export type RechargeCardProps = {
|
|
|
42
42
|
*/
|
|
43
43
|
modes?: Modes;
|
|
44
44
|
style?: ViewStyle;
|
|
45
|
+
/**
|
|
46
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
47
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
48
|
+
*/
|
|
49
|
+
onPress?: () => void;
|
|
50
|
+
/** Disable interaction when `onPress` is set. */
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
/** Accessibility label forwarded to the pressable wrapper (defaults to `title`). */
|
|
53
|
+
accessibilityLabel?: string;
|
|
45
54
|
};
|
|
46
55
|
/**
|
|
47
56
|
* RechargeCard component implementation from Figma node 2235:937.
|
|
48
57
|
* Displays a recharge plan with price, validity, data, and subscription details.
|
|
49
58
|
*/
|
|
50
|
-
export default function RechargeCard({ title, price, validity, data, disclaimer, subscriptionContent, actions, modes, style, }: RechargeCardProps): import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
export default function RechargeCard({ title, price, validity, data, disclaimer, subscriptionContent, actions, modes, style, onPress, disabled, accessibilityLabel, }: RechargeCardProps): import("react/jsx-runtime").JSX.Element;
|
|
51
60
|
//# sourceMappingURL=RechargeCard.d.ts.map
|
|
@@ -29,6 +29,13 @@ export type TestimonialsCardProps = {
|
|
|
29
29
|
* from the title and body.
|
|
30
30
|
*/
|
|
31
31
|
accessibilityLabel?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
34
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
35
|
+
*/
|
|
36
|
+
onPress?: () => void;
|
|
37
|
+
/** Disable interaction when `onPress` is set. */
|
|
38
|
+
disabled?: boolean;
|
|
32
39
|
};
|
|
33
40
|
/**
|
|
34
41
|
* TestimonialsCard renders a compact, fixed-width card with a circular avatar,
|
|
@@ -46,7 +53,7 @@ export type TestimonialsCardProps = {
|
|
|
46
53
|
* />
|
|
47
54
|
* ```
|
|
48
55
|
*/
|
|
49
|
-
declare function TestimonialsCard({ title, body, modes, style, avatarProps, accessibilityLabel, }: TestimonialsCardProps): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
declare function TestimonialsCard({ title, body, modes, style, avatarProps, accessibilityLabel, onPress, disabled, }: TestimonialsCardProps): import("react/jsx-runtime").JSX.Element;
|
|
50
57
|
declare const _default: React.MemoExoticComponent<typeof TestimonialsCard>;
|
|
51
58
|
export default _default;
|
|
52
59
|
//# sourceMappingURL=TestimonialsCard.d.ts.map
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Auto-generated from SVG files in src/icons/
|
|
5
5
|
* DO NOT EDIT MANUALLY - Run "npm run icons:generate" to regenerate
|
|
6
6
|
*
|
|
7
|
-
* Generated: 2026-06-
|
|
7
|
+
* Generated: 2026-06-29T11:40:01.320Z
|
|
8
8
|
*/
|
|
9
9
|
export declare const iconRegistry: Record<string, {
|
|
10
10
|
path: string;
|
|
@@ -25,10 +25,17 @@ export interface GlassFillProps {
|
|
|
25
25
|
/**
|
|
26
26
|
* Render a *progressive* (variable) blur instead of a uniform one: fully
|
|
27
27
|
* clear at the top, easing into a soft blur toward the bottom. Implemented
|
|
28
|
-
* by stacking
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* mask-free by stacking several bottom-anchored `BlurView` "bands": each
|
|
29
|
+
* band is clipped to start a little lower than the last, and because a
|
|
30
|
+
* `BlurView` blurs whatever is rendered behind it, the bands COMPOUND toward
|
|
31
|
+
* the bottom (a lower band re-blurs the already-blurred output above it) so
|
|
32
|
+
* the effective radius swells smoothly downward. This deliberately avoids
|
|
33
|
+
* masking a native view — the old implementation wrapped each `BlurView` in
|
|
34
|
+
* `@react-native-masked-view/masked-view`, a legacy Paper component that
|
|
35
|
+
* resolves to a plain object (crashing "Element type is invalid") under the
|
|
36
|
+
* New Architecture interop. Works on iOS and Android with no extra native
|
|
37
|
+
* module. When the native blur isn't linked at all, falls back to a pure
|
|
38
|
+
* `react-native-svg` gradient scrim (see below).
|
|
32
39
|
*/
|
|
33
40
|
progressive?: boolean;
|
|
34
41
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jfs-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "React Native Jio Finance Components Library",
|
|
5
5
|
"author": "sunshuaiqi@gmail.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
"@expo/metro-runtime": "^6.1.2",
|
|
84
84
|
"@gorhom/bottom-sheet": "5.2.6",
|
|
85
85
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
86
|
-
"@react-native-masked-view/masked-view": "^0.3.2",
|
|
87
86
|
"@shopify/flash-list": "^2.2.0",
|
|
88
87
|
"ajv": "^8.17.1",
|
|
89
88
|
"ajv-keywords": "^5.1.0",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useId } from 'react';
|
|
2
2
|
import { View, Platform, type ViewStyle } from 'react-native';
|
|
3
|
-
import
|
|
4
|
-
import Svg, { Path } from 'react-native-svg';
|
|
3
|
+
import Svg, { Defs, Mask, Path, ForeignObject } from 'react-native-svg';
|
|
5
4
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
5
|
import { EMPTY_MODES, flattenChildren } from '../../utils/react-utils';
|
|
7
6
|
import type { Modes } from '../../design-tokens'
|
|
@@ -13,6 +12,11 @@ type AvatarGroupProps = {
|
|
|
13
12
|
} & React.ComponentProps<typeof View>;
|
|
14
13
|
|
|
15
14
|
function AvatarGroup({ modes = EMPTY_MODES, children, style, ...rest }: AvatarGroupProps) {
|
|
15
|
+
// Stable, collision-free base for the per-avatar SVG mask ids so multiple
|
|
16
|
+
// groups on one screen (and multiple avatars in a group) never clash.
|
|
17
|
+
const rawId = useId();
|
|
18
|
+
const maskBaseId = `avatargroup-mask-${rawId.replace(/[^a-zA-Z0-9_-]/g, '')}`;
|
|
19
|
+
|
|
16
20
|
const gap = getVariableByName('avatarGroup/gap', modes);
|
|
17
21
|
|
|
18
22
|
|
|
@@ -43,7 +47,11 @@ function AvatarGroup({ modes = EMPTY_MODES, children, style, ...rest }: AvatarGr
|
|
|
43
47
|
const holeRadius = effectiveRadius + borderSizeInt;
|
|
44
48
|
const holeCenter = { x: nextAvatarX + r, y: r };
|
|
45
49
|
|
|
46
|
-
// Native
|
|
50
|
+
// Native mask path: the full avatar square MINUS a circular hole where the
|
|
51
|
+
// next (overlapping) avatar sits. Drawn as a single `evenodd` path so the
|
|
52
|
+
// hole is cut out of the square. Filled WHITE because react-native-svg's
|
|
53
|
+
// `<Mask>` is a *luminance* mask (white = visible, black/absent = hidden) —
|
|
54
|
+
// the inverse of the old `@react-native-masked-view` alpha convention.
|
|
47
55
|
const rectPath = `M 0 0 h ${avatarSizeInt} v ${avatarSizeInt} h -${avatarSizeInt} z`;
|
|
48
56
|
const circlePath = `M ${holeCenter.x},${holeCenter.y} m -${holeRadius},0 a ${holeRadius},${holeRadius} 0 1,0 ${holeRadius * 2},0 a ${holeRadius},${holeRadius} 0 1,0 -${holeRadius * 2},0`;
|
|
49
57
|
const maskPath = `${rectPath} ${circlePath}`;
|
|
@@ -101,23 +109,41 @@ function AvatarGroup({ modes = EMPTY_MODES, children, style, ...rest }: AvatarGr
|
|
|
101
109
|
);
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
// Native
|
|
112
|
+
// Native: mask the avatar with react-native-svg instead of the
|
|
113
|
+
// unmaintained `@react-native-masked-view/masked-view`, whose
|
|
114
|
+
// legacy `requireNativeComponent('RNCMaskedView')` resolves to a
|
|
115
|
+
// plain object (crashing "Element type is invalid") under the New
|
|
116
|
+
// Architecture interop. react-native-svg ships a Fabric/codegen
|
|
117
|
+
// `<Mask>` + `<ForeignObject>` that resolves on both architectures;
|
|
118
|
+
// the avatar is hosted inside the `<ForeignObject>` and revealed
|
|
119
|
+
// through the luminance mask.
|
|
120
|
+
const maskId = `${maskBaseId}-${index}`;
|
|
105
121
|
return (
|
|
106
122
|
<View key={index} style={wrapperStyle}>
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<Path
|
|
112
|
-
d={maskPath}
|
|
113
|
-
fill="black"
|
|
114
|
-
fillRule="evenodd"
|
|
115
|
-
/>
|
|
116
|
-
</Svg>
|
|
117
|
-
}
|
|
123
|
+
<Svg
|
|
124
|
+
height="100%"
|
|
125
|
+
width="100%"
|
|
126
|
+
viewBox={`0 0 ${avatarSizeInt} ${avatarSizeInt}`}
|
|
118
127
|
>
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
<Defs>
|
|
129
|
+
<Mask
|
|
130
|
+
id={maskId}
|
|
131
|
+
maskUnits="userSpaceOnUse"
|
|
132
|
+
maskContentUnits="userSpaceOnUse"
|
|
133
|
+
>
|
|
134
|
+
<Path d={maskPath} fill="white" fillRule="evenodd" />
|
|
135
|
+
</Mask>
|
|
136
|
+
</Defs>
|
|
137
|
+
<ForeignObject
|
|
138
|
+
x="0"
|
|
139
|
+
y="0"
|
|
140
|
+
width={avatarSizeInt}
|
|
141
|
+
height={avatarSizeInt}
|
|
142
|
+
mask={`url(#${maskId})`}
|
|
143
|
+
>
|
|
144
|
+
{clonedChild}
|
|
145
|
+
</ForeignObject>
|
|
146
|
+
</Svg>
|
|
121
147
|
</View>
|
|
122
148
|
);
|
|
123
149
|
})}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { createContext, useContext, isValidElement, cloneElement, useMemo } from 'react';
|
|
2
|
-
import { View, Text,
|
|
2
|
+
import { View, Text, Pressable, type ViewStyle, type TextStyle, type StyleProp } from 'react-native';
|
|
3
3
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
4
4
|
import { EMPTY_MODES } from '../../utils/react-utils';
|
|
5
5
|
import type { Modes } from '../../design-tokens'
|
|
@@ -39,6 +39,15 @@ export interface CardProps {
|
|
|
39
39
|
* Style overrides for the card container.
|
|
40
40
|
*/
|
|
41
41
|
style?: StyleProp<ViewStyle>;
|
|
42
|
+
/**
|
|
43
|
+
* Press handler for the whole card. When set, the card becomes pressable
|
|
44
|
+
* (rendered through a `Pressable` with `accessibilityRole="button"`).
|
|
45
|
+
*/
|
|
46
|
+
onPress?: () => void;
|
|
47
|
+
/** Disable interaction when `onPress` is set. */
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
/** Accessibility label forwarded to the pressable wrapper. */
|
|
50
|
+
accessibilityLabel?: string;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
/**
|
|
@@ -63,6 +72,9 @@ export function Card({
|
|
|
63
72
|
modes = EMPTY_MODES,
|
|
64
73
|
mediaAspectRatio = 154 / 116,
|
|
65
74
|
style,
|
|
75
|
+
onPress,
|
|
76
|
+
disabled,
|
|
77
|
+
accessibilityLabel,
|
|
66
78
|
}: CardProps) {
|
|
67
79
|
// Resolve Card Container Tokens
|
|
68
80
|
const backgroundColor = getVariableByName('card/background/color', modes);
|
|
@@ -124,23 +136,42 @@ export function Card({
|
|
|
124
136
|
paddingVertical: contentPaddingVertical,
|
|
125
137
|
};
|
|
126
138
|
|
|
139
|
+
const content = (
|
|
140
|
+
<>
|
|
141
|
+
{header && (
|
|
142
|
+
<View style={headerWrapperStyle}>
|
|
143
|
+
{headerWithModes}
|
|
144
|
+
</View>
|
|
145
|
+
)}
|
|
146
|
+
{media && (
|
|
147
|
+
<View style={mediaWrapperStyle}>
|
|
148
|
+
{mediaWithModes}
|
|
149
|
+
</View>
|
|
150
|
+
)}
|
|
151
|
+
<View style={contentWrapperStyle}>
|
|
152
|
+
{children}
|
|
153
|
+
</View>
|
|
154
|
+
</>
|
|
155
|
+
);
|
|
156
|
+
|
|
127
157
|
return (
|
|
128
158
|
<CardContext.Provider value={{ modes }}>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
{onPress ? (
|
|
160
|
+
<Pressable
|
|
161
|
+
style={[containerStyle, style]}
|
|
162
|
+
onPress={onPress}
|
|
163
|
+
disabled={disabled}
|
|
164
|
+
accessibilityRole="button"
|
|
165
|
+
accessibilityLabel={accessibilityLabel}
|
|
166
|
+
accessibilityState={{ disabled: !!disabled }}
|
|
167
|
+
>
|
|
168
|
+
{content}
|
|
169
|
+
</Pressable>
|
|
170
|
+
) : (
|
|
171
|
+
<View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
|
|
172
|
+
{content}
|
|
142
173
|
</View>
|
|
143
|
-
|
|
174
|
+
)}
|
|
144
175
|
</CardContext.Provider>
|
|
145
176
|
);
|
|
146
177
|
}
|