jfs-components 0.0.74 → 0.0.78

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 (146) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/lib/commonjs/components/Accordion/Accordion.js +55 -55
  3. package/lib/commonjs/components/ActionFooter/ActionFooter.js +193 -82
  4. package/lib/commonjs/components/Avatar/Avatar.js +20 -0
  5. package/lib/commonjs/components/Badge/Badge.js +23 -0
  6. package/lib/commonjs/components/Button/Button.js +37 -0
  7. package/lib/commonjs/components/Checkbox/Checkbox.js +21 -9
  8. package/lib/commonjs/components/DropdownInput/DropdownInput.js +30 -16
  9. package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +167 -0
  10. package/lib/commonjs/components/FormField/FormField.js +14 -1
  11. package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +355 -0
  12. package/lib/commonjs/components/IconButton/IconButton.js +20 -0
  13. package/lib/commonjs/components/Image/Image.js +26 -1
  14. package/lib/commonjs/components/ListItem/ListItem.js +25 -10
  15. package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
  16. package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
  17. package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
  18. package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
  19. package/lib/commonjs/components/MessageField/MessageField.js +318 -0
  20. package/lib/commonjs/components/NavArrow/NavArrow.js +58 -17
  21. package/lib/commonjs/components/PageHero/PageHero.js +41 -5
  22. package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
  23. package/lib/commonjs/components/Stepper/Step.js +47 -60
  24. package/lib/commonjs/components/Stepper/StepLabel.js +40 -10
  25. package/lib/commonjs/components/Stepper/Stepper.js +15 -17
  26. package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +487 -0
  27. package/lib/commonjs/components/Text/Text.js +31 -1
  28. package/lib/commonjs/components/TextInput/TextInput.js +16 -1
  29. package/lib/commonjs/components/Title/Title.js +10 -2
  30. package/lib/commonjs/components/index.js +35 -0
  31. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  32. package/lib/commonjs/icons/Icon.js +16 -0
  33. package/lib/commonjs/icons/registry.js +1 -1
  34. package/lib/commonjs/index.js +12 -0
  35. package/lib/commonjs/skeleton/Skeleton.js +234 -0
  36. package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
  37. package/lib/commonjs/skeleton/index.js +58 -0
  38. package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
  39. package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
  40. package/lib/module/components/Accordion/Accordion.js +56 -56
  41. package/lib/module/components/ActionFooter/ActionFooter.js +193 -83
  42. package/lib/module/components/Avatar/Avatar.js +19 -0
  43. package/lib/module/components/Badge/Badge.js +23 -0
  44. package/lib/module/components/Button/Button.js +37 -0
  45. package/lib/module/components/Checkbox/Checkbox.js +22 -10
  46. package/lib/module/components/DropdownInput/DropdownInput.js +30 -16
  47. package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +161 -0
  48. package/lib/module/components/FormField/FormField.js +16 -3
  49. package/lib/module/components/FullscreenModal/FullscreenModal.js +350 -0
  50. package/lib/module/components/IconButton/IconButton.js +20 -0
  51. package/lib/module/components/Image/Image.js +25 -1
  52. package/lib/module/components/ListItem/ListItem.js +25 -10
  53. package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
  54. package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
  55. package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
  56. package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
  57. package/lib/module/components/MessageField/MessageField.js +313 -0
  58. package/lib/module/components/NavArrow/NavArrow.js +59 -18
  59. package/lib/module/components/PageHero/PageHero.js +41 -5
  60. package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
  61. package/lib/module/components/Stepper/Step.js +48 -61
  62. package/lib/module/components/Stepper/StepLabel.js +40 -10
  63. package/lib/module/components/Stepper/Stepper.js +15 -17
  64. package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +481 -0
  65. package/lib/module/components/Text/Text.js +31 -1
  66. package/lib/module/components/TextInput/TextInput.js +17 -2
  67. package/lib/module/components/Title/Title.js +10 -2
  68. package/lib/module/components/index.js +5 -0
  69. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  70. package/lib/module/icons/Icon.js +16 -0
  71. package/lib/module/icons/registry.js +1 -1
  72. package/lib/module/index.js +2 -1
  73. package/lib/module/skeleton/Skeleton.js +229 -0
  74. package/lib/module/skeleton/SkeletonGroup.js +133 -0
  75. package/lib/module/skeleton/index.js +6 -0
  76. package/lib/module/skeleton/shimmer-tokens.js +181 -0
  77. package/lib/module/skeleton/useReducedMotion.js +61 -0
  78. package/lib/typescript/src/components/Accordion/Accordion.d.ts +14 -20
  79. package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
  80. package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
  81. package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
  82. package/lib/typescript/src/components/Button/Button.d.ts +8 -1
  83. package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +63 -0
  84. package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +99 -0
  85. package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
  86. package/lib/typescript/src/components/Image/Image.d.ts +8 -1
  87. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
  88. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
  89. package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
  90. package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
  91. package/lib/typescript/src/components/MessageField/MessageField.d.ts +81 -0
  92. package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +10 -5
  93. package/lib/typescript/src/components/PageHero/PageHero.d.ts +31 -5
  94. package/lib/typescript/src/components/Stepper/Step.d.ts +4 -1
  95. package/lib/typescript/src/components/Stepper/StepLabel.d.ts +4 -1
  96. package/lib/typescript/src/components/Stepper/Stepper.d.ts +3 -1
  97. package/lib/typescript/src/components/SuggestiveSearch/SuggestiveSearch.d.ts +123 -0
  98. package/lib/typescript/src/components/Text/Text.d.ts +20 -1
  99. package/lib/typescript/src/components/index.d.ts +8 -3
  100. package/lib/typescript/src/icons/Icon.d.ts +7 -1
  101. package/lib/typescript/src/icons/registry.d.ts +1 -1
  102. package/lib/typescript/src/index.d.ts +1 -0
  103. package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
  104. package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
  105. package/lib/typescript/src/skeleton/index.d.ts +5 -0
  106. package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
  107. package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
  108. package/package.json +11 -1
  109. package/src/components/Accordion/Accordion.tsx +113 -73
  110. package/src/components/ActionFooter/ActionFooter.tsx +210 -92
  111. package/src/components/Avatar/Avatar.tsx +26 -0
  112. package/src/components/Badge/Badge.tsx +27 -0
  113. package/src/components/Button/Button.tsx +40 -0
  114. package/src/components/Checkbox/Checkbox.tsx +22 -9
  115. package/src/components/DropdownInput/DropdownInput.tsx +67 -39
  116. package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +237 -0
  117. package/src/components/FormField/FormField.tsx +19 -3
  118. package/src/components/FullscreenModal/FullscreenModal.tsx +414 -0
  119. package/src/components/IconButton/IconButton.tsx +27 -0
  120. package/src/components/Image/Image.tsx +25 -0
  121. package/src/components/ListItem/ListItem.tsx +21 -10
  122. package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
  123. package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
  124. package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
  125. package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
  126. package/src/components/MessageField/MessageField.tsx +543 -0
  127. package/src/components/NavArrow/NavArrow.tsx +81 -17
  128. package/src/components/PageHero/PageHero.tsx +61 -4
  129. package/src/components/RechargeCard/RechargeCard.tsx +32 -24
  130. package/src/components/Stepper/Step.tsx +52 -51
  131. package/src/components/Stepper/StepLabel.tsx +46 -9
  132. package/src/components/Stepper/Stepper.tsx +20 -15
  133. package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +756 -0
  134. package/src/components/Text/Text.tsx +54 -0
  135. package/src/components/TextInput/TextInput.tsx +14 -1
  136. package/src/components/Title/Title.tsx +13 -2
  137. package/src/components/index.ts +8 -3
  138. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  139. package/src/icons/Icon.tsx +17 -0
  140. package/src/icons/registry.ts +1 -1
  141. package/src/index.ts +1 -0
  142. package/src/skeleton/Skeleton.tsx +298 -0
  143. package/src/skeleton/SkeletonGroup.tsx +193 -0
  144. package/src/skeleton/index.ts +10 -0
  145. package/src/skeleton/shimmer-tokens.ts +221 -0
  146. package/src/skeleton/useReducedMotion.ts +72 -0
@@ -2,6 +2,8 @@ import React from 'react'
2
2
  import { Text as RNText, type TextStyle, type StyleProp } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import { EMPTY_MODES } from '../../utils/react-utils'
5
+ import Skeleton from '../../skeleton/Skeleton'
6
+ import { useSkeleton } from '../../skeleton/SkeletonGroup'
5
7
 
6
8
  export type TextProps = {
7
9
  /**
@@ -23,6 +25,25 @@ export type TextProps = {
23
25
  style?: StyleProp<TextStyle>
24
26
  /** Number of lines to limit the text to. */
25
27
  numberOfLines?: number
28
+ /**
29
+ * Explicit per-instance loading override. When `true`, this `Text` renders
30
+ * a skeleton placeholder regardless of any surrounding `<SkeletonGroup>`.
31
+ * When `false`, the surrounding group is ignored for this instance. When
32
+ * omitted, the surrounding group's `loading` flag wins.
33
+ */
34
+ loading?: boolean
35
+ /**
36
+ * Optional width used while the skeleton is showing. Numbers are dp;
37
+ * `'100%'` (etc.) is a valid RN dimension. Defaults to a character-count
38
+ * heuristic based on the resolved font size and the supplied content.
39
+ */
40
+ skeletonWidth?: number | `${number}%`
41
+ /**
42
+ * Optional explicit line count for the skeleton placeholder. Defaults to
43
+ * `numberOfLines ?? 1`. Useful when `numberOfLines` is intentionally
44
+ * unbounded but you want a sensible multi-line placeholder.
45
+ */
46
+ skeletonLines?: number
26
47
  }
27
48
 
28
49
  const TEXT_ALIGN_MAP: Record<NonNullable<TextProps['textAlign']>, TextStyle['textAlign']> = {
@@ -37,6 +58,9 @@ function Text({
37
58
  modes = EMPTY_MODES,
38
59
  style,
39
60
  numberOfLines,
61
+ loading,
62
+ skeletonWidth,
63
+ skeletonLines,
40
64
  }: TextProps) {
41
65
  const foreground = getVariableByName('text/foreground', modes) ?? '#000000'
42
66
  const fontFamily = getVariableByName('text/fontFamily', modes) ?? 'JioType'
@@ -45,6 +69,36 @@ function Text({
45
69
  const lineHeight = getVariableByName('text/lineHeight', modes) ?? 20
46
70
  const letterSpacing = getVariableByName('text/letterSpacing', modes) ?? -0.5
47
71
 
72
+ // Skeleton short-circuit. The hook is always called (stable order); the
73
+ // surrounding group's `active` flag is the default, but an explicit
74
+ // `loading` prop overrides both directions.
75
+ const { active: groupActive } = useSkeleton()
76
+ const isLoading = loading ?? groupActive
77
+ if (isLoading) {
78
+ const resolvedFontSize = fontSize as number
79
+ const resolvedLineHeight = lineHeight as number
80
+ const lines = Math.max(1, skeletonLines ?? numberOfLines ?? 1)
81
+ // Heuristic width based on the actual content length so the placeholder
82
+ // visually matches what's about to load. Capped to a reasonable lower
83
+ // bound so very short labels still produce a visible block.
84
+ const contentLength =
85
+ typeof children === 'string'
86
+ ? children.length
87
+ : typeof text === 'string'
88
+ ? text.length
89
+ : 12
90
+ const charWidth = resolvedFontSize * 0.55
91
+ const computedWidth = Math.max(charWidth * 4, contentLength * charWidth)
92
+ return (
93
+ <Skeleton
94
+ kind="text"
95
+ width={skeletonWidth ?? computedWidth}
96
+ height={resolvedLineHeight * lines}
97
+ modes={modes}
98
+ />
99
+ )
100
+ }
101
+
48
102
  const textStyle: TextStyle = {
49
103
  color: foreground as string,
50
104
  fontFamily: fontFamily as string,
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import React, { useRef, useState } from 'react'
2
2
  import { Pressable, View, TextInput as RNTextInput, type StyleProp, type ViewStyle, type TextInputProps as RNTextInputProps, type TextStyle } from 'react-native'
3
3
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
4
4
  import Icon from '../../icons/Icon'
@@ -128,6 +128,11 @@ function TextInput({
128
128
  // Track focus state to hide placeholder when focused
129
129
  const [isFocused, setIsFocused] = useState(false)
130
130
  const [isHovered, setIsHovered] = useState(false)
131
+ // Ref to the underlying native input so a tap anywhere inside the Pressable
132
+ // wrapper can programmatically focus it. Without this, on Android the
133
+ // wrapping Pressable becomes the touch responder on the first tap and the
134
+ // native input only gains focus on the *second* tap.
135
+ const inputRef = useRef<RNTextInput>(null)
131
136
 
132
137
  // Resolve container tokens
133
138
  const backgroundColor = getVariableByName('textInput/background', modes) || '#f5f5f5'
@@ -227,6 +232,13 @@ function TextInput({
227
232
  style={[containerStyle, focusContainerStyle, hoverStyle, style]}
228
233
  onHoverIn={() => setIsHovered(true)}
229
234
  onHoverOut={() => setIsHovered(false)}
235
+ // Forward taps on the wrapper (padding, leading icon gutter, etc.) to the
236
+ // native input. This guarantees the keyboard opens on the FIRST tap on
237
+ // Android instead of requiring a second tap.
238
+ onPress={() => inputRef.current?.focus()}
239
+ // The native input is the real accessible element; don't add a redundant
240
+ // focusable node for screen readers.
241
+ accessible={false}
230
242
  >
231
243
  {processedLeading && (
232
244
  <View
@@ -237,6 +249,7 @@ function TextInput({
237
249
  </View>
238
250
  )}
239
251
  <RNTextInput
252
+ ref={inputRef}
240
253
  accessibilityLabel={undefined}
241
254
  accessibilityHint={accessibilityHint}
242
255
  placeholder={displayPlaceholder}
@@ -50,8 +50,15 @@ function Title({
50
50
  const labelColor =
51
51
  getVariableByName('title/label/color', modes) || '#0d0d0f'
52
52
  const fontSize = getVariableByName('title/fontSize', modes) || 26
53
- const lineHeight =
53
+ const rawLineHeight =
54
54
  getVariableByName('title/lineHeight', modes) || 26
55
+ // The Figma title tokens ship with `lineHeight === fontSize` (26/26). On
56
+ // native (especially Android) that produces a Text box exactly `lineHeight`
57
+ // tall, which clips descenders like p/g/y/q/j at the bottom — particularly
58
+ // noticeable with `numberOfLines={1}`. Clamp to ~1.2x fontSize so descenders
59
+ // always fit. When a downstream token already provides adequate leading,
60
+ // the original value is preserved.
61
+ const lineHeight = Math.max(rawLineHeight, Math.ceil(fontSize * 1.2))
55
62
  const fontFamily =
56
63
  getVariableByName('title/fontFamily', modes) || 'System'
57
64
  const fontWeightRaw =
@@ -65,8 +72,12 @@ function Title({
65
72
  getVariableByName('pageSubtitle/label/color', modes) || '#0d0d0f'
66
73
  const subtitleFontSize =
67
74
  getVariableByName('pageSubtitle/fontSize', modes) || 14
68
- const subtitleLineHeight =
75
+ const subtitleRawLineHeight =
69
76
  getVariableByName('pageSubtitle/lineHeight', modes) || 18
77
+ const subtitleLineHeight = Math.max(
78
+ subtitleRawLineHeight,
79
+ Math.ceil(subtitleFontSize * 1.2)
80
+ )
70
81
  const subtitleFontFamily =
71
82
  getVariableByName('pageSubtitle/fontFamily', modes) || 'System'
72
83
  const subtitleFontWeightRaw =
@@ -24,9 +24,11 @@ export { default as Divider, type DividerProps, type DividerDirection } from './
24
24
  export { default as Drawer } from './Drawer/Drawer';
25
25
  export { default as Dropdown, DropdownItem, type DropdownProps, type DropdownItemProps } from './Dropdown/Dropdown';
26
26
  export { default as DropdownInput, type DropdownInputProps, type DropdownInputOption, type DropdownInputOptionValue } from './DropdownInput/DropdownInput';
27
+ export { default as SuggestiveSearch, type SuggestiveSearchProps, type SuggestiveSearchOption, type SuggestiveSearchOptionValue, type SuggestiveSearchItem } from './SuggestiveSearch/SuggestiveSearch';
27
28
  export { default as CardCTA, type CardCTAProps, type CardCTAType } from './CardCTA/CardCTA'
28
29
  export { default as DebitCard, type DebitCardProps } from './DebitCard/DebitCard';
29
30
  export { default as FilterBar } from './FilterBar/FilterBar';
31
+ export { default as FullscreenModal, type FullscreenModalProps } from './FullscreenModal/FullscreenModal';
30
32
  export { default as Form, type FormProps } from './Form/Form';
31
33
  export { useFormContext } from './Form/Form';
32
34
  export { default as FormField, type FormFieldProps, type FormFieldType } from './FormField/FormField';
@@ -47,9 +49,11 @@ export { default as LinearMeter, type LinearMeterProps } from './LinearMeter/Lin
47
49
  export { default as LinearProgress, type LinearProgressProps } from './LinearProgress/LinearProgress';
48
50
  export { default as ListGroup } from './ListGroup/ListGroup';
49
51
  export { default as LottieIntroBlock, type LottieIntroBlockProps } from './LottieIntroBlock/LottieIntroBlock';
52
+ export { default as LottiePlayer, type LottiePlayerProps, type LottieAnimationSource } from './LottiePlayer/LottiePlayer';
50
53
  export { default as ListItem } from './ListItem/ListItem';
51
54
  export { default as MediaCard, type MediaCardProps } from './MediaCard/MediaCard';
52
55
  export { default as MerchantProfile, type MerchantProfileProps } from './MerchantProfile/MerchantProfile';
56
+ export { default as MessageField, type MessageFieldProps, type MessageFieldState } from './MessageField/MessageField';
53
57
  export { default as MetricLegendItem, type MetricLegendItemProps } from './MetricLegendItem/MetricLegendItem';
54
58
  export { default as MoneyValue } from './MoneyValue/MoneyValue';
55
59
  export { default as NoteInput, type NoteInputProps } from './NoteInput/NoteInput';
@@ -59,9 +63,9 @@ export { default as Numpad, type NumpadProps, type NumpadKeyValue } from './Nump
59
63
  export { default as Title, type TitleProps } from './Title/Title';
60
64
  export { default as Screen, type ScreenProps } from './Screen/Screen';
61
65
  export { default as Section } from './Section/Section';
62
- export { default as Stepper } from './Stepper/Stepper';
63
- export { Step } from './Stepper/Step';
64
- export { StepLabel } from './Stepper/StepLabel';
66
+ export { default as Stepper, type StepperProps } from './Stepper/Stepper';
67
+ export { Step, type StepProps, type StepStatus } from './Stepper/Step';
68
+ export { StepLabel, type StepLabelProps } from './Stepper/StepLabel';
65
69
  export { default as TextInput } from './TextInput/TextInput';
66
70
  export { default as StatusHero, type StatusHeroProps } from './StatusHero/StatusHero';
67
71
  export { default as ThreadHero, type ThreadHeroProps } from './ThreadHero/ThreadHero';
@@ -82,6 +86,7 @@ export { default as UpiHandle } from './UpiHandle/UpiHandle';
82
86
  export { default as VStack, type VStackProps } from './VStack/VStack';
83
87
  export { default as ChipGroup, type ChipGroupProps } from './ChipGroup/ChipGroup';
84
88
  export { default as EmptyState, type EmptyStateProps } from './EmptyState/EmptyState';
89
+ export { default as ExpandableCheckbox, type ExpandableCheckboxProps } from './ExpandableCheckbox/ExpandableCheckbox';
85
90
  export { default as Accordion, type AccordionProps } from './Accordion/Accordion';
86
91
  export { default as AccordionCheckbox, type AccordionCheckboxProps } from './AccordionCheckbox/AccordionCheckbox';
87
92
  export { default as ActionTile, type ActionTileProps } from './ActionTile/ActionTile';