jfs-components 0.0.73 → 0.0.74

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 (63) hide show
  1. package/CHANGELOG.md +23 -6
  2. package/lib/commonjs/components/AccountCard/AccountCard.js +247 -0
  3. package/lib/commonjs/components/AppBar/AppBar.js +17 -11
  4. package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +18 -2
  5. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +40 -25
  6. package/lib/commonjs/components/Dropdown/Dropdown.js +214 -0
  7. package/lib/commonjs/components/DropdownInput/DropdownInput.js +542 -0
  8. package/lib/commonjs/components/FormField/FormField.js +328 -178
  9. package/lib/commonjs/components/LottieIntroBlock/LottieIntroBlock.js +150 -0
  10. package/lib/commonjs/components/PageHero/PageHero.js +153 -0
  11. package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +135 -0
  12. package/lib/commonjs/components/PoweredByLabel/finvu.png +0 -0
  13. package/lib/commonjs/components/Text/Text.js +9 -2
  14. package/lib/commonjs/components/Tooltip/Tooltip.js +34 -27
  15. package/lib/commonjs/components/index.js +60 -0
  16. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  17. package/lib/commonjs/icons/registry.js +1 -1
  18. package/lib/module/components/AccountCard/AccountCard.js +241 -0
  19. package/lib/module/components/AppBar/AppBar.js +17 -11
  20. package/lib/module/components/CardBankAccount/CardBankAccount.js +17 -2
  21. package/lib/module/components/CheckboxItem/CheckboxItem.js +41 -26
  22. package/lib/module/components/Dropdown/Dropdown.js +206 -0
  23. package/lib/module/components/DropdownInput/DropdownInput.js +536 -0
  24. package/lib/module/components/FormField/FormField.js +330 -180
  25. package/lib/module/components/LottieIntroBlock/LottieIntroBlock.js +144 -0
  26. package/lib/module/components/PageHero/PageHero.js +147 -0
  27. package/lib/module/components/PoweredByLabel/PoweredByLabel.js +130 -0
  28. package/lib/module/components/PoweredByLabel/finvu.png +0 -0
  29. package/lib/module/components/Text/Text.js +9 -2
  30. package/lib/module/components/Tooltip/Tooltip.js +34 -27
  31. package/lib/module/components/index.js +7 -1
  32. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  33. package/lib/module/icons/registry.js +1 -1
  34. package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +81 -0
  35. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +9 -2
  36. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +18 -2
  37. package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +62 -0
  38. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +107 -0
  39. package/lib/typescript/src/components/FormField/FormField.d.ts +76 -19
  40. package/lib/typescript/src/components/LottieIntroBlock/LottieIntroBlock.d.ts +58 -0
  41. package/lib/typescript/src/components/PageHero/PageHero.d.ts +53 -0
  42. package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +70 -0
  43. package/lib/typescript/src/components/Text/Text.d.ts +12 -2
  44. package/lib/typescript/src/components/Tooltip/Tooltip.d.ts +13 -2
  45. package/lib/typescript/src/components/index.d.ts +7 -1
  46. package/lib/typescript/src/icons/registry.d.ts +1 -1
  47. package/package.json +1 -3
  48. package/src/components/AccountCard/AccountCard.tsx +376 -0
  49. package/src/components/AppBar/AppBar.tsx +25 -14
  50. package/src/components/CardBankAccount/CardBankAccount.tsx +29 -3
  51. package/src/components/CheckboxItem/CheckboxItem.tsx +65 -30
  52. package/src/components/Dropdown/Dropdown.tsx +331 -0
  53. package/src/components/DropdownInput/DropdownInput.tsx +819 -0
  54. package/src/components/FormField/FormField.tsx +542 -215
  55. package/src/components/LottieIntroBlock/LottieIntroBlock.tsx +202 -0
  56. package/src/components/PageHero/PageHero.tsx +200 -0
  57. package/src/components/PoweredByLabel/PoweredByLabel.tsx +221 -0
  58. package/src/components/PoweredByLabel/finvu.png +0 -0
  59. package/src/components/Text/Text.tsx +24 -3
  60. package/src/components/Tooltip/Tooltip.tsx +50 -25
  61. package/src/components/index.ts +15 -1
  62. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  63. package/src/icons/registry.ts +1 -1
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { View, Text } from 'react-native';
5
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
+ import Button from '../Button/Button';
8
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ const DEFAULT_MEDIA_SIZE = 117;
11
+ /**
12
+ * LottieIntroBlock displays a centered onboarding/intro block composed of a
13
+ * media slot (typically a Lottie animation or illustration) above a title,
14
+ * an optional supportive paragraph, and an optional action button.
15
+ *
16
+ * All visual values are resolved from Figma design tokens via
17
+ * `getVariableByName`. Slots cascade the active `modes` to their children
18
+ * through `cloneChildrenWithModes`.
19
+ *
20
+ * @component
21
+ * @example
22
+ * ```tsx
23
+ * <LottieIntroBlock
24
+ * title="Let's get to know how your financial health is doing"
25
+ * supportText="From assets to taxes, stay on top of everything in one simple view."
26
+ * buttonLabel="Get started"
27
+ * onButtonPress={() => navigate('NextScreen')}
28
+ * media={<MyLottiePlayer source={animationSource} />}
29
+ * />
30
+ * ```
31
+ */
32
+ function LottieIntroBlock({
33
+ title = "Let's get to know how your financial health is doing",
34
+ showSupportText = true,
35
+ supportText = 'From assets to taxes, stay on top of everything in one simple view.',
36
+ showButton = true,
37
+ buttonLabel = 'Button',
38
+ onButtonPress,
39
+ media,
40
+ buttonSlot,
41
+ modes: propModes = EMPTY_MODES,
42
+ style,
43
+ testID
44
+ }) {
45
+ const {
46
+ modes: globalModes
47
+ } = useTokens();
48
+ const modes = useMemo(() => ({
49
+ ...globalModes,
50
+ ...propModes
51
+ }), [globalModes, propModes]);
52
+
53
+ // Container
54
+ const gap = Number(getVariableByName('lottieIntroBlock/gap', modes)) || 36;
55
+ const paddingHorizontal = Number(getVariableByName('lottieIntroBlock/padding/horizontal', modes)) || 0;
56
+ const paddingVertical = Number(getVariableByName('lottieIntroBlock/padding/vertical', modes)) || 16;
57
+
58
+ // Text wrap
59
+ const textWrapGap = Number(getVariableByName('lottieIntroBlock/textWrap/gap', modes)) || 16;
60
+
61
+ // Title
62
+ const titleColor = getVariableByName('lottieIntroBlock/title/foreground', modes) || '#0d0d0f';
63
+ const titleFontSize = Number(getVariableByName('lottieIntroBlock/title/fontSize', modes)) || 23;
64
+ const titleFontFamily = getVariableByName('lottieIntroBlock/title/fontFamily', modes) || 'System';
65
+ const titleLineHeight = Number(getVariableByName('lottieIntroBlock/title/lineHeight', modes)) || 23;
66
+ const titleFontWeight = getVariableByName('lottieIntroBlock/title/fontWeight', modes) || 900;
67
+
68
+ // Support text
69
+ const supportColor = getVariableByName('lottieIntroBlock/supportText/foreground', modes) || '#0d0d0f';
70
+ const supportFontSize = Number(getVariableByName('lottieIntroBlock/supportText/fontSize', modes)) || 14;
71
+ const supportFontFamily = getVariableByName('lottieIntroBlock/supportText/fontFamily', modes) || 'System';
72
+ const supportLineHeight = Number(getVariableByName('lottieIntroBlock/supportText/lineHeight', modes)) || 18;
73
+ const supportFontWeight = getVariableByName('lottieIntroBlock/supportText/fontWeight', modes) || 400;
74
+ const containerStyle = {
75
+ flexDirection: 'column',
76
+ alignItems: 'center',
77
+ paddingHorizontal,
78
+ paddingVertical,
79
+ gap
80
+ };
81
+ const textWrapStyle = {
82
+ flexDirection: 'column',
83
+ alignItems: 'center',
84
+ gap: textWrapGap,
85
+ width: '100%'
86
+ };
87
+ const titleStyle = {
88
+ color: titleColor,
89
+ fontSize: titleFontSize,
90
+ fontFamily: titleFontFamily,
91
+ lineHeight: titleLineHeight,
92
+ fontWeight: String(titleFontWeight),
93
+ textAlign: 'center'
94
+ };
95
+ const supportTextStyle = {
96
+ color: supportColor,
97
+ fontSize: supportFontSize,
98
+ fontFamily: supportFontFamily,
99
+ lineHeight: supportLineHeight,
100
+ fontWeight: String(supportFontWeight),
101
+ textAlign: 'center'
102
+ };
103
+ const mediaContent = useMemo(() => {
104
+ if (media === undefined || media === null) {
105
+ return /*#__PURE__*/_jsx(View, {
106
+ style: {
107
+ width: DEFAULT_MEDIA_SIZE,
108
+ height: DEFAULT_MEDIA_SIZE
109
+ },
110
+ accessibilityElementsHidden: true,
111
+ importantForAccessibility: "no-hide-descendants"
112
+ });
113
+ }
114
+ return cloneChildrenWithModes(media, modes);
115
+ }, [media, modes]);
116
+ const buttonContent = useMemo(() => {
117
+ if (buttonSlot !== undefined && buttonSlot !== null) {
118
+ return cloneChildrenWithModes(buttonSlot, modes);
119
+ }
120
+ if (!showButton) {
121
+ return null;
122
+ }
123
+ return /*#__PURE__*/_jsx(Button, {
124
+ label: buttonLabel,
125
+ onPress: onButtonPress,
126
+ modes: modes
127
+ });
128
+ }, [buttonSlot, showButton, buttonLabel, onButtonPress, modes]);
129
+ return /*#__PURE__*/_jsxs(View, {
130
+ style: [containerStyle, style],
131
+ testID: testID,
132
+ children: [mediaContent, /*#__PURE__*/_jsxs(View, {
133
+ style: textWrapStyle,
134
+ children: [/*#__PURE__*/_jsx(Text, {
135
+ style: titleStyle,
136
+ children: title
137
+ }), showSupportText && supportText ? /*#__PURE__*/_jsx(Text, {
138
+ style: supportTextStyle,
139
+ children: supportText
140
+ }) : null, buttonContent]
141
+ })]
142
+ });
143
+ }
144
+ export default LottieIntroBlock;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { View, Text } from 'react-native';
5
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
+ import Button from '../Button/Button';
8
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ /**
11
+ * PageHero displays a centered hero block typically used at the top of a page
12
+ * or feature screen. It contains an eyebrow line, a large headline, an optional
13
+ * supporting line (e.g. price/timeline), and an optional action button.
14
+ *
15
+ * All visual values are resolved from Figma design tokens via
16
+ * `getVariableByName`. The button slot cascades the active `modes` to its
17
+ * children through `cloneChildrenWithModes`.
18
+ *
19
+ * @component
20
+ * @example
21
+ * ```tsx
22
+ * <PageHero
23
+ * eyebrow="Upgrade to JioFinance+"
24
+ * headline="Resume earning cashback, extra points, and 1% gold"
25
+ * supportingText="₹999/year · ₹0 until 2027"
26
+ * buttonLabel="Renew for free"
27
+ * onButtonPress={() => navigate('Upgrade')}
28
+ * />
29
+ * ```
30
+ */
31
+ function PageHero({
32
+ eyebrow = 'Upgrade to JioFinance+',
33
+ headline = 'Resume earning cashback, extra points, and 1% gold',
34
+ supportingText = '₹999/year · ₹0 until 2027',
35
+ showSupportingText = true,
36
+ buttonLabel = 'Renew for free',
37
+ onButtonPress,
38
+ showButton = true,
39
+ buttonSlot,
40
+ modes: propModes = EMPTY_MODES,
41
+ style,
42
+ testID
43
+ }) {
44
+ const {
45
+ modes: globalModes
46
+ } = useTokens();
47
+ const modes = useMemo(() => ({
48
+ ...globalModes,
49
+ ...propModes
50
+ }), [globalModes, propModes]);
51
+ const gap = Number(getVariableByName('PageHero/gap', modes)) || 16;
52
+ const paddingHorizontal = Number(getVariableByName('PageHero/padding/horizontal', modes)) || 0;
53
+ const textWrapGap = Number(getVariableByName('PageHero/textWrap/gap', modes)) || 8;
54
+ const eyebrowColor = getVariableByName('PageHero/eyebrow/color', modes) || '#ffffff';
55
+ const eyebrowFontFamily = getVariableByName('PageHero/eyebrow/fontFamily', modes) || 'System';
56
+ const eyebrowFontSize = Number(getVariableByName('PageHero/eyebrow/fontSize', modes)) || 18;
57
+ const eyebrowFontWeight = getVariableByName('PageHero/eyebrow/fontWeight', modes) || 700;
58
+ const eyebrowLineHeight = Number(getVariableByName('PageHero/eyebrow/lineHeight', modes)) || 20;
59
+ const headlineColor = getVariableByName('PageHero/headline/color', modes) || '#ffffff';
60
+ const headlineFontFamily = getVariableByName('PageHero/headline/fontFamily', modes) || 'System';
61
+ const headlineFontSize = Number(getVariableByName('PageHero/headline/fontSize', modes)) || 29;
62
+ const headlineFontWeight = getVariableByName('PageHero/headline/fontWeight', modes) || 900;
63
+ const headlineLineHeight = Number(getVariableByName('PageHero/headline/lineHeight', modes)) || 29;
64
+
65
+ // Only `lineHeight` is tokenized for the supporting text in the Figma source.
66
+ // Color, font size and weight are inline literals in the design (12px medium
67
+ // white) — we mirror that here so the visual stays faithful when no token
68
+ // exists.
69
+ const supportingTextLineHeight = Number(getVariableByName('PageHero/supportingText/lineHeight', modes)) || 16;
70
+ const containerStyle = {
71
+ flexDirection: 'column',
72
+ alignItems: 'center',
73
+ paddingHorizontal,
74
+ gap,
75
+ width: '100%'
76
+ };
77
+ const textWrapStyle = {
78
+ flexDirection: 'column',
79
+ alignItems: 'center',
80
+ gap: textWrapGap,
81
+ width: '100%'
82
+ };
83
+ const eyebrowStyle = {
84
+ color: eyebrowColor,
85
+ fontFamily: eyebrowFontFamily,
86
+ fontSize: eyebrowFontSize,
87
+ fontWeight: String(eyebrowFontWeight),
88
+ lineHeight: eyebrowLineHeight,
89
+ textAlign: 'center'
90
+ };
91
+ const headlineStyle = {
92
+ color: headlineColor,
93
+ fontFamily: headlineFontFamily,
94
+ fontSize: headlineFontSize,
95
+ fontWeight: String(headlineFontWeight),
96
+ lineHeight: headlineLineHeight,
97
+ textAlign: 'center',
98
+ width: '100%'
99
+ };
100
+ const supportingTextStyle = {
101
+ color: '#ffffff',
102
+ fontFamily: 'System',
103
+ fontSize: 12,
104
+ fontWeight: '500',
105
+ lineHeight: supportingTextLineHeight,
106
+ textAlign: 'center'
107
+ };
108
+ const buttonWrapStyle = {
109
+ width: '100%'
110
+ };
111
+ const buttonContent = useMemo(() => {
112
+ if (buttonSlot !== undefined && buttonSlot !== null) {
113
+ return cloneChildrenWithModes(buttonSlot, modes);
114
+ }
115
+ if (!showButton) {
116
+ return null;
117
+ }
118
+ return /*#__PURE__*/_jsx(Button, {
119
+ label: buttonLabel,
120
+ onPress: onButtonPress,
121
+ modes: modes,
122
+ style: buttonWrapStyle
123
+ });
124
+ // buttonWrapStyle is a literal object created above; it is intentionally
125
+ // omitted from deps because its identity changes on every render but its
126
+ // shape never does.
127
+ // eslint-disable-next-line react-hooks/exhaustive-deps
128
+ }, [buttonSlot, showButton, buttonLabel, onButtonPress, modes]);
129
+ return /*#__PURE__*/_jsxs(View, {
130
+ style: [containerStyle, style],
131
+ testID: testID,
132
+ children: [/*#__PURE__*/_jsxs(View, {
133
+ style: textWrapStyle,
134
+ children: [eyebrow ? /*#__PURE__*/_jsx(Text, {
135
+ style: eyebrowStyle,
136
+ children: eyebrow
137
+ }) : null, headline ? /*#__PURE__*/_jsx(Text, {
138
+ style: headlineStyle,
139
+ children: headline
140
+ }) : null]
141
+ }), showSupportingText && supportingText ? /*#__PURE__*/_jsx(Text, {
142
+ style: supportingTextStyle,
143
+ children: supportingText
144
+ }) : null, buttonContent]
145
+ });
146
+ }
147
+ export default PageHero;
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { Text, View } from 'react-native';
5
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
+ import MediaSource from '../../utils/MediaSource';
9
+
10
+ // Default bundled FINVU brand logo, matching the Figma reference so the
11
+ // component renders correctly out of the box without any image prop.
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ const DEFAULT_LOGO = require('./finvu.png');
14
+ const DEFAULT_LABEL = 'Powered by RBI-regulated account aggregator';
15
+ const DEFAULT_IMAGE_WIDTH = 33;
16
+ const DEFAULT_IMAGE_HEIGHT = 12;
17
+ const toNumber = (value, fallback) => {
18
+ if (typeof value === 'number') return Number.isFinite(value) ? value : fallback;
19
+ if (typeof value === 'string') {
20
+ const parsed = Number(value);
21
+ return Number.isFinite(parsed) ? parsed : fallback;
22
+ }
23
+ return fallback;
24
+ };
25
+ const toFontWeight = (value, fallback) => {
26
+ if (typeof value === 'number') return String(value);
27
+ if (typeof value === 'string') return value;
28
+ return fallback;
29
+ };
30
+
31
+ /**
32
+ * `PoweredByLabel` renders the small "Powered by RBI-regulated account
33
+ * aggregator" badge with a trailing brand logo, used to attribute the
34
+ * underlying account-aggregator partner in flows such as bank-account
35
+ * linking and consent screens.
36
+ *
37
+ * The component is composed of:
38
+ *
39
+ * 1. A token-styled pill container (`poweredByLabel/background`,
40
+ * `poweredByLabel/padding/*`).
41
+ * 2. The disclosure copy rendered through the `poweredByLabel/*` typography
42
+ * tokens.
43
+ * 3. A configurable brand logo slot. Defaults to the bundled FINVU mark, but
44
+ * callers can pass any image via `imageSource` or fully replace the slot
45
+ * via `imageSlot`.
46
+ *
47
+ * @component
48
+ * @param {PoweredByLabelProps} props
49
+ */
50
+ function PoweredByLabel({
51
+ label = DEFAULT_LABEL,
52
+ imageSource,
53
+ imageWidth = DEFAULT_IMAGE_WIDTH,
54
+ imageHeight = DEFAULT_IMAGE_HEIGHT,
55
+ imageSlot,
56
+ modes: propModes = EMPTY_MODES,
57
+ style,
58
+ textStyle,
59
+ imageStyle,
60
+ accessibilityLabel
61
+ }) {
62
+ const {
63
+ modes: globalModes
64
+ } = useTokens();
65
+ const modes = useMemo(() => globalModes === EMPTY_MODES && propModes === EMPTY_MODES ? EMPTY_MODES : {
66
+ ...globalModes,
67
+ ...propModes
68
+ }, [globalModes, propModes]);
69
+ const background = getVariableByName('poweredByLabel/background', modes) ?? '#f5f5f5';
70
+ const foreground = getVariableByName('poweredByLabel/foreground', modes) ?? '#191b1e';
71
+ const fontFamily = getVariableByName('poweredByLabel/fontFamily', modes) ?? 'JioType Var';
72
+ const fontSize = toNumber(getVariableByName('poweredByLabel/fontSize', modes), 10);
73
+ const lineHeight = toNumber(getVariableByName('poweredByLabel/lineHeight', modes), 12);
74
+ const fontWeight = toFontWeight(getVariableByName('poweredByLabel/fontWeight', modes), '400');
75
+ const gap = toNumber(getVariableByName('poweredByLabel/gap', modes), 10);
76
+ const paddingHorizontal = toNumber(getVariableByName('poweredByLabel/padding/horizontal', modes), 16);
77
+ const paddingVertical = toNumber(getVariableByName('poweredByLabel/padding/vertical', modes), 6);
78
+ const containerStyle = {
79
+ flexDirection: 'row',
80
+ alignItems: 'center',
81
+ justifyContent: 'center',
82
+ backgroundColor: background,
83
+ paddingHorizontal,
84
+ paddingVertical,
85
+ gap,
86
+ // Hug content horizontally so the pill does not stretch to fill the
87
+ // parent (matches Badge, BrandChip, etc.). Override via `style` if
88
+ // you want it full-width (e.g. inside a card footer).
89
+ alignSelf: 'flex-start'
90
+ };
91
+ const labelTextStyle = {
92
+ color: foreground,
93
+ fontFamily,
94
+ fontSize,
95
+ lineHeight,
96
+ fontWeight,
97
+ textAlign: 'center',
98
+ flexShrink: 1
99
+ };
100
+ const renderImage = () => {
101
+ if (imageSlot !== undefined && imageSlot !== null) {
102
+ const processed = cloneChildrenWithModes(imageSlot, modes);
103
+ if (processed.length === 0) return null;
104
+ return processed.length === 1 ? processed[0] : processed;
105
+ }
106
+ const resolvedSource = imageSource ?? DEFAULT_LOGO;
107
+ return /*#__PURE__*/_jsx(MediaSource, {
108
+ source: resolvedSource,
109
+ width: imageWidth,
110
+ height: imageHeight,
111
+ resizeMode: "contain",
112
+ style: imageStyle,
113
+ accessibilityElementsHidden: true,
114
+ importantForAccessibility: "no"
115
+ });
116
+ };
117
+ return /*#__PURE__*/_jsxs(View, {
118
+ accessibilityRole: "text",
119
+ accessibilityLabel: accessibilityLabel ?? label,
120
+ style: [containerStyle, style],
121
+ children: [/*#__PURE__*/_jsx(Text, {
122
+ style: [labelTextStyle, textStyle],
123
+ accessibilityElementsHidden: true,
124
+ importantForAccessibility: "no",
125
+ numberOfLines: 1,
126
+ children: label
127
+ }), renderImage()]
128
+ });
129
+ }
130
+ export default PoweredByLabel;
@@ -10,7 +10,8 @@ const TEXT_ALIGN_MAP = {
10
10
  Center: 'center'
11
11
  };
12
12
  function Text({
13
- text = 'Korem ipsum ',
13
+ text,
14
+ children,
14
15
  textAlign = 'Left',
15
16
  modes = EMPTY_MODES,
16
17
  style,
@@ -31,10 +32,16 @@ function Text({
31
32
  letterSpacing: letterSpacing,
32
33
  textAlign: TEXT_ALIGN_MAP[textAlign]
33
34
  };
35
+
36
+ // Prefer JSX children when present, otherwise fall back to the `text` prop.
37
+ // Keep the storybook placeholder as a last resort so the Default story
38
+ // still renders something visible when no content is supplied via either
39
+ // route.
40
+ const content = children !== undefined && children !== null && children !== false ? children : text !== undefined ? text : 'Korem ipsum ';
34
41
  return /*#__PURE__*/_jsx(RNText, {
35
42
  style: [textStyle, style],
36
43
  numberOfLines: numberOfLines,
37
- children: text
44
+ children: content
38
45
  });
39
46
  }
40
47
  export default Text;
@@ -165,7 +165,9 @@ export function TooltipTrigger({
165
165
  }
166
166
  export function TooltipContent({
167
167
  children,
168
- sideOffset = 4
168
+ sideOffset = 4,
169
+ gap = 4,
170
+ alignItems = 'flex-start'
169
171
  }) {
170
172
  const {
171
173
  isVisible,
@@ -390,6 +392,35 @@ export function TooltipContent({
390
392
  paddingHorizontal: paddingH,
391
393
  paddingVertical: paddingV
392
394
  };
395
+
396
+ // Vertical slot wrapper: stack arbitrary children top-to-bottom with a gap.
397
+ // Raw <Text> children still get auto-styled with the tooltip label tokens
398
+ // so the simple <TooltipContent><Text>label</Text></TooltipContent> usage
399
+ // keeps working without any changes.
400
+ const slotStyle = {
401
+ flexDirection: 'column',
402
+ alignItems,
403
+ gap
404
+ };
405
+ const renderSlotChildren = () => {
406
+ if (typeof children === 'string') {
407
+ return /*#__PURE__*/_jsx(Text, {
408
+ style: textStyle,
409
+ children: children
410
+ });
411
+ }
412
+ return /*#__PURE__*/_jsx(View, {
413
+ style: slotStyle,
414
+ children: React.Children.map(children, child => {
415
+ if (/*#__PURE__*/React.isValidElement(child) && (child.type === Text || child.type.displayName === 'Text')) {
416
+ return /*#__PURE__*/React.cloneElement(child, {
417
+ style: [textStyle, child.props.style]
418
+ });
419
+ }
420
+ return child;
421
+ })
422
+ });
423
+ };
393
424
  if (!hasMeasured) {
394
425
  return /*#__PURE__*/_jsx(Modal, {
395
426
  transparent: true,
@@ -401,19 +432,7 @@ export function TooltipContent({
401
432
  children: /*#__PURE__*/_jsx(View, {
402
433
  style: measureStyle,
403
434
  onLayout: e => setContentSize(e.nativeEvent.layout),
404
- children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
405
- style: textStyle,
406
- children: children
407
- }) : /*#__PURE__*/_jsx(View, {
408
- children: React.Children.map(children, child => {
409
- if (/*#__PURE__*/React.isValidElement(child) && (child.type === Text || child.type.displayName === 'Text')) {
410
- return /*#__PURE__*/React.cloneElement(child, {
411
- style: [textStyle, child.props.style]
412
- });
413
- }
414
- return child;
415
- })
416
- })
435
+ children: renderSlotChildren()
417
436
  })
418
437
  })
419
438
  });
@@ -444,19 +463,7 @@ export function TooltipContent({
444
463
  shadowRadius: 3.84,
445
464
  elevation: 5
446
465
  }],
447
- children: [typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
448
- style: textStyle,
449
- children: children
450
- }) : /*#__PURE__*/_jsx(View, {
451
- children: React.Children.map(children, child => {
452
- if (/*#__PURE__*/React.isValidElement(child) && (child.type === Text || child.type.displayName === 'Text')) {
453
- return /*#__PURE__*/React.cloneElement(child, {
454
- style: [textStyle, child.props.style]
455
- });
456
- }
457
- return child;
458
- })
459
- }), /*#__PURE__*/_jsx(View, {
466
+ children: [renderSlotChildren(), /*#__PURE__*/_jsx(View, {
460
467
  style: {
461
468
  position: 'absolute',
462
469
  left: arrowX,
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ export { default as AccountCard } from './AccountCard/AccountCard';
3
4
  export { default as ActionFooter } from './ActionFooter/ActionFooter';
4
5
  export { default as AppBar } from './AppBar/AppBar';
5
6
  export { default as Avatar } from './Avatar/Avatar';
@@ -22,6 +23,8 @@ export { default as CardInsight } from './CardInsight/CardInsight';
22
23
  export { default as Disclaimer } from './Disclaimer/Disclaimer';
23
24
  export { default as Divider } from './Divider/Divider';
24
25
  export { default as Drawer } from './Drawer/Drawer';
26
+ export { default as Dropdown, DropdownItem } from './Dropdown/Dropdown';
27
+ export { default as DropdownInput } from './DropdownInput/DropdownInput';
25
28
  export { default as CardCTA } from './CardCTA/CardCTA';
26
29
  export { default as DebitCard } from './DebitCard/DebitCard';
27
30
  export { default as FilterBar } from './FilterBar/FilterBar';
@@ -44,6 +47,7 @@ export { default as LazyList } from './LazyList/LazyList';
44
47
  export { default as LinearMeter } from './LinearMeter/LinearMeter';
45
48
  export { default as LinearProgress } from './LinearProgress/LinearProgress';
46
49
  export { default as ListGroup } from './ListGroup/ListGroup';
50
+ export { default as LottieIntroBlock } from './LottieIntroBlock/LottieIntroBlock';
47
51
  export { default as ListItem } from './ListItem/ListItem';
48
52
  export { default as MediaCard } from './MediaCard/MediaCard';
49
53
  export { default as MerchantProfile } from './MerchantProfile/MerchantProfile';
@@ -62,7 +66,7 @@ export { StepLabel } from './Stepper/StepLabel';
62
66
  export { default as TextInput } from './TextInput/TextInput';
63
67
  export { default as StatusHero } from './StatusHero/StatusHero';
64
68
  export { default as ThreadHero } from './ThreadHero/ThreadHero';
65
- export { Tooltip } from './Tooltip/Tooltip';
69
+ export { Tooltip, TooltipTrigger, TooltipContent } from './Tooltip/Tooltip';
66
70
  export { default as TransactionDetails } from './TransactionDetails/TransactionDetails';
67
71
  export { default as TransactionStatus } from './TransactionStatus/TransactionStatus';
68
72
  export { default as TransactionBubble } from './TransactionBubble/TransactionBubble';
@@ -99,8 +103,10 @@ export { default as Toast } from './Toast/Toast';
99
103
  export { default as ToastProvider } from './Toast/ToastProvider';
100
104
  export { useToast, addToast, closeToast, closeAll } from './Toast/useToast';
101
105
  export { default as AmountInput } from './AmountInput/AmountInput';
106
+ export { default as PageHero } from './PageHero/PageHero';
102
107
  export { default as Popup } from './Popup/Popup';
103
108
  export { default as PortfolioHero } from './PortfolioHero/PortfolioHero';
109
+ export { default as PoweredByLabel } from './PoweredByLabel/PoweredByLabel';
104
110
  export { default as ProductLabel } from './ProductLabel/ProductLabel';
105
111
  export { default as ProductOverview } from './ProductOverview/ProductOverview';
106
112
  export { default as ProgressBadge } from './ProgressBadge/ProgressBadge';