@xsolla/xui-tabs 0.141.1 → 0.147.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/native/index.js CHANGED
@@ -331,18 +331,26 @@ var Tabs = ({
331
331
  const [indicatorStyle, setIndicatorStyle] = (0, import_react2.useState)({ left: 0, width: 0, initialized: false });
332
332
  (0, import_react2.useEffect)(() => {
333
333
  if (!isSegmented || !isWeb) return;
334
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
335
- const activeTabEl = tabRefs.current[activeIndex];
334
+ const updateIndicator = () => {
335
+ const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
336
+ const activeTabEl = tabRefs.current[activeIndex];
337
+ const containerEl2 = containerRef.current;
338
+ if (activeTabEl && containerEl2) {
339
+ const containerRect = containerEl2.getBoundingClientRect();
340
+ const tabRect = activeTabEl.getBoundingClientRect();
341
+ setIndicatorStyle({
342
+ left: tabRect.left - containerRect.left,
343
+ width: tabRect.width,
344
+ initialized: true
345
+ });
346
+ }
347
+ };
348
+ updateIndicator();
336
349
  const containerEl = containerRef.current;
337
- if (activeTabEl && containerEl) {
338
- const containerRect = containerEl.getBoundingClientRect();
339
- const tabRect = activeTabEl.getBoundingClientRect();
340
- setIndicatorStyle({
341
- left: tabRect.left - containerRect.left,
342
- width: tabRect.width,
343
- initialized: true
344
- });
345
- }
350
+ if (!containerEl || typeof ResizeObserver === "undefined") return;
351
+ const observer = new ResizeObserver(updateIndicator);
352
+ observer.observe(containerEl);
353
+ return () => observer.disconnect();
346
354
  }, [activeTabId, tabs, isSegmented]);
347
355
  const enabledIndices = tabs.map((tab, index) => !tab.disabled ? index : -1).filter((i) => i !== -1);
348
356
  const focusTab = (0, import_react2.useCallback)((index) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Tabs.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Tabs\";\n","import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\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 <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"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"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Tabs.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Tabs\";\n","import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes or container resizes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const updateIndicator = () => {\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n };\n\n updateIndicator();\n\n const containerEl = containerRef.current;\n if (!containerEl || typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(containerEl);\n return () => observer.disconnect();\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\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 <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"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","containerEl"]}
package/native/index.mjs CHANGED
@@ -301,18 +301,26 @@ var Tabs = ({
301
301
  const [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0, initialized: false });
302
302
  useEffect(() => {
303
303
  if (!isSegmented || !isWeb) return;
304
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
305
- const activeTabEl = tabRefs.current[activeIndex];
304
+ const updateIndicator = () => {
305
+ const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
306
+ const activeTabEl = tabRefs.current[activeIndex];
307
+ const containerEl2 = containerRef.current;
308
+ if (activeTabEl && containerEl2) {
309
+ const containerRect = containerEl2.getBoundingClientRect();
310
+ const tabRect = activeTabEl.getBoundingClientRect();
311
+ setIndicatorStyle({
312
+ left: tabRect.left - containerRect.left,
313
+ width: tabRect.width,
314
+ initialized: true
315
+ });
316
+ }
317
+ };
318
+ updateIndicator();
306
319
  const containerEl = containerRef.current;
307
- if (activeTabEl && containerEl) {
308
- const containerRect = containerEl.getBoundingClientRect();
309
- const tabRect = activeTabEl.getBoundingClientRect();
310
- setIndicatorStyle({
311
- left: tabRect.left - containerRect.left,
312
- width: tabRect.width,
313
- initialized: true
314
- });
315
- }
320
+ if (!containerEl || typeof ResizeObserver === "undefined") return;
321
+ const observer = new ResizeObserver(updateIndicator);
322
+ observer.observe(containerEl);
323
+ return () => observer.disconnect();
316
324
  }, [activeTabId, tabs, isSegmented]);
317
325
  const enabledIndices = tabs.map((tab, index) => !tab.disabled ? index : -1).filter((i) => i !== -1);
318
326
  const focusTab = useCallback((index) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Tabs.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\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 <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":";AAAA,SAAgB,UAAU,QAAQ,aAAa,iBAAiB;;;ACChE;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;AAmEH,gBAAAA,YAAA;AAhEJ,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,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;AAAA,MACR;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;AClFA,OAAO,WAAW;AAClB,SAAS,QAAAC,aAAuB;AAwBvB,gBAAAC,YAAA;AArBF,IAAM,OAA4B,CAAC,EAAE,UAAU,OAAO,KAAK,MAAM;AACtE,QAAM,QAAmB;AAAA,IACvB,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA,IACzC,QAAQ,OAAO,SAAS,WAAW,OAAO;AAAA,IAC1C,YAAY;AAAA,IACZ,gBAAgB;AAAA,EAClB;AAIA,QAAM,oBAAoB,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU;AAChE,QAAI,MAAM,eAAe,KAAK,GAAG;AAC/B,aAAO,MAAM,aAAa,OAAO;AAAA,QAC/B,OAAO,MAAM,MAAM,SAAS;AAAA;AAAA,QAE5B,MAAM,MAAM,MAAM,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,gBAAAA,KAACD,OAAA,EAAK,OAAe,6BAAkB;AAChD;;;ACjBO,IAAM,QAAQ;;;AJNrB,SAAS,wBAAiD;AAC1D,SAAS,aAAa;AAsOZ,gBAAAE,MAqCE,YArCF;AA3KH,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,IAAI,iBAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,QAAM,cAAc,YAAY;AAChC,QAAM,YAAY,KAAK,GAAG,EAAE,aAAa;AAGzC,QAAM,CAAC,eAAe,eAAe,IAAI,SAAiB,EAAE;AAC5D,QAAM,UAAU,OAA+B,CAAC,CAAC;AACjD,QAAM,eAAe,OAA2B,IAAI;AAGpD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAIzC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,MAAM,CAAC;AAG5C,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,MAAO;AAE5B,UAAM,cAAc,KAAK,UAAU,CAAC,QAAQ,IAAI,OAAO,WAAW;AAClE,UAAM,cAAc,QAAQ,QAAQ,WAAW;AAC/C,UAAM,cAAc,aAAa;AAEjC,QAAI,eAAe,aAAa;AAC9B,YAAM,gBAAgB,YAAY,sBAAsB;AACxD,YAAM,UAAU,YAAY,sBAAsB;AAElD,wBAAkB;AAAA,QAChB,MAAM,QAAQ,OAAO,cAAc;AAAA,QACnC,OAAO,QAAQ;AAAA,QACf,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,aAAa,MAAM,WAAW,CAAC;AAEnC,QAAM,iBAAiB,KACpB,IAAI,CAAC,KAAK,UAAW,CAAC,IAAI,WAAW,QAAQ,EAAG,EAChD,OAAO,CAAC,MAAM,MAAM,EAAE;AAKzB,QAAM,WAAW,YAAY,CAAC,UAAkB;AAC9C,UAAM,aAAa,QAAQ,QAAQ,KAAK;AACxC,QAAI,YAAY;AACd,iBAAW,QAAQ;AACnB,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AAKL,QAAM,gBAAgB;AAAA,IACpB,CAAC,GAAwB,iBAAyB;AAChD,YAAM,sBAAsB,eAAe,QAAQ,YAAY;AAE/D,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBACJ,sBAAsB,eAAe,SAAS,IAC1C,eAAe,sBAAsB,CAAC,IACtC,eAAe,CAAC;AACtB,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBACJ,sBAAsB,IAClB,eAAe,sBAAsB,CAAC,IACtC,eAAe,eAAe,SAAS,CAAC;AAC9C,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,oBAAoB,eAAe,CAAC;AAC1C,qBAAS,iBAAiB;AAC1B,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,iBAAiB,EAAE,EAAE;AAAA,YACrC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBAAmB,eAAe,eAAe,SAAS,CAAC;AACjE,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB,cAAI,CAAC,mBAAmB,UAAU;AAChC,qBAAS,KAAK,YAAY,EAAE,EAAE;AAAA,UAChC;AACA;AAAA,QAEF;AACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,UAAU,iBAAiB,UAAU,IAAI;AAAA,EAC5D;AAGA,MAAI,aAAa;AACf,UAAM,kBAAkB,MAAM,OAAO,cAAc,IAAI;AACvD,WACE;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,IAAI;AAAA,QACJ,cAAY;AAAA,QACZ,mBAAiB;AAAA,QACjB,oBAAiB;AAAA,QACjB;AAAA,QACA,KAAK,CAAC,OAA2B;AAC/B,uBAAa,UAAU;AAAA,QACzB;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAS;AAAA,QACT,OAAO,YAAY,SAAS,QAAQ,gBAAgB;AAAA,QACpD,WAAW,CAAC,aAAa,CAAC,QAAQ,eAAe;AAAA,QACjD,QAAQ,gBAAgB;AAAA,QACxB,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,QAChD,cAAc,gBAAgB;AAAA,QAC9B,SAAS,gBAAgB;AAAA,QACzB,UAAS;AAAA,QAGR;AAAA,mBAAS,eAAe,eACvB,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,UAAS;AAAA,cACT,QAAQ;AAAA,cACR,QAAQ,eAAe,gBAAgB,mBAAmB,CAAC;AAAA,cAC3D,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,cAChD,cAAc,gBAAgB;AAAA,cAC9B,OAAO;AAAA,gBACL,MAAM,eAAe;AAAA,gBACrB,OAAO,eAAe;AAAA,gBACtB,YAAY;AAAA,gBACZ,eAAe;AAAA,cACjB;AAAA,cACA,eAAW;AAAA;AAAA,UACb;AAAA,UAED,KAAK,IAAI,CAAC,KAAK,UAAU;AACxB,kBAAM,WAAW,IAAI,OAAO;AAC5B,kBAAM,aAAa,IAAI;AACvB,kBAAM,QAAQ,KAAK,GAAG,EAAE,QAAQ,IAAI,EAAE,KAAK;AAC3C,kBAAM,aAAa,KAAK,GAAG,EAAE,aAAa,IAAI,EAAE,KAAK;AAErD,kBAAM,cAAc,MAAM;AACxB,kBAAI,CAAC,cAAc,UAAU;AAC3B,yBAAS,IAAI,EAAE;AAAA,cACjB;AAAA,YACF;AAEA,kBAAM,cAAc,MAAM;AACxB,8BAAgB,KAAK;AAAA,YACvB;AAGA,kBAAM,YAAY,aACd,MAAM,OAAO,QAAQ,UAAU,cAC/B,MAAM,OAAO,QAAQ,UAAU;AAEnC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ,iBAAe;AAAA,gBACf,iBAAe,cAAc;AAAA,gBAC7B,iBAAe;AAAA,gBACf,cAAY,IAAI,YAAY;AAAA,gBAC5B,UAAU,WAAW,IAAI;AAAA,gBACzB,UAAU;AAAA,gBACV,KAAK,CAAC,OAA2B;AAC/B,0BAAQ,QAAQ,KAAK,IAAI;AAAA,gBAC3B;AAAA,gBACA,SAAS;AAAA,gBACT,SAAS;AAAA,gBACT,WAAW,CAAC,MAA2B,cAAc,GAAG,KAAK;AAAA,gBAC7D,MAAM,YAAY,IAAI;AAAA,gBACtB,YAAY;AAAA,gBACZ,UAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,QAAO;AAAA,gBACP,mBAAmB,gBAAgB;AAAA,gBACnC,iBAAiB,gBAAgB;AAAA,gBACjC,eAAc;AAAA,gBACd,YAAW;AAAA,gBACX,gBAAe;AAAA,gBACf,KAAK,gBAAgB;AAAA,gBACrB,iBACE,CAAC,SAAS,WACN,MAAM,OAAO,QAAQ,UAAU,WAC/B;AAAA,gBAEN,cAAc,gBAAgB;AAAA,gBAC9B,QAAQ,aAAa,gBAAgB;AAAA,gBACrC,YACE,CAAC,cAAc,CAAC,WACZ;AAAA,kBACE,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,gBAClD,IACA;AAAA,gBAEN,YAAY;AAAA,kBACV,cAAc,MAAM,OAAO,OAAO;AAAA,kBAClC,cAAc;AAAA,kBACd,eAAe;AAAA,gBACjB;AAAA,gBAEC;AAAA,sBAAI,QACH,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAM,gBAAgB;AAAA,sBACtB,OAAO;AAAA,sBACP,eAAW;AAAA,sBAEV,cAAI;AAAA;AAAA,kBACP;AAAA,kBAGF,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,gBAAgB;AAAA,sBAC1B,YAAW;AAAA,sBACX,WAAU;AAAA,sBACV,YAAW;AAAA,sBACX,UAAS;AAAA,sBACT,cAAa;AAAA,sBAEZ,cAAI;AAAA;AAAA,kBACP;AAAA,kBAEC,IAAI,YAAY,UACf,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,gBAAgB;AAAA,sBAC1B,YAAW;AAAA,sBAEV,cAAI;AAAA;AAAA,kBACP,GACF;AAAA,kBAGD,IAAI,SACH,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA,KAAC,SAAM,MAAK,MACT,iBAAO,IAAI,UAAU,YACtB,OAAO,IAAI,UAAU,WACjB,IAAI,QACJ,QACN,GACF;AAAA;AAAA;AAAA,cAzFG,IAAI;AAAA,YA2FX;AAAA,UAEJ,CAAC;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AAGA,QAAM,aAAa,MAAM,OAAO,KAAK,IAAI;AACzC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,MAAK;AAAA,MACL,IAAI;AAAA,MACJ,cAAY;AAAA,MACZ,mBAAiB;AAAA,MACjB,oBAAiB;AAAA,MACjB;AAAA,MACA,eAAc;AAAA,MACd,YAAW;AAAA,MACX,gBAAgB,YAAY,eAAe;AAAA,MAC3C,OAAO,YAAY,SAAS,QAAQ,gBAAgB;AAAA,MACpD,WAAW,CAAC,aAAa,CAAC,QAAQ,eAAe;AAAA,MACjD,QAAQ,WAAW;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB,MAAM,OAAO,OAAO;AAAA,MACvC,aAAY;AAAA,MAEX,eAAK,IAAI,CAAC,KAAK,UAAU;AACxB,cAAM,WAAW,IAAI,OAAO;AAC5B,cAAM,aAAa,IAAI;AACvB,cAAM,QAAQ,GAAG,EAAE,QAAQ,IAAI,EAAE;AACjC,cAAM,aAAa,GAAG,EAAE,aAAa,IAAI,EAAE;AAE3C,cAAM,cAAc,MAAM;AACxB,cAAI,CAAC,cAAc,UAAU;AAC3B,qBAAS,IAAI,EAAE;AAAA,UACjB;AAAA,QACF;AAEA,cAAM,cAAc,MAAM;AACxB,0BAAgB,KAAK;AAAA,QACvB;AAGA,cAAM,YAAY,aACd,MAAM,OAAO,QAAQ,WACrB,WACE,MAAM,OAAO,QAAQ,UACrB,MAAM,OAAO,QAAQ;AAE3B,cAAM,oBAAoB,WACtB,MAAM,OAAO,OAAO,UACpB;AACJ,cAAM,oBAAoB,WAAW,IAAI;AAEzC,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,IAAI;AAAA,YACJ,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,cAAY,IAAI,YAAY;AAAA,YAC5B,UAAU,WAAW,IAAI;AAAA,YACzB,UAAU;AAAA,YACV,KAAK,CAAC,OAA2B;AAC/B,sBAAQ,QAAQ,KAAK,IAAI;AAAA,YAC3B;AAAA,YACA,SAAS;AAAA,YACT,SAAS;AAAA,YACT,WAAW,CAAC,MAA2B,cAAc,GAAG,KAAK;AAAA,YAC7D,QAAQ,WAAW;AAAA,YACnB,mBAAmB,WAAW;AAAA,YAC9B,eAAc;AAAA,YACd,YAAW;AAAA,YACX,gBAAe;AAAA,YACf,KAAK,WAAW;AAAA,YAChB,UAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA,aAAa,WAAW,UAAU;AAAA,YAClC,cAAc;AAAA,YACd,QAAQ,aAAa,gBAAgB;AAAA,YACrC,YACE,CAAC,cAAc,CAAC,WACZ;AAAA,cACE,iBAAiB,MAAM,OAAO,QAAQ;AAAA,YACxC,IACA;AAAA,YAEN,YAAY;AAAA,cACV,cAAc,MAAM,OAAO,OAAO;AAAA,cAClC,cAAc;AAAA,cACd,eAAe;AAAA,YACjB;AAAA,YAEC;AAAA,kBAAI,QACH,gBAAAA,KAAC,QAAK,MAAM,WAAW,UAAU,OAAO,WAAW,eAAW,MAC3D,cAAI,MACP;AAAA,cAGF,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,kBACP,UAAU,WAAW;AAAA,kBACrB,YAAY,WAAW,QAAQ;AAAA,kBAE9B,cAAI;AAAA;AAAA,cACP;AAAA,cAEC,IAAI,YAAY,UACf,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,MAAM,OAAO,QAAQ,MAAM;AAAA,kBAClC,UAAU,WAAW;AAAA,kBACrB,YAAW;AAAA,kBACX,cAAY,GAAG,IAAI,OAAO;AAAA,kBAEzB,cAAI;AAAA;AAAA,cACP,GACF;AAAA,cAGD,IAAI,SACH,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA,KAAC,SAAM,MAAK,MACT,iBAAO,IAAI,UAAU,YACtB,OAAO,IAAI,UAAU,WACjB,IAAI,QACJ,QACN,GACF;AAAA;AAAA;AAAA,UA5EG,IAAI;AAAA,QA8EX;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;AAEA,KAAK,cAAc;AAyBZ,IAAM,WAAoC,CAAC;AAAA,EAChD;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,cAAc;AAAA,EACd;AACF,MAAM;AACJ,QAAM,UAAU,GAAG,MAAM,aAAa,EAAE;AACxC,QAAM,QAAQ,GAAG,MAAM,QAAQ,EAAE;AAEjC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,MAAK;AAAA,MACL,IAAI;AAAA,MACJ,mBAAiB;AAAA,MACjB,cAAY;AAAA,MACZ,eAAa;AAAA,MACb,UAAU,SAAS,KAAK;AAAA,MACxB;AAAA,MACA,OAAO,EAAE,SAAS,SAAS,SAAS,OAAU;AAAA,MAE7C;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,cAAc;","names":["jsx","View","jsx","jsx"]}
1
+ {"version":3,"sources":["../../src/Tabs.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes or container resizes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const updateIndicator = () => {\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n };\n\n updateIndicator();\n\n const containerEl = containerRef.current;\n if (!containerEl || typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(containerEl);\n return () => observer.disconnect();\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\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 <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":";AAAA,SAAgB,UAAU,QAAQ,aAAa,iBAAiB;;;ACChE;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;AAmEH,gBAAAA,YAAA;AAhEJ,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,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;AAAA,MACR;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;AClFA,OAAO,WAAW;AAClB,SAAS,QAAAC,aAAuB;AAwBvB,gBAAAC,YAAA;AArBF,IAAM,OAA4B,CAAC,EAAE,UAAU,OAAO,KAAK,MAAM;AACtE,QAAM,QAAmB;AAAA,IACvB,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA,IACzC,QAAQ,OAAO,SAAS,WAAW,OAAO;AAAA,IAC1C,YAAY;AAAA,IACZ,gBAAgB;AAAA,EAClB;AAIA,QAAM,oBAAoB,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU;AAChE,QAAI,MAAM,eAAe,KAAK,GAAG;AAC/B,aAAO,MAAM,aAAa,OAAO;AAAA,QAC/B,OAAO,MAAM,MAAM,SAAS;AAAA;AAAA,QAE5B,MAAM,MAAM,MAAM,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,gBAAAA,KAACD,OAAA,EAAK,OAAe,6BAAkB;AAChD;;;ACjBO,IAAM,QAAQ;;;AJNrB,SAAS,wBAAiD;AAC1D,SAAS,aAAa;AAiPZ,gBAAAE,MAqCE,YArCF;AAtLH,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,IAAI,iBAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,QAAM,cAAc,YAAY;AAChC,QAAM,YAAY,KAAK,GAAG,EAAE,aAAa;AAGzC,QAAM,CAAC,eAAe,eAAe,IAAI,SAAiB,EAAE;AAC5D,QAAM,UAAU,OAA+B,CAAC,CAAC;AACjD,QAAM,eAAe,OAA2B,IAAI;AAGpD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAIzC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,MAAM,CAAC;AAG5C,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,MAAO;AAE5B,UAAM,kBAAkB,MAAM;AAC5B,YAAM,cAAc,KAAK,UAAU,CAAC,QAAQ,IAAI,OAAO,WAAW;AAClE,YAAM,cAAc,QAAQ,QAAQ,WAAW;AAC/C,YAAMC,eAAc,aAAa;AAEjC,UAAI,eAAeA,cAAa;AAC9B,cAAM,gBAAgBA,aAAY,sBAAsB;AACxD,cAAM,UAAU,YAAY,sBAAsB;AAElD,0BAAkB;AAAA,UAChB,MAAM,QAAQ,OAAO,cAAc;AAAA,UACnC,OAAO,QAAQ;AAAA,UACf,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB;AAEhB,UAAM,cAAc,aAAa;AACjC,QAAI,CAAC,eAAe,OAAO,mBAAmB,YAAa;AAE3D,UAAM,WAAW,IAAI,eAAe,eAAe;AACnD,aAAS,QAAQ,WAAW;AAC5B,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,aAAa,MAAM,WAAW,CAAC;AAEnC,QAAM,iBAAiB,KACpB,IAAI,CAAC,KAAK,UAAW,CAAC,IAAI,WAAW,QAAQ,EAAG,EAChD,OAAO,CAAC,MAAM,MAAM,EAAE;AAKzB,QAAM,WAAW,YAAY,CAAC,UAAkB;AAC9C,UAAM,aAAa,QAAQ,QAAQ,KAAK;AACxC,QAAI,YAAY;AACd,iBAAW,QAAQ;AACnB,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AAKL,QAAM,gBAAgB;AAAA,IACpB,CAAC,GAAwB,iBAAyB;AAChD,YAAM,sBAAsB,eAAe,QAAQ,YAAY;AAE/D,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBACJ,sBAAsB,eAAe,SAAS,IAC1C,eAAe,sBAAsB,CAAC,IACtC,eAAe,CAAC;AACtB,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBACJ,sBAAsB,IAClB,eAAe,sBAAsB,CAAC,IACtC,eAAe,eAAe,SAAS,CAAC;AAC9C,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,oBAAoB,eAAe,CAAC;AAC1C,qBAAS,iBAAiB;AAC1B,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,iBAAiB,EAAE,EAAE;AAAA,YACrC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AACH,YAAE,eAAe;AACjB;AACE,kBAAM,mBAAmB,eAAe,eAAe,SAAS,CAAC;AACjE,qBAAS,gBAAgB;AACzB,gBAAI,mBAAmB,UAAU;AAC/B,uBAAS,KAAK,gBAAgB,EAAE,EAAE;AAAA,YACpC;AAAA,UACF;AACA;AAAA,QAEF,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAe;AACjB,cAAI,CAAC,mBAAmB,UAAU;AAChC,qBAAS,KAAK,YAAY,EAAE,EAAE;AAAA,UAChC;AACA;AAAA,QAEF;AACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,UAAU,iBAAiB,UAAU,IAAI;AAAA,EAC5D;AAGA,MAAI,aAAa;AACf,UAAM,kBAAkB,MAAM,OAAO,cAAc,IAAI;AACvD,WACE;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,IAAI;AAAA,QACJ,cAAY;AAAA,QACZ,mBAAiB;AAAA,QACjB,oBAAiB;AAAA,QACjB;AAAA,QACA,KAAK,CAAC,OAA2B;AAC/B,uBAAa,UAAU;AAAA,QACzB;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAS;AAAA,QACT,OAAO,YAAY,SAAS,QAAQ,gBAAgB;AAAA,QACpD,WAAW,CAAC,aAAa,CAAC,QAAQ,eAAe;AAAA,QACjD,QAAQ,gBAAgB;AAAA,QACxB,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,QAChD,cAAc,gBAAgB;AAAA,QAC9B,SAAS,gBAAgB;AAAA,QACzB,UAAS;AAAA,QAGR;AAAA,mBAAS,eAAe,eACvB,gBAAAD;AAAA,YAAC;AAAA;AAAA,cACC,UAAS;AAAA,cACT,QAAQ;AAAA,cACR,QAAQ,eAAe,gBAAgB,mBAAmB,CAAC;AAAA,cAC3D,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,cAChD,cAAc,gBAAgB;AAAA,cAC9B,OAAO;AAAA,gBACL,MAAM,eAAe;AAAA,gBACrB,OAAO,eAAe;AAAA,gBACtB,YAAY;AAAA,gBACZ,eAAe;AAAA,cACjB;AAAA,cACA,eAAW;AAAA;AAAA,UACb;AAAA,UAED,KAAK,IAAI,CAAC,KAAK,UAAU;AACxB,kBAAM,WAAW,IAAI,OAAO;AAC5B,kBAAM,aAAa,IAAI;AACvB,kBAAM,QAAQ,KAAK,GAAG,EAAE,QAAQ,IAAI,EAAE,KAAK;AAC3C,kBAAM,aAAa,KAAK,GAAG,EAAE,aAAa,IAAI,EAAE,KAAK;AAErD,kBAAM,cAAc,MAAM;AACxB,kBAAI,CAAC,cAAc,UAAU;AAC3B,yBAAS,IAAI,EAAE;AAAA,cACjB;AAAA,YACF;AAEA,kBAAM,cAAc,MAAM;AACxB,8BAAgB,KAAK;AAAA,YACvB;AAGA,kBAAM,YAAY,aACd,MAAM,OAAO,QAAQ,UAAU,cAC/B,MAAM,OAAO,QAAQ,UAAU;AAEnC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ,iBAAe;AAAA,gBACf,iBAAe,cAAc;AAAA,gBAC7B,iBAAe;AAAA,gBACf,cAAY,IAAI,YAAY;AAAA,gBAC5B,UAAU,WAAW,IAAI;AAAA,gBACzB,UAAU;AAAA,gBACV,KAAK,CAAC,OAA2B;AAC/B,0BAAQ,QAAQ,KAAK,IAAI;AAAA,gBAC3B;AAAA,gBACA,SAAS;AAAA,gBACT,SAAS;AAAA,gBACT,WAAW,CAAC,MAA2B,cAAc,GAAG,KAAK;AAAA,gBAC7D,MAAM,YAAY,IAAI;AAAA,gBACtB,YAAY;AAAA,gBACZ,UAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,QAAO;AAAA,gBACP,mBAAmB,gBAAgB;AAAA,gBACnC,iBAAiB,gBAAgB;AAAA,gBACjC,eAAc;AAAA,gBACd,YAAW;AAAA,gBACX,gBAAe;AAAA,gBACf,KAAK,gBAAgB;AAAA,gBACrB,iBACE,CAAC,SAAS,WACN,MAAM,OAAO,QAAQ,UAAU,WAC/B;AAAA,gBAEN,cAAc,gBAAgB;AAAA,gBAC9B,QAAQ,aAAa,gBAAgB;AAAA,gBACrC,YACE,CAAC,cAAc,CAAC,WACZ;AAAA,kBACE,iBAAiB,MAAM,OAAO,QAAQ,UAAU;AAAA,gBAClD,IACA;AAAA,gBAEN,YAAY;AAAA,kBACV,cAAc,MAAM,OAAO,OAAO;AAAA,kBAClC,cAAc;AAAA,kBACd,eAAe;AAAA,gBACjB;AAAA,gBAEC;AAAA,sBAAI,QACH,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAM,gBAAgB;AAAA,sBACtB,OAAO;AAAA,sBACP,eAAW;AAAA,sBAEV,cAAI;AAAA;AAAA,kBACP;AAAA,kBAGF,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,gBAAgB;AAAA,sBAC1B,YAAW;AAAA,sBACX,WAAU;AAAA,sBACV,YAAW;AAAA,sBACX,UAAS;AAAA,sBACT,cAAa;AAAA,sBAEZ,cAAI;AAAA;AAAA,kBACP;AAAA,kBAEC,IAAI,YAAY,UACf,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,gBAAgB;AAAA,sBAC1B,YAAW;AAAA,sBAEV,cAAI;AAAA;AAAA,kBACP,GACF;AAAA,kBAGD,IAAI,SACH,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA,KAAC,SAAM,MAAK,MACT,iBAAO,IAAI,UAAU,YACtB,OAAO,IAAI,UAAU,WACjB,IAAI,QACJ,QACN,GACF;AAAA;AAAA;AAAA,cAzFG,IAAI;AAAA,YA2FX;AAAA,UAEJ,CAAC;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AAGA,QAAM,aAAa,MAAM,OAAO,KAAK,IAAI;AACzC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,MAAK;AAAA,MACL,IAAI;AAAA,MACJ,cAAY;AAAA,MACZ,mBAAiB;AAAA,MACjB,oBAAiB;AAAA,MACjB;AAAA,MACA,eAAc;AAAA,MACd,YAAW;AAAA,MACX,gBAAgB,YAAY,eAAe;AAAA,MAC3C,OAAO,YAAY,SAAS,QAAQ,gBAAgB;AAAA,MACpD,WAAW,CAAC,aAAa,CAAC,QAAQ,eAAe;AAAA,MACjD,QAAQ,WAAW;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB,MAAM,OAAO,OAAO;AAAA,MACvC,aAAY;AAAA,MAEX,eAAK,IAAI,CAAC,KAAK,UAAU;AACxB,cAAM,WAAW,IAAI,OAAO;AAC5B,cAAM,aAAa,IAAI;AACvB,cAAM,QAAQ,GAAG,EAAE,QAAQ,IAAI,EAAE;AACjC,cAAM,aAAa,GAAG,EAAE,aAAa,IAAI,EAAE;AAE3C,cAAM,cAAc,MAAM;AACxB,cAAI,CAAC,cAAc,UAAU;AAC3B,qBAAS,IAAI,EAAE;AAAA,UACjB;AAAA,QACF;AAEA,cAAM,cAAc,MAAM;AACxB,0BAAgB,KAAK;AAAA,QACvB;AAGA,cAAM,YAAY,aACd,MAAM,OAAO,QAAQ,WACrB,WACE,MAAM,OAAO,QAAQ,UACrB,MAAM,OAAO,QAAQ;AAE3B,cAAM,oBAAoB,WACtB,MAAM,OAAO,OAAO,UACpB;AACJ,cAAM,oBAAoB,WAAW,IAAI;AAEzC,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,IAAI;AAAA,YACJ,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,cAAY,IAAI,YAAY;AAAA,YAC5B,UAAU,WAAW,IAAI;AAAA,YACzB,UAAU;AAAA,YACV,KAAK,CAAC,OAA2B;AAC/B,sBAAQ,QAAQ,KAAK,IAAI;AAAA,YAC3B;AAAA,YACA,SAAS;AAAA,YACT,SAAS;AAAA,YACT,WAAW,CAAC,MAA2B,cAAc,GAAG,KAAK;AAAA,YAC7D,QAAQ,WAAW;AAAA,YACnB,mBAAmB,WAAW;AAAA,YAC9B,eAAc;AAAA,YACd,YAAW;AAAA,YACX,gBAAe;AAAA,YACf,KAAK,WAAW;AAAA,YAChB,UAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA,aAAa,WAAW,UAAU;AAAA,YAClC,cAAc;AAAA,YACd,QAAQ,aAAa,gBAAgB;AAAA,YACrC,YACE,CAAC,cAAc,CAAC,WACZ;AAAA,cACE,iBAAiB,MAAM,OAAO,QAAQ;AAAA,YACxC,IACA;AAAA,YAEN,YAAY;AAAA,cACV,cAAc,MAAM,OAAO,OAAO;AAAA,cAClC,cAAc;AAAA,cACd,eAAe;AAAA,YACjB;AAAA,YAEC;AAAA,kBAAI,QACH,gBAAAA,KAAC,QAAK,MAAM,WAAW,UAAU,OAAO,WAAW,eAAW,MAC3D,cAAI,MACP;AAAA,cAGF,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,kBACP,UAAU,WAAW;AAAA,kBACrB,YAAY,WAAW,QAAQ;AAAA,kBAE9B,cAAI;AAAA;AAAA,cACP;AAAA,cAEC,IAAI,YAAY,UACf,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,MAAM,OAAO,QAAQ,MAAM;AAAA,kBAClC,UAAU,WAAW;AAAA,kBACrB,YAAW;AAAA,kBACX,cAAY,GAAG,IAAI,OAAO;AAAA,kBAEzB,cAAI;AAAA;AAAA,cACP,GACF;AAAA,cAGD,IAAI,SACH,gBAAAA,KAAC,OAAI,YAAY,GAAG,eAAW,MAC7B,0BAAAA,KAAC,SAAM,MAAK,MACT,iBAAO,IAAI,UAAU,YACtB,OAAO,IAAI,UAAU,WACjB,IAAI,QACJ,QACN,GACF;AAAA;AAAA;AAAA,UA5EG,IAAI;AAAA,QA8EX;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;AAEA,KAAK,cAAc;AAyBZ,IAAM,WAAoC,CAAC;AAAA,EAChD;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,cAAc;AAAA,EACd;AACF,MAAM;AACJ,QAAM,UAAU,GAAG,MAAM,aAAa,EAAE;AACxC,QAAM,QAAQ,GAAG,MAAM,QAAQ,EAAE;AAEjC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,MAAK;AAAA,MACL,IAAI;AAAA,MACJ,mBAAiB;AAAA,MACjB,cAAY;AAAA,MACZ,eAAa;AAAA,MACb,UAAU,SAAS,KAAK;AAAA,MACxB;AAAA,MACA,OAAO,EAAE,SAAS,SAAS,SAAS,OAAU;AAAA,MAE7C;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,cAAc;","names":["jsx","View","jsx","jsx","containerEl"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-tabs",
3
- "version": "0.141.1",
3
+ "version": "0.147.1",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -12,9 +12,9 @@
12
12
  "test:watch": "vitest"
13
13
  },
14
14
  "dependencies": {
15
- "@xsolla/xui-badge": "0.141.1",
16
- "@xsolla/xui-core": "0.141.1",
17
- "@xsolla/xui-primitives-core": "0.141.1"
15
+ "@xsolla/xui-badge": "0.147.1",
16
+ "@xsolla/xui-core": "0.147.1",
17
+ "@xsolla/xui-primitives-core": "0.147.1"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": ">=16.8.0",
package/web/index.js CHANGED
@@ -373,18 +373,26 @@ var Tabs = ({
373
373
  const [indicatorStyle, setIndicatorStyle] = (0, import_react3.useState)({ left: 0, width: 0, initialized: false });
374
374
  (0, import_react3.useEffect)(() => {
375
375
  if (!isSegmented || !isWeb) return;
376
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
377
- const activeTabEl = tabRefs.current[activeIndex];
376
+ const updateIndicator = () => {
377
+ const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
378
+ const activeTabEl = tabRefs.current[activeIndex];
379
+ const containerEl2 = containerRef.current;
380
+ if (activeTabEl && containerEl2) {
381
+ const containerRect = containerEl2.getBoundingClientRect();
382
+ const tabRect = activeTabEl.getBoundingClientRect();
383
+ setIndicatorStyle({
384
+ left: tabRect.left - containerRect.left,
385
+ width: tabRect.width,
386
+ initialized: true
387
+ });
388
+ }
389
+ };
390
+ updateIndicator();
378
391
  const containerEl = containerRef.current;
379
- if (activeTabEl && containerEl) {
380
- const containerRect = containerEl.getBoundingClientRect();
381
- const tabRect = activeTabEl.getBoundingClientRect();
382
- setIndicatorStyle({
383
- left: tabRect.left - containerRect.left,
384
- width: tabRect.width,
385
- initialized: true
386
- });
387
- }
392
+ if (!containerEl || typeof ResizeObserver === "undefined") return;
393
+ const observer = new ResizeObserver(updateIndicator);
394
+ observer.observe(containerEl);
395
+ return () => observer.disconnect();
388
396
  }, [activeTabId, tabs, isSegmented]);
389
397
  const enabledIndices = tabs.map((tab, index2) => !tab.disabled ? index2 : -1).filter((i) => i !== -1);
390
398
  const focusTab = (0, import_react3.useCallback)((index2) => {
package/web/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Tabs.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","../../../../foundation/primitives-web/src/index.tsx"],"sourcesContent":["export * from \"./Tabs\";\n","import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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 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 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 }}\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 numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\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> = ({ children, ...props }) => {\n return <StyledIcon {...props}>{children}</StyledIcon>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = true;\nexport const isNative = false;\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","index"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Tabs.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","../../../../foundation/primitives-web/src/index.tsx"],"sourcesContent":["export * from \"./Tabs\";\n","import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes or container resizes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const updateIndicator = () => {\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n };\n\n updateIndicator();\n\n const containerEl = containerRef.current;\n if (!containerEl || typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(containerEl);\n return () => observer.disconnect();\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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 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 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 }}\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 numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\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> = ({ children, ...props }) => {\n return <StyledIcon {...props}>{children}</StyledIcon>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = true;\nexport const isNative = false;\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","containerEl","index"]}
package/web/index.mjs CHANGED
@@ -336,18 +336,26 @@ var Tabs = ({
336
336
  const [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0, initialized: false });
337
337
  useEffect(() => {
338
338
  if (!isSegmented || !isWeb) return;
339
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
340
- const activeTabEl = tabRefs.current[activeIndex];
339
+ const updateIndicator = () => {
340
+ const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
341
+ const activeTabEl = tabRefs.current[activeIndex];
342
+ const containerEl2 = containerRef.current;
343
+ if (activeTabEl && containerEl2) {
344
+ const containerRect = containerEl2.getBoundingClientRect();
345
+ const tabRect = activeTabEl.getBoundingClientRect();
346
+ setIndicatorStyle({
347
+ left: tabRect.left - containerRect.left,
348
+ width: tabRect.width,
349
+ initialized: true
350
+ });
351
+ }
352
+ };
353
+ updateIndicator();
341
354
  const containerEl = containerRef.current;
342
- if (activeTabEl && containerEl) {
343
- const containerRect = containerEl.getBoundingClientRect();
344
- const tabRect = activeTabEl.getBoundingClientRect();
345
- setIndicatorStyle({
346
- left: tabRect.left - containerRect.left,
347
- width: tabRect.width,
348
- initialized: true
349
- });
350
- }
355
+ if (!containerEl || typeof ResizeObserver === "undefined") return;
356
+ const observer = new ResizeObserver(updateIndicator);
357
+ observer.observe(containerEl);
358
+ return () => observer.disconnect();
351
359
  }, [activeTabId, tabs, isSegmented]);
352
360
  const enabledIndices = tabs.map((tab, index2) => !tab.disabled ? index2 : -1).filter((i) => i !== -1);
353
361
  const focusTab = useCallback((index2) => {
package/web/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Tabs.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","../../../../foundation/primitives-web/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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 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 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 }}\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 numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\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> = ({ children, ...props }) => {\n return <StyledIcon {...props}>{children}</StyledIcon>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = true;\nexport const isNative = false;\n"],"mappings":"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","names":["React","React","styled","jsx","styled","styled","jsx","FilteredDiv","styled","jsx","index"]}
1
+ {"version":3,"sources":["../../src/Tabs.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","../../../../foundation/primitives-web/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\n\nexport interface TabItemType {\n /** Unique identifier for the tab */\n id: string;\n /** Display label for the tab */\n label: string;\n /** Optional icon to display before the label */\n icon?: React.ReactNode;\n /** Optional counter to display after the label */\n counter?: string | number;\n /** Optional badge to display */\n badge?: boolean | string | number;\n /** Whether the tab is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers (defaults to label) */\n \"aria-label\"?: string;\n}\n\nexport interface TabsProps extends ThemeOverrideProps {\n /** Array of tab items */\n tabs: TabItemType[];\n /** ID of the currently active tab */\n activeTabId?: string;\n /** Callback when a tab is selected */\n onChange?: (id: string) => void;\n /** Size variant of the tabs */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n /** Visual variant of the tabs */\n variant?: \"line\" | \"segmented\";\n /** Whether to align tabs to the left (only for line variant) */\n alignLeft?: boolean;\n /** Whether the component should stretch to fill its container */\n stretched?: boolean;\n /** Accessible label for the tab list */\n \"aria-label\"?: string;\n /** ID of element that labels this tab list */\n \"aria-labelledby\"?: string;\n /** Whether keyboard navigation should automatically activate tabs */\n activateOnFocus?: boolean;\n /** HTML id attribute */\n id?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\n/**\n * Tabs - An accessible tabbed interface component\n *\n * Implements WAI-ARIA Tabs pattern with proper keyboard navigation:\n * - Arrow Left/Right: Navigate between tabs\n * - Home: Jump to first tab\n * - End: Jump to last tab\n * - Enter/Space: Activate focused tab (when activateOnFocus is false)\n *\n * Variants:\n * - \"line\" (default): Traditional underlined tabs\n * - \"segmented\": Button-group style segmented control\n */\nexport const Tabs: React.FC<TabsProps> = ({\n tabs,\n activeTabId,\n onChange,\n size = \"md\",\n variant = \"line\",\n alignLeft = true,\n stretched = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n activateOnFocus = true,\n id,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const isSegmented = variant === \"segmented\";\n const tabListId = id ? `${id}-tablist` : undefined;\n\n // Track focused tab for keyboard navigation\n const [_focusedIndex, setFocusedIndex] = useState<number>(-1);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for segmented variant animation\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active tab changes or container resizes (web only)\n useEffect(() => {\n if (!isSegmented || !isWeb) return;\n\n const updateIndicator = () => {\n const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);\n const activeTabEl = tabRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeTabEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const tabRect = activeTabEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n initialized: true,\n });\n }\n };\n\n updateIndicator();\n\n const containerEl = containerRef.current;\n if (!containerEl || typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(containerEl);\n return () => observer.disconnect();\n }, [activeTabId, tabs, isSegmented]);\n\n const enabledIndices = tabs\n .map((tab, index) => (!tab.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n /**\n * Focus a tab by its index in the full tabs array\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus?.();\n setFocusedIndex(index);\n }\n }, []);\n\n /**\n * Handle keyboard navigation within the tab list\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusTab(nextEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[nextEnabledIndex].id);\n }\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusTab(prevEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[prevEnabledIndex].id);\n }\n }\n break;\n\n case \"Home\":\n e.preventDefault();\n {\n const firstEnabledIndex = enabledIndices[0];\n focusTab(firstEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[firstEnabledIndex].id);\n }\n }\n break;\n\n case \"End\":\n e.preventDefault();\n {\n const lastEnabledIndex = enabledIndices[enabledIndices.length - 1];\n focusTab(lastEnabledIndex);\n if (activateOnFocus && onChange) {\n onChange(tabs[lastEnabledIndex].id);\n }\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (!activateOnFocus && onChange) {\n onChange(tabs[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusTab, activateOnFocus, onChange, tabs]\n );\n\n // Render segmented variant\n if (isSegmented) {\n const segmentedStyles = theme.sizing.tabsSegmented(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={segmentedStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={segmentedStyles.containerRadius}\n padding={segmentedStyles.containerPadding}\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={`calc(100% - ${segmentedStyles.containerPadding * 2}px)`}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={segmentedStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = id ? `${id}-tab-${tab.id}` : undefined;\n const tabPanelId = id ? `${id}-tabpanel-${tab.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Text color: use segmented tokens for consistency\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled || undefined}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={stretched ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height=\"100%\"\n paddingHorizontal={segmentedStyles.itemPaddingHorizontal}\n paddingVertical={segmentedStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={segmentedStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={segmentedStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon\n size={segmentedStyles.iconSize}\n color={textColor}\n aria-hidden\n >\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={textColor}\n fontSize={segmentedStyles.fontSize}\n fontWeight=\"400\"\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n }\n\n // Render line variant (default)\n const lineStyles = theme.sizing.tabs(size);\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n id={tabListId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n testID={testID}\n flexDirection=\"row\"\n alignItems=\"flex-end\"\n justifyContent={alignLeft ? \"flex-start\" : \"center\"}\n width={stretched ? \"100%\" : isWeb ? \"fit-content\" : undefined}\n alignSelf={!stretched && !isWeb ? \"flex-start\" : undefined}\n height={lineStyles.height}\n borderBottomWidth={1}\n borderBottomColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n >\n {tabs.map((tab, index) => {\n const isActive = tab.id === activeTabId;\n const isDisabled = tab.disabled;\n const tabId = `${id}-tab-${tab.id}`;\n const tabPanelId = `${id}-tabpanel-${tab.id}`;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(tab.id);\n }\n };\n\n const handleFocus = () => {\n setFocusedIndex(index);\n };\n\n // Resolve colors based on state\n const textColor = isDisabled\n ? theme.colors.content.tertiary\n : isActive\n ? theme.colors.content.primary\n : theme.colors.content.tertiary;\n\n const borderBottomColor = isActive\n ? theme.colors.border.primary\n : \"transparent\";\n const borderBottomWidth = isActive ? 2 : 0;\n\n return (\n <Box\n key={tab.id}\n as=\"button\"\n role=\"tab\"\n id={tabId}\n aria-selected={isActive}\n aria-disabled={isDisabled}\n aria-controls={tabPanelId}\n aria-label={tab[\"aria-label\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n tabRefs.current[index] = el;\n }}\n onPress={handlePress}\n onFocus={handleFocus}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n height={lineStyles.height}\n paddingHorizontal={lineStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={lineStyles.gap}\n position=\"relative\"\n borderBottomWidth={borderBottomWidth}\n borderBottomColor={borderBottomColor}\n borderStyle={isActive ? \"solid\" : \"none\"}\n marginBottom={-1} // Overlap the container's bottom border\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.overlay.mono,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {tab.icon && (\n <Icon size={lineStyles.iconSize} color={textColor} aria-hidden>\n {tab.icon}\n </Icon>\n )}\n\n <Text\n color={textColor}\n fontSize={lineStyles.fontSize}\n fontWeight={isActive ? \"600\" : \"500\"}\n >\n {tab.label}\n </Text>\n\n {tab.counter !== undefined && (\n <Box marginLeft={2} aria-hidden>\n <Text\n color={theme.colors.content.brand.primary}\n fontSize={lineStyles.fontSize}\n fontWeight=\"500\"\n aria-label={`${tab.counter} items`}\n >\n {tab.counter}\n </Text>\n </Box>\n )}\n\n {tab.badge && (\n <Box marginLeft={2} aria-hidden>\n <Badge size=\"sm\">\n {typeof tab.badge === \"string\" ||\n typeof tab.badge === \"number\"\n ? tab.badge\n : undefined}\n </Badge>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nTabs.displayName = \"Tabs\";\n\n/**\n * TabPanel - Container for tab content with proper accessibility attributes\n *\n * @example\n * <TabPanel id=\"tab1\" tabsId=\"my-tabs\" hidden={activeTab !== 'tab1'}>\n * <p>Content for tab 1</p>\n * </TabPanel>\n */\nexport interface TabPanelProps {\n /** ID matching the tab's id */\n id: string;\n /** ID of the parent Tabs component */\n tabsId: string;\n /** Whether the panel is hidden */\n hidden?: boolean;\n /** Panel content */\n children: React.ReactNode;\n /** Accessible label for the panel */\n \"aria-label\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const TabPanel: React.FC<TabPanelProps> = ({\n id,\n tabsId,\n hidden = false,\n children,\n \"aria-label\": ariaLabel,\n testID,\n}) => {\n const panelId = `${tabsId}-tabpanel-${id}`;\n const tabId = `${tabsId}-tab-${id}`;\n\n return (\n <Box\n as=\"section\"\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={tabId}\n aria-label={ariaLabel}\n aria-hidden={hidden}\n tabIndex={hidden ? -1 : 0}\n testID={testID}\n style={{ display: hidden ? \"none\" : undefined }}\n >\n {children}\n </Box>\n );\n};\n\nTabPanel.displayName = \"TabPanel\";\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 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 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 }}\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 numberOfLines: _numberOfLines,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\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> = ({ children, ...props }) => {\n return <StyledIcon {...props}>{children}</StyledIcon>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = true;\nexport const isNative = false;\n"],"mappings":"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","names":["React","React","styled","jsx","styled","styled","jsx","FilteredDiv","styled","jsx","containerEl","index"]}