freshyo/packages/ui/src/components/ImageUploaderNeo.tsx
2026-03-26 17:16:56 +05:30

98 lines
2.8 KiB
TypeScript

import React from 'react'
import { View } from 'react-native'
import { Image } from 'expo-image'
import Ionicons from '@expo/vector-icons/Ionicons'
import { MaterialIcons } from '@expo/vector-icons'
import tw from '../lib/tailwind'
import MyText from './text'
import MyTouchableOpacity from './touchable-opacity'
import usePickImage from './use-pick-image'
export interface ImageUploaderNeoItem {
imgUrl: string
mimeType: string | null
}
export interface ImageUploaderNeoPayload {
url: string
mimeType: string | null
}
interface ImageUploaderNeoProps {
images: ImageUploaderNeoItem[]
onImageAdd: (images: ImageUploaderNeoPayload[]) => void
onImageRemove: (image: ImageUploaderNeoPayload) => void
allowMultiple?: boolean
}
const ImageUploaderNeo: React.FC<ImageUploaderNeoProps> = ({
images,
onImageAdd,
onImageRemove,
allowMultiple = true,
}) => {
const totalImageCount = images.length
const handleAddImages = (files: any) => {
if (!files) return
const assets = Array.isArray(files) ? files : [files]
const payload = assets.map((asset) => ({
url: asset.uri,
mimeType: asset.mimeType ?? null,
}))
onImageAdd(payload)
}
const handlePickImage = usePickImage({
setFile: handleAddImages,
multiple: allowMultiple,
})
// console.log({images})
return (
<View style={tw`mb-4`}>
<View style={tw`flex-row flex-wrap -mx-1`}>
{images.map((image, index) => (
<View key={`neo-${index}`} style={tw`w-1/3 px-1 mb-2 relative`}>
<Image
source={{ uri: image.imgUrl }}
style={tw`w-full aspect-square rounded`}
/>
<MyTouchableOpacity
onPress={() =>
onImageRemove({
url: image.imgUrl,
mimeType: image.mimeType ?? null,
})
}
style={tw`absolute top-0 right-0 bg-red-500 rounded-full p-1`}
>
<Ionicons name='close' size={16} color='white' />
</MyTouchableOpacity>
</View>
))}
<MyTouchableOpacity
disabled={!allowMultiple && totalImageCount >= 1}
onPress={handlePickImage}
style={tw`w-1/3 px-1 mb-2`}
>
<View style={tw`w-full aspect-square bg-gray-200 rounded justify-center items-center opacity-75`}>
{!allowMultiple && totalImageCount >= 1 ? (
<View style={tw`absolute inset-0 bg-white/70 rounded justify-center items-center`}>
<MyText style={tw`text-center text-gray-500`}>
Only one image allowed
</MyText>
</View>
) : (
<MaterialIcons name='add' size={32} color='black' />
)}
</View>
</MyTouchableOpacity>
</View>
</View>
)
}
export default ImageUploaderNeo