ข้ามไปยังเนื้อหาหลัก

Dropup ทำงานอย่างไร

Dropup สร้างขึ้นจากแนวคิด headless UI - จัดการตรรกะการอัปโหลดไฟล์ที่ซับซ้อนทั้งหมดในขณะที่ให้คุณควบคุมการนำเสนอภาพได้อย่างสมบูรณ์

สถาปัตยกรรม

┌─────────────────────────────────────────────────────────────┐
│ Your React Component │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Drop Zone │ │ File List │ │ Upload Button │ │
│ │ (UI ของคุณ) │ │ (UI ของคุณ) │ │ (UI ของคุณ) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ useDropup Hook ││
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────┐ ││
│ │ │Validation │ │ State │ │ Upload │ │ Platform│ ││
│ │ │ Engine │ │ Manager │ │ Engine │ │ Adapter │ ││
│ │ └───────────┘ └───────────┘ └───────────┘ └─────────┘ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

ส่วนประกอบหลัก

1. State Manager

Dropup ใช้ useReducer ของ React สำหรับการจัดการ state ที่คาดเดาได้:

  • ติดตามไฟล์ทั้งหมดและสถานะของมัน
  • จัดการ drag state
  • จัดการความคืบหน้าการอัปโหลด
  • ให้ค่าที่คำนวณแล้ว

2. Validation Engine

ก่อนที่จะเพิ่มไฟล์ ไฟล์จะผ่านการตรวจสอบ:

const { files } = useDropup({
accept: 'image/*', // ตรวจสอบประเภทไฟล์
maxSize: 5 * 1024 * 1024, // ขนาดไฟล์สูงสุด
minSize: 1024, // ขนาดไฟล์ต่ำสุด
maxFiles: 10, // จำนวนไฟล์สูงสุด
maxWidth: 4096, // ความกว้างรูปภาพสูงสุด
maxHeight: 4096, // ความสูงรูปภาพสูงสุด
customRules: [ // การตรวจสอบแบบกำหนดเอง
(file) => file.name.length < 100 || 'ชื่อไฟล์ยาวเกินไป'
],
});

3. Upload Engine

Upload engine จัดการ:

  • การอัปโหลดแบบง่าย (คำขอเดียวต่อไฟล์)
  • การอัปโหลดแบบ chunked (แบ่งไฟล์ขนาดใหญ่)
  • ตรรกะการลองใหม่พร้อม exponential backoff
  • การจัดการการอัปโหลดพร้อมกัน
  • การติดตามความคืบหน้า

4. Platform Adapter

Dropup ทำงานข้ามแพลตฟอร์ม:

  • Web - ใช้ browser APIs ดั้งเดิม
  • React Native - ใช้การจัดการไฟล์แบบ native
  • SSR - ปลอดภัยสำหรับ server-side rendering

การไหลของข้อมูล

User Action → Validation → State Update → Upload → Callbacks
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
เลือก/ ยอมรับ/ปฏิเสธ files[] XHR/Fetch onComplete
วางไฟล์ อัปเดต Progress onError

หลักการออกแบบ

1. Headless First

ไม่มี UI components ในตัว - คุณสร้างสิ่งที่ต้องการได้อย่างแม่นยำ:

// คุณควบคุม UI ทั้งหมด
<div {...getDropProps()}>
<YourCustomDropZone />
<input {...getInputProps()} />
</div>

2. Type Safety

รองรับ TypeScript เต็มรูปแบบพร้อม types ที่ครอบคลุม:

import type { DropupFile, UseDropupOptions } from '@samithahansaka/dropup';

const options: UseDropupOptions = {
accept: 'image/*',
onUploadComplete: (file: DropupFile) => {
console.log(file.uploadedUrl);
},
};

3. Tree Shakeable

นำเข้าเฉพาะที่คุณต้องการ:

// แกนหลักเท่านั้น (~10KB)
import { useDropup } from '@samithahansaka/dropup';

// เพิ่มการรองรับคลาวด์เมื่อต้องการ
import { createS3Uploader } from '@samithahansaka/dropup/cloud/s3';

// เพิ่มการประมวลผลรูปภาพเมื่อต้องการ
import { compressImage } from '@samithahansaka/dropup/image';

4. Progressive Enhancement

เริ่มต้นง่ายๆ เพิ่มฟีเจอร์ตามต้องการ:

// การใช้งานพื้นฐาน
const { files } = useDropup();

// เพิ่มการตรวจสอบ
const { files } = useDropup({ maxSize: 10_000_000 });

// เพิ่มการอัปโหลดอัตโนมัติ
const { files } = useDropup({
maxSize: 10_000_000,
upload: { url: '/api/upload' },
autoUpload: true,
});

// เพิ่มคลาวด์สตอเรจ
const { files } = useDropup({
upload: createS3Uploader({ getPresignedUrl }),
});