@xsolla/xui-b2c-side-navigation 0.158.0 → 0.159.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.
@@ -30,6 +30,8 @@ interface SideNavigationItemProps extends ThemeOverrideProps {
30
30
  isActive?: boolean;
31
31
  onItemClick?: (item: SideNavigationItemData) => void;
32
32
  linkComponent?: React.ComponentType<SideNavigationLinkProps>;
33
+ /** Test ID for testing frameworks */
34
+ testID?: string;
33
35
  }
34
36
  interface SideNavigationProps extends ThemeOverrideProps {
35
37
  mode?: SideNavigationMode;
package/native/index.d.ts CHANGED
@@ -30,6 +30,8 @@ interface SideNavigationItemProps extends ThemeOverrideProps {
30
30
  isActive?: boolean;
31
31
  onItemClick?: (item: SideNavigationItemData) => void;
32
32
  linkComponent?: React.ComponentType<SideNavigationLinkProps>;
33
+ /** Test ID for testing frameworks */
34
+ testID?: string;
33
35
  }
34
36
  interface SideNavigationProps extends ThemeOverrideProps {
35
37
  mode?: SideNavigationMode;
package/native/index.js CHANGED
@@ -236,6 +236,8 @@ var Text = ({
236
236
  numberOfLines,
237
237
  id,
238
238
  role,
239
+ testID,
240
+ "data-testid": dataTestId,
239
241
  style: styleProp,
240
242
  ...props
241
243
  }) => {
@@ -265,7 +267,7 @@ var Text = ({
265
267
  {
266
268
  style: baseStyle,
267
269
  numberOfLines,
268
- testID: id,
270
+ testID: dataTestId || testID || id,
269
271
  accessibilityRole,
270
272
  children
271
273
  }
@@ -327,6 +329,7 @@ var SideNavigationItem = ({
327
329
  isActive,
328
330
  onItemClick,
329
331
  linkComponent: LinkComponent,
332
+ testID,
330
333
  themeMode,
331
334
  themeProductContext = "b2c"
332
335
  }) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/SideNavigationItem.tsx","../../src/SideNavigation.tsx"],"sourcesContent":["export { SideNavigation } from \"./SideNavigation\";\nexport { SideNavigationItem } from \"./SideNavigationItem\";\n\nexport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationItemState,\n SideNavigationLinkProps,\n SideNavigationMode,\n SideNavigationProps,\n} from \"./types\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n 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 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={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationMode,\n} from \"./types\";\n\nconst ACTIVE_ICON_COLOR_FALLBACK = \"#80eaff\";\n\nconst modeConfig = {\n expanded: {\n itemWidth: \"100%\",\n minHeight: 56,\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"flex-start\" as const,\n paddingHorizontal: 16,\n paddingVertical: 16,\n gap: 12,\n iconSize: 24,\n labelFontSize: 16,\n labelLineHeight: 20,\n labelAlign: \"left\" as const,\n labelLines: 1,\n },\n collapsed: {\n itemWidth: 62,\n minHeight: 56,\n flexDirection: \"column\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n paddingHorizontal: 4,\n paddingVertical: 8,\n gap: 4,\n iconSize: 24,\n labelFontSize: 12,\n labelLineHeight: 16,\n labelAlign: \"center\" as const,\n labelLines: 2,\n },\n};\n\nconst getDisplayLabel = (\n item: SideNavigationItemData,\n mode: SideNavigationMode\n) => (mode === \"collapsed\" ? item.shortLabel || item.label : item.label);\n\nconst renderIcon = (icon: React.ReactNode, size: number, color: string) => {\n if (!React.isValidElement(icon)) return icon;\n\n return React.cloneElement(\n icon as React.ReactElement<{ size?: number | string; color?: string }>,\n {\n size,\n color,\n }\n );\n};\n\nexport const SideNavigationItem: React.FC<SideNavigationItemProps> = ({\n item,\n mode = \"expanded\",\n state = \"default\",\n isActive,\n onItemClick,\n linkComponent: LinkComponent,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = modeConfig[mode];\n const resolvedState = isActive || state === \"active\" ? \"active\" : state;\n const isDisabled = Boolean(item.disabled);\n const backgroundColor =\n resolvedState === \"active\" || resolvedState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\";\n const borderColor =\n resolvedState === \"active\" ? theme.colors.border.secondary : \"transparent\";\n const labelColor = theme.colors.content.primary;\n const iconColor =\n resolvedState === \"active\"\n ? theme.colors.background.brand?.primary || ACTIVE_ICON_COLOR_FALLBACK\n : theme.colors.content.tertiary;\n\n const handlePress = () => {\n if (isDisabled) return;\n item.onPress?.();\n onItemClick?.(item);\n };\n\n const content = (\n <Box\n as={!LinkComponent && !isDisabled ? \"button\" : undefined}\n width={config.itemWidth}\n minHeight={config.minHeight}\n flexDirection={config.flexDirection}\n alignItems={config.alignItems}\n justifyContent={config.justifyContent}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n gap={config.gap}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={resolvedState === \"active\" ? 1 : 0}\n borderRadius={8}\n role={LinkComponent ? undefined : \"button\"}\n aria-label={item.accessibilityLabel || item.label}\n aria-current={resolvedState === \"active\" ? \"page\" : undefined}\n aria-disabled={isDisabled || undefined}\n disabled={isDisabled}\n onPress={!LinkComponent && !isDisabled ? handlePress : undefined}\n hoverStyle={\n resolvedState === \"default\"\n ? { backgroundColor: theme.colors.overlay.mono }\n : undefined\n }\n pressStyle={{ backgroundColor: theme.colors.overlay.mono }}\n testID={item.testID || `side-navigation-item-${item.key}`}\n >\n {item.icon && (\n <Box\n width={config.iconSize}\n height={config.iconSize}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n {renderIcon(item.icon, config.iconSize, iconColor)}\n </Box>\n )}\n <Text\n color={labelColor}\n fontFamily={theme.fonts.body}\n fontSize={config.labelFontSize}\n lineHeight={config.labelLineHeight}\n fontWeight=\"400\"\n textAlign={config.labelAlign}\n numberOfLines={config.labelLines}\n >\n {getDisplayLabel(item, mode)}\n </Text>\n </Box>\n );\n\n if (!LinkComponent) return content;\n\n return (\n <LinkComponent\n item={item}\n href={item.href}\n isActive={resolvedState === \"active\"}\n disabled={isDisabled}\n onPress={handlePress}\n testID={item.testID || `side-navigation-link-${item.key}`}\n >\n {content}\n </LinkComponent>\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 type { SideNavigationProps } from \"./types\";\nimport { SideNavigationItem } from \"./SideNavigationItem\";\n\nconst modeConfig = {\n expanded: {\n width: 280,\n alignItems: \"stretch\" as const,\n },\n collapsed: {\n width: 78,\n alignItems: \"center\" as const,\n },\n};\n\nexport const SideNavigation: React.FC<SideNavigationProps> = ({\n mode = \"expanded\",\n items = [],\n activeKey,\n onItemClick,\n linkComponent,\n \"aria-label\": ariaLabel = \"Side navigation\",\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const config = modeConfig[mode];\n\n return (\n <Box\n as=\"nav\"\n role=\"navigation\"\n aria-label={ariaLabel}\n width={config.width}\n flexDirection=\"column\"\n alignItems={config.alignItems}\n gap={16}\n paddingHorizontal={8}\n testID={testID || \"side-navigation\"}\n >\n {items.map((item) => (\n <SideNavigationItem\n key={item.key}\n item={item}\n mode={mode}\n isActive={item.key === activeKey}\n onItemClick={onItemClick}\n linkComponent={linkComponent}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n ))}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","React","import_jsx_runtime","modeConfig"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/SideNavigationItem.tsx","../../src/SideNavigation.tsx"],"sourcesContent":["export { SideNavigation } from \"./SideNavigation\";\nexport { SideNavigationItem } from \"./SideNavigationItem\";\n\nexport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationItemState,\n SideNavigationLinkProps,\n SideNavigationMode,\n SideNavigationProps,\n} from \"./types\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n 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\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationMode,\n} from \"./types\";\n\nconst ACTIVE_ICON_COLOR_FALLBACK = \"#80eaff\";\n\nconst modeConfig = {\n expanded: {\n itemWidth: \"100%\",\n minHeight: 56,\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"flex-start\" as const,\n paddingHorizontal: 16,\n paddingVertical: 16,\n gap: 12,\n iconSize: 24,\n labelFontSize: 16,\n labelLineHeight: 20,\n labelAlign: \"left\" as const,\n labelLines: 1,\n },\n collapsed: {\n itemWidth: 62,\n minHeight: 56,\n flexDirection: \"column\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n paddingHorizontal: 4,\n paddingVertical: 8,\n gap: 4,\n iconSize: 24,\n labelFontSize: 12,\n labelLineHeight: 16,\n labelAlign: \"center\" as const,\n labelLines: 2,\n },\n};\n\nconst getDisplayLabel = (\n item: SideNavigationItemData,\n mode: SideNavigationMode\n) => (mode === \"collapsed\" ? item.shortLabel || item.label : item.label);\n\nconst renderIcon = (icon: React.ReactNode, size: number, color: string) => {\n if (!React.isValidElement(icon)) return icon;\n\n return React.cloneElement(\n icon as React.ReactElement<{ size?: number | string; color?: string }>,\n {\n size,\n color,\n }\n );\n};\n\nexport const SideNavigationItem: React.FC<SideNavigationItemProps> = ({\n item,\n mode = \"expanded\",\n state = \"default\",\n isActive,\n onItemClick,\n linkComponent: LinkComponent,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = modeConfig[mode];\n const resolvedState = isActive || state === \"active\" ? \"active\" : state;\n const isDisabled = Boolean(item.disabled);\n const backgroundColor =\n resolvedState === \"active\" || resolvedState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\";\n const borderColor =\n resolvedState === \"active\" ? theme.colors.border.secondary : \"transparent\";\n const labelColor = theme.colors.content.primary;\n const iconColor =\n resolvedState === \"active\"\n ? theme.colors.background.brand?.primary || ACTIVE_ICON_COLOR_FALLBACK\n : theme.colors.content.tertiary;\n\n const handlePress = () => {\n if (isDisabled) return;\n item.onPress?.();\n onItemClick?.(item);\n };\n\n const content = (\n <Box\n as={!LinkComponent && !isDisabled ? \"button\" : undefined}\n width={config.itemWidth}\n minHeight={config.minHeight}\n flexDirection={config.flexDirection}\n alignItems={config.alignItems}\n justifyContent={config.justifyContent}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n gap={config.gap}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={resolvedState === \"active\" ? 1 : 0}\n borderRadius={8}\n role={LinkComponent ? undefined : \"button\"}\n aria-label={item.accessibilityLabel || item.label}\n aria-current={resolvedState === \"active\" ? \"page\" : undefined}\n aria-disabled={isDisabled || undefined}\n disabled={isDisabled}\n onPress={!LinkComponent && !isDisabled ? handlePress : undefined}\n hoverStyle={\n resolvedState === \"default\"\n ? { backgroundColor: theme.colors.overlay.mono }\n : undefined\n }\n pressStyle={{ backgroundColor: theme.colors.overlay.mono }}\n testID={item.testID || `side-navigation-item-${item.key}`}\n >\n {item.icon && (\n <Box\n width={config.iconSize}\n height={config.iconSize}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n {renderIcon(item.icon, config.iconSize, iconColor)}\n </Box>\n )}\n <Text\n color={labelColor}\n fontFamily={theme.fonts.body}\n fontSize={config.labelFontSize}\n lineHeight={config.labelLineHeight}\n fontWeight=\"400\"\n textAlign={config.labelAlign}\n numberOfLines={config.labelLines}\n >\n {getDisplayLabel(item, mode)}\n </Text>\n </Box>\n );\n\n if (!LinkComponent) return content;\n\n return (\n <LinkComponent\n item={item}\n href={item.href}\n isActive={resolvedState === \"active\"}\n disabled={isDisabled}\n onPress={handlePress}\n testID={item.testID || `side-navigation-link-${item.key}`}\n >\n {content}\n </LinkComponent>\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 type { SideNavigationProps } from \"./types\";\nimport { SideNavigationItem } from \"./SideNavigationItem\";\n\nconst modeConfig = {\n expanded: {\n width: 280,\n alignItems: \"stretch\" as const,\n },\n collapsed: {\n width: 78,\n alignItems: \"center\" as const,\n },\n};\n\nexport const SideNavigation: React.FC<SideNavigationProps> = ({\n mode = \"expanded\",\n items = [],\n activeKey,\n onItemClick,\n linkComponent,\n \"aria-label\": ariaLabel = \"Side navigation\",\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const config = modeConfig[mode];\n\n return (\n <Box\n as=\"nav\"\n role=\"navigation\"\n aria-label={ariaLabel}\n width={config.width}\n flexDirection=\"column\"\n alignItems={config.alignItems}\n gap={16}\n paddingHorizontal={8}\n testID={testID || \"side-navigation\"}\n >\n {items.map((item) => (\n <SideNavigationItem\n key={item.key}\n item={item}\n mode={mode}\n isActive={item.key === activeKey}\n onItemClick={onItemClick}\n linkComponent={linkComponent}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n ))}\n </Box>\n );\n};\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","React","import_jsx_runtime","modeConfig"]}
package/native/index.mjs CHANGED
@@ -206,6 +206,8 @@ var Text = ({
206
206
  numberOfLines,
207
207
  id,
208
208
  role,
209
+ testID,
210
+ "data-testid": dataTestId,
209
211
  style: styleProp,
210
212
  ...props
211
213
  }) => {
@@ -235,7 +237,7 @@ var Text = ({
235
237
  {
236
238
  style: baseStyle,
237
239
  numberOfLines,
238
- testID: id,
240
+ testID: dataTestId || testID || id,
239
241
  accessibilityRole,
240
242
  children
241
243
  }
@@ -297,6 +299,7 @@ var SideNavigationItem = ({
297
299
  isActive,
298
300
  onItemClick,
299
301
  linkComponent: LinkComponent,
302
+ testID,
300
303
  themeMode,
301
304
  themeProductContext = "b2c"
302
305
  }) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/SideNavigationItem.tsx","../../src/SideNavigation.tsx"],"sourcesContent":["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 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={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationMode,\n} from \"./types\";\n\nconst ACTIVE_ICON_COLOR_FALLBACK = \"#80eaff\";\n\nconst modeConfig = {\n expanded: {\n itemWidth: \"100%\",\n minHeight: 56,\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"flex-start\" as const,\n paddingHorizontal: 16,\n paddingVertical: 16,\n gap: 12,\n iconSize: 24,\n labelFontSize: 16,\n labelLineHeight: 20,\n labelAlign: \"left\" as const,\n labelLines: 1,\n },\n collapsed: {\n itemWidth: 62,\n minHeight: 56,\n flexDirection: \"column\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n paddingHorizontal: 4,\n paddingVertical: 8,\n gap: 4,\n iconSize: 24,\n labelFontSize: 12,\n labelLineHeight: 16,\n labelAlign: \"center\" as const,\n labelLines: 2,\n },\n};\n\nconst getDisplayLabel = (\n item: SideNavigationItemData,\n mode: SideNavigationMode\n) => (mode === \"collapsed\" ? item.shortLabel || item.label : item.label);\n\nconst renderIcon = (icon: React.ReactNode, size: number, color: string) => {\n if (!React.isValidElement(icon)) return icon;\n\n return React.cloneElement(\n icon as React.ReactElement<{ size?: number | string; color?: string }>,\n {\n size,\n color,\n }\n );\n};\n\nexport const SideNavigationItem: React.FC<SideNavigationItemProps> = ({\n item,\n mode = \"expanded\",\n state = \"default\",\n isActive,\n onItemClick,\n linkComponent: LinkComponent,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = modeConfig[mode];\n const resolvedState = isActive || state === \"active\" ? \"active\" : state;\n const isDisabled = Boolean(item.disabled);\n const backgroundColor =\n resolvedState === \"active\" || resolvedState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\";\n const borderColor =\n resolvedState === \"active\" ? theme.colors.border.secondary : \"transparent\";\n const labelColor = theme.colors.content.primary;\n const iconColor =\n resolvedState === \"active\"\n ? theme.colors.background.brand?.primary || ACTIVE_ICON_COLOR_FALLBACK\n : theme.colors.content.tertiary;\n\n const handlePress = () => {\n if (isDisabled) return;\n item.onPress?.();\n onItemClick?.(item);\n };\n\n const content = (\n <Box\n as={!LinkComponent && !isDisabled ? \"button\" : undefined}\n width={config.itemWidth}\n minHeight={config.minHeight}\n flexDirection={config.flexDirection}\n alignItems={config.alignItems}\n justifyContent={config.justifyContent}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n gap={config.gap}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={resolvedState === \"active\" ? 1 : 0}\n borderRadius={8}\n role={LinkComponent ? undefined : \"button\"}\n aria-label={item.accessibilityLabel || item.label}\n aria-current={resolvedState === \"active\" ? \"page\" : undefined}\n aria-disabled={isDisabled || undefined}\n disabled={isDisabled}\n onPress={!LinkComponent && !isDisabled ? handlePress : undefined}\n hoverStyle={\n resolvedState === \"default\"\n ? { backgroundColor: theme.colors.overlay.mono }\n : undefined\n }\n pressStyle={{ backgroundColor: theme.colors.overlay.mono }}\n testID={item.testID || `side-navigation-item-${item.key}`}\n >\n {item.icon && (\n <Box\n width={config.iconSize}\n height={config.iconSize}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n {renderIcon(item.icon, config.iconSize, iconColor)}\n </Box>\n )}\n <Text\n color={labelColor}\n fontFamily={theme.fonts.body}\n fontSize={config.labelFontSize}\n lineHeight={config.labelLineHeight}\n fontWeight=\"400\"\n textAlign={config.labelAlign}\n numberOfLines={config.labelLines}\n >\n {getDisplayLabel(item, mode)}\n </Text>\n </Box>\n );\n\n if (!LinkComponent) return content;\n\n return (\n <LinkComponent\n item={item}\n href={item.href}\n isActive={resolvedState === \"active\"}\n disabled={isDisabled}\n onPress={handlePress}\n testID={item.testID || `side-navigation-link-${item.key}`}\n >\n {content}\n </LinkComponent>\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 type { SideNavigationProps } from \"./types\";\nimport { SideNavigationItem } from \"./SideNavigationItem\";\n\nconst modeConfig = {\n expanded: {\n width: 280,\n alignItems: \"stretch\" as const,\n },\n collapsed: {\n width: 78,\n alignItems: \"center\" as const,\n },\n};\n\nexport const SideNavigation: React.FC<SideNavigationProps> = ({\n mode = \"expanded\",\n items = [],\n activeKey,\n onItemClick,\n linkComponent,\n \"aria-label\": ariaLabel = \"Side navigation\",\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const config = modeConfig[mode];\n\n return (\n <Box\n as=\"nav\"\n role=\"navigation\"\n aria-label={ariaLabel}\n width={config.width}\n flexDirection=\"column\"\n alignItems={config.alignItems}\n gap={16}\n paddingHorizontal={8}\n testID={testID || \"side-navigation\"}\n >\n {items.map((item) => (\n <SideNavigationItem\n key={item.key}\n item={item}\n mode={mode}\n isActive={item.key === activeKey}\n onItemClick={onItemClick}\n linkComponent={linkComponent}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n ))}\n </Box>\n );\n};\n"],"mappings":"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","names":["jsx","jsx","jsx","modeConfig"]}
1
+ {"version":3,"sources":["../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/SideNavigationItem.tsx","../../src/SideNavigation.tsx"],"sourcesContent":["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\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type {\n SideNavigationItemData,\n SideNavigationItemProps,\n SideNavigationMode,\n} from \"./types\";\n\nconst ACTIVE_ICON_COLOR_FALLBACK = \"#80eaff\";\n\nconst modeConfig = {\n expanded: {\n itemWidth: \"100%\",\n minHeight: 56,\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"flex-start\" as const,\n paddingHorizontal: 16,\n paddingVertical: 16,\n gap: 12,\n iconSize: 24,\n labelFontSize: 16,\n labelLineHeight: 20,\n labelAlign: \"left\" as const,\n labelLines: 1,\n },\n collapsed: {\n itemWidth: 62,\n minHeight: 56,\n flexDirection: \"column\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n paddingHorizontal: 4,\n paddingVertical: 8,\n gap: 4,\n iconSize: 24,\n labelFontSize: 12,\n labelLineHeight: 16,\n labelAlign: \"center\" as const,\n labelLines: 2,\n },\n};\n\nconst getDisplayLabel = (\n item: SideNavigationItemData,\n mode: SideNavigationMode\n) => (mode === \"collapsed\" ? item.shortLabel || item.label : item.label);\n\nconst renderIcon = (icon: React.ReactNode, size: number, color: string) => {\n if (!React.isValidElement(icon)) return icon;\n\n return React.cloneElement(\n icon as React.ReactElement<{ size?: number | string; color?: string }>,\n {\n size,\n color,\n }\n );\n};\n\nexport const SideNavigationItem: React.FC<SideNavigationItemProps> = ({\n item,\n mode = \"expanded\",\n state = \"default\",\n isActive,\n onItemClick,\n linkComponent: LinkComponent,\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = modeConfig[mode];\n const resolvedState = isActive || state === \"active\" ? \"active\" : state;\n const isDisabled = Boolean(item.disabled);\n const backgroundColor =\n resolvedState === \"active\" || resolvedState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\";\n const borderColor =\n resolvedState === \"active\" ? theme.colors.border.secondary : \"transparent\";\n const labelColor = theme.colors.content.primary;\n const iconColor =\n resolvedState === \"active\"\n ? theme.colors.background.brand?.primary || ACTIVE_ICON_COLOR_FALLBACK\n : theme.colors.content.tertiary;\n\n const handlePress = () => {\n if (isDisabled) return;\n item.onPress?.();\n onItemClick?.(item);\n };\n\n const content = (\n <Box\n as={!LinkComponent && !isDisabled ? \"button\" : undefined}\n width={config.itemWidth}\n minHeight={config.minHeight}\n flexDirection={config.flexDirection}\n alignItems={config.alignItems}\n justifyContent={config.justifyContent}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n gap={config.gap}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={resolvedState === \"active\" ? 1 : 0}\n borderRadius={8}\n role={LinkComponent ? undefined : \"button\"}\n aria-label={item.accessibilityLabel || item.label}\n aria-current={resolvedState === \"active\" ? \"page\" : undefined}\n aria-disabled={isDisabled || undefined}\n disabled={isDisabled}\n onPress={!LinkComponent && !isDisabled ? handlePress : undefined}\n hoverStyle={\n resolvedState === \"default\"\n ? { backgroundColor: theme.colors.overlay.mono }\n : undefined\n }\n pressStyle={{ backgroundColor: theme.colors.overlay.mono }}\n testID={item.testID || `side-navigation-item-${item.key}`}\n >\n {item.icon && (\n <Box\n width={config.iconSize}\n height={config.iconSize}\n flexShrink={0}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n {renderIcon(item.icon, config.iconSize, iconColor)}\n </Box>\n )}\n <Text\n color={labelColor}\n fontFamily={theme.fonts.body}\n fontSize={config.labelFontSize}\n lineHeight={config.labelLineHeight}\n fontWeight=\"400\"\n textAlign={config.labelAlign}\n numberOfLines={config.labelLines}\n >\n {getDisplayLabel(item, mode)}\n </Text>\n </Box>\n );\n\n if (!LinkComponent) return content;\n\n return (\n <LinkComponent\n item={item}\n href={item.href}\n isActive={resolvedState === \"active\"}\n disabled={isDisabled}\n onPress={handlePress}\n testID={item.testID || `side-navigation-link-${item.key}`}\n >\n {content}\n </LinkComponent>\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 type { SideNavigationProps } from \"./types\";\nimport { SideNavigationItem } from \"./SideNavigationItem\";\n\nconst modeConfig = {\n expanded: {\n width: 280,\n alignItems: \"stretch\" as const,\n },\n collapsed: {\n width: 78,\n alignItems: \"center\" as const,\n },\n};\n\nexport const SideNavigation: React.FC<SideNavigationProps> = ({\n mode = \"expanded\",\n items = [],\n activeKey,\n onItemClick,\n linkComponent,\n \"aria-label\": ariaLabel = \"Side navigation\",\n testID,\n themeMode,\n themeProductContext = \"b2c\",\n}) => {\n const config = modeConfig[mode];\n\n return (\n <Box\n as=\"nav\"\n role=\"navigation\"\n aria-label={ariaLabel}\n width={config.width}\n flexDirection=\"column\"\n alignItems={config.alignItems}\n gap={16}\n paddingHorizontal={8}\n testID={testID || \"side-navigation\"}\n >\n {items.map((item) => (\n <SideNavigationItem\n key={item.key}\n item={item}\n mode={mode}\n isActive={item.key === activeKey}\n onItemClick={onItemClick}\n linkComponent={linkComponent}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n ))}\n </Box>\n );\n};\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AA2ID;AAxIC,IAAM,MAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,oBAAoB,CAAC,aAAkC;AAAA,IAC3D,iBACE,WAAW,YAAY,kBACnB,WAAW,kBACX;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI;AAAA,EACN;AAEA,QAAM,cAAc,cAAc;AAIlC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb;AAAA,IACA,eAAe;AAAA,IACf,GAAG;AAAA,EACL,IAAI;AAGJ,MAAI,OAAO,SAAS,KAAK;AACvB,UAAM,aAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI;AAAA,IACN;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ,EAAE,KAAK,IAAI;AAAA,QACnB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAW;AAAA,QACV,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,CAAC,EAAE,QAAQ,MAAM,kBAAkB,OAAO;AAAA,QACjD,QAAQ;AAAA,QACP,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,kBAAkB;AAAA,MACzB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;;;AC/LA;AAAA,EACE,QAAQ;AAAA,EAGR;AAAA,OACK;AAqEH,gBAAAA,YAAA;AAlEJ,IAAM,UAA6C;AAAA,EACjD,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AACR;AAEA,IAAM,oBAAoB,CACxB,UACuB;AACvB,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,SAAS,WAAW,KAAK;AAC/B,SAAO,MAAM,MAAM,IAAI,SAAY;AACrC;AAEO,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,OAAO;AAAA,EACP,GAAG;AACL,MAAM;AACJ,MAAI,qBAAqB,aACrB,WAAW,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK,IACnD;AAEJ,MACE,uBAAuB,gBACvB,uBAAuB,qBACvB,uBAAuB,iBACvB;AACA,yBAAqB;AAAA,EACvB;AAEA,QAAM,gBAAgB,WAAW,QAAQ,SAAS;AAElD,QAAM,YAAuB;AAAA,IAC3B,OAAO,SAAS,eAAe;AAAA,IAC/B,UAAU,OAAO,aAAa,WAAW,WAAW;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,oBAAoB,MAAM;AAAA,IAC1B,WAAW,aAAa,eAAe;AAAA,IACvC,YAAY,kBAAkB,cAAc,eAAe,UAAU;AAAA,IACrE,WAAW;AAAA,MACT,eAAe;AAAA,IACjB;AAAA,IACA,cAAc;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,oBAAoB,OAAO,QAAQ,IAAI,IAAI;AAEjD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,cAAc,UAAU;AAAA,MAChC;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;ACpFA,OAAO,WAAW;AAGlB,SAAS,wBAAwB;AA6F7B,SA6BI,OAAAC,MA7BJ;AAtFJ,IAAM,6BAA6B;AAEnC,IAAM,aAAa;AAAA,EACjB,UAAU;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,KAAK;AAAA,IACL,UAAU;AAAA,IACV,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,KAAK;AAAA,IACL,UAAU;AAAA,IACV,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACF;AAEA,IAAM,kBAAkB,CACtB,MACA,SACI,SAAS,cAAc,KAAK,cAAc,KAAK,QAAQ,KAAK;AAElE,IAAM,aAAa,CAAC,MAAuB,MAAc,UAAkB;AACzE,MAAI,CAAC,MAAM,eAAe,IAAI,EAAG,QAAO;AAExC,SAAO,MAAM;AAAA,IACX;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,qBAAwD,CAAC;AAAA,EACpE;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,MAAM;AACJ,QAAM,EAAE,MAAM,IAAI,iBAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,QAAM,SAAS,WAAW,IAAI;AAC9B,QAAM,gBAAgB,YAAY,UAAU,WAAW,WAAW;AAClE,QAAM,aAAa,QAAQ,KAAK,QAAQ;AACxC,QAAM,kBACJ,kBAAkB,YAAY,kBAAkB,UAC5C,MAAM,OAAO,QAAQ,OACrB;AACN,QAAM,cACJ,kBAAkB,WAAW,MAAM,OAAO,OAAO,YAAY;AAC/D,QAAM,aAAa,MAAM,OAAO,QAAQ;AACxC,QAAM,YACJ,kBAAkB,WACd,MAAM,OAAO,WAAW,OAAO,WAAW,6BAC1C,MAAM,OAAO,QAAQ;AAE3B,QAAM,cAAc,MAAM;AACxB,QAAI,WAAY;AAChB,SAAK,UAAU;AACf,kBAAc,IAAI;AAAA,EACpB;AAEA,QAAM,UACJ;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,CAAC,iBAAiB,CAAC,aAAa,WAAW;AAAA,MAC/C,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,eAAe,OAAO;AAAA,MACtB,YAAY,OAAO;AAAA,MACnB,gBAAgB,OAAO;AAAA,MACvB,mBAAmB,OAAO;AAAA,MAC1B,iBAAiB,OAAO;AAAA,MACxB,KAAK,OAAO;AAAA,MACZ;AAAA,MACA;AAAA,MACA,aAAa,kBAAkB,WAAW,IAAI;AAAA,MAC9C,cAAc;AAAA,MACd,MAAM,gBAAgB,SAAY;AAAA,MAClC,cAAY,KAAK,sBAAsB,KAAK;AAAA,MAC5C,gBAAc,kBAAkB,WAAW,SAAS;AAAA,MACpD,iBAAe,cAAc;AAAA,MAC7B,UAAU;AAAA,MACV,SAAS,CAAC,iBAAiB,CAAC,aAAa,cAAc;AAAA,MACvD,YACE,kBAAkB,YACd,EAAE,iBAAiB,MAAM,OAAO,QAAQ,KAAK,IAC7C;AAAA,MAEN,YAAY,EAAE,iBAAiB,MAAM,OAAO,QAAQ,KAAK;AAAA,MACzD,QAAQ,KAAK,UAAU,wBAAwB,KAAK,GAAG;AAAA,MAEtD;AAAA,aAAK,QACJ,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO;AAAA,YACd,QAAQ,OAAO;AAAA,YACf,YAAY;AAAA,YACZ,YAAW;AAAA,YACX,gBAAe;AAAA,YAEd,qBAAW,KAAK,MAAM,OAAO,UAAU,SAAS;AAAA;AAAA,QACnD;AAAA,QAEF,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,YAAY,MAAM,MAAM;AAAA,YACxB,UAAU,OAAO;AAAA,YACjB,YAAY,OAAO;AAAA,YACnB,YAAW;AAAA,YACX,WAAW,OAAO;AAAA,YAClB,eAAe,OAAO;AAAA,YAErB,0BAAgB,MAAM,IAAI;AAAA;AAAA,QAC7B;AAAA;AAAA;AAAA,EACF;AAGF,MAAI,CAAC,cAAe,QAAO;AAE3B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAM,KAAK;AAAA,MACX,UAAU,kBAAkB;AAAA,MAC5B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,QAAQ,KAAK,UAAU,wBAAwB,KAAK,GAAG;AAAA,MAEtD;AAAA;AAAA,EACH;AAEJ;;;ACxHQ,gBAAAC,YAAA;AArCR,IAAMC,cAAa;AAAA,EACjB,UAAU;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AACF;AAEO,IAAM,iBAAgD,CAAC;AAAA,EAC5D,OAAO;AAAA,EACP,QAAQ,CAAC;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,MAAM;AACJ,QAAM,SAASA,YAAW,IAAI;AAE9B,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,eAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,KAAK;AAAA,MACL,mBAAmB;AAAA,MACnB,QAAQ,UAAU;AAAA,MAEjB,gBAAM,IAAI,CAAC,SACV,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,UAAU,KAAK,QAAQ;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAPK,KAAK;AAAA,MAQZ,CACD;AAAA;AAAA,EACH;AAEJ;","names":["jsx","jsx","jsx","modeConfig"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-b2c-side-navigation",
3
- "version": "0.158.0",
3
+ "version": "0.159.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-core": "0.158.0",
17
- "@xsolla/xui-icons": "0.158.0",
18
- "@xsolla/xui-primitives-core": "0.158.0"
16
+ "@xsolla/xui-core": "0.159.0",
17
+ "@xsolla/xui-icons": "0.159.0",
18
+ "@xsolla/xui-primitives-core": "0.159.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0"
package/web/index.d.mts CHANGED
@@ -30,6 +30,8 @@ interface SideNavigationItemProps extends ThemeOverrideProps {
30
30
  isActive?: boolean;
31
31
  onItemClick?: (item: SideNavigationItemData) => void;
32
32
  linkComponent?: React.ComponentType<SideNavigationLinkProps>;
33
+ /** Test ID for testing frameworks */
34
+ testID?: string;
33
35
  }
34
36
  interface SideNavigationProps extends ThemeOverrideProps {
35
37
  mode?: SideNavigationMode;
package/web/index.d.ts CHANGED
@@ -30,6 +30,8 @@ interface SideNavigationItemProps extends ThemeOverrideProps {
30
30
  isActive?: boolean;
31
31
  onItemClick?: (item: SideNavigationItemData) => void;
32
32
  linkComponent?: React.ComponentType<SideNavigationLinkProps>;
33
+ /** Test ID for testing frameworks */
34
+ testID?: string;
33
35
  }
34
36
  interface SideNavigationProps extends ThemeOverrideProps {
35
37
  mode?: SideNavigationMode;
package/web/index.js CHANGED
@@ -3795,6 +3795,8 @@ var Text = ({
3795
3795
  className,
3796
3796
  id,
3797
3797
  role,
3798
+ testID,
3799
+ "data-testid": dataTestId,
3798
3800
  numberOfLines: _numberOfLines,
3799
3801
  ...props
3800
3802
  }) => {
@@ -3805,7 +3807,8 @@ var Text = ({
3805
3807
  style,
3806
3808
  className,
3807
3809
  id,
3808
- role
3810
+ role,
3811
+ "data-testid": dataTestId || testID
3809
3812
  }
3810
3813
  );
3811
3814
  };
@@ -3865,6 +3868,7 @@ var SideNavigationItem = ({
3865
3868
  isActive,
3866
3869
  onItemClick,
3867
3870
  linkComponent: LinkComponent,
3871
+ testID,
3868
3872
  themeMode,
3869
3873
  themeProductContext = "b2c"
3870
3874
  }) => {