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
@@ -150,9 +150,13 @@ function GradientMask({
150
150
  }
151
151
 
152
152
  /**
153
- * Glass / frosted surface for native (iOS + Android).
153
+ * Shared glass / frosted surface for native (iOS + Android).
154
154
  *
155
- * Why this lives in its own platform-split file (mirrors `MediaCard/GlassFill`):
155
+ * This is the single source of truth for the glass effect used by `MediaCard`,
156
+ * `ProductMerchandisingCard`, `Badge`, and any future consumer. It supersedes
157
+ * the per-component `GlassFill` copies that previously drifted apart.
158
+ *
159
+ * Why this lives in its own platform-split file:
156
160
  * - `@react-native-community/blur` is a native-only module; importing it on
157
161
  * web throws because it references native components not registered there.
158
162
  * Metro's platform-extension resolution picks `GlassFill.tsx` for native
@@ -165,12 +169,16 @@ function GradientMask({
165
169
  * native module isn't linked in the running binary, the component degrades to
166
170
  * a translucent tinted scrim (`reducedTransparencyFallbackColor` / fallback
167
171
  * color) instead of rendering the "Unimplemented component" placeholder.
172
+ *
173
+ * NOTE: the consumer MUST clip this with `overflow: 'hidden'` on a rounded
174
+ * parent — the native blur view does not honor `borderRadius` itself.
168
175
  */
169
176
  function GlassFill({
170
177
  tint = 'dark',
171
178
  intensity = 50,
172
179
  overlayColor,
173
180
  progressive = false,
181
+ androidTintWash = true,
174
182
  style
175
183
  }) {
176
184
  const rawId = (0, _react.useId)();
@@ -252,7 +260,7 @@ function GlassFill({
252
260
  style: [_reactNative.StyleSheet.absoluteFill, {
253
261
  backgroundColor: overlayColor
254
262
  }]
255
- }) : null, _reactNative.Platform.OS === 'android' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
263
+ }) : null, _reactNative.Platform.OS === 'android' && androidTintWash ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
256
264
  style: [_reactNative.StyleSheet.absoluteFill, {
257
265
  backgroundColor: 'rgba(255,255,255,0.03)',
258
266
  opacity: 0.6
@@ -10,6 +10,8 @@ var _jsxRuntime = require("react/jsx-runtime");
10
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
11
  const DEFAULT_FALLBACK_DARK = '#1414174a';
12
12
  const DEFAULT_FALLBACK_LIGHT = '#ffffff66';
13
+ const DEFAULT_WEB_BLUR_SCALE = 0.32;
14
+ const DEFAULT_WEB_BLUR_MAX_PX = 32;
13
15
 
14
16
  // Mirror of the native ramp (see GlassFill.tsx). Each layer is a `mask-image`
15
17
  // gradient whose alpha stops (0 = top, 1 = bottom) ease the blur in; `amount`
@@ -57,7 +59,7 @@ function toGradient(stops) {
57
59
  }
58
60
 
59
61
  /**
60
- * Web counterpart of `GlassFill`.
62
+ * Web counterpart of the shared `GlassFill`.
61
63
  *
62
64
  * `@react-native-community/blur` ships no web implementation, so on web we
63
65
  * render a translucent `View` with `backdrop-filter: blur()`. Native bundles
@@ -69,15 +71,17 @@ function GlassFill({
69
71
  intensity = 50,
70
72
  overlayColor,
71
73
  progressive = false,
74
+ webBlurScale = DEFAULT_WEB_BLUR_SCALE,
75
+ webBlurMaxPx = DEFAULT_WEB_BLUR_MAX_PX,
72
76
  style
73
77
  }) {
74
- // intensity 0-100 -> ~0-32px CSS blur, kept in parity with the native scale.
75
- const blurPx = Math.max(0, Math.min(32, Math.round(intensity * 0.32)));
78
+ // intensity 0-100 -> ~0-maxPx CSS blur, kept in parity with the native scale.
79
+ const blurPx = Math.max(0, Math.min(webBlurMaxPx, Math.round(intensity * webBlurScale)));
76
80
  const tintColor = overlayColor ?? (tint === 'light' ? DEFAULT_FALLBACK_LIGHT : DEFAULT_FALLBACK_DARK);
77
81
  if (progressive) {
78
82
  // Full peak blur (parity with native) so the frosted glass is clearly
79
83
  // engaged at the bottom; the eased masks keep the top fully clear.
80
- const peakPx = Math.max(1, Math.min(32, Math.round(intensity * 0.32)));
84
+ const peakPx = Math.max(1, Math.min(webBlurMaxPx, Math.round(intensity * webBlurScale)));
81
85
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
82
86
  style: [_reactNative.StyleSheet.absoluteFill, style],
83
87
  pointerEvents: "none",
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.EMPTY_MODES = void 0;
7
7
  exports.cloneChildrenWithModes = cloneChildrenWithModes;
8
8
  exports.flattenChildren = flattenChildren;
9
+ exports.injectChildStyle = injectChildStyle;
9
10
  exports.mergeRefs = mergeRefs;
11
+ exports.resolveTruncation = resolveTruncation;
10
12
  var _react = _interopRequireDefault(require("react"));
11
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
14
  /**
@@ -80,6 +82,40 @@ function cloneChildrenWithModes(children, modes, forcedModes) {
80
82
  return _react.default.Children.toArray(result);
81
83
  }
82
84
 
85
+ /**
86
+ * Merges a style onto each direct (top-level) child element, with the injected
87
+ * style taking precedence over the child's own style.
88
+ *
89
+ * Used by the Stack family to *enforce* cross-axis stretching from the container
90
+ * itself: a child can set its own `alignSelf` (which, per the flexbox spec,
91
+ * overrides the parent's `alignItems`), so to guarantee equal heights / full
92
+ * width regardless of what individual children declare, we append
93
+ * `{ alignSelf: 'stretch' }` to every direct child.
94
+ *
95
+ * @remarks
96
+ * - Only top-level children are touched. Grandchildren are intentionally left
97
+ * alone — we never want to leak layout styles deeper into the tree.
98
+ * - Non-element children (strings, numbers) are passed through untouched.
99
+ * - This relies on the child forwarding `style` to its outer/root view. Built-in
100
+ * RN primitives and components that spread `style` onto their root honour it;
101
+ * a child that fully ignores `style` cannot be forced (this is a hard React
102
+ * Native limitation, not something this helper can work around).
103
+ * - Per Yoga, stretch has no effect on an axis where the child has a *fixed*
104
+ * dimension (e.g. an explicit `height` for a row). Such children opt out by
105
+ * design; this helper does not strip explicit dimensions.
106
+ */
107
+ function injectChildStyle(children, style) {
108
+ return _react.default.Children.map(children, child => {
109
+ if (! /*#__PURE__*/_react.default.isValidElement(child)) {
110
+ return child;
111
+ }
112
+ const existingStyle = child.props?.style;
113
+ return /*#__PURE__*/_react.default.cloneElement(child, {
114
+ style: existingStyle != null ? [existingStyle, style] : style
115
+ });
116
+ });
117
+ }
118
+
83
119
  /**
84
120
  * Combines several refs (object refs and/or callback refs) into a single
85
121
  * callback ref. Useful when a component needs to keep its own internal ref to a
@@ -100,6 +136,26 @@ function mergeRefs(...refs) {
100
136
  });
101
137
  };
102
138
  }
139
+ /**
140
+ * Resolves the `numberOfLines` / `ellipsizeMode` pair for a `<Text>` based on a
141
+ * `disableTruncation` flag.
142
+ *
143
+ * When `disableTruncation` is `true`, both values are returned as `undefined`
144
+ * so the text wraps to as many lines as it needs and never shows the trailing
145
+ * ellipsis. Otherwise the provided values are passed through unchanged.
146
+ */
147
+ function resolveTruncation(disableTruncation, numberOfLines, ellipsizeMode) {
148
+ if (disableTruncation) {
149
+ return {
150
+ numberOfLines: undefined,
151
+ ellipsizeMode: undefined
152
+ };
153
+ }
154
+ return {
155
+ numberOfLines,
156
+ ellipsizeMode
157
+ };
158
+ }
103
159
 
104
160
  /**
105
161
  * Flattens React children, extracting them from Fragments.
@@ -10,6 +10,8 @@ exports.getWebAccessibilityProps = getWebAccessibilityProps;
10
10
  exports.isWeb = exports.isNative = void 0;
11
11
  exports.useKeyboardNavigation = useKeyboardNavigation;
12
12
  exports.usePressableWebSupport = usePressableWebSupport;
13
+ exports.useWebOutsidePress = useWebOutsidePress;
14
+ var _react = require("react");
13
15
  var _reactNative = require("react-native");
14
16
  /**
15
17
  * Web-specific props that should NOT be passed to React Native's Pressable component.
@@ -201,6 +203,63 @@ function usePressableWebSupport({
201
203
  };
202
204
  }
203
205
 
206
+ /**
207
+ * Detects pointer presses (mouse / touch) that land OUTSIDE the node held by
208
+ * `containerRef` and invokes `onOutsidePress`.
209
+ *
210
+ * Why this exists:
211
+ * On web, React Native pressables (`Pressable`, `Button`, links, etc.) do not
212
+ * always claim DOM focus the way a native `<button>`/`<input>` does. As a
213
+ * result, tapping an *interactive* element outside a focused `<input>` may
214
+ * never trigger the input's native `blur` event, leaving a field stuck in its
215
+ * "Active" visual state. Listening for document-level pointer-down in the
216
+ * capture phase lets a component force a blur (or close a popover, etc.)
217
+ * regardless of whether the outside target takes focus.
218
+ *
219
+ * Behavior & safety:
220
+ * - **Web only.** On native (or when `document` is unavailable) this is a
221
+ * no-op, so it is safe to call unconditionally.
222
+ * - Listeners are attached only while `enabled` is `true`, and are removed on
223
+ * cleanup / when disabled — there is no standing global listener.
224
+ * - Uses the **capture** phase so it runs before element-level handlers, and
225
+ * listens to both `mousedown` and `touchstart` for parity across devices.
226
+ * - The latest `onOutsidePress` is read through a ref, so passing a fresh
227
+ * inline closure every render does NOT re-subscribe the listener.
228
+ *
229
+ * @param containerRef - Ref to the root host node to treat as "inside".
230
+ * @param onOutsidePress - Called when a pointer press occurs outside the node.
231
+ * @param enabled - When `false`, no listener is attached. Defaults to `true`.
232
+ *
233
+ * @example
234
+ * ```tsx
235
+ * const rootRef = useRef<View>(null)
236
+ * const inputRef = useRef<RNTextInput>(null)
237
+ * useWebOutsidePress(rootRef, () => inputRef.current?.blur(), isFocused)
238
+ * ```
239
+ */
240
+ function useWebOutsidePress(containerRef, onOutsidePress, enabled = true) {
241
+ const callbackRef = (0, _react.useRef)(onOutsidePress);
242
+ callbackRef.current = onOutsidePress;
243
+ (0, _react.useEffect)(() => {
244
+ if (_reactNative.Platform.OS !== 'web' || typeof document === 'undefined' || !enabled) {
245
+ return;
246
+ }
247
+ const handlePointerDown = event => {
248
+ const node = containerRef.current;
249
+ const target = event.target;
250
+ if (node?.contains && !node.contains(target)) {
251
+ callbackRef.current();
252
+ }
253
+ };
254
+ document.addEventListener('mousedown', handlePointerDown, true);
255
+ document.addEventListener('touchstart', handlePointerDown, true);
256
+ return () => {
257
+ document.removeEventListener('mousedown', handlePointerDown, true);
258
+ document.removeEventListener('touchstart', handlePointerDown, true);
259
+ };
260
+ }, [containerRef, enabled]);
261
+ }
262
+
204
263
  /**
205
264
  * Type guard to check if running on web platform
206
265
  */
@@ -5,7 +5,7 @@ import { View, Text, Pressable, LayoutAnimation, Platform, UIManager } from 'rea
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import Icon from '../../icons/Icon';
7
7
  import { usePressableWebSupport } from '../../utils/web-platform-utils';
8
- import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
8
+ import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils';
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  // Enable LayoutAnimation on Android
11
11
  if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
@@ -61,6 +61,7 @@ function Accordion({
61
61
  accessibilityHint,
62
62
  accessibilityState,
63
63
  webAccessibilityProps,
64
+ disableTruncation,
64
65
  ...rest
65
66
  }) {
66
67
  const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
@@ -160,7 +161,7 @@ function Accordion({
160
161
  ...webProps,
161
162
  children: [/*#__PURE__*/_jsx(Text, {
162
163
  style: titleStyle,
163
- numberOfLines: 1,
164
+ ...resolveTruncation(disableTruncation, 1),
164
165
  children: title
165
166
  }), /*#__PURE__*/_jsx(Icon, {
166
167
  name: isExpanded ? 'ic_minus' : 'ic_add',
@@ -3,7 +3,7 @@
3
3
  import React, { useCallback, useState } from 'react';
4
4
  import { View, Text, Pressable, LayoutAnimation, Platform, UIManager } 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 Checkbox from '../Checkbox/Checkbox';
8
8
  import Divider from '../Divider/Divider';
9
9
  import Icon from '../../icons/Icon';
@@ -58,7 +58,8 @@ function AccordionCheckbox({
58
58
  children,
59
59
  modes = EMPTY_MODES,
60
60
  style,
61
- accessibilityLabel
61
+ accessibilityLabel,
62
+ disableTruncation
62
63
  }) {
63
64
  const isExpandedControlled = controlledExpanded !== undefined;
64
65
  const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
@@ -203,12 +204,12 @@ function AccordionCheckbox({
203
204
  style: textWrapStyle,
204
205
  children: [/*#__PURE__*/_jsx(Text, {
205
206
  style: titleStyle,
206
- numberOfLines: 1,
207
+ ...resolveTruncation(disableTruncation, 1),
207
208
  selectable: false,
208
209
  children: title
209
210
  }), subtitle ? /*#__PURE__*/_jsx(Text, {
210
211
  style: subtitleStyle,
211
- numberOfLines: 1,
212
+ ...resolveTruncation(disableTruncation, 1),
212
213
  selectable: false,
213
214
  children: subtitle
214
215
  }) : null]
@@ -3,7 +3,7 @@
3
3
  import React, { useCallback, useMemo, useRef } from 'react';
4
4
  import { Image as RNImage, Platform, Pressable, Text, View } 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 Icon from '../../icons/Icon';
8
8
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
9
9
  const IS_IOS = Platform.OS === 'ios';
@@ -72,7 +72,8 @@ function AccountCard({
72
72
  modes = EMPTY_MODES,
73
73
  style,
74
74
  accessibilityLabel,
75
- accessibilityHint
75
+ accessibilityHint,
76
+ disableTruncation
76
77
  }) {
77
78
  const iconModes = useMemo(() => modes === EMPTY_MODES ? ADD_ICON_DEFAULT_MODES : {
78
79
  ...ADD_ICON_DEFAULT_MODES,
@@ -205,11 +206,11 @@ function AccountCard({
205
206
  },
206
207
  children: [title != null && title !== '' ? /*#__PURE__*/_jsx(Text, {
207
208
  style: titleStyle,
208
- numberOfLines: 1,
209
+ ...resolveTruncation(disableTruncation, 1),
209
210
  children: title
210
211
  }) : null, showSubtitle ? /*#__PURE__*/_jsx(Text, {
211
212
  style: subtitleStyle,
212
- numberOfLines: 1,
213
+ ...resolveTruncation(disableTruncation, 1),
213
214
  children: subtitle
214
215
  }) : null]
215
216
  }) : null]
@@ -5,7 +5,7 @@ import { View, Text } from 'react-native';
5
5
  import Svg, { Line } 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 MetricLegendItem from '../MetricLegendItem/MetricLegendItem';
10
10
 
11
11
  /**
@@ -61,7 +61,8 @@ function SegmentBar({
61
61
  baselineHeightPx,
62
62
  baselineLabel,
63
63
  showMarker,
64
- theme
64
+ theme,
65
+ disableTruncation
65
66
  }) {
66
67
  const {
67
68
  barWidth,
@@ -88,7 +89,7 @@ function SegmentBar({
88
89
  },
89
90
  accessibilityLabel: segment.accessibilityLabel,
90
91
  children: [showValueLabel ? /*#__PURE__*/_jsx(Text, {
91
- numberOfLines: 1,
92
+ ...resolveTruncation(disableTruncation, 1),
92
93
  style: labelStyle,
93
94
  children: segment.valueLabel
94
95
  }) : null, /*#__PURE__*/_jsx(View, {
@@ -134,7 +135,7 @@ function SegmentBar({
134
135
  strokeDasharray: "2 2"
135
136
  })
136
137
  }), isShown(baselineLabel) ? /*#__PURE__*/_jsx(Text, {
137
- numberOfLines: 1,
138
+ ...resolveTruncation(disableTruncation, 1),
138
139
  style: [labelStyle, {
139
140
  marginLeft: 6
140
141
  }],
@@ -143,7 +144,7 @@ function SegmentBar({
143
144
  }) : null]
144
145
  }) : null
145
146
  }), /*#__PURE__*/_jsx(Text, {
146
- numberOfLines: 1,
147
+ ...resolveTruncation(disableTruncation, 1),
147
148
  style: labelStyle,
148
149
  children: segment.label
149
150
  })]
@@ -180,7 +181,8 @@ function AllocationComparisonChart({
180
181
  style,
181
182
  chartStyle,
182
183
  legendStyle,
183
- accessibilityLabel
184
+ accessibilityLabel,
185
+ disableTruncation
184
186
  }) {
185
187
  const {
186
188
  modes: globalModes
@@ -284,7 +286,8 @@ function AllocationComparisonChart({
284
286
  baselineHeightPx: baselineHeightPx,
285
287
  baselineLabel: baselineLabel,
286
288
  showMarker: showMarker,
287
- theme: theme
289
+ theme: theme,
290
+ disableTruncation: disableTruncation
288
291
  }, segment.key ?? `segment-${index}`);
289
292
  })
290
293
  })]
@@ -5,7 +5,7 @@ import { PanResponder, Platform, Pressable, StyleSheet, Text, View } from 'react
5
5
  import Svg, { Circle, Line, Path } 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 MetricLegendItem from '../MetricLegendItem/MetricLegendItem';
10
10
  import { buildAreaPath, buildLineSegments, createLinearScale, extent, nearestIndex, niceTicks, resolvePoints } from './chartMath';
11
11
 
@@ -116,7 +116,8 @@ function AreaLineChart({
116
116
  modes: propModes = EMPTY_MODES,
117
117
  style,
118
118
  children,
119
- accessibilityLabel
119
+ accessibilityLabel,
120
+ disableTruncation
120
121
  }) {
121
122
  const {
122
123
  modes: globalModes
@@ -236,8 +237,9 @@ function AreaLineChart({
236
237
  formatX,
237
238
  formatY,
238
239
  showDots,
239
- modes
240
- }), [plotWidth, height, inset, xScale, yScale, yTicks, indexXs, count, resolvedSeries, curve, activeIndex, setActiveIndex, xLabels, formatX, formatY, showDots, modes]);
240
+ modes,
241
+ disableTruncation
242
+ }), [plotWidth, height, inset, xScale, yScale, yTicks, indexXs, count, resolvedSeries, curve, activeIndex, setActiveIndex, xLabels, formatX, formatY, showDots, modes, disableTruncation]);
241
243
  const isMultiSeries = resolvedSeries.length > 1;
242
244
  const resolvedFormatValue = formatValue ?? (v => formatY(v));
243
245
  return /*#__PURE__*/_jsx(ChartContext.Provider, {
@@ -378,7 +380,8 @@ function ChartYAxis({
378
380
  yScale,
379
381
  yTicks,
380
382
  formatY,
381
- modes
383
+ modes,
384
+ disableTruncation
382
385
  } = useChart();
383
386
  const typo = useAxisTypography(modes);
384
387
  const format = formatLabel ?? formatY;
@@ -406,7 +409,7 @@ function ChartYAxis({
406
409
  },
407
410
  children: showLabels ? /*#__PURE__*/_jsx(Text, {
408
411
  style: typo.style,
409
- numberOfLines: 1,
412
+ ...resolveTruncation(disableTruncation, 1),
410
413
  children: format(t)
411
414
  }) : null
412
415
  }, `yl-${t}`);
@@ -457,7 +460,8 @@ function ChartXAxis({
457
460
  formatX,
458
461
  modes,
459
462
  activeIndex,
460
- setActiveIndex
463
+ setActiveIndex,
464
+ disableTruncation
461
465
  } = useChart();
462
466
  const typo = useAxisTypography(modes);
463
467
  const format = formatLabel ?? formatX;
@@ -503,7 +507,7 @@ function ChartXAxis({
503
507
  color: activeColor,
504
508
  fontWeight: '700'
505
509
  } : null],
506
- numberOfLines: 1,
510
+ ...resolveTruncation(disableTruncation, 1),
507
511
  children: format(label, i)
508
512
  });
509
513
  return /*#__PURE__*/_jsx(View, {
@@ -3,23 +3,36 @@
3
3
  import React from 'react';
4
4
  import { View, Text, Pressable } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { EMPTY_MODES } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
7
7
  import Skeleton from '../../skeleton/Skeleton';
8
8
  import { useSkeleton } from '../../skeleton/SkeletonGroup';
9
- import { jsx as _jsx } from "react/jsx-runtime";
9
+ import GlassFill from '../../utils/GlassFill/GlassFill';
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  function Badge({
11
12
  label = 'Label',
13
+ type = 'default',
12
14
  modes = EMPTY_MODES,
13
15
  onPress,
14
16
  accessibilityLabel,
15
17
  style,
16
18
  labelStyle,
17
19
  loading,
20
+ disableTruncation,
21
+ leading,
22
+ glassOverlayColor,
23
+ glassIntensity,
18
24
  ...rest
19
25
  }) {
20
- // Resolve token values (fall back to sensible defaults)
26
+ const isGlass = type === 'glass';
27
+ const hasLeading = leading != null;
28
+
29
+ // Resolve token values (fall back to sensible defaults). The glass type
30
+ // swaps the solid fill for a translucent overlay + white label, matching the
31
+ // Figma `badge/glass/*` tokens.
21
32
  const backgroundColor = getVariableByName('badge/color/background', modes) || '#d8effe';
22
- const labelColor = getVariableByName('badge/color/label', modes) || '#000000';
33
+ const glassBackground = getVariableByName('badge/glass/color/background', modes) || '#ffffff26';
34
+ const glassLabelColor = getVariableByName('badge/glass/color/label', modes) || '#ffffff';
35
+ const labelColor = isGlass ? glassLabelColor : getVariableByName('badge/color/label', modes) || '#000000';
23
36
  const fontSize = Number(getVariableByName('badge/label/fontSize', modes)) || 12;
24
37
  const fontFamily = getVariableByName('badge/fontFamily', modes) || undefined;
25
38
  const fontWeight = getVariableByName('badge/label/fontWeight', modes) || '600';
@@ -27,6 +40,9 @@ function Badge({
27
40
  const paddingVertical = Number(getVariableByName('badge/padding/vertical', modes)) || 4;
28
41
  const borderRadius = Number(getVariableByName('badge/radius', modes)) || 4;
29
42
  const lineHeight = Number(getVariableByName('badge/label/lineHeight', modes)) || Math.round(fontSize * 1.2);
43
+ // Figma `blur/minimal` (px radius) -> GlassFill's 0–100 intensity scale, the
44
+ // same 1:1 mapping the merchandising card footer uses.
45
+ const blurIntensity = Math.max(0, Math.min(100, Math.round(Number(getVariableByName('blur/minimal', modes)) || 29)));
30
46
 
31
47
  // Skeleton short-circuit. Size derived from the same tokens the loaded
32
48
  // badge would use so the placeholder occupies the same box.
@@ -49,13 +65,25 @@ function Badge({
49
65
  }
50
66
  const Container = onPress ? Pressable : View;
51
67
  const containerStyle = {
52
- backgroundColor,
68
+ // Glass keeps the container transparent so the GlassFill blur shows through;
69
+ // `overflow: 'hidden'` clips the native blur view to the rounded pill (the
70
+ // blur view does not honor borderRadius itself).
71
+ backgroundColor: isGlass ? 'transparent' : backgroundColor,
53
72
  paddingHorizontal,
54
73
  paddingVertical,
55
74
  borderRadius,
56
75
  alignSelf: 'flex-start',
57
76
  alignItems: 'center',
58
77
  justifyContent: 'center',
78
+ // A leading node sits in-line before the label, so switch to a row with a
79
+ // small gap. Consumer `style` (spread last) can still override either.
80
+ ...(hasLeading ? {
81
+ flexDirection: 'row',
82
+ gap: 4
83
+ } : null),
84
+ ...(isGlass ? {
85
+ overflow: 'hidden'
86
+ } : null),
59
87
  ...(style || {})
60
88
  };
61
89
  const textStyle = {
@@ -68,19 +96,30 @@ function Badge({
68
96
  ...(labelStyle || {})
69
97
  };
70
98
  const defaultAccessibilityLabel = accessibilityLabel || label;
71
- return /*#__PURE__*/_jsx(Container, {
99
+ return /*#__PURE__*/_jsxs(Container, {
72
100
  style: containerStyle,
73
101
  accessibilityRole: onPress ? 'button' : 'text',
74
102
  accessibilityLabel: undefined,
75
103
  onPress: onPress,
76
104
  ...rest,
77
- children: /*#__PURE__*/_jsx(Text, {
105
+ children: [isGlass ? /*#__PURE__*/_jsx(GlassFill, {
106
+ tint: "light",
107
+ intensity: glassIntensity ?? blurIntensity,
108
+ overlayColor: glassOverlayColor ?? glassBackground,
109
+ androidTintWash: false
110
+ }) : null, hasLeading ? /*#__PURE__*/_jsx(View, {
111
+ style: LEADING_WRAP,
112
+ children: leading
113
+ }) : null, /*#__PURE__*/_jsx(Text, {
78
114
  style: textStyle,
79
- numberOfLines: 1,
80
- ellipsizeMode: "tail",
115
+ ...resolveTruncation(disableTruncation, 1, 'tail'),
81
116
  accessibilityElementsHidden: false,
82
117
  children: label
83
- })
118
+ })]
84
119
  });
85
120
  }
121
+ const LEADING_WRAP = {
122
+ justifyContent: 'center',
123
+ alignItems: 'center'
124
+ };
86
125
  export default Badge;
@@ -4,7 +4,7 @@ import React, { useMemo } from 'react';
4
4
  import { Pressable, 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 Avatar from '../Avatar/Avatar';
9
9
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const toNumber = (value, fallback) => {
@@ -89,7 +89,8 @@ function BrandChip({
89
89
  modes: propModes = EMPTY_MODES,
90
90
  style,
91
91
  labelStyle,
92
- accessibilityLabel
92
+ accessibilityLabel,
93
+ disableTruncation
93
94
  }) {
94
95
  const {
95
96
  modes: globalModes
@@ -120,8 +121,7 @@ function BrandChip({
120
121
  const content = /*#__PURE__*/_jsxs(_Fragment, {
121
122
  children: [avatarNode, /*#__PURE__*/_jsx(Text, {
122
123
  style: [tokens.labelStyle, labelStyle],
123
- numberOfLines: 1,
124
- ellipsizeMode: "tail",
124
+ ...resolveTruncation(disableTruncation, 1, 'tail'),
125
125
  children: label
126
126
  })]
127
127
  });
@@ -4,7 +4,7 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
4
4
  import { Platform, Pressable, Text, View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { usePressableWebSupport } from '../../utils/web-platform-utils';
7
- import { EMPTY_MODES } from '../../utils/react-utils';
7
+ import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
8
8
  import Icon from '../../icons/Icon';
9
9
  import Skeleton from '../../skeleton/Skeleton';
10
10
  import { useSkeleton } from '../../skeleton/SkeletonGroup';
@@ -170,6 +170,7 @@ function ButtonImpl({
170
170
  accessibilityState,
171
171
  webAccessibilityProps,
172
172
  loading,
173
+ disableTruncation,
173
174
  ...rest
174
175
  }) {
175
176
  // Hover state is web-only in practice; the setter is gated so native taps
@@ -214,7 +215,7 @@ function ButtonImpl({
214
215
  } else {
215
216
  content = /*#__PURE__*/_jsx(Text, {
216
217
  style: activeLabelStyle,
217
- numberOfLines: 1,
218
+ ...resolveTruncation(disableTruncation, 1),
218
219
  children: label
219
220
  });
220
221
  }
@@ -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 CircularProgressBar from '../CircularProgressBar/CircularProgressBar';
10
10
  import Nudge from '../Nudge/Nudge';
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -120,6 +120,7 @@ function CardAdvisory({
120
120
  progressStyle,
121
121
  nudgeStyle,
122
122
  accessibilityLabel,
123
+ disableTruncation,
123
124
  ...rest
124
125
  }) {
125
126
  const {
@@ -157,7 +158,7 @@ function CardAdvisory({
157
158
  children: [/*#__PURE__*/_jsxs(View, {
158
159
  style: tokens.headerStyle,
159
160
  children: [/*#__PURE__*/_jsx(Text, {
160
- numberOfLines: 1,
161
+ ...resolveTruncation(disableTruncation, 1),
161
162
  style: [tokens.titleStyle, titleStyle],
162
163
  children: title
163
164
  }), processedTitleEndSlot || (showInfoIcon ? /*#__PURE__*/_jsx(Icon, {