jfs-components 0.0.71 → 0.0.72

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 (35) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -2
  3. package/lib/commonjs/components/CardFinancialCondition/CardFinancialCondition.js +213 -0
  4. package/lib/commonjs/components/Carousel/Carousel.js +9 -7
  5. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -2
  6. package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +132 -0
  7. package/lib/commonjs/components/Radio/Radio.js +194 -0
  8. package/lib/commonjs/components/RadioButton/RadioButton.js +21 -188
  9. package/lib/commonjs/components/index.js +21 -0
  10. package/lib/commonjs/icons/registry.js +1 -1
  11. package/lib/module/components/CardAdvisory/CardAdvisory.js +2 -2
  12. package/lib/module/components/CardFinancialCondition/CardFinancialCondition.js +207 -0
  13. package/lib/module/components/Carousel/Carousel.js +9 -7
  14. package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -2
  15. package/lib/module/components/InstitutionBadge/InstitutionBadge.js +127 -0
  16. package/lib/module/components/Radio/Radio.js +188 -0
  17. package/lib/module/components/RadioButton/RadioButton.js +20 -185
  18. package/lib/module/components/index.js +7 -0
  19. package/lib/module/icons/registry.js +1 -1
  20. package/lib/typescript/src/components/CardFinancialCondition/CardFinancialCondition.d.ts +50 -0
  21. package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +30 -0
  22. package/lib/typescript/src/components/Radio/Radio.d.ts +30 -0
  23. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +20 -28
  24. package/lib/typescript/src/components/index.d.ts +7 -0
  25. package/lib/typescript/src/icons/registry.d.ts +1 -1
  26. package/package.json +1 -1
  27. package/src/components/CardAdvisory/CardAdvisory.tsx +2 -2
  28. package/src/components/CardFinancialCondition/CardFinancialCondition.tsx +366 -0
  29. package/src/components/Carousel/Carousel.tsx +14 -6
  30. package/src/components/HoldingsCard/HoldingsCard.tsx +2 -2
  31. package/src/components/InstitutionBadge/InstitutionBadge.tsx +216 -0
  32. package/src/components/Radio/Radio.tsx +227 -0
  33. package/src/components/RadioButton/RadioButton.tsx +23 -225
  34. package/src/components/index.ts +7 -0
  35. package/src/icons/registry.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,55 @@ 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.0.72] - 2026-05-04
8
+
9
+ High-level summary (one line per point):
10
+
11
+ - **`RadioButton` renamed to `Radio`** — naming aligned with the rest of the library; the old `RadioButton` import is preserved as a deprecated alias so consumer code keeps working without changes.
12
+ - **`Carousel` pagination is now fully token-driven** — dot size, active width, and active/inactive colors come from design tokens (`carousel/pagination/indicator/{size,activeWidth,activeColor,inactiveColor}`) instead of hardcoded values, with token names normalized to camelCase.
13
+ - **`Carousel` outer container height is now controlled by a token** — new `carousel/maxHeight` token enforces the Figma-aligned max height of the carousel viewport.
14
+ - **`HoldingsCard` migrated to `Radio`** — internal-only swap, no API change for consumers.
15
+
16
+ ### Changed
17
+
18
+ - `Carousel.Pagination` now reads `carousel/pagination/indicator/size`, `carousel/pagination/indicator/activeWidth`, `carousel/pagination/indicator/activeColor`, and `carousel/pagination/indicator/inactiveColor` from design tokens. Previous lowercase names (`activecolor`, `inactivecolor`) and hardcoded dot dimensions (6×6 / 16×6) are replaced.
19
+ - `Carousel` outer container respects a new `carousel/maxHeight` token (defaults to `280`) applied as `maxHeight` on the outer view.
20
+ - `HoldingsCard` now imports the new `Radio` component instead of `RadioButton` (no behavioral change).
21
+
22
+ ### Added
23
+
24
+ - New `Radio` component (`src/components/Radio/Radio.tsx`) with its own stories and MDX docs. Exported from the package barrel as `Radio` / `RadioProps`.
25
+
26
+ ### Deprecated
27
+
28
+ - `RadioButton` is deprecated. It is kept as a thin re-export of `Radio` for backward compatibility and will be removed in a future major release. Migrate to `import { Radio } from 'jfs-components'`.
29
+
30
+ ---
31
+
32
+ ## [0.0.71] - 2026-05-04
33
+
34
+ ### Added
35
+
36
+ - **`CardAdvisory`** — new card component with stories and MDX docs.
37
+ - **`CardFinancialCondition`** — new card component with stories and MDX docs.
38
+ - **`CircularProgressBar`** — new circular progress component with stories and MDX docs.
39
+ - **`CircularProgressBarDoted`** — new dotted variant of the circular progress component with stories and MDX docs.
40
+ - **`CircularRating`** — new circular rating display component with stories and MDX docs.
41
+ - **`Gauge`** — new gauge component with stories and MDX docs.
42
+ - **`InstitutionBadge`** — new institution badge component with stories and MDX docs.
43
+ - All new components are exported from the package barrel with their public types.
44
+
45
+ ### Changed
46
+
47
+ - **`Nudge`** — significant rewrite (props, layout, and token usage refreshed); story file simplified.
48
+ - **`CardCTA`** — expanded API and visual variants; story coverage extended.
49
+ - **`MediaCard`** — minor doc/story refresh; no breaking changes.
50
+ - **`ListGroup`** — small adjustments to internal layout; no API change.
51
+ - Refreshed component token metadata and the icon registry; updated `Coin Variables` design-token JSON.
52
+ - Storybook plumbing: added `.storybook/storybook-test-mock.js` and registered it in `.storybook/main.js` to stabilize Storybook test runs.
53
+
54
+ ---
55
+
7
56
  ## [0.0.70] - 2026-04-23
8
57
 
9
58
  ### Fixed
@@ -37,8 +37,8 @@ const toFontWeight = (value, fallback) => {
37
37
  function resolveCardAdvisoryTokens(modes) {
38
38
  const width = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/width', modes), 360);
39
39
  const gap = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/gap', modes), 16);
40
- const paddingHorizontal = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/padding/horizontal', modes), 16);
41
- const paddingVertical = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/padding/vertical', modes), 12);
40
+ const paddingHorizontal = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/padding/horizontal', modes), 0);
41
+ const paddingVertical = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/padding/vertical', modes), 0);
42
42
  const radius = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/radius', modes), 0);
43
43
  const background = (0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/background', modes) || '#ffffff';
44
44
  const mainContentGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('cardAdvisory/mainContent/gap', modes), 16);
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _reactUtils = require("../../utils/react-utils");
12
+ var _Button = _interopRequireDefault(require("../Button/Button"));
13
+ var _CircularProgressBar = _interopRequireDefault(require("../CircularProgressBar/CircularProgressBar"));
14
+ var _Divider = _interopRequireDefault(require("../Divider/Divider"));
15
+ var _Nudge = _interopRequireDefault(require("../Nudge/Nudge"));
16
+ var _jsxRuntime = require("react/jsx-runtime");
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ 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); }
19
+ const toNumber = (value, fallback) => {
20
+ if (typeof value === 'number') {
21
+ return Number.isFinite(value) ? value : fallback;
22
+ }
23
+ if (typeof value === 'string') {
24
+ const parsed = Number(value);
25
+ return Number.isFinite(parsed) ? parsed : fallback;
26
+ }
27
+ return fallback;
28
+ };
29
+ const toFontWeight = (value, fallback) => {
30
+ if (typeof value === 'number') {
31
+ return String(value);
32
+ }
33
+ if (typeof value === 'string') {
34
+ return value;
35
+ }
36
+ return fallback;
37
+ };
38
+ function resolveCardFinancialConditionTokens(modes) {
39
+ const background = (0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/background', modes) || '#ffffff';
40
+ const radius = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/radius', modes), 16);
41
+ const paddingH = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/padding/horizontal', modes), 16);
42
+ const paddingV = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/padding/vertical', modes), 16);
43
+ const gap = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/gap', modes), 8);
44
+ const headerGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/header/gap', modes), 16);
45
+ const textContentGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/textContent/gap', modes), 8);
46
+ const titleColor = (0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/title/color', modes) || '#0c0d10';
47
+ const titleFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/title/fontSize', modes), 16);
48
+ const titleFontFamily = (0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/title/fontFamily', modes) || 'JioType Var';
49
+ const titleLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/title/lineHeight', modes), 18);
50
+ const titleFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/title/fontWeight', modes), '700');
51
+ const bodyColor = (0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/body/color', modes) || '#0c0d10';
52
+ const bodyFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/body/fontSize', modes), 14);
53
+ const bodyFontFamily = (0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/body/fontFamily', modes) || 'JioType Var';
54
+ const bodyLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/body/lineHeight', modes), 17);
55
+ const bodyFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('financialConditionCard/body/fontWeight', modes), '400');
56
+ const nudgeBodyColor = (0, _figmaVariablesResolver.getVariableByName)('nudge/body/color', modes) || '#1a1c1f';
57
+ const nudgeBodyFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('nudge/body/fontSize', modes), 12);
58
+ const nudgeBodyFontFamily = (0, _figmaVariablesResolver.getVariableByName)('nudge/body/fontFamily', modes) || 'JioType Var';
59
+ const nudgeBodyLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('nudge/body/lineHeight', modes), 16);
60
+ const nudgeBodyFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('nudge/body/fontWeight', modes), '500');
61
+ return {
62
+ containerStyle: {
63
+ alignItems: 'flex-start',
64
+ backgroundColor: background,
65
+ borderRadius: radius,
66
+ gap,
67
+ justifyContent: 'center',
68
+ overflow: 'hidden',
69
+ paddingHorizontal: paddingH,
70
+ paddingVertical: paddingV
71
+ },
72
+ headerStyle: {
73
+ alignItems: 'center',
74
+ flexDirection: 'row',
75
+ gap: headerGap,
76
+ width: '100%'
77
+ },
78
+ textContentStyle: {
79
+ alignItems: 'flex-start',
80
+ flex: 1,
81
+ gap: textContentGap,
82
+ minWidth: 1
83
+ },
84
+ titleStyle: {
85
+ color: titleColor,
86
+ fontFamily: titleFontFamily,
87
+ fontSize: titleFontSize,
88
+ fontWeight: titleFontWeight,
89
+ lineHeight: titleLineHeight
90
+ },
91
+ bodyStyle: {
92
+ color: bodyColor,
93
+ fontFamily: bodyFontFamily,
94
+ fontSize: bodyFontSize,
95
+ fontWeight: bodyFontWeight,
96
+ lineHeight: bodyLineHeight
97
+ },
98
+ nudgeBodyStyle: {
99
+ color: nudgeBodyColor,
100
+ fontFamily: nudgeBodyFontFamily,
101
+ fontSize: nudgeBodyFontSize,
102
+ fontWeight: nudgeBodyFontWeight,
103
+ lineHeight: nudgeBodyLineHeight
104
+ },
105
+ buttonWrapStyle: {
106
+ alignSelf: 'stretch',
107
+ alignItems: 'flex-start'
108
+ }
109
+ };
110
+ }
111
+ function CardFinancialCondition({
112
+ title = 'Protection',
113
+ body = 'Check your coverage and gaps',
114
+ value = 0,
115
+ progressState = 'Inactive',
116
+ valueLabel,
117
+ showNudge = true,
118
+ nudgeBody = 'There may be gaps in your health or life cover\nAdd coverage to stay financially secure',
119
+ showDivider = true,
120
+ showButton = true,
121
+ buttonLabel = 'View Details',
122
+ onPressButton,
123
+ progressSlot,
124
+ nudgeSlot,
125
+ buttonSlot,
126
+ modes: propModes = _reactUtils.EMPTY_MODES,
127
+ style,
128
+ headerStyle,
129
+ titleStyle,
130
+ bodyStyle,
131
+ accessibilityLabel,
132
+ ...rest
133
+ }) {
134
+ const {
135
+ modes: globalModes
136
+ } = (0, _JFSThemeProvider.useTokens)();
137
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
138
+ ...globalModes,
139
+ ...propModes
140
+ }, [globalModes, propModes]);
141
+ const tokens = (0, _react.useMemo)(() => resolveCardFinancialConditionTokens(modes), [modes]);
142
+
143
+ // Match Figma: the action button is the primary call-to-action and uses the
144
+ // Secondary brand (purple) regardless of the card's overall AppearanceBrand,
145
+ // while Nudge / CircularProgressBar still follow the user-supplied modes.
146
+ const buttonModes = (0, _react.useMemo)(() => ({
147
+ ...modes,
148
+ AppearanceBrand: 'Secondary'
149
+ }), [modes]);
150
+ const processedProgressSlot = (0, _react.useMemo)(() => {
151
+ if (!progressSlot) return null;
152
+ const processed = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(progressSlot), modes);
153
+ return processed.length === 1 ? processed[0] : processed;
154
+ }, [progressSlot, modes]);
155
+ const processedNudgeSlot = (0, _react.useMemo)(() => {
156
+ if (!nudgeSlot) return null;
157
+ const processed = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(nudgeSlot), modes);
158
+ return processed.length === 1 ? processed[0] : processed;
159
+ }, [nudgeSlot, modes]);
160
+ const processedButtonSlot = (0, _react.useMemo)(() => {
161
+ if (!buttonSlot) return null;
162
+ const processed = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(buttonSlot), buttonModes);
163
+ return processed.length === 1 ? processed[0] : processed;
164
+ }, [buttonSlot, buttonModes]);
165
+ const defaultAccessibilityLabel = accessibilityLabel ?? `${title}. ${body}.`;
166
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
167
+ accessibilityLabel: defaultAccessibilityLabel,
168
+ style: [tokens.containerStyle, style],
169
+ ...rest,
170
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
171
+ style: [tokens.headerStyle, headerStyle],
172
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
173
+ style: tokens.textContentStyle,
174
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
175
+ style: [tokens.titleStyle, titleStyle],
176
+ children: title
177
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
178
+ style: [tokens.bodyStyle, bodyStyle],
179
+ children: body
180
+ })]
181
+ }), processedProgressSlot || /*#__PURE__*/(0, _jsxRuntime.jsx)(_CircularProgressBar.default, {
182
+ state: progressState,
183
+ value: value,
184
+ modes: modes,
185
+ ...(valueLabel ? {
186
+ valueLabel
187
+ } : {})
188
+ })]
189
+ }), showNudge ? processedNudgeSlot || /*#__PURE__*/(0, _jsxRuntime.jsx)(_Nudge.default, {
190
+ type: "inline-compact",
191
+ modes: modes,
192
+ style: {
193
+ width: '100%'
194
+ },
195
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
196
+ style: tokens.nudgeBodyStyle,
197
+ children: nudgeBody
198
+ })
199
+ }) : null, showDivider ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Divider.default, {
200
+ modes: modes
201
+ }) : null, showButton ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
202
+ style: tokens.buttonWrapStyle,
203
+ children: processedButtonSlot || /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
204
+ label: buttonLabel,
205
+ modes: buttonModes,
206
+ ...(onPressButton ? {
207
+ onPress: onPressButton
208
+ } : {})
209
+ })
210
+ }) : null]
211
+ });
212
+ }
213
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(CardFinancialCondition);
@@ -51,6 +51,8 @@ function Carousel({
51
51
  const gap = gapProp ?? tokenGap;
52
52
  const containerPaddingH = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/padding/horizontal', modes) || '0');
53
53
  const containerPaddingV = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/padding/vertical', modes) || '0');
54
+ // Outer container max height per Figma (`carousel/maxHeight`).
55
+ const maxHeight = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/maxHeight', modes) || '280');
54
56
  // Spacing between the cards row and the pagination dots uses `carousel/gap`.
55
57
  const paginationOffset = gap;
56
58
 
@@ -162,7 +164,8 @@ function Carousel({
162
164
 
163
165
  // ---- Render ----
164
166
  const outerStyle = {
165
- paddingVertical: containerPaddingV
167
+ paddingVertical: containerPaddingV,
168
+ maxHeight
166
169
  };
167
170
  const contentContainerStyle = {
168
171
  paddingHorizontal: containerPaddingH * 2,
@@ -270,13 +273,12 @@ function Pagination({
270
273
  const modes = propModes || ctxModes || {};
271
274
 
272
275
  // Token resolution for dots — matches Figma tokens
273
- // (carousel/pagination/gap, carousel/pagination/indicator/{activecolor,inactivecolor,radius}).
274
- // Dot dimensions are fixed per Figma spec: inactive 6x6, active 16x6.
275
- const dotSize = 6;
276
- const dotActiveWidth = 16;
276
+ // (carousel/pagination/gap, carousel/pagination/indicator/{activeColor,inactiveColor,radius,size,activeWidth}).
277
+ const dotSize = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/size', modes) || '6');
278
+ const dotActiveWidth = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/activeWidth', modes) || '16');
277
279
  const dotGap = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/gap', modes) || '4');
278
- const dotColor = (0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/inactivecolor', modes) || 'rgba(0,0,0,0.3)';
279
- const dotActiveColor = (0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/activecolor', modes) || '#170d0a';
280
+ const dotColor = (0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/inactiveColor', modes) || 'rgba(0,0,0,0.3)';
281
+ const dotActiveColor = (0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/activeColor', modes) || '#170d0a';
280
282
  const dotRadius = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/pagination/indicator/radius', modes) || '9999');
281
283
  const containerStyle = {
282
284
  flexDirection: 'row',
@@ -7,7 +7,7 @@ exports.default = HoldingsCard;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
- var _RadioButton = _interopRequireDefault(require("../RadioButton/RadioButton"));
10
+ var _Radio = _interopRequireDefault(require("../Radio/Radio"));
11
11
  var _reactUtils = require("../../utils/react-utils");
12
12
  var _jsxRuntime = require("react/jsx-runtime");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -128,7 +128,7 @@ function HoldingsCard({
128
128
  }
129
129
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
130
130
  pointerEvents: "none",
131
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RadioButton.default, {
131
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Radio.default, {
132
132
  selected: selected,
133
133
  disabled: disabled,
134
134
  modes: modes
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _reactUtils = require("../../utils/react-utils");
12
+ var _MediaSource = _interopRequireDefault(require("../../utils/MediaSource"));
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ 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); }
16
+ // Default avatar asset (shared with the Avatar component) so that
17
+ // InstitutionBadge has a sensible visual fallback when no `source` is
18
+ // provided in stories or playgrounds.
19
+ const DEFAULT_AVATAR_IMAGE = require('../Avatar/31595e70c4181263f9971590224b12934b280c9b.png');
20
+ const toNumber = (value, fallback) => {
21
+ if (typeof value === 'number') {
22
+ return Number.isFinite(value) ? value : fallback;
23
+ }
24
+ if (typeof value === 'string') {
25
+ const parsed = Number(value);
26
+ return Number.isFinite(parsed) ? parsed : fallback;
27
+ }
28
+ return fallback;
29
+ };
30
+ const toFontWeight = (value, fallback) => {
31
+ if (typeof value === 'number') {
32
+ return String(value);
33
+ }
34
+ if (typeof value === 'string') {
35
+ return value;
36
+ }
37
+ return fallback;
38
+ };
39
+ function resolveInstitutionBadgeTokens(modes) {
40
+ const gap = toNumber((0, _figmaVariablesResolver.getVariableByName)('institutionBadge/gap', modes), 8);
41
+ const foreground = (0, _figmaVariablesResolver.getVariableByName)('institutionBadge/foreground', modes) || '#080d1a';
42
+ const fontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('institutionBadge/fontSize', modes), 14);
43
+ const fontFamily = (0, _figmaVariablesResolver.getVariableByName)('institutionBadge/fontFamily', modes) || 'JioType Var';
44
+ const lineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('institutionBadge/lineHeight', modes), 18);
45
+ const fontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('institutionBadge/fontWeight', modes), '500');
46
+
47
+ // Avatar wrapper styled from shared `avatar/*` tokens so the badge stays
48
+ // visually consistent with other Avatar-bearing components.
49
+ const avatarSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('avatar/size', modes), 36);
50
+ const avatarRadiusRaw = toNumber((0, _figmaVariablesResolver.getVariableByName)('avatar/radius', modes), 9999);
51
+ // 9999 is the design-token sentinel for "perfect circle".
52
+ const avatarRadius = avatarRadiusRaw === 9999 ? avatarSize / 2 : avatarRadiusRaw;
53
+ const avatarBorderColor = (0, _figmaVariablesResolver.getVariableByName)('avatar/border/color', modes) || 'rgba(255,255,255,0)';
54
+ const avatarBorderSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('avatar/border/size', modes), 1);
55
+ return {
56
+ containerStyle: {
57
+ alignItems: 'center',
58
+ flexDirection: 'row',
59
+ gap
60
+ },
61
+ avatarStyle: {
62
+ width: avatarSize,
63
+ height: avatarSize,
64
+ borderRadius: avatarRadius,
65
+ borderWidth: avatarBorderSize,
66
+ borderColor: avatarBorderColor,
67
+ overflow: 'hidden'
68
+ },
69
+ avatarSize,
70
+ labelStyle: {
71
+ color: foreground,
72
+ fontFamily,
73
+ fontSize,
74
+ fontWeight,
75
+ lineHeight
76
+ }
77
+ };
78
+ }
79
+
80
+ // Default Avatar Size = M (36px in tokens) — matches the Figma badge. Callers
81
+ // can override via `modes` if needed.
82
+ const DEFAULT_AVATAR_MODE = 'M';
83
+ function InstitutionBadge({
84
+ label = 'State Bank of India',
85
+ source,
86
+ avatarSlot,
87
+ modes: propModes = _reactUtils.EMPTY_MODES,
88
+ style,
89
+ labelStyle,
90
+ accessibilityLabel,
91
+ ...rest
92
+ }) {
93
+ const {
94
+ modes: globalModes
95
+ } = (0, _JFSThemeProvider.useTokens)();
96
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
97
+ ...globalModes,
98
+ ...propModes
99
+ }, [globalModes, propModes]);
100
+ const avatarModes = (0, _react.useMemo)(() => ({
101
+ 'Avatar Size': DEFAULT_AVATAR_MODE,
102
+ ...modes
103
+ }), [modes]);
104
+ const tokens = (0, _react.useMemo)(() => resolveInstitutionBadgeTokens(avatarModes), [avatarModes]);
105
+ const processedAvatarSlot = (0, _react.useMemo)(() => {
106
+ if (!avatarSlot) return null;
107
+ const processed = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(avatarSlot), avatarModes);
108
+ return processed.length === 1 ? processed[0] : processed;
109
+ }, [avatarSlot, avatarModes]);
110
+ const resolvedSource = source ?? DEFAULT_AVATAR_IMAGE;
111
+ const defaultAccessibilityLabel = accessibilityLabel ?? label;
112
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
113
+ accessibilityLabel: defaultAccessibilityLabel,
114
+ style: [tokens.containerStyle, style],
115
+ ...rest,
116
+ children: [processedAvatarSlot || /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
117
+ style: tokens.avatarStyle,
118
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaSource.default, {
119
+ source: resolvedSource,
120
+ size: tokens.avatarSize,
121
+ resizeMode: "cover",
122
+ accessibilityElementsHidden: true,
123
+ importantForAccessibility: "no"
124
+ })
125
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
126
+ style: [tokens.labelStyle, labelStyle],
127
+ numberOfLines: 1,
128
+ children: label
129
+ })]
130
+ });
131
+ }
132
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(InstitutionBadge);
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Radio = Radio;
7
+ exports.default = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactNative = require("react-native");
10
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
11
+ var _reactUtils = require("../../utils/react-utils");
12
+ var _jsxRuntime = require("react/jsx-runtime");
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); }
14
+ // ---------------------------------------------------------------------------
15
+ // Props
16
+ // ---------------------------------------------------------------------------
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Radio
20
+ // ---------------------------------------------------------------------------
21
+
22
+ function Radio({
23
+ selected = false,
24
+ disabled = false,
25
+ onPress,
26
+ modes = _reactUtils.EMPTY_MODES,
27
+ style,
28
+ testID
29
+ }) {
30
+ // ---- Refs & State ----
31
+ const [hovered, setHovered] = (0, _react.useState)(false);
32
+ const [focused, setFocused] = (0, _react.useState)(false);
33
+ const [pressed, setPressed] = (0, _react.useState)(false);
34
+
35
+ // ---- Dimensions ----
36
+ const widthStr = (0, _figmaVariablesResolver.getVariableByName)('radio/width', modes) || '18';
37
+ const heightStr = (0, _figmaVariablesResolver.getVariableByName)('radio/height', modes) || '18';
38
+ const selectorSizeStr = (0, _figmaVariablesResolver.getVariableByName)('radio/selector/size', modes) || '10';
39
+ const width = parseFloat(widthStr?.toString() || '18');
40
+ const height = parseFloat(heightStr?.toString() || '18');
41
+ const selectorSize = parseFloat(selectorSizeStr?.toString() || '10');
42
+
43
+ // ---- State Logic ----
44
+ // Priority: Disabled -> Focused -> Hover/Pressed -> Idle
45
+ // Note: Design treats Active (Pressed) similar to Selected for some styles,
46
+ // but usually in Radios, Pressed is a transient state.
47
+ // We will map:
48
+ // - Disabled -> 'disabled'
49
+ // - Focused -> 'focus'
50
+ // - Hovered -> 'hover'
51
+ // - Idle -> 'idle'
52
+
53
+ // We handle `selected` as a separate dimension derived from state.
54
+
55
+ let visualState = 'idle';
56
+ if (disabled) {
57
+ visualState = 'disabled';
58
+ } else if (focused) {
59
+ visualState = 'focus';
60
+ } else if (hovered || pressed) {
61
+ visualState = 'hover';
62
+ }
63
+
64
+ // Construct token paths based on state + selected
65
+ let prefix = `radio/${visualState}`;
66
+ if (visualState === 'idle' && selected) {
67
+ prefix = `radio/selected`;
68
+ } else if (selected) {
69
+ prefix = `radio/${visualState}Selected`;
70
+ }
71
+
72
+ // ---- Colors & Border ----
73
+
74
+ const resolveColor = (path, fallback) => {
75
+ return (0, _figmaVariablesResolver.getVariableByName)(path, modes) || fallback;
76
+ };
77
+
78
+ // Background Color
79
+ let bgColorVar = `${prefix}/background/color`;
80
+ // Fix for disabledSelected weirdness if needed
81
+ if (visualState === 'disabled' && selected) {
82
+ // Check specific path from dump: `radio/disabledSelected/background`
83
+ if (!(0, _figmaVariablesResolver.getVariableByName)(`${prefix}/background/color`, modes)) {
84
+ bgColorVar = `${prefix}/background`;
85
+ }
86
+ }
87
+
88
+ // Border Color
89
+ let borderColorVar = `${prefix}/border/color`;
90
+
91
+ // Border Width
92
+ let borderWidthVar = `${prefix}/border/size`;
93
+ // Fix for huge path: `radio/disabled/radio/disabled/border/size`
94
+ if (visualState === 'disabled' && !selected) {
95
+ if ((0, _figmaVariablesResolver.getVariableByName)('radio/disabled/radio/disabled/border/size', modes)) {
96
+ borderWidthVar = 'radio/disabled/radio/disabled/border/size';
97
+ }
98
+ }
99
+
100
+ // Selector Color
101
+ let selectorBgVar = `${prefix}/selector/background/color`;
102
+ if (!selected) {
103
+ selectorBgVar = 'transparent';
104
+ }
105
+
106
+ // Shadows (Glow)
107
+ let shadowSizeVar = `${prefix}/boxShadow/size`;
108
+ let shadowColorVar = `${prefix}/shadow/color`;
109
+
110
+ // Resolve Values
111
+ const backgroundColor = resolveColor(bgColorVar, 'transparent');
112
+ const borderColor = resolveColor(borderColorVar, 'transparent');
113
+ const borderWidth = parseFloat((0, _figmaVariablesResolver.getVariableByName)(borderWidthVar, modes)?.toString() || '1');
114
+ const selectorColor = resolveColor(selectorBgVar, 'transparent');
115
+ const shadowSize = parseFloat((0, _figmaVariablesResolver.getVariableByName)(shadowSizeVar, modes)?.toString() || '0');
116
+ const shadowColor = resolveColor(shadowColorVar, 'transparent');
117
+
118
+ // Styles
119
+ const containerStyle = {
120
+ width,
121
+ height,
122
+ borderRadius: width / 2,
123
+ // 9999px -> circle
124
+ borderWidth,
125
+ borderColor,
126
+ backgroundColor,
127
+ justifyContent: 'center',
128
+ alignItems: 'center',
129
+ // Web shadow (ring)
130
+ ...(_reactNative.Platform.OS === 'web' && shadowSize > 0 ? {
131
+ boxShadow: `0px 0px 0px ${shadowSize}px ${shadowColor}`
132
+ } : {})
133
+ };
134
+ const selectorStyle = {
135
+ width: selectorSize,
136
+ height: selectorSize,
137
+ borderRadius: selectorSize / 2,
138
+ backgroundColor: selectorColor
139
+ };
140
+
141
+ // Dummy block for token extraction (static analysis)
142
+ if (false) {
143
+ (0, _figmaVariablesResolver.getVariableByName)('radio/idle/background/color');
144
+ (0, _figmaVariablesResolver.getVariableByName)('radio/idle/border/color');
145
+ (0, _figmaVariablesResolver.getVariableByName)('radio/selector/size');
146
+ (0, _figmaVariablesResolver.getVariableByName)('radio/width');
147
+ (0, _figmaVariablesResolver.getVariableByName)('radio/height');
148
+ (0, _figmaVariablesResolver.getVariableByName)('radio/background/color');
149
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hover/background/color');
150
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hover/border/color');
151
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hover/boxShadow/size');
152
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hover/shadow/color');
153
+ (0, _figmaVariablesResolver.getVariableByName)('radio/selected/background/color');
154
+ (0, _figmaVariablesResolver.getVariableByName)('radio/selected/border/color');
155
+ (0, _figmaVariablesResolver.getVariableByName)('radio/selected/selector/background/color');
156
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hoverSelected/background/color');
157
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hoverSelected/border/color');
158
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hoverSelected/boxShadow/size');
159
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hoverSelected/shadow/color');
160
+ (0, _figmaVariablesResolver.getVariableByName)('radio/hoverSelected/selector/background/color');
161
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focus/background/color');
162
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focus/border/color');
163
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focus/border/size');
164
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focus/boxShadow/size');
165
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focus/shadow/color');
166
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focusSelected/background/color');
167
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focusSelected/selector/background/color');
168
+ (0, _figmaVariablesResolver.getVariableByName)('radio/focusSelected/border/size');
169
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabled/radio/disabled/border/size');
170
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabled/background/color');
171
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabled/border/color');
172
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabledSelected/selector/background/color');
173
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabledSelected/background');
174
+ (0, _figmaVariablesResolver.getVariableByName)('radio/disabledSelected/border/color');
175
+ }
176
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
177
+ testID: testID,
178
+ disabled: disabled,
179
+ onPress: onPress,
180
+ onHoverIn: () => setHovered(true),
181
+ onHoverOut: () => setHovered(false),
182
+ onFocus: () => setFocused(true),
183
+ onBlur: () => setFocused(false),
184
+ onPressIn: () => setPressed(true),
185
+ onPressOut: () => setPressed(false),
186
+ style: ({
187
+ pressed: isPressed
188
+ }) => [containerStyle, style],
189
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
190
+ style: selectorStyle
191
+ })
192
+ });
193
+ }
194
+ var _default = exports.default = Radio;