@xsolla/xui-select 0.158.0 → 0.159.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Select.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Select\";\n","import React, { useState, useRef, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n ChevronDown,\n ChevronUp,\n ExclamationMarkCr,\n Search as SearchIcon,\n} from \"@xsolla/xui-icons-base\";\n\nexport interface SelectOption {\n label: string;\n value: any;\n disabled?: boolean;\n}\n\nexport interface SelectProps extends ThemeOverrideProps {\n value?: string;\n placeholder?: string;\n onPress?: () => void;\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n state?: \"default\" | \"hover\" | \"focus\" | \"disable\" | \"error\";\n disabled?: boolean;\n label?: string;\n errorMessage?: string;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n filled?: boolean;\n iconOnly?: boolean;\n options?: (string | SelectOption)[];\n onChange?: (value: string) => void;\n searchable?: boolean;\n searchPlaceholder?: string;\n noOptionsMessage?: string;\n maxHeight?: number;\n}\n\nexport const Select: React.FC<SelectProps> = ({\n value,\n placeholder = \"Select\",\n onPress,\n size = \"md\",\n state: externalState,\n disabled = false,\n label,\n errorMessage,\n iconLeft,\n iconRight,\n filled = true,\n iconOnly = false,\n options = [],\n onChange,\n searchable = false,\n searchPlaceholder = \"Search\",\n noOptionsMessage = \"No results\",\n maxHeight = 300,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const [isOpen, setIsOpen] = useState(false);\n const [selectedValue, setSelectedValue] = useState<string | undefined>(value);\n const [searchValue, setSearchValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const selectedItemRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const isDisable = externalState === \"disable\" || disabled;\n const isError = externalState === \"error\" || !!errorMessage;\n const isFocus = externalState === \"focus\" || isOpen;\n\n // Sync selectedValue with value prop\n React.useEffect(() => {\n if (value !== undefined) {\n setSelectedValue(value);\n }\n }, [value]);\n\n // Auto-scroll to selected item when dropdown opens (show at top)\n useEffect(() => {\n if (isFocus && selectedItemRef.current && dropdownRef.current) {\n // Use setTimeout to ensure DOM has rendered\n const timeoutId = setTimeout(() => {\n const selectedItem = selectedItemRef.current;\n if (selectedItem && isWeb) {\n selectedItem.scrollIntoView({ block: \"nearest\" });\n }\n }, 0);\n return () => clearTimeout(timeoutId);\n }\n }, [isFocus]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (isFocus && searchable) {\n searchInputRef.current?.focus();\n }\n }, [isFocus, searchable]);\n\n // Reset search when dropdown closes\n useEffect(() => {\n if (!isFocus) {\n setSearchValue(\"\");\n }\n }, [isFocus]);\n\n // Close dropdown when clicking outside (web only)\n useEffect(() => {\n if (isNative || !isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const getOptionLabel = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.label;\n };\n\n const getOptionValue = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.value;\n };\n\n const getOptionDisabled = (option: string | SelectOption) => {\n if (typeof option === \"string\") return false;\n return option.disabled || false;\n };\n\n // Filter options based on search value\n const filteredOptions =\n searchable && searchValue\n ? options.filter((option) => {\n const label = getOptionLabel(option);\n return label.toLowerCase().includes(searchValue.toLowerCase());\n })\n : options;\n\n // 1. Resolve Config from Theme\n const sizeStyles = theme.sizing.input(size);\n const inputColors = theme.colors.control.input;\n\n const handlePress = () => {\n if (!isDisable) {\n if (onPress) onPress();\n setIsOpen(!isOpen);\n }\n };\n\n const handleSelect = (option: string | SelectOption) => {\n if (getOptionDisabled(option)) return;\n const val = getOptionValue(option);\n setSelectedValue(val);\n setIsOpen(false);\n if (onChange) onChange(val);\n };\n\n // Resolve background and border colors based on state\n const isHover = externalState === \"hover\";\n let backgroundColor = inputColors.bg;\n let borderColor = inputColors.border;\n\n if (isDisable) {\n backgroundColor = inputColors.bgDisable;\n borderColor = inputColors.borderDisable;\n } else if (isFocus) {\n backgroundColor = theme.colors.control.focus.bg;\n borderColor = isError\n ? theme.colors.border.alert\n : theme.colors.border.brand;\n } else if (isError) {\n borderColor = theme.colors.border.alert;\n } else if (isHover) {\n backgroundColor = inputColors.bgHover;\n borderColor = inputColors.borderHover;\n }\n\n // Handle filled override if provided\n if (filled === false && !isFocus && !isError && !isHover) {\n backgroundColor = \"transparent\";\n }\n\n const currentLabel = selectedValue\n ? getOptionLabel(\n options.find((o) => getOptionValue(o) === selectedValue) ||\n selectedValue\n )\n : placeholder;\n\n const textColor = isDisable\n ? inputColors.textDisable\n : selectedValue\n ? inputColors.text\n : inputColors.placeholder;\n const iconColor = isDisable ? inputColors.textDisable : inputColors.text;\n\n return (\n <Box\n ref={containerRef}\n flexDirection=\"column\"\n gap={sizeStyles.fieldGap}\n width=\"100%\"\n position=\"relative\"\n >\n {label && (\n <Text\n color={theme.colors.content.secondary}\n fontSize={sizeStyles.fontSize - 2}\n fontWeight=\"500\"\n >\n {label}\n </Text>\n )}\n <Box\n onPress={handlePress}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={borderColor !== \"transparent\" ? 1 : 0}\n borderRadius={sizeStyles.radius}\n height={sizeStyles.height}\n width={iconOnly ? sizeStyles.height : \"100%\"}\n paddingHorizontal={iconOnly ? 0 : sizeStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={iconOnly ? \"center\" : \"flex-start\"}\n gap={iconOnly ? 4 : 12}\n position=\"relative\"\n hoverStyle={\n !isDisable && !isFocus && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n >\n {iconLeft && (\n <Box alignItems=\"center\" justifyContent=\"center\">\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconLeft}\n </Icon>\n </Box>\n )}\n\n {!iconOnly && (\n <Box flex={1} height=\"100%\" justifyContent=\"center\">\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n numberOfLines={1}\n >\n {currentLabel}\n </Text>\n </Box>\n )}\n\n {/* Trailing controls */}\n <Box flexDirection=\"row\" alignItems=\"center\" gap={4}>\n {/* Error icon */}\n {isError && (\n <Icon\n size={sizeStyles.iconSize}\n color={theme.colors.content.alert.primary}\n >\n <ExclamationMarkCr />\n </Icon>\n )}\n\n {/* Right icon or default caret */}\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconRight !== undefined ? (\n iconRight\n ) : isFocus ? (\n <ChevronUp />\n ) : (\n <ChevronDown />\n )}\n </Icon>\n </Box>\n </Box>\n\n {/* Dropdown Menu */}\n {isFocus && options.length > 0 && (\n <Box\n ref={dropdownRef}\n position=\"absolute\"\n top={\n sizeStyles.height +\n (label ? sizeStyles.fontSize + sizeStyles.fieldGap : 0) +\n sizeStyles.fieldGap\n }\n width=\"100%\"\n backgroundColor={theme.colors.background.secondary}\n borderColor={theme.colors.border.secondary}\n borderWidth={1}\n borderRadius={theme.radius.button}\n style={{\n zIndex: 1000,\n ...(isNative\n ? { elevation: 4 }\n : { boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\" }),\n minWidth: iconOnly ? sizeStyles.height * 3 : undefined,\n }}\n >\n {/* Search Input - Outside scrollable area (web only) */}\n {searchable && !isNative && (\n <Box\n paddingHorizontal={sizeStyles.paddingHorizontal}\n paddingVertical={sizeStyles.paddingVertical}\n borderBottomWidth={1}\n borderColor={theme.colors.border.secondary}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={sizeStyles.paddingHorizontal / 2}\n paddingHorizontal={4}\n >\n <Icon\n size={sizeStyles.iconSize - 2}\n color={inputColors.placeholder}\n >\n <SearchIcon />\n </Icon>\n <Box\n as=\"input\"\n ref={searchInputRef}\n flex={1}\n type=\"text\"\n value={searchValue}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setSearchValue(e.target.value)\n }\n placeholder={searchPlaceholder}\n style={{\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n color: inputColors.text,\n fontSize: sizeStyles.fontSize,\n width: \"100%\",\n }}\n />\n </Box>\n </Box>\n )}\n\n {/* Options List - Scrollable */}\n <Box\n paddingVertical={4}\n overflow=\"scroll\"\n style={{\n maxHeight: searchable ? maxHeight - 60 : maxHeight,\n ...(isWeb ? { overflowY: \"auto\" } : {}),\n }}\n >\n {filteredOptions.length === 0 ? (\n <Box\n paddingVertical={sizeStyles.paddingVertical * 2}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n alignItems=\"center\"\n >\n <Text\n color={theme.colors.content.tertiary}\n fontSize={sizeStyles.fontSize}\n >\n {noOptionsMessage}\n </Text>\n </Box>\n ) : (\n filteredOptions.map((option, index) => {\n const optionValue = getOptionValue(option);\n const optionLabel = getOptionLabel(option);\n const isOptionDisabled = getOptionDisabled(option);\n const isSelected = optionValue === selectedValue;\n const brandColors = theme.colors.control.brand.primary;\n const contentColors = theme.colors.content;\n\n return (\n <Box\n key={index}\n ref={isSelected ? selectedItemRef : undefined}\n paddingVertical={sizeStyles.paddingVertical}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n onPress={\n isOptionDisabled ? undefined : () => handleSelect(option)\n }\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n backgroundColor={\n isSelected ? brandColors.bg : \"transparent\"\n }\n style={{\n ...(isWeb\n ? {\n cursor: isOptionDisabled\n ? \"not-allowed\"\n : \"pointer\",\n }\n : {}),\n opacity: isOptionDisabled ? 0.5 : 1,\n }}\n hoverStyle={\n !isSelected && !isOptionDisabled\n ? {\n backgroundColor: theme.colors.control.input.bgHover,\n }\n : undefined\n }\n >\n <Text\n color={\n isSelected\n ? contentColors.on.brand\n : theme.colors.content.secondary\n }\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n >\n {optionLabel}\n </Text>\n </Box>\n );\n })\n )}\n </Box>\n </Box>\n )}\n\n {isError && errorMessage && (\n <Text\n color={theme.colors.content.alert.primary}\n fontSize={sizeStyles.fontSize - 2}\n style={{ lineHeight: sizeStyles.lineHeight + \"px\" }}\n >\n {errorMessage}\n </Text>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","React","label","SearchIcon"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Select.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Select\";\n","import React, { useState, useRef, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n ChevronDown,\n ChevronUp,\n ExclamationMarkCr,\n Search as SearchIcon,\n} from \"@xsolla/xui-icons-base\";\n\nexport interface SelectOption {\n label: string;\n value: any;\n disabled?: boolean;\n}\n\nexport interface SelectProps extends ThemeOverrideProps {\n value?: string;\n placeholder?: string;\n onPress?: () => void;\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n state?: \"default\" | \"hover\" | \"focus\" | \"disable\" | \"error\";\n disabled?: boolean;\n label?: string;\n errorMessage?: string;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n filled?: boolean;\n iconOnly?: boolean;\n options?: (string | SelectOption)[];\n onChange?: (value: string) => void;\n searchable?: boolean;\n searchPlaceholder?: string;\n noOptionsMessage?: string;\n maxHeight?: number;\n /** Whether the select should stretch to fill the full width of its container */\n fullWidth?: boolean;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Select: React.FC<SelectProps> = ({\n value,\n placeholder = \"Select\",\n onPress,\n size = \"md\",\n state: externalState,\n disabled = false,\n label,\n errorMessage,\n iconLeft,\n iconRight,\n filled = true,\n iconOnly = false,\n options = [],\n onChange,\n searchable = false,\n searchPlaceholder = \"Search\",\n noOptionsMessage = \"No results\",\n maxHeight = 300,\n fullWidth = true,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const [isOpen, setIsOpen] = useState(false);\n const [selectedValue, setSelectedValue] = useState<string | undefined>(value);\n const [searchValue, setSearchValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const selectedItemRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const isDisable = externalState === \"disable\" || disabled;\n const isError = externalState === \"error\" || !!errorMessage;\n const isFocus = externalState === \"focus\" || isOpen;\n\n // Sync selectedValue with value prop\n React.useEffect(() => {\n if (value !== undefined) {\n setSelectedValue(value);\n }\n }, [value]);\n\n // Auto-scroll to selected item when dropdown opens (show at top)\n useEffect(() => {\n if (isFocus && selectedItemRef.current && dropdownRef.current) {\n // Use setTimeout to ensure DOM has rendered\n const timeoutId = setTimeout(() => {\n const selectedItem = selectedItemRef.current;\n if (selectedItem && isWeb) {\n selectedItem.scrollIntoView({ block: \"nearest\" });\n }\n }, 0);\n return () => clearTimeout(timeoutId);\n }\n }, [isFocus]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (isFocus && searchable) {\n searchInputRef.current?.focus();\n }\n }, [isFocus, searchable]);\n\n // Reset search when dropdown closes\n useEffect(() => {\n if (!isFocus) {\n setSearchValue(\"\");\n }\n }, [isFocus]);\n\n // Close dropdown when clicking outside (web only)\n useEffect(() => {\n if (isNative || !isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const getOptionLabel = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.label;\n };\n\n const getOptionValue = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.value;\n };\n\n const getOptionDisabled = (option: string | SelectOption) => {\n if (typeof option === \"string\") return false;\n return option.disabled || false;\n };\n\n // Filter options based on search value\n const filteredOptions =\n searchable && searchValue\n ? options.filter((option) => {\n const label = getOptionLabel(option);\n return label.toLowerCase().includes(searchValue.toLowerCase());\n })\n : options;\n\n // 1. Resolve Config from Theme\n const sizeStyles = theme.sizing.input(size);\n const inputColors = theme.colors.control.input;\n\n const handlePress = () => {\n if (!isDisable) {\n if (onPress) onPress();\n setIsOpen(!isOpen);\n }\n };\n\n const handleSelect = (option: string | SelectOption) => {\n if (getOptionDisabled(option)) return;\n const val = getOptionValue(option);\n setSelectedValue(val);\n setIsOpen(false);\n if (onChange) onChange(val);\n };\n\n // Resolve background and border colors based on state\n const isHover = externalState === \"hover\";\n let backgroundColor = inputColors.bg;\n let borderColor = inputColors.border;\n\n if (isDisable) {\n backgroundColor = inputColors.bgDisable;\n borderColor = inputColors.borderDisable;\n } else if (isFocus) {\n backgroundColor = theme.colors.control.focus.bg;\n borderColor = isError\n ? theme.colors.border.alert\n : theme.colors.border.brand;\n } else if (isError) {\n borderColor = theme.colors.border.alert;\n } else if (isHover) {\n backgroundColor = inputColors.bgHover;\n borderColor = inputColors.borderHover;\n }\n\n // Handle filled override if provided\n if (filled === false && !isFocus && !isError && !isHover) {\n backgroundColor = \"transparent\";\n }\n\n const currentLabel = selectedValue\n ? getOptionLabel(\n options.find((o) => getOptionValue(o) === selectedValue) ||\n selectedValue\n )\n : placeholder;\n\n const textColor = isDisable\n ? inputColors.textDisable\n : selectedValue\n ? inputColors.text\n : inputColors.placeholder;\n const iconColor = isDisable ? inputColors.textDisable : inputColors.text;\n\n return (\n <Box\n testID={testID}\n ref={containerRef}\n flexDirection=\"column\"\n gap={sizeStyles.fieldGap}\n width={fullWidth ? \"100%\" : undefined}\n position=\"relative\"\n >\n {label && (\n <Text\n color={theme.colors.content.secondary}\n fontSize={sizeStyles.fontSize - 2}\n fontWeight=\"500\"\n >\n {label}\n </Text>\n )}\n <Box\n onPress={handlePress}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={borderColor !== \"transparent\" ? 1 : 0}\n borderRadius={sizeStyles.radius}\n height={sizeStyles.height}\n width={iconOnly ? sizeStyles.height : \"100%\"}\n paddingHorizontal={iconOnly ? 0 : sizeStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={iconOnly ? \"center\" : \"flex-start\"}\n gap={iconOnly ? 4 : 12}\n position=\"relative\"\n hoverStyle={\n !isDisable && !isFocus && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n >\n {iconLeft && (\n <Box alignItems=\"center\" justifyContent=\"center\">\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconLeft}\n </Icon>\n </Box>\n )}\n\n {!iconOnly && (\n <Box flex={1} height=\"100%\" justifyContent=\"center\">\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n numberOfLines={1}\n >\n {currentLabel}\n </Text>\n </Box>\n )}\n\n {/* Trailing controls */}\n <Box flexDirection=\"row\" alignItems=\"center\" gap={4}>\n {/* Error icon */}\n {isError && (\n <Icon\n size={sizeStyles.iconSize}\n color={theme.colors.content.alert.primary}\n >\n <ExclamationMarkCr />\n </Icon>\n )}\n\n {/* Right icon or default caret */}\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconRight !== undefined ? (\n iconRight\n ) : isFocus ? (\n <ChevronUp />\n ) : (\n <ChevronDown />\n )}\n </Icon>\n </Box>\n </Box>\n\n {/* Dropdown Menu */}\n {isFocus && options.length > 0 && (\n <Box\n ref={dropdownRef}\n position=\"absolute\"\n top={\n sizeStyles.height +\n (label ? sizeStyles.fontSize + sizeStyles.fieldGap : 0) +\n sizeStyles.fieldGap\n }\n width=\"100%\"\n backgroundColor={theme.colors.background.secondary}\n borderColor={theme.colors.border.secondary}\n borderWidth={1}\n borderRadius={theme.radius.button}\n style={{\n zIndex: 1000,\n ...(isNative\n ? { elevation: 4 }\n : { boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\" }),\n minWidth: iconOnly ? sizeStyles.height * 3 : undefined,\n }}\n >\n {/* Search Input - Outside scrollable area (web only) */}\n {searchable && !isNative && (\n <Box\n paddingHorizontal={sizeStyles.paddingHorizontal}\n paddingVertical={sizeStyles.paddingVertical}\n borderBottomWidth={1}\n borderColor={theme.colors.border.secondary}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={sizeStyles.paddingHorizontal / 2}\n paddingHorizontal={4}\n >\n <Icon\n size={sizeStyles.iconSize - 2}\n color={inputColors.placeholder}\n >\n <SearchIcon />\n </Icon>\n <Box\n as=\"input\"\n ref={searchInputRef}\n flex={1}\n type=\"text\"\n value={searchValue}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setSearchValue(e.target.value)\n }\n placeholder={searchPlaceholder}\n style={{\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n color: inputColors.text,\n fontSize: sizeStyles.fontSize,\n width: \"100%\",\n }}\n />\n </Box>\n </Box>\n )}\n\n {/* Options List - Scrollable */}\n <Box\n paddingVertical={4}\n overflow=\"scroll\"\n style={{\n maxHeight: searchable ? maxHeight - 60 : maxHeight,\n ...(isWeb ? { overflowY: \"auto\" } : {}),\n }}\n >\n {filteredOptions.length === 0 ? (\n <Box\n paddingVertical={sizeStyles.paddingVertical * 2}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n alignItems=\"center\"\n >\n <Text\n color={theme.colors.content.tertiary}\n fontSize={sizeStyles.fontSize}\n >\n {noOptionsMessage}\n </Text>\n </Box>\n ) : (\n filteredOptions.map((option, index) => {\n const optionValue = getOptionValue(option);\n const optionLabel = getOptionLabel(option);\n const isOptionDisabled = getOptionDisabled(option);\n const isSelected = optionValue === selectedValue;\n const brandColors = theme.colors.control.brand.primary;\n const contentColors = theme.colors.content;\n\n return (\n <Box\n testID={testID}\n key={index}\n ref={isSelected ? selectedItemRef : undefined}\n paddingVertical={sizeStyles.paddingVertical}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n onPress={\n isOptionDisabled ? undefined : () => handleSelect(option)\n }\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n backgroundColor={\n isSelected ? brandColors.bg : \"transparent\"\n }\n style={{\n ...(isWeb\n ? {\n cursor: isOptionDisabled\n ? \"not-allowed\"\n : \"pointer\",\n }\n : {}),\n opacity: isOptionDisabled ? 0.5 : 1,\n }}\n hoverStyle={\n !isSelected && !isOptionDisabled\n ? {\n backgroundColor: theme.colors.control.input.bgHover,\n }\n : undefined\n }\n >\n <Text\n color={\n isSelected\n ? contentColors.on.brand\n : theme.colors.content.secondary\n }\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n >\n {optionLabel}\n </Text>\n </Box>\n );\n })\n )}\n </Box>\n </Box>\n )}\n\n {isError && errorMessage && (\n <Text\n color={theme.colors.content.alert.primary}\n fontSize={sizeStyles.fontSize - 2}\n style={{ lineHeight: sizeStyles.lineHeight + \"px\" }}\n >\n {errorMessage}\n </Text>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","React","label","SearchIcon"]}
package/native/index.mjs CHANGED
@@ -209,6 +209,8 @@ var Text = ({
209
209
  numberOfLines,
210
210
  id,
211
211
  role,
212
+ testID,
213
+ "data-testid": dataTestId,
212
214
  style: styleProp,
213
215
  ...props
214
216
  }) => {
@@ -238,7 +240,7 @@ var Text = ({
238
240
  {
239
241
  style: baseStyle,
240
242
  numberOfLines,
241
- testID: id,
243
+ testID: dataTestId || testID || id,
242
244
  accessibilityRole,
243
245
  children
244
246
  }
@@ -249,7 +251,13 @@ var Text = ({
249
251
  import React from "react";
250
252
  import { View as View2 } from "react-native";
251
253
  import { jsx as jsx3 } from "react/jsx-runtime";
252
- var Icon = ({ children, color, size }) => {
254
+ var Icon = ({
255
+ children,
256
+ color,
257
+ size,
258
+ testID,
259
+ "data-testid": dataTestId
260
+ }) => {
253
261
  const style = {
254
262
  width: typeof size === "number" ? size : void 0,
255
263
  height: typeof size === "number" ? size : void 0,
@@ -266,7 +274,7 @@ var Icon = ({ children, color, size }) => {
266
274
  }
267
275
  return child;
268
276
  });
269
- return /* @__PURE__ */ jsx3(View2, { style, children: childrenWithProps });
277
+ return /* @__PURE__ */ jsx3(View2, { style, testID: dataTestId || testID, children: childrenWithProps });
270
278
  };
271
279
 
272
280
  // ../../foundation/primitives-native/src/index.tsx
@@ -301,6 +309,8 @@ var Select = ({
301
309
  searchPlaceholder = "Search",
302
310
  noOptionsMessage = "No results",
303
311
  maxHeight = 300,
312
+ fullWidth = true,
313
+ testID,
304
314
  themeMode,
305
315
  themeProductContext
306
316
  }) => {
@@ -408,10 +418,11 @@ var Select = ({
408
418
  return /* @__PURE__ */ jsxs(
409
419
  Box,
410
420
  {
421
+ testID,
411
422
  ref: containerRef,
412
423
  flexDirection: "column",
413
424
  gap: sizeStyles.fieldGap,
414
- width: "100%",
425
+ width: fullWidth ? "100%" : void 0,
415
426
  position: "relative",
416
427
  children: [
417
428
  label && /* @__PURE__ */ jsx4(
@@ -567,6 +578,7 @@ var Select = ({
567
578
  return /* @__PURE__ */ jsx4(
568
579
  Box,
569
580
  {
581
+ testID,
570
582
  ref: isSelected ? selectedItemRef : void 0,
571
583
  paddingVertical: sizeStyles.paddingVertical,
572
584
  paddingHorizontal: sizeStyles.paddingHorizontal,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Select.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n ChevronDown,\n ChevronUp,\n ExclamationMarkCr,\n Search as SearchIcon,\n} from \"@xsolla/xui-icons-base\";\n\nexport interface SelectOption {\n label: string;\n value: any;\n disabled?: boolean;\n}\n\nexport interface SelectProps extends ThemeOverrideProps {\n value?: string;\n placeholder?: string;\n onPress?: () => void;\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n state?: \"default\" | \"hover\" | \"focus\" | \"disable\" | \"error\";\n disabled?: boolean;\n label?: string;\n errorMessage?: string;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n filled?: boolean;\n iconOnly?: boolean;\n options?: (string | SelectOption)[];\n onChange?: (value: string) => void;\n searchable?: boolean;\n searchPlaceholder?: string;\n noOptionsMessage?: string;\n maxHeight?: number;\n}\n\nexport const Select: React.FC<SelectProps> = ({\n value,\n placeholder = \"Select\",\n onPress,\n size = \"md\",\n state: externalState,\n disabled = false,\n label,\n errorMessage,\n iconLeft,\n iconRight,\n filled = true,\n iconOnly = false,\n options = [],\n onChange,\n searchable = false,\n searchPlaceholder = \"Search\",\n noOptionsMessage = \"No results\",\n maxHeight = 300,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const [isOpen, setIsOpen] = useState(false);\n const [selectedValue, setSelectedValue] = useState<string | undefined>(value);\n const [searchValue, setSearchValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const selectedItemRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const isDisable = externalState === \"disable\" || disabled;\n const isError = externalState === \"error\" || !!errorMessage;\n const isFocus = externalState === \"focus\" || isOpen;\n\n // Sync selectedValue with value prop\n React.useEffect(() => {\n if (value !== undefined) {\n setSelectedValue(value);\n }\n }, [value]);\n\n // Auto-scroll to selected item when dropdown opens (show at top)\n useEffect(() => {\n if (isFocus && selectedItemRef.current && dropdownRef.current) {\n // Use setTimeout to ensure DOM has rendered\n const timeoutId = setTimeout(() => {\n const selectedItem = selectedItemRef.current;\n if (selectedItem && isWeb) {\n selectedItem.scrollIntoView({ block: \"nearest\" });\n }\n }, 0);\n return () => clearTimeout(timeoutId);\n }\n }, [isFocus]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (isFocus && searchable) {\n searchInputRef.current?.focus();\n }\n }, [isFocus, searchable]);\n\n // Reset search when dropdown closes\n useEffect(() => {\n if (!isFocus) {\n setSearchValue(\"\");\n }\n }, [isFocus]);\n\n // Close dropdown when clicking outside (web only)\n useEffect(() => {\n if (isNative || !isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const getOptionLabel = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.label;\n };\n\n const getOptionValue = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.value;\n };\n\n const getOptionDisabled = (option: string | SelectOption) => {\n if (typeof option === \"string\") return false;\n return option.disabled || false;\n };\n\n // Filter options based on search value\n const filteredOptions =\n searchable && searchValue\n ? options.filter((option) => {\n const label = getOptionLabel(option);\n return label.toLowerCase().includes(searchValue.toLowerCase());\n })\n : options;\n\n // 1. Resolve Config from Theme\n const sizeStyles = theme.sizing.input(size);\n const inputColors = theme.colors.control.input;\n\n const handlePress = () => {\n if (!isDisable) {\n if (onPress) onPress();\n setIsOpen(!isOpen);\n }\n };\n\n const handleSelect = (option: string | SelectOption) => {\n if (getOptionDisabled(option)) return;\n const val = getOptionValue(option);\n setSelectedValue(val);\n setIsOpen(false);\n if (onChange) onChange(val);\n };\n\n // Resolve background and border colors based on state\n const isHover = externalState === \"hover\";\n let backgroundColor = inputColors.bg;\n let borderColor = inputColors.border;\n\n if (isDisable) {\n backgroundColor = inputColors.bgDisable;\n borderColor = inputColors.borderDisable;\n } else if (isFocus) {\n backgroundColor = theme.colors.control.focus.bg;\n borderColor = isError\n ? theme.colors.border.alert\n : theme.colors.border.brand;\n } else if (isError) {\n borderColor = theme.colors.border.alert;\n } else if (isHover) {\n backgroundColor = inputColors.bgHover;\n borderColor = inputColors.borderHover;\n }\n\n // Handle filled override if provided\n if (filled === false && !isFocus && !isError && !isHover) {\n backgroundColor = \"transparent\";\n }\n\n const currentLabel = selectedValue\n ? getOptionLabel(\n options.find((o) => getOptionValue(o) === selectedValue) ||\n selectedValue\n )\n : placeholder;\n\n const textColor = isDisable\n ? inputColors.textDisable\n : selectedValue\n ? inputColors.text\n : inputColors.placeholder;\n const iconColor = isDisable ? inputColors.textDisable : inputColors.text;\n\n return (\n <Box\n ref={containerRef}\n flexDirection=\"column\"\n gap={sizeStyles.fieldGap}\n width=\"100%\"\n position=\"relative\"\n >\n {label && (\n <Text\n color={theme.colors.content.secondary}\n fontSize={sizeStyles.fontSize - 2}\n fontWeight=\"500\"\n >\n {label}\n </Text>\n )}\n <Box\n onPress={handlePress}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={borderColor !== \"transparent\" ? 1 : 0}\n borderRadius={sizeStyles.radius}\n height={sizeStyles.height}\n width={iconOnly ? sizeStyles.height : \"100%\"}\n paddingHorizontal={iconOnly ? 0 : sizeStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={iconOnly ? \"center\" : \"flex-start\"}\n gap={iconOnly ? 4 : 12}\n position=\"relative\"\n hoverStyle={\n !isDisable && !isFocus && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n >\n {iconLeft && (\n <Box alignItems=\"center\" justifyContent=\"center\">\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconLeft}\n </Icon>\n </Box>\n )}\n\n {!iconOnly && (\n <Box flex={1} height=\"100%\" justifyContent=\"center\">\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n numberOfLines={1}\n >\n {currentLabel}\n </Text>\n </Box>\n )}\n\n {/* Trailing controls */}\n <Box flexDirection=\"row\" alignItems=\"center\" gap={4}>\n {/* Error icon */}\n {isError && (\n <Icon\n size={sizeStyles.iconSize}\n color={theme.colors.content.alert.primary}\n >\n <ExclamationMarkCr />\n </Icon>\n )}\n\n {/* Right icon or default caret */}\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconRight !== undefined ? (\n iconRight\n ) : isFocus ? (\n <ChevronUp />\n ) : (\n <ChevronDown />\n )}\n </Icon>\n </Box>\n </Box>\n\n {/* Dropdown Menu */}\n {isFocus && options.length > 0 && (\n <Box\n ref={dropdownRef}\n position=\"absolute\"\n top={\n sizeStyles.height +\n (label ? sizeStyles.fontSize + sizeStyles.fieldGap : 0) +\n sizeStyles.fieldGap\n }\n width=\"100%\"\n backgroundColor={theme.colors.background.secondary}\n borderColor={theme.colors.border.secondary}\n borderWidth={1}\n borderRadius={theme.radius.button}\n style={{\n zIndex: 1000,\n ...(isNative\n ? { elevation: 4 }\n : { boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\" }),\n minWidth: iconOnly ? sizeStyles.height * 3 : undefined,\n }}\n >\n {/* Search Input - Outside scrollable area (web only) */}\n {searchable && !isNative && (\n <Box\n paddingHorizontal={sizeStyles.paddingHorizontal}\n paddingVertical={sizeStyles.paddingVertical}\n borderBottomWidth={1}\n borderColor={theme.colors.border.secondary}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={sizeStyles.paddingHorizontal / 2}\n paddingHorizontal={4}\n >\n <Icon\n size={sizeStyles.iconSize - 2}\n color={inputColors.placeholder}\n >\n <SearchIcon />\n </Icon>\n <Box\n as=\"input\"\n ref={searchInputRef}\n flex={1}\n type=\"text\"\n value={searchValue}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setSearchValue(e.target.value)\n }\n placeholder={searchPlaceholder}\n style={{\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n color: inputColors.text,\n fontSize: sizeStyles.fontSize,\n width: \"100%\",\n }}\n />\n </Box>\n </Box>\n )}\n\n {/* Options List - Scrollable */}\n <Box\n paddingVertical={4}\n overflow=\"scroll\"\n style={{\n maxHeight: searchable ? maxHeight - 60 : maxHeight,\n ...(isWeb ? { overflowY: \"auto\" } : {}),\n }}\n >\n {filteredOptions.length === 0 ? (\n <Box\n paddingVertical={sizeStyles.paddingVertical * 2}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n alignItems=\"center\"\n >\n <Text\n color={theme.colors.content.tertiary}\n fontSize={sizeStyles.fontSize}\n >\n {noOptionsMessage}\n </Text>\n </Box>\n ) : (\n filteredOptions.map((option, index) => {\n const optionValue = getOptionValue(option);\n const optionLabel = getOptionLabel(option);\n const isOptionDisabled = getOptionDisabled(option);\n const isSelected = optionValue === selectedValue;\n const brandColors = theme.colors.control.brand.primary;\n const contentColors = theme.colors.content;\n\n return (\n <Box\n key={index}\n ref={isSelected ? selectedItemRef : undefined}\n paddingVertical={sizeStyles.paddingVertical}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n onPress={\n isOptionDisabled ? undefined : () => handleSelect(option)\n }\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n backgroundColor={\n isSelected ? brandColors.bg : \"transparent\"\n }\n style={{\n ...(isWeb\n ? {\n cursor: isOptionDisabled\n ? \"not-allowed\"\n : \"pointer\",\n }\n : {}),\n opacity: isOptionDisabled ? 0.5 : 1,\n }}\n hoverStyle={\n !isSelected && !isOptionDisabled\n ? {\n backgroundColor: theme.colors.control.input.bgHover,\n }\n : undefined\n }\n >\n <Text\n color={\n isSelected\n ? contentColors.on.brand\n : theme.colors.content.secondary\n }\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n >\n {optionLabel}\n </Text>\n </Box>\n );\n })\n )}\n </Box>\n </Box>\n )}\n\n {isError && errorMessage && (\n <Text\n color={theme.colors.content.alert.primary}\n fontSize={sizeStyles.fontSize - 2}\n style={{ lineHeight: sizeStyles.lineHeight + \"px\" }}\n >\n {errorMessage}\n </Text>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return <View style={style}>{childrenWithProps}</View>;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["React","jsx","View","jsx","jsx","React","label"]}
1
+ {"version":3,"sources":["../../src/Select.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n ChevronDown,\n ChevronUp,\n ExclamationMarkCr,\n Search as SearchIcon,\n} from \"@xsolla/xui-icons-base\";\n\nexport interface SelectOption {\n label: string;\n value: any;\n disabled?: boolean;\n}\n\nexport interface SelectProps extends ThemeOverrideProps {\n value?: string;\n placeholder?: string;\n onPress?: () => void;\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\" | \"xs\";\n state?: \"default\" | \"hover\" | \"focus\" | \"disable\" | \"error\";\n disabled?: boolean;\n label?: string;\n errorMessage?: string;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n filled?: boolean;\n iconOnly?: boolean;\n options?: (string | SelectOption)[];\n onChange?: (value: string) => void;\n searchable?: boolean;\n searchPlaceholder?: string;\n noOptionsMessage?: string;\n maxHeight?: number;\n /** Whether the select should stretch to fill the full width of its container */\n fullWidth?: boolean;\n /** Test ID for testing frameworks */\n testID?: string;\n}\n\nexport const Select: React.FC<SelectProps> = ({\n value,\n placeholder = \"Select\",\n onPress,\n size = \"md\",\n state: externalState,\n disabled = false,\n label,\n errorMessage,\n iconLeft,\n iconRight,\n filled = true,\n iconOnly = false,\n options = [],\n onChange,\n searchable = false,\n searchPlaceholder = \"Search\",\n noOptionsMessage = \"No results\",\n maxHeight = 300,\n fullWidth = true,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const [isOpen, setIsOpen] = useState(false);\n const [selectedValue, setSelectedValue] = useState<string | undefined>(value);\n const [searchValue, setSearchValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const selectedItemRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const isDisable = externalState === \"disable\" || disabled;\n const isError = externalState === \"error\" || !!errorMessage;\n const isFocus = externalState === \"focus\" || isOpen;\n\n // Sync selectedValue with value prop\n React.useEffect(() => {\n if (value !== undefined) {\n setSelectedValue(value);\n }\n }, [value]);\n\n // Auto-scroll to selected item when dropdown opens (show at top)\n useEffect(() => {\n if (isFocus && selectedItemRef.current && dropdownRef.current) {\n // Use setTimeout to ensure DOM has rendered\n const timeoutId = setTimeout(() => {\n const selectedItem = selectedItemRef.current;\n if (selectedItem && isWeb) {\n selectedItem.scrollIntoView({ block: \"nearest\" });\n }\n }, 0);\n return () => clearTimeout(timeoutId);\n }\n }, [isFocus]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (isFocus && searchable) {\n searchInputRef.current?.focus();\n }\n }, [isFocus, searchable]);\n\n // Reset search when dropdown closes\n useEffect(() => {\n if (!isFocus) {\n setSearchValue(\"\");\n }\n }, [isFocus]);\n\n // Close dropdown when clicking outside (web only)\n useEffect(() => {\n if (isNative || !isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const getOptionLabel = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.label;\n };\n\n const getOptionValue = (option: string | SelectOption) => {\n if (typeof option === \"string\") return option;\n return option.value;\n };\n\n const getOptionDisabled = (option: string | SelectOption) => {\n if (typeof option === \"string\") return false;\n return option.disabled || false;\n };\n\n // Filter options based on search value\n const filteredOptions =\n searchable && searchValue\n ? options.filter((option) => {\n const label = getOptionLabel(option);\n return label.toLowerCase().includes(searchValue.toLowerCase());\n })\n : options;\n\n // 1. Resolve Config from Theme\n const sizeStyles = theme.sizing.input(size);\n const inputColors = theme.colors.control.input;\n\n const handlePress = () => {\n if (!isDisable) {\n if (onPress) onPress();\n setIsOpen(!isOpen);\n }\n };\n\n const handleSelect = (option: string | SelectOption) => {\n if (getOptionDisabled(option)) return;\n const val = getOptionValue(option);\n setSelectedValue(val);\n setIsOpen(false);\n if (onChange) onChange(val);\n };\n\n // Resolve background and border colors based on state\n const isHover = externalState === \"hover\";\n let backgroundColor = inputColors.bg;\n let borderColor = inputColors.border;\n\n if (isDisable) {\n backgroundColor = inputColors.bgDisable;\n borderColor = inputColors.borderDisable;\n } else if (isFocus) {\n backgroundColor = theme.colors.control.focus.bg;\n borderColor = isError\n ? theme.colors.border.alert\n : theme.colors.border.brand;\n } else if (isError) {\n borderColor = theme.colors.border.alert;\n } else if (isHover) {\n backgroundColor = inputColors.bgHover;\n borderColor = inputColors.borderHover;\n }\n\n // Handle filled override if provided\n if (filled === false && !isFocus && !isError && !isHover) {\n backgroundColor = \"transparent\";\n }\n\n const currentLabel = selectedValue\n ? getOptionLabel(\n options.find((o) => getOptionValue(o) === selectedValue) ||\n selectedValue\n )\n : placeholder;\n\n const textColor = isDisable\n ? inputColors.textDisable\n : selectedValue\n ? inputColors.text\n : inputColors.placeholder;\n const iconColor = isDisable ? inputColors.textDisable : inputColors.text;\n\n return (\n <Box\n testID={testID}\n ref={containerRef}\n flexDirection=\"column\"\n gap={sizeStyles.fieldGap}\n width={fullWidth ? \"100%\" : undefined}\n position=\"relative\"\n >\n {label && (\n <Text\n color={theme.colors.content.secondary}\n fontSize={sizeStyles.fontSize - 2}\n fontWeight=\"500\"\n >\n {label}\n </Text>\n )}\n <Box\n onPress={handlePress}\n backgroundColor={backgroundColor}\n borderColor={borderColor}\n borderWidth={borderColor !== \"transparent\" ? 1 : 0}\n borderRadius={sizeStyles.radius}\n height={sizeStyles.height}\n width={iconOnly ? sizeStyles.height : \"100%\"}\n paddingHorizontal={iconOnly ? 0 : sizeStyles.paddingHorizontal}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={iconOnly ? \"center\" : \"flex-start\"}\n gap={iconOnly ? 4 : 12}\n position=\"relative\"\n hoverStyle={\n !isDisable && !isFocus && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n >\n {iconLeft && (\n <Box alignItems=\"center\" justifyContent=\"center\">\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconLeft}\n </Icon>\n </Box>\n )}\n\n {!iconOnly && (\n <Box flex={1} height=\"100%\" justifyContent=\"center\">\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n numberOfLines={1}\n >\n {currentLabel}\n </Text>\n </Box>\n )}\n\n {/* Trailing controls */}\n <Box flexDirection=\"row\" alignItems=\"center\" gap={4}>\n {/* Error icon */}\n {isError && (\n <Icon\n size={sizeStyles.iconSize}\n color={theme.colors.content.alert.primary}\n >\n <ExclamationMarkCr />\n </Icon>\n )}\n\n {/* Right icon or default caret */}\n <Icon size={sizeStyles.iconSize} color={iconColor}>\n {iconRight !== undefined ? (\n iconRight\n ) : isFocus ? (\n <ChevronUp />\n ) : (\n <ChevronDown />\n )}\n </Icon>\n </Box>\n </Box>\n\n {/* Dropdown Menu */}\n {isFocus && options.length > 0 && (\n <Box\n ref={dropdownRef}\n position=\"absolute\"\n top={\n sizeStyles.height +\n (label ? sizeStyles.fontSize + sizeStyles.fieldGap : 0) +\n sizeStyles.fieldGap\n }\n width=\"100%\"\n backgroundColor={theme.colors.background.secondary}\n borderColor={theme.colors.border.secondary}\n borderWidth={1}\n borderRadius={theme.radius.button}\n style={{\n zIndex: 1000,\n ...(isNative\n ? { elevation: 4 }\n : { boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\" }),\n minWidth: iconOnly ? sizeStyles.height * 3 : undefined,\n }}\n >\n {/* Search Input - Outside scrollable area (web only) */}\n {searchable && !isNative && (\n <Box\n paddingHorizontal={sizeStyles.paddingHorizontal}\n paddingVertical={sizeStyles.paddingVertical}\n borderBottomWidth={1}\n borderColor={theme.colors.border.secondary}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={sizeStyles.paddingHorizontal / 2}\n paddingHorizontal={4}\n >\n <Icon\n size={sizeStyles.iconSize - 2}\n color={inputColors.placeholder}\n >\n <SearchIcon />\n </Icon>\n <Box\n as=\"input\"\n ref={searchInputRef}\n flex={1}\n type=\"text\"\n value={searchValue}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setSearchValue(e.target.value)\n }\n placeholder={searchPlaceholder}\n style={{\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n color: inputColors.text,\n fontSize: sizeStyles.fontSize,\n width: \"100%\",\n }}\n />\n </Box>\n </Box>\n )}\n\n {/* Options List - Scrollable */}\n <Box\n paddingVertical={4}\n overflow=\"scroll\"\n style={{\n maxHeight: searchable ? maxHeight - 60 : maxHeight,\n ...(isWeb ? { overflowY: \"auto\" } : {}),\n }}\n >\n {filteredOptions.length === 0 ? (\n <Box\n paddingVertical={sizeStyles.paddingVertical * 2}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n alignItems=\"center\"\n >\n <Text\n color={theme.colors.content.tertiary}\n fontSize={sizeStyles.fontSize}\n >\n {noOptionsMessage}\n </Text>\n </Box>\n ) : (\n filteredOptions.map((option, index) => {\n const optionValue = getOptionValue(option);\n const optionLabel = getOptionLabel(option);\n const isOptionDisabled = getOptionDisabled(option);\n const isSelected = optionValue === selectedValue;\n const brandColors = theme.colors.control.brand.primary;\n const contentColors = theme.colors.content;\n\n return (\n <Box\n testID={testID}\n key={index}\n ref={isSelected ? selectedItemRef : undefined}\n paddingVertical={sizeStyles.paddingVertical}\n paddingHorizontal={sizeStyles.paddingHorizontal}\n onPress={\n isOptionDisabled ? undefined : () => handleSelect(option)\n }\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n backgroundColor={\n isSelected ? brandColors.bg : \"transparent\"\n }\n style={{\n ...(isWeb\n ? {\n cursor: isOptionDisabled\n ? \"not-allowed\"\n : \"pointer\",\n }\n : {}),\n opacity: isOptionDisabled ? 0.5 : 1,\n }}\n hoverStyle={\n !isSelected && !isOptionDisabled\n ? {\n backgroundColor: theme.colors.control.input.bgHover,\n }\n : undefined\n }\n >\n <Text\n color={\n isSelected\n ? contentColors.on.brand\n : theme.colors.content.secondary\n }\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n >\n {optionLabel}\n </Text>\n </Box>\n );\n })\n )}\n </Box>\n </Box>\n )}\n\n {isError && errorMessage && (\n <Text\n color={theme.colors.content.alert.primary}\n fontSize={sizeStyles.fontSize - 2}\n style={{ lineHeight: sizeStyles.lineHeight + \"px\" }}\n >\n {errorMessage}\n </Text>\n )}\n </Box>\n );\n};\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["React","jsx","View","jsx","jsx","React","label"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-select",
3
- "version": "0.158.0",
3
+ "version": "0.159.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-core": "0.158.0",
17
- "@xsolla/xui-icons-base": "0.158.0",
18
- "@xsolla/xui-primitives-core": "0.158.0"
16
+ "@xsolla/xui-core": "0.159.0",
17
+ "@xsolla/xui-icons-base": "0.159.0",
18
+ "@xsolla/xui-primitives-core": "0.159.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",
package/web/index.d.mts CHANGED
@@ -25,6 +25,10 @@ interface SelectProps extends ThemeOverrideProps {
25
25
  searchPlaceholder?: string;
26
26
  noOptionsMessage?: string;
27
27
  maxHeight?: number;
28
+ /** Whether the select should stretch to fill the full width of its container */
29
+ fullWidth?: boolean;
30
+ /** Test ID for testing frameworks */
31
+ testID?: string;
28
32
  }
29
33
  declare const Select: React.FC<SelectProps>;
30
34
 
package/web/index.d.ts CHANGED
@@ -25,6 +25,10 @@ interface SelectProps extends ThemeOverrideProps {
25
25
  searchPlaceholder?: string;
26
26
  noOptionsMessage?: string;
27
27
  maxHeight?: number;
28
+ /** Whether the select should stretch to fill the full width of its container */
29
+ fullWidth?: boolean;
30
+ /** Test ID for testing frameworks */
31
+ testID?: string;
28
32
  }
29
33
  declare const Select: React.FC<SelectProps>;
30
34
 
package/web/index.js CHANGED
@@ -249,7 +249,8 @@ var Box = import_react2.default.forwardRef(
249
249
  top: typeof props.top === "number" ? `${props.top}px` : props.top,
250
250
  left: typeof props.left === "number" ? `${props.left}px` : props.left,
251
251
  right: typeof props.right === "number" ? `${props.right}px` : props.right,
252
- bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom
252
+ bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom,
253
+ ...props.style
253
254
  }
254
255
  }
255
256
  );
@@ -306,6 +307,8 @@ var Text = ({
306
307
  className,
307
308
  id,
308
309
  role,
310
+ testID,
311
+ "data-testid": dataTestId,
309
312
  numberOfLines: _numberOfLines,
310
313
  ...props
311
314
  }) => {
@@ -316,7 +319,8 @@ var Text = ({
316
319
  style,
317
320
  className,
318
321
  id,
319
- role
322
+ role,
323
+ "data-testid": dataTestId || testID
320
324
  }
321
325
  );
322
326
  };
@@ -340,8 +344,13 @@ var StyledIcon = (0, import_styled_components3.default)(FilteredDiv2)`
340
344
  stroke: currentColor;
341
345
  }
342
346
  `;
343
- var Icon = ({ children, ...props }) => {
344
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledIcon, { ...props, children });
347
+ var Icon = ({
348
+ children,
349
+ testID,
350
+ "data-testid": dataTestId,
351
+ ...props
352
+ }) => {
353
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledIcon, { "data-testid": dataTestId || testID, ...props, children });
345
354
  };
346
355
 
347
356
  // ../../foundation/primitives-web/src/index.tsx
@@ -371,6 +380,8 @@ var Select = ({
371
380
  searchPlaceholder = "Search",
372
381
  noOptionsMessage = "No results",
373
382
  maxHeight = 300,
383
+ fullWidth = true,
384
+ testID,
374
385
  themeMode,
375
386
  themeProductContext
376
387
  }) => {
@@ -478,10 +489,11 @@ var Select = ({
478
489
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
479
490
  Box,
480
491
  {
492
+ testID,
481
493
  ref: containerRef,
482
494
  flexDirection: "column",
483
495
  gap: sizeStyles.fieldGap,
484
- width: "100%",
496
+ width: fullWidth ? "100%" : void 0,
485
497
  position: "relative",
486
498
  children: [
487
499
  label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -637,6 +649,7 @@ var Select = ({
637
649
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
638
650
  Box,
639
651
  {
652
+ testID,
640
653
  ref: isSelected ? selectedItemRef : void 0,
641
654
  paddingVertical: sizeStyles.paddingVertical,
642
655
  paddingHorizontal: sizeStyles.paddingHorizontal,