jfs-components 0.0.71 → 0.0.73

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 (141) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/lib/commonjs/components/AccordionCheckbox/AccordionCheckbox.js +239 -0
  3. package/lib/commonjs/components/BrandChip/BrandChip.js +149 -0
  4. package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -2
  5. package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +213 -0
  6. package/lib/commonjs/components/CardFinancialCondition/CardFinancialCondition.js +213 -0
  7. package/lib/commonjs/components/CardInsight/CardInsight.js +166 -0
  8. package/lib/commonjs/components/Carousel/Carousel.js +9 -7
  9. package/lib/commonjs/components/CheckboxGroup/CheckboxGroup.js +67 -0
  10. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +125 -0
  11. package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +56 -9
  12. package/lib/commonjs/components/CoverageBarComparison/CoverageBarComparison.js +272 -0
  13. package/lib/commonjs/components/CoverageRing/CoverageRing.js +141 -0
  14. package/lib/commonjs/components/DonutChart/DonutChart.js +309 -0
  15. package/lib/commonjs/components/DonutChartSummary/DonutChartSummary.js +155 -0
  16. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -2
  17. package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +132 -0
  18. package/lib/commonjs/components/LinearMeter/LinearMeter.js +9 -28
  19. package/lib/commonjs/components/LinearProgress/LinearProgress.js +68 -0
  20. package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +95 -0
  21. package/lib/commonjs/components/MonthlyStatusGrid/MonthlyStatusGrid.js +286 -0
  22. package/lib/commonjs/components/OTP/OTP.js +381 -37
  23. package/lib/commonjs/components/ProductOverview/ProductOverview.js +147 -0
  24. package/lib/commonjs/components/Radio/Radio.js +194 -0
  25. package/lib/commonjs/components/RadioButton/RadioButton.js +21 -188
  26. package/lib/commonjs/components/RangeTrack/RangeTrack.js +269 -0
  27. package/lib/commonjs/components/SavingsGoalSummary/SavingsGoalSummary.js +181 -0
  28. package/lib/commonjs/components/SegmentedTrack/SegmentedTrack.js +171 -0
  29. package/lib/commonjs/components/StatGroup/StatGroup.js +128 -0
  30. package/lib/commonjs/components/StatItem/StatItem.js +65 -35
  31. package/lib/commonjs/components/StrengthIndicator/StrengthIndicator.js +157 -0
  32. package/lib/commonjs/components/SummaryTile/SummaryTile.js +150 -0
  33. package/lib/commonjs/components/index.js +192 -1
  34. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  35. package/lib/commonjs/icons/registry.js +1 -1
  36. package/lib/commonjs/utils/index.js +7 -0
  37. package/lib/commonjs/utils/number-utils.js +57 -0
  38. package/lib/module/components/AccordionCheckbox/AccordionCheckbox.js +233 -0
  39. package/lib/module/components/BrandChip/BrandChip.js +143 -0
  40. package/lib/module/components/CardAdvisory/CardAdvisory.js +2 -2
  41. package/lib/module/components/CardBankAccount/CardBankAccount.js +208 -0
  42. package/lib/module/components/CardFinancialCondition/CardFinancialCondition.js +207 -0
  43. package/lib/module/components/CardInsight/CardInsight.js +161 -0
  44. package/lib/module/components/Carousel/Carousel.js +9 -7
  45. package/lib/module/components/CheckboxGroup/CheckboxGroup.js +62 -0
  46. package/lib/module/components/CheckboxItem/CheckboxItem.js +119 -0
  47. package/lib/module/components/CircularProgressBar/CircularProgressBar.js +56 -9
  48. package/lib/module/components/CoverageBarComparison/CoverageBarComparison.js +266 -0
  49. package/lib/module/components/CoverageRing/CoverageRing.js +136 -0
  50. package/lib/module/components/DonutChart/DonutChart.js +303 -0
  51. package/lib/module/components/DonutChartSummary/DonutChartSummary.js +150 -0
  52. package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -2
  53. package/lib/module/components/InstitutionBadge/InstitutionBadge.js +127 -0
  54. package/lib/module/components/LinearMeter/LinearMeter.js +9 -28
  55. package/lib/module/components/LinearProgress/LinearProgress.js +63 -0
  56. package/lib/module/components/MetricLegendItem/MetricLegendItem.js +90 -0
  57. package/lib/module/components/MonthlyStatusGrid/MonthlyStatusGrid.js +281 -0
  58. package/lib/module/components/OTP/OTP.js +381 -38
  59. package/lib/module/components/ProductOverview/ProductOverview.js +142 -0
  60. package/lib/module/components/Radio/Radio.js +188 -0
  61. package/lib/module/components/RadioButton/RadioButton.js +20 -185
  62. package/lib/module/components/RangeTrack/RangeTrack.js +263 -0
  63. package/lib/module/components/SavingsGoalSummary/SavingsGoalSummary.js +175 -0
  64. package/lib/module/components/SegmentedTrack/SegmentedTrack.js +166 -0
  65. package/lib/module/components/StatGroup/StatGroup.js +123 -0
  66. package/lib/module/components/StatItem/StatItem.js +66 -36
  67. package/lib/module/components/StrengthIndicator/StrengthIndicator.js +152 -0
  68. package/lib/module/components/SummaryTile/SummaryTile.js +145 -0
  69. package/lib/module/components/index.js +28 -1
  70. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  71. package/lib/module/icons/registry.js +1 -1
  72. package/lib/module/utils/index.js +2 -1
  73. package/lib/module/utils/number-utils.js +53 -0
  74. package/lib/typescript/src/components/AccordionCheckbox/AccordionCheckbox.d.ts +71 -0
  75. package/lib/typescript/src/components/BrandChip/BrandChip.d.ts +43 -0
  76. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +79 -0
  77. package/lib/typescript/src/components/CardFinancialCondition/CardFinancialCondition.d.ts +50 -0
  78. package/lib/typescript/src/components/CardInsight/CardInsight.d.ts +48 -0
  79. package/lib/typescript/src/components/CheckboxGroup/CheckboxGroup.d.ts +41 -0
  80. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +56 -0
  81. package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +11 -1
  82. package/lib/typescript/src/components/CoverageBarComparison/CoverageBarComparison.d.ts +105 -0
  83. package/lib/typescript/src/components/CoverageRing/CoverageRing.d.ts +90 -0
  84. package/lib/typescript/src/components/DonutChart/DonutChart.d.ts +117 -0
  85. package/lib/typescript/src/components/DonutChartSummary/DonutChartSummary.d.ts +103 -0
  86. package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +30 -0
  87. package/lib/typescript/src/components/LinearProgress/LinearProgress.d.ts +17 -0
  88. package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +37 -0
  89. package/lib/typescript/src/components/MonthlyStatusGrid/MonthlyStatusGrid.d.ts +119 -0
  90. package/lib/typescript/src/components/OTP/OTP.d.ts +88 -2
  91. package/lib/typescript/src/components/ProductOverview/ProductOverview.d.ts +39 -0
  92. package/lib/typescript/src/components/Radio/Radio.d.ts +30 -0
  93. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +20 -28
  94. package/lib/typescript/src/components/RangeTrack/RangeTrack.d.ts +173 -0
  95. package/lib/typescript/src/components/SavingsGoalSummary/SavingsGoalSummary.d.ts +95 -0
  96. package/lib/typescript/src/components/SegmentedTrack/SegmentedTrack.d.ts +108 -0
  97. package/lib/typescript/src/components/StatGroup/StatGroup.d.ts +45 -0
  98. package/lib/typescript/src/components/StatItem/StatItem.d.ts +24 -7
  99. package/lib/typescript/src/components/StrengthIndicator/StrengthIndicator.d.ts +58 -0
  100. package/lib/typescript/src/components/SummaryTile/SummaryTile.d.ts +60 -0
  101. package/lib/typescript/src/components/index.d.ts +29 -2
  102. package/lib/typescript/src/icons/registry.d.ts +1 -1
  103. package/lib/typescript/src/utils/index.d.ts +1 -0
  104. package/lib/typescript/src/utils/number-utils.d.ts +29 -0
  105. package/package.json +1 -1
  106. package/src/components/AccordionCheckbox/AccordionCheckbox.tsx +323 -0
  107. package/src/components/BrandChip/BrandChip.tsx +235 -0
  108. package/src/components/CardAdvisory/CardAdvisory.tsx +2 -2
  109. package/src/components/CardBankAccount/CardBankAccount.tsx +295 -0
  110. package/src/components/CardFinancialCondition/CardFinancialCondition.tsx +366 -0
  111. package/src/components/CardInsight/CardInsight.tsx +239 -0
  112. package/src/components/Carousel/Carousel.tsx +14 -6
  113. package/src/components/CheckboxGroup/CheckboxGroup.tsx +86 -0
  114. package/src/components/CheckboxItem/CheckboxItem.tsx +174 -0
  115. package/src/components/CircularProgressBar/CircularProgressBar.tsx +74 -9
  116. package/src/components/CoverageBarComparison/CoverageBarComparison.tsx +378 -0
  117. package/src/components/CoverageRing/CoverageRing.tsx +225 -0
  118. package/src/components/DonutChart/DonutChart.tsx +503 -0
  119. package/src/components/DonutChartSummary/DonutChartSummary.tsx +256 -0
  120. package/src/components/HoldingsCard/HoldingsCard.tsx +2 -2
  121. package/src/components/InstitutionBadge/InstitutionBadge.tsx +216 -0
  122. package/src/components/LinearMeter/LinearMeter.tsx +9 -39
  123. package/src/components/LinearProgress/LinearProgress.tsx +92 -0
  124. package/src/components/MetricLegendItem/MetricLegendItem.tsx +167 -0
  125. package/src/components/MonthlyStatusGrid/MonthlyStatusGrid.tsx +438 -0
  126. package/src/components/OTP/OTP.tsx +476 -29
  127. package/src/components/ProductOverview/ProductOverview.tsx +236 -0
  128. package/src/components/Radio/Radio.tsx +227 -0
  129. package/src/components/RadioButton/RadioButton.tsx +23 -225
  130. package/src/components/RangeTrack/RangeTrack.tsx +394 -0
  131. package/src/components/SavingsGoalSummary/SavingsGoalSummary.tsx +269 -0
  132. package/src/components/SegmentedTrack/SegmentedTrack.tsx +268 -0
  133. package/src/components/StatGroup/StatGroup.tsx +169 -0
  134. package/src/components/StatItem/StatItem.tsx +117 -40
  135. package/src/components/StrengthIndicator/StrengthIndicator.tsx +205 -0
  136. package/src/components/SummaryTile/SummaryTile.tsx +251 -0
  137. package/src/components/index.ts +39 -2
  138. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  139. package/src/icons/registry.ts +1 -1
  140. package/src/utils/index.ts +1 -0
  141. package/src/utils/number-utils.ts +60 -0
@@ -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;
@@ -3,192 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.RadioButton = RadioButton;
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
- // RadioButton
20
- // ---------------------------------------------------------------------------
21
-
22
- function RadioButton({
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 Radio Buttons, 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
- }
6
+ exports.default = exports.RadioButton = void 0;
7
+ var _Radio = require("../Radio/Radio");
8
+ /**
9
+ * @deprecated `RadioButton` has been renamed to `Radio`.
10
+ *
11
+ * This file is kept as a backward-compatibility shim for teams that may be
12
+ * importing `RadioButton` directly from this deep path:
13
+ *
14
+ * import RadioButton from 'jfs-components/src/components/RadioButton/RadioButton'
15
+ * import { RadioButton, RadioButtonProps } from '...'
16
+ *
17
+ * The recommended public import is now:
18
+ *
19
+ * import { Radio, type RadioProps } from 'jfs-components'
20
+ *
21
+ * Going forward, this component is called `Radio`. This shim only re-exports
22
+ * the new `Radio` component under the old `RadioButton` names; please migrate
23
+ * existing usages to `Radio` at your earliest convenience.
24
+ */
25
+
26
+ const RadioButton = exports.RadioButton = _Radio.Radio;
194
27
  var _default = exports.default = RadioButton;
@@ -0,0 +1,269 @@
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 _MetricLegendItem = _interopRequireDefault(require("../MetricLegendItem/MetricLegendItem"));
13
+ var _SegmentedTrack = _interopRequireDefault(require("../SegmentedTrack/SegmentedTrack"));
14
+ var _Tabs = _interopRequireDefault(require("../Tabs/Tabs"));
15
+ var _TabItem = _interopRequireDefault(require("../Tabs/TabItem"));
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
+ /**
20
+ * One row of data inside a `RangeTrack` tab.
21
+ *
22
+ * Each item drives BOTH a `SegmentedTrack` segment and the matching
23
+ * `MetricLegendItem` row, so the segment color and legend indicator
24
+ * always share the same color by construction (same `Emphasis / DataViz`
25
+ * cascade as the standalone `SegmentedTrack`).
26
+ */
27
+
28
+ /**
29
+ * One tab inside a `RangeTrack`. Each tab carries its own `items`
30
+ * array, which is the single source of truth for both the
31
+ * `SegmentedTrack` segments AND the `MetricLegendItem` legend rows
32
+ * rendered for that tab.
33
+ */
34
+
35
+ const DEFAULT_EMPHASIS_CYCLE = ['High', 'Medium', 'Low'];
36
+ const DEFAULT_TABS = [{
37
+ label: 'Tab item',
38
+ items: [{
39
+ label: 'Large cap',
40
+ value: 1,
41
+ displayValue: '25%'
42
+ }, {
43
+ label: 'Mid cap',
44
+ value: 1,
45
+ displayValue: '25%'
46
+ }, {
47
+ label: 'Small cap',
48
+ value: 1,
49
+ displayValue: '25%'
50
+ }]
51
+ }, {
52
+ label: 'Tab item',
53
+ items: [{
54
+ label: 'Large cap',
55
+ value: 1,
56
+ displayValue: '25%'
57
+ }, {
58
+ label: 'Mid cap',
59
+ value: 1,
60
+ displayValue: '25%'
61
+ }, {
62
+ label: 'Small cap',
63
+ value: 1,
64
+ displayValue: '25%'
65
+ }]
66
+ }, {
67
+ label: 'Tab item',
68
+ items: [{
69
+ label: 'Large cap',
70
+ value: 1,
71
+ displayValue: '25%'
72
+ }, {
73
+ label: 'Mid cap',
74
+ value: 1,
75
+ displayValue: '25%'
76
+ }, {
77
+ label: 'Small cap',
78
+ value: 1,
79
+ displayValue: '25%'
80
+ }]
81
+ }];
82
+ const defaultEmphasisFor = index => DEFAULT_EMPHASIS_CYCLE[index % DEFAULT_EMPHASIS_CYCLE.length];
83
+
84
+ /**
85
+ * Resolve the shared color for an item. Honors any explicit `color`
86
+ * override, then falls back to `dataViz/bg` for the merged mode set,
87
+ * then to the Figma reference value.
88
+ *
89
+ * Mirrors the cascade used by `SegmentedTrack` (per-index `Emphasis /
90
+ * DataViz` defaults of `High` → `Medium` → `Low`, cycling) so the
91
+ * pre-computed color we pass to both the segment and the legend
92
+ * indicator matches what the `SegmentedTrack` would have computed on
93
+ * its own. This is what keeps segments and legend rows in sync by
94
+ * construction.
95
+ */
96
+ function resolveItemColor(parentModes, item, index) {
97
+ if (item.color) return item.color;
98
+ const itemModes = {
99
+ ...parentModes,
100
+ 'Emphasis / DataViz': defaultEmphasisFor(index),
101
+ ...(item.modes || {})
102
+ };
103
+ return (0, _figmaVariablesResolver.getVariableByName)('dataViz/bg', itemModes) ?? '#cea15a';
104
+ }
105
+
106
+ /**
107
+ * Resolve what to render in the legend row's right-side slot. The
108
+ * order of precedence is:
109
+ * 1. `item.displayValue` if explicitly provided (including `null` /
110
+ * `false`, which the underlying `MetricLegendItem` treats as
111
+ * "hide the value slot").
112
+ * 2. `formatValue(item.value)` when a parent-level formatter exists.
113
+ * 3. `undefined` — the value slot is hidden.
114
+ */
115
+ function resolveLegendValue(item, formatValue) {
116
+ if (item.displayValue !== undefined) return item.displayValue;
117
+ if (formatValue) return formatValue(item.value);
118
+ return undefined;
119
+ }
120
+
121
+ /**
122
+ * `RangeTrack` pairs a tab row with a `SegmentedTrack` and a vertical
123
+ * stack of `MetricLegendItem` rows. Each tab carries its own `items`
124
+ * array which is the **single source of truth** for both the segments
125
+ * and the legend rows of that tab — every segment has exactly one
126
+ * legend row and they share the same color through the same
127
+ * `Emphasis / DataViz` cascade as the standalone `SegmentedTrack`.
128
+ *
129
+ * Switching tabs swaps the segments and the legend together so the
130
+ * two visualizations can never drift out of sync.
131
+ *
132
+ * The default 3-item layout per tab receives per-index
133
+ * `Emphasis / DataViz` defaults (item 1 → `High`, 2 → `Medium`, 3 →
134
+ * `Low`, then cycles). Override `Appearance / DataViz` on the parent
135
+ * `modes` to retheme the whole component, or set `modes` per item to
136
+ * remix.
137
+ *
138
+ * The component supports both **controlled** and **uncontrolled**
139
+ * tab selection — pass `activeTabIndex` + `onTabChange` for the
140
+ * controlled mode, or omit them and the component will manage the
141
+ * selection internally starting from `defaultActiveTabIndex`.
142
+ *
143
+ * @component
144
+ * @param {RangeTrackProps} props
145
+ *
146
+ * @example
147
+ * ```tsx
148
+ * <RangeTrack
149
+ * tabs={[
150
+ * {
151
+ * label: 'Sectoral',
152
+ * items: [
153
+ * { label: 'Large cap', value: 50, displayValue: '50%' },
154
+ * { label: 'Mid cap', value: 30, displayValue: '30%' },
155
+ * { label: 'Small cap', value: 20, displayValue: '20%' },
156
+ * ],
157
+ * },
158
+ * {
159
+ * label: 'Geography',
160
+ * items: [
161
+ * { label: 'India', value: 70, displayValue: '70%' },
162
+ * { label: 'US', value: 20, displayValue: '20%' },
163
+ * { label: 'Other', value: 10, displayValue: '10%' },
164
+ * ],
165
+ * },
166
+ * ]}
167
+ * />
168
+ * ```
169
+ */
170
+ function RangeTrack({
171
+ tabs,
172
+ formatValue,
173
+ activeTabIndex,
174
+ defaultActiveTabIndex = 0,
175
+ onTabChange,
176
+ scrollableTabs = false,
177
+ modes: propModes = _reactUtils.EMPTY_MODES,
178
+ style,
179
+ tabsStyle,
180
+ trackStyle,
181
+ legendStyle,
182
+ accessibilityLabel
183
+ }) {
184
+ const {
185
+ modes: globalModes
186
+ } = (0, _JFSThemeProvider.useTokens)();
187
+ const modes = {
188
+ ...globalModes,
189
+ ...propModes
190
+ };
191
+ const resolvedTabs = tabs && tabs.length > 0 ? tabs : DEFAULT_TABS;
192
+ const [internalIndex, setInternalIndex] = (0, _react.useState)(() => clampIndex(defaultActiveTabIndex, resolvedTabs.length));
193
+ const isControlled = activeTabIndex !== undefined;
194
+ const rawIndex = isControlled ? activeTabIndex : internalIndex;
195
+ const safeIndex = clampIndex(rawIndex, resolvedTabs.length);
196
+ const handleTabPress = (0, _react.useCallback)(index => {
197
+ const nextTab = resolvedTabs[index];
198
+ if (!nextTab) return;
199
+ if (!isControlled) setInternalIndex(index);
200
+ onTabChange?.(index, nextTab);
201
+ }, [isControlled, onTabChange, resolvedTabs]);
202
+ const containerGap = (0, _figmaVariablesResolver.getVariableByName)('rangeTrack/gap', modes) ?? 28;
203
+ // Vertical gap between legend rows is not exposed as its own token —
204
+ // the Figma design uses 8px between rows, mirroring the
205
+ // `donutChartSummary/legend/gap` default. Keep the value in step
206
+ // with `DonutChartSummary` so the two summary components feel
207
+ // cohesive when stacked.
208
+ const legendRowGap = 8;
209
+ const activeTab = resolvedTabs[safeIndex];
210
+ const activeItems = activeTab?.items ?? [];
211
+ const segments = activeItems.map((item, index) => ({
212
+ key: item.key ?? `segment-${index}`,
213
+ value: item.value,
214
+ color: resolveItemColor(modes, item, index),
215
+ accessibilityLabel: item.accessibilityLabel
216
+ }));
217
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
218
+ accessibilityRole: "summary",
219
+ accessibilityLabel: accessibilityLabel,
220
+ style: [{
221
+ width: '100%',
222
+ flexDirection: 'column',
223
+ alignItems: 'flex-start',
224
+ gap: containerGap
225
+ }, style],
226
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tabs.default, {
227
+ modes: modes,
228
+ scrollable: scrollableTabs,
229
+ style: tabsStyle,
230
+ children: resolvedTabs.map((tab, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabItem.default, {
231
+ label: tab.label,
232
+ active: index === safeIndex,
233
+ onPress: () => handleTabPress(index),
234
+ accessibilityLabel: tab.accessibilityLabel ?? tab.label
235
+ }, tab.key ?? tab.label ?? `tab-${index}`))
236
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SegmentedTrack.default, {
237
+ modes: modes,
238
+ segments: segments,
239
+ style: trackStyle,
240
+ accessibilityLabel: activeTab?.accessibilityLabel ?? activeTab?.label
241
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
242
+ style: [{
243
+ width: '100%',
244
+ flexDirection: 'column',
245
+ alignItems: 'flex-start',
246
+ gap: legendRowGap
247
+ }, legendStyle],
248
+ children: activeItems.map((item, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_MetricLegendItem.default, {
249
+ label: item.label,
250
+ value: resolveLegendValue(item, formatValue),
251
+ indicatorColor: resolveItemColor(modes, item, index),
252
+ modes: modes
253
+ }, item.key ?? `legend-${index}`))
254
+ })]
255
+ });
256
+ }
257
+
258
+ /**
259
+ * Clamp a tab index into `[0, length)`. Negative or out-of-bounds
260
+ * values fall back to `0` to avoid rendering an undefined tab.
261
+ */
262
+ function clampIndex(index, length) {
263
+ if (length <= 0) return 0;
264
+ if (!Number.isFinite(index)) return 0;
265
+ if (index < 0) return 0;
266
+ if (index >= length) return length - 1;
267
+ return Math.floor(index);
268
+ }
269
+ var _default = exports.default = RangeTrack;