@xsolla/xui-avatar 0.181.0 → 0.183.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/README.md CHANGED
@@ -93,6 +93,7 @@ export default function QuickStart() {
93
93
  | `size` | `"xl" \| "lg" \| "md" \| "sm" \| "xs" \| "xxs"` | `"xl"` | Avatar size. |
94
94
  | `square` | `boolean` | `false` | Square (small radius) instead of circular. |
95
95
  | `tone` | `"mono" \| "brand"` | `"mono"` | Visual tone. |
96
+ | `stroke` | `boolean` | `true` | Render the avatar's outer border. Set `false` to remove the border entirely. |
96
97
  | `badge` | `boolean` | `false` | Show a notification badge. |
97
98
  | `badgeCount` | `ReactNode` | — | Numeric or text content rendered inside the badge. |
98
99
  | `badgeIcon` | `ReactNode` | — | Icon rendered inside the badge. |
@@ -169,6 +170,18 @@ export default function AvatarTones() {
169
170
  }
170
171
  ```
171
172
 
173
+ ### Borderless
174
+
175
+ ```tsx
176
+ import * as React from "react";
177
+ import { Avatar } from "@xsolla/xui-avatar";
178
+
179
+ export default function BorderlessAvatar() {
180
+ // stroke defaults to true; pass stroke={false} to remove the outer border
181
+ return <Avatar text="JD" stroke={false} />;
182
+ }
183
+ ```
184
+
172
185
  ### With badge
173
186
 
174
187
  ```tsx
@@ -14,6 +14,13 @@ interface AvatarProps extends ThemeOverrideProps {
14
14
  square?: boolean;
15
15
  /** Visual tone — 'mono' (default) or 'brand'. */
16
16
  tone?: "mono" | "brand";
17
+ /**
18
+ * Whether to render the avatar's outer border (stroke). Defaults to `true`,
19
+ * preserving the existing bordered look. Set to `false` to remove the border
20
+ * entirely — useful on surfaces that already provide separation, or in dense
21
+ * layouts where the border adds visual noise.
22
+ */
23
+ stroke?: boolean;
17
24
  /** Whether to show an alert badge */
18
25
  badge?: boolean;
19
26
  /** Number or text to display in the badge notification */
package/native/index.d.ts CHANGED
@@ -14,6 +14,13 @@ interface AvatarProps extends ThemeOverrideProps {
14
14
  square?: boolean;
15
15
  /** Visual tone — 'mono' (default) or 'brand'. */
16
16
  tone?: "mono" | "brand";
17
+ /**
18
+ * Whether to render the avatar's outer border (stroke). Defaults to `true`,
19
+ * preserving the existing bordered look. Set to `false` to remove the border
20
+ * entirely — useful on surfaces that already provide separation, or in dense
21
+ * layouts where the border adds visual noise.
22
+ */
23
+ stroke?: boolean;
17
24
  /** Whether to show an alert badge */
18
25
  badge?: boolean;
19
26
  /** Number or text to display in the badge notification */
package/native/index.js CHANGED
@@ -319,6 +319,7 @@ var Avatar = ({
319
319
  size = "xl",
320
320
  square = false,
321
321
  tone = "mono",
322
+ stroke = true,
322
323
  badge = false,
323
324
  badgeCount,
324
325
  badgeIcon,
@@ -410,8 +411,8 @@ var Avatar = ({
410
411
  justifyContent: "center",
411
412
  position: "relative",
412
413
  overflow: "hidden",
413
- borderWidth: 2,
414
- borderColor: theme.colors.border.secondary,
414
+ borderWidth: stroke ? 2 : 0,
415
+ borderColor: stroke ? theme.colors.border.secondary : void 0,
415
416
  ...!disableHover && !useImage && {
416
417
  hoverStyle: {
417
418
  backgroundColor: toneHoverBackground
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Avatar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["export * from \"./Avatar\";\nexport * from \"./AvatarGroup\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={2}\n borderColor={theme.colors.border.secondary}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\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 minWidth,\n minHeight,\n maxWidth,\n maxHeight,\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 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 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 {\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","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","React","import_xui_core","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Avatar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["export * from \"./Avatar\";\nexport * from \"./AvatarGroup\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /**\n * Whether to render the avatar's outer border (stroke). Defaults to `true`,\n * preserving the existing bordered look. Set to `false` to remove the border\n * entirely — useful on surfaces that already provide separation, or in dense\n * layouts where the border adds visual noise.\n */\n stroke?: boolean;\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n stroke = true,\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={stroke ? 2 : 0}\n borderColor={stroke ? theme.colors.border.secondary : undefined}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\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 minWidth,\n minHeight,\n maxWidth,\n maxHeight,\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 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 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 {\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","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","React","import_xui_core","import_jsx_runtime"]}
package/native/index.mjs CHANGED
@@ -289,6 +289,7 @@ var Avatar = ({
289
289
  size = "xl",
290
290
  square = false,
291
291
  tone = "mono",
292
+ stroke = true,
292
293
  badge = false,
293
294
  badgeCount,
294
295
  badgeIcon,
@@ -380,8 +381,8 @@ var Avatar = ({
380
381
  justifyContent: "center",
381
382
  position: "relative",
382
383
  overflow: "hidden",
383
- borderWidth: 2,
384
- borderColor: theme.colors.border.secondary,
384
+ borderWidth: stroke ? 2 : 0,
385
+ borderColor: stroke ? theme.colors.border.secondary : void 0,
385
386
  ...!disableHover && !useImage && {
386
387
  hoverStyle: {
387
388
  backgroundColor: toneHoverBackground
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Avatar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={2}\n borderColor={theme.colors.border.secondary}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\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 minWidth,\n minHeight,\n maxWidth,\n maxHeight,\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 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 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 {\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","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["React","jsx","View","jsx","jsx","React","useResolvedTheme","jsx","jsxs","useResolvedTheme"]}
1
+ {"version":3,"sources":["../../src/Avatar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /**\n * Whether to render the avatar's outer border (stroke). Defaults to `true`,\n * preserving the existing bordered look. Set to `false` to remove the border\n * entirely — useful on surfaces that already provide separation, or in dense\n * layouts where the border adds visual noise.\n */\n stroke?: boolean;\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n stroke = true,\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={stroke ? 2 : 0}\n borderColor={stroke ? theme.colors.border.secondary : undefined}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\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 minWidth,\n minHeight,\n maxWidth,\n maxHeight,\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 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 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 {\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","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["React","jsx","View","jsx","jsx","React","useResolvedTheme","jsx","jsxs","useResolvedTheme"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-avatar",
3
- "version": "0.181.0",
3
+ "version": "0.183.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -10,11 +10,11 @@
10
10
  "build:native": "PLATFORM=native tsup"
11
11
  },
12
12
  "dependencies": {
13
- "@xsolla/xui-badge": "0.181.0",
14
- "@xsolla/xui-core": "0.181.0",
15
- "@xsolla/xui-icons-base": "0.181.0",
16
- "@xsolla/xui-primitives-core": "0.181.0",
17
- "@xsolla/xui-tooltip": "0.181.0"
13
+ "@xsolla/xui-badge": "0.183.0",
14
+ "@xsolla/xui-core": "0.183.0",
15
+ "@xsolla/xui-icons-base": "0.183.0",
16
+ "@xsolla/xui-primitives-core": "0.183.0",
17
+ "@xsolla/xui-tooltip": "0.183.0"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": ">=16.8.0",
package/web/index.d.mts CHANGED
@@ -14,6 +14,13 @@ interface AvatarProps extends ThemeOverrideProps {
14
14
  square?: boolean;
15
15
  /** Visual tone — 'mono' (default) or 'brand'. */
16
16
  tone?: "mono" | "brand";
17
+ /**
18
+ * Whether to render the avatar's outer border (stroke). Defaults to `true`,
19
+ * preserving the existing bordered look. Set to `false` to remove the border
20
+ * entirely — useful on surfaces that already provide separation, or in dense
21
+ * layouts where the border adds visual noise.
22
+ */
23
+ stroke?: boolean;
17
24
  /** Whether to show an alert badge */
18
25
  badge?: boolean;
19
26
  /** Number or text to display in the badge notification */
package/web/index.d.ts CHANGED
@@ -14,6 +14,13 @@ interface AvatarProps extends ThemeOverrideProps {
14
14
  square?: boolean;
15
15
  /** Visual tone — 'mono' (default) or 'brand'. */
16
16
  tone?: "mono" | "brand";
17
+ /**
18
+ * Whether to render the avatar's outer border (stroke). Defaults to `true`,
19
+ * preserving the existing bordered look. Set to `false` to remove the border
20
+ * entirely — useful on surfaces that already provide separation, or in dense
21
+ * layouts where the border adds visual noise.
22
+ */
23
+ stroke?: boolean;
17
24
  /** Whether to show an alert badge */
18
25
  badge?: boolean;
19
26
  /** Number or text to display in the badge notification */
package/web/index.js CHANGED
@@ -366,6 +366,7 @@ var Avatar = ({
366
366
  size = "xl",
367
367
  square = false,
368
368
  tone = "mono",
369
+ stroke = true,
369
370
  badge = false,
370
371
  badgeCount,
371
372
  badgeIcon,
@@ -457,8 +458,8 @@ var Avatar = ({
457
458
  justifyContent: "center",
458
459
  position: "relative",
459
460
  overflow: "hidden",
460
- borderWidth: 2,
461
- borderColor: theme.colors.border.secondary,
461
+ borderWidth: stroke ? 2 : 0,
462
+ borderColor: stroke ? theme.colors.border.secondary : void 0,
462
463
  ...!disableHover && !useImage && {
463
464
  hoverStyle: {
464
465
  backgroundColor: toneHoverBackground
package/web/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Avatar.tsx","../../../../foundation/primitives-web/src/Box.tsx","../../../../foundation/primitives-web/src/filterDOMProps.ts","../../../../../node_modules/@emotion/memoize/dist/memoize.esm.js","../../../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js","../../../../foundation/primitives-web/src/Text.tsx","../../../../foundation/primitives-web/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["export * from \"./Avatar\";\nexport * from \"./AvatarGroup\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={2}\n borderColor={theme.colors.border.secondary}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledBox = styled(FilteredDiv)<BoxProps>`\n display: flex;\n box-sizing: border-box;\n background-color: ${(props) => props.backgroundColor || \"transparent\"};\n border-color: ${(props) => props.borderColor || \"transparent\"};\n border-width: ${(props) =>\n typeof props.borderWidth === \"number\"\n ? `${props.borderWidth}px`\n : props.borderWidth || 0};\n\n ${(props) =>\n props.borderBottomWidth !== undefined &&\n `\n border-bottom-width: ${typeof props.borderBottomWidth === \"number\" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};\n border-bottom-color: ${props.borderBottomColor || props.borderColor || \"transparent\"};\n border-bottom-style: solid;\n `}\n ${(props) =>\n props.borderTopWidth !== undefined &&\n `\n border-top-width: ${typeof props.borderTopWidth === \"number\" ? `${props.borderTopWidth}px` : props.borderTopWidth};\n border-top-color: ${props.borderTopColor || props.borderColor || \"transparent\"};\n border-top-style: solid;\n `}\n ${(props) =>\n props.borderLeftWidth !== undefined &&\n `\n border-left-width: ${typeof props.borderLeftWidth === \"number\" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};\n border-left-color: ${props.borderLeftColor || props.borderColor || \"transparent\"};\n border-left-style: solid;\n `}\n ${(props) =>\n props.borderRightWidth !== undefined &&\n `\n border-right-width: ${typeof props.borderRightWidth === \"number\" ? `${props.borderRightWidth}px` : props.borderRightWidth};\n border-right-color: ${props.borderRightColor || props.borderColor || \"transparent\"};\n border-right-style: solid;\n `}\n\n border-style: ${(props) =>\n props.borderStyle ||\n (props.borderWidth ||\n props.borderBottomWidth ||\n props.borderTopWidth ||\n props.borderLeftWidth ||\n props.borderRightWidth\n ? \"solid\"\n : \"none\")};\n border-radius: ${(props) =>\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius || 0};\n height: ${(props) =>\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height || \"auto\"};\n width: ${(props) =>\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width || \"auto\"};\n min-width: ${(props) =>\n typeof props.minWidth === \"number\"\n ? `${props.minWidth}px`\n : props.minWidth || \"auto\"};\n min-height: ${(props) =>\n typeof props.minHeight === \"number\"\n ? `${props.minHeight}px`\n : props.minHeight || \"auto\"};\n max-width: ${(props) =>\n typeof props.maxWidth === \"number\"\n ? `${props.maxWidth}px`\n : props.maxWidth || \"none\"};\n max-height: ${(props) =>\n typeof props.maxHeight === \"number\"\n ? `${props.maxHeight}px`\n : props.maxHeight || \"none\"};\n\n padding: ${(props) =>\n typeof props.padding === \"number\"\n ? `${props.padding}px`\n : props.padding || 0};\n ${(props) =>\n props.paddingHorizontal &&\n `\n padding-left: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n padding-right: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n `}\n ${(props) =>\n props.paddingVertical &&\n `\n padding-top: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n padding-bottom: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n `}\n ${(props) =>\n props.paddingTop !== undefined &&\n `padding-top: ${typeof props.paddingTop === \"number\" ? `${props.paddingTop}px` : props.paddingTop};`}\n ${(props) =>\n props.paddingBottom !== undefined &&\n `padding-bottom: ${typeof props.paddingBottom === \"number\" ? `${props.paddingBottom}px` : props.paddingBottom};`}\n ${(props) =>\n props.paddingLeft !== undefined &&\n `padding-left: ${typeof props.paddingLeft === \"number\" ? `${props.paddingLeft}px` : props.paddingLeft};`}\n ${(props) =>\n props.paddingRight !== undefined &&\n `padding-right: ${typeof props.paddingRight === \"number\" ? `${props.paddingRight}px` : props.paddingRight};`}\n\n margin: ${(props) =>\n typeof props.margin === \"number\" ? `${props.margin}px` : props.margin || 0};\n ${(props) =>\n props.marginTop !== undefined &&\n `margin-top: ${typeof props.marginTop === \"number\" ? `${props.marginTop}px` : props.marginTop};`}\n ${(props) =>\n props.marginBottom !== undefined &&\n `margin-bottom: ${typeof props.marginBottom === \"number\" ? `${props.marginBottom}px` : props.marginBottom};`}\n ${(props) =>\n props.marginLeft !== undefined &&\n `margin-left: ${typeof props.marginLeft === \"number\" ? `${props.marginLeft}px` : props.marginLeft};`}\n ${(props) =>\n props.marginRight !== undefined &&\n `margin-right: ${typeof props.marginRight === \"number\" ? `${props.marginRight}px` : props.marginRight};`}\n\n flex-direction: ${(props) => props.flexDirection || \"column\"};\n flex-wrap: ${(props) => props.flexWrap || \"nowrap\"};\n align-items: ${(props) => props.alignItems || \"stretch\"};\n justify-content: ${(props) => props.justifyContent || \"flex-start\"};\n cursor: ${(props) =>\n props.cursor\n ? props.cursor\n : props.onClick || props.onPress\n ? \"pointer\"\n : \"inherit\"};\n position: ${(props) => props.position || \"static\"};\n top: ${(props) =>\n typeof props.top === \"number\" ? `${props.top}px` : props.top};\n bottom: ${(props) =>\n typeof props.bottom === \"number\" ? `${props.bottom}px` : props.bottom};\n left: ${(props) =>\n typeof props.left === \"number\" ? `${props.left}px` : props.left};\n right: ${(props) =>\n typeof props.right === \"number\" ? `${props.right}px` : props.right};\n flex: ${(props) => props.flex};\n flex-shrink: ${(props) => props.flexShrink ?? 1};\n gap: ${(props) =>\n typeof props.gap === \"number\" ? `${props.gap}px` : props.gap || 0};\n align-self: ${(props) => props.alignSelf || \"auto\"};\n overflow: ${(props) => props.overflow || \"visible\"};\n overflow-x: ${(props) => props.overflowX || \"visible\"};\n overflow-y: ${(props) => props.overflowY || \"visible\"};\n z-index: ${(props) => props.zIndex};\n opacity: ${(props) => (props.disabled ? 0.5 : 1)};\n pointer-events: ${(props) => (props.disabled ? \"none\" : \"auto\")};\n\n &:hover {\n ${(props) =>\n props.hoverStyle?.backgroundColor &&\n `background-color: ${props.hoverStyle.backgroundColor};`}\n ${(props) =>\n props.hoverStyle?.borderColor &&\n `border-color: ${props.hoverStyle.borderColor};`}\n }\n\n &:active {\n ${(props) =>\n props.pressStyle?.backgroundColor &&\n `background-color: ${props.pressStyle.backgroundColor};`}\n }\n`;\n\nexport const Box = React.forwardRef<\n HTMLDivElement | HTMLButtonElement,\n BoxProps\n>(\n (\n {\n children,\n onPress,\n onKeyDown,\n onKeyUp,\n role,\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 \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n tabIndex,\n as,\n src,\n alt,\n onError,\n onLoad,\n type,\n disabled,\n id,\n testID,\n \"data-testid\": dataTestId,\n ...props\n },\n ref\n ) => {\n // Handle as=\"img\" for rendering images with proper border-radius\n if (as === \"img\" && src) {\n return (\n <img\n src={src}\n alt={alt || \"\"}\n onError={onError}\n onLoad={onLoad}\n style={{\n display: \"block\",\n objectFit: \"cover\",\n width:\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width,\n height:\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height,\n borderRadius:\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius,\n position: props.position,\n top: typeof props.top === \"number\" ? `${props.top}px` : props.top,\n left:\n typeof props.left === \"number\" ? `${props.left}px` : props.left,\n right:\n typeof props.right === \"number\"\n ? `${props.right}px`\n : props.right,\n bottom:\n typeof props.bottom === \"number\"\n ? `${props.bottom}px`\n : props.bottom,\n ...props.style,\n }}\n />\n );\n }\n\n return (\n <StyledBox\n ref={ref}\n elementType={as}\n id={id}\n type={as === \"button\" ? type || \"button\" : undefined}\n disabled={as === \"button\" ? disabled : undefined}\n onClick={onPress}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-current={ariaCurrent}\n aria-disabled={ariaDisabled}\n aria-busy={ariaBusy}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n aria-live={ariaLive}\n tabIndex={tabIndex !== undefined ? tabIndex : undefined}\n data-testid={dataTestId || testID}\n {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport isPropValid from \"@emotion/is-prop-valid\";\n\n// Props that @emotion/is-prop-valid incorrectly treats as valid HTML.\n// These are React Native or component-specific props that match\n// valid HTML patterns (on* event handlers, SVG attributes).\nexport const ADDITIONAL_BLOCKED_PROPS = new Set([\n // RN-only event handlers (pass isPropValid's on* pattern)\n \"onPress\",\n \"onChangeText\",\n \"onLayout\",\n \"onMoveShouldSetResponder\",\n \"onResponderGrant\",\n \"onResponderMove\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n // SVG attributes that pass isPropValid\n \"strokeWidth\",\n // CSS properties that pass isPropValid but are used as component props\n \"overflow\",\n \"cursor\",\n \"fontSize\",\n \"fontWeight\",\n \"fontFamily\",\n \"textDecoration\",\n]);\n\nfunction shouldForwardProp(key: string): boolean {\n if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;\n return isPropValid(key);\n}\n\n/**\n * Creates a React component that renders the given HTML tag\n * but filters out non-HTML props before they reach the DOM.\n *\n * Uses @emotion/is-prop-valid (same library styled-components v4\n * uses internally) to automatically block invalid HTML attributes,\n * plus a small blocklist for false positives (RN on* handlers, SVG attrs).\n *\n * Usage: `const FilteredDiv = createFilteredElement(\"div\");`\n * Then: `const StyledBox = styled(FilteredDiv)<BoxProps>\\`...\\`;`\n *\n * styled-components can still read ALL props for CSS interpolation,\n * but only valid HTML attributes are forwarded to the DOM element.\n */\nexport function createFilteredElement(defaultTag: string) {\n const Component = React.forwardRef<HTMLElement, Record<string, unknown>>(\n ({ children, elementType, ...props }, ref) => {\n const Tag = (elementType as string) || defaultTag;\n const htmlProps: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (shouldForwardProp(key)) {\n htmlProps[key] = props[key];\n }\n }\n return React.createElement(\n Tag,\n { ref, ...htmlProps },\n children as React.ReactNode\n );\n }\n );\n Component.displayName = `Filtered(${defaultTag})`;\n return Component;\n}\n","function memoize(fn) {\n var cache = {};\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar index = memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default index;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredSpan = createFilteredElement(\"span\");\n\nconst StyledText = styled(FilteredSpan)<TextProps>`\n color: ${(props) => props.color || \"inherit\"};\n font-size: ${(props) =>\n typeof props.fontSize === \"number\"\n ? `${props.fontSize}px`\n : props.fontSize || \"inherit\"};\n font-weight: ${(props) => props.fontWeight || \"normal\"};\n font-family: ${(props) =>\n props.fontFamily ||\n '\"Aktiv Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif'};\n line-height: ${(props) =>\n typeof props.lineHeight === \"number\"\n ? `${props.lineHeight}px`\n : props.lineHeight || \"inherit\"};\n white-space: ${(props) => props.whiteSpace || \"normal\"};\n text-align: ${(props) => props.textAlign || \"inherit\"};\n text-decoration: ${(props) => props.textDecoration || \"none\"};\n`;\n\nexport const Text: React.FC<TextProps> = ({\n style,\n className,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\n data-testid={dataTestId || testID}\n />\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledIcon = styled(FilteredDiv)<IconProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n height: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n color: ${(props) => props.color || \"currentColor\"};\n\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: currentColor;\n }\n`;\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n testID,\n \"data-testid\": dataTestId,\n ...props\n}) => {\n return (\n <StyledIcon data-testid={dataTestId || testID} {...props}>\n {children}\n </StyledIcon>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","React","styled","React","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","FilteredDiv","styled","import_jsx_runtime","React","import_xui_core","import_jsx_runtime","index"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Avatar.tsx","../../../../foundation/primitives-web/src/Box.tsx","../../../../foundation/primitives-web/src/filterDOMProps.ts","../../../../../node_modules/@emotion/memoize/dist/memoize.esm.js","../../../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js","../../../../foundation/primitives-web/src/Text.tsx","../../../../foundation/primitives-web/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["export * from \"./Avatar\";\nexport * from \"./AvatarGroup\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /**\n * Whether to render the avatar's outer border (stroke). Defaults to `true`,\n * preserving the existing bordered look. Set to `false` to remove the border\n * entirely — useful on surfaces that already provide separation, or in dense\n * layouts where the border adds visual noise.\n */\n stroke?: boolean;\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n stroke = true,\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={stroke ? 2 : 0}\n borderColor={stroke ? theme.colors.border.secondary : undefined}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledBox = styled(FilteredDiv)<BoxProps>`\n display: flex;\n box-sizing: border-box;\n background-color: ${(props) => props.backgroundColor || \"transparent\"};\n border-color: ${(props) => props.borderColor || \"transparent\"};\n border-width: ${(props) =>\n typeof props.borderWidth === \"number\"\n ? `${props.borderWidth}px`\n : props.borderWidth || 0};\n\n ${(props) =>\n props.borderBottomWidth !== undefined &&\n `\n border-bottom-width: ${typeof props.borderBottomWidth === \"number\" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};\n border-bottom-color: ${props.borderBottomColor || props.borderColor || \"transparent\"};\n border-bottom-style: solid;\n `}\n ${(props) =>\n props.borderTopWidth !== undefined &&\n `\n border-top-width: ${typeof props.borderTopWidth === \"number\" ? `${props.borderTopWidth}px` : props.borderTopWidth};\n border-top-color: ${props.borderTopColor || props.borderColor || \"transparent\"};\n border-top-style: solid;\n `}\n ${(props) =>\n props.borderLeftWidth !== undefined &&\n `\n border-left-width: ${typeof props.borderLeftWidth === \"number\" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};\n border-left-color: ${props.borderLeftColor || props.borderColor || \"transparent\"};\n border-left-style: solid;\n `}\n ${(props) =>\n props.borderRightWidth !== undefined &&\n `\n border-right-width: ${typeof props.borderRightWidth === \"number\" ? `${props.borderRightWidth}px` : props.borderRightWidth};\n border-right-color: ${props.borderRightColor || props.borderColor || \"transparent\"};\n border-right-style: solid;\n `}\n\n border-style: ${(props) =>\n props.borderStyle ||\n (props.borderWidth ||\n props.borderBottomWidth ||\n props.borderTopWidth ||\n props.borderLeftWidth ||\n props.borderRightWidth\n ? \"solid\"\n : \"none\")};\n border-radius: ${(props) =>\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius || 0};\n height: ${(props) =>\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height || \"auto\"};\n width: ${(props) =>\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width || \"auto\"};\n min-width: ${(props) =>\n typeof props.minWidth === \"number\"\n ? `${props.minWidth}px`\n : props.minWidth || \"auto\"};\n min-height: ${(props) =>\n typeof props.minHeight === \"number\"\n ? `${props.minHeight}px`\n : props.minHeight || \"auto\"};\n max-width: ${(props) =>\n typeof props.maxWidth === \"number\"\n ? `${props.maxWidth}px`\n : props.maxWidth || \"none\"};\n max-height: ${(props) =>\n typeof props.maxHeight === \"number\"\n ? `${props.maxHeight}px`\n : props.maxHeight || \"none\"};\n\n padding: ${(props) =>\n typeof props.padding === \"number\"\n ? `${props.padding}px`\n : props.padding || 0};\n ${(props) =>\n props.paddingHorizontal &&\n `\n padding-left: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n padding-right: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n `}\n ${(props) =>\n props.paddingVertical &&\n `\n padding-top: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n padding-bottom: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n `}\n ${(props) =>\n props.paddingTop !== undefined &&\n `padding-top: ${typeof props.paddingTop === \"number\" ? `${props.paddingTop}px` : props.paddingTop};`}\n ${(props) =>\n props.paddingBottom !== undefined &&\n `padding-bottom: ${typeof props.paddingBottom === \"number\" ? `${props.paddingBottom}px` : props.paddingBottom};`}\n ${(props) =>\n props.paddingLeft !== undefined &&\n `padding-left: ${typeof props.paddingLeft === \"number\" ? `${props.paddingLeft}px` : props.paddingLeft};`}\n ${(props) =>\n props.paddingRight !== undefined &&\n `padding-right: ${typeof props.paddingRight === \"number\" ? `${props.paddingRight}px` : props.paddingRight};`}\n\n margin: ${(props) =>\n typeof props.margin === \"number\" ? `${props.margin}px` : props.margin || 0};\n ${(props) =>\n props.marginTop !== undefined &&\n `margin-top: ${typeof props.marginTop === \"number\" ? `${props.marginTop}px` : props.marginTop};`}\n ${(props) =>\n props.marginBottom !== undefined &&\n `margin-bottom: ${typeof props.marginBottom === \"number\" ? `${props.marginBottom}px` : props.marginBottom};`}\n ${(props) =>\n props.marginLeft !== undefined &&\n `margin-left: ${typeof props.marginLeft === \"number\" ? `${props.marginLeft}px` : props.marginLeft};`}\n ${(props) =>\n props.marginRight !== undefined &&\n `margin-right: ${typeof props.marginRight === \"number\" ? `${props.marginRight}px` : props.marginRight};`}\n\n flex-direction: ${(props) => props.flexDirection || \"column\"};\n flex-wrap: ${(props) => props.flexWrap || \"nowrap\"};\n align-items: ${(props) => props.alignItems || \"stretch\"};\n justify-content: ${(props) => props.justifyContent || \"flex-start\"};\n cursor: ${(props) =>\n props.cursor\n ? props.cursor\n : props.onClick || props.onPress\n ? \"pointer\"\n : \"inherit\"};\n position: ${(props) => props.position || \"static\"};\n top: ${(props) =>\n typeof props.top === \"number\" ? `${props.top}px` : props.top};\n bottom: ${(props) =>\n typeof props.bottom === \"number\" ? `${props.bottom}px` : props.bottom};\n left: ${(props) =>\n typeof props.left === \"number\" ? `${props.left}px` : props.left};\n right: ${(props) =>\n typeof props.right === \"number\" ? `${props.right}px` : props.right};\n flex: ${(props) => props.flex};\n flex-shrink: ${(props) => props.flexShrink ?? 1};\n gap: ${(props) =>\n typeof props.gap === \"number\" ? `${props.gap}px` : props.gap || 0};\n align-self: ${(props) => props.alignSelf || \"auto\"};\n overflow: ${(props) => props.overflow || \"visible\"};\n overflow-x: ${(props) => props.overflowX || \"visible\"};\n overflow-y: ${(props) => props.overflowY || \"visible\"};\n z-index: ${(props) => props.zIndex};\n opacity: ${(props) => (props.disabled ? 0.5 : 1)};\n pointer-events: ${(props) => (props.disabled ? \"none\" : \"auto\")};\n\n &:hover {\n ${(props) =>\n props.hoverStyle?.backgroundColor &&\n `background-color: ${props.hoverStyle.backgroundColor};`}\n ${(props) =>\n props.hoverStyle?.borderColor &&\n `border-color: ${props.hoverStyle.borderColor};`}\n }\n\n &:active {\n ${(props) =>\n props.pressStyle?.backgroundColor &&\n `background-color: ${props.pressStyle.backgroundColor};`}\n }\n`;\n\nexport const Box = React.forwardRef<\n HTMLDivElement | HTMLButtonElement,\n BoxProps\n>(\n (\n {\n children,\n onPress,\n onKeyDown,\n onKeyUp,\n role,\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 \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n tabIndex,\n as,\n src,\n alt,\n onError,\n onLoad,\n type,\n disabled,\n id,\n testID,\n \"data-testid\": dataTestId,\n ...props\n },\n ref\n ) => {\n // Handle as=\"img\" for rendering images with proper border-radius\n if (as === \"img\" && src) {\n return (\n <img\n src={src}\n alt={alt || \"\"}\n onError={onError}\n onLoad={onLoad}\n style={{\n display: \"block\",\n objectFit: \"cover\",\n width:\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width,\n height:\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height,\n borderRadius:\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius,\n position: props.position,\n top: typeof props.top === \"number\" ? `${props.top}px` : props.top,\n left:\n typeof props.left === \"number\" ? `${props.left}px` : props.left,\n right:\n typeof props.right === \"number\"\n ? `${props.right}px`\n : props.right,\n bottom:\n typeof props.bottom === \"number\"\n ? `${props.bottom}px`\n : props.bottom,\n ...props.style,\n }}\n />\n );\n }\n\n return (\n <StyledBox\n ref={ref}\n elementType={as}\n id={id}\n type={as === \"button\" ? type || \"button\" : undefined}\n disabled={as === \"button\" ? disabled : undefined}\n onClick={onPress}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-current={ariaCurrent}\n aria-disabled={ariaDisabled}\n aria-busy={ariaBusy}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n aria-live={ariaLive}\n tabIndex={tabIndex !== undefined ? tabIndex : undefined}\n data-testid={dataTestId || testID}\n {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport isPropValid from \"@emotion/is-prop-valid\";\n\n// Props that @emotion/is-prop-valid incorrectly treats as valid HTML.\n// These are React Native or component-specific props that match\n// valid HTML patterns (on* event handlers, SVG attributes).\nexport const ADDITIONAL_BLOCKED_PROPS = new Set([\n // RN-only event handlers (pass isPropValid's on* pattern)\n \"onPress\",\n \"onChangeText\",\n \"onLayout\",\n \"onMoveShouldSetResponder\",\n \"onResponderGrant\",\n \"onResponderMove\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n // SVG attributes that pass isPropValid\n \"strokeWidth\",\n // CSS properties that pass isPropValid but are used as component props\n \"overflow\",\n \"cursor\",\n \"fontSize\",\n \"fontWeight\",\n \"fontFamily\",\n \"textDecoration\",\n]);\n\nfunction shouldForwardProp(key: string): boolean {\n if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;\n return isPropValid(key);\n}\n\n/**\n * Creates a React component that renders the given HTML tag\n * but filters out non-HTML props before they reach the DOM.\n *\n * Uses @emotion/is-prop-valid (same library styled-components v4\n * uses internally) to automatically block invalid HTML attributes,\n * plus a small blocklist for false positives (RN on* handlers, SVG attrs).\n *\n * Usage: `const FilteredDiv = createFilteredElement(\"div\");`\n * Then: `const StyledBox = styled(FilteredDiv)<BoxProps>\\`...\\`;`\n *\n * styled-components can still read ALL props for CSS interpolation,\n * but only valid HTML attributes are forwarded to the DOM element.\n */\nexport function createFilteredElement(defaultTag: string) {\n const Component = React.forwardRef<HTMLElement, Record<string, unknown>>(\n ({ children, elementType, ...props }, ref) => {\n const Tag = (elementType as string) || defaultTag;\n const htmlProps: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (shouldForwardProp(key)) {\n htmlProps[key] = props[key];\n }\n }\n return React.createElement(\n Tag,\n { ref, ...htmlProps },\n children as React.ReactNode\n );\n }\n );\n Component.displayName = `Filtered(${defaultTag})`;\n return Component;\n}\n","function memoize(fn) {\n var cache = {};\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar index = memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default index;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredSpan = createFilteredElement(\"span\");\n\nconst StyledText = styled(FilteredSpan)<TextProps>`\n color: ${(props) => props.color || \"inherit\"};\n font-size: ${(props) =>\n typeof props.fontSize === \"number\"\n ? `${props.fontSize}px`\n : props.fontSize || \"inherit\"};\n font-weight: ${(props) => props.fontWeight || \"normal\"};\n font-family: ${(props) =>\n props.fontFamily ||\n '\"Aktiv Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif'};\n line-height: ${(props) =>\n typeof props.lineHeight === \"number\"\n ? `${props.lineHeight}px`\n : props.lineHeight || \"inherit\"};\n white-space: ${(props) => props.whiteSpace || \"normal\"};\n text-align: ${(props) => props.textAlign || \"inherit\"};\n text-decoration: ${(props) => props.textDecoration || \"none\"};\n`;\n\nexport const Text: React.FC<TextProps> = ({\n style,\n className,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\n data-testid={dataTestId || testID}\n />\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledIcon = styled(FilteredDiv)<IconProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n height: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n color: ${(props) => props.color || \"currentColor\"};\n\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: currentColor;\n }\n`;\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n testID,\n \"data-testid\": dataTestId,\n ...props\n}) => {\n return (\n <StyledIcon data-testid={dataTestId || testID} {...props}>\n {children}\n </StyledIcon>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","React","styled","React","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","FilteredDiv","styled","import_jsx_runtime","React","import_xui_core","import_jsx_runtime","index"]}
package/web/index.mjs CHANGED
@@ -329,6 +329,7 @@ var Avatar = ({
329
329
  size = "xl",
330
330
  square = false,
331
331
  tone = "mono",
332
+ stroke = true,
332
333
  badge = false,
333
334
  badgeCount,
334
335
  badgeIcon,
@@ -420,8 +421,8 @@ var Avatar = ({
420
421
  justifyContent: "center",
421
422
  position: "relative",
422
423
  overflow: "hidden",
423
- borderWidth: 2,
424
- borderColor: theme.colors.border.secondary,
424
+ borderWidth: stroke ? 2 : 0,
425
+ borderColor: stroke ? theme.colors.border.secondary : void 0,
425
426
  ...!disableHover && !useImage && {
426
427
  hoverStyle: {
427
428
  backgroundColor: toneHoverBackground
package/web/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Avatar.tsx","../../../../foundation/primitives-web/src/Box.tsx","../../../../foundation/primitives-web/src/filterDOMProps.ts","../../../../../node_modules/@emotion/memoize/dist/memoize.esm.js","../../../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js","../../../../foundation/primitives-web/src/Text.tsx","../../../../foundation/primitives-web/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={2}\n borderColor={theme.colors.border.secondary}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledBox = styled(FilteredDiv)<BoxProps>`\n display: flex;\n box-sizing: border-box;\n background-color: ${(props) => props.backgroundColor || \"transparent\"};\n border-color: ${(props) => props.borderColor || \"transparent\"};\n border-width: ${(props) =>\n typeof props.borderWidth === \"number\"\n ? `${props.borderWidth}px`\n : props.borderWidth || 0};\n\n ${(props) =>\n props.borderBottomWidth !== undefined &&\n `\n border-bottom-width: ${typeof props.borderBottomWidth === \"number\" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};\n border-bottom-color: ${props.borderBottomColor || props.borderColor || \"transparent\"};\n border-bottom-style: solid;\n `}\n ${(props) =>\n props.borderTopWidth !== undefined &&\n `\n border-top-width: ${typeof props.borderTopWidth === \"number\" ? `${props.borderTopWidth}px` : props.borderTopWidth};\n border-top-color: ${props.borderTopColor || props.borderColor || \"transparent\"};\n border-top-style: solid;\n `}\n ${(props) =>\n props.borderLeftWidth !== undefined &&\n `\n border-left-width: ${typeof props.borderLeftWidth === \"number\" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};\n border-left-color: ${props.borderLeftColor || props.borderColor || \"transparent\"};\n border-left-style: solid;\n `}\n ${(props) =>\n props.borderRightWidth !== undefined &&\n `\n border-right-width: ${typeof props.borderRightWidth === \"number\" ? `${props.borderRightWidth}px` : props.borderRightWidth};\n border-right-color: ${props.borderRightColor || props.borderColor || \"transparent\"};\n border-right-style: solid;\n `}\n\n border-style: ${(props) =>\n props.borderStyle ||\n (props.borderWidth ||\n props.borderBottomWidth ||\n props.borderTopWidth ||\n props.borderLeftWidth ||\n props.borderRightWidth\n ? \"solid\"\n : \"none\")};\n border-radius: ${(props) =>\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius || 0};\n height: ${(props) =>\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height || \"auto\"};\n width: ${(props) =>\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width || \"auto\"};\n min-width: ${(props) =>\n typeof props.minWidth === \"number\"\n ? `${props.minWidth}px`\n : props.minWidth || \"auto\"};\n min-height: ${(props) =>\n typeof props.minHeight === \"number\"\n ? `${props.minHeight}px`\n : props.minHeight || \"auto\"};\n max-width: ${(props) =>\n typeof props.maxWidth === \"number\"\n ? `${props.maxWidth}px`\n : props.maxWidth || \"none\"};\n max-height: ${(props) =>\n typeof props.maxHeight === \"number\"\n ? `${props.maxHeight}px`\n : props.maxHeight || \"none\"};\n\n padding: ${(props) =>\n typeof props.padding === \"number\"\n ? `${props.padding}px`\n : props.padding || 0};\n ${(props) =>\n props.paddingHorizontal &&\n `\n padding-left: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n padding-right: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n `}\n ${(props) =>\n props.paddingVertical &&\n `\n padding-top: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n padding-bottom: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n `}\n ${(props) =>\n props.paddingTop !== undefined &&\n `padding-top: ${typeof props.paddingTop === \"number\" ? `${props.paddingTop}px` : props.paddingTop};`}\n ${(props) =>\n props.paddingBottom !== undefined &&\n `padding-bottom: ${typeof props.paddingBottom === \"number\" ? `${props.paddingBottom}px` : props.paddingBottom};`}\n ${(props) =>\n props.paddingLeft !== undefined &&\n `padding-left: ${typeof props.paddingLeft === \"number\" ? `${props.paddingLeft}px` : props.paddingLeft};`}\n ${(props) =>\n props.paddingRight !== undefined &&\n `padding-right: ${typeof props.paddingRight === \"number\" ? `${props.paddingRight}px` : props.paddingRight};`}\n\n margin: ${(props) =>\n typeof props.margin === \"number\" ? `${props.margin}px` : props.margin || 0};\n ${(props) =>\n props.marginTop !== undefined &&\n `margin-top: ${typeof props.marginTop === \"number\" ? `${props.marginTop}px` : props.marginTop};`}\n ${(props) =>\n props.marginBottom !== undefined &&\n `margin-bottom: ${typeof props.marginBottom === \"number\" ? `${props.marginBottom}px` : props.marginBottom};`}\n ${(props) =>\n props.marginLeft !== undefined &&\n `margin-left: ${typeof props.marginLeft === \"number\" ? `${props.marginLeft}px` : props.marginLeft};`}\n ${(props) =>\n props.marginRight !== undefined &&\n `margin-right: ${typeof props.marginRight === \"number\" ? `${props.marginRight}px` : props.marginRight};`}\n\n flex-direction: ${(props) => props.flexDirection || \"column\"};\n flex-wrap: ${(props) => props.flexWrap || \"nowrap\"};\n align-items: ${(props) => props.alignItems || \"stretch\"};\n justify-content: ${(props) => props.justifyContent || \"flex-start\"};\n cursor: ${(props) =>\n props.cursor\n ? props.cursor\n : props.onClick || props.onPress\n ? \"pointer\"\n : \"inherit\"};\n position: ${(props) => props.position || \"static\"};\n top: ${(props) =>\n typeof props.top === \"number\" ? `${props.top}px` : props.top};\n bottom: ${(props) =>\n typeof props.bottom === \"number\" ? `${props.bottom}px` : props.bottom};\n left: ${(props) =>\n typeof props.left === \"number\" ? `${props.left}px` : props.left};\n right: ${(props) =>\n typeof props.right === \"number\" ? `${props.right}px` : props.right};\n flex: ${(props) => props.flex};\n flex-shrink: ${(props) => props.flexShrink ?? 1};\n gap: ${(props) =>\n typeof props.gap === \"number\" ? `${props.gap}px` : props.gap || 0};\n align-self: ${(props) => props.alignSelf || \"auto\"};\n overflow: ${(props) => props.overflow || \"visible\"};\n overflow-x: ${(props) => props.overflowX || \"visible\"};\n overflow-y: ${(props) => props.overflowY || \"visible\"};\n z-index: ${(props) => props.zIndex};\n opacity: ${(props) => (props.disabled ? 0.5 : 1)};\n pointer-events: ${(props) => (props.disabled ? \"none\" : \"auto\")};\n\n &:hover {\n ${(props) =>\n props.hoverStyle?.backgroundColor &&\n `background-color: ${props.hoverStyle.backgroundColor};`}\n ${(props) =>\n props.hoverStyle?.borderColor &&\n `border-color: ${props.hoverStyle.borderColor};`}\n }\n\n &:active {\n ${(props) =>\n props.pressStyle?.backgroundColor &&\n `background-color: ${props.pressStyle.backgroundColor};`}\n }\n`;\n\nexport const Box = React.forwardRef<\n HTMLDivElement | HTMLButtonElement,\n BoxProps\n>(\n (\n {\n children,\n onPress,\n onKeyDown,\n onKeyUp,\n role,\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 \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n tabIndex,\n as,\n src,\n alt,\n onError,\n onLoad,\n type,\n disabled,\n id,\n testID,\n \"data-testid\": dataTestId,\n ...props\n },\n ref\n ) => {\n // Handle as=\"img\" for rendering images with proper border-radius\n if (as === \"img\" && src) {\n return (\n <img\n src={src}\n alt={alt || \"\"}\n onError={onError}\n onLoad={onLoad}\n style={{\n display: \"block\",\n objectFit: \"cover\",\n width:\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width,\n height:\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height,\n borderRadius:\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius,\n position: props.position,\n top: typeof props.top === \"number\" ? `${props.top}px` : props.top,\n left:\n typeof props.left === \"number\" ? `${props.left}px` : props.left,\n right:\n typeof props.right === \"number\"\n ? `${props.right}px`\n : props.right,\n bottom:\n typeof props.bottom === \"number\"\n ? `${props.bottom}px`\n : props.bottom,\n ...props.style,\n }}\n />\n );\n }\n\n return (\n <StyledBox\n ref={ref}\n elementType={as}\n id={id}\n type={as === \"button\" ? type || \"button\" : undefined}\n disabled={as === \"button\" ? disabled : undefined}\n onClick={onPress}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-current={ariaCurrent}\n aria-disabled={ariaDisabled}\n aria-busy={ariaBusy}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n aria-live={ariaLive}\n tabIndex={tabIndex !== undefined ? tabIndex : undefined}\n data-testid={dataTestId || testID}\n {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport isPropValid from \"@emotion/is-prop-valid\";\n\n// Props that @emotion/is-prop-valid incorrectly treats as valid HTML.\n// These are React Native or component-specific props that match\n// valid HTML patterns (on* event handlers, SVG attributes).\nexport const ADDITIONAL_BLOCKED_PROPS = new Set([\n // RN-only event handlers (pass isPropValid's on* pattern)\n \"onPress\",\n \"onChangeText\",\n \"onLayout\",\n \"onMoveShouldSetResponder\",\n \"onResponderGrant\",\n \"onResponderMove\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n // SVG attributes that pass isPropValid\n \"strokeWidth\",\n // CSS properties that pass isPropValid but are used as component props\n \"overflow\",\n \"cursor\",\n \"fontSize\",\n \"fontWeight\",\n \"fontFamily\",\n \"textDecoration\",\n]);\n\nfunction shouldForwardProp(key: string): boolean {\n if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;\n return isPropValid(key);\n}\n\n/**\n * Creates a React component that renders the given HTML tag\n * but filters out non-HTML props before they reach the DOM.\n *\n * Uses @emotion/is-prop-valid (same library styled-components v4\n * uses internally) to automatically block invalid HTML attributes,\n * plus a small blocklist for false positives (RN on* handlers, SVG attrs).\n *\n * Usage: `const FilteredDiv = createFilteredElement(\"div\");`\n * Then: `const StyledBox = styled(FilteredDiv)<BoxProps>\\`...\\`;`\n *\n * styled-components can still read ALL props for CSS interpolation,\n * but only valid HTML attributes are forwarded to the DOM element.\n */\nexport function createFilteredElement(defaultTag: string) {\n const Component = React.forwardRef<HTMLElement, Record<string, unknown>>(\n ({ children, elementType, ...props }, ref) => {\n const Tag = (elementType as string) || defaultTag;\n const htmlProps: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (shouldForwardProp(key)) {\n htmlProps[key] = props[key];\n }\n }\n return React.createElement(\n Tag,\n { ref, ...htmlProps },\n children as React.ReactNode\n );\n }\n );\n Component.displayName = `Filtered(${defaultTag})`;\n return Component;\n}\n","function memoize(fn) {\n var cache = {};\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar index = memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default index;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredSpan = createFilteredElement(\"span\");\n\nconst StyledText = styled(FilteredSpan)<TextProps>`\n color: ${(props) => props.color || \"inherit\"};\n font-size: ${(props) =>\n typeof props.fontSize === \"number\"\n ? `${props.fontSize}px`\n : props.fontSize || \"inherit\"};\n font-weight: ${(props) => props.fontWeight || \"normal\"};\n font-family: ${(props) =>\n props.fontFamily ||\n '\"Aktiv Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif'};\n line-height: ${(props) =>\n typeof props.lineHeight === \"number\"\n ? `${props.lineHeight}px`\n : props.lineHeight || \"inherit\"};\n white-space: ${(props) => props.whiteSpace || \"normal\"};\n text-align: ${(props) => props.textAlign || \"inherit\"};\n text-decoration: ${(props) => props.textDecoration || \"none\"};\n`;\n\nexport const Text: React.FC<TextProps> = ({\n style,\n className,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\n data-testid={dataTestId || testID}\n />\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledIcon = styled(FilteredDiv)<IconProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n height: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n color: ${(props) => props.color || \"currentColor\"};\n\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: currentColor;\n }\n`;\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n testID,\n \"data-testid\": dataTestId,\n ...props\n}) => {\n return (\n <StyledIcon data-testid={dataTestId || testID} {...props}>\n {children}\n </StyledIcon>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["React","React","React","styled","jsx","styled","styled","jsx","FilteredDiv","styled","jsx","React","useResolvedTheme","jsx","jsxs","useResolvedTheme","index"]}
1
+ {"version":3,"sources":["../../src/Avatar.tsx","../../../../foundation/primitives-web/src/Box.tsx","../../../../foundation/primitives-web/src/filterDOMProps.ts","../../../../../node_modules/@emotion/memoize/dist/memoize.esm.js","../../../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js","../../../../foundation/primitives-web/src/Text.tsx","../../../../foundation/primitives-web/src/Icon.tsx","../../src/AvatarGroup.tsx"],"sourcesContent":["import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport { User } from \"@xsolla/xui-icons-base\";\n\nexport interface AvatarProps extends ThemeOverrideProps {\n /** Image source URL */\n src?: string;\n /** Icon component to display when no image is provided */\n icon?: React.ReactNode;\n /** Text/Initials to display when no image or icon is provided */\n text?: string;\n /** Size of the avatar */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\" | \"xxs\";\n /** If true, the avatar will be square with small border radius. If false, it will be a circle. */\n square?: boolean;\n /** Visual tone — 'mono' (default) or 'brand'. */\n tone?: \"mono\" | \"brand\";\n /**\n * Whether to render the avatar's outer border (stroke). Defaults to `true`,\n * preserving the existing bordered look. Set to `false` to remove the border\n * entirely — useful on surfaces that already provide separation, or in dense\n * layouts where the border adds visual noise.\n */\n stroke?: boolean;\n /** Whether to show an alert badge */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /**\n * Background colour override. Intended for internal use by AvatarGroup to\n * drive its `avatarBackgroundMode` cycling; not part of the public API.\n * @internal\n */\n backgroundColor?: string;\n /** Disable hover effect. Used internally by AvatarGroup. */\n disableHover?: boolean;\n /** Accessible label for the avatar. Recommended for screen readers. */\n \"aria-label\"?: string;\n /** Alternative text for the avatar image */\n alt?: string;\n /** Click handler for the avatar */\n onClick?: () => void;\n /** Color tone for the badge */\n badgeTone?:\n | \"primary\"\n | \"secondary\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\";\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Avatar: React.FC<AvatarProps> = ({\n src,\n icon,\n text,\n size = \"xl\",\n square = false,\n tone = \"mono\",\n stroke = true,\n badge = false,\n badgeCount,\n badgeIcon,\n badgeTone = \"alert\",\n backgroundColor,\n disableHover = true,\n \"aria-label\": ariaLabel,\n alt,\n onClick,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [hasImageError, setHasImageError] = React.useState(false);\n\n React.useEffect(() => {\n setHasImageError(false);\n }, [src]);\n\n const useImage = !!src && !hasImageError;\n\n const sizeStyles = theme.sizing.avatar(size);\n\n const toneBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.primary\n : theme.colors.overlay.mono;\n const toneHoverBackground =\n tone === \"brand\"\n ? theme.colors.background.brand.secondary\n : theme.colors.overlay.monoHover;\n const toneContent =\n tone === \"brand\"\n ? theme.colors.content.on.brand\n : theme.colors.content.primary;\n\n // Border radius based on square or circle variant\n const borderRadius = square\n ? sizeStyles.borderRadiusSquare\n : sizeStyles.borderRadiusCircle;\n\n const countSizeMap = {\n xl: \"xl\",\n lg: \"xl\",\n md: \"lg\",\n sm: \"lg\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const dotSizeMap = {\n xl: \"md\",\n lg: \"md\",\n md: \"sm\",\n sm: \"sm\",\n xs: \"sm\",\n xxs: \"xs\",\n } as const;\n const hasBadgeContent = !!(badgeCount || badgeIcon);\n const badgeSize = hasBadgeContent ? countSizeMap[size] : dotSizeMap[size];\n // Badge sizes sm/xs are dot-only — content is dropped, so position as a dot.\n const rendersAsDot = badgeSize === \"sm\" || badgeSize === \"xs\";\n\n // Badge offset differs for circle vs square, and for dot vs count\n // Dot badge (8px) needs different offset per avatar size\n const getDotOffset = () => {\n if (square) {\n return size === \"xxs\" ? { right: -1, top: -1 } : { right: -3, top: -3 };\n }\n // Circle - position dot on the edge based on avatar size\n const circleOffsets = {\n xl: { right: 2, top: 2 },\n lg: { right: 2, top: 2 },\n md: { right: 2, top: 2 },\n sm: { right: 2, top: 2 },\n xs: { right: 0, top: 0 },\n xxs: { right: 1, top: 1 },\n };\n return circleOffsets[size];\n };\n\n const badgeOffset =\n hasBadgeContent && !rendersAsDot\n ? square\n ? sizeStyles.badgeOffsetSquare\n : sizeStyles.badgeOffsetCircle\n : getDotOffset();\n\n // Display badge count\n const displayBadgeCount = badgeCount;\n\n return (\n <Box\n testID={testID}\n width={sizeStyles.size}\n height={sizeStyles.size}\n position=\"relative\"\n {...(!useImage && { role: \"img\", \"aria-label\": ariaLabel })}\n {...(onClick && {\n onPress: onClick,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n },\n cursor: \"pointer\",\n role: \"button\",\n tabIndex: 0,\n })}\n >\n <Box\n width={sizeStyles.size}\n height={sizeStyles.size}\n borderRadius={borderRadius}\n backgroundColor={backgroundColor || toneBackground}\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n overflow=\"hidden\"\n borderWidth={stroke ? 2 : 0}\n borderColor={stroke ? theme.colors.border.secondary : undefined}\n {...(!disableHover &&\n !useImage && {\n hoverStyle: {\n backgroundColor: toneHoverBackground,\n },\n })}\n >\n {useImage ? (\n <Box\n as=\"img\"\n src={src}\n alt={alt || ariaLabel || \"\"}\n position=\"absolute\"\n top={0}\n left={0}\n width=\"100%\"\n height=\"100%\"\n borderRadius={borderRadius}\n onError={() => setHasImageError(true)}\n />\n ) : icon ? (\n <Icon size={sizeStyles.iconSize} color={toneContent}>\n {icon}\n </Icon>\n ) : text ? (\n <Text\n fontSize={sizeStyles.fontSize}\n color={toneContent}\n fontWeight=\"400\"\n letterSpacing={0.4}\n >\n {text}\n </Text>\n ) : (\n <User\n variant=\"solid\"\n size={sizeStyles.iconSize}\n color={toneContent}\n />\n )}\n </Box>\n\n {badge && (\n <Box\n position=\"absolute\"\n right={badgeOffset.right}\n top={badgeOffset.top}\n >\n <Badge\n size={badgeSize}\n tone={badgeTone}\n icon={badgeIcon}\n showStroke={size !== \"xxs\"}\n aria-label={\n displayBadgeCount\n ? `${displayBadgeCount} notifications`\n : \"Notification\"\n }\n >\n {displayBadgeCount}\n </Badge>\n </Box>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledBox = styled(FilteredDiv)<BoxProps>`\n display: flex;\n box-sizing: border-box;\n background-color: ${(props) => props.backgroundColor || \"transparent\"};\n border-color: ${(props) => props.borderColor || \"transparent\"};\n border-width: ${(props) =>\n typeof props.borderWidth === \"number\"\n ? `${props.borderWidth}px`\n : props.borderWidth || 0};\n\n ${(props) =>\n props.borderBottomWidth !== undefined &&\n `\n border-bottom-width: ${typeof props.borderBottomWidth === \"number\" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};\n border-bottom-color: ${props.borderBottomColor || props.borderColor || \"transparent\"};\n border-bottom-style: solid;\n `}\n ${(props) =>\n props.borderTopWidth !== undefined &&\n `\n border-top-width: ${typeof props.borderTopWidth === \"number\" ? `${props.borderTopWidth}px` : props.borderTopWidth};\n border-top-color: ${props.borderTopColor || props.borderColor || \"transparent\"};\n border-top-style: solid;\n `}\n ${(props) =>\n props.borderLeftWidth !== undefined &&\n `\n border-left-width: ${typeof props.borderLeftWidth === \"number\" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};\n border-left-color: ${props.borderLeftColor || props.borderColor || \"transparent\"};\n border-left-style: solid;\n `}\n ${(props) =>\n props.borderRightWidth !== undefined &&\n `\n border-right-width: ${typeof props.borderRightWidth === \"number\" ? `${props.borderRightWidth}px` : props.borderRightWidth};\n border-right-color: ${props.borderRightColor || props.borderColor || \"transparent\"};\n border-right-style: solid;\n `}\n\n border-style: ${(props) =>\n props.borderStyle ||\n (props.borderWidth ||\n props.borderBottomWidth ||\n props.borderTopWidth ||\n props.borderLeftWidth ||\n props.borderRightWidth\n ? \"solid\"\n : \"none\")};\n border-radius: ${(props) =>\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius || 0};\n height: ${(props) =>\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height || \"auto\"};\n width: ${(props) =>\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width || \"auto\"};\n min-width: ${(props) =>\n typeof props.minWidth === \"number\"\n ? `${props.minWidth}px`\n : props.minWidth || \"auto\"};\n min-height: ${(props) =>\n typeof props.minHeight === \"number\"\n ? `${props.minHeight}px`\n : props.minHeight || \"auto\"};\n max-width: ${(props) =>\n typeof props.maxWidth === \"number\"\n ? `${props.maxWidth}px`\n : props.maxWidth || \"none\"};\n max-height: ${(props) =>\n typeof props.maxHeight === \"number\"\n ? `${props.maxHeight}px`\n : props.maxHeight || \"none\"};\n\n padding: ${(props) =>\n typeof props.padding === \"number\"\n ? `${props.padding}px`\n : props.padding || 0};\n ${(props) =>\n props.paddingHorizontal &&\n `\n padding-left: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n padding-right: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n `}\n ${(props) =>\n props.paddingVertical &&\n `\n padding-top: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n padding-bottom: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n `}\n ${(props) =>\n props.paddingTop !== undefined &&\n `padding-top: ${typeof props.paddingTop === \"number\" ? `${props.paddingTop}px` : props.paddingTop};`}\n ${(props) =>\n props.paddingBottom !== undefined &&\n `padding-bottom: ${typeof props.paddingBottom === \"number\" ? `${props.paddingBottom}px` : props.paddingBottom};`}\n ${(props) =>\n props.paddingLeft !== undefined &&\n `padding-left: ${typeof props.paddingLeft === \"number\" ? `${props.paddingLeft}px` : props.paddingLeft};`}\n ${(props) =>\n props.paddingRight !== undefined &&\n `padding-right: ${typeof props.paddingRight === \"number\" ? `${props.paddingRight}px` : props.paddingRight};`}\n\n margin: ${(props) =>\n typeof props.margin === \"number\" ? `${props.margin}px` : props.margin || 0};\n ${(props) =>\n props.marginTop !== undefined &&\n `margin-top: ${typeof props.marginTop === \"number\" ? `${props.marginTop}px` : props.marginTop};`}\n ${(props) =>\n props.marginBottom !== undefined &&\n `margin-bottom: ${typeof props.marginBottom === \"number\" ? `${props.marginBottom}px` : props.marginBottom};`}\n ${(props) =>\n props.marginLeft !== undefined &&\n `margin-left: ${typeof props.marginLeft === \"number\" ? `${props.marginLeft}px` : props.marginLeft};`}\n ${(props) =>\n props.marginRight !== undefined &&\n `margin-right: ${typeof props.marginRight === \"number\" ? `${props.marginRight}px` : props.marginRight};`}\n\n flex-direction: ${(props) => props.flexDirection || \"column\"};\n flex-wrap: ${(props) => props.flexWrap || \"nowrap\"};\n align-items: ${(props) => props.alignItems || \"stretch\"};\n justify-content: ${(props) => props.justifyContent || \"flex-start\"};\n cursor: ${(props) =>\n props.cursor\n ? props.cursor\n : props.onClick || props.onPress\n ? \"pointer\"\n : \"inherit\"};\n position: ${(props) => props.position || \"static\"};\n top: ${(props) =>\n typeof props.top === \"number\" ? `${props.top}px` : props.top};\n bottom: ${(props) =>\n typeof props.bottom === \"number\" ? `${props.bottom}px` : props.bottom};\n left: ${(props) =>\n typeof props.left === \"number\" ? `${props.left}px` : props.left};\n right: ${(props) =>\n typeof props.right === \"number\" ? `${props.right}px` : props.right};\n flex: ${(props) => props.flex};\n flex-shrink: ${(props) => props.flexShrink ?? 1};\n gap: ${(props) =>\n typeof props.gap === \"number\" ? `${props.gap}px` : props.gap || 0};\n align-self: ${(props) => props.alignSelf || \"auto\"};\n overflow: ${(props) => props.overflow || \"visible\"};\n overflow-x: ${(props) => props.overflowX || \"visible\"};\n overflow-y: ${(props) => props.overflowY || \"visible\"};\n z-index: ${(props) => props.zIndex};\n opacity: ${(props) => (props.disabled ? 0.5 : 1)};\n pointer-events: ${(props) => (props.disabled ? \"none\" : \"auto\")};\n\n &:hover {\n ${(props) =>\n props.hoverStyle?.backgroundColor &&\n `background-color: ${props.hoverStyle.backgroundColor};`}\n ${(props) =>\n props.hoverStyle?.borderColor &&\n `border-color: ${props.hoverStyle.borderColor};`}\n }\n\n &:active {\n ${(props) =>\n props.pressStyle?.backgroundColor &&\n `background-color: ${props.pressStyle.backgroundColor};`}\n }\n`;\n\nexport const Box = React.forwardRef<\n HTMLDivElement | HTMLButtonElement,\n BoxProps\n>(\n (\n {\n children,\n onPress,\n onKeyDown,\n onKeyUp,\n role,\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 \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n tabIndex,\n as,\n src,\n alt,\n onError,\n onLoad,\n type,\n disabled,\n id,\n testID,\n \"data-testid\": dataTestId,\n ...props\n },\n ref\n ) => {\n // Handle as=\"img\" for rendering images with proper border-radius\n if (as === \"img\" && src) {\n return (\n <img\n src={src}\n alt={alt || \"\"}\n onError={onError}\n onLoad={onLoad}\n style={{\n display: \"block\",\n objectFit: \"cover\",\n width:\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width,\n height:\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height,\n borderRadius:\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius,\n position: props.position,\n top: typeof props.top === \"number\" ? `${props.top}px` : props.top,\n left:\n typeof props.left === \"number\" ? `${props.left}px` : props.left,\n right:\n typeof props.right === \"number\"\n ? `${props.right}px`\n : props.right,\n bottom:\n typeof props.bottom === \"number\"\n ? `${props.bottom}px`\n : props.bottom,\n ...props.style,\n }}\n />\n );\n }\n\n return (\n <StyledBox\n ref={ref}\n elementType={as}\n id={id}\n type={as === \"button\" ? type || \"button\" : undefined}\n disabled={as === \"button\" ? disabled : undefined}\n onClick={onPress}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-current={ariaCurrent}\n aria-disabled={ariaDisabled}\n aria-busy={ariaBusy}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n aria-live={ariaLive}\n tabIndex={tabIndex !== undefined ? tabIndex : undefined}\n data-testid={dataTestId || testID}\n {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport isPropValid from \"@emotion/is-prop-valid\";\n\n// Props that @emotion/is-prop-valid incorrectly treats as valid HTML.\n// These are React Native or component-specific props that match\n// valid HTML patterns (on* event handlers, SVG attributes).\nexport const ADDITIONAL_BLOCKED_PROPS = new Set([\n // RN-only event handlers (pass isPropValid's on* pattern)\n \"onPress\",\n \"onChangeText\",\n \"onLayout\",\n \"onMoveShouldSetResponder\",\n \"onResponderGrant\",\n \"onResponderMove\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n // SVG attributes that pass isPropValid\n \"strokeWidth\",\n // CSS properties that pass isPropValid but are used as component props\n \"overflow\",\n \"cursor\",\n \"fontSize\",\n \"fontWeight\",\n \"fontFamily\",\n \"textDecoration\",\n]);\n\nfunction shouldForwardProp(key: string): boolean {\n if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;\n return isPropValid(key);\n}\n\n/**\n * Creates a React component that renders the given HTML tag\n * but filters out non-HTML props before they reach the DOM.\n *\n * Uses @emotion/is-prop-valid (same library styled-components v4\n * uses internally) to automatically block invalid HTML attributes,\n * plus a small blocklist for false positives (RN on* handlers, SVG attrs).\n *\n * Usage: `const FilteredDiv = createFilteredElement(\"div\");`\n * Then: `const StyledBox = styled(FilteredDiv)<BoxProps>\\`...\\`;`\n *\n * styled-components can still read ALL props for CSS interpolation,\n * but only valid HTML attributes are forwarded to the DOM element.\n */\nexport function createFilteredElement(defaultTag: string) {\n const Component = React.forwardRef<HTMLElement, Record<string, unknown>>(\n ({ children, elementType, ...props }, ref) => {\n const Tag = (elementType as string) || defaultTag;\n const htmlProps: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (shouldForwardProp(key)) {\n htmlProps[key] = props[key];\n }\n }\n return React.createElement(\n Tag,\n { ref, ...htmlProps },\n children as React.ReactNode\n );\n }\n );\n Component.displayName = `Filtered(${defaultTag})`;\n return Component;\n}\n","function memoize(fn) {\n var cache = {};\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar index = memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default index;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredSpan = createFilteredElement(\"span\");\n\nconst StyledText = styled(FilteredSpan)<TextProps>`\n color: ${(props) => props.color || \"inherit\"};\n font-size: ${(props) =>\n typeof props.fontSize === \"number\"\n ? `${props.fontSize}px`\n : props.fontSize || \"inherit\"};\n font-weight: ${(props) => props.fontWeight || \"normal\"};\n font-family: ${(props) =>\n props.fontFamily ||\n '\"Aktiv Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif'};\n line-height: ${(props) =>\n typeof props.lineHeight === \"number\"\n ? `${props.lineHeight}px`\n : props.lineHeight || \"inherit\"};\n white-space: ${(props) => props.whiteSpace || \"normal\"};\n text-align: ${(props) => props.textAlign || \"inherit\"};\n text-decoration: ${(props) => props.textDecoration || \"none\"};\n`;\n\nexport const Text: React.FC<TextProps> = ({\n style,\n className,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\n data-testid={dataTestId || testID}\n />\n );\n};\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledIcon = styled(FilteredDiv)<IconProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n height: ${(props) =>\n typeof props.size === \"number\" ? `${props.size}px` : props.size || \"24px\"};\n color: ${(props) => props.color || \"currentColor\"};\n\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: currentColor;\n }\n`;\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n testID,\n \"data-testid\": dataTestId,\n ...props\n}) => {\n return (\n <StyledIcon data-testid={dataTestId || testID} {...props}>\n {children}\n </StyledIcon>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Tooltip } from \"@xsolla/xui-tooltip\";\nimport { Avatar, AvatarProps } from \"./Avatar\";\n\n/** Theme type from the design system */\ntype Theme = ReturnType<typeof useResolvedTheme>[\"theme\"];\n\n/** Item in the avatar group list */\nexport interface AvatarGroupItem {\n /** Image source URL */\n src?: string;\n /** Initials to display when no image is provided */\n initials?: string;\n /** Tooltip text to display on hover */\n tooltip?: string;\n /** Whether to show a badge on the avatar */\n badge?: boolean;\n /** Number or text to display in the badge notification */\n badgeCount?: React.ReactNode;\n /** Icon to display in the badge */\n badgeIcon?: React.ReactNode;\n /** Color tone for the badge */\n badgeTone?: AvatarProps[\"badgeTone\"];\n}\n\n/** Avatar background mode - preset colors, 'mixed' for cycling, or a theme function */\nexport type AvatarBackgroundMode =\n | \"mixed\"\n | \"brand\"\n | \"brandExtra\"\n | \"success\"\n | \"warning\"\n | \"alert\"\n | \"neutral\"\n | ((theme: Theme) => string);\n\nexport interface AvatarGroupProps extends ThemeOverrideProps {\n /**\n * List of avatars to display in the group.\n * `tooltip` property is text to be displayed in the tooltip when hovering over the avatar.\n */\n list: AvatarGroupItem[];\n /** Size of the avatars in the group */\n size?: \"xxs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Maximum number of slots rendered, including the \"+N\" overflow counter.\n * When the list exceeds this, (maxVisible - 1) avatars are shown plus a \"+N\" indicator.\n * When the list fits, all avatars are shown and no \"+N\" is rendered.\n */\n maxVisible?: number;\n /**\n * Controls the background color mode for avatars in the group.\n * - 'mixed' (default): Avatars cycle through different colors\n * - 'brand', 'brandExtra', 'success', 'warning', 'alert', 'neutral': Single color for all avatars\n * - Theme function: A function that receives theme and returns any color from the design system.\n * Example: (theme) => theme.colors.core.link.link\n */\n avatarBackgroundMode?: AvatarBackgroundMode;\n /** Accessible label for the avatar group. Defaults to \"Group of X users\". */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nconst DEFAULT_MAX_VISIBLE = 6;\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({\n list,\n size = \"sm\",\n maxVisible = DEFAULT_MAX_VISIBLE,\n avatarBackgroundMode = \"mixed\",\n \"aria-label\": ariaLabel,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n if (maxVisible < 1) {\n console.warn(\n `[AvatarGroup] \"maxVisible\" must be a positive number. Received ${maxVisible}, falling back to default (${DEFAULT_MAX_VISIBLE}).`\n );\n }\n const effectiveMaxVisible = maxVisible < 1 ? DEFAULT_MAX_VISIBLE : maxVisible;\n\n const totalCount = list.length;\n const overflows = totalCount > effectiveMaxVisible;\n const visibleCount = overflows ? effectiveMaxVisible - 1 : totalCount;\n const visibleListItems = list.slice(0, visibleCount);\n const remainingCount = totalCount - visibleCount;\n\n // Overlap amount: 4px in Figma\n const overlap = -4;\n\n // Background colors for text/icon avatars (cycling through theme colors)\n const mixedBackgrounds = [\n theme.colors.background.alert.secondary,\n theme.colors.background.warning.secondary,\n theme.colors.background.brandExtra.secondary,\n theme.colors.background.neutral.secondary,\n theme.colors.background.brand.secondary,\n theme.colors.background.success.secondary,\n theme.colors.background.success.primary,\n ];\n\n // Preset color mapping\n const presetColors: Record<string, string> = {\n brand: theme.colors.background.brand.secondary,\n brandExtra: theme.colors.background.brandExtra.secondary,\n success: theme.colors.background.success.secondary,\n warning: theme.colors.background.warning.secondary,\n alert: theme.colors.background.alert.secondary,\n neutral: theme.colors.background.neutral.secondary,\n };\n\n // Get background color based on avatarBackgroundMode\n const getBackgroundColor = (index: number): string => {\n if (typeof avatarBackgroundMode === \"function\") {\n return avatarBackgroundMode(theme);\n }\n if (avatarBackgroundMode === \"mixed\") {\n return mixedBackgrounds[index % mixedBackgrounds.length];\n }\n // Preset color mode\n return (\n presetColors[avatarBackgroundMode] || theme.colors.background.secondary\n );\n };\n\n // Default accessible label for the group\n const defaultAriaLabel =\n totalCount === 1\n ? \"1 user\"\n : totalCount === visibleCount\n ? `${totalCount} users`\n : `${visibleCount} of ${totalCount} users`;\n\n // Render an avatar with optional tooltip wrapper\n const renderAvatarWithTooltip = (\n avatar: React.ReactNode,\n tooltip: string | undefined,\n key: number\n ) => {\n if (tooltip) {\n return (\n <Tooltip key={key} content={tooltip} placement=\"top\">\n {avatar}\n </Tooltip>\n );\n }\n return avatar;\n };\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"center\"\n role=\"group\"\n aria-label={ariaLabel || defaultAriaLabel}\n >\n {visibleListItems.map((item, index) => {\n const shouldApplyBackground = !item.src;\n const backgroundColor = shouldApplyBackground\n ? getBackgroundColor(index)\n : undefined;\n\n const avatar = (\n <Box\n key={index}\n marginLeft={index === 0 ? 0 : overlap}\n zIndex={totalCount - index}\n >\n <Avatar\n src={item.src}\n text={item.initials}\n size={size}\n backgroundColor={backgroundColor}\n disableHover={true}\n badge={item.badge}\n badgeCount={item.badgeCount}\n badgeIcon={item.badgeIcon}\n badgeTone={item.badgeTone}\n {...(item.tooltip ? { \"aria-label\": item.tooltip } : {})}\n />\n </Box>\n );\n\n return renderAvatarWithTooltip(avatar, item.tooltip, index);\n })}\n\n {remainingCount > 0 && (\n <Box marginLeft={overlap} zIndex={0}>\n <Avatar\n size={size}\n text={remainingCount > 99 ? \"99+\" : `+${remainingCount}`}\n backgroundColor={theme.colors.background.secondary}\n disableHover={true}\n aria-label={`${remainingCount} more ${remainingCount === 1 ? \"user\" : \"users\"}`}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["React","React","React","styled","jsx","styled","styled","jsx","FilteredDiv","styled","jsx","React","useResolvedTheme","jsx","jsxs","useResolvedTheme","index"]}