jfs-components 0.1.2 → 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 (287) hide show
  1. package/CHANGELOG.md +45 -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/AmountInput/AmountInput.js +8 -5
  7. package/lib/commonjs/components/AreaLineChart/AreaLineChart.js +11 -7
  8. package/lib/commonjs/components/Badge/Badge.js +47 -8
  9. package/lib/commonjs/components/BenefitCard/BenefitCard.js +231 -0
  10. package/lib/commonjs/components/BrandChip/BrandChip.js +3 -3
  11. package/lib/commonjs/components/Button/Button.js +2 -1
  12. package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -1
  13. package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +3 -2
  14. package/lib/commonjs/components/CardCTA/CardCTA.js +197 -27
  15. package/lib/commonjs/components/CardInsight/CardInsight.js +5 -1
  16. package/lib/commonjs/components/CcCard/CcCard.js +470 -0
  17. package/lib/commonjs/components/Checkbox/Checkbox.js +4 -3
  18. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +4 -3
  19. package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +7 -3
  20. package/lib/commonjs/components/CircularProgressBarDoted/CircularProgressBarDoted.js +3 -2
  21. package/lib/commonjs/components/CircularRating/CircularRating.js +2 -1
  22. package/lib/commonjs/components/ClusterBubble/ClusterBubble.js +3 -2
  23. package/lib/commonjs/components/CompareTable/CompareTable.js +401 -0
  24. package/lib/commonjs/components/ComparisonBar/ComparisonBar.js +266 -0
  25. package/lib/commonjs/components/CoverageBarComparison/CoverageBarComparison.js +3 -2
  26. package/lib/commonjs/components/DonutChart/DonutChart.js +4 -3
  27. package/lib/commonjs/components/Dropdown/Dropdown.js +3 -2
  28. package/lib/commonjs/components/DropdownInput/DropdownInput.js +38 -5
  29. package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
  30. package/lib/commonjs/components/FormField/FormField.js +45 -4
  31. package/lib/commonjs/components/Gauge/Gauge.js +1 -1
  32. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +3 -2
  33. package/lib/commonjs/components/InputSearch/InputSearch.js +6 -4
  34. package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +2 -1
  35. package/lib/commonjs/components/ListGroup/ListGroup.js +2 -1
  36. package/lib/commonjs/components/ListItem/ListItem.js +3 -2
  37. package/lib/commonjs/components/MediaCard/MediaCard.js +4 -2
  38. package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +3 -2
  39. package/lib/commonjs/components/MonthlyStatusGrid/MonthlyStatusGrid.js +6 -3
  40. package/lib/commonjs/components/NoteInput/NoteInput.js +6 -5
  41. package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +273 -0
  42. package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +3 -2
  43. package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +427 -0
  44. package/lib/commonjs/components/ProductOverview/ProductOverview.js +4 -3
  45. package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +2 -2
  46. package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +162 -0
  47. package/lib/commonjs/components/Radio/Radio.js +5 -5
  48. package/lib/commonjs/components/Section/Section.js +3 -2
  49. package/lib/commonjs/components/Slider/Slider.js +474 -0
  50. package/lib/commonjs/components/Stack/Stack.js +86 -0
  51. package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
  52. package/lib/commonjs/components/SummaryTile/SummaryTile.js +3 -2
  53. package/lib/commonjs/components/Table/Table.js +324 -0
  54. package/lib/commonjs/components/Text/Text.js +2 -1
  55. package/lib/commonjs/components/TextInput/TextInput.js +22 -9
  56. package/lib/commonjs/components/TextSegment/TextSegment.js +119 -0
  57. package/lib/commonjs/components/ThreadHero/ThreadHero.js +4 -5
  58. package/lib/commonjs/components/Title/Title.js +2 -1
  59. package/lib/commonjs/components/Toast/Toast.js +3 -2
  60. package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +2 -1
  61. package/lib/commonjs/components/TransactionStatus/TransactionStatus.js +3 -2
  62. package/lib/commonjs/components/UpiHandle/UpiHandle.js +2 -2
  63. package/lib/commonjs/components/index.js +107 -0
  64. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  65. package/lib/commonjs/design-tokens/figma-modes.generated.js +39 -9
  66. package/lib/commonjs/icons/registry.js +1 -1
  67. package/lib/commonjs/utils/GlassFill/GlassFill.js +271 -0
  68. package/lib/commonjs/utils/GlassFill/GlassFill.web.js +120 -0
  69. package/lib/commonjs/utils/react-utils.js +78 -0
  70. package/lib/commonjs/utils/web-platform-utils.js +59 -0
  71. package/lib/module/components/Accordion/Accordion.js +3 -2
  72. package/lib/module/components/AccordionCheckbox/AccordionCheckbox.js +5 -4
  73. package/lib/module/components/AccountCard/AccountCard.js +5 -4
  74. package/lib/module/components/AllocationComparisonChart/AllocationComparisonChart.js +10 -7
  75. package/lib/module/components/AmountInput/AmountInput.js +6 -4
  76. package/lib/module/components/AreaLineChart/AreaLineChart.js +12 -8
  77. package/lib/module/components/Badge/Badge.js +49 -10
  78. package/lib/module/components/BenefitCard/BenefitCard.js +225 -0
  79. package/lib/module/components/BrandChip/BrandChip.js +4 -4
  80. package/lib/module/components/Button/Button.js +3 -2
  81. package/lib/module/components/CardAdvisory/CardAdvisory.js +3 -2
  82. package/lib/module/components/CardBankAccount/CardBankAccount.js +4 -3
  83. package/lib/module/components/CardCTA/CardCTA.js +198 -28
  84. package/lib/module/components/CardInsight/CardInsight.js +5 -1
  85. package/lib/module/components/CcCard/CcCard.js +464 -0
  86. package/lib/module/components/Checkbox/Checkbox.js +5 -4
  87. package/lib/module/components/CheckboxItem/CheckboxItem.js +5 -4
  88. package/lib/module/components/CircularProgressBar/CircularProgressBar.js +8 -4
  89. package/lib/module/components/CircularProgressBarDoted/CircularProgressBarDoted.js +4 -3
  90. package/lib/module/components/CircularRating/CircularRating.js +3 -2
  91. package/lib/module/components/ClusterBubble/ClusterBubble.js +4 -3
  92. package/lib/module/components/CompareTable/CompareTable.js +396 -0
  93. package/lib/module/components/ComparisonBar/ComparisonBar.js +260 -0
  94. package/lib/module/components/CoverageBarComparison/CoverageBarComparison.js +4 -3
  95. package/lib/module/components/DonutChart/DonutChart.js +5 -4
  96. package/lib/module/components/Dropdown/Dropdown.js +4 -3
  97. package/lib/module/components/DropdownInput/DropdownInput.js +40 -7
  98. package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
  99. package/lib/module/components/FormField/FormField.js +48 -7
  100. package/lib/module/components/Gauge/Gauge.js +1 -1
  101. package/lib/module/components/HoldingsCard/HoldingsCard.js +4 -3
  102. package/lib/module/components/InputSearch/InputSearch.js +6 -4
  103. package/lib/module/components/InstitutionBadge/InstitutionBadge.js +3 -2
  104. package/lib/module/components/ListGroup/ListGroup.js +3 -2
  105. package/lib/module/components/ListItem/ListItem.js +4 -3
  106. package/lib/module/components/MediaCard/MediaCard.js +4 -2
  107. package/lib/module/components/MetricLegendItem/MetricLegendItem.js +4 -3
  108. package/lib/module/components/MonthlyStatusGrid/MonthlyStatusGrid.js +7 -4
  109. package/lib/module/components/NoteInput/NoteInput.js +7 -6
  110. package/lib/module/components/PdpCcCard/PdpCcCard.js +267 -0
  111. package/lib/module/components/PoweredByLabel/PoweredByLabel.js +4 -3
  112. package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +421 -0
  113. package/lib/module/components/ProductOverview/ProductOverview.js +5 -4
  114. package/lib/module/components/ProgressBadge/ProgressBadge.js +3 -3
  115. package/lib/module/components/ProjectionMarker/ProjectionMarker.js +157 -0
  116. package/lib/module/components/Radio/Radio.js +5 -4
  117. package/lib/module/components/Section/Section.js +4 -3
  118. package/lib/module/components/Slider/Slider.js +469 -0
  119. package/lib/module/components/Stack/Stack.js +81 -0
  120. package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
  121. package/lib/module/components/SummaryTile/SummaryTile.js +4 -3
  122. package/lib/module/components/Table/Table.js +315 -0
  123. package/lib/module/components/Text/Text.js +3 -2
  124. package/lib/module/components/TextInput/TextInput.js +24 -11
  125. package/lib/module/components/TextSegment/TextSegment.js +114 -0
  126. package/lib/module/components/ThreadHero/ThreadHero.js +5 -6
  127. package/lib/module/components/Title/Title.js +3 -2
  128. package/lib/module/components/Toast/Toast.js +4 -3
  129. package/lib/module/components/TransactionBubble/TransactionBubble.js +3 -2
  130. package/lib/module/components/TransactionStatus/TransactionStatus.js +4 -3
  131. package/lib/module/components/UpiHandle/UpiHandle.js +3 -3
  132. package/lib/module/components/index.js +11 -0
  133. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  134. package/lib/module/design-tokens/figma-modes.generated.js +39 -9
  135. package/lib/module/icons/registry.js +1 -1
  136. package/lib/module/utils/GlassFill/GlassFill.js +265 -0
  137. package/lib/module/utils/GlassFill/GlassFill.web.js +115 -0
  138. package/lib/module/utils/react-utils.js +75 -0
  139. package/lib/module/utils/web-platform-utils.js +58 -0
  140. package/lib/typescript/src/components/Accordion/Accordion.d.ts +7 -1
  141. package/lib/typescript/src/components/AccordionCheckbox/AccordionCheckbox.d.ts +7 -1
  142. package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +7 -1
  143. package/lib/typescript/src/components/AllocationComparisonChart/AllocationComparisonChart.d.ts +7 -1
  144. package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +3 -2
  145. package/lib/typescript/src/components/AreaLineChart/AreaLineChart.d.ts +8 -1
  146. package/lib/typescript/src/components/Badge/Badge.d.ts +32 -2
  147. package/lib/typescript/src/components/BenefitCard/BenefitCard.d.ts +93 -0
  148. package/lib/typescript/src/components/BrandChip/BrandChip.d.ts +7 -1
  149. package/lib/typescript/src/components/Button/Button.d.ts +7 -1
  150. package/lib/typescript/src/components/CardAdvisory/CardAdvisory.d.ts +7 -1
  151. package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +7 -1
  152. package/lib/typescript/src/components/CardCTA/CardCTA.d.ts +27 -5
  153. package/lib/typescript/src/components/CcCard/CcCard.d.ts +137 -0
  154. package/lib/typescript/src/components/Checkbox/Checkbox.d.ts +3 -2
  155. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +2 -2
  156. package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +7 -1
  157. package/lib/typescript/src/components/CircularProgressBarDoted/CircularProgressBarDoted.d.ts +7 -1
  158. package/lib/typescript/src/components/CircularRating/CircularRating.d.ts +7 -1
  159. package/lib/typescript/src/components/ClusterBubble/ClusterBubble.d.ts +7 -1
  160. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +94 -0
  161. package/lib/typescript/src/components/ComparisonBar/ComparisonBar.d.ts +118 -0
  162. package/lib/typescript/src/components/CoverageBarComparison/CoverageBarComparison.d.ts +7 -1
  163. package/lib/typescript/src/components/DonutChart/DonutChart.d.ts +7 -1
  164. package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +7 -1
  165. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +26 -1
  166. package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +7 -1
  167. package/lib/typescript/src/components/FormField/FormField.d.ts +2 -2
  168. package/lib/typescript/src/components/HoldingsCard/HoldingsCard.d.ts +7 -1
  169. package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +23 -2
  170. package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +7 -1
  171. package/lib/typescript/src/components/ListGroup/ListGroup.d.ts +7 -1
  172. package/lib/typescript/src/components/ListItem/ListItem.d.ts +7 -1
  173. package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +7 -1
  174. package/lib/typescript/src/components/MonthlyStatusGrid/MonthlyStatusGrid.d.ts +14 -2
  175. package/lib/typescript/src/components/NoteInput/NoteInput.d.ts +19 -2
  176. package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +84 -0
  177. package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +7 -1
  178. package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +87 -0
  179. package/lib/typescript/src/components/ProductOverview/ProductOverview.d.ts +7 -1
  180. package/lib/typescript/src/components/ProgressBadge/ProgressBadge.d.ts +7 -1
  181. package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +88 -0
  182. package/lib/typescript/src/components/Radio/Radio.d.ts +3 -2
  183. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +2 -2
  184. package/lib/typescript/src/components/Section/Section.d.ts +7 -1
  185. package/lib/typescript/src/components/Slider/Slider.d.ts +105 -0
  186. package/lib/typescript/src/components/Stack/Stack.d.ts +81 -0
  187. package/lib/typescript/src/components/SummaryTile/SummaryTile.d.ts +7 -1
  188. package/lib/typescript/src/components/Table/Table.d.ts +139 -0
  189. package/lib/typescript/src/components/Text/Text.d.ts +7 -1
  190. package/lib/typescript/src/components/TextInput/TextInput.d.ts +9 -29
  191. package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +106 -0
  192. package/lib/typescript/src/components/ThreadHero/ThreadHero.d.ts +7 -1
  193. package/lib/typescript/src/components/Title/Title.d.ts +7 -1
  194. package/lib/typescript/src/components/Toast/Toast.d.ts +7 -1
  195. package/lib/typescript/src/components/TransactionBubble/TransactionBubble.d.ts +7 -1
  196. package/lib/typescript/src/components/TransactionStatus/TransactionStatus.d.ts +7 -1
  197. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +7 -1
  198. package/lib/typescript/src/components/index.d.ts +14 -3
  199. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +22 -2
  200. package/lib/typescript/src/icons/registry.d.ts +1 -1
  201. package/lib/typescript/src/utils/GlassFill/GlassFill.d.ts +84 -0
  202. package/lib/typescript/src/utils/GlassFill/GlassFill.web.d.ts +43 -0
  203. package/lib/typescript/src/utils/react-utils.d.ts +47 -0
  204. package/lib/typescript/src/utils/web-platform-utils.d.ts +36 -0
  205. package/package.json +2 -1
  206. package/src/components/Accordion/Accordion.tsx +9 -2
  207. package/src/components/AccordionCheckbox/AccordionCheckbox.tsx +10 -3
  208. package/src/components/AccountCard/AccountCard.tsx +10 -3
  209. package/src/components/AllocationComparisonChart/AllocationComparisonChart.tsx +14 -4
  210. package/src/components/AmountInput/AmountInput.tsx +7 -5
  211. package/src/components/AreaLineChart/AreaLineChart.tsx +15 -5
  212. package/src/components/Badge/Badge.tsx +78 -8
  213. package/src/components/BenefitCard/BenefitCard.tsx +309 -0
  214. package/src/components/BrandChip/BrandChip.tsx +9 -3
  215. package/src/components/Button/Button.tsx +9 -2
  216. package/src/components/CardAdvisory/CardAdvisory.tsx +9 -2
  217. package/src/components/CardBankAccount/CardBankAccount.tsx +9 -2
  218. package/src/components/CardCTA/CardCTA.tsx +214 -41
  219. package/src/components/CardInsight/CardInsight.tsx +7 -1
  220. package/src/components/CcCard/CcCard.tsx +598 -0
  221. package/src/components/Checkbox/Checkbox.tsx +5 -4
  222. package/src/components/CheckboxItem/CheckboxItem.tsx +5 -4
  223. package/src/components/CircularProgressBar/CircularProgressBar.tsx +14 -4
  224. package/src/components/CircularProgressBarDoted/CircularProgressBarDoted.tsx +10 -3
  225. package/src/components/CircularRating/CircularRating.tsx +9 -2
  226. package/src/components/ClusterBubble/ClusterBubble.tsx +9 -2
  227. package/src/components/CompareTable/CompareTable.tsx +525 -0
  228. package/src/components/ComparisonBar/ComparisonBar.tsx +356 -0
  229. package/src/components/CoverageBarComparison/CoverageBarComparison.tsx +9 -2
  230. package/src/components/DonutChart/DonutChart.tsx +10 -3
  231. package/src/components/Dropdown/Dropdown.tsx +9 -2
  232. package/src/components/DropdownInput/DropdownInput.tsx +64 -5
  233. package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +8 -1
  234. package/src/components/FormField/FormField.tsx +52 -6
  235. package/src/components/Gauge/Gauge.tsx +1 -1
  236. package/src/components/HoldingsCard/HoldingsCard.tsx +9 -2
  237. package/src/components/InputSearch/InputSearch.tsx +8 -5
  238. package/src/components/InstitutionBadge/InstitutionBadge.tsx +9 -2
  239. package/src/components/ListGroup/ListGroup.tsx +9 -2
  240. package/src/components/ListItem/ListItem.tsx +10 -3
  241. package/src/components/MediaCard/MediaCard.tsx +2 -2
  242. package/src/components/MetricLegendItem/MetricLegendItem.tsx +9 -2
  243. package/src/components/MonthlyStatusGrid/MonthlyStatusGrid.tsx +17 -2
  244. package/src/components/NoteInput/NoteInput.tsx +8 -6
  245. package/src/components/PdpCcCard/PdpCcCard.tsx +356 -0
  246. package/src/components/PoweredByLabel/PoweredByLabel.tsx +9 -2
  247. package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +490 -0
  248. package/src/components/ProductOverview/ProductOverview.tsx +10 -3
  249. package/src/components/ProgressBadge/ProgressBadge.tsx +9 -3
  250. package/src/components/ProjectionMarker/ProjectionMarker.tsx +284 -0
  251. package/src/components/Radio/Radio.tsx +5 -4
  252. package/src/components/Section/Section.tsx +10 -3
  253. package/src/components/Slider/Slider.tsx +635 -0
  254. package/src/components/Stack/Stack.tsx +131 -0
  255. package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +10 -1
  256. package/src/components/SummaryTile/SummaryTile.tsx +9 -2
  257. package/src/components/Table/Table.tsx +449 -0
  258. package/src/components/Text/Text.tsx +9 -2
  259. package/src/components/TextInput/TextInput.tsx +22 -12
  260. package/src/components/TextSegment/TextSegment.tsx +173 -0
  261. package/src/components/ThreadHero/ThreadHero.tsx +10 -3
  262. package/src/components/Title/Title.tsx +9 -2
  263. package/src/components/Toast/Toast.tsx +9 -2
  264. package/src/components/TransactionBubble/TransactionBubble.tsx +9 -2
  265. package/src/components/TransactionStatus/TransactionStatus.tsx +9 -2
  266. package/src/components/UpiHandle/UpiHandle.tsx +9 -3
  267. package/src/components/index.ts +33 -3
  268. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  269. package/src/design-tokens/figma-modes.generated.ts +39 -9
  270. package/src/icons/registry.ts +1 -1
  271. package/src/utils/GlassFill/GlassFill.tsx +305 -0
  272. package/src/utils/GlassFill/GlassFill.web.tsx +148 -0
  273. package/src/utils/react-utils.ts +84 -0
  274. package/src/utils/web-platform-utils.ts +68 -0
  275. package/lib/commonjs/components/MediaCard/GlassFill.js +0 -62
  276. package/lib/commonjs/components/MediaCard/GlassFill.web.js +0 -48
  277. package/lib/module/components/MediaCard/GlassFill.js +0 -57
  278. package/lib/module/components/MediaCard/GlassFill.web.js +0 -43
  279. package/lib/typescript/scripts/extract-component-tokens.d.ts +0 -9
  280. package/lib/typescript/scripts/generate-component-docs.d.ts +0 -9
  281. package/lib/typescript/scripts/generate-icon-registry.d.ts +0 -3
  282. package/lib/typescript/scripts/generate-mode-types.d.ts +0 -2
  283. package/lib/typescript/scripts/retype-modes.d.cts +0 -2
  284. package/lib/typescript/src/components/MediaCard/GlassFill.d.ts +0 -47
  285. package/lib/typescript/src/components/MediaCard/GlassFill.web.d.ts +0 -20
  286. package/src/components/MediaCard/GlassFill.tsx +0 -89
  287. package/src/components/MediaCard/GlassFill.web.tsx +0 -53
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { View, Text, type ViewStyle, type TextStyle, type StyleProp } from 'react-native'
2
+ import { View, Text, type ViewStyle, type TextStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
3
3
  import { findVariablesByPattern, getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { useTokens } from '../../design-tokens/JFSThemeProvider'
5
5
  import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils'
@@ -8,12 +8,24 @@ import Button from '../Button/Button'
8
8
  import Badge from '../Badge/Badge'
9
9
  import ButtonGroup from '../ButtonGroup/ButtonGroup'
10
10
  import IconButton from '../IconButton/IconButton'
11
+ import Avatar from '../Avatar/Avatar'
11
12
  import type { Modes } from '../../design-tokens'
12
13
 
13
- export type CardCTAType = 'cta' | 'rating'
14
+ export type CardCTAType = 'cta' | 'rating' | 'sip'
15
+
16
+ /**
17
+ * Accepted `type` values. The canonical (and historical) values are lowercase
18
+ * (`'cta' | 'rating' | 'sip'`). The Figma variant names are PascalCase
19
+ * (`'CTA' | 'Rating' | 'Sip'`) — we accept those too and normalize internally
20
+ * so callers can pass either casing without a breaking change.
21
+ */
22
+ export type CardCTATypeInput = CardCTAType | 'CTA' | 'Rating' | 'Sip'
14
23
 
15
24
  const optionalTokenAvailability = new Map<string, boolean>()
16
25
 
26
+ const toWeight = (w: number | string): TextStyle['fontWeight'] =>
27
+ (typeof w === 'number' ? `${w}` : w) as TextStyle['fontWeight']
28
+
17
29
  function getOptionalVariableByName<T>(name: string, modes: Modes, fallback: T): T {
18
30
  let isAvailable = optionalTokenAvailability.get(name)
19
31
 
@@ -30,8 +42,13 @@ function getOptionalVariableByName<T>(name: string, modes: Modes, fallback: T):
30
42
  }
31
43
 
32
44
  export type CardCTAProps = {
33
- /** Visual layout variant */
34
- type?: CardCTAType;
45
+ /**
46
+ * Visual layout variant. `'cta'` (default) is the horizontal CTA card,
47
+ * `'rating'` is the rating card, and `'sip'` is the avatar-led card with a
48
+ * headline/description/subtitle footer. PascalCase Figma names
49
+ * (`'CTA' | 'Rating' | 'Sip'`) are also accepted.
50
+ */
51
+ type?: CardCTATypeInput;
35
52
  /** Title text */
36
53
  title?: string;
37
54
  /** Body / subtitle text */
@@ -50,6 +67,14 @@ export type CardCTAProps = {
50
67
  onPressLike?: () => void;
51
68
  /** Callback for the default dislike action */
52
69
  onPressDislike?: () => void;
70
+ /** [sip] Headline text shown above the description row */
71
+ headline?: string;
72
+ /** [sip] Description text (left of subtitle) */
73
+ description?: string;
74
+ /** [sip] Subtitle text (right of description) */
75
+ subtitle?: string;
76
+ /** [sip] Image source for the default Avatar */
77
+ avatarSource?: ImageSourcePropType | string;
53
78
  /** Mode configuration for design token resolution */
54
79
  modes?: Modes;
55
80
  /** Slot: replaces the default icon area (right side) */
@@ -60,6 +85,8 @@ export type CardCTAProps = {
60
85
  ratingBadgeSlot?: React.ReactNode;
61
86
  /** Slot: replaces the default like/dislike action group */
62
87
  ratingActionsSlot?: React.ReactNode;
88
+ /** [sip] Slot: replaces the default Avatar */
89
+ avatarSlot?: React.ReactNode;
63
90
  /** Container style overrides */
64
91
  style?: StyleProp<ViewStyle>;
65
92
  };
@@ -75,16 +102,24 @@ function CardCTA({
75
102
  showRatingActions = true,
76
103
  onPressLike,
77
104
  onPressDislike,
105
+ headline = 'Headline',
106
+ description = 'Description',
107
+ subtitle = 'Subtitle',
108
+ avatarSource,
78
109
  modes: propModes = EMPTY_MODES,
79
110
  iconSlot,
80
111
  buttonSlot,
81
112
  ratingBadgeSlot,
82
113
  ratingActionsSlot,
114
+ avatarSlot,
83
115
  style,
84
116
  }: CardCTAProps) {
85
117
  const { modes: globalModes } = useTokens()
86
118
  const modes = { ...globalModes, ...propModes }
87
- const isRating = type === 'rating'
119
+ // Accept both lowercase (canonical) and Figma PascalCase variant names.
120
+ const normalizedType = (typeof type === 'string' ? type.toLowerCase() : 'cta') as CardCTAType
121
+ const isRating = normalizedType === 'rating'
122
+ const isSip = normalizedType === 'sip'
88
123
 
89
124
  const background = getVariableByName('cardCTA/background', modes) || '#ffffff'
90
125
  const radius = getVariableByName('cardCTA/radius', modes) || 12
@@ -103,14 +138,14 @@ function CardCTA({
103
138
  const titleColor = getVariableByName('cardCTA/title/color', modes) || '#0c0d10'
104
139
  const titleFontFamily = getVariableByName('cardCTA/title/fontFamily', modes) || 'JioType Var'
105
140
  const titleFontSize = getVariableByName('cardCTA/title/fontSize', modes) || 16
106
- const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) || 17.6
141
+ const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) || 18
107
142
  const titleFontWeightRaw = getVariableByName('cardCTA/title/fontWeight', modes) || 700
108
143
  const titleFontWeight = typeof titleFontWeightRaw === 'number' ? titleFontWeightRaw.toString() : titleFontWeightRaw
109
144
 
110
145
  const bodyColor = getVariableByName('cardCTA/body/color', modes) || '#13002d'
111
146
  const bodyFontFamily = getVariableByName('cardCTA/body/fontFamily', modes) || 'JioType Var'
112
- const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) || 10
113
- const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) || 12
147
+ const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) || 14
148
+ const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) || 17
114
149
  const bodyFontWeightRaw = getVariableByName('cardCTA/body/fontWeight', modes) || 400
115
150
  const bodyFontWeight = typeof bodyFontWeightRaw === 'number' ? bodyFontWeightRaw.toString() : bodyFontWeightRaw
116
151
 
@@ -122,6 +157,34 @@ function CardCTA({
122
157
  const ratingFooterPaddingTop = getOptionalVariableByName('cardCTA/rating/footer/top', modes, 0)
123
158
  const ratingFooterPaddingBottom = getOptionalVariableByName('cardCTA/rating/footer/bottom', modes, 12)
124
159
 
160
+ // Sip variant footer text block (Headline / Description / Subtitle). These
161
+ // `ccCard/*` tokens were introduced for the Sip layout — resolve them
162
+ // optionally so older token snapshots that lack them fall back gracefully.
163
+ const sipFooterGap = getOptionalVariableByName('ccCard/footer/textWrap/gap', modes, 4)
164
+
165
+ const sipHeadlineColor = getOptionalVariableByName('ccCard/headline/color', modes, '#707275')
166
+ const sipHeadlineFontFamily = getOptionalVariableByName('ccCard/headline/fontFamily', modes, 'JioType Var')
167
+ const sipHeadlineFontSize = getOptionalVariableByName('ccCard/headline/fontSize', modes, 10)
168
+ const sipHeadlineLineHeight = getOptionalVariableByName('ccCard/headline/lineHeight', modes, 13)
169
+ const sipHeadlineFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/headline/fontWeight', modes, 500)
170
+ const sipHeadlineFontWeight = typeof sipHeadlineFontWeightRaw === 'number' ? sipHeadlineFontWeightRaw.toString() : sipHeadlineFontWeightRaw
171
+
172
+ const sipDescriptionColor = getOptionalVariableByName('ccCard/title/color', modes, '#081007')
173
+ const sipDescriptionFontFamily = getOptionalVariableByName('ccCard/title/fontFamily', modes, 'JioType Var')
174
+ const sipDescriptionFontSize = getOptionalVariableByName('ccCard/title/fontSize', modes, 14)
175
+ const sipDescriptionLineHeight = getOptionalVariableByName('ccCard/title/lineHeight', modes, 15)
176
+ const sipDescriptionFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/title/fontWeight', modes, 700)
177
+ const sipDescriptionFontWeight = typeof sipDescriptionFontWeightRaw === 'number' ? sipDescriptionFontWeightRaw.toString() : sipDescriptionFontWeightRaw
178
+
179
+ const sipSubtitleColor = getOptionalVariableByName('ccCard/subtitle/color', modes, '#707275')
180
+ const sipSubtitleFontFamily = getOptionalVariableByName('ccCard/subtitle/fontFamily', modes, 'JioType Var')
181
+ const sipSubtitleFontSize = getOptionalVariableByName('ccCard/subtitle/fontSize', modes, 10)
182
+ const sipSubtitleLineHeight = getOptionalVariableByName('ccCard/subtitle/lineHeight', modes, 13)
183
+ const sipSubtitleFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/subtitle/fontWeight', modes, 500)
184
+ const sipSubtitleFontWeight = typeof sipSubtitleFontWeightRaw === 'number' ? sipSubtitleFontWeightRaw.toString() : sipSubtitleFontWeightRaw
185
+
186
+ const avatarModes = { ...modes, 'Avatar Size': 'L' }
187
+
125
188
  const buttonModes = {...modes, AppearanceBrand: 'Secondary', 'Button / Size': 'S'}
126
189
  const iconButtonModes = {'Button / Size': 'S', 'Emphasis': 'Low', 'AppearanceBrand':'Neutral',...modes }
127
190
  const effectiveButtonLabel = buttonLabel ?? (isRating ? 'Save' : 'Button')
@@ -130,33 +193,72 @@ function CardCTA({
130
193
 
131
194
  const buttonPaddingH = getVariableByName('button/padding/horizontal', buttonModes) || 20
132
195
  const buttonBorderSize = getVariableByName('button/border/size', buttonModes) ?? 1
196
+ // Small safety pad so sub-pixel rounding between the measure pass and the
197
+ // rendered glyph run can never clip the final character.
133
198
  const measuredButtonWidth = measuredButtonLabelWidth === null
134
199
  ? undefined
135
- : Math.ceil(measuredButtonLabelWidth + (buttonPaddingH as number) * 2 + (buttonBorderSize as number) * 2)
136
-
137
- const handleButtonLabelTextLayout = React.useCallback((event: any) => {
138
- const lines = event?.nativeEvent?.lines
139
- if (!Array.isArray(lines) || lines.length === 0) return
140
-
141
- const nextWidth = Math.ceil(
142
- lines.reduce((sum, line) => sum + (typeof line?.width === 'number' ? line.width : 0), 0)
200
+ : Math.ceil(measuredButtonLabelWidth + (buttonPaddingH as number) * 2 + (buttonBorderSize as number) * 2 + 2)
201
+
202
+ // ROOT-CAUSE FIX for the Android "jumping button" feedback loop + clipping.
203
+ //
204
+ // Previously the *visible* label measured itself via `onTextLayout` and we
205
+ // fed that width straight back onto the same Button. Because the button is
206
+ // width-constrained by its parent, Android clamps the overflowing text and
207
+ // even character-breaks a single word ("Save" -> "Sav"/"e"); the re-applied
208
+ // width re-triggers layout, producing an endless ~60fps width oscillation.
209
+ //
210
+ // We now measure an *off-screen* copy of the label, laid out at an
211
+ // effectively unbounded width, so its reported single-line width is
212
+ // intrinsic and constant regardless of the button's applied width — the
213
+ // measurement can no longer depend on the value it produces, so the loop is
214
+ // impossible. Crucially the measurer reuses the Button's own resolved label
215
+ // styles (passed into `renderContent`), so the measured font matches the
216
+ // rendered font exactly and the width is never an under-estimate. The label
217
+ // is always a single line that overflows rather than wraps or truncates.
218
+ const handleMeasureTextLayout = React.useCallback((event: any) => {
219
+ const line = event?.nativeEvent?.lines?.[0]
220
+ const width = line && typeof line.width === 'number' ? line.width : 0
221
+ if (width <= 0) return
222
+
223
+ setMeasuredButtonLabelWidth((currentWidth) =>
224
+ currentWidth !== null && Math.abs(currentWidth - width) < 0.5
225
+ ? currentWidth
226
+ : Math.ceil(width)
143
227
  )
144
- if (nextWidth <= 0) return
145
-
146
- setMeasuredButtonLabelWidth((currentWidth) => {
147
- if (currentWidth !== null && Math.abs(currentWidth - nextWidth) < 1) {
148
- return currentWidth
149
- }
150
- return nextWidth
151
- })
152
228
  }, [])
153
229
 
230
+ // Off-screen measurer wrapper: absolute + opacity 0 + pointerEvents none =>
231
+ // out of flow, invisible, never intercepts touches, zero layout impact.
232
+ const measurerWrapStyle: ViewStyle = { position: 'absolute', left: 0, top: 0, opacity: 0 }
233
+
234
+ // Renders the visible single-line label (never wraps, never ellipsizes) plus
235
+ // the co-located off-screen measurer that shares the Button's exact label
236
+ // styles. `width: 9999` forces the measurer onto one line so `onTextLayout`
237
+ // reports the true intrinsic width.
238
+ const renderButtonContent = (labelExtraStyle: TextStyle) => (labelStyles: StyleProp<TextStyle>) => (
239
+ <>
240
+ <Text numberOfLines={1} ellipsizeMode="clip" style={[labelStyles, labelExtraStyle]}>
241
+ {nonWrappingButtonLabel}
242
+ </Text>
243
+ <View
244
+ pointerEvents="none"
245
+ accessibilityElementsHidden
246
+ importantForAccessibility="no"
247
+ style={measurerWrapStyle}
248
+ >
249
+ <Text style={[labelStyles, { width: 9999 }]} onTextLayout={handleMeasureTextLayout}>
250
+ {nonWrappingButtonLabel}
251
+ </Text>
252
+ </View>
253
+ </>
254
+ )
255
+
154
256
  const containerStyle: ViewStyle = {
155
257
  backgroundColor: background,
156
258
  borderRadius: radius,
157
259
  borderWidth: borderSize,
158
260
  borderColor,
159
- flexDirection: isRating ? 'column' : 'row',
261
+ flexDirection: isRating || isSip ? 'column' : 'row',
160
262
  overflow: 'visible',
161
263
  }
162
264
 
@@ -245,6 +347,53 @@ function CardCTA({
245
347
  fontWeight: bodyFontWeight,
246
348
  }
247
349
 
350
+ const sipWrapStyle: ViewStyle = {
351
+ width: '100%',
352
+ paddingHorizontal: leftPaddingH,
353
+ paddingVertical: leftPaddingV,
354
+ gap: leftGap,
355
+ alignItems: 'flex-start',
356
+ justifyContent: 'flex-start',
357
+ overflow: 'visible',
358
+ }
359
+
360
+ const sipFooterTextWrapStyle: ViewStyle = {
361
+ gap: sipFooterGap,
362
+ alignItems: 'flex-start',
363
+ alignSelf: 'stretch',
364
+ minWidth: 0,
365
+ }
366
+
367
+ const sipDescriptionWrapStyle: ViewStyle = {
368
+ flexDirection: 'row',
369
+ gap: sipFooterGap,
370
+ alignItems: 'flex-end',
371
+ }
372
+
373
+ const sipHeadlineStyle: TextStyle = {
374
+ color: sipHeadlineColor,
375
+ fontFamily: sipHeadlineFontFamily,
376
+ fontSize: sipHeadlineFontSize,
377
+ lineHeight: sipHeadlineLineHeight,
378
+ fontWeight: toWeight(sipHeadlineFontWeightRaw),
379
+ }
380
+
381
+ const sipDescriptionStyle: TextStyle = {
382
+ color: sipDescriptionColor,
383
+ fontFamily: sipDescriptionFontFamily,
384
+ fontSize: sipDescriptionFontSize,
385
+ lineHeight: sipDescriptionLineHeight,
386
+ fontWeight: toWeight(sipDescriptionFontWeightRaw),
387
+ }
388
+
389
+ const sipSubtitleStyle: TextStyle = {
390
+ color: sipSubtitleColor,
391
+ fontFamily: sipSubtitleFontFamily,
392
+ fontSize: sipSubtitleFontSize,
393
+ lineHeight: sipSubtitleLineHeight,
394
+ fontWeight: toWeight(sipSubtitleFontWeightRaw),
395
+ }
396
+
248
397
  const ratingContentStyle: ViewStyle = {
249
398
  paddingHorizontal: ratingContentPaddingH,
250
399
  paddingVertical: ratingContentPaddingV,
@@ -294,6 +443,44 @@ function CardCTA({
294
443
  flexWrap: 'nowrap',
295
444
  }
296
445
 
446
+ if (isSip) {
447
+ return (
448
+ <View style={[containerStyle, style]}>
449
+ <View style={sipWrapStyle}>
450
+ {avatarSlot ? (
451
+ cloneChildrenWithModes(avatarSlot, avatarModes)
452
+ ) : (
453
+ <Avatar style="Image" imageSource={avatarSource} modes={avatarModes} />
454
+ )}
455
+ <View style={textWrapStyle}>
456
+ <Text style={titleStyle}>{title}</Text>
457
+ <Text style={bodyStyle}>{body}</Text>
458
+ </View>
459
+ <View style={sipFooterTextWrapStyle}>
460
+ <Text style={sipHeadlineStyle}>{headline}</Text>
461
+ <View style={sipDescriptionWrapStyle}>
462
+ <Text style={sipDescriptionStyle}>{description}</Text>
463
+ <Text style={sipSubtitleStyle}>{subtitle}</Text>
464
+ </View>
465
+ </View>
466
+ <View style={buttonWrapStyle}>
467
+ {buttonSlot ? (
468
+ cloneChildrenWithModes(buttonSlot, buttonModes)
469
+ ) : (
470
+ <Button
471
+ label={effectiveButtonLabel}
472
+ onPress={onPressButton || (() => {})}
473
+ modes={buttonModes}
474
+ style={buttonStyle}
475
+ renderContent={renderButtonContent(buttonLabelStyle)}
476
+ />
477
+ )}
478
+ </View>
479
+ </View>
480
+ </View>
481
+ )
482
+ }
483
+
297
484
  if (isRating) {
298
485
  return (
299
486
  <View style={[containerStyle, style]}>
@@ -318,14 +505,7 @@ function CardCTA({
318
505
  onPress={onPressButton || (() => {})}
319
506
  modes={buttonModes}
320
507
  style={ratingButtonStyle}
321
- renderContent={(labelStyles) => (
322
- <Text
323
- onTextLayout={handleButtonLabelTextLayout}
324
- style={[labelStyles, ratingButtonLabelStyle]}
325
- >
326
- {nonWrappingButtonLabel}
327
- </Text>
328
- )}
508
+ renderContent={renderButtonContent(ratingButtonLabelStyle)}
329
509
  />
330
510
  )}
331
511
  </View>
@@ -368,14 +548,7 @@ function CardCTA({
368
548
  onPress={onPressButton || (() => {})}
369
549
  modes={buttonModes}
370
550
  style={buttonStyle}
371
- renderContent={(labelStyles) => (
372
- <Text
373
- onTextLayout={handleButtonLabelTextLayout}
374
- style={[labelStyles, buttonLabelStyle]}
375
- >
376
- {nonWrappingButtonLabel}
377
- </Text>
378
- )}
551
+ renderContent={renderButtonContent(buttonLabelStyle)}
379
552
  />
380
553
  )}
381
554
  </View>
@@ -71,7 +71,11 @@ function CardInsight({
71
71
  const background =
72
72
  (getVariableByName('cardInsight/background', modes) as string | null) ?? '#ffffff'
73
73
  const radius =
74
- (getVariableByName('cardInsight/radius', modes) as number | null) ?? 16
74
+ (getVariableByName('cardInsight/radius', modes) as number | null) ?? 12
75
+ const borderWidth =
76
+ (getVariableByName('cardInsight/borderWidth', modes) as number | null) ?? 1
77
+ const borderColor =
78
+ (getVariableByName('cardInsight/border/color', modes) as string | null) ?? '#ffffff'
75
79
  const paddingHorizontal =
76
80
  (getVariableByName('cardInsight/padding/horizontal', modes) as number | null) ?? 12
77
81
  const paddingVertical =
@@ -164,6 +168,8 @@ function CardInsight({
164
168
  width,
165
169
  backgroundColor: background,
166
170
  borderRadius: radius,
171
+ borderWidth,
172
+ borderColor,
167
173
  paddingHorizontal,
168
174
  paddingVertical,
169
175
  gap,