@xsolla/xui-tab-bar 0.112.0 → 0.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/native/index.js +31 -3
- package/native/index.js.map +1 -1
- package/native/index.mjs +35 -4
- package/native/index.mjs.map +1 -1
- package/package.json +4 -4
- package/web/index.js +1 -0
- package/web/index.js.map +1 -1
- package/web/index.mjs +1 -0
- package/web/index.mjs.map +1 -1
package/native/index.js
CHANGED
|
@@ -214,29 +214,57 @@ var roleMap = {
|
|
|
214
214
|
link: "link",
|
|
215
215
|
text: "text"
|
|
216
216
|
};
|
|
217
|
+
var parseNumericValue = (value) => {
|
|
218
|
+
if (value === void 0) return void 0;
|
|
219
|
+
if (typeof value === "number") return value;
|
|
220
|
+
const parsed = parseFloat(value);
|
|
221
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
222
|
+
};
|
|
217
223
|
var Text = ({
|
|
218
224
|
children,
|
|
219
225
|
color,
|
|
220
226
|
fontSize,
|
|
221
227
|
fontWeight,
|
|
222
228
|
fontFamily,
|
|
229
|
+
textAlign,
|
|
230
|
+
lineHeight,
|
|
231
|
+
numberOfLines,
|
|
223
232
|
id,
|
|
224
233
|
role,
|
|
234
|
+
style: styleProp,
|
|
225
235
|
...props
|
|
226
236
|
}) => {
|
|
227
237
|
let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
|
|
228
238
|
if (resolvedFontFamily === "Pilat Wide" || resolvedFontFamily === "Pilat Wide Bold" || resolvedFontFamily === "Aktiv Grotesk") {
|
|
229
239
|
resolvedFontFamily = void 0;
|
|
230
240
|
}
|
|
231
|
-
const
|
|
241
|
+
const incomingStyle = import_react_native2.StyleSheet.flatten(styleProp);
|
|
242
|
+
const baseStyle = {
|
|
232
243
|
color,
|
|
233
244
|
fontSize: typeof fontSize === "number" ? fontSize : void 0,
|
|
234
245
|
fontWeight,
|
|
235
246
|
fontFamily: resolvedFontFamily,
|
|
236
|
-
textDecorationLine: props.textDecoration
|
|
247
|
+
textDecorationLine: props.textDecoration,
|
|
248
|
+
textAlign: textAlign ?? incomingStyle?.textAlign,
|
|
249
|
+
lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),
|
|
250
|
+
marginTop: parseNumericValue(
|
|
251
|
+
incomingStyle?.marginTop
|
|
252
|
+
),
|
|
253
|
+
marginBottom: parseNumericValue(
|
|
254
|
+
incomingStyle?.marginBottom
|
|
255
|
+
)
|
|
237
256
|
};
|
|
238
257
|
const accessibilityRole = role ? roleMap[role] : void 0;
|
|
239
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
259
|
+
import_react_native2.Text,
|
|
260
|
+
{
|
|
261
|
+
style: baseStyle,
|
|
262
|
+
numberOfLines,
|
|
263
|
+
testID: id,
|
|
264
|
+
accessibilityRole,
|
|
265
|
+
children
|
|
266
|
+
}
|
|
267
|
+
);
|
|
240
268
|
};
|
|
241
269
|
|
|
242
270
|
// ../primitives-native/src/Icon.tsx
|
package/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../src/TabBar.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["export * from \"./TabBar\";\nexport * from \"./TabBarItem\";\nexport * from \"./types\";\n","import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport { Text as RNText, TextStyle, AccessibilityRole } from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web roles to React Native accessibility roles\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n id,\n role,\n ...props\n}) => {\n // Extract the first font name from a comma-separated list (e.g. for web-style font stacks)\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n // On native, if we don't have the custom font loaded, fall back to the system font\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const style: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n };\n\n // Map role to React Native accessibilityRole\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText style={style} testID={id} accessibilityRole={accessibilityRole}>\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_xui_core","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/TabBar.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["export * from \"./TabBar\";\nexport * from \"./TabBarItem\";\nexport * from \"./types\";\n","import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\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,\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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_xui_core","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
package/native/index.mjs
CHANGED
|
@@ -172,7 +172,10 @@ var Box = ({
|
|
|
172
172
|
};
|
|
173
173
|
|
|
174
174
|
// ../primitives-native/src/Text.tsx
|
|
175
|
-
import {
|
|
175
|
+
import {
|
|
176
|
+
Text as RNText,
|
|
177
|
+
StyleSheet
|
|
178
|
+
} from "react-native";
|
|
176
179
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
177
180
|
var roleMap = {
|
|
178
181
|
alert: "alert",
|
|
@@ -181,29 +184,57 @@ var roleMap = {
|
|
|
181
184
|
link: "link",
|
|
182
185
|
text: "text"
|
|
183
186
|
};
|
|
187
|
+
var parseNumericValue = (value) => {
|
|
188
|
+
if (value === void 0) return void 0;
|
|
189
|
+
if (typeof value === "number") return value;
|
|
190
|
+
const parsed = parseFloat(value);
|
|
191
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
192
|
+
};
|
|
184
193
|
var Text = ({
|
|
185
194
|
children,
|
|
186
195
|
color,
|
|
187
196
|
fontSize,
|
|
188
197
|
fontWeight,
|
|
189
198
|
fontFamily,
|
|
199
|
+
textAlign,
|
|
200
|
+
lineHeight,
|
|
201
|
+
numberOfLines,
|
|
190
202
|
id,
|
|
191
203
|
role,
|
|
204
|
+
style: styleProp,
|
|
192
205
|
...props
|
|
193
206
|
}) => {
|
|
194
207
|
let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
|
|
195
208
|
if (resolvedFontFamily === "Pilat Wide" || resolvedFontFamily === "Pilat Wide Bold" || resolvedFontFamily === "Aktiv Grotesk") {
|
|
196
209
|
resolvedFontFamily = void 0;
|
|
197
210
|
}
|
|
198
|
-
const
|
|
211
|
+
const incomingStyle = StyleSheet.flatten(styleProp);
|
|
212
|
+
const baseStyle = {
|
|
199
213
|
color,
|
|
200
214
|
fontSize: typeof fontSize === "number" ? fontSize : void 0,
|
|
201
215
|
fontWeight,
|
|
202
216
|
fontFamily: resolvedFontFamily,
|
|
203
|
-
textDecorationLine: props.textDecoration
|
|
217
|
+
textDecorationLine: props.textDecoration,
|
|
218
|
+
textAlign: textAlign ?? incomingStyle?.textAlign,
|
|
219
|
+
lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),
|
|
220
|
+
marginTop: parseNumericValue(
|
|
221
|
+
incomingStyle?.marginTop
|
|
222
|
+
),
|
|
223
|
+
marginBottom: parseNumericValue(
|
|
224
|
+
incomingStyle?.marginBottom
|
|
225
|
+
)
|
|
204
226
|
};
|
|
205
227
|
const accessibilityRole = role ? roleMap[role] : void 0;
|
|
206
|
-
return /* @__PURE__ */ jsx2(
|
|
228
|
+
return /* @__PURE__ */ jsx2(
|
|
229
|
+
RNText,
|
|
230
|
+
{
|
|
231
|
+
style: baseStyle,
|
|
232
|
+
numberOfLines,
|
|
233
|
+
testID: id,
|
|
234
|
+
accessibilityRole,
|
|
235
|
+
children
|
|
236
|
+
}
|
|
237
|
+
);
|
|
207
238
|
};
|
|
208
239
|
|
|
209
240
|
// ../primitives-native/src/Icon.tsx
|
package/native/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TabBar.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport { Text as RNText, TextStyle, AccessibilityRole } from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web roles to React Native accessibility roles\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n id,\n role,\n ...props\n}) => {\n // Extract the first font name from a comma-separated list (e.g. for web-style font stacks)\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n // On native, if we don't have the custom font loaded, fall back to the system font\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const style: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n };\n\n // Map role to React Native accessibilityRole\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText style={style} testID={id} accessibilityRole={accessibilityRole}>\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["jsx","View","jsx","useDesignSystem","isWeb","jsx","jsx","jsxs","useDesignSystem","isWeb"]}
|
|
1
|
+
{"version":3,"sources":["../../src/TabBar.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\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,\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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["jsx","View","jsx","useDesignSystem","isWeb","jsx","jsx","jsxs","useDesignSystem","isWeb"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-tab-bar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.113.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-badge": "0.
|
|
17
|
-
"@xsolla/xui-core": "0.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.
|
|
16
|
+
"@xsolla/xui-badge": "0.113.0",
|
|
17
|
+
"@xsolla/xui-core": "0.113.0",
|
|
18
|
+
"@xsolla/xui-primitives-core": "0.113.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": ">=16.8.0"
|
package/web/index.js
CHANGED
package/web/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../src/TabBar.tsx","../../../primitives-web/src/Box.tsx","../../../primitives-web/src/Text.tsx","../../../primitives-web/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["export * from \"./TabBar\";\nexport * from \"./TabBarItem\";\nexport * from \"./types\";\n","import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledBox = styled.div<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\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 ...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 as={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 {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledText = styled.span<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 ...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\";\n\nconst StyledIcon = styled.div<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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["import_react","styled","React","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_xui_core","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/TabBar.tsx","../../../primitives-web/src/Box.tsx","../../../primitives-web/src/Text.tsx","../../../primitives-web/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["export * from \"./TabBar\";\nexport * from \"./TabBarItem\";\nexport * from \"./types\";\n","import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledBox = styled.div<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\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 ...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 as={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 {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledText = styled.span<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\";\n\nconst StyledIcon = styled.div<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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["import_react","styled","React","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_xui_core","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
package/web/index.mjs
CHANGED
package/web/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TabBar.tsx","../../../primitives-web/src/Box.tsx","../../../primitives-web/src/Text.tsx","../../../primitives-web/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledBox = styled.div<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\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 ...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 as={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 {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledText = styled.span<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 ...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\";\n\nconst StyledIcon = styled.div<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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["styled","jsx","styled","jsx","useDesignSystem","isWeb","jsx","jsx","jsxs","useDesignSystem","isWeb"]}
|
|
1
|
+
{"version":3,"sources":["../../src/TabBar.tsx","../../../primitives-web/src/Box.tsx","../../../primitives-web/src/Text.tsx","../../../primitives-web/src/Icon.tsx","../../src/TabBarItem.tsx"],"sourcesContent":["import React, { useRef, useCallback, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { TabBarItem } from \"./TabBarItem\";\nimport type { TabBarProps } from \"./types\";\n\n/**\n * TabBar - An accessible tab bar navigation 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 * @example\n * ```tsx\n * <TabBar\n * state={navigationState}\n * descriptors={descriptors}\n * navigation={navigation}\n * aria-label=\"Main navigation\"\n * />\n * ```\n */\nexport const TabBar: React.FC<TabBarProps> = ({\n state,\n descriptors,\n navigation,\n labelPosition = \"below-icon\",\n backgroundColor,\n testID,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id,\n activateOnFocus = true,\n}) => {\n const { theme } = useDesignSystem();\n const tabRefs = useRef<(any | null)[]>([]);\n const containerRef = useRef<any>(null);\n const tabCount = state.routes.length;\n\n // Indicator position for sliding selection 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 (!isWeb) return;\n\n const activeIndex = state.index;\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 }, [state.index]);\n\n /**\n * Focus a tab by its index\n */\n const focusTab = useCallback((index: number) => {\n const tabElement = tabRefs.current[index];\n if (tabElement) {\n tabElement.focus();\n }\n }, []);\n\n /**\n * Navigate to a tab by index\n */\n const navigateToTab = useCallback(\n (index: number) => {\n const route = state.routes[index];\n if (route) {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n }\n },\n [state.routes, navigation]\n );\n\n /**\n * Handle keyboard navigation within the tab bar\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n let nextIndex: number | null = null;\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n nextIndex = currentIndex < tabCount - 1 ? currentIndex + 1 : 0;\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : tabCount - 1;\n break;\n\n case \"Home\":\n e.preventDefault();\n nextIndex = 0;\n break;\n\n case \"End\":\n e.preventDefault();\n nextIndex = tabCount - 1;\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n navigateToTab(currentIndex);\n break;\n\n default:\n break;\n }\n\n if (nextIndex !== null) {\n focusTab(nextIndex);\n if (activateOnFocus) {\n navigateToTab(nextIndex);\n }\n }\n },\n [tabCount, focusTab, navigateToTab, activateOnFocus]\n );\n\n return (\n <Box\n as=\"nav\"\n role=\"tablist\"\n aria-label={ariaLabel || \"Tab navigation\"}\n aria-labelledby={ariaLabelledBy}\n aria-orientation=\"horizontal\"\n ref={(el: any) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n position=\"relative\"\n backgroundColor={backgroundColor || theme.colors.background.primary}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n borderRadius={8}\n height={56}\n width=\"100%\"\n overflow=\"hidden\"\n testID={testID || \"tab-bar-container\"}\n id={id}\n >\n {/* Sliding selection indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n top={0}\n zIndex={0}\n height={54}\n backgroundColor={theme.colors.control.faint.bg}\n borderRadius={6}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\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 {state.routes.map((route, index) => {\n const { options } = descriptors[route.key];\n const label =\n options.tabBarShowLabel === false\n ? undefined\n : options.tabBarLabel !== undefined\n ? options.tabBarLabel\n : options.title !== undefined\n ? options.title\n : route.name;\n\n const isFocused = state.index === index;\n\n const onPress = () => {\n const event = navigation.emit({\n type: \"tabPress\",\n target: route.key,\n canPreventDefault: true,\n });\n\n if (!isFocused && !event.defaultPrevented) {\n navigation.navigate(route.name, route.params);\n }\n };\n\n const onLongPress = () => {\n navigation.emit({\n type: \"tabLongPress\",\n target: route.key,\n });\n };\n\n // Use inverse color (white) when selected for floating design\n const iconColor = isFocused\n ? theme.colors.content.inverse\n : theme.colors.content.primary;\n\n const icon = options.tabBarIcon\n ? options.tabBarIcon({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n size: 24,\n })\n : undefined;\n\n const badge = options.tabBarBadge;\n\n // Generate accessible label fallback\n const resolvedLabel =\n typeof label === \"function\"\n ? label({\n focused: isFocused,\n color: isFocused\n ? theme.colors.content.primary\n : theme.colors.content.secondary,\n position: labelPosition,\n })\n : label;\n\n // Use explicit accessibility label or fall back to text label\n const accessibilityLabel =\n options.tabBarAccessibilityLabel ||\n (typeof resolvedLabel === \"string\" ? resolvedLabel : route.name);\n\n // Generate unique tab ID\n const tabId = id ? `${id}-tab-${route.key}` : undefined;\n\n return (\n <TabBarItem\n key={route.key}\n id={tabId}\n label={resolvedLabel}\n icon={icon}\n badge={badge}\n focused={isFocused}\n onPress={onPress}\n onLongPress={onLongPress}\n labelPosition={labelPosition}\n accessibilityLabel={accessibilityLabel}\n testID={options.tabBarTestID}\n index={index}\n tabCount={tabCount}\n onKeyDown={handleKeyDown}\n tabRef={(el) => {\n tabRefs.current[index] = el;\n }}\n />\n );\n })}\n </Box>\n );\n};\n\nTabBar.displayName = \"TabBar\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledBox = styled.div<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\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 ...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 as={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 {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst StyledText = styled.span<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\";\n\nconst StyledIcon = styled.div<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","import React, { cloneElement, isValidElement, type ReactNode } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem, isWeb } from \"@xsolla/xui-core\";\nimport { Badge } from \"@xsolla/xui-badge\";\nimport type { TabBarItemProps } from \"./types\";\n\n/**\n * TabBarItem - An accessible tab item component\n *\n * Implements WAI-ARIA tab role with proper semantics:\n * - role=\"tab\" for tab semantics\n * - aria-selected to indicate active state\n * - tabIndex management for roving tabindex pattern\n * - Keyboard navigation support\n */\nexport const TabBarItem: React.FC<TabBarItemProps> = ({\n label,\n icon,\n badge,\n focused,\n onPress,\n onLongPress,\n labelPosition,\n accessibilityLabel,\n testID,\n id,\n index,\n onKeyDown,\n tabRef,\n}) => {\n const { theme } = useDesignSystem();\n\n // Use inverse color (white) when focused for floating design\n const color = focused\n ? theme.colors.content.primary\n : theme.colors.content.secondary;\n\n const renderIcon = () => {\n if (!icon) return null;\n\n return (\n <Box\n position=\"relative\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Icon size={24} color={color}>\n {isValidElement(icon)\n ? cloneElement(icon as React.ReactElement<any>, {\n size: 24,\n color: color,\n stroke: color,\n })\n : icon}\n </Icon>\n {badge !== undefined && badge !== null && (\n <Box position=\"absolute\" top={-5} right={-10} zIndex={1}>\n <Badge\n size=\"sm\"\n aria-label={\n typeof badge === \"number\"\n ? `${badge} notifications`\n : String(badge)\n }\n >\n {badge}\n </Badge>\n </Box>\n )}\n </Box>\n );\n };\n\n const renderLabel = () => {\n if (typeof label === \"string\") {\n return (\n <Text\n color={color}\n fontSize={10}\n fontWeight={focused ? \"500\" : \"400\"}\n numberOfLines={1}\n aria-hidden={true}\n >\n {label}\n </Text>\n );\n }\n return label as ReactNode;\n };\n\n /**\n * Handle keyboard events for this tab\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onKeyDown) {\n onKeyDown(e, index);\n }\n };\n\n return (\n <Box\n as=\"button\"\n role=\"tab\"\n id={id}\n aria-selected={focused}\n aria-label={accessibilityLabel}\n tabIndex={focused ? 0 : -1}\n ref={tabRef}\n flex={1}\n flexBasis={0}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingVertical={8}\n paddingHorizontal={4}\n cursor=\"pointer\"\n flexDirection={labelPosition === \"beside-icon\" ? \"row\" : \"column\"}\n gap={labelPosition === \"beside-icon\" ? 8 : 4}\n backgroundColor={\n !isWeb && focused ? theme.colors.control.faint.bg : \"transparent\"\n }\n borderWidth={!isWeb && focused ? 1 : 0}\n borderColor={\n !isWeb && focused ? theme.colors.border.secondary : \"transparent\"\n }\n borderStyle=\"solid\"\n borderRadius={8}\n onPress={onPress}\n onLongPress={onLongPress}\n onKeyDown={handleKeyDown}\n testID={testID}\n hoverStyle={{\n backgroundColor: focused\n ? theme.colors.control.faint.bgHover\n : theme.colors.overlay.mono,\n }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n outlineStyle: \"solid\",\n }}\n >\n {renderIcon()}\n {renderLabel()}\n </Box>\n );\n};\n\nTabBarItem.displayName = \"TabBarItem\";\n"],"mappings":"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","names":["styled","jsx","styled","jsx","useDesignSystem","isWeb","jsx","jsx","jsxs","useDesignSystem","isWeb"]}
|