jfs-components 0.1.8 → 0.1.12

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 (238) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/lib/commonjs/components/Accordion/Accordion.js +2 -1
  3. package/lib/commonjs/components/AccordionCheckbox/AccordionCheckbox.js +4 -3
  4. package/lib/commonjs/components/AccountCard/AccountCard.js +4 -3
  5. package/lib/commonjs/components/AllocationComparisonChart/AllocationComparisonChart.js +9 -6
  6. package/lib/commonjs/components/AreaLineChart/AreaLineChart.js +11 -7
  7. package/lib/commonjs/components/Badge/Badge.js +47 -8
  8. package/lib/commonjs/components/BrandChip/BrandChip.js +3 -3
  9. package/lib/commonjs/components/Button/Button.js +2 -1
  10. package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -1
  11. package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +3 -2
  12. package/lib/commonjs/components/CardCTA/CardCTA.js +197 -27
  13. package/lib/commonjs/components/CardInsight/CardInsight.js +5 -1
  14. package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +7 -3
  15. package/lib/commonjs/components/CircularProgressBarDoted/CircularProgressBarDoted.js +3 -2
  16. package/lib/commonjs/components/CircularRating/CircularRating.js +2 -1
  17. package/lib/commonjs/components/ClusterBubble/ClusterBubble.js +3 -2
  18. package/lib/commonjs/components/CompareTable/CompareTable.js +72 -43
  19. package/lib/commonjs/components/CoverageBarComparison/CoverageBarComparison.js +3 -2
  20. package/lib/commonjs/components/DonutChart/DonutChart.js +4 -3
  21. package/lib/commonjs/components/Dropdown/Dropdown.js +3 -2
  22. package/lib/commonjs/components/DropdownInput/DropdownInput.js +3 -2
  23. package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
  24. package/lib/commonjs/components/FormField/FormField.js +42 -2
  25. package/lib/commonjs/components/Gauge/Gauge.js +1 -1
  26. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +3 -2
  27. package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +2 -1
  28. package/lib/commonjs/components/ListGroup/ListGroup.js +2 -1
  29. package/lib/commonjs/components/ListItem/ListItem.js +3 -2
  30. package/lib/commonjs/components/MediaCard/MediaCard.js +4 -2
  31. package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +3 -2
  32. package/lib/commonjs/components/MonthlyStatusGrid/MonthlyStatusGrid.js +6 -3
  33. package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +3 -2
  34. package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +107 -33
  35. package/lib/commonjs/components/ProductOverview/ProductOverview.js +4 -3
  36. package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +2 -2
  37. package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +3 -2
  38. package/lib/commonjs/components/Section/Section.js +3 -2
  39. package/lib/commonjs/components/Slider/Slider.js +3 -2
  40. package/lib/commonjs/components/Stack/Stack.js +86 -0
  41. package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
  42. package/lib/commonjs/components/SummaryTile/SummaryTile.js +3 -2
  43. package/lib/commonjs/components/Table/Table.js +324 -0
  44. package/lib/commonjs/components/Text/Text.js +2 -1
  45. package/lib/commonjs/components/TextInput/TextInput.js +9 -1
  46. package/lib/commonjs/components/TextSegment/TextSegment.js +2 -1
  47. package/lib/commonjs/components/ThreadHero/ThreadHero.js +4 -5
  48. package/lib/commonjs/components/Title/Title.js +2 -1
  49. package/lib/commonjs/components/Toast/Toast.js +3 -2
  50. package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +2 -1
  51. package/lib/commonjs/components/TransactionStatus/TransactionStatus.js +3 -2
  52. package/lib/commonjs/components/UpiHandle/UpiHandle.js +2 -2
  53. package/lib/commonjs/components/index.js +44 -0
  54. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  55. package/lib/commonjs/design-tokens/figma-modes.generated.js +1 -0
  56. package/lib/commonjs/icons/registry.js +1 -1
  57. package/lib/commonjs/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.js +11 -3
  58. package/lib/commonjs/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.js +8 -4
  59. package/lib/commonjs/utils/react-utils.js +56 -0
  60. package/lib/commonjs/utils/web-platform-utils.js +59 -0
  61. package/lib/module/components/Accordion/Accordion.js +3 -2
  62. package/lib/module/components/AccordionCheckbox/AccordionCheckbox.js +5 -4
  63. package/lib/module/components/AccountCard/AccountCard.js +5 -4
  64. package/lib/module/components/AllocationComparisonChart/AllocationComparisonChart.js +10 -7
  65. package/lib/module/components/AreaLineChart/AreaLineChart.js +12 -8
  66. package/lib/module/components/Badge/Badge.js +49 -10
  67. package/lib/module/components/BrandChip/BrandChip.js +4 -4
  68. package/lib/module/components/Button/Button.js +3 -2
  69. package/lib/module/components/CardAdvisory/CardAdvisory.js +3 -2
  70. package/lib/module/components/CardBankAccount/CardBankAccount.js +4 -3
  71. package/lib/module/components/CardCTA/CardCTA.js +198 -28
  72. package/lib/module/components/CardInsight/CardInsight.js +5 -1
  73. package/lib/module/components/CircularProgressBar/CircularProgressBar.js +8 -4
  74. package/lib/module/components/CircularProgressBarDoted/CircularProgressBarDoted.js +4 -3
  75. package/lib/module/components/CircularRating/CircularRating.js +3 -2
  76. package/lib/module/components/ClusterBubble/ClusterBubble.js +4 -3
  77. package/lib/module/components/CompareTable/CompareTable.js +73 -44
  78. package/lib/module/components/CoverageBarComparison/CoverageBarComparison.js +4 -3
  79. package/lib/module/components/DonutChart/DonutChart.js +5 -4
  80. package/lib/module/components/Dropdown/Dropdown.js +4 -3
  81. package/lib/module/components/DropdownInput/DropdownInput.js +4 -3
  82. package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
  83. package/lib/module/components/FormField/FormField.js +45 -5
  84. package/lib/module/components/Gauge/Gauge.js +1 -1
  85. package/lib/module/components/HoldingsCard/HoldingsCard.js +4 -3
  86. package/lib/module/components/InstitutionBadge/InstitutionBadge.js +3 -2
  87. package/lib/module/components/ListGroup/ListGroup.js +3 -2
  88. package/lib/module/components/ListItem/ListItem.js +4 -3
  89. package/lib/module/components/MediaCard/MediaCard.js +4 -2
  90. package/lib/module/components/MetricLegendItem/MetricLegendItem.js +4 -3
  91. package/lib/module/components/MonthlyStatusGrid/MonthlyStatusGrid.js +7 -4
  92. package/lib/module/components/PoweredByLabel/PoweredByLabel.js +4 -3
  93. package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +109 -35
  94. package/lib/module/components/ProductOverview/ProductOverview.js +5 -4
  95. package/lib/module/components/ProgressBadge/ProgressBadge.js +3 -3
  96. package/lib/module/components/ProjectionMarker/ProjectionMarker.js +4 -3
  97. package/lib/module/components/Section/Section.js +4 -3
  98. package/lib/module/components/Slider/Slider.js +4 -3
  99. package/lib/module/components/Stack/Stack.js +81 -0
  100. package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
  101. package/lib/module/components/SummaryTile/SummaryTile.js +4 -3
  102. package/lib/module/components/Table/Table.js +315 -0
  103. package/lib/module/components/Text/Text.js +3 -2
  104. package/lib/module/components/TextInput/TextInput.js +9 -1
  105. package/lib/module/components/TextSegment/TextSegment.js +3 -2
  106. package/lib/module/components/ThreadHero/ThreadHero.js +5 -6
  107. package/lib/module/components/Title/Title.js +3 -2
  108. package/lib/module/components/Toast/Toast.js +4 -3
  109. package/lib/module/components/TransactionBubble/TransactionBubble.js +3 -2
  110. package/lib/module/components/TransactionStatus/TransactionStatus.js +4 -3
  111. package/lib/module/components/UpiHandle/UpiHandle.js +3 -3
  112. package/lib/module/components/index.js +2 -0
  113. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  114. package/lib/module/design-tokens/figma-modes.generated.js +1 -0
  115. package/lib/module/icons/registry.js +1 -1
  116. package/lib/module/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.js +11 -3
  117. package/lib/module/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.js +8 -4
  118. package/lib/module/utils/react-utils.js +54 -0
  119. package/lib/module/utils/web-platform-utils.js +58 -0
  120. package/lib/typescript/src/components/Accordion/Accordion.d.ts +7 -1
  121. package/lib/typescript/src/components/AccordionCheckbox/AccordionCheckbox.d.ts +7 -1
  122. package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +7 -1
  123. package/lib/typescript/src/components/AllocationComparisonChart/AllocationComparisonChart.d.ts +7 -1
  124. package/lib/typescript/src/components/AreaLineChart/AreaLineChart.d.ts +8 -1
  125. package/lib/typescript/src/components/Badge/Badge.d.ts +32 -2
  126. package/lib/typescript/src/components/BrandChip/BrandChip.d.ts +7 -1
  127. package/lib/typescript/src/components/Button/Button.d.ts +7 -1
  128. package/lib/typescript/src/components/CardAdvisory/CardAdvisory.d.ts +7 -1
  129. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +7 -1
  130. package/lib/typescript/src/components/CardCTA/CardCTA.d.ts +27 -5
  131. package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +7 -1
  132. package/lib/typescript/src/components/CircularProgressBarDoted/CircularProgressBarDoted.d.ts +7 -1
  133. package/lib/typescript/src/components/CircularRating/CircularRating.d.ts +7 -1
  134. package/lib/typescript/src/components/ClusterBubble/ClusterBubble.d.ts +7 -1
  135. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +7 -1
  136. package/lib/typescript/src/components/CoverageBarComparison/CoverageBarComparison.d.ts +7 -1
  137. package/lib/typescript/src/components/DonutChart/DonutChart.d.ts +7 -1
  138. package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +7 -1
  139. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +6 -0
  140. package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +7 -1
  141. package/lib/typescript/src/components/HoldingsCard/HoldingsCard.d.ts +7 -1
  142. package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +7 -1
  143. package/lib/typescript/src/components/ListGroup/ListGroup.d.ts +7 -1
  144. package/lib/typescript/src/components/ListItem/ListItem.d.ts +7 -1
  145. package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +7 -1
  146. package/lib/typescript/src/components/MonthlyStatusGrid/MonthlyStatusGrid.d.ts +14 -2
  147. package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +7 -1
  148. package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +7 -1
  149. package/lib/typescript/src/components/ProductOverview/ProductOverview.d.ts +7 -1
  150. package/lib/typescript/src/components/ProgressBadge/ProgressBadge.d.ts +7 -1
  151. package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +7 -1
  152. package/lib/typescript/src/components/Section/Section.d.ts +7 -1
  153. package/lib/typescript/src/components/Slider/Slider.d.ts +6 -0
  154. package/lib/typescript/src/components/Stack/Stack.d.ts +81 -0
  155. package/lib/typescript/src/components/SummaryTile/SummaryTile.d.ts +7 -1
  156. package/lib/typescript/src/components/Table/Table.d.ts +139 -0
  157. package/lib/typescript/src/components/Text/Text.d.ts +7 -1
  158. package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +7 -1
  159. package/lib/typescript/src/components/ThreadHero/ThreadHero.d.ts +7 -1
  160. package/lib/typescript/src/components/Title/Title.d.ts +7 -1
  161. package/lib/typescript/src/components/Toast/Toast.d.ts +7 -1
  162. package/lib/typescript/src/components/TransactionBubble/TransactionBubble.d.ts +7 -1
  163. package/lib/typescript/src/components/TransactionStatus/TransactionStatus.d.ts +7 -1
  164. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +7 -1
  165. package/lib/typescript/src/components/index.d.ts +4 -2
  166. package/lib/typescript/src/icons/registry.d.ts +1 -1
  167. package/lib/typescript/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.d.ts +31 -3
  168. package/lib/typescript/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.d.ts +18 -2
  169. package/lib/typescript/src/utils/react-utils.d.ts +37 -0
  170. package/lib/typescript/src/utils/web-platform-utils.d.ts +36 -0
  171. package/package.json +1 -1
  172. package/src/components/Accordion/Accordion.tsx +9 -2
  173. package/src/components/AccordionCheckbox/AccordionCheckbox.tsx +10 -3
  174. package/src/components/AccountCard/AccountCard.tsx +10 -3
  175. package/src/components/AllocationComparisonChart/AllocationComparisonChart.tsx +14 -4
  176. package/src/components/AreaLineChart/AreaLineChart.tsx +15 -5
  177. package/src/components/Badge/Badge.tsx +78 -8
  178. package/src/components/BrandChip/BrandChip.tsx +9 -3
  179. package/src/components/Button/Button.tsx +9 -2
  180. package/src/components/CardAdvisory/CardAdvisory.tsx +9 -2
  181. package/src/components/CardBankAccount/CardBankAccount.tsx +9 -2
  182. package/src/components/CardCTA/CardCTA.tsx +214 -41
  183. package/src/components/CardInsight/CardInsight.tsx +7 -1
  184. package/src/components/CircularProgressBar/CircularProgressBar.tsx +14 -4
  185. package/src/components/CircularProgressBarDoted/CircularProgressBarDoted.tsx +10 -3
  186. package/src/components/CircularRating/CircularRating.tsx +9 -2
  187. package/src/components/ClusterBubble/ClusterBubble.tsx +9 -2
  188. package/src/components/CompareTable/CompareTable.tsx +98 -50
  189. package/src/components/CoverageBarComparison/CoverageBarComparison.tsx +9 -2
  190. package/src/components/DonutChart/DonutChart.tsx +10 -3
  191. package/src/components/Dropdown/Dropdown.tsx +9 -2
  192. package/src/components/DropdownInput/DropdownInput.tsx +9 -2
  193. package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +8 -1
  194. package/src/components/FormField/FormField.tsx +49 -4
  195. package/src/components/Gauge/Gauge.tsx +1 -1
  196. package/src/components/HoldingsCard/HoldingsCard.tsx +9 -2
  197. package/src/components/InstitutionBadge/InstitutionBadge.tsx +9 -2
  198. package/src/components/ListGroup/ListGroup.tsx +9 -2
  199. package/src/components/ListItem/ListItem.tsx +10 -3
  200. package/src/components/MediaCard/MediaCard.tsx +2 -2
  201. package/src/components/MetricLegendItem/MetricLegendItem.tsx +9 -2
  202. package/src/components/MonthlyStatusGrid/MonthlyStatusGrid.tsx +17 -2
  203. package/src/components/PoweredByLabel/PoweredByLabel.tsx +9 -2
  204. package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +104 -37
  205. package/src/components/ProductOverview/ProductOverview.tsx +10 -3
  206. package/src/components/ProgressBadge/ProgressBadge.tsx +9 -3
  207. package/src/components/ProjectionMarker/ProjectionMarker.tsx +9 -2
  208. package/src/components/Section/Section.tsx +10 -3
  209. package/src/components/Slider/Slider.tsx +9 -2
  210. package/src/components/Stack/Stack.tsx +131 -0
  211. package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +10 -1
  212. package/src/components/SummaryTile/SummaryTile.tsx +9 -2
  213. package/src/components/Table/Table.tsx +449 -0
  214. package/src/components/Text/Text.tsx +9 -2
  215. package/src/components/TextInput/TextInput.tsx +7 -1
  216. package/src/components/TextSegment/TextSegment.tsx +9 -2
  217. package/src/components/ThreadHero/ThreadHero.tsx +10 -3
  218. package/src/components/Title/Title.tsx +9 -2
  219. package/src/components/Toast/Toast.tsx +9 -2
  220. package/src/components/TransactionBubble/TransactionBubble.tsx +9 -2
  221. package/src/components/TransactionStatus/TransactionStatus.tsx +9 -2
  222. package/src/components/UpiHandle/UpiHandle.tsx +9 -3
  223. package/src/components/index.ts +23 -2
  224. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  225. package/src/design-tokens/figma-modes.generated.ts +1 -0
  226. package/src/icons/registry.ts +1 -1
  227. package/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.tsx +32 -3
  228. package/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.tsx +25 -4
  229. package/src/utils/react-utils.ts +61 -0
  230. package/src/utils/web-platform-utils.ts +68 -0
  231. package/lib/commonjs/components/MediaCard/GlassFill.js +0 -62
  232. package/lib/commonjs/components/MediaCard/GlassFill.web.js +0 -48
  233. package/lib/module/components/MediaCard/GlassFill.js +0 -57
  234. package/lib/module/components/MediaCard/GlassFill.web.js +0 -43
  235. package/lib/typescript/src/components/MediaCard/GlassFill.d.ts +0 -47
  236. package/lib/typescript/src/components/MediaCard/GlassFill.web.d.ts +0 -20
  237. package/src/components/MediaCard/GlassFill.tsx +0 -89
  238. package/src/components/MediaCard/GlassFill.web.tsx +0 -53
@@ -3,7 +3,7 @@
3
3
  import React, { useMemo } from 'react';
4
4
  import { View, Text } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils';
7
7
  import Badge from '../Badge/Badge';
8
8
  import Button from '../Button/Button';
9
9
  import InstitutionBadge from '../InstitutionBadge/InstitutionBadge';
@@ -66,7 +66,8 @@ function CardBankAccount({
66
66
  footer,
67
67
  modes: propModes = EMPTY_MODES,
68
68
  style,
69
- accessibilityLabel
69
+ accessibilityLabel,
70
+ disableTruncation
70
71
  }) {
71
72
  // Merge caller modes on top of `DEFAULT_MODES` so every default key
72
73
  // (e.g. `Button / Size`, `AppearanceBrand`, `Emphasis`) can be overridden
@@ -183,7 +184,7 @@ function CardBankAccount({
183
184
  })
184
185
  }), typeof item.value === 'string' || typeof item.value === 'number' ? /*#__PURE__*/_jsx(Text, {
185
186
  style: valueTextStyle,
186
- numberOfLines: 1,
187
+ ...resolveTruncation(disableTruncation, 1),
187
188
  children: item.value
188
189
  }) : cloneChildrenWithModes(item.value, modes)]
189
190
  }, `${item.label}-${index}`))
@@ -10,8 +10,17 @@ import Button from '../Button/Button';
10
10
  import Badge from '../Badge/Badge';
11
11
  import ButtonGroup from '../ButtonGroup/ButtonGroup';
12
12
  import IconButton from '../IconButton/IconButton';
13
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import Avatar from '../Avatar/Avatar';
14
+
15
+ /**
16
+ * Accepted `type` values. The canonical (and historical) values are lowercase
17
+ * (`'cta' | 'rating' | 'sip'`). The Figma variant names are PascalCase
18
+ * (`'CTA' | 'Rating' | 'Sip'`) — we accept those too and normalize internally
19
+ * so callers can pass either casing without a breaking change.
20
+ */
21
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
22
  const optionalTokenAvailability = new Map();
23
+ const toWeight = w => typeof w === 'number' ? `${w}` : w;
15
24
  function getOptionalVariableByName(name, modes, fallback) {
16
25
  let isAvailable = optionalTokenAvailability.get(name);
17
26
  if (isAvailable === undefined) {
@@ -34,11 +43,16 @@ function CardCTA({
34
43
  showRatingActions = true,
35
44
  onPressLike,
36
45
  onPressDislike,
46
+ headline = 'Headline',
47
+ description = 'Description',
48
+ subtitle = 'Subtitle',
49
+ avatarSource,
37
50
  modes: propModes = EMPTY_MODES,
38
51
  iconSlot,
39
52
  buttonSlot,
40
53
  ratingBadgeSlot,
41
54
  ratingActionsSlot,
55
+ avatarSlot,
42
56
  style
43
57
  }) {
44
58
  const {
@@ -48,7 +62,10 @@ function CardCTA({
48
62
  ...globalModes,
49
63
  ...propModes
50
64
  };
51
- const isRating = type === 'rating';
65
+ // Accept both lowercase (canonical) and Figma PascalCase variant names.
66
+ const normalizedType = typeof type === 'string' ? type.toLowerCase() : 'cta';
67
+ const isRating = normalizedType === 'rating';
68
+ const isSip = normalizedType === 'sip';
52
69
  const background = getVariableByName('cardCTA/background', modes) || '#ffffff';
53
70
  const radius = getVariableByName('cardCTA/radius', modes) || 12;
54
71
  const borderSize = getVariableByName('cardCTA/border/size', modes) || 1;
@@ -62,13 +79,13 @@ function CardCTA({
62
79
  const titleColor = getVariableByName('cardCTA/title/color', modes) || '#0c0d10';
63
80
  const titleFontFamily = getVariableByName('cardCTA/title/fontFamily', modes) || 'JioType Var';
64
81
  const titleFontSize = getVariableByName('cardCTA/title/fontSize', modes) || 16;
65
- const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) || 17.6;
82
+ const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) || 18;
66
83
  const titleFontWeightRaw = getVariableByName('cardCTA/title/fontWeight', modes) || 700;
67
84
  const titleFontWeight = typeof titleFontWeightRaw === 'number' ? titleFontWeightRaw.toString() : titleFontWeightRaw;
68
85
  const bodyColor = getVariableByName('cardCTA/body/color', modes) || '#13002d';
69
86
  const bodyFontFamily = getVariableByName('cardCTA/body/fontFamily', modes) || 'JioType Var';
70
- const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) || 10;
71
- const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) || 12;
87
+ const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) || 14;
88
+ const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) || 17;
72
89
  const bodyFontWeightRaw = getVariableByName('cardCTA/body/fontWeight', modes) || 400;
73
90
  const bodyFontWeight = typeof bodyFontWeightRaw === 'number' ? bodyFontWeightRaw.toString() : bodyFontWeightRaw;
74
91
  const ratingContentGap = getOptionalVariableByName('cardCTA/rating/content/gap', modes, 12);
@@ -77,6 +94,33 @@ function CardCTA({
77
94
  const ratingFooterPaddingH = getOptionalVariableByName('cardCTA/rating/footer/horizontal', modes, 16);
78
95
  const ratingFooterPaddingTop = getOptionalVariableByName('cardCTA/rating/footer/top', modes, 0);
79
96
  const ratingFooterPaddingBottom = getOptionalVariableByName('cardCTA/rating/footer/bottom', modes, 12);
97
+
98
+ // Sip variant footer text block (Headline / Description / Subtitle). These
99
+ // `ccCard/*` tokens were introduced for the Sip layout — resolve them
100
+ // optionally so older token snapshots that lack them fall back gracefully.
101
+ const sipFooterGap = getOptionalVariableByName('ccCard/footer/textWrap/gap', modes, 4);
102
+ const sipHeadlineColor = getOptionalVariableByName('ccCard/headline/color', modes, '#707275');
103
+ const sipHeadlineFontFamily = getOptionalVariableByName('ccCard/headline/fontFamily', modes, 'JioType Var');
104
+ const sipHeadlineFontSize = getOptionalVariableByName('ccCard/headline/fontSize', modes, 10);
105
+ const sipHeadlineLineHeight = getOptionalVariableByName('ccCard/headline/lineHeight', modes, 13);
106
+ const sipHeadlineFontWeightRaw = getOptionalVariableByName('ccCard/headline/fontWeight', modes, 500);
107
+ const sipHeadlineFontWeight = typeof sipHeadlineFontWeightRaw === 'number' ? sipHeadlineFontWeightRaw.toString() : sipHeadlineFontWeightRaw;
108
+ const sipDescriptionColor = getOptionalVariableByName('ccCard/title/color', modes, '#081007');
109
+ const sipDescriptionFontFamily = getOptionalVariableByName('ccCard/title/fontFamily', modes, 'JioType Var');
110
+ const sipDescriptionFontSize = getOptionalVariableByName('ccCard/title/fontSize', modes, 14);
111
+ const sipDescriptionLineHeight = getOptionalVariableByName('ccCard/title/lineHeight', modes, 15);
112
+ const sipDescriptionFontWeightRaw = getOptionalVariableByName('ccCard/title/fontWeight', modes, 700);
113
+ const sipDescriptionFontWeight = typeof sipDescriptionFontWeightRaw === 'number' ? sipDescriptionFontWeightRaw.toString() : sipDescriptionFontWeightRaw;
114
+ const sipSubtitleColor = getOptionalVariableByName('ccCard/subtitle/color', modes, '#707275');
115
+ const sipSubtitleFontFamily = getOptionalVariableByName('ccCard/subtitle/fontFamily', modes, 'JioType Var');
116
+ const sipSubtitleFontSize = getOptionalVariableByName('ccCard/subtitle/fontSize', modes, 10);
117
+ const sipSubtitleLineHeight = getOptionalVariableByName('ccCard/subtitle/lineHeight', modes, 13);
118
+ const sipSubtitleFontWeightRaw = getOptionalVariableByName('ccCard/subtitle/fontWeight', modes, 500);
119
+ const sipSubtitleFontWeight = typeof sipSubtitleFontWeightRaw === 'number' ? sipSubtitleFontWeightRaw.toString() : sipSubtitleFontWeightRaw;
120
+ const avatarModes = {
121
+ ...modes,
122
+ 'Avatar Size': 'L'
123
+ };
80
124
  const buttonModes = {
81
125
  ...modes,
82
126
  AppearanceBrand: 'Secondary',
@@ -93,25 +137,72 @@ function CardCTA({
93
137
  const [measuredButtonLabelWidth, setMeasuredButtonLabelWidth] = React.useState(null);
94
138
  const buttonPaddingH = getVariableByName('button/padding/horizontal', buttonModes) || 20;
95
139
  const buttonBorderSize = getVariableByName('button/border/size', buttonModes) ?? 1;
96
- const measuredButtonWidth = measuredButtonLabelWidth === null ? undefined : Math.ceil(measuredButtonLabelWidth + buttonPaddingH * 2 + buttonBorderSize * 2);
97
- const handleButtonLabelTextLayout = React.useCallback(event => {
98
- const lines = event?.nativeEvent?.lines;
99
- if (!Array.isArray(lines) || lines.length === 0) return;
100
- const nextWidth = Math.ceil(lines.reduce((sum, line) => sum + (typeof line?.width === 'number' ? line.width : 0), 0));
101
- if (nextWidth <= 0) return;
102
- setMeasuredButtonLabelWidth(currentWidth => {
103
- if (currentWidth !== null && Math.abs(currentWidth - nextWidth) < 1) {
104
- return currentWidth;
105
- }
106
- return nextWidth;
107
- });
140
+ // Small safety pad so sub-pixel rounding between the measure pass and the
141
+ // rendered glyph run can never clip the final character.
142
+ const measuredButtonWidth = measuredButtonLabelWidth === null ? undefined : Math.ceil(measuredButtonLabelWidth + buttonPaddingH * 2 + buttonBorderSize * 2 + 2);
143
+
144
+ // ROOT-CAUSE FIX for the Android "jumping button" feedback loop + clipping.
145
+ //
146
+ // Previously the *visible* label measured itself via `onTextLayout` and we
147
+ // fed that width straight back onto the same Button. Because the button is
148
+ // width-constrained by its parent, Android clamps the overflowing text and
149
+ // even character-breaks a single word ("Save" -> "Sav"/"e"); the re-applied
150
+ // width re-triggers layout, producing an endless ~60fps width oscillation.
151
+ //
152
+ // We now measure an *off-screen* copy of the label, laid out at an
153
+ // effectively unbounded width, so its reported single-line width is
154
+ // intrinsic and constant regardless of the button's applied width — the
155
+ // measurement can no longer depend on the value it produces, so the loop is
156
+ // impossible. Crucially the measurer reuses the Button's own resolved label
157
+ // styles (passed into `renderContent`), so the measured font matches the
158
+ // rendered font exactly and the width is never an under-estimate. The label
159
+ // is always a single line that overflows rather than wraps or truncates.
160
+ const handleMeasureTextLayout = React.useCallback(event => {
161
+ const line = event?.nativeEvent?.lines?.[0];
162
+ const width = line && typeof line.width === 'number' ? line.width : 0;
163
+ if (width <= 0) return;
164
+ setMeasuredButtonLabelWidth(currentWidth => currentWidth !== null && Math.abs(currentWidth - width) < 0.5 ? currentWidth : Math.ceil(width));
108
165
  }, []);
166
+
167
+ // Off-screen measurer wrapper: absolute + opacity 0 + pointerEvents none =>
168
+ // out of flow, invisible, never intercepts touches, zero layout impact.
169
+ const measurerWrapStyle = {
170
+ position: 'absolute',
171
+ left: 0,
172
+ top: 0,
173
+ opacity: 0
174
+ };
175
+
176
+ // Renders the visible single-line label (never wraps, never ellipsizes) plus
177
+ // the co-located off-screen measurer that shares the Button's exact label
178
+ // styles. `width: 9999` forces the measurer onto one line so `onTextLayout`
179
+ // reports the true intrinsic width.
180
+ const renderButtonContent = labelExtraStyle => labelStyles => /*#__PURE__*/_jsxs(_Fragment, {
181
+ children: [/*#__PURE__*/_jsx(Text, {
182
+ numberOfLines: 1,
183
+ ellipsizeMode: "clip",
184
+ style: [labelStyles, labelExtraStyle],
185
+ children: nonWrappingButtonLabel
186
+ }), /*#__PURE__*/_jsx(View, {
187
+ pointerEvents: "none",
188
+ accessibilityElementsHidden: true,
189
+ importantForAccessibility: "no",
190
+ style: measurerWrapStyle,
191
+ children: /*#__PURE__*/_jsx(Text, {
192
+ style: [labelStyles, {
193
+ width: 9999
194
+ }],
195
+ onTextLayout: handleMeasureTextLayout,
196
+ children: nonWrappingButtonLabel
197
+ })
198
+ })]
199
+ });
109
200
  const containerStyle = {
110
201
  backgroundColor: background,
111
202
  borderRadius: radius,
112
203
  borderWidth: borderSize,
113
204
  borderColor,
114
- flexDirection: isRating ? 'column' : 'row',
205
+ flexDirection: isRating || isSip ? 'column' : 'row',
115
206
  overflow: 'visible'
116
207
  };
117
208
 
@@ -197,6 +288,47 @@ function CardCTA({
197
288
  lineHeight: bodyLineHeight,
198
289
  fontWeight: bodyFontWeight
199
290
  };
291
+ const sipWrapStyle = {
292
+ width: '100%',
293
+ paddingHorizontal: leftPaddingH,
294
+ paddingVertical: leftPaddingV,
295
+ gap: leftGap,
296
+ alignItems: 'flex-start',
297
+ justifyContent: 'flex-start',
298
+ overflow: 'visible'
299
+ };
300
+ const sipFooterTextWrapStyle = {
301
+ gap: sipFooterGap,
302
+ alignItems: 'flex-start',
303
+ alignSelf: 'stretch',
304
+ minWidth: 0
305
+ };
306
+ const sipDescriptionWrapStyle = {
307
+ flexDirection: 'row',
308
+ gap: sipFooterGap,
309
+ alignItems: 'flex-end'
310
+ };
311
+ const sipHeadlineStyle = {
312
+ color: sipHeadlineColor,
313
+ fontFamily: sipHeadlineFontFamily,
314
+ fontSize: sipHeadlineFontSize,
315
+ lineHeight: sipHeadlineLineHeight,
316
+ fontWeight: toWeight(sipHeadlineFontWeightRaw)
317
+ };
318
+ const sipDescriptionStyle = {
319
+ color: sipDescriptionColor,
320
+ fontFamily: sipDescriptionFontFamily,
321
+ fontSize: sipDescriptionFontSize,
322
+ lineHeight: sipDescriptionLineHeight,
323
+ fontWeight: toWeight(sipDescriptionFontWeightRaw)
324
+ };
325
+ const sipSubtitleStyle = {
326
+ color: sipSubtitleColor,
327
+ fontFamily: sipSubtitleFontFamily,
328
+ fontSize: sipSubtitleFontSize,
329
+ lineHeight: sipSubtitleLineHeight,
330
+ fontWeight: toWeight(sipSubtitleFontWeightRaw)
331
+ };
200
332
  const ratingContentStyle = {
201
333
  paddingHorizontal: ratingContentPaddingH,
202
334
  paddingVertical: ratingContentPaddingV,
@@ -243,6 +375,52 @@ function CardCTA({
243
375
  flexShrink: 0,
244
376
  flexWrap: 'nowrap'
245
377
  };
378
+ if (isSip) {
379
+ return /*#__PURE__*/_jsx(View, {
380
+ style: [containerStyle, style],
381
+ children: /*#__PURE__*/_jsxs(View, {
382
+ style: sipWrapStyle,
383
+ children: [avatarSlot ? cloneChildrenWithModes(avatarSlot, avatarModes) : /*#__PURE__*/_jsx(Avatar, {
384
+ style: "Image",
385
+ imageSource: avatarSource,
386
+ modes: avatarModes
387
+ }), /*#__PURE__*/_jsxs(View, {
388
+ style: textWrapStyle,
389
+ children: [/*#__PURE__*/_jsx(Text, {
390
+ style: titleStyle,
391
+ children: title
392
+ }), /*#__PURE__*/_jsx(Text, {
393
+ style: bodyStyle,
394
+ children: body
395
+ })]
396
+ }), /*#__PURE__*/_jsxs(View, {
397
+ style: sipFooterTextWrapStyle,
398
+ children: [/*#__PURE__*/_jsx(Text, {
399
+ style: sipHeadlineStyle,
400
+ children: headline
401
+ }), /*#__PURE__*/_jsxs(View, {
402
+ style: sipDescriptionWrapStyle,
403
+ children: [/*#__PURE__*/_jsx(Text, {
404
+ style: sipDescriptionStyle,
405
+ children: description
406
+ }), /*#__PURE__*/_jsx(Text, {
407
+ style: sipSubtitleStyle,
408
+ children: subtitle
409
+ })]
410
+ })]
411
+ }), /*#__PURE__*/_jsx(View, {
412
+ style: buttonWrapStyle,
413
+ children: buttonSlot ? cloneChildrenWithModes(buttonSlot, buttonModes) : /*#__PURE__*/_jsx(Button, {
414
+ label: effectiveButtonLabel,
415
+ onPress: onPressButton || (() => {}),
416
+ modes: buttonModes,
417
+ style: buttonStyle,
418
+ renderContent: renderButtonContent(buttonLabelStyle)
419
+ })
420
+ })]
421
+ })
422
+ });
423
+ }
246
424
  if (isRating) {
247
425
  return /*#__PURE__*/_jsxs(View, {
248
426
  style: [containerStyle, style],
@@ -270,11 +448,7 @@ function CardCTA({
270
448
  onPress: onPressButton || (() => {}),
271
449
  modes: buttonModes,
272
450
  style: ratingButtonStyle,
273
- renderContent: labelStyles => /*#__PURE__*/_jsx(Text, {
274
- onTextLayout: handleButtonLabelTextLayout,
275
- style: [labelStyles, ratingButtonLabelStyle],
276
- children: nonWrappingButtonLabel
277
- })
451
+ renderContent: renderButtonContent(ratingButtonLabelStyle)
278
452
  })
279
453
  }), showRatingActions ? ratingActionsSlot ? cloneChildrenWithModes(ratingActionsSlot, iconButtonModes) : /*#__PURE__*/_jsxs(ButtonGroup, {
280
454
  modes: iconButtonModes,
@@ -315,11 +489,7 @@ function CardCTA({
315
489
  onPress: onPressButton || (() => {}),
316
490
  modes: buttonModes,
317
491
  style: buttonStyle,
318
- renderContent: labelStyles => /*#__PURE__*/_jsx(Text, {
319
- onTextLayout: handleButtonLabelTextLayout,
320
- style: [labelStyles, buttonLabelStyle],
321
- children: nonWrappingButtonLabel
322
- })
492
+ renderContent: renderButtonContent(buttonLabelStyle)
323
493
  })
324
494
  })]
325
495
  }), /*#__PURE__*/_jsx(View, {
@@ -31,7 +31,9 @@ function CardInsight({
31
31
  style
32
32
  }) {
33
33
  const background = getVariableByName('cardInsight/background', modes) ?? '#ffffff';
34
- const radius = getVariableByName('cardInsight/radius', modes) ?? 16;
34
+ const radius = getVariableByName('cardInsight/radius', modes) ?? 12;
35
+ const borderWidth = getVariableByName('cardInsight/borderWidth', modes) ?? 1;
36
+ const borderColor = getVariableByName('cardInsight/border/color', modes) ?? '#ffffff';
35
37
  const paddingHorizontal = getVariableByName('cardInsight/padding/horizontal', modes) ?? 12;
36
38
  const paddingVertical = getVariableByName('cardInsight/padding/vertical', modes) ?? 16;
37
39
  const gap = getVariableByName('cardInsight/gap', modes) ?? 12;
@@ -104,6 +106,8 @@ function CardInsight({
104
106
  width,
105
107
  backgroundColor: background,
106
108
  borderRadius: radius,
109
+ borderWidth,
110
+ borderColor,
107
111
  paddingHorizontal,
108
112
  paddingVertical,
109
113
  gap,
@@ -5,7 +5,7 @@ import { StyleSheet, Text, View } from 'react-native';
5
5
  import Svg, { Circle } from 'react-native-svg';
6
6
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
7
7
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
8
- import { EMPTY_MODES } from '../../utils/react-utils';
8
+ import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
9
9
  import { IconMinus } from '../../icons/components/IconMinus';
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  const STROKE_WIDTH_RATIO = 8 / 60;
@@ -30,8 +30,11 @@ const toFontWeight = (value, fallback) => {
30
30
  return fallback;
31
31
  };
32
32
  const getStrokeColor = (style, fallback) => {
33
+ // `StyleSheet.flatten(undefined)` returns `undefined`, so guard before
34
+ // reading `backgroundColor` — otherwise omitting the optional style prop
35
+ // crashes with "Cannot read property 'backgroundColor' of undefined".
33
36
  const flattened = StyleSheet.flatten(style);
34
- return typeof flattened.backgroundColor === 'string' ? flattened.backgroundColor : fallback;
37
+ return typeof flattened?.backgroundColor === 'string' ? flattened.backgroundColor : fallback;
35
38
  };
36
39
  function CircularProgressBar({
37
40
  value = 70,
@@ -45,6 +48,7 @@ function CircularProgressBar({
45
48
  valueStyle,
46
49
  supportTextStyle,
47
50
  accessibilityLabel,
51
+ disableTruncation,
48
52
  ...rest
49
53
  }) {
50
54
  const {
@@ -169,11 +173,11 @@ function CircularProgressBar({
169
173
  pointerEvents: "none",
170
174
  children: [hasSupportText ? /*#__PURE__*/_jsx(Text, {
171
175
  style: [computedSupportTextStyle, supportTextStyle],
172
- numberOfLines: 1,
176
+ ...resolveTruncation(disableTruncation, 1),
173
177
  children: supportText
174
178
  }) : null, /*#__PURE__*/_jsx(Text, {
175
179
  style: [computedValueStyle, valueStyle],
176
- numberOfLines: 1,
180
+ ...resolveTruncation(disableTruncation, 1),
177
181
  children: displayValue
178
182
  })]
179
183
  }) : /*#__PURE__*/_jsx(IconMinus, {
@@ -4,7 +4,7 @@ import React, { useMemo, useState } from 'react';
4
4
  import { Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
- import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils';
8
8
  import { IconChevronright } from '../../icons/components/IconChevronright';
9
9
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const DEFAULT_DOT_COUNT = 24;
@@ -31,7 +31,7 @@ const toFontWeight = (value, fallback) => {
31
31
  };
32
32
  const getBackgroundColor = (style, fallback) => {
33
33
  const flattened = StyleSheet.flatten(style);
34
- return typeof flattened.backgroundColor === 'string' ? flattened.backgroundColor : fallback;
34
+ return flattened && typeof flattened.backgroundColor === 'string' ? flattened.backgroundColor : fallback;
35
35
  };
36
36
  function CircularProgressBarDoted({
37
37
  value = 72,
@@ -54,6 +54,7 @@ function CircularProgressBarDoted({
54
54
  scoreLabelStyle,
55
55
  tierLabelStyle,
56
56
  accessibilityLabel,
57
+ disableTruncation,
57
58
  onLayout,
58
59
  ...rest
59
60
  }) {
@@ -188,7 +189,7 @@ function CircularProgressBarDoted({
188
189
  };
189
190
  const trendContent = /*#__PURE__*/_jsxs(_Fragment, {
190
191
  children: [/*#__PURE__*/_jsx(Text, {
191
- numberOfLines: 1,
192
+ ...resolveTruncation(disableTruncation, 1),
192
193
  style: [computedTierLabelStyle, tierLabelStyle],
193
194
  children: tierLabel
194
195
  }), showChevron ? /*#__PURE__*/_jsx(IconChevronright, {
@@ -5,7 +5,7 @@ import { Text, View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
7
  import Icon from '../../icons/Icon';
8
- import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
+ import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils';
9
9
  import CircularProgressBarDoted from '../CircularProgressBarDoted/CircularProgressBarDoted';
10
10
  import Nudge from '../Nudge/Nudge';
11
11
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
@@ -90,6 +90,7 @@ function CircularRating({
90
90
  footerTextStyle,
91
91
  nudgeStyle,
92
92
  accessibilityLabel,
93
+ disableTruncation,
93
94
  ...rest
94
95
  }) {
95
96
  const {
@@ -129,7 +130,7 @@ function CircularRating({
129
130
  style: [tokens.footerStyle, footerStyle],
130
131
  children: processedFooterSlot || /*#__PURE__*/_jsxs(_Fragment, {
131
132
  children: [/*#__PURE__*/_jsx(Text, {
132
- numberOfLines: 1,
133
+ ...resolveTruncation(disableTruncation, 1),
133
134
  style: [tokens.footerTextStyle, footerTextStyle],
134
135
  children: footerText
135
136
  }), showFooterIcon ? /*#__PURE__*/_jsx(Icon, {
@@ -4,7 +4,7 @@ import React, { useMemo, useState } from 'react';
4
4
  import { Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
7
- import { EMPTY_MODES } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
8
8
 
9
9
  /** Where the value/label text sits relative to the circle. */
10
10
 
@@ -83,7 +83,8 @@ function ClusterBubble({
83
83
  circleStyle,
84
84
  style,
85
85
  modes: propModes = EMPTY_MODES,
86
- accessibilityLabel
86
+ accessibilityLabel,
87
+ disableTruncation
87
88
  }) {
88
89
  const {
89
90
  modes: globalModes
@@ -130,7 +131,7 @@ function ClusterBubble({
130
131
  if (typeof node === 'string' || typeof node === 'number') {
131
132
  return /*#__PURE__*/_jsx(Text, {
132
133
  style: [baseStyle, override],
133
- numberOfLines: 2,
134
+ ...resolveTruncation(disableTruncation, 2),
134
135
  children: node
135
136
  });
136
137
  }