jfs-components 0.1.25 → 0.1.30
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 +53 -0
- package/lib/commonjs/components/AutoplayControl/AutoplayControl.js +66 -0
- package/lib/commonjs/components/Carousel/Carousel.js +112 -19
- package/lib/commonjs/components/CompareTable/CompareTable.js +191 -25
- package/lib/commonjs/components/ContentSheet/ContentSheet.js +104 -10
- package/lib/commonjs/components/FormUpload/Additem.js +168 -0
- package/lib/commonjs/components/FormUpload/FormUpload.js +198 -0
- package/lib/commonjs/components/Grid/Grid.js +206 -0
- package/lib/commonjs/components/MoneyValue/MoneyValue.js +179 -54
- package/lib/commonjs/components/NumberPagination/NumberPagination.js +144 -0
- package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +7 -1
- package/lib/commonjs/components/ProfileCard/ProfileCard.js +208 -0
- package/lib/commonjs/components/Table/Table.js +27 -7
- package/lib/commonjs/components/UpiHandle/UpiHandle.js +23 -11
- package/lib/commonjs/components/index.js +42 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/design-tokens/figma-modes.generated.js +21 -10
- package/lib/commonjs/icons/components/IconBrokenimage.js +19 -0
- package/lib/commonjs/icons/components/IconImage.js +19 -0
- package/lib/commonjs/icons/components/IconMic.js +19 -0
- package/lib/commonjs/icons/components/IconMicoff.js +19 -0
- package/lib/commonjs/icons/components/IconPause.js +19 -0
- package/lib/commonjs/icons/components/IconPlay.js +19 -0
- package/lib/commonjs/icons/components/index.js +66 -0
- package/lib/commonjs/icons/registry.js +2 -2
- package/lib/module/components/AutoplayControl/AutoplayControl.js +60 -0
- package/lib/module/components/Carousel/Carousel.js +111 -19
- package/lib/module/components/CompareTable/CompareTable.js +191 -26
- package/lib/module/components/ContentSheet/ContentSheet.js +108 -14
- package/lib/module/components/FormUpload/Additem.js +162 -0
- package/lib/module/components/FormUpload/FormUpload.js +192 -0
- package/lib/module/components/Grid/Grid.js +201 -0
- package/lib/module/components/MoneyValue/MoneyValue.js +182 -57
- package/lib/module/components/NumberPagination/NumberPagination.js +138 -0
- package/lib/module/components/PdpCcCard/PdpCcCard.js +7 -1
- package/lib/module/components/ProfileCard/ProfileCard.js +202 -0
- package/lib/module/components/Table/Table.js +27 -7
- package/lib/module/components/UpiHandle/UpiHandle.js +23 -11
- package/lib/module/components/index.js +7 -1
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/design-tokens/figma-modes.generated.js +21 -10
- package/lib/module/icons/components/IconBrokenimage.js +12 -0
- package/lib/module/icons/components/IconImage.js +12 -0
- package/lib/module/icons/components/IconMic.js +12 -0
- package/lib/module/icons/components/IconMicoff.js +12 -0
- package/lib/module/icons/components/IconPause.js +12 -0
- package/lib/module/icons/components/IconPlay.js +12 -0
- package/lib/module/icons/components/index.js +6 -0
- package/lib/module/icons/registry.js +2 -2
- package/lib/typescript/src/components/AutoplayControl/AutoplayControl.d.ts +15 -0
- package/lib/typescript/src/components/Carousel/Carousel.d.ts +8 -1
- package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +21 -1
- package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +20 -1
- package/lib/typescript/src/components/FormUpload/Additem.d.ts +96 -0
- package/lib/typescript/src/components/FormUpload/FormUpload.d.ts +85 -0
- package/lib/typescript/src/components/Grid/Grid.d.ts +87 -0
- package/lib/typescript/src/components/MoneyValue/MoneyValue.d.ts +10 -1
- package/lib/typescript/src/components/NumberPagination/NumberPagination.d.ts +21 -0
- package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +25 -1
- package/lib/typescript/src/components/ProfileCard/ProfileCard.d.ts +89 -0
- package/lib/typescript/src/components/Table/Table.d.ts +9 -1
- package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +7 -1
- package/lib/typescript/src/components/index.d.ts +34 -28
- package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +10 -4
- package/lib/typescript/src/icons/components/IconBrokenimage.d.ts +3 -0
- package/lib/typescript/src/icons/components/IconImage.d.ts +3 -0
- package/lib/typescript/src/icons/components/IconMic.d.ts +3 -0
- package/lib/typescript/src/icons/components/IconMicoff.d.ts +3 -0
- package/lib/typescript/src/icons/components/IconPause.d.ts +3 -0
- package/lib/typescript/src/icons/components/IconPlay.d.ts +3 -0
- package/lib/typescript/src/icons/components/index.d.ts +6 -0
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/AutoplayControl/AutoplayControl.tsx +77 -0
- package/src/components/Carousel/Carousel.tsx +133 -23
- package/src/components/CompareTable/CompareTable.tsx +224 -30
- package/src/components/ContentSheet/ContentSheet.tsx +138 -8
- package/src/components/FormUpload/Additem.tsx +262 -0
- package/src/components/FormUpload/FormUpload.tsx +313 -0
- package/src/components/Grid/Grid.tsx +368 -0
- package/src/components/MoneyValue/MoneyValue.tsx +216 -65
- package/src/components/NumberPagination/NumberPagination.tsx +170 -0
- package/src/components/PdpCcCard/PdpCcCard.tsx +36 -1
- package/src/components/ProfileCard/ProfileCard.tsx +268 -0
- package/src/components/Table/Table.tsx +29 -4
- package/src/components/UpiHandle/UpiHandle.tsx +35 -24
- package/src/components/index.ts +329 -182
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/design-tokens/figma-modes.generated.ts +21 -10
- package/src/icons/components/IconBrokenimage.tsx +11 -0
- package/src/icons/components/IconImage.tsx +11 -0
- package/src/icons/components/IconMic.tsx +11 -0
- package/src/icons/components/IconMicoff.tsx +11 -0
- package/src/icons/components/IconPause.tsx +11 -0
- package/src/icons/components/IconPlay.tsx +11 -0
- package/src/icons/components/index.ts +6 -0
- package/src/icons/registry.ts +25 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
|
+
import { useTokens } from '../../design-tokens/JFSThemeProvider';
|
|
7
|
+
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
|
|
8
|
+
import Avatar from '../Avatar/Avatar';
|
|
9
|
+
import Attached from '../Attached/Attached';
|
|
10
|
+
import IconCapsule from '../IconCapsule/IconCapsule';
|
|
11
|
+
import ListItem from '../ListItem/ListItem';
|
|
12
|
+
import UpiHandle from '../UpiHandle/UpiHandle';
|
|
13
|
+
import Divider from '../Divider/Divider';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A single UPI handle pill rendered under the profile name.
|
|
17
|
+
*/
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
// Forced modes for everything rendered inside the card — the profile card is
|
|
20
|
+
// an on-dark (jioPlus) surface, so child components (Avatar, UpiHandle,
|
|
21
|
+
// ListItem, Divider, Text, Button, …) must resolve their tokens through the
|
|
22
|
+
// `context 10: jioPlus` mode. Consumer modes are spread first so appearance
|
|
23
|
+
// modes (e.g. `Profile Card Appearance: Premium`) still cascade through.
|
|
24
|
+
const CARD_CONTEXT = Object.freeze({
|
|
25
|
+
'context 10': 'jioPlus'
|
|
26
|
+
});
|
|
27
|
+
const DEFAULT_UPI_HANDLES = [{
|
|
28
|
+
label: 'username@jio',
|
|
29
|
+
iconName: 'ic_copy'
|
|
30
|
+
}, {
|
|
31
|
+
label: '9999999999',
|
|
32
|
+
iconName: 'ic_confirm'
|
|
33
|
+
}];
|
|
34
|
+
function resolveProfileCardTokens(modes) {
|
|
35
|
+
const backgroundColor = getVariableByName('profileCard/bg', modes) ?? '#00065a';
|
|
36
|
+
const gap = getVariableByName('profileCard/gap', modes) ?? 12;
|
|
37
|
+
const borderRadius = getVariableByName('profileCard/radius', modes) ?? 12;
|
|
38
|
+
const paddingHorizontal = getVariableByName('profileCard/padding/horizontal', modes) ?? 20;
|
|
39
|
+
const paddingVertical = getVariableByName('profileCard/padding/vertical', modes) ?? 20;
|
|
40
|
+
const childModes = {
|
|
41
|
+
...modes,
|
|
42
|
+
...CARD_CONTEXT
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// The UPI handle pills sit in the header ListItem's support slot, whose row
|
|
46
|
+
// gap is the `slot/gap` token in the ListItem context.
|
|
47
|
+
const handlesGap = getVariableByName('slot/gap', {
|
|
48
|
+
...childModes,
|
|
49
|
+
Context: 'ListItem'
|
|
50
|
+
}) ?? 2;
|
|
51
|
+
|
|
52
|
+
// The avatar badge is a white circle: the fill comes from the Attached
|
|
53
|
+
// slot's background token (the IconCapsule itself resolves transparent).
|
|
54
|
+
const badgeBackground = getVariableByName('attached/slot/background', childModes) ?? '#ffffff';
|
|
55
|
+
return {
|
|
56
|
+
containerStyle: {
|
|
57
|
+
backgroundColor,
|
|
58
|
+
borderRadius,
|
|
59
|
+
paddingHorizontal,
|
|
60
|
+
paddingVertical,
|
|
61
|
+
gap,
|
|
62
|
+
flexDirection: 'column',
|
|
63
|
+
alignItems: 'stretch'
|
|
64
|
+
},
|
|
65
|
+
handlesRowStyle: {
|
|
66
|
+
flexDirection: 'row',
|
|
67
|
+
flexWrap: 'wrap',
|
|
68
|
+
alignItems: 'center',
|
|
69
|
+
alignSelf: 'flex-start',
|
|
70
|
+
gap: handlesGap
|
|
71
|
+
},
|
|
72
|
+
badgeBackground,
|
|
73
|
+
childModes,
|
|
74
|
+
// XS capsule per the Figma spec; consumers can still override the size
|
|
75
|
+
// through their own modes.
|
|
76
|
+
badgeModes: {
|
|
77
|
+
'Icon Capsule Size': 'XS',
|
|
78
|
+
...modes,
|
|
79
|
+
...CARD_CONTEXT
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* ProfileCard — Figma node 6914:38498 ("Profile Card").
|
|
86
|
+
*
|
|
87
|
+
* A dark, rounded profile summary card composed from the shared primitives:
|
|
88
|
+
*
|
|
89
|
+
* - **Header** — a {@link ListItem} whose leading slot is an {@link Attached}
|
|
90
|
+
* monogram {@link Avatar} with a small {@link IconCapsule} badge at its
|
|
91
|
+
* bottom-right, the user's name as the title, and a row of
|
|
92
|
+
* {@link UpiHandle} pills in the support slot.
|
|
93
|
+
* - **Divider** — separates the header from the body.
|
|
94
|
+
* - **Body slot** — arbitrary children (typically `ListItem`s separated by
|
|
95
|
+
* `Divider`s). All profile-card context modes cascade into the slot, so
|
|
96
|
+
* nested components automatically resolve their on-dark token values.
|
|
97
|
+
*
|
|
98
|
+
* The card supports the `Profile Card Appearance` collection
|
|
99
|
+
* (`Default` | `Premium`) via the `modes` prop, which recolors the container,
|
|
100
|
+
* avatar, pills and divider in one go.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```tsx
|
|
104
|
+
* <ProfileCard
|
|
105
|
+
* name="Shruti Chandarshekhar Rai"
|
|
106
|
+
* monogram="SR"
|
|
107
|
+
* upiHandles={[
|
|
108
|
+
* { label: 'shrutirai-1@jio', iconName: 'ic_copy', onPress: copyHandle },
|
|
109
|
+
* { label: '9184844184', iconName: 'ic_confirm' },
|
|
110
|
+
* ]}
|
|
111
|
+
* >
|
|
112
|
+
* <ListItem layout="Horizontal" title="JioFinance+" navArrow={false} />
|
|
113
|
+
* </ProfileCard>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
function ProfileCard({
|
|
117
|
+
name = 'Name',
|
|
118
|
+
monogram = 'MS',
|
|
119
|
+
avatarSource,
|
|
120
|
+
badgeIcon = 'ic_qr_code',
|
|
121
|
+
upiHandles = DEFAULT_UPI_HANDLES,
|
|
122
|
+
header,
|
|
123
|
+
children,
|
|
124
|
+
showDivider = true,
|
|
125
|
+
width = 344,
|
|
126
|
+
modes: propModes = EMPTY_MODES,
|
|
127
|
+
style,
|
|
128
|
+
accessibilityLabel
|
|
129
|
+
}) {
|
|
130
|
+
const {
|
|
131
|
+
modes: globalModes
|
|
132
|
+
} = useTokens();
|
|
133
|
+
const modes = useMemo(() => globalModes === EMPTY_MODES && propModes === EMPTY_MODES ? EMPTY_MODES : {
|
|
134
|
+
...globalModes,
|
|
135
|
+
...propModes
|
|
136
|
+
}, [globalModes, propModes]);
|
|
137
|
+
const tokens = useMemo(() => resolveProfileCardTokens(modes), [modes]);
|
|
138
|
+
|
|
139
|
+
// ---- Header -------------------------------------------------------------
|
|
140
|
+
const headerNode = useMemo(() => {
|
|
141
|
+
if (header) return cloneChildrenWithModes(header, tokens.childModes);
|
|
142
|
+
const avatar = /*#__PURE__*/_jsx(Attached, {
|
|
143
|
+
position: "bottom-right",
|
|
144
|
+
modes: tokens.childModes,
|
|
145
|
+
badge: badgeIcon != null ? /*#__PURE__*/_jsx(IconCapsule, {
|
|
146
|
+
iconName: badgeIcon,
|
|
147
|
+
modes: tokens.badgeModes,
|
|
148
|
+
style: {
|
|
149
|
+
backgroundColor: tokens.badgeBackground
|
|
150
|
+
}
|
|
151
|
+
}) : null,
|
|
152
|
+
children: /*#__PURE__*/_jsx(Avatar, {
|
|
153
|
+
monogram: monogram,
|
|
154
|
+
style: avatarSource ? 'Image' : 'Monogram',
|
|
155
|
+
...(avatarSource != null ? {
|
|
156
|
+
imageSource: avatarSource
|
|
157
|
+
} : {}),
|
|
158
|
+
modes: tokens.childModes
|
|
159
|
+
})
|
|
160
|
+
});
|
|
161
|
+
const handles = upiHandles.length > 0 ? /*#__PURE__*/_jsx(View, {
|
|
162
|
+
style: tokens.handlesRowStyle,
|
|
163
|
+
children: upiHandles.map((handle, index) => /*#__PURE__*/_jsx(UpiHandle, {
|
|
164
|
+
label: handle.label,
|
|
165
|
+
...(handle.iconName != null ? {
|
|
166
|
+
iconName: handle.iconName
|
|
167
|
+
} : {}),
|
|
168
|
+
showIcon: handle.showIcon ?? true,
|
|
169
|
+
...(handle.onPress != null ? {
|
|
170
|
+
onPress: handle.onPress
|
|
171
|
+
} : {}),
|
|
172
|
+
modes: tokens.childModes
|
|
173
|
+
}, `${handle.label}-${index}`))
|
|
174
|
+
}) : null;
|
|
175
|
+
return /*#__PURE__*/_jsx(ListItem, {
|
|
176
|
+
layout: "Horizontal",
|
|
177
|
+
title: name,
|
|
178
|
+
navArrow: false,
|
|
179
|
+
showSupportText: handles != null,
|
|
180
|
+
supportSlot: handles,
|
|
181
|
+
leading: avatar,
|
|
182
|
+
modes: tokens.childModes
|
|
183
|
+
});
|
|
184
|
+
}, [header, name, monogram, avatarSource, badgeIcon, upiHandles, tokens]);
|
|
185
|
+
|
|
186
|
+
// ---- Body slot ----------------------------------------------------------
|
|
187
|
+
const bodyChildren = useMemo(() => children != null ? cloneChildrenWithModes(children, tokens.childModes) : null, [children, tokens.childModes]);
|
|
188
|
+
const hasBody = bodyChildren != null && bodyChildren.length > 0;
|
|
189
|
+
const containerStyle = useMemo(() => ({
|
|
190
|
+
...tokens.containerStyle,
|
|
191
|
+
width
|
|
192
|
+
}), [tokens.containerStyle, width]);
|
|
193
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
194
|
+
style: [containerStyle, style],
|
|
195
|
+
accessibilityLabel: accessibilityLabel,
|
|
196
|
+
children: [headerNode, hasBody && showDivider ? /*#__PURE__*/_jsx(Divider, {
|
|
197
|
+
direction: "horizontal",
|
|
198
|
+
modes: tokens.childModes
|
|
199
|
+
}) : null, bodyChildren]
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
export default /*#__PURE__*/React.memo(ProfileCard);
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { createContext, useContext } from 'react';
|
|
4
4
|
import { View, Text, Pressable, ScrollView, Platform } from 'react-native';
|
|
5
5
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
6
|
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
|
|
7
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
/**
|
|
9
|
+
* Carries the root `Table`'s `columnWidth` down to every cell so that, when it
|
|
10
|
+
* is set, all columns (header + body, data-driven or composed) share the same
|
|
11
|
+
* fixed width without each cell having to repeat the prop. Cells still honour
|
|
12
|
+
* an explicit `width` prop over this context value. `undefined` (the default,
|
|
13
|
+
* when no `Table` ancestor is present, or `columnWidth` is unset) leaves cells
|
|
14
|
+
* to flex — preserving the original behaviour.
|
|
15
|
+
*/
|
|
16
|
+
const TableContext = /*#__PURE__*/createContext(undefined);
|
|
7
17
|
|
|
8
18
|
/* -------------------------------------------------------------------------------------------------
|
|
9
19
|
* Shared types & token resolution
|
|
10
20
|
* -----------------------------------------------------------------------------------------------*/
|
|
11
21
|
|
|
12
22
|
/** Resolved styling for a header cell and a body cell, derived from design tokens. */
|
|
13
|
-
|
|
23
|
+
|
|
14
24
|
const toWeight = w => typeof w === 'number' ? `${w}` : w;
|
|
15
25
|
|
|
16
26
|
/**
|
|
@@ -88,6 +98,10 @@ function TableCell({
|
|
|
88
98
|
style
|
|
89
99
|
}) {
|
|
90
100
|
const t = resolveTableTokens(modes);
|
|
101
|
+
// A cell's width resolves in priority order: an explicit `width` prop, then
|
|
102
|
+
// the root Table's `columnWidth` (via context), then fall back to flex.
|
|
103
|
+
const ctxColumnWidth = useContext(TableContext);
|
|
104
|
+
const effectiveWidth = width ?? ctxColumnWidth;
|
|
91
105
|
return /*#__PURE__*/_jsx(View, {
|
|
92
106
|
style: [{
|
|
93
107
|
backgroundColor: t.cellBg,
|
|
@@ -99,8 +113,8 @@ function TableCell({
|
|
|
99
113
|
borderColor: t.borderColor,
|
|
100
114
|
borderBottomWidth: isLastRow ? 0 : t.borderSize,
|
|
101
115
|
borderRightWidth: isLastColumn ? 0 : t.borderSize,
|
|
102
|
-
...(
|
|
103
|
-
width
|
|
116
|
+
...(effectiveWidth != null ? {
|
|
117
|
+
width: effectiveWidth
|
|
104
118
|
} : {
|
|
105
119
|
flex,
|
|
106
120
|
minWidth: 0
|
|
@@ -128,6 +142,8 @@ function TableHeaderCell({
|
|
|
128
142
|
style
|
|
129
143
|
}) {
|
|
130
144
|
const t = resolveTableTokens(modes);
|
|
145
|
+
const ctxColumnWidth = useContext(TableContext);
|
|
146
|
+
const effectiveWidth = width ?? ctxColumnWidth;
|
|
131
147
|
return /*#__PURE__*/_jsx(View, {
|
|
132
148
|
style: [{
|
|
133
149
|
backgroundColor: t.headerBg,
|
|
@@ -136,8 +152,8 @@ function TableHeaderCell({
|
|
|
136
152
|
justifyContent: alignToJustify(align),
|
|
137
153
|
paddingHorizontal: t.headerPaddingH,
|
|
138
154
|
paddingVertical: t.headerPaddingV,
|
|
139
|
-
...(
|
|
140
|
-
width
|
|
155
|
+
...(effectiveWidth != null ? {
|
|
156
|
+
width: effectiveWidth
|
|
141
157
|
} : {
|
|
142
158
|
flex,
|
|
143
159
|
minWidth: 0
|
|
@@ -252,6 +268,7 @@ function Table({
|
|
|
252
268
|
getRowKey,
|
|
253
269
|
onRowPress,
|
|
254
270
|
scrollable = false,
|
|
271
|
+
columnWidth,
|
|
255
272
|
accessibilityLabel,
|
|
256
273
|
modes = EMPTY_MODES,
|
|
257
274
|
style
|
|
@@ -295,7 +312,10 @@ function Table({
|
|
|
295
312
|
}, !scrollable && {
|
|
296
313
|
width: '100%'
|
|
297
314
|
}, style],
|
|
298
|
-
children:
|
|
315
|
+
children: /*#__PURE__*/_jsx(TableContext.Provider, {
|
|
316
|
+
value: columnWidth,
|
|
317
|
+
children: body
|
|
318
|
+
})
|
|
299
319
|
});
|
|
300
320
|
if (scrollable) {
|
|
301
321
|
return /*#__PURE__*/_jsx(ScrollView, {
|
|
@@ -8,9 +8,6 @@ import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils';
|
|
|
8
8
|
import MediaSource from '../../utils/MediaSource';
|
|
9
9
|
import Icon from '../../icons/Icon';
|
|
10
10
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
// Default static asset from the component folder.
|
|
12
|
-
// Consumers can override the image via the `source` prop if needed.
|
|
13
|
-
const DEFAULT_AVATAR_IMAGE = require('./Image.png');
|
|
14
11
|
const IS_WEB = Platform.OS === 'web';
|
|
15
12
|
const IS_IOS = Platform.OS === 'ios';
|
|
16
13
|
const PRESS_DELAY = IS_IOS ? 130 : 0;
|
|
@@ -83,7 +80,7 @@ function resolveUpiHandleTokens(modes) {
|
|
|
83
80
|
* @param {Object} [props.modes={}] - Modes object passed directly to `getVariableByName`.
|
|
84
81
|
* @param {boolean} [props.showIcon=true] - Toggles the trailing icon visibility.
|
|
85
82
|
* @param {string} [props.iconName='ic_scan_qr_code'] - Icon name from the actions set.
|
|
86
|
-
* @param {UnifiedSource} [props.source] - Unified avatar source (URI, inline SVG XML, `require()` asset, SVG React component, or React element). Smart-detects raster vs SVG so the same prop works on iOS, Android and web.
|
|
83
|
+
* @param {UnifiedSource} [props.source] - Unified avatar source (URI, inline SVG XML, `require()` asset, SVG React component, or React element). Smart-detects raster vs SVG so the same prop works on iOS, Android and web. Providing a source force-sets `UPI Handle Image: True` (avatar shown); omitting it force-sets `False` (avatar hidden), overriding any `UPI Handle Image` value passed via `modes`.
|
|
87
84
|
* @param {ImageSourcePropType|UnifiedSource} [props.avatarSource] - Deprecated alias for `source`; kept for back-compat.
|
|
88
85
|
* @param {Function} [props.onClick] - Click/tap handler. Works as an alias for `onPress`.
|
|
89
86
|
* @param {string} [props.accessibilityLabel] - Accessibility label for screen readers
|
|
@@ -118,10 +115,24 @@ function UpiHandle({
|
|
|
118
115
|
const {
|
|
119
116
|
modes: globalModes
|
|
120
117
|
} = useTokens();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
|
|
119
|
+
// The avatar is fully driven by the presence of a `source`. It force-sets the
|
|
120
|
+
// Figma "UPI Handle Image" collection to `True` when a source is provided and
|
|
121
|
+
// `False` otherwise. This is applied last so it overrides any consumer-passed
|
|
122
|
+
// `UPI Handle Image` mode, keeping the avatar visibility and the token layout
|
|
123
|
+
// (symmetric padding in the hidden-image state) in lockstep with the source.
|
|
124
|
+
const hasSource = source != null || avatarSource != null;
|
|
125
|
+
const modes = useMemo(() => {
|
|
126
|
+
const base = globalModes === EMPTY_MODES && propModes === EMPTY_MODES ? EMPTY_MODES : {
|
|
127
|
+
...globalModes,
|
|
128
|
+
...propModes
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
...base,
|
|
132
|
+
'UPI Handle Image': hasSource ? 'True' : 'False'
|
|
133
|
+
};
|
|
134
|
+
}, [globalModes, propModes, hasSource]);
|
|
135
|
+
const showImageResolved = hasSource;
|
|
125
136
|
const tokens = useMemo(() => resolveUpiHandleTokens(modes), [modes]);
|
|
126
137
|
|
|
127
138
|
// Focus is a sustained visible state (web-only). Setter is gated so it
|
|
@@ -155,11 +166,12 @@ function UpiHandle({
|
|
|
155
166
|
|
|
156
167
|
// `source` wins; `avatarSource` is the legacy fallback. Both are accepted
|
|
157
168
|
// as a UnifiedSource (string / number / {uri} / component / element), and
|
|
158
|
-
// the legacy `ImageSourcePropType` shapes naturally fit that union too.
|
|
159
|
-
|
|
169
|
+
// the legacy `ImageSourcePropType` shapes naturally fit that union too. This
|
|
170
|
+
// is only read when `showImageResolved` is true, which requires a source.
|
|
171
|
+
const resolvedAvatarSource = source ?? avatarSource;
|
|
160
172
|
const avatarSize = tokens.avatarStyle.width ?? 23;
|
|
161
173
|
const innerContent = /*#__PURE__*/_jsxs(_Fragment, {
|
|
162
|
-
children: [/*#__PURE__*/_jsx(View, {
|
|
174
|
+
children: [showImageResolved && /*#__PURE__*/_jsx(View, {
|
|
163
175
|
style: tokens.avatarStyle,
|
|
164
176
|
children: /*#__PURE__*/_jsx(MediaSource, {
|
|
165
177
|
source: resolvedAvatarSource,
|
|
@@ -37,6 +37,9 @@ export { default as FullscreenModal } from './FullscreenModal/FullscreenModal';
|
|
|
37
37
|
export { default as Form } from './Form/Form';
|
|
38
38
|
export { useFormContext } from './Form/Form';
|
|
39
39
|
export { default as FormField } from './FormField/FormField';
|
|
40
|
+
export { default as Grid } from './Grid/Grid';
|
|
41
|
+
export { default as FormUpload } from './FormUpload/FormUpload';
|
|
42
|
+
export { default as Additem } from './FormUpload/Additem';
|
|
40
43
|
export { default as ContentSheet } from './ContentSheet/ContentSheet';
|
|
41
44
|
export { default as CircularProgressBar } from './CircularProgressBar/CircularProgressBar';
|
|
42
45
|
export { default as CircularProgressBarDoted } from './CircularProgressBarDoted/CircularProgressBarDoted';
|
|
@@ -136,6 +139,7 @@ export { default as CompareTable } from './CompareTable/CompareTable';
|
|
|
136
139
|
export { default as Table, TableHeader, TableHeaderCell, TableBody, TableRow, TableCell } from './Table/Table';
|
|
137
140
|
export { default as PoweredByLabel } from './PoweredByLabel/PoweredByLabel';
|
|
138
141
|
export { default as ProductLabel } from './ProductLabel/ProductLabel';
|
|
142
|
+
export { default as ProfileCard } from './ProfileCard/ProfileCard';
|
|
139
143
|
export { default as ProductMerchandisingCard } from './ProductMerchandisingCard/ProductMerchandisingCard';
|
|
140
144
|
export { default as ProductOverview } from './ProductOverview/ProductOverview';
|
|
141
145
|
export { default as ProjectionMarker } from './ProjectionMarker/ProjectionMarker';
|
|
@@ -151,4 +155,6 @@ export { default as TestimonialsCard } from './TestimonialsCard/TestimonialsCard
|
|
|
151
155
|
export { default as Text } from './Text/Text';
|
|
152
156
|
export { default as TextSegment } from './TextSegment/TextSegment';
|
|
153
157
|
export { default as SegmentedControl } from './SegmentedControl/SegmentedControl';
|
|
154
|
-
export { default as Toggle } from './Toggle/Toggle';
|
|
158
|
+
export { default as Toggle } from './Toggle/Toggle';
|
|
159
|
+
export { default as AutoplayControl } from './AutoplayControl/AutoplayControl';
|
|
160
|
+
export { default as NumberPagination } from './NumberPagination/NumberPagination';
|