u
This commit is contained in:
1 parent
63b168affc
commit
069b4506e4
29 files changed
+1077
-1116
No files matched your search
@@ -0,0 +1,105 @@
|
||||
import type { icons } from 'lucide-react-native'
|
||||
import type { ReactElement, ReactNode } from 'react'
|
||||
import type { ViewStyle } from 'react-native'
|
||||
import { Children, cloneElement, isValidElement } from 'react'
|
||||
import { Text, TouchableOpacity, View } from 'react-native'
|
||||
import LucideIcon from './LucideIcon'
|
||||
|
||||
/* ================= Cell ================= */
|
||||
export interface CellProps {
|
||||
left?: ReactNode
|
||||
right?: ReactNode
|
||||
|
||||
title?: string
|
||||
leftIcon?: keyof typeof icons
|
||||
rightIcon?: keyof typeof icons
|
||||
rightText?: string
|
||||
|
||||
isLink?: boolean
|
||||
className?: string
|
||||
style?: ViewStyle
|
||||
|
||||
showDivider?: boolean // 由 CellGroup 注入
|
||||
|
||||
onPress?: () => void
|
||||
}
|
||||
|
||||
export function Cell({
|
||||
left,
|
||||
right,
|
||||
title,
|
||||
leftIcon,
|
||||
rightIcon = 'ChevronRight',
|
||||
rightText,
|
||||
isLink = false,
|
||||
className,
|
||||
style,
|
||||
showDivider = false,
|
||||
onPress,
|
||||
}: CellProps) {
|
||||
return (
|
||||
<View>
|
||||
<TouchableOpacity
|
||||
activeOpacity={isLink ? 0.5 : 1}
|
||||
className={`flex flex-row items-center justify-between px-4 py-3 ${className}`}
|
||||
style={style}
|
||||
onPress={onPress}
|
||||
>
|
||||
{left || (
|
||||
<View className="flex flex-row items-center space-x-2">
|
||||
{leftIcon && <LucideIcon icon={leftIcon} size={18} />}
|
||||
{title && <Text className="text-base text-gray-900 ml-2">{title}</Text>}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{right || (
|
||||
<View className="flex flex-row items-center ">
|
||||
{rightText && <Text className="text-gray-500 text-base mr-2">{rightText}</Text>}
|
||||
{isLink && rightIcon && (
|
||||
<LucideIcon icon={rightIcon} size={16} color="#9ca3af" />
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
{showDivider && (
|
||||
<View
|
||||
className="bg-gray-100"
|
||||
style={{ marginLeft: 16, marginRight: 16, height: 1 }}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
/* ================= CellGroup ================= */
|
||||
export interface CellGroupProps {
|
||||
className?: string
|
||||
style?: ViewStyle
|
||||
children?: ReactNode
|
||||
showDivider?: boolean // 整组是否显示下划线
|
||||
}
|
||||
|
||||
export function CellGroup({
|
||||
className,
|
||||
style,
|
||||
children,
|
||||
showDivider = true,
|
||||
}: CellGroupProps) {
|
||||
const elements = Children.toArray(children)
|
||||
|
||||
return (
|
||||
<View className={`bg-white ${className}`} style={style}>
|
||||
{elements.map((child, index) => {
|
||||
if (!isValidElement<CellProps>(child))
|
||||
return child
|
||||
|
||||
const isLast = index === elements.length - 1
|
||||
|
||||
return cloneElement<CellProps>(child as ReactElement<CellProps>, {
|
||||
showDivider: showDivider && !isLast,
|
||||
})
|
||||
})}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user