jfs-components 0.0.79 → 0.0.85

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 (138) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/lib/commonjs/components/AppBar/AppBar.js +70 -6
  3. package/lib/commonjs/components/AreaLineChart/AreaLineChart.js +866 -0
  4. package/lib/commonjs/components/AreaLineChart/chartMath.js +252 -0
  5. package/lib/commonjs/components/Attached/Attached.js +76 -7
  6. package/lib/commonjs/components/BubbleChart/BubbleChart.js +191 -0
  7. package/lib/commonjs/components/BubbleChart/bubblePacking.js +378 -0
  8. package/lib/commonjs/components/Checkbox/Checkbox.js +18 -2
  9. package/lib/commonjs/components/ClusterBubble/ClusterBubble.js +272 -0
  10. package/lib/commonjs/components/Drawer/Drawer.js +6 -1
  11. package/lib/commonjs/components/DropdownInput/DropdownInput.js +30 -6
  12. package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +17 -11
  13. package/lib/commonjs/components/FormField/FormField.js +1 -14
  14. package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +5 -1
  15. package/lib/commonjs/components/ListItem/ListItem.js +6 -11
  16. package/lib/commonjs/components/MessageField/MessageField.js +1 -13
  17. package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +7 -1
  18. package/lib/commonjs/components/PaymentFeedback/PaymentFeedback.js +12 -9
  19. package/lib/commonjs/components/PlanComparisonCard/PlanComparisonCard.js +69 -160
  20. package/lib/commonjs/components/Spinner/Spinner.js +217 -0
  21. package/lib/commonjs/components/TextInput/TextInput.js +33 -18
  22. package/lib/commonjs/components/index.js +34 -0
  23. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  24. package/lib/commonjs/icons/components/IconArrowdown.js +19 -0
  25. package/lib/commonjs/icons/components/IconArrowup.js +19 -0
  26. package/lib/commonjs/icons/components/IconChevrondowncircle.js +19 -0
  27. package/lib/commonjs/icons/components/IconChevronleftcircle.js +19 -0
  28. package/lib/commonjs/icons/components/IconChevronrightcircle.js +19 -0
  29. package/lib/commonjs/icons/components/IconChevronupcircle.js +19 -0
  30. package/lib/commonjs/icons/components/IconOsnavback.js +19 -0
  31. package/lib/commonjs/icons/components/IconOsnavcenter.js +19 -0
  32. package/lib/commonjs/icons/components/IconOsnavhome.js +19 -0
  33. package/lib/commonjs/icons/components/IconOsnavtask.js +19 -0
  34. package/lib/commonjs/icons/components/IconSignin.js +19 -0
  35. package/lib/commonjs/icons/components/IconSignout.js +19 -0
  36. package/lib/commonjs/icons/components/index.js +132 -0
  37. package/lib/commonjs/icons/registry.js +2 -2
  38. package/lib/module/components/AppBar/AppBar.js +70 -6
  39. package/lib/module/components/AreaLineChart/AreaLineChart.js +859 -0
  40. package/lib/module/components/AreaLineChart/chartMath.js +242 -0
  41. package/lib/module/components/Attached/Attached.js +76 -7
  42. package/lib/module/components/BubbleChart/BubbleChart.js +185 -0
  43. package/lib/module/components/BubbleChart/bubblePacking.js +370 -0
  44. package/lib/module/components/Checkbox/Checkbox.js +18 -2
  45. package/lib/module/components/ClusterBubble/ClusterBubble.js +267 -0
  46. package/lib/module/components/Drawer/Drawer.js +6 -1
  47. package/lib/module/components/DropdownInput/DropdownInput.js +30 -6
  48. package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +17 -11
  49. package/lib/module/components/FormField/FormField.js +3 -16
  50. package/lib/module/components/FullscreenModal/FullscreenModal.js +5 -1
  51. package/lib/module/components/ListItem/ListItem.js +6 -11
  52. package/lib/module/components/MessageField/MessageField.js +3 -15
  53. package/lib/module/components/MetricLegendItem/MetricLegendItem.js +7 -1
  54. package/lib/module/components/PaymentFeedback/PaymentFeedback.js +13 -9
  55. package/lib/module/components/PlanComparisonCard/PlanComparisonCard.js +72 -160
  56. package/lib/module/components/Spinner/Spinner.js +212 -0
  57. package/lib/module/components/TextInput/TextInput.js +34 -19
  58. package/lib/module/components/index.js +4 -0
  59. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  60. package/lib/module/icons/components/IconArrowdown.js +12 -0
  61. package/lib/module/icons/components/IconArrowup.js +12 -0
  62. package/lib/module/icons/components/IconChevrondowncircle.js +12 -0
  63. package/lib/module/icons/components/IconChevronleftcircle.js +12 -0
  64. package/lib/module/icons/components/IconChevronrightcircle.js +12 -0
  65. package/lib/module/icons/components/IconChevronupcircle.js +12 -0
  66. package/lib/module/icons/components/IconOsnavback.js +12 -0
  67. package/lib/module/icons/components/IconOsnavcenter.js +12 -0
  68. package/lib/module/icons/components/IconOsnavhome.js +12 -0
  69. package/lib/module/icons/components/IconOsnavtask.js +12 -0
  70. package/lib/module/icons/components/IconSignin.js +12 -0
  71. package/lib/module/icons/components/IconSignout.js +12 -0
  72. package/lib/module/icons/components/index.js +12 -0
  73. package/lib/module/icons/registry.js +2 -2
  74. package/lib/typescript/src/components/AppBar/AppBar.d.ts +12 -1
  75. package/lib/typescript/src/components/AreaLineChart/AreaLineChart.d.ts +212 -0
  76. package/lib/typescript/src/components/AreaLineChart/chartMath.d.ts +90 -0
  77. package/lib/typescript/src/components/Attached/Attached.d.ts +19 -16
  78. package/lib/typescript/src/components/BubbleChart/BubbleChart.d.ts +81 -0
  79. package/lib/typescript/src/components/BubbleChart/bubblePacking.d.ts +83 -0
  80. package/lib/typescript/src/components/ClusterBubble/ClusterBubble.d.ts +76 -0
  81. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +3 -2
  82. package/lib/typescript/src/components/ListItem/ListItem.d.ts +3 -3
  83. package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +7 -1
  84. package/lib/typescript/src/components/PaymentFeedback/PaymentFeedback.d.ts +5 -1
  85. package/lib/typescript/src/components/PlanComparisonCard/PlanComparisonCard.d.ts +10 -8
  86. package/lib/typescript/src/components/Spinner/Spinner.d.ts +45 -0
  87. package/lib/typescript/src/components/index.d.ts +4 -0
  88. package/lib/typescript/src/icons/components/IconArrowdown.d.ts +3 -0
  89. package/lib/typescript/src/icons/components/IconArrowup.d.ts +3 -0
  90. package/lib/typescript/src/icons/components/IconChevrondowncircle.d.ts +3 -0
  91. package/lib/typescript/src/icons/components/IconChevronleftcircle.d.ts +3 -0
  92. package/lib/typescript/src/icons/components/IconChevronrightcircle.d.ts +3 -0
  93. package/lib/typescript/src/icons/components/IconChevronupcircle.d.ts +3 -0
  94. package/lib/typescript/src/icons/components/IconOsnavback.d.ts +3 -0
  95. package/lib/typescript/src/icons/components/IconOsnavcenter.d.ts +3 -0
  96. package/lib/typescript/src/icons/components/IconOsnavhome.d.ts +3 -0
  97. package/lib/typescript/src/icons/components/IconOsnavtask.d.ts +3 -0
  98. package/lib/typescript/src/icons/components/IconSignin.d.ts +3 -0
  99. package/lib/typescript/src/icons/components/IconSignout.d.ts +3 -0
  100. package/lib/typescript/src/icons/components/index.d.ts +12 -0
  101. package/lib/typescript/src/icons/registry.d.ts +1 -1
  102. package/package.json +3 -2
  103. package/src/components/AppBar/AppBar.tsx +92 -12
  104. package/src/components/AreaLineChart/AreaLineChart.tsx +1161 -0
  105. package/src/components/AreaLineChart/chartMath.ts +265 -0
  106. package/src/components/Attached/Attached.tsx +94 -7
  107. package/src/components/BubbleChart/BubbleChart.tsx +319 -0
  108. package/src/components/BubbleChart/bubblePacking.ts +397 -0
  109. package/src/components/Checkbox/Checkbox.tsx +14 -2
  110. package/src/components/ClusterBubble/ClusterBubble.tsx +359 -0
  111. package/src/components/Drawer/Drawer.tsx +4 -0
  112. package/src/components/DropdownInput/DropdownInput.tsx +54 -20
  113. package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +13 -9
  114. package/src/components/FormField/FormField.tsx +3 -19
  115. package/src/components/FullscreenModal/FullscreenModal.tsx +3 -0
  116. package/src/components/ListItem/ListItem.tsx +14 -16
  117. package/src/components/MessageField/MessageField.tsx +3 -18
  118. package/src/components/MetricLegendItem/MetricLegendItem.tsx +20 -6
  119. package/src/components/PaymentFeedback/PaymentFeedback.tsx +15 -8
  120. package/src/components/PlanComparisonCard/PlanComparisonCard.tsx +82 -192
  121. package/src/components/Spinner/Spinner.tsx +273 -0
  122. package/src/components/TextInput/TextInput.tsx +37 -19
  123. package/src/components/index.ts +4 -0
  124. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  125. package/src/icons/components/IconArrowdown.tsx +11 -0
  126. package/src/icons/components/IconArrowup.tsx +11 -0
  127. package/src/icons/components/IconChevrondowncircle.tsx +11 -0
  128. package/src/icons/components/IconChevronleftcircle.tsx +11 -0
  129. package/src/icons/components/IconChevronrightcircle.tsx +11 -0
  130. package/src/icons/components/IconChevronupcircle.tsx +11 -0
  131. package/src/icons/components/IconOsnavback.tsx +11 -0
  132. package/src/icons/components/IconOsnavcenter.tsx +11 -0
  133. package/src/icons/components/IconOsnavhome.tsx +11 -0
  134. package/src/icons/components/IconOsnavtask.tsx +11 -0
  135. package/src/icons/components/IconSignin.tsx +11 -0
  136. package/src/icons/components/IconSignout.tsx +11 -0
  137. package/src/icons/components/index.ts +12 -0
  138. package/src/icons/registry.ts +49 -1
@@ -145,7 +145,7 @@ function DropdownInput({
145
145
  supportText,
146
146
  errorMessage,
147
147
  menuMaxHeight = 240,
148
- menuOffset = 6,
148
+ menuOffset,
149
149
  matchTriggerWidth = true,
150
150
  closeOnBackdropPress = true,
151
151
  modes: propModes = _reactUtils.EMPTY_MODES,
@@ -208,10 +208,29 @@ function DropdownInput({
208
208
  const tokens = useFormFieldTokens(modes);
209
209
  const chevron = useChevronTokens(modes);
210
210
 
211
+ // Gap between the input and the popup. Falls back to the `formField/gap`
212
+ // token so the menu's offset matches the field's own internal spacing.
213
+ const effectiveMenuOffset = menuOffset ?? tokens.gap;
214
+
211
215
  // ---------------- Layout / measurement ----------------
212
216
  const triggerRef = (0, _react.useRef)(null);
213
217
  const [triggerRect, setTriggerRect] = (0, _react.useState)(null);
214
218
  const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
219
+
220
+ // Android coordinate-space bridge.
221
+ //
222
+ // The popup lives inside a `statusBarTranslucent` Modal, whose window is
223
+ // laid out from the PHYSICAL top of the screen (behind the status bar).
224
+ // The trigger, however, is rendered inside the app's content area (Expo
225
+ // Router / react-native-screens under edge-to-edge), so its
226
+ // `measureInWindow` Y is relative to the content area — it does NOT include
227
+ // the status bar height. Feeding that Y straight into the Modal would place
228
+ // the popup one status-bar-height too high, landing it on top of the input.
229
+ //
230
+ // Adding `insets.top` converts the trigger's content-relative Y into the
231
+ // Modal's full-screen coordinate space. iOS/web share a single coordinate
232
+ // space for the Modal and the trigger, so no shift is needed there.
233
+ const windowTopOffset = _reactNative.Platform.OS === 'android' ? insets.top : 0;
215
234
  const measure = (0, _react.useCallback)(() => {
216
235
  if (!triggerRef.current) return;
217
236
  triggerRef.current.measureInWindow((x, y, width, height) => {
@@ -277,7 +296,7 @@ function DropdownInput({
277
296
  const spaceBelow = windowHeight - (triggerRect.y + triggerRect.height) - insets.bottom;
278
297
  const spaceAbove = triggerRect.y - insets.top;
279
298
  const desiredHeight = Math.min(menuSize?.height ?? menuMaxHeight, menuMaxHeight);
280
- const needed = desiredHeight + menuOffset + 8;
299
+ const needed = desiredHeight + effectiveMenuOffset + 8;
281
300
  if (placement === 'top') {
282
301
  return spaceAbove >= needed || spaceAbove >= spaceBelow ? 'top' : 'bottom';
283
302
  }
@@ -285,7 +304,7 @@ function DropdownInput({
285
304
  return spaceBelow >= needed || spaceBelow >= spaceAbove ? 'bottom' : 'top';
286
305
  }
287
306
  return spaceBelow >= needed || spaceBelow >= spaceAbove ? 'bottom' : 'top';
288
- }, [triggerRect, placement, windowHeight, menuSize?.height, menuMaxHeight, menuOffset, insets.top, insets.bottom]);
307
+ }, [triggerRect, placement, windowHeight, menuSize?.height, menuMaxHeight, effectiveMenuOffset, insets.top, insets.bottom]);
289
308
  const popupStyle = (0, _react.useMemo)(() => {
290
309
  if (!triggerRect) {
291
310
  return {
@@ -304,15 +323,18 @@ function DropdownInput({
304
323
  const minLeft = insets.left + screenPadding;
305
324
  if (leftPos > maxLeft) leftPos = maxLeft;
306
325
  if (leftPos < minLeft) leftPos = minLeft;
326
+
327
+ // Trigger top expressed in the Modal's (full-screen) coordinate space.
328
+ const triggerTop = triggerRect.y + windowTopOffset;
307
329
  let topPos;
308
330
  if (computedPlacement === 'top') {
309
331
  const desiredHeight = menuSize?.height ?? menuMaxHeight;
310
- topPos = triggerRect.y - desiredHeight - menuOffset;
332
+ topPos = triggerTop - desiredHeight - effectiveMenuOffset;
311
333
  if (topPos < insets.top + screenPadding) {
312
334
  topPos = insets.top + screenPadding;
313
335
  }
314
336
  } else {
315
- topPos = triggerRect.y + triggerRect.height + menuOffset;
337
+ topPos = triggerTop + triggerRect.height + effectiveMenuOffset;
316
338
  }
317
339
  const style = {
318
340
  position: 'absolute',
@@ -324,7 +346,7 @@ function DropdownInput({
324
346
  // the wrong place. menuSize becomes truthy after the first layout.
325
347
  if (menuSize == null) style.opacity = 0;
326
348
  return style;
327
- }, [triggerRect, computedPlacement, menuSize, menuOffset, menuMaxHeight, matchTriggerWidth, windowWidth, insets.top, insets.left, insets.right]);
349
+ }, [triggerRect, computedPlacement, menuSize, effectiveMenuOffset, windowTopOffset, menuMaxHeight, matchTriggerWidth, windowWidth, insets.top, insets.left, insets.right]);
328
350
 
329
351
  // Reset menu size when closing so the next open re-measures (handles items
330
352
  // changing while the menu was closed).
@@ -513,6 +535,8 @@ function DropdownInput({
513
535
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
514
536
  visible: isOpen,
515
537
  transparent: true,
538
+ statusBarTranslucent: true,
539
+ navigationBarTranslucent: true,
516
540
  animationType: "fade",
517
541
  onRequestClose: closeMenu,
518
542
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
@@ -88,8 +88,6 @@ function ExpandableCheckbox({
88
88
  }, [disabled, isExpanded, isExpandedControlled, onExpandedChange]);
89
89
  const gap = (0, _figmaVariablesResolver.getVariableByName)('expandableCheckbox/gap', modes) ?? 8;
90
90
  const rowGap = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/gap', modes) ?? 8;
91
- const rowPaddingHorizontal = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/padding/horizontal', modes) ?? 0;
92
- const rowPaddingVertical = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/padding/vertical', modes) ?? 0;
93
91
  const labelColor = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/foreground', modes) ?? '#1a1c1f';
94
92
  const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/label/fontFamily', modes) ?? 'JioType Var';
95
93
  const labelFontSize = (0, _figmaVariablesResolver.getVariableByName)('checkboxItem/label/fontSize', modes) ?? 14;
@@ -110,11 +108,9 @@ function ExpandableCheckbox({
110
108
  alignSelf: isExpanded ? 'stretch' : 'auto',
111
109
  minWidth: 0,
112
110
  flexDirection: 'row',
113
- alignItems: 'flex-start',
114
- gap: rowGap,
115
- paddingHorizontal: rowPaddingHorizontal,
116
- paddingVertical: rowPaddingVertical
117
- }), [isExpanded, rowGap, rowPaddingHorizontal, rowPaddingVertical]);
111
+ alignItems: isExpanded ? 'flex-start' : 'center',
112
+ gap: rowGap
113
+ }), [isExpanded, rowGap]);
118
114
  const resolvedLabelStyle = (0, _react.useMemo)(() => ({
119
115
  flex: 1,
120
116
  minWidth: 0,
@@ -122,11 +118,21 @@ function ExpandableCheckbox({
122
118
  fontFamily: labelFontFamily,
123
119
  fontSize: labelFontSize,
124
120
  lineHeight: labelLineHeight,
125
- fontWeight: labelFontWeight
126
- }), [labelColor, labelFontFamily, labelFontSize, labelLineHeight, labelFontWeight]);
121
+ fontWeight: labelFontWeight,
122
+ // Android adds asymmetric font padding and top-aligns the glyph inside
123
+ // an inflated line box when `lineHeight` is set. That makes the centered
124
+ // checkbox look like it drops below the text. Disabling the extra
125
+ // padding + centering the glyph keeps the single-line label optically
126
+ // aligned with the checkbox. No-op on iOS / web.
127
+ includeFontPadding: false,
128
+ textAlignVertical: isExpanded ? 'top' : 'center'
129
+ }), [labelColor, labelFontFamily, labelFontSize, labelLineHeight, labelFontWeight, isExpanded]);
130
+
131
+ // Layer component modes first (e.g. Color Mode), then button defaults so
132
+ // Secondary / XS / Low always win unless a dedicated override prop is added.
127
133
  const buttonModes = (0, _react.useMemo)(() => ({
128
- ...BUTTON_DEFAULT_MODES,
129
- ...modes
134
+ ...modes,
135
+ ...BUTTON_DEFAULT_MODES
130
136
  }), [modes]);
131
137
  const a11yLabel = accessibilityLabel ?? (typeof label === 'string' ? label : undefined);
132
138
  const buttonLabel = isExpanded ? readLessLabel : readMoreLabel;
@@ -208,16 +208,6 @@ function FormField({
208
208
  const [isFocused, setIsFocused] = (0, _react.useState)(false);
209
209
  const interactive = !isDisabled && !isReadOnly;
210
210
 
211
- // Ref to the native input so tapping anywhere in the input row (padding,
212
- // leading/trailing gutters) focuses it on the FIRST tap — fixing the Android
213
- // "two taps to open the keyboard" issue caused by the row intercepting the
214
- // initial touch.
215
- const inputRef = (0, _react.useRef)(null);
216
- const focusInput = (0, _react.useCallback)(() => {
217
- if (!interactive) return;
218
- inputRef.current?.focus();
219
- }, [interactive]);
220
-
221
211
  // FormField States cascade — error > read only/disabled > active (focused) > idle.
222
212
  // Disabled maps to "Read Only" since there is no dedicated disabled mode and
223
213
  // the visual treatment is closest. This is only the DEFAULT — an explicit
@@ -350,16 +340,13 @@ function FormField({
350
340
  style: requiredIndicatorStyle,
351
341
  children: " *"
352
342
  })]
353
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
343
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
354
344
  style: [inputRowStyle, inputStyle],
355
- onPress: focusInput,
356
- accessible: false,
357
345
  children: [processedLeading != null && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
358
346
  accessibilityElementsHidden: true,
359
347
  importantForAccessibility: "no",
360
348
  children: processedLeading
361
349
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
362
- ref: inputRef,
363
350
  style: [inputTextStyles, inputTextStyle],
364
351
  value: value ?? '',
365
352
  onChangeText: handleChangeText,
@@ -301,7 +301,11 @@ function FullscreenModal({
301
301
  contentContainerStyle: scrollContentStyle,
302
302
  showsVerticalScrollIndicator: false,
303
303
  onScroll: onScroll,
304
- scrollEventThrottle: 16,
304
+ scrollEventThrottle: 16
305
+ // Tap an input in the body and it focuses on the FIRST tap, even when
306
+ // the keyboard is already open (default 'never' eats that tap).
307
+ ,
308
+ keyboardShouldPersistTaps: "handled",
305
309
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
306
310
  style: heroTextRegionStyle,
307
311
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(HeroText, {
@@ -7,7 +7,6 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
- var _IconCapsule = _interopRequireDefault(require("../IconCapsule/IconCapsule"));
11
10
  var _NavArrow = _interopRequireDefault(require("../NavArrow/NavArrow"));
12
11
  var _webPlatformUtils = require("../../utils/web-platform-utils");
13
12
  var _reactUtils = require("../../utils/react-utils");
@@ -150,7 +149,7 @@ const verticalSupportTextOverride = {
150
149
  * @param {string} [props.title='Title'] - Primary title used in the horizontal layout.
151
150
  * @param {string} [props.supportText='Support Text'] - Support text used in both layouts when `supportSlot` is not provided.
152
151
  * @param {boolean} [props.showSupportText=true] - Toggles rendering of the support text in Horizontal layout.
153
- * @param {React.ReactNode} [props.leading] - Optional leading slot. Defaults to `IconCapsule`.
152
+ * @param {React.ReactNode|null} [props.leading] - Optional leading slot. Omitted or `null` renders nothing.
154
153
  * @param {React.ReactNode} [props.supportSlot] - Optional custom slot used instead of the default support text block.
155
154
  * @param {React.ReactNode} [props.trailing] - Optional trailing slot (Figma Slot "trailing"). Horizontal layout only.
156
155
  * @param {boolean} [props.navArrow=true] - Whether to show NavArrow on the far right (Horizontal layout only).
@@ -219,13 +218,9 @@ function ListItemImpl({
219
218
  // Process leading slot to pass modes to children. Memoized on
220
219
  // (leading, resolvedModes) so a parent re-render doesn't re-walk the tree.
221
220
  const leadingElement = (0, _react.useMemo)(() => {
222
- const processed = leading ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(leading), tokens.resolvedModes, SLOT_FORCED_MODES) : [];
223
- if (processed.length === 0) {
224
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconCapsule.default, {
225
- modes: tokens.resolvedModes,
226
- accessibilityLabel: undefined
227
- });
228
- }
221
+ if (leading == null) return null;
222
+ const processed = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(leading), tokens.resolvedModes, SLOT_FORCED_MODES);
223
+ if (processed.length === 0) return null;
229
224
  return processed.length === 1 ? processed[0] : processed;
230
225
  }, [leading, tokens.resolvedModes]);
231
226
  const processedSupportSlot = (0, _react.useMemo)(() => {
@@ -275,7 +270,7 @@ function ListItemImpl({
275
270
  if (layout === 'Horizontal') {
276
271
  const innerContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
277
272
  style: innerContentStyleArray,
278
- children: [leadingElement, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
273
+ children: [leadingElement ?? null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
279
274
  style: {
280
275
  flex: 1,
281
276
  minWidth: 1,
@@ -322,7 +317,7 @@ function ListItemImpl({
322
317
  // Vertical layout — icon on top, support text/slot below
323
318
  const verticalContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
324
319
  style: verticalContentStyleArray,
325
- children: [leadingElement, renderSupportContent()]
320
+ children: [leadingElement ?? null, renderSupportContent()]
326
321
  });
327
322
  if (onPress) {
328
323
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
@@ -145,15 +145,6 @@ function MessageField({
145
145
  const currentValue = isControlled ? value : uncontrolledValue;
146
146
  const [isFocused, setIsFocused] = (0, _react.useState)(false);
147
147
  const interactive = !isDisabled && !isReadOnly;
148
-
149
- // Ref to the native textarea so tapping anywhere in the (padded) textarea
150
- // container focuses it on the FIRST tap, fixing the Android "two taps to
151
- // open the keyboard" issue.
152
- const inputRef = (0, _react.useRef)(null);
153
- const focusInput = (0, _react.useCallback)(() => {
154
- if (!interactive) return;
155
- inputRef.current?.focus();
156
- }, [interactive]);
157
148
  const {
158
149
  modes: globalModes
159
150
  } = (0, _JFSThemeProvider.useTokens)();
@@ -288,12 +279,9 @@ function MessageField({
288
279
  style: requiredIndicatorStyle,
289
280
  children: " *"
290
281
  })]
291
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
282
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
292
283
  style: [textareaContainerStyle, textareaStyle],
293
- onPress: focusInput,
294
- accessible: false,
295
284
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
296
- ref: inputRef,
297
285
  multiline: true,
298
286
  value: currentValue,
299
287
  onChangeText: handleChangeText,
@@ -22,6 +22,7 @@ function MetricLegendItem({
22
22
  label = 'Current (4 months)',
23
23
  value,
24
24
  indicatorColor,
25
+ indicatorShape = 'dot',
25
26
  modes = _reactUtils.EMPTY_MODES,
26
27
  style,
27
28
  indicatorStyle,
@@ -54,7 +55,12 @@ function MetricLegendItem({
54
55
  }, style],
55
56
  accessibilityRole: "text",
56
57
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
57
- style: [{
58
+ style: [indicatorShape === 'line' ? {
59
+ width: indicatorSize * 2,
60
+ height: Math.max(2, Math.round(indicatorSize / 4)),
61
+ borderRadius: indicatorRadius,
62
+ backgroundColor: indicatorBg
63
+ } : {
58
64
  width: indicatorSize,
59
65
  height: indicatorSize,
60
66
  borderRadius: indicatorRadius,
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = PaymentFeedback;
7
- var _react = _interopRequireWildcard(require("react"));
7
+ var _react = _interopRequireDefault(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
10
  var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
@@ -12,11 +12,10 @@ var _IconCapsule = _interopRequireDefault(require("../IconCapsule/IconCapsule"))
12
12
  var _reactUtils = require("../../utils/react-utils");
13
13
  var _jsxRuntime = require("react/jsx-runtime");
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
16
15
  function PaymentFeedback({
17
16
  title = '₹50,000',
18
17
  subtitle = 'Payment successful',
19
- body = 'Your payment has been\nsuccessfully processed.',
18
+ body,
20
19
  details = '18 March 2025, 4:15 pm\nTransaction ID: TXN121466784',
21
20
  showDetails = true,
22
21
  iconName = 'ic_confirm',
@@ -103,17 +102,21 @@ function PaymentFeedback({
103
102
  fontWeight: String(detailsFontWeight),
104
103
  textAlign: 'center'
105
104
  };
106
- const mediaContent = /*#__PURE__*/(0, _react.isValidElement)(renderMedia) ? /*#__PURE__*/(0, _react.cloneElement)(renderMedia, {
107
- modes
108
- }) : renderMedia;
105
+
106
+ // Cascade modes into a custom media slot (per the modes-cascade convention);
107
+ // any modes the consumer set on the slot child still take precedence.
108
+ const mediaContent = renderMedia != null ? (0, _reactUtils.cloneChildrenWithModes)(renderMedia, modes) : null;
109
109
  const defaultMedia = /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconCapsule.default, {
110
- iconName: iconName,
110
+ iconName: iconName
111
+ // `positive` is the default; consumers override the capsule color by
112
+ // passing `AppearanceSystem` (or any other mode) via the `modes` prop.
113
+ ,
111
114
  modes: {
115
+ AppearanceSystem: 'positive',
112
116
  ...modes,
113
117
  'Icon Capsule Size': 'L',
114
118
  Emphasis: 'High',
115
- 'Semantic Intent': 'System',
116
- AppearanceSystem: 'positive'
119
+ 'Semantic Intent': 'System'
117
120
  }
118
121
  });
119
122
  const detailLines = details?.split('\n') ?? [];