@xsolla/xui-game-card 0.104.0 → 0.105.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 +4 -1
- package/native/index.d.ts +4 -1
- package/native/index.js +85 -23
- package/native/index.js.flow +7 -1
- package/native/index.js.map +1 -1
- package/native/index.mjs +85 -23
- package/native/index.mjs.map +1 -1
- package/package.json +3 -3
- package/web/index.d.mts +4 -1
- package/web/index.d.ts +4 -1
- package/web/index.js +85 -23
- package/web/index.js.flow +7 -1
- package/web/index.js.map +1 -1
- package/web/index.mjs +85 -23
- package/web/index.mjs.map +1 -1
package/native/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
type GameCardSize = "lg" | "md" | "sm";
|
|
4
|
+
type LootBadgeTier = "best" | "better" | "good";
|
|
4
5
|
interface GameCardProps {
|
|
5
6
|
/** Game artwork image URL */
|
|
6
7
|
image: string;
|
|
@@ -10,6 +11,8 @@ interface GameCardProps {
|
|
|
10
11
|
subtitle?: string;
|
|
11
12
|
/** Size variant of the card */
|
|
12
13
|
size?: GameCardSize;
|
|
14
|
+
/** Loot tier badge displayed above tags on the image */
|
|
15
|
+
lootBadge?: LootBadgeTier;
|
|
13
16
|
/** Custom content for top-left corner tags */
|
|
14
17
|
tagsTopLeft?: React.ReactNode;
|
|
15
18
|
/** Custom content for top-right corner tags */
|
|
@@ -30,4 +33,4 @@ interface GameCardProps {
|
|
|
30
33
|
|
|
31
34
|
declare const GameCard: React.FC<GameCardProps>;
|
|
32
35
|
|
|
33
|
-
export { GameCard, type GameCardProps, type GameCardSize };
|
|
36
|
+
export { GameCard, type GameCardProps, type GameCardSize, type LootBadgeTier };
|
package/native/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
type GameCardSize = "lg" | "md" | "sm";
|
|
4
|
+
type LootBadgeTier = "best" | "better" | "good";
|
|
4
5
|
interface GameCardProps {
|
|
5
6
|
/** Game artwork image URL */
|
|
6
7
|
image: string;
|
|
@@ -10,6 +11,8 @@ interface GameCardProps {
|
|
|
10
11
|
subtitle?: string;
|
|
11
12
|
/** Size variant of the card */
|
|
12
13
|
size?: GameCardSize;
|
|
14
|
+
/** Loot tier badge displayed above tags on the image */
|
|
15
|
+
lootBadge?: LootBadgeTier;
|
|
13
16
|
/** Custom content for top-left corner tags */
|
|
14
17
|
tagsTopLeft?: React.ReactNode;
|
|
15
18
|
/** Custom content for top-right corner tags */
|
|
@@ -30,4 +33,4 @@ interface GameCardProps {
|
|
|
30
33
|
|
|
31
34
|
declare const GameCard: React.FC<GameCardProps>;
|
|
32
35
|
|
|
33
|
-
export { GameCard, type GameCardProps, type GameCardSize };
|
|
36
|
+
export { GameCard, type GameCardProps, type GameCardSize, type LootBadgeTier };
|
package/native/index.js
CHANGED
|
@@ -233,10 +233,10 @@ var getSizeConfig = (size) => {
|
|
|
233
233
|
case "lg":
|
|
234
234
|
return {
|
|
235
235
|
imageAspectRatio: 366 / 206,
|
|
236
|
-
titleFontSize:
|
|
237
|
-
titleLineHeight:
|
|
238
|
-
subtitleFontSize:
|
|
239
|
-
subtitleLineHeight:
|
|
236
|
+
titleFontSize: 16,
|
|
237
|
+
titleLineHeight: 20,
|
|
238
|
+
subtitleFontSize: 12,
|
|
239
|
+
subtitleLineHeight: 18,
|
|
240
240
|
padding: 8,
|
|
241
241
|
tagGap: 4,
|
|
242
242
|
buttonHeight: 32,
|
|
@@ -244,15 +244,19 @@ var getSizeConfig = (size) => {
|
|
|
244
244
|
buttonFontSize: 12,
|
|
245
245
|
buttonLineHeight: 14,
|
|
246
246
|
borderRadius: 4,
|
|
247
|
-
fadeHeight: 64
|
|
247
|
+
fadeHeight: 64,
|
|
248
|
+
lootBadgeFontSize: 12,
|
|
249
|
+
lootBadgeLineHeight: 16,
|
|
250
|
+
lootBadgePaddingX: 6,
|
|
251
|
+
lootBadgePaddingY: 4
|
|
248
252
|
};
|
|
249
253
|
case "md":
|
|
250
254
|
return {
|
|
251
255
|
imageAspectRatio: 280 / 158,
|
|
252
|
-
titleFontSize:
|
|
253
|
-
titleLineHeight:
|
|
254
|
-
subtitleFontSize:
|
|
255
|
-
subtitleLineHeight:
|
|
256
|
+
titleFontSize: 14,
|
|
257
|
+
titleLineHeight: 18,
|
|
258
|
+
subtitleFontSize: 11,
|
|
259
|
+
subtitleLineHeight: 16,
|
|
256
260
|
padding: 6,
|
|
257
261
|
tagGap: 3,
|
|
258
262
|
buttonHeight: 28,
|
|
@@ -260,15 +264,19 @@ var getSizeConfig = (size) => {
|
|
|
260
264
|
buttonFontSize: 11,
|
|
261
265
|
buttonLineHeight: 13,
|
|
262
266
|
borderRadius: 4,
|
|
263
|
-
fadeHeight: 48
|
|
267
|
+
fadeHeight: 48,
|
|
268
|
+
lootBadgeFontSize: 11,
|
|
269
|
+
lootBadgeLineHeight: 14,
|
|
270
|
+
lootBadgePaddingX: 5,
|
|
271
|
+
lootBadgePaddingY: 3
|
|
264
272
|
};
|
|
265
273
|
case "sm":
|
|
266
274
|
return {
|
|
267
275
|
imageAspectRatio: 200 / 113,
|
|
268
276
|
titleFontSize: 12,
|
|
269
|
-
titleLineHeight:
|
|
270
|
-
subtitleFontSize:
|
|
271
|
-
subtitleLineHeight:
|
|
277
|
+
titleLineHeight: 16,
|
|
278
|
+
subtitleFontSize: 10,
|
|
279
|
+
subtitleLineHeight: 14,
|
|
272
280
|
padding: 4,
|
|
273
281
|
tagGap: 2,
|
|
274
282
|
buttonHeight: 24,
|
|
@@ -276,15 +284,39 @@ var getSizeConfig = (size) => {
|
|
|
276
284
|
buttonFontSize: 10,
|
|
277
285
|
buttonLineHeight: 12,
|
|
278
286
|
borderRadius: 4,
|
|
279
|
-
fadeHeight: 32
|
|
287
|
+
fadeHeight: 32,
|
|
288
|
+
lootBadgeFontSize: 10,
|
|
289
|
+
lootBadgeLineHeight: 12,
|
|
290
|
+
lootBadgePaddingX: 4,
|
|
291
|
+
lootBadgePaddingY: 2
|
|
280
292
|
};
|
|
281
293
|
}
|
|
282
294
|
};
|
|
295
|
+
var LOOT_BADGE_LABELS = {
|
|
296
|
+
best: "Best Loot",
|
|
297
|
+
better: "Better Loot",
|
|
298
|
+
good: "Good Loot"
|
|
299
|
+
};
|
|
300
|
+
var LOOT_BADGE_WEB_BACKGROUNDS = {
|
|
301
|
+
best: { backgroundColor: "#cef655" },
|
|
302
|
+
better: {
|
|
303
|
+
backgroundImage: "linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)"
|
|
304
|
+
},
|
|
305
|
+
good: {
|
|
306
|
+
backgroundImage: "linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)"
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
var LOOT_BADGE_NATIVE_COLORS = {
|
|
310
|
+
best: "#cef655",
|
|
311
|
+
better: "#dff98f",
|
|
312
|
+
good: "#f0fccc"
|
|
313
|
+
};
|
|
283
314
|
var GameCard = ({
|
|
284
315
|
image,
|
|
285
316
|
title,
|
|
286
317
|
subtitle,
|
|
287
318
|
size = "lg",
|
|
319
|
+
lootBadge,
|
|
288
320
|
tagsTopLeft,
|
|
289
321
|
tagsTopRight,
|
|
290
322
|
trailing,
|
|
@@ -316,7 +348,6 @@ var GameCard = ({
|
|
|
316
348
|
borderRadius: `${config.borderRadius}px`,
|
|
317
349
|
overflow: "hidden"
|
|
318
350
|
} : {
|
|
319
|
-
// React Native shadow properties
|
|
320
351
|
shadowColor: "#070708",
|
|
321
352
|
shadowOffset: { width: 0, height: 2 },
|
|
322
353
|
shadowOpacity: 0.15,
|
|
@@ -363,12 +394,11 @@ var GameCard = ({
|
|
|
363
394
|
style: import_xui_core.isWeb ? {
|
|
364
395
|
background: "linear-gradient(to top, rgba(0, 0, 0, 0.48) 0%, transparent 100%)"
|
|
365
396
|
} : {
|
|
366
|
-
// Fallback for React Native - solid semi-transparent overlay
|
|
367
397
|
backgroundColor: "rgba(0, 0, 0, 0.24)"
|
|
368
398
|
}
|
|
369
399
|
}
|
|
370
400
|
),
|
|
371
|
-
tagsTopLeft && /* @__PURE__ */ (0, import_jsx_runtime3.
|
|
401
|
+
(lootBadge || tagsTopLeft) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
372
402
|
Box,
|
|
373
403
|
{
|
|
374
404
|
position: "absolute",
|
|
@@ -377,7 +407,37 @@ var GameCard = ({
|
|
|
377
407
|
flexDirection: "column",
|
|
378
408
|
gap: config.tagGap,
|
|
379
409
|
alignItems: "flex-start",
|
|
380
|
-
children:
|
|
410
|
+
children: [
|
|
411
|
+
lootBadge && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
412
|
+
Box,
|
|
413
|
+
{
|
|
414
|
+
borderRadius: config.borderRadius,
|
|
415
|
+
paddingHorizontal: config.lootBadgePaddingX,
|
|
416
|
+
paddingVertical: config.lootBadgePaddingY,
|
|
417
|
+
style: import_xui_core.isWeb ? {
|
|
418
|
+
...LOOT_BADGE_WEB_BACKGROUNDS[lootBadge],
|
|
419
|
+
border: "1px solid rgba(0, 0, 0, 0.15)",
|
|
420
|
+
borderRadius: `${config.borderRadius}px`
|
|
421
|
+
} : {
|
|
422
|
+
backgroundColor: LOOT_BADGE_NATIVE_COLORS[lootBadge],
|
|
423
|
+
borderWidth: 1,
|
|
424
|
+
borderColor: "rgba(0, 0, 0, 0.15)",
|
|
425
|
+
borderRadius: config.borderRadius
|
|
426
|
+
},
|
|
427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
428
|
+
Text,
|
|
429
|
+
{
|
|
430
|
+
color: theme.colors.content.on.brandExtra,
|
|
431
|
+
fontSize: config.lootBadgeFontSize,
|
|
432
|
+
lineHeight: config.lootBadgeLineHeight,
|
|
433
|
+
fontWeight: "500",
|
|
434
|
+
children: LOOT_BADGE_LABELS[lootBadge]
|
|
435
|
+
}
|
|
436
|
+
)
|
|
437
|
+
}
|
|
438
|
+
),
|
|
439
|
+
tagsTopLeft
|
|
440
|
+
]
|
|
381
441
|
}
|
|
382
442
|
),
|
|
383
443
|
tagsTopRight && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -411,7 +471,7 @@ var GameCard = ({
|
|
|
411
471
|
color: theme.colors.content.primary,
|
|
412
472
|
fontSize: config.titleFontSize,
|
|
413
473
|
lineHeight: config.titleLineHeight,
|
|
414
|
-
fontWeight: "
|
|
474
|
+
fontWeight: "500",
|
|
415
475
|
numberOfLines: 1,
|
|
416
476
|
style: import_xui_core.isWeb ? {
|
|
417
477
|
overflow: "hidden",
|
|
@@ -443,20 +503,22 @@ var GameCard = ({
|
|
|
443
503
|
Box,
|
|
444
504
|
{
|
|
445
505
|
onPress: onButtonClick,
|
|
446
|
-
backgroundColor:
|
|
447
|
-
borderRadius:
|
|
506
|
+
backgroundColor: theme.colors.control.mono.secondary.bg,
|
|
507
|
+
borderRadius: config.borderRadius,
|
|
448
508
|
height: config.buttonHeight,
|
|
449
509
|
paddingHorizontal: config.buttonPaddingX,
|
|
450
510
|
alignItems: "center",
|
|
451
511
|
justifyContent: "center",
|
|
452
512
|
style: import_xui_core.isWeb ? {
|
|
453
|
-
backdropFilter: "blur(
|
|
513
|
+
backdropFilter: "blur(30px)",
|
|
514
|
+
WebkitBackdropFilter: "blur(30px)",
|
|
515
|
+
border: `1px solid ${theme.colors.control.mono.secondary.border}`,
|
|
454
516
|
cursor: onButtonClick ? "pointer" : "default"
|
|
455
517
|
} : void 0,
|
|
456
518
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
457
519
|
Text,
|
|
458
520
|
{
|
|
459
|
-
color: theme.colors.
|
|
521
|
+
color: theme.colors.control.mono.text.secondary,
|
|
460
522
|
fontSize: config.buttonFontSize,
|
|
461
523
|
lineHeight: config.buttonLineHeight,
|
|
462
524
|
fontWeight: "500",
|
package/native/index.js.flow
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
declare type GameCardSize = "lg" | "md" | "sm";
|
|
10
|
+
declare type LootBadgeTier = "best" | "better" | "good";
|
|
10
11
|
declare interface GameCardProps {
|
|
11
12
|
/**
|
|
12
13
|
* Game artwork image URL
|
|
@@ -28,6 +29,11 @@ declare interface GameCardProps {
|
|
|
28
29
|
*/
|
|
29
30
|
size?: GameCardSize;
|
|
30
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Loot tier badge displayed above tags on the image
|
|
34
|
+
*/
|
|
35
|
+
lootBadge?: LootBadgeTier;
|
|
36
|
+
|
|
31
37
|
/**
|
|
32
38
|
* Custom content for top-left corner tags
|
|
33
39
|
*/
|
|
@@ -69,5 +75,5 @@ declare interface GameCardProps {
|
|
|
69
75
|
className?: string;
|
|
70
76
|
}
|
|
71
77
|
declare var GameCard: React.FC<GameCardProps>;
|
|
72
|
-
export type { GameCardProps, GameCardSize };
|
|
78
|
+
export type { GameCardProps, GameCardSize, LootBadgeTier };
|
|
73
79
|
declare export { GameCard };
|
package/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../src/GameCard.tsx"],"sourcesContent":["export * from \"./GameCard\";\nexport * from \"./types\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\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 alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\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 zIndex,\n height: height as DimensionValue,\n width: width 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 alignItems,\n justifyContent,\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 ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\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 className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\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 resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\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 {...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 {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport { Text as RNText, TextStyle, AccessibilityRole } from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web roles to React Native accessibility roles\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n id,\n role,\n ...props\n}) => {\n // Extract the first font name from a comma-separated list (e.g. for web-style font stacks)\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n // On native, if we don't have the custom font loaded, fall back to the system font\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const style: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n };\n\n // Map role to React Native accessibilityRole\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText style={style} testID={id} accessibilityRole={accessibilityRole}>\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport type { GameCardProps, GameCardSize } from \"./types\";\n\nconst getSizeConfig = (size: GameCardSize) => {\n switch (size) {\n case \"lg\":\n return {\n imageAspectRatio: 366 / 206,\n titleFontSize: 14,\n titleLineHeight: 18,\n subtitleFontSize: 11,\n subtitleLineHeight: 14,\n padding: 8,\n tagGap: 4,\n buttonHeight: 32,\n buttonPaddingX: 20,\n buttonFontSize: 12,\n buttonLineHeight: 14,\n borderRadius: 4,\n fadeHeight: 64,\n };\n case \"md\":\n return {\n imageAspectRatio: 280 / 158,\n titleFontSize: 13,\n titleLineHeight: 16,\n subtitleFontSize: 10,\n subtitleLineHeight: 12,\n padding: 6,\n tagGap: 3,\n buttonHeight: 28,\n buttonPaddingX: 16,\n buttonFontSize: 11,\n buttonLineHeight: 13,\n borderRadius: 4,\n fadeHeight: 48,\n };\n case \"sm\":\n return {\n imageAspectRatio: 200 / 113,\n titleFontSize: 12,\n titleLineHeight: 14,\n subtitleFontSize: 9,\n subtitleLineHeight: 11,\n padding: 4,\n tagGap: 2,\n buttonHeight: 24,\n buttonPaddingX: 12,\n buttonFontSize: 10,\n buttonLineHeight: 12,\n borderRadius: 4,\n fadeHeight: 32,\n };\n }\n};\n\nexport const GameCard: React.FC<GameCardProps> = ({\n image,\n title,\n subtitle,\n size = \"lg\",\n tagsTopLeft,\n tagsTopRight,\n trailing,\n buttonText,\n onButtonClick,\n onPress,\n imageAlt,\n className,\n}) => {\n const { theme } = useDesignSystem();\n const config = getSizeConfig(size);\n\n const wrapperProps = onPress ? { onPress } : {};\n\n return (\n <Box\n className={className}\n flexDirection=\"column\"\n width=\"100%\"\n {...wrapperProps}\n >\n <Box\n backgroundColor={theme.colors.background.primary}\n borderRadius={config.borderRadius}\n overflow=\"hidden\"\n flexDirection=\"column\"\n style={\n isWeb\n ? {\n boxShadow: theme.shadow.surface,\n borderRadius: `${config.borderRadius}px`,\n overflow: \"hidden\",\n }\n : {\n // React Native shadow properties\n shadowColor: \"#070708\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.15,\n shadowRadius: 6,\n elevation: 4,\n borderRadius: config.borderRadius,\n overflow: \"hidden\",\n }\n }\n >\n {/* Image Container */}\n <Box\n position=\"relative\"\n width=\"100%\"\n overflow=\"hidden\"\n style={{\n aspectRatio: config.imageAspectRatio,\n borderTopLeftRadius: config.borderRadius,\n borderTopRightRadius: config.borderRadius,\n }}\n >\n {/* Game Image */}\n <Box\n as=\"img\"\n src={image}\n alt={imageAlt || title}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n />\n\n {/* Bottom Gradient Fade */}\n <Box\n position=\"absolute\"\n bottom={0}\n left={0}\n right={0}\n height={config.fadeHeight}\n style={\n isWeb\n ? {\n background:\n \"linear-gradient(to top, rgba(0, 0, 0, 0.48) 0%, transparent 100%)\",\n }\n : {\n // Fallback for React Native - solid semi-transparent overlay\n backgroundColor: \"rgba(0, 0, 0, 0.24)\",\n }\n }\n />\n\n {/* Top Left Tags */}\n {tagsTopLeft && (\n <Box\n position=\"absolute\"\n top={config.padding}\n left={config.padding}\n flexDirection=\"column\"\n gap={config.tagGap}\n alignItems=\"flex-start\"\n >\n {tagsTopLeft}\n </Box>\n )}\n\n {/* Top Right Tags */}\n {tagsTopRight && (\n <Box\n position=\"absolute\"\n top={config.padding}\n right={config.padding}\n flexDirection=\"column\"\n gap={config.tagGap}\n alignItems=\"flex-end\"\n >\n {tagsTopRight}\n </Box>\n )}\n </Box>\n\n {/* Card Footer */}\n <Box\n backgroundColor={theme.colors.background.primary}\n padding={config.padding}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={8}\n >\n {/* Title and Subtitle */}\n <Box flex={1} flexDirection=\"column\" style={{ minWidth: 0 }}>\n <Text\n color={theme.colors.content.primary}\n fontSize={config.titleFontSize}\n lineHeight={config.titleLineHeight}\n fontWeight=\"600\"\n numberOfLines={1}\n style={\n isWeb\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : undefined\n }\n >\n {title}\n </Text>\n {subtitle && (\n <Text\n color={theme.colors.content.tertiary}\n fontSize={config.subtitleFontSize}\n lineHeight={config.subtitleLineHeight}\n fontWeight=\"400\"\n numberOfLines={1}\n style={\n isWeb\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : undefined\n }\n >\n {subtitle}\n </Text>\n )}\n </Box>\n\n {/* Trailing Content (custom or default button) */}\n {trailing}\n {!trailing && buttonText && (\n <Box\n onPress={onButtonClick}\n backgroundColor=\"rgba(0, 0, 0, 0.12)\"\n borderRadius={2}\n height={config.buttonHeight}\n paddingHorizontal={config.buttonPaddingX}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={\n isWeb\n ? {\n backdropFilter: \"blur(6px)\",\n cursor: onButtonClick ? \"pointer\" : \"default\",\n }\n : undefined\n }\n >\n <Text\n color={theme.colors.content.primary}\n fontSize={config.buttonFontSize}\n lineHeight={config.buttonLineHeight}\n fontWeight=\"500\"\n letterSpacing={0.4}\n >\n {buttonText}\n </Text>\n </Box>\n )}\n </Box>\n </Box>\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../src/GameCard.tsx"],"sourcesContent":["export * from \"./GameCard\";\nexport * from \"./types\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\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 alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\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 zIndex,\n height: height as DimensionValue,\n width: width 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 alignItems,\n justifyContent,\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 ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\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 className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\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 resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\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 {...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 {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport { Text as RNText, TextStyle, AccessibilityRole } from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web roles to React Native accessibility roles\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n id,\n role,\n ...props\n}) => {\n // Extract the first font name from a comma-separated list (e.g. for web-style font stacks)\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n // On native, if we don't have the custom font loaded, fall back to the system font\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const style: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n };\n\n // Map role to React Native accessibilityRole\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText style={style} testID={id} accessibilityRole={accessibilityRole}>\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport type { GameCardProps, GameCardSize, LootBadgeTier } from \"./types\";\n\nconst getSizeConfig = (size: GameCardSize) => {\n switch (size) {\n case \"lg\":\n return {\n imageAspectRatio: 366 / 206,\n titleFontSize: 16,\n titleLineHeight: 20,\n subtitleFontSize: 12,\n subtitleLineHeight: 18,\n padding: 8,\n tagGap: 4,\n buttonHeight: 32,\n buttonPaddingX: 20,\n buttonFontSize: 12,\n buttonLineHeight: 14,\n borderRadius: 4,\n fadeHeight: 64,\n lootBadgeFontSize: 12,\n lootBadgeLineHeight: 16,\n lootBadgePaddingX: 6,\n lootBadgePaddingY: 4,\n };\n case \"md\":\n return {\n imageAspectRatio: 280 / 158,\n titleFontSize: 14,\n titleLineHeight: 18,\n subtitleFontSize: 11,\n subtitleLineHeight: 16,\n padding: 6,\n tagGap: 3,\n buttonHeight: 28,\n buttonPaddingX: 16,\n buttonFontSize: 11,\n buttonLineHeight: 13,\n borderRadius: 4,\n fadeHeight: 48,\n lootBadgeFontSize: 11,\n lootBadgeLineHeight: 14,\n lootBadgePaddingX: 5,\n lootBadgePaddingY: 3,\n };\n case \"sm\":\n return {\n imageAspectRatio: 200 / 113,\n titleFontSize: 12,\n titleLineHeight: 16,\n subtitleFontSize: 10,\n subtitleLineHeight: 14,\n padding: 4,\n tagGap: 2,\n buttonHeight: 24,\n buttonPaddingX: 12,\n buttonFontSize: 10,\n buttonLineHeight: 12,\n borderRadius: 4,\n fadeHeight: 32,\n lootBadgeFontSize: 10,\n lootBadgeLineHeight: 12,\n lootBadgePaddingX: 4,\n lootBadgePaddingY: 2,\n };\n }\n};\n\nconst LOOT_BADGE_LABELS: Record<LootBadgeTier, string> = {\n best: \"Best Loot\",\n better: \"Better Loot\",\n good: \"Good Loot\",\n};\n\nconst LOOT_BADGE_WEB_BACKGROUNDS: Record<LootBadgeTier, React.CSSProperties> =\n {\n best: { backgroundColor: \"#cef655\" },\n better: {\n backgroundImage:\n \"linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), \" +\n \"linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), \" +\n \"linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), \" +\n \"linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)\",\n },\n good: {\n backgroundImage:\n \"linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), \" +\n \"linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)\",\n },\n };\n\nconst LOOT_BADGE_NATIVE_COLORS: Record<LootBadgeTier, string> = {\n best: \"#cef655\",\n better: \"#dff98f\",\n good: \"#f0fccc\",\n};\n\nexport const GameCard: React.FC<GameCardProps> = ({\n image,\n title,\n subtitle,\n size = \"lg\",\n lootBadge,\n tagsTopLeft,\n tagsTopRight,\n trailing,\n buttonText,\n onButtonClick,\n onPress,\n imageAlt,\n className,\n}) => {\n const { theme } = useDesignSystem();\n const config = getSizeConfig(size);\n\n const wrapperProps = onPress ? { onPress } : {};\n\n return (\n <Box\n className={className}\n flexDirection=\"column\"\n width=\"100%\"\n {...wrapperProps}\n >\n <Box\n backgroundColor={theme.colors.background.primary}\n borderRadius={config.borderRadius}\n overflow=\"hidden\"\n flexDirection=\"column\"\n style={\n isWeb\n ? {\n boxShadow: theme.shadow.surface,\n borderRadius: `${config.borderRadius}px`,\n overflow: \"hidden\",\n }\n : {\n shadowColor: \"#070708\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.15,\n shadowRadius: 6,\n elevation: 4,\n borderRadius: config.borderRadius,\n overflow: \"hidden\",\n }\n }\n >\n {/* Image Container */}\n <Box\n position=\"relative\"\n width=\"100%\"\n overflow=\"hidden\"\n style={{\n aspectRatio: config.imageAspectRatio,\n borderTopLeftRadius: config.borderRadius,\n borderTopRightRadius: config.borderRadius,\n }}\n >\n <Box\n as=\"img\"\n src={image}\n alt={imageAlt || title}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n />\n\n <Box\n position=\"absolute\"\n bottom={0}\n left={0}\n right={0}\n height={config.fadeHeight}\n style={\n isWeb\n ? {\n background:\n \"linear-gradient(to top, rgba(0, 0, 0, 0.48) 0%, transparent 100%)\",\n }\n : {\n backgroundColor: \"rgba(0, 0, 0, 0.24)\",\n }\n }\n />\n\n {(lootBadge || tagsTopLeft) && (\n <Box\n position=\"absolute\"\n top={config.padding}\n left={config.padding}\n flexDirection=\"column\"\n gap={config.tagGap}\n alignItems=\"flex-start\"\n >\n {lootBadge && (\n <Box\n borderRadius={config.borderRadius}\n paddingHorizontal={config.lootBadgePaddingX}\n paddingVertical={config.lootBadgePaddingY}\n style={\n isWeb\n ? {\n ...LOOT_BADGE_WEB_BACKGROUNDS[lootBadge],\n border: \"1px solid rgba(0, 0, 0, 0.15)\",\n borderRadius: `${config.borderRadius}px`,\n }\n : {\n backgroundColor:\n LOOT_BADGE_NATIVE_COLORS[lootBadge],\n borderWidth: 1,\n borderColor: \"rgba(0, 0, 0, 0.15)\",\n borderRadius: config.borderRadius,\n }\n }\n >\n <Text\n color={theme.colors.content.on.brandExtra}\n fontSize={config.lootBadgeFontSize}\n lineHeight={config.lootBadgeLineHeight}\n fontWeight=\"500\"\n >\n {LOOT_BADGE_LABELS[lootBadge]}\n </Text>\n </Box>\n )}\n {tagsTopLeft}\n </Box>\n )}\n\n {tagsTopRight && (\n <Box\n position=\"absolute\"\n top={config.padding}\n right={config.padding}\n flexDirection=\"column\"\n gap={config.tagGap}\n alignItems=\"flex-end\"\n >\n {tagsTopRight}\n </Box>\n )}\n </Box>\n\n {/* Card Footer */}\n <Box\n backgroundColor={theme.colors.background.primary}\n padding={config.padding}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={8}\n >\n <Box flex={1} flexDirection=\"column\" style={{ minWidth: 0 }}>\n <Text\n color={theme.colors.content.primary}\n fontSize={config.titleFontSize}\n lineHeight={config.titleLineHeight}\n fontWeight=\"500\"\n numberOfLines={1}\n style={\n isWeb\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : undefined\n }\n >\n {title}\n </Text>\n {subtitle && (\n <Text\n color={theme.colors.content.tertiary}\n fontSize={config.subtitleFontSize}\n lineHeight={config.subtitleLineHeight}\n fontWeight=\"400\"\n numberOfLines={1}\n style={\n isWeb\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : undefined\n }\n >\n {subtitle}\n </Text>\n )}\n </Box>\n\n {trailing}\n {!trailing && buttonText && (\n <Box\n onPress={onButtonClick}\n backgroundColor={theme.colors.control.mono.secondary.bg}\n borderRadius={config.borderRadius}\n height={config.buttonHeight}\n paddingHorizontal={config.buttonPaddingX}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={\n isWeb\n ? {\n backdropFilter: \"blur(30px)\",\n WebkitBackdropFilter: \"blur(30px)\",\n border: `1px solid ${theme.colors.control.mono.secondary.border}`,\n cursor: onButtonClick ? \"pointer\" : \"default\",\n }\n : undefined\n }\n >\n <Text\n color={theme.colors.control.mono.text.secondary}\n fontSize={config.buttonFontSize}\n lineHeight={config.buttonLineHeight}\n fontWeight=\"500\"\n letterSpacing={0.4}\n >\n {buttonText}\n </Text>\n </Box>\n )}\n </Box>\n </Box>\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime"]}
|
package/native/index.mjs
CHANGED
|
@@ -211,10 +211,10 @@ var getSizeConfig = (size) => {
|
|
|
211
211
|
case "lg":
|
|
212
212
|
return {
|
|
213
213
|
imageAspectRatio: 366 / 206,
|
|
214
|
-
titleFontSize:
|
|
215
|
-
titleLineHeight:
|
|
216
|
-
subtitleFontSize:
|
|
217
|
-
subtitleLineHeight:
|
|
214
|
+
titleFontSize: 16,
|
|
215
|
+
titleLineHeight: 20,
|
|
216
|
+
subtitleFontSize: 12,
|
|
217
|
+
subtitleLineHeight: 18,
|
|
218
218
|
padding: 8,
|
|
219
219
|
tagGap: 4,
|
|
220
220
|
buttonHeight: 32,
|
|
@@ -222,15 +222,19 @@ var getSizeConfig = (size) => {
|
|
|
222
222
|
buttonFontSize: 12,
|
|
223
223
|
buttonLineHeight: 14,
|
|
224
224
|
borderRadius: 4,
|
|
225
|
-
fadeHeight: 64
|
|
225
|
+
fadeHeight: 64,
|
|
226
|
+
lootBadgeFontSize: 12,
|
|
227
|
+
lootBadgeLineHeight: 16,
|
|
228
|
+
lootBadgePaddingX: 6,
|
|
229
|
+
lootBadgePaddingY: 4
|
|
226
230
|
};
|
|
227
231
|
case "md":
|
|
228
232
|
return {
|
|
229
233
|
imageAspectRatio: 280 / 158,
|
|
230
|
-
titleFontSize:
|
|
231
|
-
titleLineHeight:
|
|
232
|
-
subtitleFontSize:
|
|
233
|
-
subtitleLineHeight:
|
|
234
|
+
titleFontSize: 14,
|
|
235
|
+
titleLineHeight: 18,
|
|
236
|
+
subtitleFontSize: 11,
|
|
237
|
+
subtitleLineHeight: 16,
|
|
234
238
|
padding: 6,
|
|
235
239
|
tagGap: 3,
|
|
236
240
|
buttonHeight: 28,
|
|
@@ -238,15 +242,19 @@ var getSizeConfig = (size) => {
|
|
|
238
242
|
buttonFontSize: 11,
|
|
239
243
|
buttonLineHeight: 13,
|
|
240
244
|
borderRadius: 4,
|
|
241
|
-
fadeHeight: 48
|
|
245
|
+
fadeHeight: 48,
|
|
246
|
+
lootBadgeFontSize: 11,
|
|
247
|
+
lootBadgeLineHeight: 14,
|
|
248
|
+
lootBadgePaddingX: 5,
|
|
249
|
+
lootBadgePaddingY: 3
|
|
242
250
|
};
|
|
243
251
|
case "sm":
|
|
244
252
|
return {
|
|
245
253
|
imageAspectRatio: 200 / 113,
|
|
246
254
|
titleFontSize: 12,
|
|
247
|
-
titleLineHeight:
|
|
248
|
-
subtitleFontSize:
|
|
249
|
-
subtitleLineHeight:
|
|
255
|
+
titleLineHeight: 16,
|
|
256
|
+
subtitleFontSize: 10,
|
|
257
|
+
subtitleLineHeight: 14,
|
|
250
258
|
padding: 4,
|
|
251
259
|
tagGap: 2,
|
|
252
260
|
buttonHeight: 24,
|
|
@@ -254,15 +262,39 @@ var getSizeConfig = (size) => {
|
|
|
254
262
|
buttonFontSize: 10,
|
|
255
263
|
buttonLineHeight: 12,
|
|
256
264
|
borderRadius: 4,
|
|
257
|
-
fadeHeight: 32
|
|
265
|
+
fadeHeight: 32,
|
|
266
|
+
lootBadgeFontSize: 10,
|
|
267
|
+
lootBadgeLineHeight: 12,
|
|
268
|
+
lootBadgePaddingX: 4,
|
|
269
|
+
lootBadgePaddingY: 2
|
|
258
270
|
};
|
|
259
271
|
}
|
|
260
272
|
};
|
|
273
|
+
var LOOT_BADGE_LABELS = {
|
|
274
|
+
best: "Best Loot",
|
|
275
|
+
better: "Better Loot",
|
|
276
|
+
good: "Good Loot"
|
|
277
|
+
};
|
|
278
|
+
var LOOT_BADGE_WEB_BACKGROUNDS = {
|
|
279
|
+
best: { backgroundColor: "#cef655" },
|
|
280
|
+
better: {
|
|
281
|
+
backgroundImage: "linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)"
|
|
282
|
+
},
|
|
283
|
+
good: {
|
|
284
|
+
backgroundImage: "linear-gradient(90deg, rgba(206,246,85,0.3) 0%, rgba(206,246,85,0.3) 100%), linear-gradient(90deg, rgb(255,255,255) 0%, rgb(255,255,255) 100%)"
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
var LOOT_BADGE_NATIVE_COLORS = {
|
|
288
|
+
best: "#cef655",
|
|
289
|
+
better: "#dff98f",
|
|
290
|
+
good: "#f0fccc"
|
|
291
|
+
};
|
|
261
292
|
var GameCard = ({
|
|
262
293
|
image,
|
|
263
294
|
title,
|
|
264
295
|
subtitle,
|
|
265
296
|
size = "lg",
|
|
297
|
+
lootBadge,
|
|
266
298
|
tagsTopLeft,
|
|
267
299
|
tagsTopRight,
|
|
268
300
|
trailing,
|
|
@@ -294,7 +326,6 @@ var GameCard = ({
|
|
|
294
326
|
borderRadius: `${config.borderRadius}px`,
|
|
295
327
|
overflow: "hidden"
|
|
296
328
|
} : {
|
|
297
|
-
// React Native shadow properties
|
|
298
329
|
shadowColor: "#070708",
|
|
299
330
|
shadowOffset: { width: 0, height: 2 },
|
|
300
331
|
shadowOpacity: 0.15,
|
|
@@ -341,12 +372,11 @@ var GameCard = ({
|
|
|
341
372
|
style: isWeb ? {
|
|
342
373
|
background: "linear-gradient(to top, rgba(0, 0, 0, 0.48) 0%, transparent 100%)"
|
|
343
374
|
} : {
|
|
344
|
-
// Fallback for React Native - solid semi-transparent overlay
|
|
345
375
|
backgroundColor: "rgba(0, 0, 0, 0.24)"
|
|
346
376
|
}
|
|
347
377
|
}
|
|
348
378
|
),
|
|
349
|
-
tagsTopLeft && /* @__PURE__ */
|
|
379
|
+
(lootBadge || tagsTopLeft) && /* @__PURE__ */ jsxs(
|
|
350
380
|
Box,
|
|
351
381
|
{
|
|
352
382
|
position: "absolute",
|
|
@@ -355,7 +385,37 @@ var GameCard = ({
|
|
|
355
385
|
flexDirection: "column",
|
|
356
386
|
gap: config.tagGap,
|
|
357
387
|
alignItems: "flex-start",
|
|
358
|
-
children:
|
|
388
|
+
children: [
|
|
389
|
+
lootBadge && /* @__PURE__ */ jsx3(
|
|
390
|
+
Box,
|
|
391
|
+
{
|
|
392
|
+
borderRadius: config.borderRadius,
|
|
393
|
+
paddingHorizontal: config.lootBadgePaddingX,
|
|
394
|
+
paddingVertical: config.lootBadgePaddingY,
|
|
395
|
+
style: isWeb ? {
|
|
396
|
+
...LOOT_BADGE_WEB_BACKGROUNDS[lootBadge],
|
|
397
|
+
border: "1px solid rgba(0, 0, 0, 0.15)",
|
|
398
|
+
borderRadius: `${config.borderRadius}px`
|
|
399
|
+
} : {
|
|
400
|
+
backgroundColor: LOOT_BADGE_NATIVE_COLORS[lootBadge],
|
|
401
|
+
borderWidth: 1,
|
|
402
|
+
borderColor: "rgba(0, 0, 0, 0.15)",
|
|
403
|
+
borderRadius: config.borderRadius
|
|
404
|
+
},
|
|
405
|
+
children: /* @__PURE__ */ jsx3(
|
|
406
|
+
Text,
|
|
407
|
+
{
|
|
408
|
+
color: theme.colors.content.on.brandExtra,
|
|
409
|
+
fontSize: config.lootBadgeFontSize,
|
|
410
|
+
lineHeight: config.lootBadgeLineHeight,
|
|
411
|
+
fontWeight: "500",
|
|
412
|
+
children: LOOT_BADGE_LABELS[lootBadge]
|
|
413
|
+
}
|
|
414
|
+
)
|
|
415
|
+
}
|
|
416
|
+
),
|
|
417
|
+
tagsTopLeft
|
|
418
|
+
]
|
|
359
419
|
}
|
|
360
420
|
),
|
|
361
421
|
tagsTopRight && /* @__PURE__ */ jsx3(
|
|
@@ -389,7 +449,7 @@ var GameCard = ({
|
|
|
389
449
|
color: theme.colors.content.primary,
|
|
390
450
|
fontSize: config.titleFontSize,
|
|
391
451
|
lineHeight: config.titleLineHeight,
|
|
392
|
-
fontWeight: "
|
|
452
|
+
fontWeight: "500",
|
|
393
453
|
numberOfLines: 1,
|
|
394
454
|
style: isWeb ? {
|
|
395
455
|
overflow: "hidden",
|
|
@@ -421,20 +481,22 @@ var GameCard = ({
|
|
|
421
481
|
Box,
|
|
422
482
|
{
|
|
423
483
|
onPress: onButtonClick,
|
|
424
|
-
backgroundColor:
|
|
425
|
-
borderRadius:
|
|
484
|
+
backgroundColor: theme.colors.control.mono.secondary.bg,
|
|
485
|
+
borderRadius: config.borderRadius,
|
|
426
486
|
height: config.buttonHeight,
|
|
427
487
|
paddingHorizontal: config.buttonPaddingX,
|
|
428
488
|
alignItems: "center",
|
|
429
489
|
justifyContent: "center",
|
|
430
490
|
style: isWeb ? {
|
|
431
|
-
backdropFilter: "blur(
|
|
491
|
+
backdropFilter: "blur(30px)",
|
|
492
|
+
WebkitBackdropFilter: "blur(30px)",
|
|
493
|
+
border: `1px solid ${theme.colors.control.mono.secondary.border}`,
|
|
432
494
|
cursor: onButtonClick ? "pointer" : "default"
|
|
433
495
|
} : void 0,
|
|
434
496
|
children: /* @__PURE__ */ jsx3(
|
|
435
497
|
Text,
|
|
436
498
|
{
|
|
437
|
-
color: theme.colors.
|
|
499
|
+
color: theme.colors.control.mono.text.secondary,
|
|
438
500
|
fontSize: config.buttonFontSize,
|
|
439
501
|
lineHeight: config.buttonLineHeight,
|
|
440
502
|
fontWeight: "500",
|