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
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [0.1.19] - 2026-06-29
|
|
8
|
+
|
|
9
|
+
- Card components — optional `onPress` handler added to `Card`, `CardInsight`, `CardProviderInfo`, `MediaCard`, `DebitCard`, `CardFeedback`, `RechargeCard`, and `TestimonialsCard`. When set, the card renders through a `Pressable` with `accessibilityRole="button"`, optional `disabled`, and a pressed-state opacity feedback; when omitted, behaviour is unchanged.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## [0.1.18] - 2026-06-29
|
|
14
|
+
|
|
15
|
+
- **Fix:** Remove `@react-native-masked-view/masked-view` — fixes `Element type is invalid` crash on New Architecture (`ProductMerchandisingCard` image cards, `AvatarGroup`, `GlassFill` progressive blur). All masking now uses `react-native-svg` (no new peer deps; consumers can drop `masked-view` if added as a workaround).
|
|
16
|
+
- `ProductMerchandisingCard` — footer image blur via SVG `FeGaussianBlur` + gradient mask (cross-platform, no per-platform `blurRadius` tuning).
|
|
17
|
+
- `AvatarGroup` — overlap cutout via SVG `Mask` + `ForeignObject`.
|
|
18
|
+
- `GlassFill` — progressive blur via stacked `BlurView` bands; no-native-blur fallback uses SVG gradient scrim.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
7
22
|
## [0.1.16] - 2026-06-26
|
|
8
23
|
|
|
9
24
|
- Added `CarouselCardAccounts` — horizontally scrollable account-card strip built on `Carousel` with token-driven gap and snap-aligned card slots.
|
|
@@ -4,21 +4,23 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
var _react =
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
-
var _maskedView = _interopRequireDefault(require("@react-native-masked-view/masked-view"));
|
|
10
9
|
var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
|
|
11
10
|
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
12
11
|
var _reactUtils = require("../../utils/react-utils");
|
|
13
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
13
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
15
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
14
|
function AvatarGroup({
|
|
17
15
|
modes = _reactUtils.EMPTY_MODES,
|
|
18
16
|
children,
|
|
19
17
|
style,
|
|
20
18
|
...rest
|
|
21
19
|
}) {
|
|
20
|
+
// Stable, collision-free base for the per-avatar SVG mask ids so multiple
|
|
21
|
+
// groups on one screen (and multiple avatars in a group) never clash.
|
|
22
|
+
const rawId = (0, _react.useId)();
|
|
23
|
+
const maskBaseId = `avatargroup-mask-${rawId.replace(/[^a-zA-Z0-9_-]/g, '')}`;
|
|
22
24
|
const gap = (0, _figmaVariablesResolver.getVariableByName)('avatarGroup/gap', modes);
|
|
23
25
|
const avatarSize = (0, _figmaVariablesResolver.getVariableByName)('avatar/size', modes);
|
|
24
26
|
const avatarRadius = (0, _figmaVariablesResolver.getVariableByName)('avatar/radius', modes);
|
|
@@ -47,7 +49,11 @@ function AvatarGroup({
|
|
|
47
49
|
y: r
|
|
48
50
|
};
|
|
49
51
|
|
|
50
|
-
// Native
|
|
52
|
+
// Native mask path: the full avatar square MINUS a circular hole where the
|
|
53
|
+
// next (overlapping) avatar sits. Drawn as a single `evenodd` path so the
|
|
54
|
+
// hole is cut out of the square. Filled WHITE because react-native-svg's
|
|
55
|
+
// `<Mask>` is a *luminance* mask (white = visible, black/absent = hidden) —
|
|
56
|
+
// the inverse of the old `@react-native-masked-view` alpha convention.
|
|
51
57
|
const rectPath = `M 0 0 h ${avatarSizeInt} v ${avatarSizeInt} h -${avatarSizeInt} z`;
|
|
52
58
|
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`;
|
|
53
59
|
const maskPath = `${rectPath} ${circlePath}`;
|
|
@@ -105,25 +111,40 @@ function AvatarGroup({
|
|
|
105
111
|
}, index);
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
// Native
|
|
114
|
+
// Native: mask the avatar with react-native-svg instead of the
|
|
115
|
+
// unmaintained `@react-native-masked-view/masked-view`, whose
|
|
116
|
+
// legacy `requireNativeComponent('RNCMaskedView')` resolves to a
|
|
117
|
+
// plain object (crashing "Element type is invalid") under the New
|
|
118
|
+
// Architecture interop. react-native-svg ships a Fabric/codegen
|
|
119
|
+
// `<Mask>` + `<ForeignObject>` that resolves on both architectures;
|
|
120
|
+
// the avatar is hosted inside the `<ForeignObject>` and revealed
|
|
121
|
+
// through the luminance mask.
|
|
122
|
+
const maskId = `${maskBaseId}-${index}`;
|
|
109
123
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
110
124
|
style: wrapperStyle,
|
|
111
|
-
children: /*#__PURE__*/(0, _jsxRuntime.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.default, {
|
|
126
|
+
height: "100%",
|
|
127
|
+
width: "100%",
|
|
128
|
+
viewBox: `0 0 ${avatarSizeInt} ${avatarSizeInt}`,
|
|
129
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Defs, {
|
|
130
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Mask, {
|
|
131
|
+
id: maskId,
|
|
132
|
+
maskUnits: "userSpaceOnUse",
|
|
133
|
+
maskContentUnits: "userSpaceOnUse",
|
|
134
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
|
|
135
|
+
d: maskPath,
|
|
136
|
+
fill: "white",
|
|
137
|
+
fillRule: "evenodd"
|
|
138
|
+
})
|
|
124
139
|
})
|
|
125
|
-
}),
|
|
126
|
-
|
|
140
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.ForeignObject, {
|
|
141
|
+
x: "0",
|
|
142
|
+
y: "0",
|
|
143
|
+
width: avatarSizeInt,
|
|
144
|
+
height: avatarSizeInt,
|
|
145
|
+
mask: `url(#${maskId})`,
|
|
146
|
+
children: clonedChild
|
|
147
|
+
})]
|
|
127
148
|
})
|
|
128
149
|
}, index);
|
|
129
150
|
})
|
|
@@ -38,7 +38,10 @@ function Card({
|
|
|
38
38
|
children,
|
|
39
39
|
modes = _reactUtils.EMPTY_MODES,
|
|
40
40
|
mediaAspectRatio = 154 / 116,
|
|
41
|
-
style
|
|
41
|
+
style,
|
|
42
|
+
onPress,
|
|
43
|
+
disabled,
|
|
44
|
+
accessibilityLabel
|
|
42
45
|
}) {
|
|
43
46
|
// Resolve Card Container Tokens
|
|
44
47
|
const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('card/background/color', modes);
|
|
@@ -102,22 +105,36 @@ function Card({
|
|
|
102
105
|
paddingHorizontal: contentPaddingHorizontal,
|
|
103
106
|
paddingVertical: contentPaddingVertical
|
|
104
107
|
};
|
|
108
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
109
|
+
children: [header && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
110
|
+
style: headerWrapperStyle,
|
|
111
|
+
children: headerWithModes
|
|
112
|
+
}), media && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
113
|
+
style: mediaWrapperStyle,
|
|
114
|
+
children: mediaWithModes
|
|
115
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
116
|
+
style: contentWrapperStyle,
|
|
117
|
+
children: children
|
|
118
|
+
})]
|
|
119
|
+
});
|
|
105
120
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(CardContext.Provider, {
|
|
106
121
|
value: {
|
|
107
122
|
modes
|
|
108
123
|
},
|
|
109
|
-
children: /*#__PURE__*/(0, _jsxRuntime.
|
|
124
|
+
children: onPress ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
125
|
+
style: [containerStyle, style],
|
|
126
|
+
onPress: onPress,
|
|
127
|
+
disabled: disabled,
|
|
128
|
+
accessibilityRole: "button",
|
|
129
|
+
accessibilityLabel: accessibilityLabel,
|
|
130
|
+
accessibilityState: {
|
|
131
|
+
disabled: !!disabled
|
|
132
|
+
},
|
|
133
|
+
children: content
|
|
134
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
110
135
|
style: [containerStyle, style],
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
children: headerWithModes
|
|
114
|
-
}), media && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
115
|
-
style: mediaWrapperStyle,
|
|
116
|
-
children: mediaWithModes
|
|
117
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
118
|
-
style: contentWrapperStyle,
|
|
119
|
-
children: children
|
|
120
|
-
})]
|
|
136
|
+
accessibilityLabel: accessibilityLabel,
|
|
137
|
+
children: content
|
|
121
138
|
})
|
|
122
139
|
});
|
|
123
140
|
}
|
|
@@ -29,7 +29,10 @@ const CardFeedbackContext = /*#__PURE__*/(0, _react.createContext)({});
|
|
|
29
29
|
function CardFeedback({
|
|
30
30
|
children,
|
|
31
31
|
modes: propModes,
|
|
32
|
-
style
|
|
32
|
+
style,
|
|
33
|
+
onPress,
|
|
34
|
+
disabled,
|
|
35
|
+
accessibilityLabel
|
|
33
36
|
}) {
|
|
34
37
|
const modes = {
|
|
35
38
|
'Appearance.System': 'positive',
|
|
@@ -58,8 +61,19 @@ function CardFeedback({
|
|
|
58
61
|
value: {
|
|
59
62
|
modes
|
|
60
63
|
},
|
|
61
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.
|
|
64
|
+
children: onPress ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.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: children
|
|
74
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
62
75
|
style: [containerStyle, style],
|
|
76
|
+
accessibilityLabel: accessibilityLabel,
|
|
63
77
|
children: children
|
|
64
78
|
})
|
|
65
79
|
});
|
|
@@ -33,7 +33,10 @@ function CardInsight({
|
|
|
33
33
|
footer,
|
|
34
34
|
divider,
|
|
35
35
|
modes = _reactUtils.EMPTY_MODES,
|
|
36
|
-
style
|
|
36
|
+
style,
|
|
37
|
+
onPress,
|
|
38
|
+
disabled,
|
|
39
|
+
accessibilityLabel
|
|
37
40
|
}) {
|
|
38
41
|
const background = (0, _figmaVariablesResolver.getVariableByName)('cardInsight/background', modes) ?? '#ffffff';
|
|
39
42
|
const radius = (0, _figmaVariablesResolver.getVariableByName)('cardInsight/radius', modes) ?? 12;
|
|
@@ -106,18 +109,18 @@ function CardInsight({
|
|
|
106
109
|
};
|
|
107
110
|
const footerNode = renderFooter();
|
|
108
111
|
const showDivider = footerNode !== null && divider !== false && divider !== null;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
const containerStyle = {
|
|
113
|
+
backgroundColor: background,
|
|
114
|
+
borderRadius: radius,
|
|
115
|
+
borderWidth,
|
|
116
|
+
borderColor,
|
|
117
|
+
paddingHorizontal,
|
|
118
|
+
paddingVertical,
|
|
119
|
+
gap,
|
|
120
|
+
overflow: 'hidden',
|
|
121
|
+
alignItems: 'stretch'
|
|
122
|
+
};
|
|
123
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
121
124
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
122
125
|
style: {
|
|
123
126
|
flexDirection: 'row',
|
|
@@ -165,5 +168,23 @@ function CardInsight({
|
|
|
165
168
|
children: renderSlot()
|
|
166
169
|
}), showDivider ? renderDivider() : null, footerNode]
|
|
167
170
|
});
|
|
171
|
+
if (onPress) {
|
|
172
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
173
|
+
style: [containerStyle, style],
|
|
174
|
+
onPress: onPress,
|
|
175
|
+
disabled: disabled,
|
|
176
|
+
accessibilityRole: "button",
|
|
177
|
+
accessibilityLabel: accessibilityLabel ?? title,
|
|
178
|
+
accessibilityState: {
|
|
179
|
+
disabled: !!disabled
|
|
180
|
+
},
|
|
181
|
+
children: content
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
185
|
+
style: [containerStyle, style],
|
|
186
|
+
accessibilityLabel: accessibilityLabel,
|
|
187
|
+
children: content
|
|
188
|
+
});
|
|
168
189
|
}
|
|
169
190
|
var _default = exports.default = CardInsight;
|
|
@@ -23,7 +23,10 @@ function CardProviderInfo({
|
|
|
23
23
|
imageSource,
|
|
24
24
|
children,
|
|
25
25
|
modes = _reactUtils.EMPTY_MODES,
|
|
26
|
-
style
|
|
26
|
+
style,
|
|
27
|
+
onPress,
|
|
28
|
+
disabled,
|
|
29
|
+
accessibilityLabel
|
|
27
30
|
}) {
|
|
28
31
|
const background = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/background', modes) ?? '#fef4e5';
|
|
29
32
|
const border = (0, _figmaVariablesResolver.getVariableByName)('card/providerInfo/border', modes) ?? '#fef4e5';
|
|
@@ -48,8 +51,7 @@ function CardProviderInfo({
|
|
|
48
51
|
for (let i = 0; i < childArray.length; i += 2) {
|
|
49
52
|
rows.push(childArray.slice(i, i + 2));
|
|
50
53
|
}
|
|
51
|
-
|
|
52
|
-
style: [containerStyle, style],
|
|
54
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
53
55
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ProductLabel.default, {
|
|
54
56
|
label: label,
|
|
55
57
|
imageSource: imageSource,
|
|
@@ -72,5 +74,23 @@ function CardProviderInfo({
|
|
|
72
74
|
}, i))
|
|
73
75
|
})]
|
|
74
76
|
});
|
|
77
|
+
if (onPress) {
|
|
78
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
79
|
+
style: [containerStyle, style],
|
|
80
|
+
onPress: onPress,
|
|
81
|
+
disabled: disabled,
|
|
82
|
+
accessibilityRole: "button",
|
|
83
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
84
|
+
accessibilityState: {
|
|
85
|
+
disabled: !!disabled
|
|
86
|
+
},
|
|
87
|
+
children: content
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
91
|
+
style: [containerStyle, style],
|
|
92
|
+
accessibilityLabel: accessibilityLabel,
|
|
93
|
+
children: content
|
|
94
|
+
});
|
|
75
95
|
}
|
|
76
96
|
var _default = exports.default = CardProviderInfo;
|
|
@@ -22,7 +22,10 @@ function DebitCard({
|
|
|
22
22
|
bankLogoSlot,
|
|
23
23
|
providerLogoSlot,
|
|
24
24
|
modes: propModes = _reactUtils.EMPTY_MODES,
|
|
25
|
-
style
|
|
25
|
+
style,
|
|
26
|
+
onPress,
|
|
27
|
+
disabled,
|
|
28
|
+
accessibilityLabel
|
|
26
29
|
}) {
|
|
27
30
|
const {
|
|
28
31
|
modes: globalModes
|
|
@@ -121,8 +124,7 @@ function DebitCard({
|
|
|
121
124
|
};
|
|
122
125
|
return cardArtSource;
|
|
123
126
|
}, [cardArtSource]);
|
|
124
|
-
|
|
125
|
-
style: [containerStyle, style],
|
|
127
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
126
128
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
127
129
|
style: headerStyle,
|
|
128
130
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
@@ -162,5 +164,23 @@ function DebitCard({
|
|
|
162
164
|
})]
|
|
163
165
|
})]
|
|
164
166
|
});
|
|
167
|
+
if (onPress) {
|
|
168
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
169
|
+
style: [containerStyle, style],
|
|
170
|
+
onPress: onPress,
|
|
171
|
+
disabled: disabled,
|
|
172
|
+
accessibilityRole: "button",
|
|
173
|
+
accessibilityLabel: accessibilityLabel ?? `${bankName} ${cardType} ${cardNumber}`,
|
|
174
|
+
accessibilityState: {
|
|
175
|
+
disabled: !!disabled
|
|
176
|
+
},
|
|
177
|
+
children: content
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
181
|
+
style: [containerStyle, style],
|
|
182
|
+
accessibilityLabel: accessibilityLabel,
|
|
183
|
+
children: content
|
|
184
|
+
});
|
|
165
185
|
}
|
|
166
186
|
var _default = exports.default = DebitCard;
|
|
@@ -44,7 +44,10 @@ function MediaCard({
|
|
|
44
44
|
media,
|
|
45
45
|
children,
|
|
46
46
|
modes = _reactUtils.EMPTY_MODES,
|
|
47
|
-
style
|
|
47
|
+
style,
|
|
48
|
+
onPress,
|
|
49
|
+
disabled,
|
|
50
|
+
accessibilityLabel
|
|
48
51
|
}) {
|
|
49
52
|
const radius = parseFloat((0, _figmaVariablesResolver.getVariableByName)('cardMedia/radius', modes));
|
|
50
53
|
const containerStyle = {
|
|
@@ -59,17 +62,31 @@ function MediaCard({
|
|
|
59
62
|
accessibilityElementsHidden: true,
|
|
60
63
|
importantForAccessibility: "no"
|
|
61
64
|
}) : null);
|
|
65
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
66
|
+
children: [background, children != null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
67
|
+
style: _reactNative.StyleSheet.absoluteFill,
|
|
68
|
+
pointerEvents: "box-none",
|
|
69
|
+
children: children
|
|
70
|
+
}) : null]
|
|
71
|
+
});
|
|
62
72
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(MediaCardContext.Provider, {
|
|
63
73
|
value: {
|
|
64
74
|
modes
|
|
65
75
|
},
|
|
66
|
-
children: /*#__PURE__*/(0, _jsxRuntime.
|
|
76
|
+
children: onPress ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
77
|
+
style: [containerStyle, style],
|
|
78
|
+
onPress: onPress,
|
|
79
|
+
disabled: disabled,
|
|
80
|
+
accessibilityRole: "button",
|
|
81
|
+
accessibilityLabel: accessibilityLabel,
|
|
82
|
+
accessibilityState: {
|
|
83
|
+
disabled: !!disabled
|
|
84
|
+
},
|
|
85
|
+
children: content
|
|
86
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
67
87
|
style: [containerStyle, style],
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
pointerEvents: "box-none",
|
|
71
|
-
children: children
|
|
72
|
-
}) : null]
|
|
88
|
+
accessibilityLabel: accessibilityLabel,
|
|
89
|
+
children: content
|
|
73
90
|
})
|
|
74
91
|
});
|
|
75
92
|
}
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
-
var _maskedView = _interopRequireDefault(require("@react-native-masked-view/masked-view"));
|
|
10
9
|
var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
|
|
11
10
|
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
12
11
|
var _reactUtils = require("../../utils/react-utils");
|
|
@@ -71,7 +70,9 @@ function ProductMerchandisingCard({
|
|
|
71
70
|
const rawId = (0, _react.useId)();
|
|
72
71
|
const safeId = rawId.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
73
72
|
const scrimId = `pmc-footer-scrim-${safeId}`;
|
|
73
|
+
const blurGradientId = `pmc-footer-blurgrad-${safeId}`;
|
|
74
74
|
const blurMaskId = `pmc-footer-blurmask-${safeId}`;
|
|
75
|
+
const blurFilterId = `pmc-footer-blurfilter-${safeId}`;
|
|
75
76
|
const normalizedImageSource = (0, _react.useMemo)(() => normalizeImageSource(imageSource), [imageSource]);
|
|
76
77
|
const tokens = (0, _react.useMemo)(() => resolveTokens(modes), [modes]);
|
|
77
78
|
const containerStyle = {
|
|
@@ -165,57 +166,63 @@ function ProductMerchandisingCard({
|
|
|
165
166
|
children: [normalizedImageSource != null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
166
167
|
style: _reactNative.StyleSheet.absoluteFill,
|
|
167
168
|
pointerEvents: "none",
|
|
168
|
-
children: /*#__PURE__*/(0, _jsxRuntime.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
169
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.default, {
|
|
170
|
+
width: "100%",
|
|
171
|
+
height: "100%",
|
|
172
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.Defs, {
|
|
173
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Filter, {
|
|
174
|
+
id: blurFilterId,
|
|
175
|
+
x: "-15%",
|
|
176
|
+
y: "-15%",
|
|
177
|
+
width: "130%",
|
|
178
|
+
height: "130%",
|
|
179
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.FeGaussianBlur, {
|
|
180
|
+
stdDeviation: tokens.imageBlurStdDeviation,
|
|
181
|
+
edgeMode: "duplicate"
|
|
182
|
+
})
|
|
183
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.LinearGradient, {
|
|
184
|
+
id: blurGradientId,
|
|
185
|
+
x1: "0",
|
|
186
|
+
y1: "0",
|
|
187
|
+
x2: "0",
|
|
188
|
+
y2: "1",
|
|
189
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, {
|
|
190
|
+
offset: "0",
|
|
191
|
+
stopColor: "#ffffff",
|
|
192
|
+
stopOpacity: 0
|
|
193
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, {
|
|
194
|
+
offset: "0.35",
|
|
195
|
+
stopColor: "#ffffff",
|
|
196
|
+
stopOpacity: 0.5
|
|
197
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, {
|
|
198
|
+
offset: "0.7",
|
|
199
|
+
stopColor: "#ffffff",
|
|
200
|
+
stopOpacity: 0.92
|
|
201
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Stop, {
|
|
202
|
+
offset: "1",
|
|
203
|
+
stopColor: "#ffffff",
|
|
204
|
+
stopOpacity: 1
|
|
205
|
+
})]
|
|
206
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Mask, {
|
|
207
|
+
id: blurMaskId,
|
|
208
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Rect, {
|
|
209
|
+
x: "0",
|
|
210
|
+
y: "0",
|
|
211
|
+
width: "100%",
|
|
212
|
+
height: "100%",
|
|
213
|
+
fill: `url(#${blurGradientId})`
|
|
197
214
|
})
|
|
198
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Rect, {
|
|
199
|
-
x: "0",
|
|
200
|
-
y: "0",
|
|
201
|
-
width: "100%",
|
|
202
|
-
height: "100%",
|
|
203
|
-
fill: `url(#${blurMaskId})`
|
|
204
215
|
})]
|
|
205
|
-
}),
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
width: '100%',
|
|
216
|
-
height
|
|
217
|
-
}
|
|
218
|
-
})
|
|
216
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Image, {
|
|
217
|
+
href: normalizedImageSource,
|
|
218
|
+
x: "0",
|
|
219
|
+
y: "0",
|
|
220
|
+
width: "100%",
|
|
221
|
+
height: "100%",
|
|
222
|
+
preserveAspectRatio: "xMidYMid slice",
|
|
223
|
+
filter: `url(#${blurFilterId})`,
|
|
224
|
+
mask: `url(#${blurMaskId})`
|
|
225
|
+
})]
|
|
219
226
|
})
|
|
220
227
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_GlassFill.default, {
|
|
221
228
|
tint: "dark",
|
|
@@ -334,19 +341,16 @@ function resolveTokens(modes) {
|
|
|
334
341
|
const sbFamily = asStr((0, _figmaVariablesResolver.getVariableByName)('productMerchandisingcard/specialbadge/text/fontfamily', modes), 'JioType Var');
|
|
335
342
|
const sbWeight = asStr((0, _figmaVariablesResolver.getVariableByName)('productMerchandisingcard/specialbadge/text/fontweight', modes), '500');
|
|
336
343
|
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
//
|
|
340
|
-
// "
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
android: Math.max(12, Math.round(blurRadius * 0.95)),
|
|
344
|
-
default: Math.max(8, Math.round(blurRadius * 0.6))
|
|
345
|
-
});
|
|
344
|
+
// SVG `<FeGaussianBlur stdDeviation>` is resolution-independent and renders
|
|
345
|
+
// an identical Gaussian on iOS, Android and web — so unlike the old
|
|
346
|
+
// `Image.blurRadius` path it needs no per-platform tuning. `stdDeviation` is
|
|
347
|
+
// roughly half a perceptual "blur radius", so we scale the `blur/minimal`
|
|
348
|
+
// token down to land on the same subtle frosted strength as the design.
|
|
349
|
+
const imageBlurStdDeviation = Math.max(4, Math.round(blurRadius * 0.35));
|
|
346
350
|
return {
|
|
347
351
|
radius,
|
|
348
352
|
blurIntensity: Math.max(0, Math.min(100, Math.round(blurRadius * BLUR_INTENSITY_FACTOR))),
|
|
349
|
-
|
|
353
|
+
imageBlurStdDeviation,
|
|
350
354
|
header: {
|
|
351
355
|
flexDirection: 'row',
|
|
352
356
|
alignItems: 'flex-start',
|
|
@@ -41,7 +41,10 @@ function RechargeCard({
|
|
|
41
41
|
subscriptionContent,
|
|
42
42
|
actions,
|
|
43
43
|
modes = _reactUtils.EMPTY_MODES,
|
|
44
|
-
style
|
|
44
|
+
style,
|
|
45
|
+
onPress,
|
|
46
|
+
disabled,
|
|
47
|
+
accessibilityLabel
|
|
45
48
|
}) {
|
|
46
49
|
// Container Tokens (defaults mirror Figma node 2235:937).
|
|
47
50
|
const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('rechargeCard/background', modes);
|
|
@@ -90,18 +93,18 @@ function RechargeCard({
|
|
|
90
93
|
// Pass modes to subscription children (e.g. AvatarGroup)
|
|
91
94
|
// Now encapsulated, so we just pass children to AvatarGroup
|
|
92
95
|
const hasSubscriptions = _react.default.Children.count(subscriptionContent) > 0;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
96
|
+
const containerStyle = {
|
|
97
|
+
backgroundColor,
|
|
98
|
+
paddingHorizontal,
|
|
99
|
+
paddingVertical,
|
|
100
|
+
gap,
|
|
101
|
+
borderRadius: radius,
|
|
102
|
+
borderWidth: strokeWidth,
|
|
103
|
+
borderColor: strokeColor,
|
|
104
|
+
minWidth,
|
|
105
|
+
alignItems: 'flex-start'
|
|
106
|
+
};
|
|
107
|
+
const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
105
108
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
106
109
|
style: {
|
|
107
110
|
gap: headerGap,
|
|
@@ -217,4 +220,22 @@ function RechargeCard({
|
|
|
217
220
|
children: actions
|
|
218
221
|
})]
|
|
219
222
|
});
|
|
223
|
+
if (onPress) {
|
|
224
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
225
|
+
style: [containerStyle, style],
|
|
226
|
+
onPress: onPress,
|
|
227
|
+
disabled: disabled,
|
|
228
|
+
accessibilityRole: "button",
|
|
229
|
+
accessibilityLabel: accessibilityLabel ?? title,
|
|
230
|
+
accessibilityState: {
|
|
231
|
+
disabled: !!disabled
|
|
232
|
+
},
|
|
233
|
+
children: content
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
237
|
+
style: [containerStyle, style],
|
|
238
|
+
accessibilityLabel: accessibilityLabel,
|
|
239
|
+
children: content
|
|
240
|
+
});
|
|
220
241
|
}
|