Upload

Upload files by selecting or dragging.

Component Features

  • 📁 Multiple Files: Supports multiple prop for selecting multiple files.
  • 📄 File Type Restriction: Supports accept prop to restrict uploadable file types.
  • 📊 Count & Size Limits: Supports maxCount for upload count and maxSize for file size limits.
  • Auto Upload: Supports autoUpload prop to control whether to upload immediately after selection.
  • 🔧 Custom Request: Supports action, headers, data props to configure upload request parameters.
  • 📝 Form Integration: Seamlessly integrates with BrForm and supports vee-validate validation.
  • 🎨 Theme Customization: Supports TailwindCSS local style overrides.

Basic Usage

<script setup lang="ts">
import { ref } from 'vue'
import { BrUpload, BrUploadDropzone, BrUploadFileList, BrUploadFileItem, BrUploadPreview } from '@breezeui/vue'
import { UploadCloud } from 'lucide-vue-next'

const files = ref([])
const previewFile = ref(null)
const previewOpen = ref(false)

const handlePreview = (file: any) => {
  previewFile.value = file
  previewOpen.value = true
}

const handleExceed = () => {
  alert('Exceeded maximum file count!')
}
</script>

<template>
  <div>
    <BrUpload 
      v-model="files" 
      multiple
      :max-count="5"
      action="https://jsonplaceholder.typicode.com/posts/"
      @preview="handlePreview"
      @exceed="handleExceed"
    >
      <BrUploadDropzone v-slot="{ isDragOver }">
        <div class="flex flex-col items-center justify-center py-6">
          <UploadCloud 
            class="w-12 h-12 mb-4 transition-colors" 
            :class="isDragOver ? 'text-[var(--br-primary)]' : 'text-[var(--br-muted-foreground)]'" 
          />
          <p class="text-lg font-medium text-[var(--br-foreground)]">Click or drag files to this area</p>
          <p class="text-sm text-[var(--br-muted-foreground)] mt-2">Supports multi-file upload, max 5 files.</p>
        </div>
      </BrUploadDropzone>
      
      <BrUploadFileList v-slot="{ files }">
        <BrUploadFileItem v-for="file in files" :key="file.id" :file="file" />
      </BrUploadFileList>
    </BrUpload>

    <BrUploadPreview v-model:open="previewOpen" :file="previewFile" />
  </div>
</template>

Form Integration

The Upload component seamlessly integrates with BrForm and vee-validate.

<script setup lang="ts">
import { ref } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { 
  BrUpload, 
  BrUploadTrigger, 
  BrUploadFileList, 
  BrUploadFileItem,
  BrUploadPreview,
  BrForm, 
  BrFormItem, 
  BrFormLabel, 
  BrFormControl, 
  BrFormMessage,
  BrButton
} from '@breezeui/vue'
import { Upload } from 'lucide-vue-next'

const schema = toTypedSchema(
  z.object({
    documents: z.array(z.any()).min(1, 'Please upload at least one document')
  })
)

const form = useForm({
  validationSchema: schema,
  initialValues: {
    documents: []
  }
})

const onSubmit = form.handleSubmit((values) => {
  console.log('Form submitted with values:', values)
  alert('Form submitted successfully!')
})

const previewFile = ref<any>(null)
const previewOpen = ref(false)

const handlePreview = (file: any) => {
  previewFile.value = file
  previewOpen.value = true
}
</script>

<template>
  <div>
    <BrForm class="space-y-6 max-w-md" @submit="onSubmit">
      <BrFormItem name="documents">
        <BrFormLabel>Important Documents *</BrFormLabel>
        <BrFormControl>
          <BrUpload
            action="https://jsonplaceholder.typicode.com/posts/"
            @preview="handlePreview"
          >
            <BrUploadTrigger>
              <BrButton variant="outline" type="button">
                <Upload class="w-4 h-4 mr-2" />
                Select Document
              </BrButton>
            </BrUploadTrigger>
            <BrUploadFileList v-slot="{ files }">
              <BrUploadFileItem v-for="file in files" :key="file.id" :file="file" />
            </BrUploadFileList>
          </BrUpload>
        </BrFormControl>
        <BrFormMessage />
      </BrFormItem>
      <BrButton type="submit">Submit Form</BrButton>
    </BrForm>

    <BrUploadPreview v-model:open="previewOpen" :file="previewFile" />
  </div>
</template>

API

BrUpload Props

NameTypeDefaultDescription
modelValueUploadFile[][]V-model value representing the selected files
namestring'file'The name of the input file field
actionstring''Upload URL
headersRecord<string, string>{}Request headers
dataRecord<string, any>{}Extra payload data
multiplebooleanfalseWhether multiple files are allowed
acceptstring''Accepted file types
maxCountnumber-Maximum number of files allowed
maxSizenumber-Maximum size of a file in bytes
disabledbooleanfalseWhether the upload is disabled
autoUploadbooleantrueWhether to automatically upload files after selection

BrUpload Emits

NameDescriptionParameters
update:modelValueEmitted when file list changes(files: UploadFile[])
changeEmitted when a file is selected(file: UploadFile, fileList: UploadFile[])
removeEmitted when a file is removed(file: UploadFile, fileList: UploadFile[])
successEmitted on successful upload(response: any, file: UploadFile, fileList: UploadFile[])
errorEmitted on upload error(error: Error, file: UploadFile, fileList: UploadFile[])
progressEmitted during upload progress(event: ProgressEvent, file: UploadFile, fileList: UploadFile[])
exceedEmitted when max count is exceeded(files: File[], fileList: UploadFile[])
previewEmitted when previewing a file(file: UploadFile)