@xsolla/xui-b2c-media-card 0.218.0 → 0.219.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.js CHANGED
@@ -59,6 +59,7 @@ var toGapValue = (gap) => {
59
59
  const asNumber = Number(gap);
60
60
  return Number.isFinite(asNumber) ? asNumber : void 0;
61
61
  };
62
+ var toNativeDisplay = (display) => display === "none" ? "none" : void 0;
62
63
  var Box = ({
63
64
  children,
64
65
  onPress,
@@ -90,6 +91,7 @@ var Box = ({
90
91
  marginBottom,
91
92
  marginLeft,
92
93
  marginRight,
94
+ display,
93
95
  flexDirection,
94
96
  flexWrap,
95
97
  alignItems,
@@ -153,6 +155,7 @@ var Box = ({
153
155
  marginBottom,
154
156
  marginLeft,
155
157
  marginRight,
158
+ display: toNativeDisplay(display),
156
159
  flexDirection,
157
160
  flexWrap,
158
161
  alignItems,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/MediaCard.tsx"],"sourcesContent":["export { MediaCard } from \"./MediaCard\";\n\nexport type { MediaCardProps, MediaCardOrientation } from \"./types\";\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","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.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 textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","import React from \"react\";\n// @ts-expect-error resolved at build time to web/native primitives\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { MediaCardOrientation, MediaCardProps } from \"./types\";\n\n/**\n * Figma `MediaCard` (743:3142) on the B2C Components page. The component set\n * declares three properties — `Orientation`, `Rewarded` and `Watch Button` —\n * which map onto `orientation`, `rewarded` and `showWatchButton`.\n *\n * Both orientations share the 8 px radius, the 1 px inside stroke and the\n * clipped full-bleed thumbnail; only the frame's aspect changes.\n */\nconst FRAME: Record<MediaCardOrientation, { width: number; height: number }> = {\n horizontal: { width: 319, height: 179 },\n vertical: { width: 95, height: 169 },\n};\n\nconst CARD_RADIUS = 8;\n\n/** The Watch control: a filled brand-extra pill centred over the thumbnail. */\nconst WATCH_RADIUS = 4;\nconst WATCH_PADDING_X = 16;\nconst WATCH_PADDING_Y = 8;\nconst WATCH_GAP = 8;\nconst WATCH_FONT_SIZE = 14;\nconst WATCH_LINE_HEIGHT = 20;\nconst WATCH_FONT_WEIGHT = \"500\";\nconst REWARD_GLYPH_SIZE = 16;\n\ntype WatchControlProps = {\n label: string;\n accessibleName: string;\n disabled: boolean;\n onPress?: () => void;\n background: string;\n foreground: string;\n fontFamily: string;\n children?: React.ReactNode;\n};\n\n/**\n * On web this is a real `<button>`: it stops the press from also reaching the\n * plate's own `onPress`, and it gets keyboard activation and focus for free.\n * Native has no bubbling `onPress` to stop, so a `Box` with the accessibility\n * role is enough. Same split as the B2B MediaCard's `ActionButton`.\n */\nconst WatchControl = ({\n label,\n accessibleName,\n disabled,\n onPress,\n background,\n foreground,\n fontFamily,\n children,\n}: WatchControlProps) => {\n if (isWeb) {\n return (\n <button\n type=\"button\"\n aria-label={accessibleName}\n disabled={disabled}\n data-testid=\"media-card-watch\"\n onClick={(event) => {\n event.stopPropagation();\n onPress?.();\n }}\n style={{\n alignItems: \"center\",\n background,\n border: 0,\n borderRadius: WATCH_RADIUS,\n color: foreground,\n cursor: onPress && !disabled ? \"pointer\" : \"default\",\n display: \"inline-flex\",\n fontFamily,\n fontSize: WATCH_FONT_SIZE,\n fontWeight: WATCH_FONT_WEIGHT,\n gap: WATCH_GAP,\n lineHeight: `${WATCH_LINE_HEIGHT}px`,\n margin: 0,\n padding: `${WATCH_PADDING_Y}px ${WATCH_PADDING_X}px`,\n whiteSpace: \"nowrap\",\n zIndex: 10,\n }}\n >\n <span data-testid=\"media-card-watch-label\">{label}</span>\n {children}\n </button>\n );\n }\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={WATCH_GAP}\n paddingHorizontal={WATCH_PADDING_X}\n paddingVertical={WATCH_PADDING_Y}\n borderRadius={WATCH_RADIUS}\n backgroundColor={background}\n zIndex={10}\n onPress={disabled ? undefined : onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibleName}\n testID=\"media-card-watch\"\n >\n <Text\n color={foreground}\n fontFamily={fontFamily}\n fontSize={WATCH_FONT_SIZE}\n lineHeight={WATCH_LINE_HEIGHT}\n fontWeight={WATCH_FONT_WEIGHT}\n numberOfLines={1}\n testID=\"media-card-watch-label\"\n >\n {label}\n </Text>\n {children}\n </Box>\n );\n};\n\nexport const MediaCard: React.FC<MediaCardProps> = ({\n src,\n mediaName,\n alt = \"\",\n orientation = \"horizontal\",\n rewarded = false,\n rewardIcon,\n showWatchButton = true,\n watchLabel = \"Watch\",\n onWatchPress,\n onPress,\n disabled = false,\n width,\n height,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const frame = FRAME[orientation];\n const isPlateInteractive = Boolean(onPress) && !disabled;\n\n // Figma pins each orientation to a fixed frame, but a card in a real rail has\n // to flex with its column — so the frame width is only a default and it is\n // the aspect ratio, not the height, that is preserved. `height` opts out.\n const aspectRatio = frame.width / frame.height;\n\n /**\n * The accessibility criterion on the ticket: a rail of cards must not\n * announce ten identical \"Watch\" buttons. The visible label stays short while\n * the accessible name carries the media's own name — and the reward, which is\n * otherwise communicated by a glyph alone.\n */\n const watchAccessibleName = rewarded\n ? `${watchLabel} ${mediaName}, rewarded`\n : `${watchLabel} ${mediaName}`;\n\n const plateInteractiveProps =\n isWeb && isPlateInteractive\n ? {\n role: \"button\",\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onPress?.();\n }\n },\n }\n : {};\n\n return (\n <Box\n width={width ?? frame.width}\n height={height}\n position=\"relative\"\n overflow=\"hidden\"\n borderRadius={CARD_RADIUS}\n borderWidth={1}\n borderStyle=\"solid\"\n borderColor={theme.colors.border.secondary}\n backgroundColor={theme.colors.background.secondary}\n alignItems=\"center\"\n justifyContent=\"center\"\n opacity={disabled ? 0.48 : 1}\n onPress={isPlateInteractive ? onPress : undefined}\n aria-label={mediaName}\n aria-disabled={disabled || undefined}\n {...(!isWeb\n ? { accessibilityLabel: mediaName }\n : {})}\n style={{\n aspectRatio: height ? undefined : aspectRatio,\n ...(isWeb && isPlateInteractive ? { cursor: \"pointer\" as const } : {}),\n }}\n data-testid={testID || \"media-card\"}\n testID={testID || \"media-card\"}\n {...plateInteractiveProps}\n >\n <Box\n as=\"img\"\n src={src}\n alt={alt}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n data-testid=\"media-card-thumbnail\"\n testID=\"media-card-thumbnail\"\n />\n\n {showWatchButton && (\n <WatchControl\n label={watchLabel}\n accessibleName={watchAccessibleName}\n disabled={disabled}\n onPress={onWatchPress}\n background={theme.colors.control.brandExtra.primary.bg}\n foreground={theme.colors.content.on.brandExtra}\n fontFamily={theme.fonts.body}\n >\n {rewarded && (\n <Box\n width={REWARD_GLYPH_SIZE}\n height={REWARD_GLYPH_SIZE}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderRadius={REWARD_GLYPH_SIZE / 2}\n // Figma draws a reward coin here. The glyph is product-specific,\n // so it stays a slot — the fallback is a neutral mark rather than\n // a guess at someone's currency icon. It is decorative either\n // way: the reward is already in the button's accessible name.\n backgroundColor={\n rewardIcon ? undefined : theme.colors.content.on.brandExtra\n }\n aria-hidden\n data-testid=\"media-card-reward\"\n testID=\"media-card-reward\"\n >\n {rewardIcon}\n </Box>\n )}\n </WatchControl>\n )}\n </Box>\n );\n};\n\nMediaCard.displayName = \"MediaCard\";\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/MediaCard.tsx"],"sourcesContent":["export { MediaCard } from \"./MediaCard\";\n\nexport type { MediaCardProps, MediaCardOrientation } from \"./types\";\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\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\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 display,\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 display: toNativeDisplay(display),\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","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.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 textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","import React from \"react\";\n// @ts-expect-error resolved at build time to web/native primitives\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { MediaCardOrientation, MediaCardProps } from \"./types\";\n\n/**\n * Figma `MediaCard` (743:3142) on the B2C Components page. The component set\n * declares three properties — `Orientation`, `Rewarded` and `Watch Button` —\n * which map onto `orientation`, `rewarded` and `showWatchButton`.\n *\n * Both orientations share the 8 px radius, the 1 px inside stroke and the\n * clipped full-bleed thumbnail; only the frame's aspect changes.\n */\nconst FRAME: Record<MediaCardOrientation, { width: number; height: number }> = {\n horizontal: { width: 319, height: 179 },\n vertical: { width: 95, height: 169 },\n};\n\nconst CARD_RADIUS = 8;\n\n/** The Watch control: a filled brand-extra pill centred over the thumbnail. */\nconst WATCH_RADIUS = 4;\nconst WATCH_PADDING_X = 16;\nconst WATCH_PADDING_Y = 8;\nconst WATCH_GAP = 8;\nconst WATCH_FONT_SIZE = 14;\nconst WATCH_LINE_HEIGHT = 20;\nconst WATCH_FONT_WEIGHT = \"500\";\nconst REWARD_GLYPH_SIZE = 16;\n\ntype WatchControlProps = {\n label: string;\n accessibleName: string;\n disabled: boolean;\n onPress?: () => void;\n background: string;\n foreground: string;\n fontFamily: string;\n children?: React.ReactNode;\n};\n\n/**\n * On web this is a real `<button>`: it stops the press from also reaching the\n * plate's own `onPress`, and it gets keyboard activation and focus for free.\n * Native has no bubbling `onPress` to stop, so a `Box` with the accessibility\n * role is enough. Same split as the B2B MediaCard's `ActionButton`.\n */\nconst WatchControl = ({\n label,\n accessibleName,\n disabled,\n onPress,\n background,\n foreground,\n fontFamily,\n children,\n}: WatchControlProps) => {\n if (isWeb) {\n return (\n <button\n type=\"button\"\n aria-label={accessibleName}\n disabled={disabled}\n data-testid=\"media-card-watch\"\n onClick={(event) => {\n event.stopPropagation();\n onPress?.();\n }}\n style={{\n alignItems: \"center\",\n background,\n border: 0,\n borderRadius: WATCH_RADIUS,\n color: foreground,\n cursor: onPress && !disabled ? \"pointer\" : \"default\",\n display: \"inline-flex\",\n fontFamily,\n fontSize: WATCH_FONT_SIZE,\n fontWeight: WATCH_FONT_WEIGHT,\n gap: WATCH_GAP,\n lineHeight: `${WATCH_LINE_HEIGHT}px`,\n margin: 0,\n padding: `${WATCH_PADDING_Y}px ${WATCH_PADDING_X}px`,\n whiteSpace: \"nowrap\",\n zIndex: 10,\n }}\n >\n <span data-testid=\"media-card-watch-label\">{label}</span>\n {children}\n </button>\n );\n }\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={WATCH_GAP}\n paddingHorizontal={WATCH_PADDING_X}\n paddingVertical={WATCH_PADDING_Y}\n borderRadius={WATCH_RADIUS}\n backgroundColor={background}\n zIndex={10}\n onPress={disabled ? undefined : onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibleName}\n testID=\"media-card-watch\"\n >\n <Text\n color={foreground}\n fontFamily={fontFamily}\n fontSize={WATCH_FONT_SIZE}\n lineHeight={WATCH_LINE_HEIGHT}\n fontWeight={WATCH_FONT_WEIGHT}\n numberOfLines={1}\n testID=\"media-card-watch-label\"\n >\n {label}\n </Text>\n {children}\n </Box>\n );\n};\n\nexport const MediaCard: React.FC<MediaCardProps> = ({\n src,\n mediaName,\n alt = \"\",\n orientation = \"horizontal\",\n rewarded = false,\n rewardIcon,\n showWatchButton = true,\n watchLabel = \"Watch\",\n onWatchPress,\n onPress,\n disabled = false,\n width,\n height,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const frame = FRAME[orientation];\n const isPlateInteractive = Boolean(onPress) && !disabled;\n\n // Figma pins each orientation to a fixed frame, but a card in a real rail has\n // to flex with its column — so the frame width is only a default and it is\n // the aspect ratio, not the height, that is preserved. `height` opts out.\n const aspectRatio = frame.width / frame.height;\n\n /**\n * The accessibility criterion on the ticket: a rail of cards must not\n * announce ten identical \"Watch\" buttons. The visible label stays short while\n * the accessible name carries the media's own name — and the reward, which is\n * otherwise communicated by a glyph alone.\n */\n const watchAccessibleName = rewarded\n ? `${watchLabel} ${mediaName}, rewarded`\n : `${watchLabel} ${mediaName}`;\n\n const plateInteractiveProps =\n isWeb && isPlateInteractive\n ? {\n role: \"button\",\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onPress?.();\n }\n },\n }\n : {};\n\n return (\n <Box\n width={width ?? frame.width}\n height={height}\n position=\"relative\"\n overflow=\"hidden\"\n borderRadius={CARD_RADIUS}\n borderWidth={1}\n borderStyle=\"solid\"\n borderColor={theme.colors.border.secondary}\n backgroundColor={theme.colors.background.secondary}\n alignItems=\"center\"\n justifyContent=\"center\"\n opacity={disabled ? 0.48 : 1}\n onPress={isPlateInteractive ? onPress : undefined}\n aria-label={mediaName}\n aria-disabled={disabled || undefined}\n {...(!isWeb\n ? { accessibilityLabel: mediaName }\n : {})}\n style={{\n aspectRatio: height ? undefined : aspectRatio,\n ...(isWeb && isPlateInteractive ? { cursor: \"pointer\" as const } : {}),\n }}\n data-testid={testID || \"media-card\"}\n testID={testID || \"media-card\"}\n {...plateInteractiveProps}\n >\n <Box\n as=\"img\"\n src={src}\n alt={alt}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n data-testid=\"media-card-thumbnail\"\n testID=\"media-card-thumbnail\"\n />\n\n {showWatchButton && (\n <WatchControl\n label={watchLabel}\n accessibleName={watchAccessibleName}\n disabled={disabled}\n onPress={onWatchPress}\n background={theme.colors.control.brandExtra.primary.bg}\n foreground={theme.colors.content.on.brandExtra}\n fontFamily={theme.fonts.body}\n >\n {rewarded && (\n <Box\n width={REWARD_GLYPH_SIZE}\n height={REWARD_GLYPH_SIZE}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderRadius={REWARD_GLYPH_SIZE / 2}\n // Figma draws a reward coin here. The glyph is product-specific,\n // so it stays a slot — the fallback is a neutral mark rather than\n // a guess at someone's currency icon. It is decorative either\n // way: the reward is already in the button's accessible name.\n backgroundColor={\n rewardIcon ? undefined : theme.colors.content.on.brandExtra\n }\n aria-hidden\n data-testid=\"media-card-reward\"\n testID=\"media-card-reward\"\n >\n {rewardIcon}\n </Box>\n )}\n </WatchControl>\n )}\n </Box>\n );\n};\n\nMediaCard.displayName = \"MediaCard\";\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime"]}
package/native/index.mjs CHANGED
@@ -37,6 +37,7 @@ var toGapValue = (gap) => {
37
37
  const asNumber = Number(gap);
38
38
  return Number.isFinite(asNumber) ? asNumber : void 0;
39
39
  };
40
+ var toNativeDisplay = (display) => display === "none" ? "none" : void 0;
40
41
  var Box = ({
41
42
  children,
42
43
  onPress,
@@ -68,6 +69,7 @@ var Box = ({
68
69
  marginBottom,
69
70
  marginLeft,
70
71
  marginRight,
72
+ display,
71
73
  flexDirection,
72
74
  flexWrap,
73
75
  alignItems,
@@ -131,6 +133,7 @@ var Box = ({
131
133
  marginBottom,
132
134
  marginLeft,
133
135
  marginRight,
136
+ display: toNativeDisplay(display),
134
137
  flexDirection,
135
138
  flexWrap,
136
139
  alignItems,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/MediaCard.tsx"],"sourcesContent":["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","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.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 textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","import React from \"react\";\n// @ts-expect-error resolved at build time to web/native primitives\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { MediaCardOrientation, MediaCardProps } from \"./types\";\n\n/**\n * Figma `MediaCard` (743:3142) on the B2C Components page. The component set\n * declares three properties — `Orientation`, `Rewarded` and `Watch Button` —\n * which map onto `orientation`, `rewarded` and `showWatchButton`.\n *\n * Both orientations share the 8 px radius, the 1 px inside stroke and the\n * clipped full-bleed thumbnail; only the frame's aspect changes.\n */\nconst FRAME: Record<MediaCardOrientation, { width: number; height: number }> = {\n horizontal: { width: 319, height: 179 },\n vertical: { width: 95, height: 169 },\n};\n\nconst CARD_RADIUS = 8;\n\n/** The Watch control: a filled brand-extra pill centred over the thumbnail. */\nconst WATCH_RADIUS = 4;\nconst WATCH_PADDING_X = 16;\nconst WATCH_PADDING_Y = 8;\nconst WATCH_GAP = 8;\nconst WATCH_FONT_SIZE = 14;\nconst WATCH_LINE_HEIGHT = 20;\nconst WATCH_FONT_WEIGHT = \"500\";\nconst REWARD_GLYPH_SIZE = 16;\n\ntype WatchControlProps = {\n label: string;\n accessibleName: string;\n disabled: boolean;\n onPress?: () => void;\n background: string;\n foreground: string;\n fontFamily: string;\n children?: React.ReactNode;\n};\n\n/**\n * On web this is a real `<button>`: it stops the press from also reaching the\n * plate's own `onPress`, and it gets keyboard activation and focus for free.\n * Native has no bubbling `onPress` to stop, so a `Box` with the accessibility\n * role is enough. Same split as the B2B MediaCard's `ActionButton`.\n */\nconst WatchControl = ({\n label,\n accessibleName,\n disabled,\n onPress,\n background,\n foreground,\n fontFamily,\n children,\n}: WatchControlProps) => {\n if (isWeb) {\n return (\n <button\n type=\"button\"\n aria-label={accessibleName}\n disabled={disabled}\n data-testid=\"media-card-watch\"\n onClick={(event) => {\n event.stopPropagation();\n onPress?.();\n }}\n style={{\n alignItems: \"center\",\n background,\n border: 0,\n borderRadius: WATCH_RADIUS,\n color: foreground,\n cursor: onPress && !disabled ? \"pointer\" : \"default\",\n display: \"inline-flex\",\n fontFamily,\n fontSize: WATCH_FONT_SIZE,\n fontWeight: WATCH_FONT_WEIGHT,\n gap: WATCH_GAP,\n lineHeight: `${WATCH_LINE_HEIGHT}px`,\n margin: 0,\n padding: `${WATCH_PADDING_Y}px ${WATCH_PADDING_X}px`,\n whiteSpace: \"nowrap\",\n zIndex: 10,\n }}\n >\n <span data-testid=\"media-card-watch-label\">{label}</span>\n {children}\n </button>\n );\n }\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={WATCH_GAP}\n paddingHorizontal={WATCH_PADDING_X}\n paddingVertical={WATCH_PADDING_Y}\n borderRadius={WATCH_RADIUS}\n backgroundColor={background}\n zIndex={10}\n onPress={disabled ? undefined : onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibleName}\n testID=\"media-card-watch\"\n >\n <Text\n color={foreground}\n fontFamily={fontFamily}\n fontSize={WATCH_FONT_SIZE}\n lineHeight={WATCH_LINE_HEIGHT}\n fontWeight={WATCH_FONT_WEIGHT}\n numberOfLines={1}\n testID=\"media-card-watch-label\"\n >\n {label}\n </Text>\n {children}\n </Box>\n );\n};\n\nexport const MediaCard: React.FC<MediaCardProps> = ({\n src,\n mediaName,\n alt = \"\",\n orientation = \"horizontal\",\n rewarded = false,\n rewardIcon,\n showWatchButton = true,\n watchLabel = \"Watch\",\n onWatchPress,\n onPress,\n disabled = false,\n width,\n height,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const frame = FRAME[orientation];\n const isPlateInteractive = Boolean(onPress) && !disabled;\n\n // Figma pins each orientation to a fixed frame, but a card in a real rail has\n // to flex with its column — so the frame width is only a default and it is\n // the aspect ratio, not the height, that is preserved. `height` opts out.\n const aspectRatio = frame.width / frame.height;\n\n /**\n * The accessibility criterion on the ticket: a rail of cards must not\n * announce ten identical \"Watch\" buttons. The visible label stays short while\n * the accessible name carries the media's own name — and the reward, which is\n * otherwise communicated by a glyph alone.\n */\n const watchAccessibleName = rewarded\n ? `${watchLabel} ${mediaName}, rewarded`\n : `${watchLabel} ${mediaName}`;\n\n const plateInteractiveProps =\n isWeb && isPlateInteractive\n ? {\n role: \"button\",\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onPress?.();\n }\n },\n }\n : {};\n\n return (\n <Box\n width={width ?? frame.width}\n height={height}\n position=\"relative\"\n overflow=\"hidden\"\n borderRadius={CARD_RADIUS}\n borderWidth={1}\n borderStyle=\"solid\"\n borderColor={theme.colors.border.secondary}\n backgroundColor={theme.colors.background.secondary}\n alignItems=\"center\"\n justifyContent=\"center\"\n opacity={disabled ? 0.48 : 1}\n onPress={isPlateInteractive ? onPress : undefined}\n aria-label={mediaName}\n aria-disabled={disabled || undefined}\n {...(!isWeb\n ? { accessibilityLabel: mediaName }\n : {})}\n style={{\n aspectRatio: height ? undefined : aspectRatio,\n ...(isWeb && isPlateInteractive ? { cursor: \"pointer\" as const } : {}),\n }}\n data-testid={testID || \"media-card\"}\n testID={testID || \"media-card\"}\n {...plateInteractiveProps}\n >\n <Box\n as=\"img\"\n src={src}\n alt={alt}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n data-testid=\"media-card-thumbnail\"\n testID=\"media-card-thumbnail\"\n />\n\n {showWatchButton && (\n <WatchControl\n label={watchLabel}\n accessibleName={watchAccessibleName}\n disabled={disabled}\n onPress={onWatchPress}\n background={theme.colors.control.brandExtra.primary.bg}\n foreground={theme.colors.content.on.brandExtra}\n fontFamily={theme.fonts.body}\n >\n {rewarded && (\n <Box\n width={REWARD_GLYPH_SIZE}\n height={REWARD_GLYPH_SIZE}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderRadius={REWARD_GLYPH_SIZE / 2}\n // Figma draws a reward coin here. The glyph is product-specific,\n // so it stays a slot — the fallback is a neutral mark rather than\n // a guess at someone's currency icon. It is decorative either\n // way: the reward is already in the button's accessible name.\n backgroundColor={\n rewardIcon ? undefined : theme.colors.content.on.brandExtra\n }\n aria-hidden\n data-testid=\"media-card-reward\"\n testID=\"media-card-reward\"\n >\n {rewardIcon}\n </Box>\n )}\n </WatchControl>\n )}\n </Box>\n );\n};\n\nMediaCard.displayName = \"MediaCard\";\n"],"mappings":"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","names":["jsx","jsx"]}
1
+ {"version":3,"sources":["../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/MediaCard.tsx"],"sourcesContent":["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\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\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 display,\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 display: toNativeDisplay(display),\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","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.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 textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","import React from \"react\";\n// @ts-expect-error resolved at build time to web/native primitives\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { MediaCardOrientation, MediaCardProps } from \"./types\";\n\n/**\n * Figma `MediaCard` (743:3142) on the B2C Components page. The component set\n * declares three properties — `Orientation`, `Rewarded` and `Watch Button` —\n * which map onto `orientation`, `rewarded` and `showWatchButton`.\n *\n * Both orientations share the 8 px radius, the 1 px inside stroke and the\n * clipped full-bleed thumbnail; only the frame's aspect changes.\n */\nconst FRAME: Record<MediaCardOrientation, { width: number; height: number }> = {\n horizontal: { width: 319, height: 179 },\n vertical: { width: 95, height: 169 },\n};\n\nconst CARD_RADIUS = 8;\n\n/** The Watch control: a filled brand-extra pill centred over the thumbnail. */\nconst WATCH_RADIUS = 4;\nconst WATCH_PADDING_X = 16;\nconst WATCH_PADDING_Y = 8;\nconst WATCH_GAP = 8;\nconst WATCH_FONT_SIZE = 14;\nconst WATCH_LINE_HEIGHT = 20;\nconst WATCH_FONT_WEIGHT = \"500\";\nconst REWARD_GLYPH_SIZE = 16;\n\ntype WatchControlProps = {\n label: string;\n accessibleName: string;\n disabled: boolean;\n onPress?: () => void;\n background: string;\n foreground: string;\n fontFamily: string;\n children?: React.ReactNode;\n};\n\n/**\n * On web this is a real `<button>`: it stops the press from also reaching the\n * plate's own `onPress`, and it gets keyboard activation and focus for free.\n * Native has no bubbling `onPress` to stop, so a `Box` with the accessibility\n * role is enough. Same split as the B2B MediaCard's `ActionButton`.\n */\nconst WatchControl = ({\n label,\n accessibleName,\n disabled,\n onPress,\n background,\n foreground,\n fontFamily,\n children,\n}: WatchControlProps) => {\n if (isWeb) {\n return (\n <button\n type=\"button\"\n aria-label={accessibleName}\n disabled={disabled}\n data-testid=\"media-card-watch\"\n onClick={(event) => {\n event.stopPropagation();\n onPress?.();\n }}\n style={{\n alignItems: \"center\",\n background,\n border: 0,\n borderRadius: WATCH_RADIUS,\n color: foreground,\n cursor: onPress && !disabled ? \"pointer\" : \"default\",\n display: \"inline-flex\",\n fontFamily,\n fontSize: WATCH_FONT_SIZE,\n fontWeight: WATCH_FONT_WEIGHT,\n gap: WATCH_GAP,\n lineHeight: `${WATCH_LINE_HEIGHT}px`,\n margin: 0,\n padding: `${WATCH_PADDING_Y}px ${WATCH_PADDING_X}px`,\n whiteSpace: \"nowrap\",\n zIndex: 10,\n }}\n >\n <span data-testid=\"media-card-watch-label\">{label}</span>\n {children}\n </button>\n );\n }\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={WATCH_GAP}\n paddingHorizontal={WATCH_PADDING_X}\n paddingVertical={WATCH_PADDING_Y}\n borderRadius={WATCH_RADIUS}\n backgroundColor={background}\n zIndex={10}\n onPress={disabled ? undefined : onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibleName}\n testID=\"media-card-watch\"\n >\n <Text\n color={foreground}\n fontFamily={fontFamily}\n fontSize={WATCH_FONT_SIZE}\n lineHeight={WATCH_LINE_HEIGHT}\n fontWeight={WATCH_FONT_WEIGHT}\n numberOfLines={1}\n testID=\"media-card-watch-label\"\n >\n {label}\n </Text>\n {children}\n </Box>\n );\n};\n\nexport const MediaCard: React.FC<MediaCardProps> = ({\n src,\n mediaName,\n alt = \"\",\n orientation = \"horizontal\",\n rewarded = false,\n rewardIcon,\n showWatchButton = true,\n watchLabel = \"Watch\",\n onWatchPress,\n onPress,\n disabled = false,\n width,\n height,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const frame = FRAME[orientation];\n const isPlateInteractive = Boolean(onPress) && !disabled;\n\n // Figma pins each orientation to a fixed frame, but a card in a real rail has\n // to flex with its column — so the frame width is only a default and it is\n // the aspect ratio, not the height, that is preserved. `height` opts out.\n const aspectRatio = frame.width / frame.height;\n\n /**\n * The accessibility criterion on the ticket: a rail of cards must not\n * announce ten identical \"Watch\" buttons. The visible label stays short while\n * the accessible name carries the media's own name — and the reward, which is\n * otherwise communicated by a glyph alone.\n */\n const watchAccessibleName = rewarded\n ? `${watchLabel} ${mediaName}, rewarded`\n : `${watchLabel} ${mediaName}`;\n\n const plateInteractiveProps =\n isWeb && isPlateInteractive\n ? {\n role: \"button\",\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onPress?.();\n }\n },\n }\n : {};\n\n return (\n <Box\n width={width ?? frame.width}\n height={height}\n position=\"relative\"\n overflow=\"hidden\"\n borderRadius={CARD_RADIUS}\n borderWidth={1}\n borderStyle=\"solid\"\n borderColor={theme.colors.border.secondary}\n backgroundColor={theme.colors.background.secondary}\n alignItems=\"center\"\n justifyContent=\"center\"\n opacity={disabled ? 0.48 : 1}\n onPress={isPlateInteractive ? onPress : undefined}\n aria-label={mediaName}\n aria-disabled={disabled || undefined}\n {...(!isWeb\n ? { accessibilityLabel: mediaName }\n : {})}\n style={{\n aspectRatio: height ? undefined : aspectRatio,\n ...(isWeb && isPlateInteractive ? { cursor: \"pointer\" as const } : {}),\n }}\n data-testid={testID || \"media-card\"}\n testID={testID || \"media-card\"}\n {...plateInteractiveProps}\n >\n <Box\n as=\"img\"\n src={src}\n alt={alt}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n style={isWeb ? { objectFit: \"cover\" } : undefined}\n data-testid=\"media-card-thumbnail\"\n testID=\"media-card-thumbnail\"\n />\n\n {showWatchButton && (\n <WatchControl\n label={watchLabel}\n accessibleName={watchAccessibleName}\n disabled={disabled}\n onPress={onWatchPress}\n background={theme.colors.control.brandExtra.primary.bg}\n foreground={theme.colors.content.on.brandExtra}\n fontFamily={theme.fonts.body}\n >\n {rewarded && (\n <Box\n width={REWARD_GLYPH_SIZE}\n height={REWARD_GLYPH_SIZE}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderRadius={REWARD_GLYPH_SIZE / 2}\n // Figma draws a reward coin here. The glyph is product-specific,\n // so it stays a slot — the fallback is a neutral mark rather than\n // a guess at someone's currency icon. It is decorative either\n // way: the reward is already in the button's accessible name.\n backgroundColor={\n rewardIcon ? undefined : theme.colors.content.on.brandExtra\n }\n aria-hidden\n data-testid=\"media-card-reward\"\n testID=\"media-card-reward\"\n >\n {rewardIcon}\n </Box>\n )}\n </WatchControl>\n )}\n </Box>\n );\n};\n\nMediaCard.displayName = \"MediaCard\";\n"],"mappings":"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","names":["jsx","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-b2c-media-card",
3
- "version": "0.218.0",
3
+ "version": "0.219.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,8 +13,8 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-core": "0.218.0",
17
- "@xsolla/xui-primitives-core": "0.218.0"
16
+ "@xsolla/xui-core": "0.219.0",
17
+ "@xsolla/xui-primitives-core": "0.219.0"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": ">=16.8.0"
package/web/index.js CHANGED
@@ -3573,6 +3573,10 @@ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
3573
3573
  "fontWeight",
3574
3574
  "fontFamily",
3575
3575
  "textDecoration",
3576
+ // `display` is a presentation attribute on SVG, so isPropValid lets it
3577
+ // through — but Box consumes it purely as CSS. Without this it lands on the
3578
+ // DOM node as a bogus `display="inline-flex"` attribute.
3579
+ "display",
3576
3580
  // Cross-platform layout prop that Text consumes as CSS, never as an
3577
3581
  // attribute. Pinned explicitly because it is now spread into the styled
3578
3582
  // component rather than destructured away before it can reach the DOM.
@@ -3607,7 +3611,7 @@ function createFilteredElement(defaultTag) {
3607
3611
  var import_jsx_runtime = require("react/jsx-runtime");
3608
3612
  var FilteredDiv = createFilteredElement("div");
3609
3613
  var StyledBox = styled_components_esm_default(FilteredDiv)`
3610
- display: flex;
3614
+ display: ${(props) => props.display || "flex"};
3611
3615
  box-sizing: border-box;
3612
3616
  background-color: ${(props) => props.backgroundColor || "transparent"};
3613
3617
  border-color: ${(props) => props.borderColor || "transparent"};
@@ -3743,7 +3747,7 @@ var Box = import_react3.default.forwardRef(
3743
3747
  onLoad,
3744
3748
  "data-testid": dataTestId || testID,
3745
3749
  style: {
3746
- display: "block",
3750
+ display: props.display || "block",
3747
3751
  objectFit: "cover",
3748
3752
  width: typeof props.width === "number" ? `${props.width}px` : props.width,
3749
3753
  height: typeof props.height === "number" ? `${props.height}px` : props.height,