jfs-components 0.0.74 → 0.0.77

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 (92) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/lib/commonjs/components/ActionFooter/ActionFooter.js +147 -82
  3. package/lib/commonjs/components/Avatar/Avatar.js +20 -0
  4. package/lib/commonjs/components/Badge/Badge.js +23 -0
  5. package/lib/commonjs/components/Button/Button.js +37 -0
  6. package/lib/commonjs/components/IconButton/IconButton.js +20 -0
  7. package/lib/commonjs/components/Image/Image.js +26 -1
  8. package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
  9. package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
  10. package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
  11. package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
  12. package/lib/commonjs/components/PageHero/PageHero.js +41 -5
  13. package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
  14. package/lib/commonjs/components/Text/Text.js +31 -1
  15. package/lib/commonjs/components/index.js +7 -0
  16. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  17. package/lib/commonjs/icons/Icon.js +16 -0
  18. package/lib/commonjs/icons/registry.js +1 -1
  19. package/lib/commonjs/index.js +12 -0
  20. package/lib/commonjs/skeleton/Skeleton.js +234 -0
  21. package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
  22. package/lib/commonjs/skeleton/index.js +58 -0
  23. package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
  24. package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
  25. package/lib/module/components/ActionFooter/ActionFooter.js +146 -82
  26. package/lib/module/components/Avatar/Avatar.js +19 -0
  27. package/lib/module/components/Badge/Badge.js +23 -0
  28. package/lib/module/components/Button/Button.js +37 -0
  29. package/lib/module/components/IconButton/IconButton.js +20 -0
  30. package/lib/module/components/Image/Image.js +25 -1
  31. package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
  32. package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
  33. package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
  34. package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
  35. package/lib/module/components/PageHero/PageHero.js +41 -5
  36. package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
  37. package/lib/module/components/Text/Text.js +31 -1
  38. package/lib/module/components/index.js +1 -0
  39. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  40. package/lib/module/icons/Icon.js +16 -0
  41. package/lib/module/icons/registry.js +1 -1
  42. package/lib/module/index.js +2 -1
  43. package/lib/module/skeleton/Skeleton.js +229 -0
  44. package/lib/module/skeleton/SkeletonGroup.js +133 -0
  45. package/lib/module/skeleton/index.js +6 -0
  46. package/lib/module/skeleton/shimmer-tokens.js +181 -0
  47. package/lib/module/skeleton/useReducedMotion.js +61 -0
  48. package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
  49. package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
  50. package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
  51. package/lib/typescript/src/components/Button/Button.d.ts +8 -1
  52. package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
  53. package/lib/typescript/src/components/Image/Image.d.ts +8 -1
  54. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
  55. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
  56. package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
  57. package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
  58. package/lib/typescript/src/components/PageHero/PageHero.d.ts +31 -5
  59. package/lib/typescript/src/components/Text/Text.d.ts +20 -1
  60. package/lib/typescript/src/components/index.d.ts +1 -0
  61. package/lib/typescript/src/icons/Icon.d.ts +7 -1
  62. package/lib/typescript/src/icons/registry.d.ts +1 -1
  63. package/lib/typescript/src/index.d.ts +1 -0
  64. package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
  65. package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
  66. package/lib/typescript/src/skeleton/index.d.ts +5 -0
  67. package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
  68. package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
  69. package/package.json +11 -1
  70. package/src/components/ActionFooter/ActionFooter.tsx +152 -86
  71. package/src/components/Avatar/Avatar.tsx +26 -0
  72. package/src/components/Badge/Badge.tsx +27 -0
  73. package/src/components/Button/Button.tsx +40 -0
  74. package/src/components/IconButton/IconButton.tsx +27 -0
  75. package/src/components/Image/Image.tsx +25 -0
  76. package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
  77. package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
  78. package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
  79. package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
  80. package/src/components/PageHero/PageHero.tsx +61 -4
  81. package/src/components/RechargeCard/RechargeCard.tsx +32 -24
  82. package/src/components/Text/Text.tsx +54 -0
  83. package/src/components/index.ts +1 -0
  84. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  85. package/src/icons/Icon.tsx +17 -0
  86. package/src/icons/registry.ts +1 -1
  87. package/src/index.ts +1 -0
  88. package/src/skeleton/Skeleton.tsx +298 -0
  89. package/src/skeleton/SkeletonGroup.tsx +193 -0
  90. package/src/skeleton/index.ts +10 -0
  91. package/src/skeleton/shimmer-tokens.ts +221 -0
  92. package/src/skeleton/useReducedMotion.ts +72 -0
@@ -1,11 +1,26 @@
1
- import React, { isValidElement, cloneElement } from 'react';
2
- import { View, Text, StyleSheet, type ViewStyle } from 'react-native';
1
+ import React from 'react';
2
+ import { View, Text, type ViewStyle } from 'react-native';
3
3
  import ButtonGroup from '../ButtonGroup/ButtonGroup';
4
4
  import AvatarGroup from '../AvatarGroup/AvatarGroup';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { EMPTY_MODES } from '../../utils/react-utils';
7
7
  import MoneyValue from '../MoneyValue/MoneyValue';
8
- import Button from '../Button/Button';
8
+
9
+ // Defaults applied to the inner ButtonGroup so the card matches Figma out of
10
+ // the box. They are spread *before* the caller's `modes` so any consumer can
11
+ // override an individual key (e.g. swap the size to "M").
12
+ const DEFAULT_BUTTON_GROUP_MODES: Record<string, string> = {
13
+ AppearanceBrand: 'Secondary',
14
+ 'Button / Size': 'S',
15
+ Emphasis: 'High',
16
+ };
17
+
18
+ // Defaults applied to the inner MoneyValue so the price renders at the
19
+ // 36 px / 900-weight scale defined for cards in Figma. Same merge rule as
20
+ // the button group — consumer `modes` override these.
21
+ const DEFAULT_MONEY_VALUE_MODES: Record<string, string> = {
22
+ Context3: 'Balance & Cards',
23
+ };
9
24
 
10
25
 
11
26
  export type RechargeCardProps = {
@@ -66,17 +81,19 @@ export default function RechargeCard({
66
81
  modes = EMPTY_MODES,
67
82
  style,
68
83
  }: RechargeCardProps) {
69
- // Container Tokens
70
- const backgroundColor = getVariableByName('rechargeCard/background', modes) || '#f6f3ff';
84
+ // Container Tokens (defaults mirror Figma node 2235:937).
85
+ const backgroundColor = getVariableByName('rechargeCard/background', modes) || '#ffffff';
71
86
  const paddingHorizontal = parseInt(getVariableByName('rechargeCard/padding/horizontal', modes) || 16, 10);
72
87
  const paddingVertical = parseInt(getVariableByName('rechargeCard/padding/vertical', modes) || 20, 10);
73
88
  const gap = parseInt(getVariableByName('rechargeCard/gap', modes) || 20, 10);
74
89
  const radius = parseInt(getVariableByName('rechargeCard/radius', modes) || 20, 10);
75
- const minWidth = parseInt(getVariableByName('rechargeCard/minWidth', modes) || 328, 10);
90
+ const minWidth = parseInt(getVariableByName('rechargeCard/minWidth', modes) || 312, 10);
91
+ const strokeWidth = parseInt(getVariableByName('rechargeCard/strokeWidth', modes) || 1, 10);
92
+ const strokeColor = getVariableByName('rechargeCard/stroke/color', modes) || '#ebebed';
76
93
 
77
94
  // Header Tokens
78
95
  const headerGap = parseInt(getVariableByName('rechargeCard/header/gap', modes) || 4, 10);
79
- const titleColor = getVariableByName('rechargeCard/title/color', modes) || '#13002d';
96
+ const titleColor = getVariableByName('rechargeCard/title/color', modes) || '#000000';
80
97
  const titleFontSize = parseInt(getVariableByName('rechargeCard/title/fontSize', modes) || 12, 10);
81
98
  const titleFontFamily = getVariableByName('rechargeCard/title/fontFamily', modes) || 'JioType Var';
82
99
  const titleLineHeight = parseInt(getVariableByName('rechargeCard/title/lineHeight', modes) || 14, 10);
@@ -87,30 +104,26 @@ export default function RechargeCard({
87
104
  const specItemGap = parseInt(getVariableByName('rechargeCard/specItem/gap', modes) || 4, 10);
88
105
 
89
106
  // Spec Label Tokens
90
- const specLabelColor = getVariableByName('rechargeCard/specItem/label/color', modes) || '#13002d';
107
+ const specLabelColor = getVariableByName('rechargeCard/specItem/label/color', modes) || '#000000';
91
108
  const specLabelFontSize = parseInt(getVariableByName('rechargeCard/specItem/label/fontSize', modes) || 12, 10);
92
109
  const specLabelFontFamily = getVariableByName('rechargeCard/specItem/label/fontFamily', modes) || 'JioType Var';
93
110
  const specLabelLineHeight = parseInt(getVariableByName('rechargeCard/specItem/label/lineHeight', modes) || 14, 10);
94
111
  const specLabelFontWeight = getVariableByName('rechargeCard/specItem/label/fontWeight', modes) || '500';
95
112
 
96
113
  // Spec Value Tokens
97
- const specValueColor = getVariableByName('rechargeCard/specItem/value/color', modes) || '#310064';
114
+ const specValueColor = getVariableByName('rechargeCard/specItem/value/color', modes) || '#000000';
98
115
  const specValueFontSize = parseInt(getVariableByName('rechargeCard/specItem/value/fontSize', modes) || 14, 10);
99
116
  const specValueFontFamily = getVariableByName('rechargeCard/specItem/value/fontFamily', modes) || 'JioType Var';
100
117
  const specValueLineHeight = parseInt(getVariableByName('rechargeCard/specItem/value/lineHeight', modes) || 17, 10);
101
118
  const specValueFontWeight = getVariableByName('rechargeCard/specItem/value/fontWeight', modes) || '500';
102
119
 
103
120
  // Disclaimer Tokens
104
- const disclaimerColor = getVariableByName('rechargeCard/disclaimer/color', modes) || '#22004a';
121
+ const disclaimerColor = getVariableByName('rechargeCard/disclaimer/color', modes) || '#000000';
105
122
  const disclaimerFontSize = parseInt(getVariableByName('rechargeCard/disclaimer/fontSize', modes) || 10, 10);
106
123
  const disclaimerFontFamily = getVariableByName('rechargeCard/disclaimer/fontFamily', modes) || 'JioType Var';
107
124
  const disclaimerLineHeight = parseInt(getVariableByName('rechargeCard/disclaimer/lineHeight', modes) || 13, 10);
108
125
  const disclaimerFontWeight = getVariableByName('rechargeCard/disclaimer/fontWeight', modes) || '400';
109
126
 
110
- // Button Group Tokens
111
- // Handled by ButtonGroup component directly
112
-
113
- // Helpers
114
127
  const resolveFontWeight = (weight: string | number) => typeof weight === 'number' ? weight.toString() : weight;
115
128
 
116
129
  // Pass modes to subscription children (e.g. AvatarGroup)
@@ -125,6 +138,8 @@ export default function RechargeCard({
125
138
  paddingVertical,
126
139
  gap,
127
140
  borderRadius: radius,
141
+ borderWidth: strokeWidth,
142
+ borderColor: strokeColor,
128
143
  minWidth,
129
144
  alignItems: 'flex-start',
130
145
  }, style]}>
@@ -142,7 +157,7 @@ export default function RechargeCard({
142
157
  <MoneyValue
143
158
  value={price}
144
159
  currency="₹"
145
- modes={modes}
160
+ modes={{ ...DEFAULT_MONEY_VALUE_MODES, ...modes }}
146
161
  />
147
162
  </View>
148
163
 
@@ -224,15 +239,8 @@ export default function RechargeCard({
224
239
  {disclaimer}
225
240
  </Text>
226
241
 
227
- {/* Button Group */}
228
- <ButtonGroup
229
- modes={{
230
- ...modes,
231
- "Appearance.Brand": "Secondary",
232
- "Button / Size": "S",
233
- "Emphasis": "High"
234
- }}
235
- >
242
+ {/* Button Group: defaults are overridable via the consumer's `modes` */}
243
+ <ButtonGroup modes={{ ...DEFAULT_BUTTON_GROUP_MODES, ...modes }}>
236
244
  {actions}
237
245
  </ButtonGroup>
238
246
  </View>
@@ -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,
@@ -47,6 +47,7 @@ export { default as LinearMeter, type LinearMeterProps } from './LinearMeter/Lin
47
47
  export { default as LinearProgress, type LinearProgressProps } from './LinearProgress/LinearProgress';
48
48
  export { default as ListGroup } from './ListGroup/ListGroup';
49
49
  export { default as LottieIntroBlock, type LottieIntroBlockProps } from './LottieIntroBlock/LottieIntroBlock';
50
+ export { default as LottiePlayer, type LottiePlayerProps, type LottieAnimationSource } from './LottiePlayer/LottiePlayer';
50
51
  export { default as ListItem } from './ListItem/ListItem';
51
52
  export { default as MediaCard, type MediaCardProps } from './MediaCard/MediaCard';
52
53
  export { default as MerchantProfile, type MerchantProfileProps } from './MerchantProfile/MerchantProfile';