jfs-components 0.0.95 → 0.1.0
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.
- package/CHANGELOG.md +10 -0
- package/lib/commonjs/components/Drawer/Drawer.js +146 -82
- package/lib/commonjs/components/Dropdown/Dropdown.js +37 -18
- package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +22 -1
- package/lib/commonjs/components/Spinner/Spinner.js +5 -1
- package/lib/commonjs/components/TestimonialsCard/TestimonialsCard.js +121 -0
- package/lib/commonjs/components/index.js +7 -0
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/skeleton/Skeleton.js +10 -2
- package/lib/module/components/Drawer/Drawer.js +148 -84
- package/lib/module/components/Dropdown/Dropdown.js +37 -18
- package/lib/module/components/FullscreenModal/FullscreenModal.js +22 -1
- package/lib/module/components/Spinner/Spinner.js +6 -2
- package/lib/module/components/TestimonialsCard/TestimonialsCard.js +116 -0
- package/lib/module/components/index.js +1 -0
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/skeleton/Skeleton.js +11 -3
- package/lib/typescript/src/components/Drawer/Drawer.d.ts +23 -4
- package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +7 -1
- package/lib/typescript/src/components/TestimonialsCard/TestimonialsCard.d.ts +51 -0
- package/lib/typescript/src/components/index.d.ts +2 -1
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/Drawer/Drawer.tsx +94 -15
- package/src/components/Dropdown/Dropdown.tsx +38 -18
- package/src/components/FullscreenModal/FullscreenModal.tsx +29 -2
- package/src/components/Spinner/Spinner.tsx +2 -2
- package/src/components/TestimonialsCard/TestimonialsCard.tsx +162 -0
- package/src/components/index.ts +2 -1
- package/src/icons/registry.ts +1 -1
- package/src/skeleton/Skeleton.tsx +10 -3
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
type ViewStyle,
|
|
6
|
+
type TextStyle,
|
|
7
|
+
type StyleProp,
|
|
8
|
+
} from 'react-native'
|
|
9
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
|
+
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
11
|
+
import Avatar, { type AvatarProps } from '../Avatar/Avatar'
|
|
12
|
+
|
|
13
|
+
export type TestimonialsCardProps = {
|
|
14
|
+
/**
|
|
15
|
+
* The testimonial heading, typically the author's name.
|
|
16
|
+
*/
|
|
17
|
+
title?: string
|
|
18
|
+
/**
|
|
19
|
+
* The testimonial body copy.
|
|
20
|
+
*/
|
|
21
|
+
body?: string
|
|
22
|
+
/**
|
|
23
|
+
* Mode configuration passed to the token resolver. Also forwarded to the
|
|
24
|
+
* Avatar child for consistent theming.
|
|
25
|
+
*/
|
|
26
|
+
modes?: Record<string, any>
|
|
27
|
+
/**
|
|
28
|
+
* Optional style overrides for the card container.
|
|
29
|
+
*/
|
|
30
|
+
style?: StyleProp<ViewStyle>
|
|
31
|
+
/**
|
|
32
|
+
* Props forwarded to the Avatar component (e.g. a custom `imageSource`).
|
|
33
|
+
*/
|
|
34
|
+
avatarProps?: Partial<AvatarProps>
|
|
35
|
+
/**
|
|
36
|
+
* Accessibility label for the card region. Falls back to a label generated
|
|
37
|
+
* from the title and body.
|
|
38
|
+
*/
|
|
39
|
+
accessibilityLabel?: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* TestimonialsCard renders a compact, fixed-width card with a circular avatar,
|
|
44
|
+
* a bold title, and a body paragraph. It is typically used inside a horizontal
|
|
45
|
+
* carousel of customer testimonials.
|
|
46
|
+
*
|
|
47
|
+
* All styling values are resolved from Figma design tokens using the provided
|
|
48
|
+
* `modes`.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <TestimonialsCard
|
|
53
|
+
* title="Aarav S."
|
|
54
|
+
* body="I was dreading renewing my car insurance, but JioFinance made it a breeze."
|
|
55
|
+
* />
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
function TestimonialsCard({
|
|
59
|
+
title = 'Title',
|
|
60
|
+
body = 'I was dreading renewing my car insurance, but JioFinance made it a breeze.',
|
|
61
|
+
modes = EMPTY_MODES,
|
|
62
|
+
style,
|
|
63
|
+
avatarProps,
|
|
64
|
+
accessibilityLabel,
|
|
65
|
+
}: TestimonialsCardProps) {
|
|
66
|
+
// Container tokens
|
|
67
|
+
const background = getVariableByName('testimonialsCard/background', modes) ?? '#ffffff'
|
|
68
|
+
const borderColor = getVariableByName('testimonialsCard/border/color', modes) ?? '#e8e8e8'
|
|
69
|
+
const radius = getVariableByName('testimonialsCard/radius', modes) ?? 8
|
|
70
|
+
const gap = getVariableByName('testimonialsCard/gap', modes) ?? 8
|
|
71
|
+
const paddingHorizontal = getVariableByName('testimonialsCard/padding/horizontal', modes) ?? 12
|
|
72
|
+
const paddingVertical = getVariableByName('testimonialsCard/padding/vertical', modes) ?? 12
|
|
73
|
+
|
|
74
|
+
// Title typography tokens
|
|
75
|
+
const titleColor = getVariableByName('testimonialsCard/subtitle/color', modes) ?? '#1a1c1f'
|
|
76
|
+
const titleFontSize = getVariableByName('testimonialsCard/title/fontSize', modes) ?? 14
|
|
77
|
+
const titleFontFamily = getVariableByName('testimonialsCard/title/fontFamily', modes) ?? 'JioType Var'
|
|
78
|
+
const titleFontWeightRaw = getVariableByName('testimonialsCard/title/fontWeight', modes) ?? 700
|
|
79
|
+
const titleFontWeight =
|
|
80
|
+
typeof titleFontWeightRaw === 'number' ? titleFontWeightRaw.toString() : titleFontWeightRaw
|
|
81
|
+
|
|
82
|
+
// Body typography tokens
|
|
83
|
+
const bodyColor = getVariableByName('testimonialsCard/title/color', modes) ?? '#010101'
|
|
84
|
+
const bodyFontSize = getVariableByName('testimonialsCard/subtitle/fontSize', modes) ?? 12
|
|
85
|
+
const bodyLineHeight = getVariableByName('testimonialsCard/subtitle/lineHeight', modes) ?? 16
|
|
86
|
+
const bodyFontFamily = getVariableByName('testimonialsCard/subtitle/fontFamily', modes) ?? 'JioType Var'
|
|
87
|
+
const bodyFontWeightRaw = getVariableByName('testimonialsCard/subtitle/fontWeight', modes) ?? 400
|
|
88
|
+
const bodyFontWeight =
|
|
89
|
+
typeof bodyFontWeightRaw === 'number' ? bodyFontWeightRaw.toString() : bodyFontWeightRaw
|
|
90
|
+
|
|
91
|
+
const containerStyle: ViewStyle = {
|
|
92
|
+
width: 180,
|
|
93
|
+
backgroundColor: background as string,
|
|
94
|
+
borderColor: borderColor as string,
|
|
95
|
+
borderWidth: 1,
|
|
96
|
+
borderRadius: radius as number,
|
|
97
|
+
paddingHorizontal: paddingHorizontal as number,
|
|
98
|
+
paddingVertical: paddingVertical as number,
|
|
99
|
+
alignItems: 'flex-start',
|
|
100
|
+
gap: gap as number,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const titleTextStyle: TextStyle = {
|
|
104
|
+
color: titleColor as string,
|
|
105
|
+
fontSize: titleFontSize as number,
|
|
106
|
+
lineHeight: bodyLineHeight as number,
|
|
107
|
+
fontFamily: titleFontFamily as string,
|
|
108
|
+
fontWeight: titleFontWeight as TextStyle['fontWeight'],
|
|
109
|
+
width: '100%',
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const bodyTextStyle: TextStyle = {
|
|
113
|
+
color: bodyColor as string,
|
|
114
|
+
fontSize: bodyFontSize as number,
|
|
115
|
+
lineHeight: bodyLineHeight as number,
|
|
116
|
+
fontFamily: bodyFontFamily as string,
|
|
117
|
+
fontWeight: bodyFontWeight as TextStyle['fontWeight'],
|
|
118
|
+
width: '100%',
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const avatarModes = {
|
|
122
|
+
...modes,
|
|
123
|
+
...(avatarProps?.modes || {}),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const resolvedAccessibilityLabel =
|
|
127
|
+
accessibilityLabel ?? `Testimonial${title ? ` from ${title}` : ''}${body ? `: ${body}` : ''}`
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<View
|
|
131
|
+
style={[containerStyle, style]}
|
|
132
|
+
accessibilityRole="text"
|
|
133
|
+
accessibilityLabel={resolvedAccessibilityLabel}
|
|
134
|
+
>
|
|
135
|
+
<Avatar
|
|
136
|
+
style="Image"
|
|
137
|
+
modes={avatarModes}
|
|
138
|
+
{...avatarProps}
|
|
139
|
+
/>
|
|
140
|
+
<View style={textContainerStyle}>
|
|
141
|
+
{!!title && (
|
|
142
|
+
<Text style={titleTextStyle} accessibilityElementsHidden importantForAccessibility="no-hide-descendants">
|
|
143
|
+
{title}
|
|
144
|
+
</Text>
|
|
145
|
+
)}
|
|
146
|
+
{!!body && (
|
|
147
|
+
<Text style={bodyTextStyle} accessibilityElementsHidden importantForAccessibility="no-hide-descendants">
|
|
148
|
+
{body}
|
|
149
|
+
</Text>
|
|
150
|
+
)}
|
|
151
|
+
</View>
|
|
152
|
+
</View>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const textContainerStyle: ViewStyle = {
|
|
157
|
+
width: '100%',
|
|
158
|
+
alignItems: 'flex-start',
|
|
159
|
+
gap: 4,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export default React.memo(TestimonialsCard)
|
package/src/components/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ export { default as CardFinancialCondition, type CardFinancialConditionProps } f
|
|
|
22
22
|
export { default as CardInsight, type CardInsightProps } from './CardInsight/CardInsight';
|
|
23
23
|
export { default as Disclaimer } from './Disclaimer/Disclaimer';
|
|
24
24
|
export { default as Divider, type DividerProps, type DividerDirection } from './Divider/Divider';
|
|
25
|
-
export { default as Drawer } from './Drawer/Drawer';
|
|
25
|
+
export { default as Drawer, type DrawerProps, type DrawerHandle } from './Drawer/Drawer';
|
|
26
26
|
export { default as Dropdown, DropdownItem, type DropdownProps, type DropdownItemProps } from './Dropdown/Dropdown';
|
|
27
27
|
export { default as DropdownInput, type DropdownInputProps, type DropdownInputOption, type DropdownInputOptionValue } from './DropdownInput/DropdownInput';
|
|
28
28
|
export { default as SuggestiveSearch, type SuggestiveSearchProps, type SuggestiveSearchOption, type SuggestiveSearchOptionValue, type SuggestiveSearchItem } from './SuggestiveSearch/SuggestiveSearch';
|
|
@@ -149,6 +149,7 @@ export { default as StatItem, type StatItemProps, type StatItemLabelPosition } f
|
|
|
149
149
|
export { default as StatGroup, type StatGroupProps, type StatGroupItem } from './StatGroup/StatGroup';
|
|
150
150
|
export { default as StrengthIndicator, type StrengthIndicatorProps, type StrengthIndicatorConfidence, type StrengthIndicatorConfidenceValue } from './StrengthIndicator/StrengthIndicator';
|
|
151
151
|
export { default as SummaryTile, type SummaryTileProps } from './SummaryTile/SummaryTile';
|
|
152
|
+
export { default as TestimonialsCard, type TestimonialsCardProps } from './TestimonialsCard/TestimonialsCard';
|
|
152
153
|
export { default as Text, type TextProps } from './Text/Text';
|
|
153
154
|
export { default as SegmentedControl, type SegmentedControlProps, type SegmentedControlItem } from './SegmentedControl/SegmentedControl';
|
|
154
155
|
export { default as Toggle, type ToggleProps } from './Toggle/Toggle';
|
package/src/icons/registry.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useId, useMemo, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
type LayoutChangeEvent,
|
|
4
|
-
StyleSheet,
|
|
5
4
|
View,
|
|
6
5
|
type DimensionValue,
|
|
7
6
|
type StyleProp,
|
|
@@ -60,13 +59,21 @@ const SOLID_OVERLAY_COLOR = 'rgba(255, 255, 255, 1)'
|
|
|
60
59
|
// `pointerEvents: 'none'` lives on the style (not the deprecated prop) so it
|
|
61
60
|
// works on both native and React Native Web without warnings.
|
|
62
61
|
const absoluteFillStyle: ViewStyle = {
|
|
63
|
-
|
|
62
|
+
position: 'absolute',
|
|
63
|
+
top: 0,
|
|
64
|
+
left: 0,
|
|
65
|
+
right: 0,
|
|
66
|
+
bottom: 0,
|
|
64
67
|
overflow: 'hidden',
|
|
65
68
|
pointerEvents: 'none',
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
const solidOverlayStyle: ViewStyle = {
|
|
69
|
-
|
|
72
|
+
position: 'absolute',
|
|
73
|
+
top: 0,
|
|
74
|
+
left: 0,
|
|
75
|
+
right: 0,
|
|
76
|
+
bottom: 0,
|
|
70
77
|
backgroundColor: SOLID_OVERLAY_COLOR,
|
|
71
78
|
}
|
|
72
79
|
|