jfs-components 0.0.37 → 0.0.38
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/lib/commonjs/Containers.js.map +1 -1
- package/lib/commonjs/components/AvatarGroup/AvatarGroup.js.map +1 -1
- package/lib/commonjs/components/BottomNav/BottomNav.js +2 -2
- package/lib/commonjs/components/BottomNav/BottomNav.js.map +1 -1
- package/lib/commonjs/components/BottomNavItem/BottomNavItem.js +9 -7
- package/lib/commonjs/components/BottomNavItem/BottomNavItem.js.map +1 -1
- package/lib/commonjs/components/Card/Card.js.map +1 -1
- package/lib/commonjs/components/CardFeedback/CardFeedback.js +14 -4
- package/lib/commonjs/components/CardFeedback/CardFeedback.js.map +1 -1
- package/lib/commonjs/components/ChipGroup/ChipGroup.js.map +1 -1
- package/lib/commonjs/components/ChipSelect/ChipSelect.js +16 -11
- package/lib/commonjs/components/ChipSelect/ChipSelect.js.map +1 -1
- package/lib/commonjs/components/CtaCard/CtaCard.js +9 -4
- package/lib/commonjs/components/CtaCard/CtaCard.js.map +1 -1
- package/lib/commonjs/components/CtaCard/index.js.map +1 -1
- package/lib/commonjs/components/EmptyState/EmptyState.js +4 -0
- package/lib/commonjs/components/EmptyState/EmptyState.js.map +1 -1
- package/lib/commonjs/components/IconButton/IconButton.js +16 -13
- package/lib/commonjs/components/IconButton/IconButton.js.map +1 -1
- package/lib/commonjs/components/IconCapsule/IconCapsule.js +21 -22
- package/lib/commonjs/components/IconCapsule/IconCapsule.js.map +1 -1
- package/lib/commonjs/components/MediaCard/MediaCard.js.map +1 -1
- package/lib/commonjs/components/NavArrow/NavArrow.js +9 -18
- package/lib/commonjs/components/NavArrow/NavArrow.js.map +1 -1
- package/lib/commonjs/components/RechargeCard/RechargeCard.js.map +1 -1
- package/lib/commonjs/components/SupportText/SupportText.js.map +1 -1
- package/lib/commonjs/components/SupportText/SupportTextIcon.js.map +1 -1
- package/lib/commonjs/components/SupportText/index.js.map +1 -1
- package/lib/commonjs/components/UpiHandle/UpiHandle.js +10 -8
- package/lib/commonjs/components/UpiHandle/UpiHandle.js.map +1 -1
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/design-tokens/JFSThemeProvider.js.map +1 -1
- package/lib/commonjs/design-tokens/figma-variables-resolver.js +9 -3
- package/lib/commonjs/design-tokens/figma-variables-resolver.js.map +1 -1
- package/lib/commonjs/icons/Icon.js.map +1 -1
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/react-utils.js.map +1 -1
- package/lib/module/Containers.js.map +1 -1
- package/lib/module/components/AvatarGroup/AvatarGroup.js.map +1 -1
- package/lib/module/components/BottomNav/BottomNav.js +2 -2
- package/lib/module/components/BottomNavItem/BottomNavItem.js +10 -7
- package/lib/module/components/BottomNavItem/BottomNavItem.js.map +1 -1
- package/lib/module/components/Card/Card.js.map +1 -1
- package/lib/module/components/CardFeedback/CardFeedback.js +13 -4
- package/lib/module/components/CardFeedback/CardFeedback.js.map +1 -1
- package/lib/module/components/ChipGroup/ChipGroup.js.map +1 -1
- package/lib/module/components/ChipSelect/ChipSelect.js +15 -10
- package/lib/module/components/ChipSelect/ChipSelect.js.map +1 -1
- package/lib/module/components/CtaCard/CtaCard.js +8 -4
- package/lib/module/components/CtaCard/CtaCard.js.map +1 -1
- package/lib/module/components/EmptyState/EmptyState.js +4 -0
- package/lib/module/components/EmptyState/EmptyState.js.map +1 -1
- package/lib/module/components/IconButton/IconButton.js +16 -12
- package/lib/module/components/IconButton/IconButton.js.map +1 -1
- package/lib/module/components/IconCapsule/IconCapsule.js +20 -21
- package/lib/module/components/IconCapsule/IconCapsule.js.map +1 -1
- package/lib/module/components/MediaCard/MediaCard.js.map +1 -1
- package/lib/module/components/NavArrow/NavArrow.js +8 -17
- package/lib/module/components/NavArrow/NavArrow.js.map +1 -1
- package/lib/module/components/RechargeCard/RechargeCard.js.map +1 -1
- package/lib/module/components/SupportText/SupportText.js.map +1 -1
- package/lib/module/components/SupportText/SupportTextIcon.js.map +1 -1
- package/lib/module/components/UpiHandle/UpiHandle.js +10 -7
- package/lib/module/components/UpiHandle/UpiHandle.js.map +1 -1
- package/lib/module/design-tokens/figma-variables-resolver.js.map +1 -1
- package/lib/module/icons/Icon.js.map +1 -1
- package/lib/module/icons/registry.js +1 -1
- package/lib/typescript/Containers.d.ts.map +1 -1
- package/lib/typescript/components/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/lib/typescript/components/BottomNav/BottomNav.d.ts +2 -2
- package/lib/typescript/components/BottomNav/BottomNav.d.ts.map +1 -1
- package/lib/typescript/components/BottomNavItem/BottomNavItem.d.ts +8 -2
- package/lib/typescript/components/BottomNavItem/BottomNavItem.d.ts.map +1 -1
- package/lib/typescript/components/Card/Card.d.ts.map +1 -1
- package/lib/typescript/components/CardFeedback/CardFeedback.d.ts +3 -2
- package/lib/typescript/components/CardFeedback/CardFeedback.d.ts.map +1 -1
- package/lib/typescript/components/ChipGroup/ChipGroup.d.ts.map +1 -1
- package/lib/typescript/components/ChipSelect/ChipSelect.d.ts +12 -5
- package/lib/typescript/components/ChipSelect/ChipSelect.d.ts.map +1 -1
- package/lib/typescript/components/CtaCard/CtaCard.d.ts +6 -1
- package/lib/typescript/components/CtaCard/CtaCard.d.ts.map +1 -1
- package/lib/typescript/components/CtaCard/index.d.ts.map +1 -1
- package/lib/typescript/components/EmptyState/EmptyState.d.ts.map +1 -1
- package/lib/typescript/components/IconButton/IconButton.d.ts +12 -6
- package/lib/typescript/components/IconButton/IconButton.d.ts.map +1 -1
- package/lib/typescript/components/IconCapsule/IconCapsule.d.ts +10 -11
- package/lib/typescript/components/IconCapsule/IconCapsule.d.ts.map +1 -1
- package/lib/typescript/components/MediaCard/MediaCard.d.ts.map +1 -1
- package/lib/typescript/components/NavArrow/NavArrow.d.ts +6 -1
- package/lib/typescript/components/NavArrow/NavArrow.d.ts.map +1 -1
- package/lib/typescript/components/RechargeCard/RechargeCard.d.ts.map +1 -1
- package/lib/typescript/components/SupportText/SupportText.d.ts.map +1 -1
- package/lib/typescript/components/SupportText/SupportTextIcon.d.ts.map +1 -1
- package/lib/typescript/components/SupportText/index.d.ts.map +1 -1
- package/lib/typescript/components/UpiHandle/UpiHandle.d.ts +11 -3
- package/lib/typescript/components/UpiHandle/UpiHandle.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/design-tokens/JFSThemeProvider.d.ts.map +1 -1
- package/lib/typescript/design-tokens/figma-variables-resolver.d.ts.map +1 -1
- package/lib/typescript/design-tokens/index.d.ts.map +1 -1
- package/lib/typescript/icons/Icon.d.ts.map +1 -1
- package/lib/typescript/icons/index.d.ts.map +1 -1
- package/lib/typescript/icons/registry.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils/react-utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Containers.tsx +4 -4
- package/src/components/AvatarGroup/AvatarGroup.tsx +41 -41
- package/src/components/BottomNav/BottomNav.tsx +14 -14
- package/src/components/BottomNavItem/BottomNavItem.tsx +20 -11
- package/src/components/ButtonGroup/ButtonGroup.tsx +4 -4
- package/src/components/Card/Card.tsx +42 -42
- package/src/components/CardFeedback/CardFeedback.tsx +71 -64
- package/src/components/ChipGroup/ChipGroup.tsx +15 -15
- package/src/components/ChipSelect/ChipSelect.tsx +51 -31
- package/src/components/CtaCard/CtaCard.tsx +33 -24
- package/src/components/CtaCard/index.ts +1 -1
- package/src/components/EmptyState/EmptyState.tsx +2 -1
- package/src/components/IconButton/IconButton.tsx +30 -21
- package/src/components/IconCapsule/IconCapsule.tsx +22 -24
- package/src/components/InputSearch/InputSearch.tsx +1 -1
- package/src/components/MediaCard/MediaCard.tsx +52 -52
- package/src/components/NavArrow/NavArrow.tsx +15 -17
- package/src/components/RechargeCard/RechargeCard.tsx +39 -39
- package/src/components/SupportText/SupportText.tsx +20 -20
- package/src/components/SupportText/SupportTextIcon.tsx +10 -10
- package/src/components/SupportText/index.ts +2 -2
- package/src/components/UpiHandle/UpiHandle.tsx +23 -13
- package/src/components/index.ts +49 -49
- package/src/design-tokens/JFSThemeProvider.tsx +12 -12
- package/src/design-tokens/figma-variables-resolver.js +117 -117
- package/src/design-tokens/figma-variables-resolver.ts +117 -117
- package/src/design-tokens/index.ts +2 -2
- package/src/icons/Icon.tsx +22 -22
- package/src/icons/index.ts +3 -3
- package/src/icons/registry.ts +1 -1
- package/src/index.ts +4 -4
- package/src/utils/react-utils.ts +8 -8
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { View, Platform, type ViewStyle } from 'react-native'
|
|
3
|
-
import MaskedView from '@react-native-masked-view/masked-view'
|
|
4
|
-
import Svg, { Path } from 'react-native-svg'
|
|
5
|
-
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
6
|
-
import { flattenChildren } from '../../utils/react-utils'
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { View, Platform, type ViewStyle } from 'react-native'
|
|
3
|
+
import MaskedView from '@react-native-masked-view/masked-view'
|
|
4
|
+
import Svg, { Path } from 'react-native-svg'
|
|
5
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
6
|
+
import { flattenChildren } from '../../utils/react-utils'
|
|
7
7
|
|
|
8
8
|
type AvatarGroupProps = {
|
|
9
9
|
modes?: Record<string, any>;
|
|
@@ -12,44 +12,44 @@ type AvatarGroupProps = {
|
|
|
12
12
|
} & React.ComponentProps<typeof View>;
|
|
13
13
|
|
|
14
14
|
function AvatarGroup({ modes = {}, children, style, ...rest }: AvatarGroupProps) {
|
|
15
|
-
const gap = getVariableByName('avatarGroup/gap', modes) || 0
|
|
15
|
+
const gap = getVariableByName('avatarGroup/gap', modes) || 0
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
const avatarSize = getVariableByName('avatar/size', modes) || 29
|
|
19
|
-
const avatarRadius = getVariableByName('avatar/radius', modes) || 9999
|
|
20
|
-
const borderSize = getVariableByName('avatar/border/size', modes) || 1
|
|
21
|
-
const borderColor = getVariableByName('avatar/border/color', modes) || 'rgba(255,255,255,0)'
|
|
18
|
+
const avatarSize = getVariableByName('avatar/size', modes) || 29
|
|
19
|
+
const avatarRadius = getVariableByName('avatar/radius', modes) || 9999
|
|
20
|
+
const borderSize = getVariableByName('avatar/border/size', modes) || 1
|
|
21
|
+
const borderColor = getVariableByName('avatar/border/color', modes) || 'rgba(255,255,255,0)'
|
|
22
22
|
|
|
23
|
-
const paddingLeft = getVariableByName('avatarGroup/padding/left', modes) || 0
|
|
24
|
-
const paddingRight = getVariableByName('avatarGroup/padding/right', modes) || 0
|
|
25
|
-
const paddingTop = getVariableByName('avatarGroup/padding/top', modes) || 0
|
|
26
|
-
const paddingBottom = getVariableByName('avatarGroup/padding/bottom', modes) || 0
|
|
23
|
+
const paddingLeft = getVariableByName('avatarGroup/padding/left', modes) || 0
|
|
24
|
+
const paddingRight = getVariableByName('avatarGroup/padding/right', modes) || 0
|
|
25
|
+
const paddingTop = getVariableByName('avatarGroup/padding/top', modes) || 0
|
|
26
|
+
const paddingBottom = getVariableByName('avatarGroup/padding/bottom', modes) || 0
|
|
27
27
|
|
|
28
|
-
const validChildren = flattenChildren(children)
|
|
29
|
-
const totalChildren = validChildren.length
|
|
28
|
+
const validChildren = flattenChildren(children)
|
|
29
|
+
const totalChildren = validChildren.length
|
|
30
30
|
|
|
31
31
|
// shared geometry logic
|
|
32
|
-
const r = avatarSize / 2
|
|
33
|
-
const gapInt = parseInt(gap.toString(), 10)
|
|
34
|
-
const avatarSizeInt = parseInt(avatarSize.toString(), 10)
|
|
35
|
-
const borderSizeInt = parseInt(borderSize.toString(), 10)
|
|
36
|
-
const avatarRadiusInt = parseInt(avatarRadius.toString(), 10)
|
|
32
|
+
const r = avatarSize / 2
|
|
33
|
+
const gapInt = parseInt(gap.toString(), 10)
|
|
34
|
+
const avatarSizeInt = parseInt(avatarSize.toString(), 10)
|
|
35
|
+
const borderSizeInt = parseInt(borderSize.toString(), 10)
|
|
36
|
+
const avatarRadiusInt = parseInt(avatarRadius.toString(), 10)
|
|
37
37
|
|
|
38
|
-
const nextAvatarX = avatarSizeInt + gapInt
|
|
38
|
+
const nextAvatarX = avatarSizeInt + gapInt
|
|
39
39
|
// If radius is 9999 (full circle), use actual radius r.
|
|
40
40
|
// Effective radius for the hole includes the border of the next avatar.
|
|
41
|
-
const effectiveRadius = (avatarRadiusInt >= 9999 ? r : avatarRadiusInt)
|
|
42
|
-
const holeRadius = effectiveRadius + borderSizeInt
|
|
43
|
-
const holeCenter = { x: nextAvatarX + r, y: r }
|
|
41
|
+
const effectiveRadius = (avatarRadiusInt >= 9999 ? r : avatarRadiusInt)
|
|
42
|
+
const holeRadius = effectiveRadius + borderSizeInt
|
|
43
|
+
const holeCenter = { x: nextAvatarX + r, y: r }
|
|
44
44
|
|
|
45
45
|
// Native Mask Path
|
|
46
|
-
const rectPath = `M 0 0 h ${avatarSizeInt} v ${avatarSizeInt} h -${avatarSizeInt} z
|
|
47
|
-
const circlePath = `M ${holeCenter.x},${holeCenter.y} m -${holeRadius},0 a ${holeRadius},${holeRadius} 0 1,0 ${holeRadius * 2},0 a ${holeRadius},${holeRadius} 0 1,0 -${holeRadius * 2},0
|
|
48
|
-
const maskPath = `${rectPath} ${circlePath}
|
|
46
|
+
const rectPath = `M 0 0 h ${avatarSizeInt} v ${avatarSizeInt} h -${avatarSizeInt} z`
|
|
47
|
+
const circlePath = `M ${holeCenter.x},${holeCenter.y} m -${holeRadius},0 a ${holeRadius},${holeRadius} 0 1,0 ${holeRadius * 2},0 a ${holeRadius},${holeRadius} 0 1,0 -${holeRadius * 2},0`
|
|
48
|
+
const maskPath = `${rectPath} ${circlePath}`
|
|
49
49
|
|
|
50
50
|
// Web Mask Gradient
|
|
51
51
|
// radial-gradient(circle at CX CY, transparent R, black R+1)
|
|
52
|
-
const webMaskImage = `radial-gradient(circle at ${holeCenter.x}px ${holeCenter.y}px, transparent ${holeRadius}px, black ${holeRadius + 0.5}px)
|
|
52
|
+
const webMaskImage = `radial-gradient(circle at ${holeCenter.x}px ${holeCenter.y}px, transparent ${holeRadius}px, black ${holeRadius + 0.5}px)`
|
|
53
53
|
|
|
54
54
|
const containerStyle: ViewStyle = {
|
|
55
55
|
flexDirection: 'row',
|
|
@@ -58,25 +58,25 @@ function AvatarGroup({ modes = {}, children, style, ...rest }: AvatarGroupProps)
|
|
|
58
58
|
paddingRight: parseInt(paddingRight.toString(), 10),
|
|
59
59
|
paddingTop: parseInt(paddingTop.toString(), 10),
|
|
60
60
|
paddingBottom: parseInt(paddingBottom.toString(), 10),
|
|
61
|
-
}
|
|
61
|
+
}
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
64
|
<View style={[containerStyle, style]} {...rest}>
|
|
65
65
|
{validChildren.map((child, index) => {
|
|
66
|
-
const isLast = index === totalChildren - 1
|
|
67
|
-
const element = child as React.ReactElement<any
|
|
68
|
-
const elementProps = element.props || {}
|
|
66
|
+
const isLast = index === totalChildren - 1
|
|
67
|
+
const element = child as React.ReactElement<any>
|
|
68
|
+
const elementProps = element.props || {}
|
|
69
69
|
|
|
70
70
|
const clonedChild = React.cloneElement(element, {
|
|
71
71
|
modes: { ...modes, ...(elementProps.modes || {}) },
|
|
72
|
-
})
|
|
72
|
+
})
|
|
73
73
|
|
|
74
74
|
if (isLast) {
|
|
75
75
|
return (
|
|
76
76
|
<View key={index} style={{ zIndex: index }}>
|
|
77
77
|
{clonedChild}
|
|
78
78
|
</View>
|
|
79
|
-
)
|
|
79
|
+
)
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// Wrapper style for avatar dimension
|
|
@@ -90,14 +90,14 @@ function AvatarGroup({ modes = {}, children, style, ...rest }: AvatarGroupProps)
|
|
|
90
90
|
maskImage: webMaskImage,
|
|
91
91
|
WebkitMaskImage: webMaskImage,
|
|
92
92
|
} : {})
|
|
93
|
-
}
|
|
93
|
+
}
|
|
94
94
|
|
|
95
95
|
if (Platform.OS === 'web') {
|
|
96
96
|
return (
|
|
97
97
|
<View key={index} style={wrapperStyle}>
|
|
98
98
|
{clonedChild}
|
|
99
99
|
</View>
|
|
100
|
-
)
|
|
100
|
+
)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
// Native MaskedView
|
|
@@ -118,10 +118,10 @@ function AvatarGroup({ modes = {}, children, style, ...rest }: AvatarGroupProps)
|
|
|
118
118
|
{clonedChild}
|
|
119
119
|
</MaskedView>
|
|
120
120
|
</View>
|
|
121
|
-
)
|
|
121
|
+
)
|
|
122
122
|
})}
|
|
123
123
|
</View>
|
|
124
|
-
)
|
|
124
|
+
)
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
export default AvatarGroup
|
|
127
|
+
export default AvatarGroup
|
|
@@ -32,8 +32,8 @@ type BottomNavProps = {
|
|
|
32
32
|
* Usage:
|
|
33
33
|
* ```tsx
|
|
34
34
|
* <BottomNav value={currentTab} onChange={setCurrentTab}>
|
|
35
|
-
* <BottomNav.Item value="home"
|
|
36
|
-
* <BottomNav.Item value="profile"
|
|
35
|
+
* <BottomNav.Item value="home" icon={<Icon name="ic_home" />} label="Home" />
|
|
36
|
+
* <BottomNav.Item value="profile" icon={<Icon name="ic_profile" />} label="Profile" />
|
|
37
37
|
* </BottomNav>
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
@@ -86,19 +86,19 @@ function BottomNav({
|
|
|
86
86
|
>
|
|
87
87
|
{React.Children.map(children, (child) => {
|
|
88
88
|
if (!React.isValidElement(child)) {
|
|
89
|
-
return null
|
|
89
|
+
return null
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// Cast to ReactElement to access props safely in TS
|
|
93
|
-
const childElement = child as React.ReactElement<any
|
|
93
|
+
const childElement = child as React.ReactElement<any>
|
|
94
94
|
|
|
95
95
|
// We assume the child is a BottomNav.Item (or compatible)
|
|
96
96
|
// We extract 'value' from the child's props to check selection
|
|
97
|
-
const childValue = childElement.props.value
|
|
98
|
-
const selected = childValue === value
|
|
97
|
+
const childValue = childElement.props.value
|
|
98
|
+
const selected = childValue === value
|
|
99
99
|
|
|
100
100
|
// Define the mode for the Item's state
|
|
101
|
-
const stateMode = selected ? 'Active' : 'Idle'
|
|
101
|
+
const stateMode = selected ? 'Active' : 'Idle'
|
|
102
102
|
|
|
103
103
|
return React.cloneElement(childElement, {
|
|
104
104
|
// Pass down modes, injecting the State mode for this item
|
|
@@ -111,9 +111,9 @@ function BottomNav({
|
|
|
111
111
|
// Intercept onPress to handle generic selection logic
|
|
112
112
|
onPress: (event?: any) => {
|
|
113
113
|
if (onChange && childValue !== undefined) {
|
|
114
|
-
onChange(childValue)
|
|
114
|
+
onChange(childValue)
|
|
115
115
|
}
|
|
116
|
-
childElement.props.onPress?.(event)
|
|
116
|
+
childElement.props.onPress?.(event)
|
|
117
117
|
},
|
|
118
118
|
|
|
119
119
|
// Accessibility state
|
|
@@ -124,7 +124,7 @@ function BottomNav({
|
|
|
124
124
|
|
|
125
125
|
// Flex to fill
|
|
126
126
|
style: [{ flex: 1 }, childElement.props.style]
|
|
127
|
-
})
|
|
127
|
+
})
|
|
128
128
|
})}
|
|
129
129
|
</View>
|
|
130
130
|
)
|
|
@@ -140,12 +140,12 @@ const Item = (props: BottomNavItemProps) => {
|
|
|
140
140
|
// We strip 'value' before passing to BottomNavItem just in case,
|
|
141
141
|
// though passing extra props to BottomNavItem (which spreads ...rest to View/Pressable)
|
|
142
142
|
// is usually fine, but clean is better.
|
|
143
|
-
const { value, ...rest } = props
|
|
144
|
-
return <BottomNavItem {...rest}
|
|
145
|
-
}
|
|
143
|
+
const { value, ...rest } = props
|
|
144
|
+
return <BottomNavItem {...rest} />
|
|
145
|
+
}
|
|
146
146
|
|
|
147
147
|
// Attach Item to BottomNav
|
|
148
|
-
const BottomNavWithItem = Object.assign(BottomNav, { Item })
|
|
148
|
+
const BottomNavWithItem = Object.assign(BottomNav, { Item })
|
|
149
149
|
|
|
150
150
|
export default BottomNavWithItem
|
|
151
151
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { useState, isValidElement, cloneElement } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Pressable,
|
|
4
4
|
Text,
|
|
@@ -10,10 +10,13 @@ import {
|
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
12
12
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
13
|
-
import Icon from '../../icons/Icon'
|
|
14
13
|
import { usePressableWebSupport, type SafePressableProps, type WebAccessibilityProps } from '../../utils/web-platform-utils'
|
|
15
14
|
|
|
16
15
|
type BottomNavItemProps = SafePressableProps & {
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Deprecated: Use icon prop instead
|
|
19
|
+
*/
|
|
17
20
|
iconName?: string;
|
|
18
21
|
label?: string;
|
|
19
22
|
modes?: Record<string, any>;
|
|
@@ -40,11 +43,13 @@ type BottomNavItemProps = SafePressableProps & {
|
|
|
40
43
|
*
|
|
41
44
|
* @component
|
|
42
45
|
* @param {Object} props
|
|
43
|
-
* @param {
|
|
46
|
+
* @param {React.ReactNode} [props.icon] - Icon element to display.
|
|
47
|
+
* @param {string} [props.iconName] - DEPRECATED: Icon name from the registry.
|
|
44
48
|
* ...
|
|
45
49
|
*/
|
|
46
50
|
function BottomNavItem({
|
|
47
|
-
|
|
51
|
+
icon,
|
|
52
|
+
iconName,
|
|
48
53
|
label = 'Home',
|
|
49
54
|
modes: propModes = {},
|
|
50
55
|
onPress,
|
|
@@ -114,13 +119,17 @@ function BottomNavItem({
|
|
|
114
119
|
|
|
115
120
|
const renderContent = () => (
|
|
116
121
|
<>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
{(icon || iconName) && (
|
|
123
|
+
isValidElement(icon) ? cloneElement(icon as React.ReactElement<any>, {
|
|
124
|
+
size: resolvedIconSize,
|
|
125
|
+
width: resolvedIconSize,
|
|
126
|
+
height: resolvedIconSize,
|
|
127
|
+
color: resolvedIconColor,
|
|
128
|
+
fill: resolvedIconColor,
|
|
129
|
+
accessibilityElementsHidden: true,
|
|
130
|
+
importantForAccessibility: "no"
|
|
131
|
+
}) : null
|
|
132
|
+
)}
|
|
124
133
|
<Text
|
|
125
134
|
style={[textStyle, labelStyle]}
|
|
126
135
|
accessibilityElementsHidden={true}
|
|
@@ -59,7 +59,7 @@ function ButtonGroup({
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Flatten children to handle Fragments properly
|
|
62
|
-
const flatChildren = flattenChildren(children)
|
|
62
|
+
const flatChildren = flattenChildren(children)
|
|
63
63
|
|
|
64
64
|
// Clone children to pass `modes` prop
|
|
65
65
|
const childrenWithModes = React.Children.map(flatChildren, (child) => {
|
|
@@ -67,9 +67,9 @@ function ButtonGroup({
|
|
|
67
67
|
// We safely try to pass `modes` to the child.
|
|
68
68
|
// We merge the group modes with any modes defined on the child explicitly.
|
|
69
69
|
// Child modes take precedence.
|
|
70
|
-
const element = child as React.ReactElement<any
|
|
71
|
-
const childModes = element.props.modes || {}
|
|
72
|
-
const mergedModes = { ...modes, ...childModes }
|
|
70
|
+
const element = child as React.ReactElement<any>
|
|
71
|
+
const childModes = element.props.modes || {}
|
|
72
|
+
const mergedModes = { ...modes, ...childModes }
|
|
73
73
|
|
|
74
74
|
return React.cloneElement(element, { modes: mergedModes })
|
|
75
75
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React, { createContext, useContext, isValidElement, cloneElement, useMemo } from 'react'
|
|
2
|
-
import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp } from 'react-native'
|
|
3
|
-
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
1
|
+
import React, { createContext, useContext, isValidElement, cloneElement, useMemo } from 'react'
|
|
2
|
+
import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp } from 'react-native'
|
|
3
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Context to share 'modes' with child components like Card.Title and Card.SupportText.
|
|
7
7
|
* This ensures that nested components can resolve their tokens correctly without
|
|
8
8
|
* needing explicit mode prop passing for every child.
|
|
9
9
|
*/
|
|
10
|
-
const CardContext = createContext<{ modes?: Record<string, any> }>({})
|
|
10
|
+
const CardContext = createContext<{ modes?: Record<string, any> }>({})
|
|
11
11
|
|
|
12
12
|
export interface CardProps {
|
|
13
13
|
/**
|
|
@@ -55,23 +55,23 @@ export function Card({
|
|
|
55
55
|
style,
|
|
56
56
|
}: CardProps) {
|
|
57
57
|
// Resolve Card Container Tokens
|
|
58
|
-
const backgroundColor = getVariableByName('card/background/color', modes) || '#ffffff'
|
|
59
|
-
const borderColor = getVariableByName('card/border/color', modes) || '#ebebed'
|
|
60
|
-
const borderWidth = parseFloat(getVariableByName('card/strokeWidth', modes) || '0.5')
|
|
61
|
-
const radius = parseFloat(getVariableByName('card/radius', modes) || '8')
|
|
62
|
-
const gap = parseFloat(getVariableByName('card/gap', modes) || '4')
|
|
63
|
-
const paddingHorizontal = parseFloat(getVariableByName('card/padding-horizontal', modes) || '0')
|
|
64
|
-
const paddingVertical = parseFloat(getVariableByName('card/padding-vertical', modes) || '0')
|
|
58
|
+
const backgroundColor = getVariableByName('card/background/color', modes) || '#ffffff'
|
|
59
|
+
const borderColor = getVariableByName('card/border/color', modes) || '#ebebed'
|
|
60
|
+
const borderWidth = parseFloat(getVariableByName('card/strokeWidth', modes) || '0.5') // Ensure number
|
|
61
|
+
const radius = parseFloat(getVariableByName('card/radius', modes) || '8')
|
|
62
|
+
const gap = parseFloat(getVariableByName('card/gap', modes) || '4')
|
|
63
|
+
const paddingHorizontal = parseFloat(getVariableByName('card/padding-horizontal', modes) || '0')
|
|
64
|
+
const paddingVertical = parseFloat(getVariableByName('card/padding-vertical', modes) || '0')
|
|
65
65
|
|
|
66
66
|
// Resolve Content Wrapper Tokens
|
|
67
|
-
const contentGap = parseFloat(getVariableByName('card/content/gap', modes) || '4')
|
|
68
|
-
const contentPaddingHorizontal = parseFloat(getVariableByName('card/content/padding/horizontal', modes) || '12')
|
|
69
|
-
const contentPaddingVertical = parseFloat(getVariableByName('card/content/padding/vertical', modes) || '16')
|
|
67
|
+
const contentGap = parseFloat(getVariableByName('card/content/gap', modes) || '4')
|
|
68
|
+
const contentPaddingHorizontal = parseFloat(getVariableByName('card/content/padding/horizontal', modes) || '12')
|
|
69
|
+
const contentPaddingVertical = parseFloat(getVariableByName('card/content/padding/vertical', modes) || '16')
|
|
70
70
|
|
|
71
71
|
// Clone media to pass modes if it's a valid element, facilitating nested style resolution
|
|
72
72
|
const mediaWithModes = isValidElement(media)
|
|
73
73
|
? cloneElement(media as any, { modes: { ...(media.props as any).modes, ...modes } })
|
|
74
|
-
: media
|
|
74
|
+
: media
|
|
75
75
|
|
|
76
76
|
const containerStyle: ViewStyle = {
|
|
77
77
|
backgroundColor,
|
|
@@ -82,7 +82,7 @@ export function Card({
|
|
|
82
82
|
paddingHorizontal,
|
|
83
83
|
paddingVertical,
|
|
84
84
|
overflow: 'hidden', // Ensure border radius clips content
|
|
85
|
-
}
|
|
85
|
+
}
|
|
86
86
|
|
|
87
87
|
const mediaWrapperStyle: ViewStyle = {
|
|
88
88
|
width: '100%',
|
|
@@ -91,14 +91,14 @@ export function Card({
|
|
|
91
91
|
// Figma has 'bg-[#3a46f7]' on the Ratio definition, but that's a placeholder.
|
|
92
92
|
// We assume the media content handles its own fill, or we can add a placeholder bg if needed.
|
|
93
93
|
// For now, we leave it transparent or rely on media.
|
|
94
|
-
}
|
|
94
|
+
}
|
|
95
95
|
|
|
96
96
|
const contentWrapperStyle: ViewStyle = {
|
|
97
97
|
width: '100%',
|
|
98
98
|
gap: contentGap,
|
|
99
99
|
paddingHorizontal: contentPaddingHorizontal,
|
|
100
100
|
paddingVertical: contentPaddingVertical,
|
|
101
|
-
}
|
|
101
|
+
}
|
|
102
102
|
|
|
103
103
|
return (
|
|
104
104
|
<CardContext.Provider value={{ modes }}>
|
|
@@ -113,7 +113,7 @@ export function Card({
|
|
|
113
113
|
</View>
|
|
114
114
|
</View>
|
|
115
115
|
</CardContext.Provider>
|
|
116
|
-
)
|
|
116
|
+
)
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
// ----------------------------------------------------------------------------
|
|
@@ -131,18 +131,18 @@ export interface CardTextProps {
|
|
|
131
131
|
* Uses tokens: card/title/*
|
|
132
132
|
*/
|
|
133
133
|
function Title({ children, style, modes: propModes }: CardTextProps) {
|
|
134
|
-
const context = useContext(CardContext)
|
|
135
|
-
const modes = propModes || context.modes || {}
|
|
134
|
+
const context = useContext(CardContext)
|
|
135
|
+
const modes = propModes || context.modes || {}
|
|
136
136
|
|
|
137
|
-
const color = getVariableByName('card/title/color', modes) || '#081007'
|
|
138
|
-
const fontSize = parseFloat(getVariableByName('card/title/fontSize', modes) || '16')
|
|
139
|
-
const fontFamily = getVariableByName('card/title/fontFamily', modes) || 'JioType Var'
|
|
140
|
-
const lineHeight = parseFloat(getVariableByName('card/title/lineHeight', modes) || '18')
|
|
137
|
+
const color = getVariableByName('card/title/color', modes) || '#081007'
|
|
138
|
+
const fontSize = parseFloat(getVariableByName('card/title/fontSize', modes) || '16')
|
|
139
|
+
const fontFamily = getVariableByName('card/title/fontFamily', modes) || 'JioType Var'
|
|
140
|
+
const lineHeight = parseFloat(getVariableByName('card/title/lineHeight', modes) || '18')
|
|
141
141
|
|
|
142
142
|
// Handling the potential typo in Figma variables "fonwWeight" vs "fontWeight"
|
|
143
143
|
// We check both keys to be safe.
|
|
144
|
-
const rawFontWeight = getVariableByName('card/title/fontWeight', modes) || getVariableByName('card/title/fonwWeight', modes) || '900'
|
|
145
|
-
const fontWeight = typeof rawFontWeight === 'number' ? rawFontWeight.toString() : rawFontWeight
|
|
144
|
+
const rawFontWeight = getVariableByName('card/title/fontWeight', modes) || getVariableByName('card/title/fonwWeight', modes) || '900'
|
|
145
|
+
const fontWeight = typeof rawFontWeight === 'number' ? rawFontWeight.toString() : rawFontWeight
|
|
146
146
|
|
|
147
147
|
const textStyle: TextStyle = {
|
|
148
148
|
color,
|
|
@@ -150,9 +150,9 @@ function Title({ children, style, modes: propModes }: CardTextProps) {
|
|
|
150
150
|
fontFamily,
|
|
151
151
|
lineHeight,
|
|
152
152
|
fontWeight: fontWeight as TextStyle['fontWeight'],
|
|
153
|
-
}
|
|
153
|
+
}
|
|
154
154
|
|
|
155
|
-
return <Text style={[textStyle, style]}>{children}</Text
|
|
155
|
+
return <Text style={[textStyle, style]}>{children}</Text>
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
@@ -160,15 +160,15 @@ function Title({ children, style, modes: propModes }: CardTextProps) {
|
|
|
160
160
|
* Uses tokens: card/supportive-text/*
|
|
161
161
|
*/
|
|
162
162
|
function SupportText({ children, style, modes: propModes }: CardTextProps) {
|
|
163
|
-
const context = useContext(CardContext)
|
|
164
|
-
const modes = propModes || context.modes || {}
|
|
163
|
+
const context = useContext(CardContext)
|
|
164
|
+
const modes = propModes || context.modes || {}
|
|
165
165
|
|
|
166
|
-
const color = getVariableByName('card/supportive-text/color', modes) || '#191b1e'
|
|
167
|
-
const fontSize = parseFloat(getVariableByName('card/supportive-text/fontSize', modes) || '12')
|
|
168
|
-
const fontFamily = getVariableByName('card/supportive-text/fontFamily', modes) || 'JioType Var'
|
|
169
|
-
const lineHeight = parseFloat(getVariableByName('card/supportive-text/lineHeight', modes) || '16')
|
|
170
|
-
const rawFontWeight = getVariableByName('card/supportive-text/fontWeight', modes) || '400'
|
|
171
|
-
const fontWeight = typeof rawFontWeight === 'number' ? rawFontWeight.toString() : rawFontWeight
|
|
166
|
+
const color = getVariableByName('card/supportive-text/color', modes) || '#191b1e'
|
|
167
|
+
const fontSize = parseFloat(getVariableByName('card/supportive-text/fontSize', modes) || '12')
|
|
168
|
+
const fontFamily = getVariableByName('card/supportive-text/fontFamily', modes) || 'JioType Var'
|
|
169
|
+
const lineHeight = parseFloat(getVariableByName('card/supportive-text/lineHeight', modes) || '16')
|
|
170
|
+
const rawFontWeight = getVariableByName('card/supportive-text/fontWeight', modes) || '400'
|
|
171
|
+
const fontWeight = typeof rawFontWeight === 'number' ? rawFontWeight.toString() : rawFontWeight
|
|
172
172
|
|
|
173
173
|
const textStyle: TextStyle = {
|
|
174
174
|
color,
|
|
@@ -176,13 +176,13 @@ function SupportText({ children, style, modes: propModes }: CardTextProps) {
|
|
|
176
176
|
fontFamily,
|
|
177
177
|
lineHeight,
|
|
178
178
|
fontWeight: fontWeight as TextStyle['fontWeight'],
|
|
179
|
-
}
|
|
179
|
+
}
|
|
180
180
|
|
|
181
|
-
return <Text style={[textStyle, style]}>{children}</Text
|
|
181
|
+
return <Text style={[textStyle, style]}>{children}</Text>
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
// Attach sub-components to Card
|
|
185
|
-
Card.Title = Title
|
|
186
|
-
Card.SupportText = SupportText
|
|
185
|
+
Card.Title = Title
|
|
186
|
+
Card.SupportText = SupportText
|
|
187
187
|
|
|
188
|
-
export default Card
|
|
188
|
+
export default Card
|