@xsolla/xui-b2b-onboard-empty-state 0.216.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/native/index.d.mts +43 -0
- package/native/index.d.ts +43 -0
- package/native/index.js +342 -0
- package/native/index.js.map +1 -0
- package/native/index.mjs +319 -0
- package/native/index.mjs.map +1 -0
- package/package.json +59 -0
- package/web/index.d.mts +43 -0
- package/web/index.d.ts +43 -0
- package/web/index.js +381 -0
- package/web/index.js.map +1 -0
- package/web/index.mjs +344 -0
- package/web/index.mjs.map +1 -0
package/native/index.mjs
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// src/OnboardEmptyState.tsx
|
|
2
|
+
import { cloneElement, isValidElement } from "react";
|
|
3
|
+
|
|
4
|
+
// ../../foundation/primitives-native/src/Box.tsx
|
|
5
|
+
import {
|
|
6
|
+
View,
|
|
7
|
+
Pressable,
|
|
8
|
+
Image
|
|
9
|
+
} from "react-native";
|
|
10
|
+
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
var roleToAccessibilityRole = {
|
|
12
|
+
button: "button",
|
|
13
|
+
link: "link",
|
|
14
|
+
img: "image",
|
|
15
|
+
image: "image",
|
|
16
|
+
summary: "summary",
|
|
17
|
+
switch: "switch",
|
|
18
|
+
checkbox: "checkbox",
|
|
19
|
+
radio: "radio",
|
|
20
|
+
heading: "header",
|
|
21
|
+
text: "text",
|
|
22
|
+
search: "search",
|
|
23
|
+
alert: "alert",
|
|
24
|
+
none: "none",
|
|
25
|
+
presentation: "none",
|
|
26
|
+
progressbar: "progressbar",
|
|
27
|
+
scrollbar: "scrollbar",
|
|
28
|
+
adjustable: "adjustable",
|
|
29
|
+
tab: "tab",
|
|
30
|
+
menu: "menu",
|
|
31
|
+
menuitem: "menuitem",
|
|
32
|
+
list: "list",
|
|
33
|
+
timer: "timer"
|
|
34
|
+
};
|
|
35
|
+
var toGapValue = (gap) => {
|
|
36
|
+
if (gap === void 0) return void 0;
|
|
37
|
+
if (typeof gap === "number") return gap;
|
|
38
|
+
const pxMatch = /^(\d+(?:\.\d+)?)px$/.exec(gap);
|
|
39
|
+
if (pxMatch) return Number(pxMatch[1]);
|
|
40
|
+
const asNumber = Number(gap);
|
|
41
|
+
return Number.isFinite(asNumber) ? asNumber : void 0;
|
|
42
|
+
};
|
|
43
|
+
var Box = ({
|
|
44
|
+
children,
|
|
45
|
+
onPress,
|
|
46
|
+
onLayout,
|
|
47
|
+
onMoveShouldSetResponder,
|
|
48
|
+
onResponderGrant,
|
|
49
|
+
onResponderMove,
|
|
50
|
+
onResponderRelease,
|
|
51
|
+
onResponderTerminate,
|
|
52
|
+
backgroundColor,
|
|
53
|
+
borderColor,
|
|
54
|
+
borderWidth,
|
|
55
|
+
borderBottomWidth,
|
|
56
|
+
borderBottomColor,
|
|
57
|
+
borderTopWidth,
|
|
58
|
+
borderTopColor,
|
|
59
|
+
borderLeftWidth,
|
|
60
|
+
borderLeftColor,
|
|
61
|
+
borderRightWidth,
|
|
62
|
+
borderRightColor,
|
|
63
|
+
borderRadius,
|
|
64
|
+
borderStyle,
|
|
65
|
+
height,
|
|
66
|
+
padding,
|
|
67
|
+
paddingHorizontal,
|
|
68
|
+
paddingVertical,
|
|
69
|
+
margin,
|
|
70
|
+
marginTop,
|
|
71
|
+
marginBottom,
|
|
72
|
+
marginLeft,
|
|
73
|
+
marginRight,
|
|
74
|
+
flexDirection,
|
|
75
|
+
flexWrap,
|
|
76
|
+
alignItems,
|
|
77
|
+
justifyContent,
|
|
78
|
+
alignSelf,
|
|
79
|
+
position,
|
|
80
|
+
top,
|
|
81
|
+
bottom,
|
|
82
|
+
left,
|
|
83
|
+
right,
|
|
84
|
+
width,
|
|
85
|
+
minWidth,
|
|
86
|
+
minHeight,
|
|
87
|
+
maxWidth,
|
|
88
|
+
maxHeight,
|
|
89
|
+
flex,
|
|
90
|
+
flexShrink,
|
|
91
|
+
gap,
|
|
92
|
+
overflow,
|
|
93
|
+
opacity,
|
|
94
|
+
zIndex,
|
|
95
|
+
hoverStyle,
|
|
96
|
+
pressStyle,
|
|
97
|
+
style,
|
|
98
|
+
disabled,
|
|
99
|
+
"data-testid": dataTestId,
|
|
100
|
+
testID,
|
|
101
|
+
as,
|
|
102
|
+
src,
|
|
103
|
+
alt,
|
|
104
|
+
...rest
|
|
105
|
+
}) => {
|
|
106
|
+
const getContainerStyle = (pressed) => ({
|
|
107
|
+
backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
|
|
108
|
+
borderColor,
|
|
109
|
+
borderWidth,
|
|
110
|
+
borderBottomWidth,
|
|
111
|
+
borderBottomColor,
|
|
112
|
+
borderTopWidth,
|
|
113
|
+
borderTopColor,
|
|
114
|
+
borderLeftWidth,
|
|
115
|
+
borderLeftColor,
|
|
116
|
+
borderRightWidth,
|
|
117
|
+
borderRightColor,
|
|
118
|
+
borderRadius,
|
|
119
|
+
borderStyle,
|
|
120
|
+
overflow,
|
|
121
|
+
opacity: opacity ?? (disabled ? 0.5 : void 0),
|
|
122
|
+
zIndex,
|
|
123
|
+
height,
|
|
124
|
+
width,
|
|
125
|
+
minWidth,
|
|
126
|
+
minHeight,
|
|
127
|
+
maxWidth,
|
|
128
|
+
maxHeight,
|
|
129
|
+
padding,
|
|
130
|
+
paddingHorizontal,
|
|
131
|
+
paddingVertical,
|
|
132
|
+
margin,
|
|
133
|
+
marginTop,
|
|
134
|
+
marginBottom,
|
|
135
|
+
marginLeft,
|
|
136
|
+
marginRight,
|
|
137
|
+
flexDirection,
|
|
138
|
+
flexWrap,
|
|
139
|
+
alignItems,
|
|
140
|
+
justifyContent,
|
|
141
|
+
alignSelf,
|
|
142
|
+
position,
|
|
143
|
+
top,
|
|
144
|
+
bottom,
|
|
145
|
+
left,
|
|
146
|
+
right,
|
|
147
|
+
flex,
|
|
148
|
+
flexShrink,
|
|
149
|
+
gap: toGapValue(gap),
|
|
150
|
+
...style
|
|
151
|
+
});
|
|
152
|
+
const finalTestID = dataTestId || testID;
|
|
153
|
+
const {
|
|
154
|
+
role,
|
|
155
|
+
tabIndex,
|
|
156
|
+
onKeyDown,
|
|
157
|
+
onKeyUp,
|
|
158
|
+
"aria-label": ariaLabel,
|
|
159
|
+
"aria-labelledby": _ariaLabelledBy,
|
|
160
|
+
"aria-current": _ariaCurrent,
|
|
161
|
+
"aria-disabled": ariaDisabled,
|
|
162
|
+
"aria-live": ariaLive,
|
|
163
|
+
"aria-busy": ariaBusy,
|
|
164
|
+
className,
|
|
165
|
+
"data-testid": _dataTestId,
|
|
166
|
+
cursor: _cursor,
|
|
167
|
+
type: _type,
|
|
168
|
+
...nativeRest
|
|
169
|
+
} = rest;
|
|
170
|
+
const accessibilityRole = typeof role === "string" && roleToAccessibilityRole[role] || (as === "button" ? "button" : void 0);
|
|
171
|
+
const isDisabled = Boolean(disabled || ariaDisabled);
|
|
172
|
+
const accessibilityState = {
|
|
173
|
+
disabled: isDisabled || void 0,
|
|
174
|
+
busy: Boolean(ariaBusy) || void 0
|
|
175
|
+
};
|
|
176
|
+
const accessibilityLiveRegion = ariaLive === "polite" || ariaLive === "assertive" ? ariaLive : void 0;
|
|
177
|
+
if (as === "img" && src) {
|
|
178
|
+
const imageStyle = {
|
|
179
|
+
width,
|
|
180
|
+
height,
|
|
181
|
+
borderRadius,
|
|
182
|
+
position,
|
|
183
|
+
top,
|
|
184
|
+
bottom,
|
|
185
|
+
left,
|
|
186
|
+
right,
|
|
187
|
+
...style
|
|
188
|
+
};
|
|
189
|
+
return /* @__PURE__ */ jsx(
|
|
190
|
+
Image,
|
|
191
|
+
{
|
|
192
|
+
source: { uri: src },
|
|
193
|
+
style: imageStyle,
|
|
194
|
+
testID: finalTestID,
|
|
195
|
+
accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : alt,
|
|
196
|
+
resizeMode: "cover",
|
|
197
|
+
...nativeRest
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
if (onPress || as === "button") {
|
|
202
|
+
return /* @__PURE__ */ jsx(
|
|
203
|
+
Pressable,
|
|
204
|
+
{
|
|
205
|
+
onPress: !isDisabled && onPress ? onPress : void 0,
|
|
206
|
+
disabled: isDisabled,
|
|
207
|
+
onLayout,
|
|
208
|
+
onMoveShouldSetResponder,
|
|
209
|
+
onResponderGrant,
|
|
210
|
+
onResponderMove,
|
|
211
|
+
onResponderRelease,
|
|
212
|
+
onResponderTerminate,
|
|
213
|
+
style: ({ pressed }) => getContainerStyle(pressed),
|
|
214
|
+
testID: finalTestID,
|
|
215
|
+
accessibilityRole,
|
|
216
|
+
accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
|
|
217
|
+
accessibilityState,
|
|
218
|
+
accessibilityLiveRegion,
|
|
219
|
+
...nativeRest,
|
|
220
|
+
children
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
return /* @__PURE__ */ jsx(
|
|
225
|
+
View,
|
|
226
|
+
{
|
|
227
|
+
style: getContainerStyle(),
|
|
228
|
+
testID: finalTestID,
|
|
229
|
+
onLayout,
|
|
230
|
+
onMoveShouldSetResponder,
|
|
231
|
+
onResponderGrant,
|
|
232
|
+
onResponderMove,
|
|
233
|
+
onResponderRelease,
|
|
234
|
+
onResponderTerminate,
|
|
235
|
+
accessibilityRole,
|
|
236
|
+
accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
|
|
237
|
+
accessibilityState,
|
|
238
|
+
accessibilityLiveRegion,
|
|
239
|
+
...nativeRest,
|
|
240
|
+
children
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/OnboardEmptyState.tsx
|
|
246
|
+
import { useResolvedTheme } from "@xsolla/xui-core";
|
|
247
|
+
import { Typography } from "@xsolla/xui-typography";
|
|
248
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
249
|
+
var ASSET_GAP = 24;
|
|
250
|
+
var TEXT_GAP = 12;
|
|
251
|
+
var ITEM_GAP = 24;
|
|
252
|
+
var ACTIONS_GAP = 40;
|
|
253
|
+
var BUTTON_GAP = 8;
|
|
254
|
+
var OnboardEmptyState = ({
|
|
255
|
+
items = [],
|
|
256
|
+
primaryAction,
|
|
257
|
+
secondaryAction,
|
|
258
|
+
className,
|
|
259
|
+
testID,
|
|
260
|
+
themeMode,
|
|
261
|
+
themeProductContext
|
|
262
|
+
}) => {
|
|
263
|
+
const { theme } = useResolvedTheme({ themeMode, themeProductContext });
|
|
264
|
+
const actions = [primaryAction, secondaryAction].filter(
|
|
265
|
+
(action) => isValidElement(action)
|
|
266
|
+
);
|
|
267
|
+
return /* @__PURE__ */ jsxs(
|
|
268
|
+
Box,
|
|
269
|
+
{
|
|
270
|
+
flexDirection: "column",
|
|
271
|
+
gap: ACTIONS_GAP,
|
|
272
|
+
className,
|
|
273
|
+
testID,
|
|
274
|
+
children: [
|
|
275
|
+
items.length > 0 && /* @__PURE__ */ jsx2(Box, { flexDirection: "column", gap: ITEM_GAP, children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
276
|
+
Box,
|
|
277
|
+
{
|
|
278
|
+
flexDirection: "row",
|
|
279
|
+
alignItems: "flex-start",
|
|
280
|
+
gap: ASSET_GAP,
|
|
281
|
+
children: [
|
|
282
|
+
item.asset ? /* @__PURE__ */ jsx2(Box, { flexShrink: 0, children: item.asset }) : null,
|
|
283
|
+
/* @__PURE__ */ jsxs(Box, { flex: 1, flexDirection: "column", gap: TEXT_GAP, children: [
|
|
284
|
+
/* @__PURE__ */ jsx2(
|
|
285
|
+
Typography,
|
|
286
|
+
{
|
|
287
|
+
variant: "bodyMdAccent",
|
|
288
|
+
color: theme.colors.content.primary,
|
|
289
|
+
children: item.headline
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
item.description && /* @__PURE__ */ jsx2(
|
|
293
|
+
Typography,
|
|
294
|
+
{
|
|
295
|
+
variant: "bodyMdParagraph",
|
|
296
|
+
color: theme.colors.content.secondary,
|
|
297
|
+
children: item.description
|
|
298
|
+
}
|
|
299
|
+
)
|
|
300
|
+
] })
|
|
301
|
+
]
|
|
302
|
+
},
|
|
303
|
+
item.id ?? index
|
|
304
|
+
)) }),
|
|
305
|
+
actions.length > 0 && /* @__PURE__ */ jsx2(Box, { flexDirection: "column", alignSelf: "stretch", gap: BUTTON_GAP, children: actions.map(
|
|
306
|
+
(action, index) => cloneElement(action, {
|
|
307
|
+
key: index,
|
|
308
|
+
fullWidth: true
|
|
309
|
+
})
|
|
310
|
+
) })
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
};
|
|
315
|
+
OnboardEmptyState.displayName = "OnboardEmptyState";
|
|
316
|
+
export {
|
|
317
|
+
OnboardEmptyState
|
|
318
|
+
};
|
|
319
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/OnboardEmptyState.tsx","../../../../foundation/primitives-native/src/Box.tsx"],"sourcesContent":["import React, { cloneElement, isValidElement } from \"react\";\nimport type { ReactElement } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport type { OnboardEmptyStateProps } from \"./types\";\n\n/** Gap between an item's asset slot and its text block. */\nconst ASSET_GAP = 24;\n/** Gap between an item's headline and its description. */\nconst TEXT_GAP = 12;\n/** Gap between consecutive items. */\nconst ITEM_GAP = 24;\n/** Gap between the item list and the button group. */\nconst ACTIONS_GAP = 40;\n/** Gap between the stacked action buttons. */\nconst BUTTON_GAP = 8;\n\nexport const OnboardEmptyState: React.FC<OnboardEmptyStateProps> = ({\n items = [],\n primaryAction,\n secondaryAction,\n className,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const actions = [primaryAction, secondaryAction].filter(\n (action): action is ReactElement => isValidElement(action)\n );\n\n return (\n <Box\n flexDirection=\"column\"\n gap={ACTIONS_GAP}\n className={className}\n testID={testID}\n >\n {items.length > 0 && (\n <Box flexDirection=\"column\" gap={ITEM_GAP}>\n {items.map((item, index) => (\n <Box\n key={item.id ?? index}\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n gap={ASSET_GAP}\n >\n {item.asset ? <Box flexShrink={0}>{item.asset}</Box> : null}\n <Box flex={1} flexDirection=\"column\" gap={TEXT_GAP}>\n <Typography\n variant=\"bodyMdAccent\"\n color={theme.colors.content.primary}\n >\n {item.headline}\n </Typography>\n {item.description && (\n <Typography\n variant=\"bodyMdParagraph\"\n color={theme.colors.content.secondary}\n >\n {item.description}\n </Typography>\n )}\n </Box>\n </Box>\n ))}\n </Box>\n )}\n {actions.length > 0 && (\n <Box flexDirection=\"column\" alignSelf=\"stretch\" gap={BUTTON_GAP}>\n {actions.map((action, index) =>\n cloneElement(action as ReactElement<{ fullWidth?: boolean }>, {\n key: index,\n fullWidth: true,\n })\n )}\n </Box>\n )}\n </Box>\n );\n};\n\nOnboardEmptyState.displayName = \"OnboardEmptyState\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n"],"mappings":"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","names":["jsx"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xsolla/xui-b2b-onboard-empty-state",
|
|
3
|
+
"version": "0.216.0",
|
|
4
|
+
"main": "./web/index.js",
|
|
5
|
+
"module": "./web/index.mjs",
|
|
6
|
+
"types": "./web/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "yarn build:web && yarn build:native",
|
|
9
|
+
"build:web": "PLATFORM=web tsup",
|
|
10
|
+
"build:native": "PLATFORM=native tsup",
|
|
11
|
+
"test": "vitest",
|
|
12
|
+
"test:run": "vitest run",
|
|
13
|
+
"test:coverage": "vitest run --coverage"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@xsolla/xui-core": "0.216.0",
|
|
17
|
+
"@xsolla/xui-primitives-core": "0.216.0",
|
|
18
|
+
"@xsolla/xui-typography": "0.216.0"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"react": ">=16.8.0",
|
|
22
|
+
"react-dom": ">=16",
|
|
23
|
+
"styled-components": ">=4"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
27
|
+
"@testing-library/react": "^14.1.2",
|
|
28
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
29
|
+
"jsdom": "^24.0.0",
|
|
30
|
+
"react": "^18.0.0",
|
|
31
|
+
"react-dom": "^18.0.0",
|
|
32
|
+
"tsup": "^8.0.0",
|
|
33
|
+
"vitest": "^4.0.18"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"sideEffects": false,
|
|
37
|
+
"react-native": "./native/index.js",
|
|
38
|
+
"exports": {
|
|
39
|
+
".": {
|
|
40
|
+
"react-native": {
|
|
41
|
+
"types": "./native/index.d.ts",
|
|
42
|
+
"import": "./native/index.mjs",
|
|
43
|
+
"require": "./native/index.js"
|
|
44
|
+
},
|
|
45
|
+
"import": {
|
|
46
|
+
"types": "./web/index.d.ts",
|
|
47
|
+
"default": "./web/index.mjs"
|
|
48
|
+
},
|
|
49
|
+
"require": {
|
|
50
|
+
"types": "./web/index.d.ts",
|
|
51
|
+
"default": "./web/index.js"
|
|
52
|
+
},
|
|
53
|
+
"default": {
|
|
54
|
+
"types": "./web/index.d.ts",
|
|
55
|
+
"default": "./web/index.js"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
package/web/index.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { ThemeOverrideProps } from '@xsolla/xui-core';
|
|
3
|
+
|
|
4
|
+
interface OnboardEmptyStateItem {
|
|
5
|
+
/**
|
|
6
|
+
* Stable key for the item. Falls back to the array index when omitted.
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Graphic slot rendered to the left of the text, aligned to its top edge.
|
|
11
|
+
* Accepts any node — a 2D illustration, an `IconWrapper`, or a plain `<img>`.
|
|
12
|
+
* Omit it to render a text-only item.
|
|
13
|
+
*/
|
|
14
|
+
asset?: ReactNode;
|
|
15
|
+
/** Item heading, rendered in `bodyMdAccent`. */
|
|
16
|
+
headline: string;
|
|
17
|
+
/** Supporting copy below the heading, rendered in `bodyMdParagraph`. */
|
|
18
|
+
description?: string;
|
|
19
|
+
}
|
|
20
|
+
interface OnboardEmptyStateProps extends ThemeOverrideProps {
|
|
21
|
+
/**
|
|
22
|
+
* Onboarding items, stacked vertically. Any number is supported — the
|
|
23
|
+
* component does not assume the three shown in the primary Storybook story.
|
|
24
|
+
*/
|
|
25
|
+
items?: OnboardEmptyStateItem[];
|
|
26
|
+
/**
|
|
27
|
+
* Primary action button. Cloned with `fullWidth` set to `true` and stacked
|
|
28
|
+
* above `secondaryAction`.
|
|
29
|
+
*/
|
|
30
|
+
primaryAction?: ReactElement;
|
|
31
|
+
/**
|
|
32
|
+
* Secondary action button. Cloned with `fullWidth` set to `true` and stacked
|
|
33
|
+
* below `primaryAction`. Both actions are optional — the component renders
|
|
34
|
+
* with two buttons, one button, or none.
|
|
35
|
+
*/
|
|
36
|
+
secondaryAction?: ReactElement;
|
|
37
|
+
className?: string;
|
|
38
|
+
testID?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare const OnboardEmptyState: React.FC<OnboardEmptyStateProps>;
|
|
42
|
+
|
|
43
|
+
export { OnboardEmptyState, type OnboardEmptyStateItem, type OnboardEmptyStateProps };
|
package/web/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { ThemeOverrideProps } from '@xsolla/xui-core';
|
|
3
|
+
|
|
4
|
+
interface OnboardEmptyStateItem {
|
|
5
|
+
/**
|
|
6
|
+
* Stable key for the item. Falls back to the array index when omitted.
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Graphic slot rendered to the left of the text, aligned to its top edge.
|
|
11
|
+
* Accepts any node — a 2D illustration, an `IconWrapper`, or a plain `<img>`.
|
|
12
|
+
* Omit it to render a text-only item.
|
|
13
|
+
*/
|
|
14
|
+
asset?: ReactNode;
|
|
15
|
+
/** Item heading, rendered in `bodyMdAccent`. */
|
|
16
|
+
headline: string;
|
|
17
|
+
/** Supporting copy below the heading, rendered in `bodyMdParagraph`. */
|
|
18
|
+
description?: string;
|
|
19
|
+
}
|
|
20
|
+
interface OnboardEmptyStateProps extends ThemeOverrideProps {
|
|
21
|
+
/**
|
|
22
|
+
* Onboarding items, stacked vertically. Any number is supported — the
|
|
23
|
+
* component does not assume the three shown in the primary Storybook story.
|
|
24
|
+
*/
|
|
25
|
+
items?: OnboardEmptyStateItem[];
|
|
26
|
+
/**
|
|
27
|
+
* Primary action button. Cloned with `fullWidth` set to `true` and stacked
|
|
28
|
+
* above `secondaryAction`.
|
|
29
|
+
*/
|
|
30
|
+
primaryAction?: ReactElement;
|
|
31
|
+
/**
|
|
32
|
+
* Secondary action button. Cloned with `fullWidth` set to `true` and stacked
|
|
33
|
+
* below `primaryAction`. Both actions are optional — the component renders
|
|
34
|
+
* with two buttons, one button, or none.
|
|
35
|
+
*/
|
|
36
|
+
secondaryAction?: ReactElement;
|
|
37
|
+
className?: string;
|
|
38
|
+
testID?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare const OnboardEmptyState: React.FC<OnboardEmptyStateProps>;
|
|
42
|
+
|
|
43
|
+
export { OnboardEmptyState, type OnboardEmptyStateItem, type OnboardEmptyStateProps };
|