jfs-components 0.1.18 → 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.
Files changed (38) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/lib/commonjs/components/Card/Card.js +29 -12
  3. package/lib/commonjs/components/CardFeedback/CardFeedback.js +16 -2
  4. package/lib/commonjs/components/CardInsight/CardInsight.js +34 -13
  5. package/lib/commonjs/components/CardProviderInfo/CardProviderInfo.js +23 -3
  6. package/lib/commonjs/components/DebitCard/DebitCard.js +23 -3
  7. package/lib/commonjs/components/MediaCard/MediaCard.js +24 -7
  8. package/lib/commonjs/components/RechargeCard/RechargeCard.js +34 -13
  9. package/lib/commonjs/components/TestimonialsCard/TestimonialsCard.js +23 -5
  10. package/lib/commonjs/icons/registry.js +1 -1
  11. package/lib/module/components/Card/Card.js +31 -14
  12. package/lib/module/components/CardFeedback/CardFeedback.js +17 -3
  13. package/lib/module/components/CardInsight/CardInsight.js +36 -15
  14. package/lib/module/components/CardProviderInfo/CardProviderInfo.js +25 -5
  15. package/lib/module/components/DebitCard/DebitCard.js +25 -5
  16. package/lib/module/components/MediaCard/MediaCard.js +26 -9
  17. package/lib/module/components/RechargeCard/RechargeCard.js +36 -15
  18. package/lib/module/components/TestimonialsCard/TestimonialsCard.js +25 -7
  19. package/lib/module/icons/registry.js +1 -1
  20. package/lib/typescript/src/components/Card/Card.d.ts +10 -1
  21. package/lib/typescript/src/components/CardFeedback/CardFeedback.d.ts +10 -1
  22. package/lib/typescript/src/components/CardInsight/CardInsight.d.ts +10 -1
  23. package/lib/typescript/src/components/CardProviderInfo/CardProviderInfo.d.ts +10 -1
  24. package/lib/typescript/src/components/DebitCard/DebitCard.d.ts +10 -1
  25. package/lib/typescript/src/components/MediaCard/MediaCard.d.ts +10 -1
  26. package/lib/typescript/src/components/RechargeCard/RechargeCard.d.ts +10 -1
  27. package/lib/typescript/src/components/TestimonialsCard/TestimonialsCard.d.ts +8 -1
  28. package/lib/typescript/src/icons/registry.d.ts +1 -1
  29. package/package.json +1 -1
  30. package/src/components/Card/Card.tsx +46 -15
  31. package/src/components/CardFeedback/CardFeedback.tsx +29 -4
  32. package/src/components/CardInsight/CardInsight.tsx +48 -17
  33. package/src/components/CardProviderInfo/CardProviderInfo.tsx +36 -3
  34. package/src/components/DebitCard/DebitCard.tsx +36 -3
  35. package/src/components/MediaCard/MediaCard.tsx +40 -9
  36. package/src/components/RechargeCard/RechargeCard.tsx +48 -13
  37. package/src/components/TestimonialsCard/TestimonialsCard.tsx +37 -6
  38. package/src/icons/registry.ts +1 -1
@@ -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-29T08:47:00.741Z
7
+ * Generated: 2026-06-29T11:40:01.320Z
8
8
  */
9
9
  export declare const iconRegistry: Record<string, {
10
10
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfs-components",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "React Native Jio Finance Components Library",
5
5
  "author": "sunshuaiqi@gmail.com",
6
6
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext, isValidElement, cloneElement, useMemo } from 'react';
2
- import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp } from 'react-native';
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
- <View style={[containerStyle, style]}>
130
- {header && (
131
- <View style={headerWrapperStyle}>
132
- {headerWithModes}
133
- </View>
134
- )}
135
- {media && (
136
- <View style={mediaWrapperStyle}>
137
- {mediaWithModes}
138
- </View>
139
- )}
140
- <View style={contentWrapperStyle}>
141
- {children}
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
- </View>
174
+ )}
144
175
  </CardContext.Provider>
145
176
  );
146
177
  }
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext, isValidElement, cloneElement } from 'react';
2
- import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp, Image } from 'react-native';
2
+ import { View, Text, Pressable, type ViewStyle, type TextStyle, type StyleProp, Image } from 'react-native';
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
4
4
  import IconComponent from '../../icons/Icon';
5
5
  import type { Modes } from '../../design-tokens'
@@ -22,6 +22,15 @@ export interface CardFeedbackProps {
22
22
  * Style overrides for the card container.
23
23
  */
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
35
 
27
36
  /**
@@ -33,6 +42,9 @@ export function CardFeedback({
33
42
  children,
34
43
  modes: propModes,
35
44
  style,
45
+ onPress,
46
+ disabled,
47
+ accessibilityLabel,
36
48
  }: CardFeedbackProps) {
37
49
  const modes = {
38
50
  'Appearance.System': 'positive',
@@ -61,9 +73,22 @@ export function CardFeedback({
61
73
 
62
74
  return (
63
75
  <CardFeedbackContext.Provider value={{ modes }}>
64
- <View style={[containerStyle, style]}>
65
- {children}
66
- </View>
76
+ {onPress ? (
77
+ <Pressable
78
+ style={[containerStyle, style]}
79
+ onPress={onPress}
80
+ disabled={disabled}
81
+ accessibilityRole="button"
82
+ accessibilityLabel={accessibilityLabel}
83
+ accessibilityState={{ disabled: !!disabled }}
84
+ >
85
+ {children}
86
+ </Pressable>
87
+ ) : (
88
+ <View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
89
+ {children}
90
+ </View>
91
+ )}
67
92
  </CardFeedbackContext.Provider>
68
93
  );
69
94
  }
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import {
3
3
  View,
4
4
  Text,
5
+ Pressable,
5
6
  type StyleProp,
6
7
  type ViewStyle,
7
8
  type TextStyle,
@@ -45,6 +46,15 @@ export type CardInsightProps = {
45
46
  modes?: Modes
46
47
  /** Override container styles. */
47
48
  style?: StyleProp<ViewStyle>
49
+ /**
50
+ * Press handler for the whole card. When set, the card becomes pressable
51
+ * (rendered through a `Pressable` with `accessibilityRole="button"`).
52
+ */
53
+ onPress?: () => void
54
+ /** Disable interaction when `onPress` is set. */
55
+ disabled?: boolean
56
+ /** Accessibility label forwarded to the pressable wrapper (defaults to `title`). */
57
+ accessibilityLabel?: string
48
58
  }
49
59
 
50
60
  /**
@@ -67,6 +77,9 @@ function CardInsight({
67
77
  divider,
68
78
  modes = EMPTY_MODES,
69
79
  style,
80
+ onPress,
81
+ disabled,
82
+ accessibilityLabel,
70
83
  }: CardInsightProps) {
71
84
  const background =
72
85
  (getVariableByName('cardInsight/background', modes) as string | null) ?? '#ffffff'
@@ -160,23 +173,20 @@ function CardInsight({
160
173
  const footerNode = renderFooter()
161
174
  const showDivider = footerNode !== null && divider !== false && divider !== null
162
175
 
163
- return (
164
- <View
165
- style={[
166
- {
167
- backgroundColor: background,
168
- borderRadius: radius,
169
- borderWidth,
170
- borderColor,
171
- paddingHorizontal,
172
- paddingVertical,
173
- gap,
174
- overflow: 'hidden',
175
- alignItems: 'stretch',
176
- },
177
- style,
178
- ]}
179
- >
176
+ const containerStyle: ViewStyle = {
177
+ backgroundColor: background,
178
+ borderRadius: radius,
179
+ borderWidth,
180
+ borderColor,
181
+ paddingHorizontal,
182
+ paddingVertical,
183
+ gap,
184
+ overflow: 'hidden',
185
+ alignItems: 'stretch',
186
+ }
187
+
188
+ const content = (
189
+ <>
180
190
  <View
181
191
  style={{
182
192
  flexDirection: 'row',
@@ -237,6 +247,27 @@ function CardInsight({
237
247
  {showDivider ? renderDivider() : null}
238
248
 
239
249
  {footerNode}
250
+ </>
251
+ )
252
+
253
+ if (onPress) {
254
+ return (
255
+ <Pressable
256
+ style={[containerStyle, style]}
257
+ onPress={onPress}
258
+ disabled={disabled}
259
+ accessibilityRole="button"
260
+ accessibilityLabel={accessibilityLabel ?? title}
261
+ accessibilityState={{ disabled: !!disabled }}
262
+ >
263
+ {content}
264
+ </Pressable>
265
+ )
266
+ }
267
+
268
+ return (
269
+ <View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
270
+ {content}
240
271
  </View>
241
272
  )
242
273
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { View, type ViewStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
2
+ import { View, Pressable, type ViewStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import ProductLabel from '../ProductLabel/ProductLabel'
5
5
  import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
@@ -16,6 +16,15 @@ export type CardProviderInfoProps = {
16
16
  modes?: Modes
17
17
  /** Override container styles. */
18
18
  style?: StyleProp<ViewStyle>
19
+ /**
20
+ * Press handler for the whole card. When set, the card becomes pressable
21
+ * (rendered through a `Pressable` with `accessibilityRole="button"`).
22
+ */
23
+ onPress?: () => void
24
+ /** Disable interaction when `onPress` is set. */
25
+ disabled?: boolean
26
+ /** Accessibility label forwarded to the pressable wrapper (defaults to `label`). */
27
+ accessibilityLabel?: string
19
28
  }
20
29
 
21
30
  /**
@@ -31,6 +40,9 @@ function CardProviderInfo({
31
40
  children,
32
41
  modes = EMPTY_MODES,
33
42
  style,
43
+ onPress,
44
+ disabled,
45
+ accessibilityLabel,
34
46
  }: CardProviderInfoProps) {
35
47
  const background = getVariableByName('card/providerInfo/background', modes) ?? '#fef4e5'
36
48
  const border = getVariableByName('card/providerInfo/border', modes) ?? '#fef4e5'
@@ -59,8 +71,8 @@ function CardProviderInfo({
59
71
  rows.push(childArray.slice(i, i + 2))
60
72
  }
61
73
 
62
- return (
63
- <View style={[containerStyle, style]}>
74
+ const content = (
75
+ <>
64
76
  <ProductLabel label={label} imageSource={imageSource} modes={modes} />
65
77
  {childArray.length > 0 && (
66
78
  <View style={{ rowGap: gridGapNum }}>
@@ -75,6 +87,27 @@ function CardProviderInfo({
75
87
  ))}
76
88
  </View>
77
89
  )}
90
+ </>
91
+ )
92
+
93
+ if (onPress) {
94
+ return (
95
+ <Pressable
96
+ style={[containerStyle, style]}
97
+ onPress={onPress}
98
+ disabled={disabled}
99
+ accessibilityRole="button"
100
+ accessibilityLabel={accessibilityLabel ?? label}
101
+ accessibilityState={{ disabled: !!disabled }}
102
+ >
103
+ {content}
104
+ </Pressable>
105
+ )
106
+ }
107
+
108
+ return (
109
+ <View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
110
+ {content}
78
111
  </View>
79
112
  )
80
113
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { View, Text, Image, type ViewStyle, type TextStyle, type ImageStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
2
+ import { View, Text, Image, Pressable, type ViewStyle, type TextStyle, type ImageStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
  import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils'
@@ -28,6 +28,15 @@ export type DebitCardProps = {
28
28
  modes?: Modes;
29
29
  /** Container style overrides */
30
30
  style?: StyleProp<ViewStyle>;
31
+ /**
32
+ * Press handler for the whole card. When set, the card becomes pressable
33
+ * (rendered through a `Pressable` with `accessibilityRole="button"`).
34
+ */
35
+ onPress?: () => void;
36
+ /** Disable interaction when `onPress` is set. */
37
+ disabled?: boolean;
38
+ /** Accessibility label forwarded to the pressable wrapper. */
39
+ accessibilityLabel?: string;
31
40
  };
32
41
 
33
42
  function DebitCard({
@@ -41,6 +50,9 @@ function DebitCard({
41
50
  providerLogoSlot,
42
51
  modes: propModes = EMPTY_MODES,
43
52
  style,
53
+ onPress,
54
+ disabled,
55
+ accessibilityLabel,
44
56
  }: DebitCardProps) {
45
57
  const { modes: globalModes } = useTokens()
46
58
  const modes = { ...globalModes, ...propModes }
@@ -149,8 +161,8 @@ function DebitCard({
149
161
  return cardArtSource
150
162
  }, [cardArtSource])
151
163
 
152
- return (
153
- <View style={[containerStyle, style]}>
164
+ const content = (
165
+ <>
154
166
  <View style={headerStyle}>
155
167
  <View style={headerLeftStyle}>
156
168
  {bankLogoSlot ? cloneChildrenWithModes(bankLogoSlot, modes) : null}
@@ -179,6 +191,27 @@ function DebitCard({
179
191
  <Text style={textStyle}>{expireDate}</Text>
180
192
  </View>
181
193
  </View>
194
+ </>
195
+ )
196
+
197
+ if (onPress) {
198
+ return (
199
+ <Pressable
200
+ style={[containerStyle, style]}
201
+ onPress={onPress}
202
+ disabled={disabled}
203
+ accessibilityRole="button"
204
+ accessibilityLabel={accessibilityLabel ?? `${bankName} ${cardType} ${cardNumber}`}
205
+ accessibilityState={{ disabled: !!disabled }}
206
+ >
207
+ {content}
208
+ </Pressable>
209
+ )
210
+ }
211
+
212
+ return (
213
+ <View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
214
+ {content}
182
215
  </View>
183
216
  )
184
217
  }
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext } from 'react'
2
- import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
2
+ import { View, Text, Pressable, StyleSheet, type ViewStyle, type TextStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import Image from '../Image/Image'
5
5
  import GlassFill, { type GlassTint } from '../../utils/GlassFill/GlassFill'
@@ -40,6 +40,15 @@ export interface MediaCardProps {
40
40
  * Style overrides for the card container.
41
41
  */
42
42
  style?: StyleProp<ViewStyle>
43
+ /**
44
+ * Press handler for the whole card. When set, the card becomes pressable
45
+ * (rendered through a `Pressable` with `accessibilityRole="button"`).
46
+ */
47
+ onPress?: () => void
48
+ /** Disable interaction when `onPress` is set. */
49
+ disabled?: boolean
50
+ /** Accessibility label forwarded to the pressable wrapper. */
51
+ accessibilityLabel?: string
43
52
  }
44
53
 
45
54
  /**
@@ -67,6 +76,9 @@ export function MediaCard({
67
76
  children,
68
77
  modes = EMPTY_MODES,
69
78
  style,
79
+ onPress,
80
+ disabled,
81
+ accessibilityLabel,
70
82
  }: MediaCardProps) {
71
83
  const radius = parseFloat(getVariableByName('cardMedia/radius', modes))
72
84
 
@@ -88,16 +100,35 @@ export function MediaCard({
88
100
  ) : null
89
101
  )
90
102
 
103
+ const content = (
104
+ <>
105
+ {background}
106
+ {children != null ? (
107
+ <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
108
+ {children}
109
+ </View>
110
+ ) : null}
111
+ </>
112
+ )
113
+
91
114
  return (
92
115
  <MediaCardContext.Provider value={{ modes }}>
93
- <View style={[containerStyle, style]}>
94
- {background}
95
- {children != null ? (
96
- <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
97
- {children}
98
- </View>
99
- ) : null}
100
- </View>
116
+ {onPress ? (
117
+ <Pressable
118
+ style={[containerStyle, style]}
119
+ onPress={onPress}
120
+ disabled={disabled}
121
+ accessibilityRole="button"
122
+ accessibilityLabel={accessibilityLabel}
123
+ accessibilityState={{ disabled: !!disabled }}
124
+ >
125
+ {content}
126
+ </Pressable>
127
+ ) : (
128
+ <View style={[containerStyle, style]} accessibilityLabel={accessibilityLabel}>
129
+ {content}
130
+ </View>
131
+ )}
101
132
  </MediaCardContext.Provider>
102
133
  )
103
134
  }