import React, { useState, useRef, useEffect } from 'react'; import { View, Text, Pressable, Animated, StyleSheet, StyleProp, ViewStyle, Platform, UIManager, LayoutAnimation, useWindowDimensions, } from 'react-native'; import { useUx4gTheme } from '../../theme/Ux4gThemeContext'; import { Ux4gButton } from '../button/Button'; import { Ux4gTag, Ux4gTagColor, Ux4gUnifiedPillTag, Ux4gPillSegment } from '../tag/Tag'; import { UX4GColors } from '../../foundation/colors'; import { Ux4gIcons } from '../../foundation/icons'; if (Platform.OS === 'android') { if (UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } } export interface Ux4gResultDetail { label: string; value: string; icon?: string; valueColor?: string; isBold?: boolean; customValueWidget?: React.ReactNode; } export interface Ux4gResultListProps { title: string; titleTrailing?: React.ReactNode; statusTag?: string; tagColorScheme?: Ux4gTagColor; metadataSegments?: Ux4gPillSegment[]; customMetadata?: React.ReactNode; actionButtonText?: string; actionLeading?: React.ReactNode; onActionPressed?: () => void; actionButtonIcon?: React.ReactNode | ((props: { color: string; size: number }) => React.ReactNode); actionButtonColor?: string; details?: Ux4gResultDetail[]; expandedChild?: React.ReactNode; detailsColumns?: number; initialExpanded?: boolean; onToggle?: (expanded: boolean) => void; showBottomDivider?: boolean; contentPadding?: number; testID?: string; } export const Ux4gResultList: React.FC = ({ title, titleTrailing, statusTag, tagColorScheme = 'neutral', metadataSegments, customMetadata, actionButtonText, actionLeading, onActionPressed, actionButtonIcon, actionButtonColor, details = [], expandedChild, detailsColumns = 2, initialExpanded = false, onToggle, showBottomDivider = true, contentPadding = 16, testID, }) => { const theme = useUx4gTheme(); const { colors, typography, isDark } = theme; const [isExpanded, setIsExpanded] = useState(initialExpanded); const { width: screenWidth } = useWindowDimensions(); // Animation for the chevron rotation const rotationAnimation = useRef(new Animated.Value(initialExpanded ? 1 : 0)).current; useEffect(() => { Animated.timing(rotationAnimation, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true, }).start(); }, [isExpanded, rotationAnimation]); const chevronRotation = rotationAnimation.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '180deg'], }); const handleToggle = () => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); const nextState = !isExpanded; setIsExpanded(nextState); if (onToggle) { onToggle(nextState); } }; const ChevronDown = Ux4gIcons.chevronDown as any; const borderColor = isDark ? 'UX4GColors.neutral800' : 'UX4GColors.neutral300'; // neutral800 vs neutral300 approximation const renderDetails = () => { if (!isExpanded) return null; const columnCount = screenWidth > 400 ? detailsColumns : 1; const itemWidth = columnCount > 1 ? `${100 / columnCount}%` : '100%'; return ( {details.length > 0 && ( {details.map((detail, index) => { const DetailIcon = detail.icon ? Ux4gIcons[detail.icon.replace(/-([a-z])/g, (g) => g[1].toUpperCase()) as keyof typeof Ux4gIcons] as any : null; return ( {detail.label} {detail.customValueWidget ? ( detail.customValueWidget ) : ( {DetailIcon && ( )} {detail.value} )} ); })} )} {expandedChild} ); }; return ( {/* Left Content */} {title} {titleTrailing && ( {titleTrailing} )} {(statusTag || (metadataSegments && metadataSegments.length > 0) || customMetadata) && ( {statusTag && ( )} {customMetadata && ( {customMetadata} )} {!customMetadata && metadataSegments && metadataSegments.length > 0 && ( )} )} {/* Right Content */} {actionLeading && ( {actionLeading} )} {actionButtonText && ( {})} /> )} {ChevronDown ? ( ) : ( ▼ )} {/* Expanded Content */} {renderDetails()} {/* Bottom Divider */} {showBottomDivider && ( )} ); }; const styles = StyleSheet.create({ container: { width: '100%', }, headerRow: { flexDirection: 'row', alignItems: 'flex-start', width: '100%', }, leftContent: { flex: 1, minWidth: 0, flexDirection: 'column', justifyContent: 'flex-start', }, titleRow: { flexDirection: 'row', alignItems: 'center', width: '100%', }, metadataWrap: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', marginTop: 8, maxWidth: '100%', }, rightContent: { flexDirection: 'row', alignItems: 'center', marginLeft: 8, flexShrink: 0, }, expandedContainer: { width: '100%', }, detailsGrid: { flexDirection: 'row', flexWrap: 'wrap', width: '100%', }, detailValueRow: { flexDirection: 'row', alignItems: 'center', }, divider: { height: 1, width: '100%', }, });