jfs-components 0.0.72 → 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 (116) hide show
  1. package/CHANGELOG.md +11 -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/CardBankAccount/CardBankAccount.js +213 -0
  5. package/lib/commonjs/components/CardInsight/CardInsight.js +166 -0
  6. package/lib/commonjs/components/CheckboxGroup/CheckboxGroup.js +67 -0
  7. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +125 -0
  8. package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +56 -9
  9. package/lib/commonjs/components/CoverageBarComparison/CoverageBarComparison.js +272 -0
  10. package/lib/commonjs/components/CoverageRing/CoverageRing.js +141 -0
  11. package/lib/commonjs/components/DonutChart/DonutChart.js +309 -0
  12. package/lib/commonjs/components/DonutChartSummary/DonutChartSummary.js +155 -0
  13. package/lib/commonjs/components/LinearMeter/LinearMeter.js +9 -28
  14. package/lib/commonjs/components/LinearProgress/LinearProgress.js +68 -0
  15. package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +95 -0
  16. package/lib/commonjs/components/MonthlyStatusGrid/MonthlyStatusGrid.js +286 -0
  17. package/lib/commonjs/components/OTP/OTP.js +381 -37
  18. package/lib/commonjs/components/ProductOverview/ProductOverview.js +147 -0
  19. package/lib/commonjs/components/RangeTrack/RangeTrack.js +269 -0
  20. package/lib/commonjs/components/SavingsGoalSummary/SavingsGoalSummary.js +181 -0
  21. package/lib/commonjs/components/SegmentedTrack/SegmentedTrack.js +171 -0
  22. package/lib/commonjs/components/StatGroup/StatGroup.js +128 -0
  23. package/lib/commonjs/components/StatItem/StatItem.js +65 -35
  24. package/lib/commonjs/components/StrengthIndicator/StrengthIndicator.js +157 -0
  25. package/lib/commonjs/components/SummaryTile/SummaryTile.js +150 -0
  26. package/lib/commonjs/components/index.js +171 -1
  27. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  28. package/lib/commonjs/icons/registry.js +1 -1
  29. package/lib/commonjs/utils/index.js +7 -0
  30. package/lib/commonjs/utils/number-utils.js +57 -0
  31. package/lib/module/components/AccordionCheckbox/AccordionCheckbox.js +233 -0
  32. package/lib/module/components/BrandChip/BrandChip.js +143 -0
  33. package/lib/module/components/CardBankAccount/CardBankAccount.js +208 -0
  34. package/lib/module/components/CardInsight/CardInsight.js +161 -0
  35. package/lib/module/components/CheckboxGroup/CheckboxGroup.js +62 -0
  36. package/lib/module/components/CheckboxItem/CheckboxItem.js +119 -0
  37. package/lib/module/components/CircularProgressBar/CircularProgressBar.js +56 -9
  38. package/lib/module/components/CoverageBarComparison/CoverageBarComparison.js +266 -0
  39. package/lib/module/components/CoverageRing/CoverageRing.js +136 -0
  40. package/lib/module/components/DonutChart/DonutChart.js +303 -0
  41. package/lib/module/components/DonutChartSummary/DonutChartSummary.js +150 -0
  42. package/lib/module/components/LinearMeter/LinearMeter.js +9 -28
  43. package/lib/module/components/LinearProgress/LinearProgress.js +63 -0
  44. package/lib/module/components/MetricLegendItem/MetricLegendItem.js +90 -0
  45. package/lib/module/components/MonthlyStatusGrid/MonthlyStatusGrid.js +281 -0
  46. package/lib/module/components/OTP/OTP.js +381 -38
  47. package/lib/module/components/ProductOverview/ProductOverview.js +142 -0
  48. package/lib/module/components/RangeTrack/RangeTrack.js +263 -0
  49. package/lib/module/components/SavingsGoalSummary/SavingsGoalSummary.js +175 -0
  50. package/lib/module/components/SegmentedTrack/SegmentedTrack.js +166 -0
  51. package/lib/module/components/StatGroup/StatGroup.js +123 -0
  52. package/lib/module/components/StatItem/StatItem.js +66 -36
  53. package/lib/module/components/StrengthIndicator/StrengthIndicator.js +152 -0
  54. package/lib/module/components/SummaryTile/SummaryTile.js +145 -0
  55. package/lib/module/components/index.js +21 -1
  56. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  57. package/lib/module/icons/registry.js +1 -1
  58. package/lib/module/utils/index.js +2 -1
  59. package/lib/module/utils/number-utils.js +53 -0
  60. package/lib/typescript/src/components/AccordionCheckbox/AccordionCheckbox.d.ts +71 -0
  61. package/lib/typescript/src/components/BrandChip/BrandChip.d.ts +43 -0
  62. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +79 -0
  63. package/lib/typescript/src/components/CardInsight/CardInsight.d.ts +48 -0
  64. package/lib/typescript/src/components/CheckboxGroup/CheckboxGroup.d.ts +41 -0
  65. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +56 -0
  66. package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +11 -1
  67. package/lib/typescript/src/components/CoverageBarComparison/CoverageBarComparison.d.ts +105 -0
  68. package/lib/typescript/src/components/CoverageRing/CoverageRing.d.ts +90 -0
  69. package/lib/typescript/src/components/DonutChart/DonutChart.d.ts +117 -0
  70. package/lib/typescript/src/components/DonutChartSummary/DonutChartSummary.d.ts +103 -0
  71. package/lib/typescript/src/components/LinearProgress/LinearProgress.d.ts +17 -0
  72. package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +37 -0
  73. package/lib/typescript/src/components/MonthlyStatusGrid/MonthlyStatusGrid.d.ts +119 -0
  74. package/lib/typescript/src/components/OTP/OTP.d.ts +88 -2
  75. package/lib/typescript/src/components/ProductOverview/ProductOverview.d.ts +39 -0
  76. package/lib/typescript/src/components/RangeTrack/RangeTrack.d.ts +173 -0
  77. package/lib/typescript/src/components/SavingsGoalSummary/SavingsGoalSummary.d.ts +95 -0
  78. package/lib/typescript/src/components/SegmentedTrack/SegmentedTrack.d.ts +108 -0
  79. package/lib/typescript/src/components/StatGroup/StatGroup.d.ts +45 -0
  80. package/lib/typescript/src/components/StatItem/StatItem.d.ts +24 -7
  81. package/lib/typescript/src/components/StrengthIndicator/StrengthIndicator.d.ts +58 -0
  82. package/lib/typescript/src/components/SummaryTile/SummaryTile.d.ts +60 -0
  83. package/lib/typescript/src/components/index.d.ts +22 -2
  84. package/lib/typescript/src/icons/registry.d.ts +1 -1
  85. package/lib/typescript/src/utils/index.d.ts +1 -0
  86. package/lib/typescript/src/utils/number-utils.d.ts +29 -0
  87. package/package.json +1 -1
  88. package/src/components/AccordionCheckbox/AccordionCheckbox.tsx +323 -0
  89. package/src/components/BrandChip/BrandChip.tsx +235 -0
  90. package/src/components/CardBankAccount/CardBankAccount.tsx +295 -0
  91. package/src/components/CardInsight/CardInsight.tsx +239 -0
  92. package/src/components/CheckboxGroup/CheckboxGroup.tsx +86 -0
  93. package/src/components/CheckboxItem/CheckboxItem.tsx +174 -0
  94. package/src/components/CircularProgressBar/CircularProgressBar.tsx +74 -9
  95. package/src/components/CoverageBarComparison/CoverageBarComparison.tsx +378 -0
  96. package/src/components/CoverageRing/CoverageRing.tsx +225 -0
  97. package/src/components/DonutChart/DonutChart.tsx +503 -0
  98. package/src/components/DonutChartSummary/DonutChartSummary.tsx +256 -0
  99. package/src/components/LinearMeter/LinearMeter.tsx +9 -39
  100. package/src/components/LinearProgress/LinearProgress.tsx +92 -0
  101. package/src/components/MetricLegendItem/MetricLegendItem.tsx +167 -0
  102. package/src/components/MonthlyStatusGrid/MonthlyStatusGrid.tsx +438 -0
  103. package/src/components/OTP/OTP.tsx +476 -29
  104. package/src/components/ProductOverview/ProductOverview.tsx +236 -0
  105. package/src/components/RangeTrack/RangeTrack.tsx +394 -0
  106. package/src/components/SavingsGoalSummary/SavingsGoalSummary.tsx +269 -0
  107. package/src/components/SegmentedTrack/SegmentedTrack.tsx +268 -0
  108. package/src/components/StatGroup/StatGroup.tsx +169 -0
  109. package/src/components/StatItem/StatItem.tsx +117 -40
  110. package/src/components/StrengthIndicator/StrengthIndicator.tsx +205 -0
  111. package/src/components/SummaryTile/SummaryTile.tsx +251 -0
  112. package/src/components/index.ts +32 -2
  113. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  114. package/src/icons/registry.ts +1 -1
  115. package/src/utils/index.ts +1 -0
  116. package/src/utils/number-utils.ts +60 -0
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _reactUtils = require("../../utils/react-utils");
11
+ var _StatItem = _interopRequireDefault(require("../StatItem/StatItem"));
12
+ var _Divider = _interopRequireDefault(require("../Divider/Divider"));
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ const DEFAULT_ITEMS = [{
16
+ label: 'Updates',
17
+ value: 'Daily'
18
+ }, {
19
+ label: 'Data range',
20
+ value: '24 months'
21
+ }, {
22
+ label: 'Validity',
23
+ value: '24 months'
24
+ }, {
25
+ label: 'Stored for',
26
+ value: '1 month'
27
+ }];
28
+
29
+ /**
30
+ * StatGroup renders a card-style container holding a horizontal row of
31
+ * `StatItem`s separated by vertical dividers. It is typically used to surface
32
+ * 3–5 short metrics (e.g. validity, data range, storage) at a glance.
33
+ *
34
+ * Pass `items` for the simple data-driven case, or use the `children` slot
35
+ * for full control over the row contents (the component still auto-inserts
36
+ * vertical dividers between top-level children).
37
+ *
38
+ * @component
39
+ * @param {StatGroupProps} props
40
+ */
41
+ function StatGroup({
42
+ items,
43
+ children,
44
+ modes = _reactUtils.EMPTY_MODES,
45
+ style
46
+ }) {
47
+ const background = (0, _figmaVariablesResolver.getVariableByName)('statGroup/background', modes) ?? '#ffffff';
48
+ const strokeColor = (0, _figmaVariablesResolver.getVariableByName)('statGroup/stroke/color', modes) ?? '#ebebed';
49
+ const strokeSize = (0, _figmaVariablesResolver.getVariableByName)('statGroup/stroke/size', modes) ?? 1;
50
+ const radius = (0, _figmaVariablesResolver.getVariableByName)('statGroup/radius', modes) ?? 12;
51
+ const paddingTop = (0, _figmaVariablesResolver.getVariableByName)('statGroup/padding/top', modes) ?? 16;
52
+ const paddingRight = (0, _figmaVariablesResolver.getVariableByName)('statGroup/padding/right', modes) ?? 0;
53
+ const paddingBottom = (0, _figmaVariablesResolver.getVariableByName)('statGroup/padding/bottom', modes) ?? 12;
54
+ const paddingLeft = (0, _figmaVariablesResolver.getVariableByName)('statGroup/padding/left', modes) ?? 0;
55
+ const containerStyle = {
56
+ backgroundColor: background,
57
+ borderColor: strokeColor,
58
+ borderWidth: strokeSize,
59
+ borderStyle: 'solid',
60
+ borderRadius: radius,
61
+ paddingTop,
62
+ paddingRight,
63
+ paddingBottom,
64
+ paddingLeft,
65
+ overflow: 'hidden'
66
+ };
67
+ const slotChildren = renderSlotChildren({
68
+ items,
69
+ children,
70
+ modes
71
+ });
72
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
73
+ style: [containerStyle, style],
74
+ accessibilityRole: "summary",
75
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
76
+ style: {
77
+ flexDirection: 'row',
78
+ alignItems: 'stretch',
79
+ width: '100%'
80
+ },
81
+ children: slotChildren
82
+ })
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Build the row of items: render either the supplied children or the
88
+ * `items` array, wrap each entry so it grows equally, and inject a vertical
89
+ * `Divider` between siblings.
90
+ */
91
+ function renderSlotChildren({
92
+ items,
93
+ children,
94
+ modes
95
+ }) {
96
+ let nodes;
97
+ if (children !== undefined && children !== null) {
98
+ const cloned = (0, _reactUtils.cloneChildrenWithModes)(children, modes);
99
+ nodes = (0, _reactUtils.flattenChildren)(cloned);
100
+ } else {
101
+ const list = items && items.length > 0 ? items : DEFAULT_ITEMS;
102
+ nodes = list.map((item, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_StatItem.default, {
103
+ label: item.label,
104
+ value: item.value,
105
+ labelPosition: "Bottom",
106
+ modes: modes
107
+ }, item.key ?? `${item.label ?? 'item'}-${index}`));
108
+ }
109
+ const result = [];
110
+ nodes.forEach((node, index) => {
111
+ if (index > 0) {
112
+ result.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_Divider.default, {
113
+ direction: "vertical",
114
+ modes: modes
115
+ }, `divider-${index}`));
116
+ }
117
+ result.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
118
+ style: {
119
+ flex: 1,
120
+ minWidth: 0,
121
+ alignSelf: 'center'
122
+ },
123
+ children: node
124
+ }, `slot-${index}`));
125
+ });
126
+ return result;
127
+ }
128
+ var _default = exports.default = StatGroup;
@@ -11,8 +11,12 @@ var _reactUtils = require("../../utils/react-utils");
11
11
  var _jsxRuntime = require("react/jsx-runtime");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  /**
14
- * StatItem displays a label/value pair with the value in a large, bold style.
15
- * Useful for metrics, product stats, or KPI callouts.
14
+ * StatItem displays a label/value pair, useful for product stats, metrics
15
+ * or KPI callouts.
16
+ *
17
+ * Supports two layouts via the `labelPosition` variant:
18
+ * - `'Top'` — Small label above a large prominent value (default).
19
+ * - `'Bottom'` — Value above a smaller label, content centered.
16
20
  *
17
21
  * @component
18
22
  * @param {StatItemProps} props
@@ -20,43 +24,69 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
20
24
  function StatItem({
21
25
  label = 'Purity verified by NABL',
22
26
  value = '99.99%',
27
+ labelPosition = 'Top',
23
28
  modes = _reactUtils.EMPTY_MODES,
24
- style
29
+ style,
30
+ labelStyle,
31
+ valueStyle
25
32
  }) {
26
- const gap = (0, _figmaVariablesResolver.getVariableByName)('statItem/gap', modes) ?? 2;
27
- const labelForeground = (0, _figmaVariablesResolver.getVariableByName)('statItem/label/foreground', modes) ?? '#1a1c1f';
33
+ const isBottom = labelPosition === 'Bottom';
34
+
35
+ // The Figma `Bottom` variant overrides token values locally inside the
36
+ // component (it is not exposed in the design-tokens JSON), so the resolved
37
+ // token values reflect only the `Top` variant. For the `Bottom` variant we
38
+ // therefore use hardcoded literals that match the Figma design, while still
39
+ // allowing the resolver to surface any future mode-based overrides for the
40
+ // `Top` variant.
41
+ const gap = isBottom ? 6 : (0, _figmaVariablesResolver.getVariableByName)('statItem/gap', modes) ?? 2;
42
+ const labelForeground = isBottom ? '#24262b' : (0, _figmaVariablesResolver.getVariableByName)('statItem/label/foreground', modes) ?? '#1a1c1f';
28
43
  const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('statItem/label/fontFamily', modes) ?? 'JioType Var';
29
- const labelFontSize = (0, _figmaVariablesResolver.getVariableByName)('statItem/label/fontSize', modes) ?? 12;
30
- const labelFontWeight = (0, _figmaVariablesResolver.getVariableByName)('statItem/label/fontWeight', modes) ?? '500';
31
- const labelLineHeight = (0, _figmaVariablesResolver.getVariableByName)('statItem/label/lineHeight', modes) ?? 16;
32
- const valueForeground = (0, _figmaVariablesResolver.getVariableByName)('statItem/value/foreground', modes) ?? '#0d0d0f';
44
+ const labelFontSize = isBottom ? 10 : (0, _figmaVariablesResolver.getVariableByName)('statItem/label/fontSize', modes) ?? 12;
45
+ const labelFontWeightRaw = isBottom ? 400 : (0, _figmaVariablesResolver.getVariableByName)('statItem/label/fontWeight', modes) ?? 500;
46
+ const labelFontWeight = String(labelFontWeightRaw);
47
+ const labelLineHeight = isBottom ? 13 : (0, _figmaVariablesResolver.getVariableByName)('statItem/label/lineHeight', modes) ?? 16;
48
+ const valueForeground = isBottom ? '#141414' : (0, _figmaVariablesResolver.getVariableByName)('statItem/value/foreground', modes) ?? '#0d0d0f';
33
49
  const valueFontFamily = (0, _figmaVariablesResolver.getVariableByName)('statItem/value/fontFamily', modes) ?? 'JioType Var';
34
- const valueFontSize = (0, _figmaVariablesResolver.getVariableByName)('statItem/value/fontSize', modes) ?? 26;
35
- const valueFontWeight = (0, _figmaVariablesResolver.getVariableByName)('statItem/value/fontWeight', modes) ?? '900';
36
- const valueLineHeight = (0, _figmaVariablesResolver.getVariableByName)('statItem/value/lineHeight', modes) ?? 26;
37
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
38
- style: [{
39
- gap: gap
40
- }, style],
41
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
42
- style: {
43
- color: labelForeground,
44
- fontFamily: labelFontFamily,
45
- fontSize: labelFontSize,
46
- fontWeight: String(labelFontWeight),
47
- lineHeight: labelLineHeight
48
- },
49
- children: label
50
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
51
- style: {
52
- color: valueForeground,
53
- fontFamily: valueFontFamily,
54
- fontSize: valueFontSize,
55
- fontWeight: String(valueFontWeight),
56
- lineHeight: valueLineHeight
57
- },
58
- children: value
59
- })]
50
+ const valueFontSize = isBottom ? 12 : (0, _figmaVariablesResolver.getVariableByName)('statItem/value/fontSize', modes) ?? 26;
51
+ const valueFontWeightRaw = isBottom ? 500 : (0, _figmaVariablesResolver.getVariableByName)('statItem/value/fontWeight', modes) ?? 900;
52
+ const valueFontWeight = String(valueFontWeightRaw);
53
+ const valueLineHeight = isBottom ? 16 : (0, _figmaVariablesResolver.getVariableByName)('statItem/value/lineHeight', modes) ?? 26;
54
+ const containerStyle = {
55
+ gap,
56
+ alignItems: isBottom ? 'center' : 'flex-start',
57
+ justifyContent: isBottom ? 'center' : 'flex-start'
58
+ };
59
+ const labelTextStyle = {
60
+ color: labelForeground,
61
+ fontFamily: labelFontFamily,
62
+ fontSize: labelFontSize,
63
+ fontWeight: labelFontWeight,
64
+ lineHeight: labelLineHeight,
65
+ textAlign: isBottom ? 'center' : 'left'
66
+ };
67
+ const valueTextStyle = {
68
+ color: valueForeground,
69
+ fontFamily: valueFontFamily,
70
+ fontSize: valueFontSize,
71
+ fontWeight: valueFontWeight,
72
+ lineHeight: valueLineHeight,
73
+ textAlign: isBottom ? 'center' : 'left'
74
+ };
75
+ const labelNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
76
+ style: [labelTextStyle, labelStyle],
77
+ children: label
78
+ });
79
+ const valueNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
80
+ style: [valueTextStyle, valueStyle],
81
+ children: value
82
+ });
83
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
84
+ style: [containerStyle, style],
85
+ children: isBottom ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
86
+ children: [valueNode, labelNode]
87
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
88
+ children: [labelNode, valueNode]
89
+ })
60
90
  });
61
91
  }
62
92
  var _default = exports.default = StatItem;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _reactUtils = require("../../utils/react-utils");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ /**
14
+ * Confidence levels supported by the indicator. Mirrors the Figma `Confidence`
15
+ * mode collection exactly (`High` | `Medium` | `Low` | `None`).
16
+ */
17
+
18
+ /**
19
+ * Accepted shape for the `confidence` prop. Either:
20
+ * - one of the named levels (`'High' | 'Medium' | 'Low' | 'None'`), or
21
+ * - a float in `[0, 1]`. Floats are bucketed to the nearest level using
22
+ * midpoint thresholds (1/6, 1/2, 5/6) so anchor values land squarely:
23
+ * `0` → `None`, `~0.33` → `Low`, `~0.66` → `Medium`, `1` → `High`.
24
+ * Values outside `[0, 1]` are clamped.
25
+ */
26
+
27
+ const BAR_SIZES = ['small', 'medium', 'large'];
28
+
29
+ /**
30
+ * Maps an overall confidence level to per-bar confidence modes. Bars are
31
+ * filled from the smallest (left) to the largest (right) as confidence
32
+ * rises, with each lit bar tinted at its own confidence level so the
33
+ * indicator visually communicates *which* level the value is at — not just
34
+ * how many bars are lit.
35
+ *
36
+ * High -> [High, High, High] (3/3 lit, bright)
37
+ * Medium -> [Medium, Medium, None] (2/3 lit, mid intensity)
38
+ * Low -> [Low, None, None] (1/3 lit, low intensity)
39
+ * None -> [None, None, None] (0/3 lit)
40
+ *
41
+ * Each bar resolves its color through `getVariableByName` with its own
42
+ * per-bar `Confidence` mode, so the mapping survives any token updates in
43
+ * the Figma variables export.
44
+ */
45
+ const CONFIDENCE_TO_BARS = {
46
+ High: ['High', 'High', 'High'],
47
+ Medium: ['Medium', 'Medium', 'None'],
48
+ Low: ['Low', 'None', 'None'],
49
+ None: ['None', 'None', 'None']
50
+ };
51
+
52
+ /**
53
+ * Fallback colors used when the `strengthIndicator/*` design tokens have not
54
+ * yet been imported into `Coin Variables-variables-full.json`. The `High`
55
+ * fallback matches the Figma export (`#25ab21`); the intermediate levels
56
+ * use progressively lighter greens, and `None` uses a neutral gray for
57
+ * unlit bars. Once the tokens land, `getVariableByName` returns the
58
+ * canonical value and these fallbacks are bypassed.
59
+ */
60
+ const FALLBACK_BAR_COLOR = {
61
+ High: '#25ab21',
62
+ Medium: '#5cc257',
63
+ Low: '#a8dba2',
64
+ None: '#d9d9dd'
65
+ };
66
+
67
+ /**
68
+ * Bucket a float `[0, 1]` into the nearest named confidence level using
69
+ * midpoint thresholds between the four anchor values (`0`, `1/3`, `2/3`,
70
+ * `1`). Out-of-range values are clamped.
71
+ */
72
+ function floatToConfidence(value) {
73
+ const clamped = Math.min(Math.max(value, 0), 1);
74
+ if (clamped > 5 / 6) return 'High';
75
+ if (clamped > 1 / 2) return 'Medium';
76
+ if (clamped > 1 / 6) return 'Low';
77
+ return 'None';
78
+ }
79
+
80
+ /**
81
+ * Normalize the union `confidence` prop into a single named level.
82
+ * Strings pass through; numbers are bucketed via {@link floatToConfidence}.
83
+ * Anything else (e.g. `null`/`undefined`) defaults to `'High'` to match
84
+ * Figma's default mode.
85
+ */
86
+ function resolveConfidence(value) {
87
+ if (typeof value === 'number') return floatToConfidence(value);
88
+ if (value === 'High' || value === 'Medium' || value === 'Low' || value === 'None') {
89
+ return value;
90
+ }
91
+ return 'High';
92
+ }
93
+
94
+ /**
95
+ * StrengthIndicator renders three fixed-size, ascending bars that
96
+ * communicate a discrete confidence/strength level — typically used to
97
+ * signal model confidence, signal quality, or password strength.
98
+ *
99
+ * Sizes are intentionally fixed (matching the Figma spec): 3px-wide bars
100
+ * 6/9/12px tall with a 2px gap and 2px container padding.
101
+ *
102
+ * Pass a single `confidence` value (named enum *or* float `[0, 1]`); the
103
+ * component normalizes it to a level, maps that level to a per-bar
104
+ * confidence mode, and resolves each bar's color through design tokens
105
+ * (`strengthIndicator/bar/<size>/background`).
106
+ *
107
+ * @component
108
+ * @param {StrengthIndicatorProps} props
109
+ */
110
+ function StrengthIndicator({
111
+ confidence = 'High',
112
+ modes = _reactUtils.EMPTY_MODES,
113
+ style,
114
+ ...rest
115
+ }) {
116
+ const containerGap = (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/container/gap', modes) ?? 2;
117
+ const containerPadding = (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/container/padding', modes) ?? 2;
118
+ const barWidth = (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/bar/width', modes) ?? 3;
119
+ const barRadius = (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/bar/radius', modes) ?? 1;
120
+ const barHeights = {
121
+ small: (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/bar/height/small', modes) ?? 6,
122
+ medium: (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/bar/height/medium', modes) ?? 9,
123
+ large: (0, _figmaVariablesResolver.getVariableByName)('strengthIndicator/bar/height/large', modes) ?? 12
124
+ };
125
+ const resolvedLevel = resolveConfidence(confidence);
126
+ const perBarConfidence = CONFIDENCE_TO_BARS[resolvedLevel];
127
+ const containerStyle = {
128
+ flexDirection: 'row',
129
+ alignItems: 'flex-end',
130
+ gap: containerGap,
131
+ padding: containerPadding
132
+ };
133
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
134
+ style: [containerStyle, style],
135
+ accessibilityRole: "image",
136
+ accessibilityLabel: `Strength indicator: ${resolvedLevel} confidence`,
137
+ ...rest,
138
+ children: BAR_SIZES.map((size, index) => {
139
+ const barConfidence = perBarConfidence[index] ?? 'None';
140
+ const barModes = {
141
+ ...modes,
142
+ Confidence: barConfidence
143
+ };
144
+ const tokenColor = (0, _figmaVariablesResolver.getVariableByName)(`strengthIndicator/bar/${size}/background`, barModes);
145
+ const backgroundColor = tokenColor ?? FALLBACK_BAR_COLOR[barConfidence];
146
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
147
+ style: {
148
+ width: barWidth,
149
+ height: barHeights[size],
150
+ borderRadius: barRadius,
151
+ backgroundColor
152
+ }
153
+ }, size);
154
+ })
155
+ });
156
+ }
157
+ var _default = exports.default = StrengthIndicator;
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _reactUtils = require("../../utils/react-utils");
11
+ var _Button = _interopRequireDefault(require("../Button/Button"));
12
+ var _NavArrow = _interopRequireDefault(require("../NavArrow/NavArrow"));
13
+ var _StrengthIndicator = _interopRequireDefault(require("../StrengthIndicator/StrengthIndicator"));
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ /**
17
+ * SummaryTile composes a title (with an inline `StrengthIndicator`), a
18
+ * supporting description and an action slot into a compact horizontal row,
19
+ * commonly used at the top of dashboard cards (e.g. "Spending — know your
20
+ * spending and savings"). An optional trailing chevron and tile-level
21
+ * `onPress` handler turn the whole row into a navigational entry point.
22
+ *
23
+ * @component
24
+ * @param {SummaryTileProps} props
25
+ */
26
+ function SummaryTile({
27
+ title = 'Spending',
28
+ description = 'Know your spending and savings',
29
+ confidence = 'None',
30
+ chevron = false,
31
+ children,
32
+ onPress,
33
+ modes = _reactUtils.EMPTY_MODES,
34
+ style,
35
+ titleStyle,
36
+ descriptionStyle,
37
+ accessibilityLabel
38
+ }) {
39
+ const containerGap = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/gap', modes) ?? 8;
40
+ const containerPadding = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/padding', modes) ?? 0;
41
+ const contentGap = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/content/gap', modes) ?? 8;
42
+ const titleWrapGap = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/titleWrap/gap', modes) ?? 4;
43
+ const titleColor = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/title/color', modes) ?? '#0d0d0f';
44
+ const titleFontFamily = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/title/fontFamily', modes) ?? 'JioType Var';
45
+ const titleFontSize = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/title/fontSize', modes) ?? 16;
46
+ const titleFontWeight = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/title/fontWeight', modes) ?? 700;
47
+ const titleLineHeight = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/title/lineHeight', modes) ?? 18;
48
+ const descriptionColor = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/description/color', modes) ?? '#24262b';
49
+ const descriptionFontFamily = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/description/fontFamily', modes) ?? 'JioType Var';
50
+ const descriptionFontSize = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/description/fontSize', modes) ?? 12;
51
+ const descriptionFontWeight = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/description/fontWeight', modes) ?? 500;
52
+ const descriptionLineHeight = (0, _figmaVariablesResolver.getVariableByName)('summaryTile/description/lineHeight', modes) ?? 16;
53
+ const titleTextStyle = {
54
+ color: titleColor,
55
+ fontFamily: titleFontFamily,
56
+ fontSize: titleFontSize,
57
+ fontWeight: String(titleFontWeight),
58
+ lineHeight: titleLineHeight
59
+ };
60
+ const descriptionTextStyle = {
61
+ color: descriptionColor,
62
+ fontFamily: descriptionFontFamily,
63
+ fontSize: descriptionFontSize,
64
+ fontWeight: String(descriptionFontWeight),
65
+ lineHeight: descriptionLineHeight
66
+ };
67
+ const showIndicator = confidence !== null;
68
+
69
+ // When the entire tile is pressable, the default `Button` slot is
70
+ // suppressed so we don't render a `<button>` inside another `<button>`
71
+ // (which is invalid HTML and triggers a React hydration warning on
72
+ // web). Consumers can still pass an explicit non-button node via
73
+ // `children` if they want a visible affordance alongside `onPress`.
74
+ const isPressable = onPress != null;
75
+ const actionSlot = children !== undefined ? children !== null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
76
+ children: (0, _reactUtils.cloneChildrenWithModes)(children, modes)
77
+ }) : null : isPressable ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
78
+ label: "Button",
79
+ modes: {
80
+ 'AppearanceBrand': 'Secondary',
81
+ ...modes,
82
+ 'Button / Size': 'S'
83
+ }
84
+ });
85
+ const tileContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
86
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
87
+ style: {
88
+ flex: 1,
89
+ minWidth: 0,
90
+ flexDirection: 'column',
91
+ gap: contentGap,
92
+ alignItems: 'flex-start'
93
+ },
94
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
95
+ style: {
96
+ flexDirection: 'row',
97
+ alignItems: 'center',
98
+ gap: titleWrapGap,
99
+ width: '100%'
100
+ },
101
+ children: [title ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
102
+ style: [titleTextStyle, titleStyle],
103
+ numberOfLines: 1,
104
+ children: title
105
+ }) : null, showIndicator ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_StrengthIndicator.default, {
106
+ confidence: confidence,
107
+ modes: modes
108
+ }) : null]
109
+ }), description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
110
+ style: [descriptionTextStyle, descriptionStyle],
111
+ children: description
112
+ }) : null]
113
+ }), actionSlot != null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
114
+ style: {
115
+ flexDirection: 'row',
116
+ alignItems: 'center'
117
+ },
118
+ children: actionSlot
119
+ }) : null, chevron ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_NavArrow.default, {
120
+ direction: "Forward",
121
+ modes: modes
122
+ }) : null]
123
+ });
124
+ const containerLayoutStyle = {
125
+ flexDirection: 'row',
126
+ alignItems: 'center',
127
+ gap: containerGap,
128
+ padding: containerPadding,
129
+ width: '100%'
130
+ };
131
+ if (onPress) {
132
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
133
+ onPress: onPress,
134
+ accessibilityRole: "button",
135
+ accessibilityLabel: accessibilityLabel ?? title,
136
+ style: ({
137
+ pressed
138
+ }) => [containerLayoutStyle, style, pressed ? {
139
+ opacity: 0.7
140
+ } : null],
141
+ children: tileContent
142
+ });
143
+ }
144
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
145
+ style: [containerLayoutStyle, style],
146
+ accessibilityLabel: accessibilityLabel,
147
+ children: tileContent
148
+ });
149
+ }
150
+ var _default = exports.default = SummaryTile;