@xsolla/xui-button 0.64.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/native/index.js CHANGED
@@ -1182,6 +1182,7 @@ var FlexButton = ({
1182
1182
  FlexButton.displayName = "FlexButton";
1183
1183
 
1184
1184
  // src/ButtonGroup.tsx
1185
+ var import_react7 = __toESM(require("react"));
1185
1186
  var import_xui_core4 = require("@xsolla/xui-core");
1186
1187
  var import_jsx_runtime11 = require("react/jsx-runtime");
1187
1188
  var ButtonGroup = ({
@@ -1198,6 +1199,20 @@ var ButtonGroup = ({
1198
1199
  testID
1199
1200
  }) => {
1200
1201
  const { theme } = (0, import_xui_core4.useDesignSystem)();
1202
+ const flattenChildren = (children2) => {
1203
+ const result = [];
1204
+ import_react7.default.Children.forEach(children2, (child) => {
1205
+ if (import_react7.default.isValidElement(child) && child.type === import_react7.default.Fragment) {
1206
+ result.push(...flattenChildren(child.props.children));
1207
+ } else if (child !== null && child !== void 0) {
1208
+ result.push(child);
1209
+ }
1210
+ });
1211
+ return result;
1212
+ };
1213
+ const flatChildren = flattenChildren(children);
1214
+ const childCount = flatChildren.length;
1215
+ const useSpaceBetween = orientation === "horizontal" && childCount > 2;
1201
1216
  const verticalGapMap = {
1202
1217
  xl: 16,
1203
1218
  l: 16,
@@ -1220,6 +1235,36 @@ var ButtonGroup = ({
1220
1235
  error && errorId ? errorId : void 0,
1221
1236
  description && !error && descriptionId ? descriptionId : void 0
1222
1237
  ].filter(Boolean).join(" ") || void 0;
1238
+ const processChildren = (childrenToProcess) => {
1239
+ if (orientation === "vertical") {
1240
+ return childrenToProcess.map((child, index) => {
1241
+ if (import_react7.default.isValidElement(child)) {
1242
+ return import_react7.default.cloneElement(child, {
1243
+ ...child.props,
1244
+ fullWidth: true,
1245
+ key: child.key ?? index
1246
+ });
1247
+ }
1248
+ return child;
1249
+ });
1250
+ }
1251
+ return childrenToProcess;
1252
+ };
1253
+ const renderChildren = () => {
1254
+ const processedChildren = processChildren(flatChildren);
1255
+ if (useSpaceBetween) {
1256
+ const firstChild = processedChildren[0];
1257
+ const restChildren = processedChildren.slice(1);
1258
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1259
+ firstChild,
1260
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { flexDirection: "row", gap: computedGap, children: restChildren })
1261
+ ] });
1262
+ }
1263
+ if (orientation === "vertical") {
1264
+ return processedChildren;
1265
+ }
1266
+ return children;
1267
+ };
1223
1268
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box, { flexDirection: "column", width: "100%", gap: 8, children: [
1224
1269
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1225
1270
  Box,
@@ -1233,8 +1278,9 @@ var ButtonGroup = ({
1233
1278
  flexDirection: orientation === "horizontal" ? "row" : "column",
1234
1279
  alignItems: "stretch",
1235
1280
  gap: computedGap,
1281
+ justifyContent: useSpaceBetween ? "space-between" : void 0,
1236
1282
  width: "100%",
1237
- children
1283
+ children: renderChildren()
1238
1284
  }
1239
1285
  ),
1240
1286
  error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { marginTop: 4, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -1246,6 +1292,7 @@ var ButtonGroup = ({
1246
1292
  color: theme.colors.content.alert.primary,
1247
1293
  fontSize: 14,
1248
1294
  fontWeight: "400",
1295
+ style: orientation === "vertical" ? { textAlign: "center" } : void 0,
1249
1296
  children: error
1250
1297
  }
1251
1298
  ) }),
@@ -1256,6 +1303,7 @@ var ButtonGroup = ({
1256
1303
  color: theme.colors.content.tertiary,
1257
1304
  fontSize: 14,
1258
1305
  fontWeight: "400",
1306
+ style: orientation === "vertical" ? { textAlign: "center" } : void 0,
1259
1307
  children: description
1260
1308
  }
1261
1309
  ) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../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":["export * from \"./Button\";\nexport * from \"./IconButton\";\nexport * from \"./FlexButton\";\nexport * from \"./ButtonGroup\";\n","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 type 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 // 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 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 width=\"100%\"\n >\n {children}\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 >\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 >\n {description}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n\nButtonGroup.displayName = \"ButtonGroup\";\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","import_react_native","import_jsx_runtime","React","import_react_native","import_jsx_runtime","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_xui_core","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../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":["export * from \"./Button\";\nexport * from \"./IconButton\";\nexport * from \"./FlexButton\";\nexport * from \"./ButtonGroup\";\n","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":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","import_react_native","import_jsx_runtime","React","import_react_native","import_jsx_runtime","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","children","React"]}
package/native/index.mjs CHANGED
@@ -1147,8 +1147,9 @@ var FlexButton = ({
1147
1147
  FlexButton.displayName = "FlexButton";
1148
1148
 
1149
1149
  // src/ButtonGroup.tsx
1150
+ import React6 from "react";
1150
1151
  import { useDesignSystem as useDesignSystem4 } from "@xsolla/xui-core";
1151
- import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
1152
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
1152
1153
  var ButtonGroup = ({
1153
1154
  orientation = "horizontal",
1154
1155
  size = "m",
@@ -1163,6 +1164,20 @@ var ButtonGroup = ({
1163
1164
  testID
1164
1165
  }) => {
1165
1166
  const { theme } = useDesignSystem4();
1167
+ const flattenChildren = (children2) => {
1168
+ const result = [];
1169
+ React6.Children.forEach(children2, (child) => {
1170
+ if (React6.isValidElement(child) && child.type === React6.Fragment) {
1171
+ result.push(...flattenChildren(child.props.children));
1172
+ } else if (child !== null && child !== void 0) {
1173
+ result.push(child);
1174
+ }
1175
+ });
1176
+ return result;
1177
+ };
1178
+ const flatChildren = flattenChildren(children);
1179
+ const childCount = flatChildren.length;
1180
+ const useSpaceBetween = orientation === "horizontal" && childCount > 2;
1166
1181
  const verticalGapMap = {
1167
1182
  xl: 16,
1168
1183
  l: 16,
@@ -1185,6 +1200,36 @@ var ButtonGroup = ({
1185
1200
  error && errorId ? errorId : void 0,
1186
1201
  description && !error && descriptionId ? descriptionId : void 0
1187
1202
  ].filter(Boolean).join(" ") || void 0;
1203
+ const processChildren = (childrenToProcess) => {
1204
+ if (orientation === "vertical") {
1205
+ return childrenToProcess.map((child, index) => {
1206
+ if (React6.isValidElement(child)) {
1207
+ return React6.cloneElement(child, {
1208
+ ...child.props,
1209
+ fullWidth: true,
1210
+ key: child.key ?? index
1211
+ });
1212
+ }
1213
+ return child;
1214
+ });
1215
+ }
1216
+ return childrenToProcess;
1217
+ };
1218
+ const renderChildren = () => {
1219
+ const processedChildren = processChildren(flatChildren);
1220
+ if (useSpaceBetween) {
1221
+ const firstChild = processedChildren[0];
1222
+ const restChildren = processedChildren.slice(1);
1223
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
1224
+ firstChild,
1225
+ /* @__PURE__ */ jsx11(Box, { flexDirection: "row", gap: computedGap, children: restChildren })
1226
+ ] });
1227
+ }
1228
+ if (orientation === "vertical") {
1229
+ return processedChildren;
1230
+ }
1231
+ return children;
1232
+ };
1188
1233
  return /* @__PURE__ */ jsxs3(Box, { flexDirection: "column", width: "100%", gap: 8, children: [
1189
1234
  /* @__PURE__ */ jsx11(
1190
1235
  Box,
@@ -1198,8 +1243,9 @@ var ButtonGroup = ({
1198
1243
  flexDirection: orientation === "horizontal" ? "row" : "column",
1199
1244
  alignItems: "stretch",
1200
1245
  gap: computedGap,
1246
+ justifyContent: useSpaceBetween ? "space-between" : void 0,
1201
1247
  width: "100%",
1202
- children
1248
+ children: renderChildren()
1203
1249
  }
1204
1250
  ),
1205
1251
  error && /* @__PURE__ */ jsx11(Box, { marginTop: 4, children: /* @__PURE__ */ jsx11(
@@ -1211,6 +1257,7 @@ var ButtonGroup = ({
1211
1257
  color: theme.colors.content.alert.primary,
1212
1258
  fontSize: 14,
1213
1259
  fontWeight: "400",
1260
+ style: orientation === "vertical" ? { textAlign: "center" } : void 0,
1214
1261
  children: error
1215
1262
  }
1216
1263
  ) }),
@@ -1221,6 +1268,7 @@ var ButtonGroup = ({
1221
1268
  color: theme.colors.content.tertiary,
1222
1269
  fontSize: 14,
1223
1270
  fontWeight: "400",
1271
+ style: orientation === "vertical" ? { textAlign: "center" } : void 0,
1224
1272
  children: description
1225
1273
  }
1226
1274
  ) })