This commit is contained in:
oneao committed 2025-11-21 17:27:44 +08:00
1 parent bb780a42ab
commit d3145e3dc5
19 files changed
+15364 -416

No files matched your search

@@ -12,7 +12,7 @@ import LucideIcon from './LucideIcon'
type IconProp = (LucideIconProps & { icon: keyof typeof icons }) | React.ReactNode
interface CustomButtonProps {
children: React.ReactNode
children?: React.ReactNode
onPress?: () => void
disabled?: boolean
loading?: boolean
@@ -40,19 +40,21 @@ const Button: React.FC<CustomButtonProps> = ({
rightIcon,
}) => {
const isDisabled = disabled || loading
const hasChildren = !!children
console.log(hasChildren)
const renderLeftIcon = () => {
if (loading)
return <ButtonSpinner color="#fff" className="mr-2" />
return <ButtonSpinner color="#fff" className={hasChildren ? 'mr-2' : ''} />
if (!leftIcon)
return null
if (React.isValidElement(leftIcon)) {
return <span className="mr-2">{leftIcon}</span>
return <span className={hasChildren ? 'mr-2' : ''}>{leftIcon}</span>
}
const { icon, ...props } = leftIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className="mr-2" {...props} />
return <LucideIcon icon={icon} className={hasChildren ? 'mr-2' : ''} {...props} />
}
const renderRightIcon = () => {
@@ -60,11 +62,11 @@ const Button: React.FC<CustomButtonProps> = ({
return null
if (React.isValidElement(rightIcon)) {
return <span className="ml-2">{rightIcon}</span>
return <span className={hasChildren ? 'ml-2' : ''}>{rightIcon}</span>
}
const { icon, ...props } = rightIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className="ml-2" {...props} />
return <LucideIcon icon={icon} className={hasChildren ? 'ml-2' : ''} {...props} />
}
return (
@@ -78,7 +80,11 @@ const Button: React.FC<CustomButtonProps> = ({
size={size}
>
{renderLeftIcon()}
<ButtonText>{children}</ButtonText>
{
children && (
<ButtonText>{children}</ButtonText>
)
}
{renderRightIcon()}
</NativeButton>
)
@@ -0,0 +1,46 @@
import { useState } from 'react'
import { Pressable, Text, View } from 'react-native'
interface TabItem {
label: string
key: string
}
interface TabProps {
data?: TabItem[]
defaultIndex?: number
onChange?: (index: number) => void
}
export default function Tab({ data, defaultIndex = 0, onChange }: TabProps) {
const [selectedIndex, setSelectedIndex] = useState(defaultIndex)
if (!data || data.length === 0)
return null
const handlePress = (index: number) => {
setSelectedIndex(index)
onChange?.(index)
}
return (
<View className="flex flex-row gap-2 overflow-hidden">
{data.map((item, index) => {
const isActive = index === selectedIndex
return (
<Pressable
key={item.key}
onPress={() => handlePress(index)}
className={`items-center justify-center rounded-md px-4 py-2 ${
isActive ? 'bg-gray-800' : 'bg-gray-200'
}`}
>
<Text className={`${isActive ? 'text-white' : 'text-gray-700'}`}>
{item.label}
</Text>
</Pressable>
)
})}
</View>
)
}
@@ -8,6 +8,7 @@ import Input from './Input'
import LucideIcon from './LucideIcon'
import Modal from './Modal'
import SegmentedTabs from './SegmentedTabs'
import Tab from './Tab'
export {
Button as AButton,
@@ -21,5 +22,6 @@ export {
Input as AInput,
Modal as AModal,
SegmentedTabs as ASegmentedTabs,
Tab as ATab,
LucideIcon,
}