| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | import type { ChangeEvent, FC } from 'react' | 
					
						
							|  |  |  | import { useState } from 'react' | 
					
						
							| 
									
										
										
										
											2023-12-01 16:50:22 +08:00
										 |  |  | import { useLocalFileUploader } from './hooks' | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | import type { ImageFile } from '@/types/app' | 
					
						
							| 
									
										
										
										
											2023-12-01 16:50:22 +08:00
										 |  |  | import { ALLOW_FILE_EXTENSIONS } from '@/types/app' | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type UploaderProps = { | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |   children: (hovering: boolean) => React.JSX.Element | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |   onUpload: (imageFile: ImageFile) => void | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |   closePopover?: () => void | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |   limit?: number | 
					
						
							|  |  |  |   disabled?: boolean | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Uploader: FC<UploaderProps> = ({ | 
					
						
							|  |  |  |   children, | 
					
						
							|  |  |  |   onUpload, | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |   closePopover, | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |   limit, | 
					
						
							|  |  |  |   disabled, | 
					
						
							|  |  |  | }) => { | 
					
						
							|  |  |  |   const [hovering, setHovering] = useState(false) | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |   const { handleLocalFileUpload } = useLocalFileUploader({ | 
					
						
							|  |  |  |     limit, | 
					
						
							|  |  |  |     onUpload, | 
					
						
							|  |  |  |     disabled, | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const handleChange = (e: ChangeEvent<HTMLInputElement>) => { | 
					
						
							|  |  |  |     const file = e.target.files?.[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!file) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-01 16:50:22 +08:00
										 |  |  |     handleLocalFileUpload(file) | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |     closePopover?.() | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <div | 
					
						
							|  |  |  |       className='relative' | 
					
						
							|  |  |  |       onMouseEnter={() => setHovering(true)} | 
					
						
							|  |  |  |       onMouseLeave={() => setHovering(false)} | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       {children(hovering)} | 
					
						
							|  |  |  |       <input | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         className='absolute inset-0 block w-full cursor-pointer text-[0] opacity-0 disabled:cursor-not-allowed' | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |         onClick={e => ((e.target as HTMLInputElement).value = '')} | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |         type='file' | 
					
						
							| 
									
										
										
										
											2023-12-01 10:04:14 +08:00
										 |  |  |         accept={ALLOW_FILE_EXTENSIONS.map(ext => `.${ext}`).join(',')} | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |         onChange={handleChange} | 
					
						
							|  |  |  |         disabled={disabled} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default Uploader |