@xsolla/xui-button 0.69.0 → 0.71.0-pr105.1769420965

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.mjs CHANGED
@@ -510,7 +510,7 @@ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
510
510
  var Button = ({
511
511
  variant = "primary",
512
512
  tone = "brand",
513
- size = "m",
513
+ size = "md",
514
514
  disabled = false,
515
515
  loading = false,
516
516
  children,
@@ -700,7 +700,7 @@ import { jsx as jsx9 } from "react/jsx-runtime";
700
700
  var IconButton = ({
701
701
  variant = "primary",
702
702
  tone = "brand",
703
- size = "m",
703
+ size = "md",
704
704
  disabled = false,
705
705
  loading = false,
706
706
  icon,
@@ -817,43 +817,43 @@ import { useDesignSystem as useDesignSystem3 } from "@xsolla/xui-core";
817
817
  import { Fragment, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
818
818
  var ICON_SIZES = {
819
819
  xs: 12,
820
- s: 14,
821
- m: 16,
822
- l: 18,
820
+ sm: 14,
821
+ md: 16,
822
+ lg: 18,
823
823
  xl: 20
824
824
  };
825
825
  var SPINNER_SIZES = {
826
826
  xs: 12,
827
- s: 14,
828
- m: 16,
829
- l: 18,
827
+ sm: 14,
828
+ md: 16,
829
+ lg: 18,
830
830
  xl: 20
831
831
  };
832
832
  var LINE_HEIGHTS = {
833
833
  xs: "14px",
834
- s: "16px",
835
- m: "18px",
836
- l: "20px",
834
+ sm: "16px",
835
+ md: "18px",
836
+ lg: "20px",
837
837
  xl: "22px"
838
838
  };
839
839
  var FONT_SIZES = {
840
840
  xs: 12,
841
- s: 14,
842
- m: 14,
843
- l: 16,
841
+ sm: 14,
842
+ md: 14,
843
+ lg: 16,
844
844
  xl: 18
845
845
  };
846
846
  var BORDER_RADIUS = {
847
847
  xl: 4,
848
- l: 4,
849
- m: 2,
850
- s: 2,
848
+ lg: 4,
849
+ md: 2,
850
+ sm: 2,
851
851
  xs: 2
852
852
  };
853
853
  var FlexButton = ({
854
854
  children,
855
855
  variant = "brand",
856
- size = "m",
856
+ size = "md",
857
857
  background = false,
858
858
  disabled = false,
859
859
  loading = false,
@@ -1152,7 +1152,7 @@ import { useDesignSystem as useDesignSystem4 } from "@xsolla/xui-core";
1152
1152
  import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
1153
1153
  var ButtonGroup = ({
1154
1154
  orientation = "horizontal",
1155
- size = "m",
1155
+ size = "md",
1156
1156
  children,
1157
1157
  description,
1158
1158
  error,
@@ -1180,16 +1180,16 @@ var ButtonGroup = ({
1180
1180
  const useSpaceBetween = orientation === "horizontal" && childCount > 2;
1181
1181
  const verticalGapMap = {
1182
1182
  xl: 16,
1183
- l: 16,
1184
- m: 12,
1185
- s: 8,
1183
+ lg: 16,
1184
+ md: 12,
1185
+ sm: 8,
1186
1186
  xs: 4
1187
1187
  };
1188
1188
  const horizontalGapMap = {
1189
1189
  xl: 16,
1190
- l: 16,
1191
- m: 16,
1192
- s: 12,
1190
+ lg: 16,
1191
+ md: 16,
1192
+ sm: 12,
1193
1193
  xs: 12
1194
1194
  };
1195
1195
  const computedGap = gap ?? (orientation === "vertical" ? verticalGapMap[size] : horizontalGapMap[size]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Button.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Spinner.tsx","../../../primitives-native/src/Icon.tsx","../../../primitives-native/src/Divider.tsx","../../../primitives-native/src/Input.tsx","../../../primitives-native/src/TextArea.tsx","../../src/IconButton.tsx","../../src/FlexButton.tsx","../../src/ButtonGroup.tsx"],"sourcesContent":["import React, { useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Spinner, Icon, Divider } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface ButtonProps {\n /** Visual variant of the button */\n variant?: \"primary\" | \"secondary\";\n /** Color tone of the button */\n tone?: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n /** Size of the button */\n size?: \"xl\" | \"l\" | \"m\" | \"s\" | \"xs\";\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Button content */\n children: React.ReactNode;\n /** Click handler */\n onPress?: () => void;\n /** Icon to display on the left side */\n iconLeft?: React.ReactNode;\n /** Icon to display on the right side */\n iconRight?: React.ReactNode;\n /** Accessible label for screen readers (defaults to children if string) */\n \"aria-label\"?: string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n /** HTML id attribute */\n id?: string;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Whether the button should take up the full width of its container */\n fullWidth?: boolean;\n}\n\n/**\n * Button - An accessible button component\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n * Supports various visual variants, sizes, and states including loading.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n *\n */\nexport const Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n tone = \"brand\",\n size = \"m\",\n disabled = false,\n loading = false,\n children,\n onPress,\n iconLeft,\n iconRight,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n id,\n type = \"button\",\n fullWidth = false,\n}) => {\n const { theme } = useDesignSystem();\n const [isKeyboardPressed, setIsKeyboardPressed] = useState(false);\n\n const isDisabled = disabled || loading;\n\n // Resolve Config from Theme\n const sizeStyles = theme.sizing.button(size);\n\n const variantStyles = theme?.colors?.control?.[tone]?.[variant] ||\n theme?.colors?.control?.brand?.primary || {\n bg: \"transparent\",\n text: { primary: \"#000\" },\n };\n\n const handlePress = () => {\n if (!isDisabled && onPress) {\n onPress();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(true);\n }\n };\n\n const handleKeyUp = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(false);\n if (onPress) {\n onPress();\n }\n }\n };\n\n // Resolve specific values based on state\n // Type assertion needed because secondary variant doesn't have all properties\n const styles = variantStyles as any;\n\n // Determine background color based on state\n let backgroundColor = styles.bg;\n if (disabled) {\n backgroundColor = styles.bgDisable || styles.bg;\n } else if (isKeyboardPressed) {\n backgroundColor = styles.bgPress || styles.bg;\n }\n\n const borderColor = disabled\n ? styles.borderDisable || styles.border\n : styles.border;\n const textColor = disabled\n ? styles.text?.disable || styles.text?.primary\n : styles.text?.primary;\n\n const isDarkText =\n textColor === \"#000000\" ||\n textColor === \"black\" ||\n textColor.startsWith(\"rgba(0, 0, 0\");\n const dividerColor = isDarkText\n ? \"rgba(0, 0, 0, 0.2)\"\n : \"rgba(255, 255, 255, 0.2)\";\n\n // Generate accessible label from children if not provided\n const computedAriaLabel =\n ariaLabel || (typeof children === \"string\" ? children : undefined);\n\n return (\n <Box\n as=\"button\"\n type={type}\n id={id}\n onPress={handlePress}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n disabled={isDisabled}\n aria-label={computedAriaLabel}\n aria-disabled={isDisabled || undefined}\n aria-busy={loading || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n testID={testID}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={\n borderColor !== \"transparent\" &&\n borderColor !== \"rgba(255, 255, 255, 0)\"\n ? 1\n : 0\n }\n borderRadius={theme.radius.button}\n height={sizeStyles.height}\n width={fullWidth ? \"100%\" : undefined}\n padding={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n cursor={disabled ? \"not-allowed\" : loading ? \"wait\" : \"pointer\"}\n opacity={disabled ? 0.6 : 1}\n hoverStyle={\n !isDisabled\n ? {\n backgroundColor: variantStyles?.bgHover,\n }\n : undefined\n }\n pressStyle={\n !isDisabled\n ? {\n backgroundColor: variantStyles?.bgPress,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: 2,\n outlineStyle: \"solid\",\n }}\n >\n {/* Left Icon Section */}\n {!loading && iconLeft && (\n <Box\n height=\"100%\"\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Box\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={sizeStyles.iconPadding}\n >\n <Icon size={sizeStyles.iconSize} color={textColor}>\n {iconLeft}\n </Icon>\n </Box>\n <Divider vertical color={dividerColor} height=\"100%\" />\n </Box>\n )}\n\n {/* Center Section: Content Area */}\n <Box\n flex={fullWidth ? 1 : undefined}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={\n loading ? sizeStyles.loadingPadding : sizeStyles.padding\n }\n height=\"100%\"\n >\n {loading ? (\n <Spinner\n color={textColor}\n size={sizeStyles.spinnerSize}\n aria-hidden={true}\n />\n ) : (\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"500\"\n aria-hidden={computedAriaLabel ? true : undefined}\n >\n {children}\n </Text>\n )}\n </Box>\n\n {/* Right Icon Section */}\n {!loading && iconRight && (\n <Box\n height=\"100%\"\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Divider vertical color={dividerColor} height=\"100%\" />\n <Box\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={sizeStyles.iconPadding}\n >\n <Icon size={sizeStyles.iconSize} color={textColor}>\n {iconRight}\n </Icon>\n </Box>\n </Box>\n )}\n </Box>\n );\n};\n\nButton.displayName = \"Button\";\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, it's better to use the system font\n // to avoid rendering issues or missing text.\n if (resolvedFontFamily === \"Pilat Wide Bold\") {\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 type React from \"react\";\nimport { ActivityIndicator, View } from \"react-native\";\nimport type { SpinnerProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Spinner: React.FC<SpinnerProps> = ({\n color,\n size,\n role,\n \"aria-label\": ariaLabel,\n \"aria-live\": ariaLive,\n \"aria-describedby\": ariaDescribedBy,\n testID,\n}) => {\n return (\n <View\n accessible={true}\n accessibilityRole={role === \"status\" ? \"none\" : undefined}\n accessibilityLabel={ariaLabel}\n accessibilityLiveRegion={\n ariaLive === \"polite\"\n ? \"polite\"\n : ariaLive === \"assertive\"\n ? \"assertive\"\n : \"none\"\n }\n testID={testID}\n >\n <ActivityIndicator\n color={color}\n size={typeof size === \"number\" ? size : \"small\"}\n />\n </View>\n );\n};\n\nSpinner.displayName = \"Spinner\";\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 // @ts-ignore - passing color down to potential Text/Icon children\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 from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { DividerProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Divider: React.FC<DividerProps> = ({\n color,\n height,\n width,\n vertical,\n dashStroke,\n}) => {\n const style: ViewStyle = {\n backgroundColor: dashStroke\n ? \"transparent\"\n : color || \"rgba(255, 255, 255, 0.15)\",\n width: vertical ? (typeof width === \"number\" ? width : 1) : \"100%\",\n height: vertical ? \"100%\" : typeof height === \"number\" ? height : 1,\n ...(dashStroke && {\n borderStyle: \"dashed\",\n borderColor: color || \"rgba(255, 255, 255, 0.15)\",\n borderWidth: 0,\n ...(vertical\n ? { borderLeftWidth: typeof width === \"number\" ? width : 1 }\n : { borderTopWidth: typeof height === \"number\" ? height : 1 }),\n }),\n };\n\n return <View style={style} />;\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { InputPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web input types to React Native keyboard types\nconst keyboardTypeMap: Record<string, any> = {\n text: \"default\",\n number: \"numeric\",\n email: \"email-address\",\n tel: \"phone-pad\",\n url: \"url\",\n decimal: \"decimal-pad\",\n};\n\n// Map web inputMode to React Native keyboard types\nconst inputModeToKeyboardType: Record<string, any> = {\n none: \"default\",\n text: \"default\",\n decimal: \"decimal-pad\",\n numeric: \"number-pad\",\n tel: \"phone-pad\",\n search: \"default\",\n email: \"email-address\",\n url: \"url\",\n};\n\n// Map web autoComplete to React Native textContentType (iOS)\nconst autoCompleteToTextContentType: Record<string, any> = {\n \"one-time-code\": \"oneTimeCode\",\n email: \"emailAddress\",\n username: \"username\",\n password: \"password\",\n \"new-password\": \"newPassword\",\n tel: \"telephoneNumber\",\n \"postal-code\": \"postalCode\",\n name: \"name\",\n};\n\nexport const InputPrimitive = forwardRef<RNTextInput, InputPrimitiveProps>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n secureTextEntry,\n style,\n color,\n fontSize,\n placeholderTextColor,\n maxLength,\n name,\n type,\n inputMode,\n autoComplete,\n id,\n \"aria-invalid\": ariaInvalid,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"data-testid\": dataTestId,\n },\n ref\n ) => {\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n // Create a synthetic event for onChange compatibility\n // Include nativeEvent and no-op methods to prevent runtime errors\n // when consumers expect DOM-like event behavior\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n };\n\n // Determine keyboard type - inputMode takes precedence over type\n const keyboardType = inputMode\n ? inputModeToKeyboardType[inputMode] || \"default\"\n : type\n ? keyboardTypeMap[type] || \"default\"\n : \"default\";\n\n // Determine textContentType for iOS autofill\n const textContentType = autoComplete\n ? autoCompleteToTextContentType[autoComplete]\n : undefined;\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n // Map onKeyPress to onKeyDown for cross-platform compatibility\n // Include preventDefault to avoid runtime errors when consumers call it\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled}\n secureTextEntry={secureTextEntry || type === \"password\"}\n keyboardType={keyboardType}\n textContentType={textContentType}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n flex: 1,\n padding: 0,\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n // React Native accessibility props\n testID={dataTestId || id}\n accessibilityLabel={ariaLabel}\n accessibilityHint={ariaDescribedBy}\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nInputPrimitive.displayName = \"InputPrimitive\";\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n style,\n color,\n fontSize,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-invalid\": ariaInvalid,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"data-testid\": dataTestId,\n },\n ref\n ) => {\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || id}\n accessibilityLabel={ariaLabel}\n accessibilityHint={ariaDescribedBy}\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","import React, { useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Icon, Spinner } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface IconButtonProps {\n /** Visual variant of the button */\n variant?: \"primary\" | \"secondary\";\n /** Color tone of the button */\n tone?: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n /** Size of the button */\n size?: \"xl\" | \"l\" | \"m\" | \"s\" | \"xs\";\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Icon to display in the button (required) */\n icon: React.ReactNode;\n /** Click handler */\n onPress?: () => void;\n /**\n * Accessible label for screen readers (REQUIRED for icon-only buttons)\n * Since icon buttons have no visible text, this label is essential for accessibility.\n * @example aria-label=\"Close dialog\"\n * @example aria-label=\"Open settings menu\"\n */\n \"aria-label\": string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n /** HTML id attribute */\n id?: string;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n}\n\n/**\n * IconButton - An accessible icon-only button component\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n * Supports various visual variants, sizes, and states including loading.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Required aria-label**: Ensures screen readers can announce the button's purpose\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n *\n * ## Usage\n *\n * ```tsx\n * // Basic usage - aria-label is required\n * <IconButton icon={<CloseIcon />} aria-label=\"Close dialog\" onPress={handleClose} />\n *\n * // Toggle button\n * <IconButton\n * icon={<MenuIcon />}\n * aria-label=\"Toggle menu\"\n * aria-expanded={isOpen}\n * aria-controls=\"menu-id\"\n * onPress={toggleMenu}\n * />\n *\n * // Loading state\n * <IconButton icon={<SaveIcon />} aria-label=\"Save changes\" loading />\n * ```\n */\nexport const IconButton: React.FC<IconButtonProps> = ({\n variant = \"primary\",\n tone = \"brand\",\n size = \"m\",\n disabled = false,\n loading = false,\n icon,\n onPress,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n id,\n type = \"button\",\n}) => {\n const { theme } = useDesignSystem();\n const [isKeyboardPressed, setIsKeyboardPressed] = useState(false);\n\n const isDisabled = disabled || loading;\n\n const sizeStyles = theme.sizing.button(size);\n const variantStyles = theme?.colors?.control?.[tone]?.[variant] ||\n theme?.colors?.control?.brand?.primary || {\n bg: \"transparent\",\n text: { primary: \"#000\" },\n };\n\n const handlePress = () => {\n if (!isDisabled && onPress) {\n onPress();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(true);\n }\n };\n\n const handleKeyUp = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(false);\n if (onPress) {\n onPress();\n }\n }\n };\n\n // Resolve specific values based on state\n // Type assertion needed because secondary variant doesn't have all properties\n const styles = variantStyles as any;\n\n // Determine background color based on state\n let backgroundColor = styles.bg;\n if (disabled) {\n backgroundColor = styles.bgDisable || styles.bg;\n } else if (isKeyboardPressed) {\n backgroundColor = styles.bgPress || styles.bg;\n }\n\n const borderColor = disabled\n ? styles.borderDisable || styles.border\n : styles.border;\n const textColor = disabled\n ? styles.text?.disable || styles.text?.primary\n : styles.text?.primary;\n\n return (\n <Box\n as=\"button\"\n type={type}\n id={id}\n onPress={handlePress}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-disabled={isDisabled || undefined}\n aria-busy={loading || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n testID={testID}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={\n borderColor !== \"transparent\" &&\n borderColor !== \"rgba(255, 255, 255, 0)\"\n ? 1\n : 0\n }\n borderRadius={theme.radius.button}\n height={sizeStyles.height}\n width={sizeStyles.height}\n padding={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n cursor={disabled ? \"not-allowed\" : loading ? \"wait\" : \"pointer\"}\n opacity={disabled ? 0.6 : 1}\n hoverStyle={\n !isDisabled\n ? {\n backgroundColor: styles.bgHover,\n }\n : undefined\n }\n pressStyle={\n !isDisabled\n ? {\n backgroundColor: styles.bgPress,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: 2,\n outlineStyle: \"solid\",\n }}\n >\n {loading ? (\n <Spinner\n color={textColor}\n size={sizeStyles.spinnerSize}\n aria-hidden={true}\n />\n ) : (\n <Icon size={sizeStyles.iconSize} color={textColor} aria-hidden={true}>\n {icon}\n </Icon>\n )}\n </Box>\n );\n};\n\nIconButton.displayName = \"IconButton\";\n","import type React from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { useRef, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Spinner, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface FlexButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\"\n> {\n /** Button content */\n children: ReactNode;\n /** Visual variant of the button */\n variant?:\n | \"brand\"\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"brandExtra\"\n | \"inverse\";\n /** Size of the button */\n size?: \"xl\" | \"l\" | \"m\" | \"s\" | \"xs\";\n /** Whether to show background fill */\n background?: boolean;\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Icon to display on the left side */\n iconLeft?: ReactNode;\n /** Icon to display on the right side */\n iconRight?: ReactNode;\n /** Click handler */\n onPress?: () => void;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Accessible label for screen readers */\n \"aria-label\"?: string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\ntype ButtonState = \"default\" | \"hover\" | \"press\";\n\nconst ICON_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n s: 14,\n m: 16,\n l: 18,\n xl: 20,\n};\n\nconst SPINNER_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n s: 14,\n m: 16,\n l: 18,\n xl: 20,\n};\n\nconst LINE_HEIGHTS: Record<NonNullable<FlexButtonProps[\"size\"]>, string> = {\n xs: \"14px\",\n s: \"16px\",\n m: \"18px\",\n l: \"20px\",\n xl: \"22px\",\n};\n\nconst FONT_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n s: 14,\n m: 14,\n l: 16,\n xl: 18,\n};\n\nconst BORDER_RADIUS: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xl: 4,\n l: 4,\n m: 2,\n s: 2,\n xs: 2,\n};\n\n/**\n * FlexButton - A compact button component designed for use in modals and popups.\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n */\nexport const FlexButton: React.FC<FlexButtonProps> = ({\n children,\n variant = \"brand\",\n size = \"m\",\n background = false,\n disabled = false,\n loading = false,\n iconLeft,\n iconRight,\n onPress,\n onClick,\n className,\n type = \"button\",\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n tabIndex = 0,\n ...buttonProps\n}) => {\n const { theme } = useDesignSystem();\n const [state, setState] = useState<ButtonState>(\"default\");\n const [isFocused, setIsFocused] = useState(false);\n const isMouseOverRef = useRef(false);\n\n const isDisabled = disabled || loading;\n\n const getVariantColors = (\n currentState: ButtonState\n ): { bg: string; text: string; border?: string } => {\n if (isDisabled) {\n return {\n bg: background ? theme.colors.overlay.mono : \"transparent\",\n text: theme.colors.control.text.disable,\n border: undefined,\n };\n }\n\n const effectiveBackground = loading ? false : background;\n\n switch (variant) {\n case \"brand\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.brand.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.brand.primary.bgHover\n : theme.colors.background.brand.primary,\n text: theme.colors.content.on.brand,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.background.brand.primary\n : currentState === \"hover\"\n ? theme.colors.overlay.brand\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.on.brand\n : theme.colors.content.brand.primary,\n border: undefined,\n };\n\n case \"primary\":\n if (effectiveBackground) {\n return {\n bg: theme.colors.background.primary,\n text: theme.colors.content.primary,\n border:\n currentState === \"press\"\n ? theme.colors.border.primary\n : undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text: theme.colors.content.primary,\n border:\n currentState === \"press\" ? theme.colors.border.primary : undefined,\n };\n\n case \"secondary\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.secondary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.secondary.bgHover\n : theme.colors.background.secondary,\n text: theme.colors.content.secondary,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.primary\n : currentState === \"hover\"\n ? theme.colors.content.secondary\n : theme.colors.content.secondary,\n border: undefined,\n };\n\n case \"tertiary\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.secondary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.secondary.bgHover\n : theme.colors.background.secondary,\n text: theme.colors.content.tertiary,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.secondary\n : currentState === \"hover\"\n ? theme.colors.content.tertiary\n : theme.colors.content.tertiary,\n border: undefined,\n };\n\n case \"brandExtra\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.brandExtra.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.brandExtra.primary.bgHover\n : theme.colors.background.brandExtra.primary,\n text: theme.colors.content.on.brandExtra,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.background.brandExtra.primary\n : currentState === \"hover\"\n ? theme.colors.overlay.brandExtra\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.on.brandExtra\n : theme.colors.content.brandExtra.secondary,\n border: undefined,\n };\n\n case \"inverse\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.primary.bgHover\n : theme.colors.background.inverse,\n text: theme.colors.content.inverse,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text: theme.colors.content.inverse,\n border: undefined,\n };\n\n default:\n return {\n bg: \"transparent\",\n text: theme.colors.content.primary,\n border: undefined,\n };\n }\n };\n\n const getFocusRingColor = (): string => {\n switch (variant) {\n case \"brand\":\n return theme.colors.overlay.brand;\n case \"brandExtra\":\n return theme.colors.overlay.brandExtra;\n case \"inverse\":\n return \"rgba(255, 255, 255, 0.3)\";\n default:\n return theme.colors.overlay.mono;\n }\n };\n\n const getSpinnerColor = (): string => {\n switch (variant) {\n case \"brand\":\n return theme.colors.content.brand.primary;\n case \"primary\":\n return theme.colors.content.primary;\n case \"secondary\":\n return theme.colors.content.secondary;\n case \"tertiary\":\n return theme.colors.content.tertiary;\n case \"brandExtra\":\n return theme.colors.content.brandExtra.secondary;\n case \"inverse\":\n return theme.colors.content.inverse;\n default:\n return theme.colors.content.brand.primary;\n }\n };\n\n const colors = getVariantColors(state);\n const focusRingColor = getFocusRingColor();\n const spinnerColor = getSpinnerColor();\n const iconSize = ICON_SIZES[size];\n const spinnerSize = SPINNER_SIZES[size];\n const fontSize = FONT_SIZES[size];\n const borderRadius = BORDER_RADIUS[size];\n const lineHeight = LINE_HEIGHTS[size];\n\n const handleMouseEnter = () => {\n if (!isDisabled) {\n isMouseOverRef.current = true;\n setState(\"hover\");\n }\n };\n\n const handleMouseLeave = () => {\n if (!isDisabled) {\n isMouseOverRef.current = false;\n setState(\"default\");\n }\n };\n\n const handleMouseDown = () => {\n if (!isDisabled) {\n setState(\"press\");\n }\n };\n\n const handleMouseUp = () => {\n if (!isDisabled) {\n setState(isMouseOverRef.current ? \"hover\" : \"default\");\n }\n };\n\n const handleFocus = () => {\n if (!isDisabled) {\n setIsFocused(true);\n }\n };\n\n const handleBlur = () => {\n setIsFocused(false);\n };\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (onPress) {\n onPress();\n }\n if (onClick) {\n onClick(event);\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setState(\"press\");\n }\n };\n\n const handleKeyUp = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setState(isMouseOverRef.current ? \"hover\" : \"default\");\n if (onPress) {\n onPress();\n }\n }\n };\n\n const borderShadow = colors.border\n ? `inset 0 0 0 1px ${colors.border}`\n : undefined;\n const focusShadow =\n isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : undefined;\n\n const boxShadows: string[] = [];\n if (borderShadow) boxShadows.push(borderShadow);\n if (focusShadow) boxShadows.push(focusShadow);\n const combinedBoxShadow =\n boxShadows.length > 0 ? boxShadows.join(\", \") : \"none\";\n\n const buttonStyle: CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2px\",\n padding: \"4px\",\n backgroundColor: loading ? \"transparent\" : colors.bg,\n color: colors.text,\n border: \"none\",\n borderWidth: \"0px\",\n borderRadius: `${borderRadius}px`,\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\n fontSize: `${fontSize}px`,\n fontWeight: 500,\n lineHeight: lineHeight,\n fontFamily: \"inherit\",\n transition:\n \"background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out\",\n outline: \"none\",\n boxShadow: combinedBoxShadow,\n opacity: isDisabled && !loading ? 0.6 : 1,\n };\n\n const contentStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2px\",\n };\n\n const spinnerStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"transparent\",\n height: lineHeight,\n };\n\n const computedAriaLabel =\n ariaLabel || (typeof children === \"string\" ? children : undefined);\n\n return (\n <button\n {...buttonProps}\n type={type}\n className={className}\n disabled={isDisabled}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onFocus={handleFocus}\n onBlur={handleBlur}\n aria-label={computedAriaLabel}\n aria-busy={loading || undefined}\n aria-disabled={isDisabled || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n tabIndex={tabIndex}\n style={buttonStyle}\n data-testid={testID || \"flex-button\"}\n >\n <span style={contentStyle}>\n {loading ? (\n <span style={spinnerStyle}>\n <Spinner size={spinnerSize} color={spinnerColor} />\n </span>\n ) : (\n <>\n {iconLeft && (\n <Icon size={iconSize} color={colors.text}>\n {iconLeft}\n </Icon>\n )}\n <span>{children}</span>\n {iconRight && (\n <Icon size={iconSize} color={colors.text}>\n {iconRight}\n </Icon>\n )}\n </>\n )}\n </span>\n </button>\n );\n};\n\nFlexButton.displayName = \"FlexButton\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface ButtonGroupProps {\n /**\n * Layout orientation of the buttons\n * @default 'horizontal'\n */\n orientation?: \"horizontal\" | \"vertical\";\n /**\n * Size of the button group, determines default gap between buttons\n * @default 'm'\n */\n size?: \"xl\" | \"l\" | \"m\" | \"s\" | \"xs\";\n /**\n * Buttons to be grouped\n */\n children: React.ReactNode;\n /**\n * Optional description text below the buttons\n */\n description?: string;\n /**\n * Optional error message text below the buttons\n */\n error?: string;\n /**\n * Custom gap between buttons (in pixels). If not provided, uses size and orientation based default.\n */\n gap?: number;\n /**\n * Accessible label for the button group\n */\n \"aria-label\"?: string;\n /**\n * ID of element that labels this button group\n */\n \"aria-labelledby\"?: string;\n /**\n * ID of element that describes this button group\n */\n \"aria-describedby\"?: string;\n /**\n * HTML id attribute\n */\n id?: string;\n /**\n * Test ID for testing frameworks\n */\n testID?: string;\n}\n\n/**\n * ButtonGroup - A container for grouping related buttons\n *\n * Provides semantic grouping for related actions with proper accessibility support.\n *\n * ## Accessibility Features\n *\n * - **Semantic Grouping**: Uses `role=\"group\"` to indicate related buttons\n * - **Accessible Name**: Supports `aria-label` or `aria-labelledby` to describe the group's purpose\n * - **Error Announcements**: Errors are announced to screen readers via `aria-live`\n * - **Description Support**: Optional description text for additional context\n *\n */\nexport const ButtonGroup: React.FC<ButtonGroupProps> = ({\n orientation = \"horizontal\",\n size = \"m\",\n children,\n description,\n error,\n gap,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n id,\n testID,\n}) => {\n const { theme } = useDesignSystem();\n\n // Flatten children to handle fragments and get actual button elements\n const flattenChildren = (children: React.ReactNode): React.ReactNode[] => {\n const result: React.ReactNode[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n result.push(...flattenChildren(child.props.children));\n } else if (child !== null && child !== undefined) {\n result.push(child);\n }\n });\n return result;\n };\n\n const flatChildren = flattenChildren(children);\n const childCount = flatChildren.length;\n\n // Check if we need space-between layout (horizontal with more than 2 buttons)\n const useSpaceBetween = orientation === \"horizontal\" && childCount > 2;\n\n // Size-based default gaps by orientation\n const verticalGapMap = {\n xl: 16,\n l: 16,\n m: 12,\n s: 8,\n xs: 4,\n };\n\n const horizontalGapMap = {\n xl: 16,\n l: 16,\n m: 16,\n s: 12,\n xs: 12,\n };\n\n // Use provided gap or fall back to orientation and size based default\n const computedGap =\n gap ??\n (orientation === \"vertical\"\n ? verticalGapMap[size]\n : horizontalGapMap[size]);\n\n // Generate IDs for description and error elements\n const descriptionId = id ? `${id}-description` : undefined;\n const errorId = id ? `${id}-error` : undefined;\n\n // Build aria-describedby value combining external and internal references\n const computedAriaDescribedBy =\n [\n ariaDescribedBy,\n error && errorId ? errorId : undefined,\n description && !error && descriptionId ? descriptionId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n // Apply fullWidth to children in vertical orientation for proper alignment\n const processChildren = (childrenToProcess: React.ReactNode[]) => {\n if (orientation === \"vertical\") {\n return childrenToProcess.map((child, index) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n ...child.props,\n fullWidth: true,\n key: child.key ?? index,\n });\n }\n return child;\n });\n }\n return childrenToProcess;\n };\n\n // Split children for space-between layout\n const renderChildren = () => {\n const processedChildren = processChildren(flatChildren);\n\n if (useSpaceBetween) {\n const firstChild = processedChildren[0];\n const restChildren = processedChildren.slice(1);\n\n return (\n <>\n {firstChild}\n <Box flexDirection=\"row\" gap={computedGap}>\n {restChildren}\n </Box>\n </>\n );\n }\n\n // For non-space-between layout, return processed children or original\n if (orientation === \"vertical\") {\n return processedChildren;\n }\n return children;\n };\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" gap={8}>\n <Box\n role=\"group\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={computedAriaDescribedBy}\n id={id}\n testID={testID}\n flexDirection={orientation === \"horizontal\" ? \"row\" : \"column\"}\n alignItems=\"stretch\"\n gap={computedGap}\n justifyContent={useSpaceBetween ? \"space-between\" : undefined}\n width=\"100%\"\n >\n {renderChildren()}\n </Box>\n\n {error && (\n <Box marginTop={4}>\n <Text\n id={errorId}\n role=\"alert\"\n aria-live=\"assertive\"\n color={theme.colors.content.alert.primary}\n fontSize={14}\n fontWeight=\"400\"\n style={\n orientation === \"vertical\" ? { textAlign: \"center\" } : undefined\n }\n >\n {error}\n </Text>\n </Box>\n )}\n\n {description && !error && (\n <Box marginTop={4}>\n <Text\n id={descriptionId}\n color={theme.colors.content.tertiary}\n fontSize={14}\n fontWeight=\"400\"\n style={\n orientation === \"vertical\" ? { textAlign: \"center\" } : undefined\n }\n >\n {description}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n\nButtonGroup.displayName = \"ButtonGroup\";\n"],"mappings":"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","names":["jsx","View","jsx","View","jsx","View","jsx","jsx","forwardRef","RNTextInput","jsx","jsx","useState","useDesignSystem","jsx","useState","useState","useDesignSystem","jsx","jsxs","useState","React","useDesignSystem","Fragment","jsx","jsxs","children","React"]}
1
+ {"version":3,"sources":["../../src/Button.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Spinner.tsx","../../../primitives-native/src/Icon.tsx","../../../primitives-native/src/Divider.tsx","../../../primitives-native/src/Input.tsx","../../../primitives-native/src/TextArea.tsx","../../src/IconButton.tsx","../../src/FlexButton.tsx","../../src/ButtonGroup.tsx"],"sourcesContent":["import React, { useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Spinner, Icon, Divider } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface ButtonProps {\n /** Visual variant of the button */\n variant?: \"primary\" | \"secondary\";\n /** Color tone of the button */\n tone?: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n /** Size of the button */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Button content */\n children: React.ReactNode;\n /** Click handler */\n onPress?: () => void;\n /** Icon to display on the left side */\n iconLeft?: React.ReactNode;\n /** Icon to display on the right side */\n iconRight?: React.ReactNode;\n /** Accessible label for screen readers (defaults to children if string) */\n \"aria-label\"?: string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n /** HTML id attribute */\n id?: string;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Whether the button should take up the full width of its container */\n fullWidth?: boolean;\n}\n\n/**\n * Button - An accessible button component\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n * Supports various visual variants, sizes, and states including loading.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n *\n */\nexport const Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n tone = \"brand\",\n size = \"md\",\n disabled = false,\n loading = false,\n children,\n onPress,\n iconLeft,\n iconRight,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n id,\n type = \"button\",\n fullWidth = false,\n}) => {\n const { theme } = useDesignSystem();\n const [isKeyboardPressed, setIsKeyboardPressed] = useState(false);\n\n const isDisabled = disabled || loading;\n\n // Resolve Config from Theme\n const sizeStyles = theme.sizing.button(size);\n\n const variantStyles = theme?.colors?.control?.[tone]?.[variant] ||\n theme?.colors?.control?.brand?.primary || {\n bg: \"transparent\",\n text: { primary: \"#000\" },\n };\n\n const handlePress = () => {\n if (!isDisabled && onPress) {\n onPress();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(true);\n }\n };\n\n const handleKeyUp = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(false);\n if (onPress) {\n onPress();\n }\n }\n };\n\n // Resolve specific values based on state\n // Type assertion needed because secondary variant doesn't have all properties\n const styles = variantStyles as any;\n\n // Determine background color based on state\n let backgroundColor = styles.bg;\n if (disabled) {\n backgroundColor = styles.bgDisable || styles.bg;\n } else if (isKeyboardPressed) {\n backgroundColor = styles.bgPress || styles.bg;\n }\n\n const borderColor = disabled\n ? styles.borderDisable || styles.border\n : styles.border;\n const textColor = disabled\n ? styles.text?.disable || styles.text?.primary\n : styles.text?.primary;\n\n const isDarkText =\n textColor === \"#000000\" ||\n textColor === \"black\" ||\n textColor.startsWith(\"rgba(0, 0, 0\");\n const dividerColor = isDarkText\n ? \"rgba(0, 0, 0, 0.2)\"\n : \"rgba(255, 255, 255, 0.2)\";\n\n // Generate accessible label from children if not provided\n const computedAriaLabel =\n ariaLabel || (typeof children === \"string\" ? children : undefined);\n\n return (\n <Box\n as=\"button\"\n type={type}\n id={id}\n onPress={handlePress}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n disabled={isDisabled}\n aria-label={computedAriaLabel}\n aria-disabled={isDisabled || undefined}\n aria-busy={loading || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n testID={testID}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={\n borderColor !== \"transparent\" &&\n borderColor !== \"rgba(255, 255, 255, 0)\"\n ? 1\n : 0\n }\n borderRadius={theme.radius.button}\n height={sizeStyles.height}\n width={fullWidth ? \"100%\" : undefined}\n padding={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n cursor={disabled ? \"not-allowed\" : loading ? \"wait\" : \"pointer\"}\n opacity={disabled ? 0.6 : 1}\n hoverStyle={\n !isDisabled\n ? {\n backgroundColor: variantStyles?.bgHover,\n }\n : undefined\n }\n pressStyle={\n !isDisabled\n ? {\n backgroundColor: variantStyles?.bgPress,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: 2,\n outlineStyle: \"solid\",\n }}\n >\n {/* Left Icon Section */}\n {!loading && iconLeft && (\n <Box\n height=\"100%\"\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Box\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={sizeStyles.iconPadding}\n >\n <Icon size={sizeStyles.iconSize} color={textColor}>\n {iconLeft}\n </Icon>\n </Box>\n <Divider vertical color={dividerColor} height=\"100%\" />\n </Box>\n )}\n\n {/* Center Section: Content Area */}\n <Box\n flex={fullWidth ? 1 : undefined}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={\n loading ? sizeStyles.loadingPadding : sizeStyles.padding\n }\n height=\"100%\"\n >\n {loading ? (\n <Spinner\n color={textColor}\n size={sizeStyles.spinnerSize}\n aria-hidden={true}\n />\n ) : (\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"500\"\n aria-hidden={computedAriaLabel ? true : undefined}\n >\n {children}\n </Text>\n )}\n </Box>\n\n {/* Right Icon Section */}\n {!loading && iconRight && (\n <Box\n height=\"100%\"\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n aria-hidden={true}\n >\n <Divider vertical color={dividerColor} height=\"100%\" />\n <Box\n alignItems=\"center\"\n justifyContent=\"center\"\n paddingHorizontal={sizeStyles.iconPadding}\n >\n <Icon size={sizeStyles.iconSize} color={textColor}>\n {iconRight}\n </Icon>\n </Box>\n </Box>\n )}\n </Box>\n );\n};\n\nButton.displayName = \"Button\";\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, it's better to use the system font\n // to avoid rendering issues or missing text.\n if (resolvedFontFamily === \"Pilat Wide Bold\") {\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 type React from \"react\";\nimport { ActivityIndicator, View } from \"react-native\";\nimport type { SpinnerProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Spinner: React.FC<SpinnerProps> = ({\n color,\n size,\n role,\n \"aria-label\": ariaLabel,\n \"aria-live\": ariaLive,\n \"aria-describedby\": ariaDescribedBy,\n testID,\n}) => {\n return (\n <View\n accessible={true}\n accessibilityRole={role === \"status\" ? \"none\" : undefined}\n accessibilityLabel={ariaLabel}\n accessibilityLiveRegion={\n ariaLive === \"polite\"\n ? \"polite\"\n : ariaLive === \"assertive\"\n ? \"assertive\"\n : \"none\"\n }\n testID={testID}\n >\n <ActivityIndicator\n color={color}\n size={typeof size === \"number\" ? size : \"small\"}\n />\n </View>\n );\n};\n\nSpinner.displayName = \"Spinner\";\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 // @ts-ignore - passing color down to potential Text/Icon children\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 from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { DividerProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Divider: React.FC<DividerProps> = ({\n color,\n height,\n width,\n vertical,\n dashStroke,\n}) => {\n const style: ViewStyle = {\n backgroundColor: dashStroke\n ? \"transparent\"\n : color || \"rgba(255, 255, 255, 0.15)\",\n width: vertical ? (typeof width === \"number\" ? width : 1) : \"100%\",\n height: vertical ? \"100%\" : typeof height === \"number\" ? height : 1,\n ...(dashStroke && {\n borderStyle: \"dashed\",\n borderColor: color || \"rgba(255, 255, 255, 0.15)\",\n borderWidth: 0,\n ...(vertical\n ? { borderLeftWidth: typeof width === \"number\" ? width : 1 }\n : { borderTopWidth: typeof height === \"number\" ? height : 1 }),\n }),\n };\n\n return <View style={style} />;\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { InputPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\n// Map web input types to React Native keyboard types\nconst keyboardTypeMap: Record<string, any> = {\n text: \"default\",\n number: \"numeric\",\n email: \"email-address\",\n tel: \"phone-pad\",\n url: \"url\",\n decimal: \"decimal-pad\",\n};\n\n// Map web inputMode to React Native keyboard types\nconst inputModeToKeyboardType: Record<string, any> = {\n none: \"default\",\n text: \"default\",\n decimal: \"decimal-pad\",\n numeric: \"number-pad\",\n tel: \"phone-pad\",\n search: \"default\",\n email: \"email-address\",\n url: \"url\",\n};\n\n// Map web autoComplete to React Native textContentType (iOS)\nconst autoCompleteToTextContentType: Record<string, any> = {\n \"one-time-code\": \"oneTimeCode\",\n email: \"emailAddress\",\n username: \"username\",\n password: \"password\",\n \"new-password\": \"newPassword\",\n tel: \"telephoneNumber\",\n \"postal-code\": \"postalCode\",\n name: \"name\",\n};\n\nexport const InputPrimitive = forwardRef<RNTextInput, InputPrimitiveProps>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n secureTextEntry,\n style,\n color,\n fontSize,\n placeholderTextColor,\n maxLength,\n name,\n type,\n inputMode,\n autoComplete,\n id,\n \"aria-invalid\": ariaInvalid,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"data-testid\": dataTestId,\n },\n ref\n ) => {\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n // Create a synthetic event for onChange compatibility\n // Include nativeEvent and no-op methods to prevent runtime errors\n // when consumers expect DOM-like event behavior\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n };\n\n // Determine keyboard type - inputMode takes precedence over type\n const keyboardType = inputMode\n ? inputModeToKeyboardType[inputMode] || \"default\"\n : type\n ? keyboardTypeMap[type] || \"default\"\n : \"default\";\n\n // Determine textContentType for iOS autofill\n const textContentType = autoComplete\n ? autoCompleteToTextContentType[autoComplete]\n : undefined;\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n // Map onKeyPress to onKeyDown for cross-platform compatibility\n // Include preventDefault to avoid runtime errors when consumers call it\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled}\n secureTextEntry={secureTextEntry || type === \"password\"}\n keyboardType={keyboardType}\n textContentType={textContentType}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n flex: 1,\n padding: 0,\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n // React Native accessibility props\n testID={dataTestId || id}\n accessibilityLabel={ariaLabel}\n accessibilityHint={ariaDescribedBy}\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nInputPrimitive.displayName = \"InputPrimitive\";\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n style,\n color,\n fontSize,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-invalid\": ariaInvalid,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"data-testid\": dataTestId,\n },\n ref\n ) => {\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || id}\n accessibilityLabel={ariaLabel}\n accessibilityHint={ariaDescribedBy}\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","import React, { useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Icon, Spinner } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface IconButtonProps {\n /** Visual variant of the button */\n variant?: \"primary\" | \"secondary\";\n /** Color tone of the button */\n tone?: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n /** Size of the button */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Icon to display in the button (required) */\n icon: React.ReactNode;\n /** Click handler */\n onPress?: () => void;\n /**\n * Accessible label for screen readers (REQUIRED for icon-only buttons)\n * Since icon buttons have no visible text, this label is essential for accessibility.\n * @example aria-label=\"Close dialog\"\n * @example aria-label=\"Open settings menu\"\n */\n \"aria-label\": string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n /** HTML id attribute */\n id?: string;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n}\n\n/**\n * IconButton - An accessible icon-only button component\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n * Supports various visual variants, sizes, and states including loading.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Required aria-label**: Ensures screen readers can announce the button's purpose\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n *\n * ## Usage\n *\n * ```tsx\n * // Basic usage - aria-label is required\n * <IconButton icon={<CloseIcon />} aria-label=\"Close dialog\" onPress={handleClose} />\n *\n * // Toggle button\n * <IconButton\n * icon={<MenuIcon />}\n * aria-label=\"Toggle menu\"\n * aria-expanded={isOpen}\n * aria-controls=\"menu-id\"\n * onPress={toggleMenu}\n * />\n *\n * // Loading state\n * <IconButton icon={<SaveIcon />} aria-label=\"Save changes\" loading />\n * ```\n */\nexport const IconButton: React.FC<IconButtonProps> = ({\n variant = \"primary\",\n tone = \"brand\",\n size = \"md\",\n disabled = false,\n loading = false,\n icon,\n onPress,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n id,\n type = \"button\",\n}) => {\n const { theme } = useDesignSystem();\n const [isKeyboardPressed, setIsKeyboardPressed] = useState(false);\n\n const isDisabled = disabled || loading;\n\n const sizeStyles = theme.sizing.button(size);\n const variantStyles = theme?.colors?.control?.[tone]?.[variant] ||\n theme?.colors?.control?.brand?.primary || {\n bg: \"transparent\",\n text: { primary: \"#000\" },\n };\n\n const handlePress = () => {\n if (!isDisabled && onPress) {\n onPress();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(true);\n }\n };\n\n const handleKeyUp = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setIsKeyboardPressed(false);\n if (onPress) {\n onPress();\n }\n }\n };\n\n // Resolve specific values based on state\n // Type assertion needed because secondary variant doesn't have all properties\n const styles = variantStyles as any;\n\n // Determine background color based on state\n let backgroundColor = styles.bg;\n if (disabled) {\n backgroundColor = styles.bgDisable || styles.bg;\n } else if (isKeyboardPressed) {\n backgroundColor = styles.bgPress || styles.bg;\n }\n\n const borderColor = disabled\n ? styles.borderDisable || styles.border\n : styles.border;\n const textColor = disabled\n ? styles.text?.disable || styles.text?.primary\n : styles.text?.primary;\n\n return (\n <Box\n as=\"button\"\n type={type}\n id={id}\n onPress={handlePress}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-disabled={isDisabled || undefined}\n aria-busy={loading || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n testID={testID}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={\n borderColor !== \"transparent\" &&\n borderColor !== \"rgba(255, 255, 255, 0)\"\n ? 1\n : 0\n }\n borderRadius={theme.radius.button}\n height={sizeStyles.height}\n width={sizeStyles.height}\n padding={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n position=\"relative\"\n cursor={disabled ? \"not-allowed\" : loading ? \"wait\" : \"pointer\"}\n opacity={disabled ? 0.6 : 1}\n hoverStyle={\n !isDisabled\n ? {\n backgroundColor: styles.bgHover,\n }\n : undefined\n }\n pressStyle={\n !isDisabled\n ? {\n backgroundColor: styles.bgPress,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: 2,\n outlineStyle: \"solid\",\n }}\n >\n {loading ? (\n <Spinner\n color={textColor}\n size={sizeStyles.spinnerSize}\n aria-hidden={true}\n />\n ) : (\n <Icon size={sizeStyles.iconSize} color={textColor} aria-hidden={true}>\n {icon}\n </Icon>\n )}\n </Box>\n );\n};\n\nIconButton.displayName = \"IconButton\";\n","import type React from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { useRef, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Spinner, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface FlexButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\"\n> {\n /** Button content */\n children: ReactNode;\n /** Visual variant of the button */\n variant?:\n | \"brand\"\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"brandExtra\"\n | \"inverse\";\n /** Size of the button */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n /** Whether to show background fill */\n background?: boolean;\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Whether the button is in a loading state */\n loading?: boolean;\n /** Icon to display on the left side */\n iconLeft?: ReactNode;\n /** Icon to display on the right side */\n iconRight?: ReactNode;\n /** Click handler */\n onPress?: () => void;\n /** HTML type attribute for the button */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Accessible label for screen readers */\n \"aria-label\"?: string;\n /** ID of element that describes this button */\n \"aria-describedby\"?: string;\n /** Indicates the button controls an expandable element */\n \"aria-expanded\"?: boolean;\n /** Indicates the type of popup triggered by the button */\n \"aria-haspopup\"?: boolean | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\";\n /** Indicates the button is pressed (for toggle buttons) */\n \"aria-pressed\"?: boolean | \"mixed\";\n /** ID of the element this button controls */\n \"aria-controls\"?: string;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\ntype ButtonState = \"default\" | \"hover\" | \"press\";\n\nconst ICON_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n sm: 14,\n md: 16,\n lg: 18,\n xl: 20,\n};\n\nconst SPINNER_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n sm: 14,\n md: 16,\n lg: 18,\n xl: 20,\n};\n\nconst LINE_HEIGHTS: Record<NonNullable<FlexButtonProps[\"size\"]>, string> = {\n xs: \"14px\",\n sm: \"16px\",\n md: \"18px\",\n lg: \"20px\",\n xl: \"22px\",\n};\n\nconst FONT_SIZES: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xs: 12,\n sm: 14,\n md: 14,\n lg: 16,\n xl: 18,\n};\n\nconst BORDER_RADIUS: Record<NonNullable<FlexButtonProps[\"size\"]>, number> = {\n xl: 4,\n lg: 4,\n md: 2,\n sm: 2,\n xs: 2,\n};\n\n/**\n * FlexButton - A compact button component designed for use in modals and popups.\n *\n * Renders as a semantic `<button>` element with full ARIA support.\n *\n * ## Accessibility Features\n *\n * - **Semantic HTML**: Renders as a native `<button>` element\n * - **Keyboard Navigation**: Focusable via Tab, activated with Enter or Space\n * - **ARIA States**: Properly announces disabled and loading states\n * - **Focus Indicator**: Visible focus ring for keyboard navigation\n * - **Screen Reader Support**: Announces button label, state, and any associated descriptions\n */\nexport const FlexButton: React.FC<FlexButtonProps> = ({\n children,\n variant = \"brand\",\n size = \"md\",\n background = false,\n disabled = false,\n loading = false,\n iconLeft,\n iconRight,\n onPress,\n onClick,\n className,\n type = \"button\",\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n testID,\n tabIndex = 0,\n ...buttonProps\n}) => {\n const { theme } = useDesignSystem();\n const [state, setState] = useState<ButtonState>(\"default\");\n const [isFocused, setIsFocused] = useState(false);\n const isMouseOverRef = useRef(false);\n\n const isDisabled = disabled || loading;\n\n const getVariantColors = (\n currentState: ButtonState\n ): { bg: string; text: string; border?: string } => {\n if (isDisabled) {\n return {\n bg: background ? theme.colors.overlay.mono : \"transparent\",\n text: theme.colors.control.text.disable,\n border: undefined,\n };\n }\n\n const effectiveBackground = loading ? false : background;\n\n switch (variant) {\n case \"brand\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.brand.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.brand.primary.bgHover\n : theme.colors.background.brand.primary,\n text: theme.colors.content.on.brand,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.background.brand.primary\n : currentState === \"hover\"\n ? theme.colors.overlay.brand\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.on.brand\n : theme.colors.content.brand.primary,\n border: undefined,\n };\n\n case \"primary\":\n if (effectiveBackground) {\n return {\n bg: theme.colors.background.primary,\n text: theme.colors.content.primary,\n border:\n currentState === \"press\"\n ? theme.colors.border.primary\n : undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text: theme.colors.content.primary,\n border:\n currentState === \"press\" ? theme.colors.border.primary : undefined,\n };\n\n case \"secondary\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.secondary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.secondary.bgHover\n : theme.colors.background.secondary,\n text: theme.colors.content.secondary,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.primary\n : currentState === \"hover\"\n ? theme.colors.content.secondary\n : theme.colors.content.secondary,\n border: undefined,\n };\n\n case \"tertiary\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.secondary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.secondary.bgHover\n : theme.colors.background.secondary,\n text: theme.colors.content.tertiary,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.secondary\n : currentState === \"hover\"\n ? theme.colors.content.tertiary\n : theme.colors.content.tertiary,\n border: undefined,\n };\n\n case \"brandExtra\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.brandExtra.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.brandExtra.primary.bgHover\n : theme.colors.background.brandExtra.primary,\n text: theme.colors.content.on.brandExtra,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.background.brandExtra.primary\n : currentState === \"hover\"\n ? theme.colors.overlay.brandExtra\n : \"transparent\",\n text:\n currentState === \"press\"\n ? theme.colors.content.on.brandExtra\n : theme.colors.content.brandExtra.secondary,\n border: undefined,\n };\n\n case \"inverse\":\n if (effectiveBackground) {\n return {\n bg:\n currentState === \"press\"\n ? theme.colors.control.mono.primary.bgPress\n : currentState === \"hover\"\n ? theme.colors.control.mono.primary.bgHover\n : theme.colors.background.inverse,\n text: theme.colors.content.inverse,\n border: undefined,\n };\n }\n return {\n bg:\n currentState === \"press\" || currentState === \"hover\"\n ? theme.colors.overlay.mono\n : \"transparent\",\n text: theme.colors.content.inverse,\n border: undefined,\n };\n\n default:\n return {\n bg: \"transparent\",\n text: theme.colors.content.primary,\n border: undefined,\n };\n }\n };\n\n const getFocusRingColor = (): string => {\n switch (variant) {\n case \"brand\":\n return theme.colors.overlay.brand;\n case \"brandExtra\":\n return theme.colors.overlay.brandExtra;\n case \"inverse\":\n return \"rgba(255, 255, 255, 0.3)\";\n default:\n return theme.colors.overlay.mono;\n }\n };\n\n const getSpinnerColor = (): string => {\n switch (variant) {\n case \"brand\":\n return theme.colors.content.brand.primary;\n case \"primary\":\n return theme.colors.content.primary;\n case \"secondary\":\n return theme.colors.content.secondary;\n case \"tertiary\":\n return theme.colors.content.tertiary;\n case \"brandExtra\":\n return theme.colors.content.brandExtra.secondary;\n case \"inverse\":\n return theme.colors.content.inverse;\n default:\n return theme.colors.content.brand.primary;\n }\n };\n\n const colors = getVariantColors(state);\n const focusRingColor = getFocusRingColor();\n const spinnerColor = getSpinnerColor();\n const iconSize = ICON_SIZES[size];\n const spinnerSize = SPINNER_SIZES[size];\n const fontSize = FONT_SIZES[size];\n const borderRadius = BORDER_RADIUS[size];\n const lineHeight = LINE_HEIGHTS[size];\n\n const handleMouseEnter = () => {\n if (!isDisabled) {\n isMouseOverRef.current = true;\n setState(\"hover\");\n }\n };\n\n const handleMouseLeave = () => {\n if (!isDisabled) {\n isMouseOverRef.current = false;\n setState(\"default\");\n }\n };\n\n const handleMouseDown = () => {\n if (!isDisabled) {\n setState(\"press\");\n }\n };\n\n const handleMouseUp = () => {\n if (!isDisabled) {\n setState(isMouseOverRef.current ? \"hover\" : \"default\");\n }\n };\n\n const handleFocus = () => {\n if (!isDisabled) {\n setIsFocused(true);\n }\n };\n\n const handleBlur = () => {\n setIsFocused(false);\n };\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (onPress) {\n onPress();\n }\n if (onClick) {\n onClick(event);\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setState(\"press\");\n }\n };\n\n const handleKeyUp = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setState(isMouseOverRef.current ? \"hover\" : \"default\");\n if (onPress) {\n onPress();\n }\n }\n };\n\n const borderShadow = colors.border\n ? `inset 0 0 0 1px ${colors.border}`\n : undefined;\n const focusShadow =\n isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : undefined;\n\n const boxShadows: string[] = [];\n if (borderShadow) boxShadows.push(borderShadow);\n if (focusShadow) boxShadows.push(focusShadow);\n const combinedBoxShadow =\n boxShadows.length > 0 ? boxShadows.join(\", \") : \"none\";\n\n const buttonStyle: CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2px\",\n padding: \"4px\",\n backgroundColor: loading ? \"transparent\" : colors.bg,\n color: colors.text,\n border: \"none\",\n borderWidth: \"0px\",\n borderRadius: `${borderRadius}px`,\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\n fontSize: `${fontSize}px`,\n fontWeight: 500,\n lineHeight: lineHeight,\n fontFamily: \"inherit\",\n transition:\n \"background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out\",\n outline: \"none\",\n boxShadow: combinedBoxShadow,\n opacity: isDisabled && !loading ? 0.6 : 1,\n };\n\n const contentStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2px\",\n };\n\n const spinnerStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"transparent\",\n height: lineHeight,\n };\n\n const computedAriaLabel =\n ariaLabel || (typeof children === \"string\" ? children : undefined);\n\n return (\n <button\n {...buttonProps}\n type={type}\n className={className}\n disabled={isDisabled}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onFocus={handleFocus}\n onBlur={handleBlur}\n aria-label={computedAriaLabel}\n aria-busy={loading || undefined}\n aria-disabled={isDisabled || undefined}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n tabIndex={tabIndex}\n style={buttonStyle}\n data-testid={testID || \"flex-button\"}\n >\n <span style={contentStyle}>\n {loading ? (\n <span style={spinnerStyle}>\n <Spinner size={spinnerSize} color={spinnerColor} />\n </span>\n ) : (\n <>\n {iconLeft && (\n <Icon size={iconSize} color={colors.text}>\n {iconLeft}\n </Icon>\n )}\n <span>{children}</span>\n {iconRight && (\n <Icon size={iconSize} color={colors.text}>\n {iconRight}\n </Icon>\n )}\n </>\n )}\n </span>\n </button>\n );\n};\n\nFlexButton.displayName = \"FlexButton\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\n\nexport interface ButtonGroupProps {\n /**\n * Layout orientation of the buttons\n * @default 'horizontal'\n */\n orientation?: \"horizontal\" | \"vertical\";\n /**\n * Size of the button group, determines default gap between buttons\n * @default 'md'\n */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n /**\n * Buttons to be grouped\n */\n children: React.ReactNode;\n /**\n * Optional description text below the buttons\n */\n description?: string;\n /**\n * Optional error message text below the buttons\n */\n error?: string;\n /**\n * Custom gap between buttons (in pixels). If not provided, uses size and orientation based default.\n */\n gap?: number;\n /**\n * Accessible label for the button group\n */\n \"aria-label\"?: string;\n /**\n * ID of element that labels this button group\n */\n \"aria-labelledby\"?: string;\n /**\n * ID of element that describes this button group\n */\n \"aria-describedby\"?: string;\n /**\n * HTML id attribute\n */\n id?: string;\n /**\n * Test ID for testing frameworks\n */\n testID?: string;\n}\n\n/**\n * ButtonGroup - A container for grouping related buttons\n *\n * Provides semantic grouping for related actions with proper accessibility support.\n *\n * ## Accessibility Features\n *\n * - **Semantic Grouping**: Uses `role=\"group\"` to indicate related buttons\n * - **Accessible Name**: Supports `aria-label` or `aria-labelledby` to describe the group's purpose\n * - **Error Announcements**: Errors are announced to screen readers via `aria-live`\n * - **Description Support**: Optional description text for additional context\n *\n */\nexport const ButtonGroup: React.FC<ButtonGroupProps> = ({\n orientation = \"horizontal\",\n size = \"md\",\n children,\n description,\n error,\n gap,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n id,\n testID,\n}) => {\n const { theme } = useDesignSystem();\n\n // Flatten children to handle fragments and get actual button elements\n const flattenChildren = (children: React.ReactNode): React.ReactNode[] => {\n const result: React.ReactNode[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n result.push(...flattenChildren(child.props.children));\n } else if (child !== null && child !== undefined) {\n result.push(child);\n }\n });\n return result;\n };\n\n const flatChildren = flattenChildren(children);\n const childCount = flatChildren.length;\n\n // Check if we need space-between layout (horizontal with more than 2 buttons)\n const useSpaceBetween = orientation === \"horizontal\" && childCount > 2;\n\n // Size-based default gaps by orientation\n const verticalGapMap = {\n xl: 16,\n lg: 16,\n md: 12,\n sm: 8,\n xs: 4,\n };\n\n const horizontalGapMap = {\n xl: 16,\n lg: 16,\n md: 16,\n sm: 12,\n xs: 12,\n };\n\n // Use provided gap or fall back to orientation and size based default\n const computedGap =\n gap ??\n (orientation === \"vertical\"\n ? verticalGapMap[size]\n : horizontalGapMap[size]);\n\n // Generate IDs for description and error elements\n const descriptionId = id ? `${id}-description` : undefined;\n const errorId = id ? `${id}-error` : undefined;\n\n // Build aria-describedby value combining external and internal references\n const computedAriaDescribedBy =\n [\n ariaDescribedBy,\n error && errorId ? errorId : undefined,\n description && !error && descriptionId ? descriptionId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n // Apply fullWidth to children in vertical orientation for proper alignment\n const processChildren = (childrenToProcess: React.ReactNode[]) => {\n if (orientation === \"vertical\") {\n return childrenToProcess.map((child, index) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n ...child.props,\n fullWidth: true,\n key: child.key ?? index,\n });\n }\n return child;\n });\n }\n return childrenToProcess;\n };\n\n // Split children for space-between layout\n const renderChildren = () => {\n const processedChildren = processChildren(flatChildren);\n\n if (useSpaceBetween) {\n const firstChild = processedChildren[0];\n const restChildren = processedChildren.slice(1);\n\n return (\n <>\n {firstChild}\n <Box flexDirection=\"row\" gap={computedGap}>\n {restChildren}\n </Box>\n </>\n );\n }\n\n // For non-space-between layout, return processed children or original\n if (orientation === \"vertical\") {\n return processedChildren;\n }\n return children;\n };\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" gap={8}>\n <Box\n role=\"group\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={computedAriaDescribedBy}\n id={id}\n testID={testID}\n flexDirection={orientation === \"horizontal\" ? \"row\" : \"column\"}\n alignItems=\"stretch\"\n gap={computedGap}\n justifyContent={useSpaceBetween ? \"space-between\" : undefined}\n width=\"100%\"\n >\n {renderChildren()}\n </Box>\n\n {error && (\n <Box marginTop={4}>\n <Text\n id={errorId}\n role=\"alert\"\n aria-live=\"assertive\"\n color={theme.colors.content.alert.primary}\n fontSize={14}\n fontWeight=\"400\"\n style={\n orientation === \"vertical\" ? { textAlign: \"center\" } : undefined\n }\n >\n {error}\n </Text>\n </Box>\n )}\n\n {description && !error && (\n <Box marginTop={4}>\n <Text\n id={descriptionId}\n color={theme.colors.content.tertiary}\n fontSize={14}\n fontWeight=\"400\"\n style={\n orientation === \"vertical\" ? { textAlign: \"center\" } : undefined\n }\n >\n {description}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n\nButtonGroup.displayName = \"ButtonGroup\";\n"],"mappings":"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","names":["jsx","View","jsx","View","jsx","View","jsx","jsx","forwardRef","RNTextInput","jsx","jsx","useState","useDesignSystem","jsx","useState","useState","useDesignSystem","jsx","jsxs","useState","React","useDesignSystem","Fragment","jsx","jsxs","children","React"]}
package/package.json CHANGED
@@ -1,25 +1,35 @@
1
1
  {
2
2
  "name": "@xsolla/xui-button",
3
- "version": "0.69.0",
3
+ "version": "0.71.0-pr105.1769420965",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "yarn build:web && yarn build:native",
9
9
  "build:web": "PLATFORM=web tsup",
10
- "build:native": "PLATFORM=native tsup"
10
+ "build:native": "PLATFORM=native tsup",
11
+ "test": "vitest",
12
+ "test:run": "vitest run",
13
+ "test:coverage": "vitest run --coverage"
11
14
  },
12
15
  "dependencies": {
13
- "@xsolla/xui-core": "0.69.0",
14
- "@xsolla/xui-icons": "0.69.0",
15
- "@xsolla/xui-primitives-core": "0.69.0"
16
+ "@xsolla/xui-core": "0.71.0-pr105.1769420965",
17
+ "@xsolla/xui-icons": "0.71.0-pr105.1769420965",
18
+ "@xsolla/xui-primitives-core": "0.71.0-pr105.1769420965"
16
19
  },
17
20
  "peerDependencies": {
18
21
  "react": ">=16.8.0",
19
22
  "styled-components": ">=4"
20
23
  },
21
24
  "devDependencies": {
22
- "tsup": "^8.0.0"
25
+ "@testing-library/jest-dom": "^6.1.5",
26
+ "@testing-library/react": "^14.1.2",
27
+ "@vitest/coverage-v8": "^1.0.0",
28
+ "jsdom": "^24.0.0",
29
+ "react": "^18.0.0",
30
+ "react-dom": "^18.0.0",
31
+ "tsup": "^8.0.0",
32
+ "vitest": "^1.0.0"
23
33
  },
24
34
  "license": "MIT",
25
35
  "react-native": "./native/index.js",
package/web/index.d.mts CHANGED
@@ -6,7 +6,7 @@ interface ButtonProps {
6
6
  /** Color tone of the button */
7
7
  tone?: "brand" | "brandExtra" | "alert" | "mono";
8
8
  /** Size of the button */
9
- size?: "xl" | "l" | "m" | "s" | "xs";
9
+ size?: "xl" | "lg" | "md" | "sm" | "xs";
10
10
  /** Whether the button is disabled */
11
11
  disabled?: boolean;
12
12
  /** Whether the button is in a loading state */
@@ -63,7 +63,7 @@ interface IconButtonProps {
63
63
  /** Color tone of the button */
64
64
  tone?: "brand" | "brandExtra" | "alert" | "mono";
65
65
  /** Size of the button */
66
- size?: "xl" | "l" | "m" | "s" | "xs";
66
+ size?: "xl" | "lg" | "md" | "sm" | "xs";
67
67
  /** Whether the button is disabled */
68
68
  disabled?: boolean;
69
69
  /** Whether the button is in a loading state */
@@ -138,7 +138,7 @@ interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
138
138
  /** Visual variant of the button */
139
139
  variant?: "brand" | "primary" | "secondary" | "tertiary" | "brandExtra" | "inverse";
140
140
  /** Size of the button */
141
- size?: "xl" | "l" | "m" | "s" | "xs";
141
+ size?: "xl" | "lg" | "md" | "sm" | "xs";
142
142
  /** Whether to show background fill */
143
143
  background?: boolean;
144
144
  /** Whether the button is disabled */
@@ -191,9 +191,9 @@ interface ButtonGroupProps {
191
191
  orientation?: "horizontal" | "vertical";
192
192
  /**
193
193
  * Size of the button group, determines default gap between buttons
194
- * @default 'm'
194
+ * @default 'md'
195
195
  */
196
- size?: "xl" | "l" | "m" | "s" | "xs";
196
+ size?: "xl" | "lg" | "md" | "sm" | "xs";
197
197
  /**
198
198
  * Buttons to be grouped
199
199
  */