1*1119c2eaS猫头猫import React, {ReactNode} from 'react'; 2*1119c2eaS猫头猫import { 3*1119c2eaS猫头猫 StyleProp, 4*1119c2eaS猫头猫 StyleSheet, 5*1119c2eaS猫头猫 TextProps, 6*1119c2eaS猫头猫 TextStyle, 7*1119c2eaS猫头猫 TouchableHighlight, 8*1119c2eaS猫头猫 TouchableOpacity, 9*1119c2eaS猫头猫 View, 10*1119c2eaS猫头猫 ViewStyle, 11*1119c2eaS猫头猫} from 'react-native'; 1219dc08ecS猫头猫import rpx from '@/utils/rpx'; 13*1119c2eaS猫头猫import useColors from '@/hooks/useColors'; 14*1119c2eaS猫头猫import ThemeText from './themeText'; 15*1119c2eaS猫头猫import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; 16*1119c2eaS猫头猫import { 17*1119c2eaS猫头猫 fontSizeConst, 18*1119c2eaS猫头猫 fontWeightConst, 19*1119c2eaS猫头猫 iconSizeConst, 20*1119c2eaS猫头猫} from '@/constants/uiConst'; 21*1119c2eaS猫头猫import FastImage from './fastImage'; 22*1119c2eaS猫头猫import {ImageStyle} from 'react-native-fast-image'; 2319dc08ecS猫头猫 24*1119c2eaS猫头猫interface IListItemProps { 25*1119c2eaS猫头猫 // 是否有左右边距 26*1119c2eaS猫头猫 withHorizonalPadding?: boolean; 27*1119c2eaS猫头猫 // 左边距 28*1119c2eaS猫头猫 leftPadding?: number; 29*1119c2eaS猫头猫 // 右边距 30*1119c2eaS猫头猫 rightPadding?: number; 31*1119c2eaS猫头猫 // height: 32*1119c2eaS猫头猫 style?: StyleProp<ViewStyle>; 33*1119c2eaS猫头猫 // 高度类型 34*1119c2eaS猫头猫 heightType?: 'big' | 'small' | 'normal' | 'none'; 35*1119c2eaS猫头猫 children?: ReactNode; 36*1119c2eaS猫头猫 onPress?: () => void; 37*1119c2eaS猫头猫 onLongPress?: () => void; 38*1119c2eaS猫头猫} 39*1119c2eaS猫头猫 40*1119c2eaS猫头猫const defaultPadding = rpx(24); 41*1119c2eaS猫头猫const defaultActionWidth = rpx(80); 42*1119c2eaS猫头猫 43*1119c2eaS猫头猫const Size = { 44*1119c2eaS猫头猫 big: rpx(120), 45*1119c2eaS猫头猫 normal: rpx(108), 46*1119c2eaS猫头猫 small: rpx(96), 47*1119c2eaS猫头猫 none: undefined, 48*1119c2eaS猫头猫}; 49*1119c2eaS猫头猫 50*1119c2eaS猫头猫function ListItem(props: IListItemProps) { 51*1119c2eaS猫头猫 const { 52*1119c2eaS猫头猫 withHorizonalPadding, 53*1119c2eaS猫头猫 leftPadding = defaultPadding, 54*1119c2eaS猫头猫 rightPadding = defaultPadding, 55*1119c2eaS猫头猫 style, 56*1119c2eaS猫头猫 heightType = 'normal', 57*1119c2eaS猫头猫 children, 58*1119c2eaS猫头猫 onPress, 59*1119c2eaS猫头猫 onLongPress, 60*1119c2eaS猫头猫 } = props; 61*1119c2eaS猫头猫 62*1119c2eaS猫头猫 const defaultStyle: StyleProp<ViewStyle> = { 63*1119c2eaS猫头猫 paddingLeft: withHorizonalPadding ? leftPadding : 0, 64*1119c2eaS猫头猫 paddingRight: withHorizonalPadding ? rightPadding : 0, 65*1119c2eaS猫头猫 height: Size[heightType], 66*1119c2eaS猫头猫 }; 67*1119c2eaS猫头猫 68*1119c2eaS猫头猫 const colors = useColors(); 69*1119c2eaS猫头猫 70*1119c2eaS猫头猫 return ( 71*1119c2eaS猫头猫 <TouchableHighlight 72*1119c2eaS猫头猫 style={styles.container} 73*1119c2eaS猫头猫 underlayColor={colors.listActive} 74*1119c2eaS猫头猫 onPress={onPress} 75*1119c2eaS猫头猫 onLongPress={onLongPress}> 76*1119c2eaS猫头猫 <View style={[styles.container, defaultStyle, style]}> 77*1119c2eaS猫头猫 {children} 78*1119c2eaS猫头猫 </View> 79*1119c2eaS猫头猫 </TouchableHighlight> 80*1119c2eaS猫头猫 ); 81*1119c2eaS猫头猫} 82*1119c2eaS猫头猫 83*1119c2eaS猫头猫interface IListItemTextProps { 84*1119c2eaS猫头猫 children?: number | string; 85*1119c2eaS猫头猫 fontSize?: keyof typeof fontSizeConst; 86*1119c2eaS猫头猫 fontWeight?: keyof typeof fontWeightConst; 87*1119c2eaS猫头猫 width?: number; 88*1119c2eaS猫头猫 position?: 'left' | 'right' | 'none'; 89*1119c2eaS猫头猫 fixedWidth?: boolean; 90*1119c2eaS猫头猫 containerStyle?: StyleProp<ViewStyle>; 91*1119c2eaS猫头猫 contentStyle?: StyleProp<TextStyle>; 92*1119c2eaS猫头猫 contentProps?: TextProps; 93*1119c2eaS猫头猫} 94*1119c2eaS猫头猫 95*1119c2eaS猫头猫function ListItemText(props: IListItemTextProps) { 96*1119c2eaS猫头猫 const { 97*1119c2eaS猫头猫 children, 98*1119c2eaS猫头猫 fontSize, 99*1119c2eaS猫头猫 fontWeight, 100*1119c2eaS猫头猫 position = 'left', 101*1119c2eaS猫头猫 fixedWidth, 102*1119c2eaS猫头猫 width, 103*1119c2eaS猫头猫 containerStyle, 104*1119c2eaS猫头猫 contentStyle, 105*1119c2eaS猫头猫 contentProps = {}, 106*1119c2eaS猫头猫 } = props; 107*1119c2eaS猫头猫 108*1119c2eaS猫头猫 const defaultStyle: StyleProp<ViewStyle> = { 109*1119c2eaS猫头猫 marginRight: position === 'left' ? defaultPadding : 0, 110*1119c2eaS猫头猫 marginLeft: position === 'right' ? defaultPadding : 0, 111*1119c2eaS猫头猫 width: fixedWidth ? width ?? defaultActionWidth : undefined, 112*1119c2eaS猫头猫 flexBasis: fixedWidth ? width ?? defaultActionWidth : undefined, 113*1119c2eaS猫头猫 }; 114*1119c2eaS猫头猫 115*1119c2eaS猫头猫 return ( 116*1119c2eaS猫头猫 <View style={[styles.actionBase, defaultStyle, containerStyle]}> 117*1119c2eaS猫头猫 <ThemeText 118*1119c2eaS猫头猫 fontSize={fontSize} 119*1119c2eaS猫头猫 style={contentStyle} 120*1119c2eaS猫头猫 fontWeight={fontWeight} 121*1119c2eaS猫头猫 {...contentProps}> 122*1119c2eaS猫头猫 {children} 123*1119c2eaS猫头猫 </ThemeText> 124*1119c2eaS猫头猫 </View> 125*1119c2eaS猫头猫 ); 126*1119c2eaS猫头猫} 127*1119c2eaS猫头猫 128*1119c2eaS猫头猫interface IListItemIconProps { 129*1119c2eaS猫头猫 icon: string; 130*1119c2eaS猫头猫 iconSize?: number; 131*1119c2eaS猫头猫 width?: number; 132*1119c2eaS猫头猫 position?: 'left' | 'right' | 'none'; 133*1119c2eaS猫头猫 fixedWidth?: boolean; 134*1119c2eaS猫头猫 containerStyle?: StyleProp<ViewStyle>; 135*1119c2eaS猫头猫 contentStyle?: StyleProp<TextStyle>; 136*1119c2eaS猫头猫 onPress?: () => void; 137*1119c2eaS猫头猫} 138*1119c2eaS猫头猫 139*1119c2eaS猫头猫function ListItemIcon(props: IListItemIconProps) { 140*1119c2eaS猫头猫 const { 141*1119c2eaS猫头猫 icon, 142*1119c2eaS猫头猫 iconSize = iconSizeConst.normal, 143*1119c2eaS猫头猫 position = 'left', 144*1119c2eaS猫头猫 fixedWidth, 145*1119c2eaS猫头猫 width, 146*1119c2eaS猫头猫 containerStyle, 147*1119c2eaS猫头猫 contentStyle, 148*1119c2eaS猫头猫 onPress, 149*1119c2eaS猫头猫 } = props; 150*1119c2eaS猫头猫 151*1119c2eaS猫头猫 const defaultStyle: StyleProp<ViewStyle> = { 152*1119c2eaS猫头猫 marginRight: position === 'left' ? defaultPadding : 0, 153*1119c2eaS猫头猫 marginLeft: position === 'right' ? defaultPadding : 0, 154*1119c2eaS猫头猫 width: fixedWidth ? width ?? defaultActionWidth : undefined, 155*1119c2eaS猫头猫 flexBasis: fixedWidth ? width ?? defaultActionWidth : undefined, 156*1119c2eaS猫头猫 }; 157*1119c2eaS猫头猫 158*1119c2eaS猫头猫 const innerContent = ( 159*1119c2eaS猫头猫 <View style={[styles.actionBase, defaultStyle, containerStyle]}> 160*1119c2eaS猫头猫 <Icon name={icon} size={iconSize} style={contentStyle} /> 161*1119c2eaS猫头猫 </View> 162*1119c2eaS猫头猫 ); 163*1119c2eaS猫头猫 164*1119c2eaS猫头猫 return onPress ? ( 165*1119c2eaS猫头猫 <TouchableOpacity onPress={onPress}>{innerContent}</TouchableOpacity> 166*1119c2eaS猫头猫 ) : ( 167*1119c2eaS猫头猫 innerContent 168*1119c2eaS猫头猫 ); 169*1119c2eaS猫头猫} 170*1119c2eaS猫头猫 171*1119c2eaS猫头猫interface IListItemImageProps { 172*1119c2eaS猫头猫 uri?: string; 173*1119c2eaS猫头猫 fallbackImg?: number; 174*1119c2eaS猫头猫 imageSize?: number; 175*1119c2eaS猫头猫 width?: number; 176*1119c2eaS猫头猫 position?: 'left' | 'right'; 177*1119c2eaS猫头猫 fixedWidth?: boolean; 178*1119c2eaS猫头猫 containerStyle?: StyleProp<ViewStyle>; 179*1119c2eaS猫头猫 contentStyle?: StyleProp<ImageStyle>; 180*1119c2eaS猫头猫} 181*1119c2eaS猫头猫 182*1119c2eaS猫头猫function ListItemImage(props: IListItemImageProps) { 183*1119c2eaS猫头猫 const { 184*1119c2eaS猫头猫 uri, 185*1119c2eaS猫头猫 fallbackImg, 186*1119c2eaS猫头猫 position = 'left', 187*1119c2eaS猫头猫 fixedWidth, 188*1119c2eaS猫头猫 width, 189*1119c2eaS猫头猫 containerStyle, 190*1119c2eaS猫头猫 contentStyle, 191*1119c2eaS猫头猫 } = props; 192*1119c2eaS猫头猫 193*1119c2eaS猫头猫 const defaultStyle: StyleProp<ViewStyle> = { 194*1119c2eaS猫头猫 marginRight: position === 'left' ? defaultPadding : 0, 195*1119c2eaS猫头猫 marginLeft: position === 'right' ? defaultPadding : 0, 196*1119c2eaS猫头猫 width: fixedWidth ? width ?? defaultActionWidth : undefined, 197*1119c2eaS猫头猫 flexBasis: fixedWidth ? width ?? defaultActionWidth : undefined, 198*1119c2eaS猫头猫 }; 199*1119c2eaS猫头猫 200*1119c2eaS猫头猫 return ( 201*1119c2eaS猫头猫 <View style={[styles.actionBase, defaultStyle, containerStyle]}> 202*1119c2eaS猫头猫 <FastImage 203*1119c2eaS猫头猫 style={[styles.leftImage, contentStyle]} 204*1119c2eaS猫头猫 uri={uri} 205*1119c2eaS猫头猫 emptySrc={fallbackImg} 206*1119c2eaS猫头猫 /> 207*1119c2eaS猫头猫 </View> 208*1119c2eaS猫头猫 ); 209*1119c2eaS猫头猫} 210*1119c2eaS猫头猫 211*1119c2eaS猫头猫interface IContentProps { 212*1119c2eaS猫头猫 title?: ReactNode; 213*1119c2eaS猫头猫 description?: ReactNode; 214*1119c2eaS猫头猫 containerStyle?: StyleProp<ViewStyle>; 215*1119c2eaS猫头猫} 216*1119c2eaS猫头猫 217*1119c2eaS猫头猫function Content(props: IContentProps) { 218*1119c2eaS猫头猫 const {title, description = null, containerStyle} = props; 219*1119c2eaS猫头猫 220*1119c2eaS猫头猫 let realTitle; 221*1119c2eaS猫头猫 let realDescription; 222*1119c2eaS猫头猫 223*1119c2eaS猫头猫 if (typeof title === 'string' || typeof title === 'number') { 224*1119c2eaS猫头猫 realTitle = <ThemeText numberOfLines={1}>{title}</ThemeText>; 225*1119c2eaS猫头猫 } else { 226*1119c2eaS猫头猫 realTitle = title; 227*1119c2eaS猫头猫 } 228*1119c2eaS猫头猫 229*1119c2eaS猫头猫 if (typeof description === 'string' || typeof description === 'number') { 230*1119c2eaS猫头猫 realDescription = ( 231*1119c2eaS猫头猫 <ThemeText 232*1119c2eaS猫头猫 numberOfLines={1} 233*1119c2eaS猫头猫 fontSize="description" 234*1119c2eaS猫头猫 fontColor="secondary" 235*1119c2eaS猫头猫 style={styles.contentDesc}> 236*1119c2eaS猫头猫 {description} 237*1119c2eaS猫头猫 </ThemeText> 238*1119c2eaS猫头猫 ); 239*1119c2eaS猫头猫 } else { 240*1119c2eaS猫头猫 realDescription = description; 241*1119c2eaS猫头猫 } 242*1119c2eaS猫头猫 243*1119c2eaS猫头猫 return ( 244*1119c2eaS猫头猫 <View style={[styles.itemContentContainer, containerStyle]}> 245*1119c2eaS猫头猫 {realTitle} 246*1119c2eaS猫头猫 {realDescription} 247*1119c2eaS猫头猫 </View> 248*1119c2eaS猫头猫 ); 24919dc08ecS猫头猫} 250e650bfb3S猫头猫 251e650bfb3S猫头猫const styles = StyleSheet.create({ 252*1119c2eaS猫头猫 /** listitem */ 253*1119c2eaS猫头猫 container: { 254*1119c2eaS猫头猫 width: '100%', 255*1119c2eaS猫头猫 flexDirection: 'row', 256*1119c2eaS猫头猫 alignItems: 'center', 257*1119c2eaS猫头猫 }, 258*1119c2eaS猫头猫 /** left */ 259*1119c2eaS猫头猫 actionBase: { 260*1119c2eaS猫头猫 height: '100%', 261*1119c2eaS猫头猫 flexShrink: 0, 262*1119c2eaS猫头猫 flexGrow: 0, 263*1119c2eaS猫头猫 flexBasis: 0, 264*1119c2eaS猫头猫 flexDirection: 'row', 265*1119c2eaS猫头猫 justifyContent: 'center', 266*1119c2eaS猫头猫 alignItems: 'center', 267*1119c2eaS猫头猫 }, 268*1119c2eaS猫头猫 269*1119c2eaS猫头猫 leftImage: { 270*1119c2eaS猫头猫 width: rpx(80), 271*1119c2eaS猫头猫 height: rpx(80), 272*1119c2eaS猫头猫 borderRadius: rpx(16), 273*1119c2eaS猫头猫 }, 274*1119c2eaS猫头猫 itemContentContainer: { 275*1119c2eaS猫头猫 flex: 1, 276*1119c2eaS猫头猫 height: '100%', 277*1119c2eaS猫头猫 justifyContent: 'center', 278*1119c2eaS猫头猫 }, 279*1119c2eaS猫头猫 contentDesc: { 280*1119c2eaS猫头猫 marginTop: rpx(16), 28119dc08ecS猫头猫 }, 28219dc08ecS猫头猫}); 283*1119c2eaS猫头猫 284*1119c2eaS猫头猫ListItem.Size = Size; 285*1119c2eaS猫头猫ListItem.ListItemIcon = ListItemIcon; 286*1119c2eaS猫头猫ListItem.ListItemImage = ListItemImage; 287*1119c2eaS猫头猫ListItem.ListItemText = ListItemText; 288*1119c2eaS猫头猫ListItem.Content = Content; 289*1119c2eaS猫头猫 290*1119c2eaS猫头猫export default ListItem; 291