Skip to content
RTL Support: Full
Accessibility: Full
Translations: Not Needed

Upload

A versatile component that supports drag-and-drop or button-triggered file uploads.

Default

The default upload mode renders a drag-and-drop drop zone that also accepts clicks to open the file picker.

Click to upload

or drag and drop

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload v-model:file-list="fileList" @change="handleChange"> </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const handleChange = data => {
    console.log('Files changed:', data)
  }

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
    {
      id: 'b',
      name: 'Tech design requirements.pdf',
      status: 'finished',
      type: 'video/mp4',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/ab8d4d61-33a6-48be-a56b-df60693544ae.jpeg',
    },
    {
      id: 'c',
      name: 'Tech design requirements.pdf',
      status: 'uploading',
      percentage: 50,
      type: 'application/pdf',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/6396e0f2b5d8bd0ff06eb0df.jpeg',
    },
    {
      id: 'd',
      name: 'Tech design requirements.pdf',
      status: 'error',
      type: 'zip',
      percentage: 50,
    },
  ])
</script>

Button Trigger

Set type="button" to render a single upload button instead of the drag-and-drop area. Clicking it opens the native file picker. Customize the button's icon and label through the buttonContent slot.

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload id="example-upload" v-model:file-list="fileList" :multiple="true" @change="handleChange" type="button">
    <template #buttonContent>
      <UploadCloud01Icon class="w-4 h-4 mr-2" />
      <span>Upload Multiple Images</span>
    </template>
  </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

Customizing the Trigger Button

With type="button", pass buttonProps to style the trigger — it accepts any HLButton prop, so variant, size, color, and the rest all apply. Use the buttonIcon slot for a leading icon.

INFO

buttonIcon and buttonContent compose: with both, the icon renders to the left of your content. With buttonIcon alone, it becomes the button's only icon. buttonContent alone replaces the whole label.

vue
<template>
  <HLUpload
    id="example-upload-button-props"
    v-model:file-list="fileList"
    type="button"
    :multiple="true"
    :button-props="{ variant: 'primary', color: 'warning', size: 'md' }"
  >
    <template #buttonIcon>
      <Upload01Icon />
    </template>
    <template #buttonContent>
      <span>Choose files</span>
    </template>
  </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { Upload01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([])
</script>

INFO

disabled is merged from both sources — setting it on the component or inside buttonProps disables the trigger.

Custom Content

Use the icon and extra slots to replace the default drop-zone icon and helper text.

Click or Drag and Drop

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload v-model:file-list="fileList" @change="handleChange">
    <template #icon>
      <Upload01Icon class="w-4 h-4 mr-2" />
    </template>
    <template #extra>
      <HLText size="md" weight="medium" class="text-primary-600">Click or Drag and Drop</HLText>
    </template>
  </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload, HLText } from '@platform-ui/highrise'
  import { Upload01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

Upload Source Menu

This example adds a custom "Add files" link inside the drag-and-drop area. Clicking it opens a dropdown with two choices:

  • Upload media — opens your device's native file picker (via the component's openFileDialog() method).
  • Add from Media library — opens a modal where you'd embed your own media picker.

Dragging files directly onto the area still works as usual — the menu just gives users a second way to start an upload and choose the source.

INFO

The menu lives in the extra slot. Wrap it in @click.prevent.stop so clicking the link opens the dropdown instead of immediately firing the area's default file picker. In the dropdown's select handler, call uploadRef.value.openFileDialog() only for the "Upload media" option; the other option opens the modal.

vue
<template>
  <HLUpload
    ref="uploadRef"
    type="draggable"
    v-model:file-list="openFileDialogFileList"
    @change="handleOpenFileDialogChange"
  >
    <template #extra>
      <div @click.prevent.stop>
        <HLDropdown
          id="upload-source-dropdown"
          :options="uploadSourceOptions"
          :show-search="false"
          :show-arrow="false"
          :highlight-selection="false"
          @select="handleUploadSourceSelect"
        >
          <div class="flex flex-row items-center justify-center gap-1 cursor-pointer">
            <HLText size="md" weight="medium" class="text-primary-600">Add files</HLText>
            <HLText size="md" class="text-gray-600">or drag and drop</HLText>
          </div>
        </HLDropdown>
      </div>
    </template>
  </HLUpload>

  <HLModal v-model:show="showMediaLibraryModal" title="Add from Media Library" size="md">
    <div class="p-4">
      <HLText size="md" class="text-gray-600">
        Select from your media library. Integrate your media picker component here.
      </HLText>
    </div>
  </HLModal>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { HLUpload, HLDropdown, HLModal, HLText } from '@platform-ui/highrise'
import { uploadSourceOptions } from './options'

const uploadRef = ref(null)
const openFileDialogFileList = ref([])
const showMediaLibraryModal = ref(false)

const handleUploadSourceSelect = key => {
  if (key === 'upload-media') uploadRef.value?.openFileDialog()
  else if (key === 'media-library') showMediaLibraryModal.value = true
}

const handleOpenFileDialogChange = ({ fileList }) => {
  openFileDialogFileList.value = fileList
}
</script>
ts
import { UploadCloud01Icon, Image01Icon } from '@gohighlevel/ghl-icons/24/outline'

export const uploadSourceOptions = [
  { key: 'upload-media', label: 'Upload media', type: 'icon', icon: UploadCloud01Icon },
  { key: 'media-library', label: 'Add from Media library', type: 'icon', icon: Image01Icon },
]

Multiple Upload

Set the multiple prop to true to allow selecting and uploading more than one file at a time.

Click to upload

or drag and drop

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload id="example-upload" v-model:file-list="fileList" :multiple="true" @change="handleChange" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

Limiting File Count

Set max to cap how many files the list can hold. Once the limit is reached, further selections are rejected.

Click to upload

or drag and drop

vue
<template>
  <!-- At most 3 files -->
  <HLUpload id="example-upload-max" v-model:file-list="fileList" :multiple="true" :max="3" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'

  const fileList = ref([])
</script>

In inline mode max does something extra: once the count is reached, the inline label itself is disabled, so the trigger visibly greys out instead of silently rejecting the next selection. Add two files below to see it.

Attach up to 2 files

N/A

vue
<template>
  <!-- The inline label is disabled once 2 files are attached -->
  <HLUpload id="example-upload-max-inline" v-model:file-list="fileList" :inline="true" :multiple="true" :max="2">
    <template #inlineUploadLabelIcon>
      <UploadCloud01Icon class="w-4 h-4" />
    </template>
    <template #inlineUploadLabelText>
      <HLText size="lg" weight="medium" class="text-gray-600">Attach up to 2 files</HLText>
    </template>
  </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload, HLText } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([])
</script>

Restrict File Types

Pass a comma-separated list of extensions or MIME types to the accept prop to limit what the file picker allows. Here only .pdf, .jpeg, and .png files can be selected.

Click to upload

or drag and drop

Supported file types: .pdf,.jpeg,.png

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload id="example-upload" v-model:file-list="fileList" :multiple="true" @change="handleChange" accept=".pdf,.jpeg,.png" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

File Handling

Handle the change event to upload selected files and update each entry's status, percentage, and url as the upload progresses.

Click to upload

or drag and drop

vue
<template>
  <HLUpload v-model:file-list="fileListUpload" @change="handleUpload"> </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  const fileListUpload = ref([])

  const handleUpload = data => {
    // simulating file upload - call actual upload API here and update the fileListUpload with the actual file info
    let progress = 0
    const interval = setInterval(() => {
      progress += 20
      fileListUpload.value = fileListUpload.value.map(file => ({
        ...file,
        status: progress >= 100 ? 'finished' : 'uploading',
        percentage: progress,
        url:
          progress >= 100 ? 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg' : undefined,
      }))

      if (progress >= 100) {
        clearInterval(interval)
      }
    }, 500)
  }
</script>

Queued Uploads

Set :default-upload="false" to hold selected files instead of uploading them straight away. Files wait in the queued state — shown with a clock tag rather than a progress bar — until your own trigger starts the upload.

INFO

While uploads are deferred, files that have not started yet render as queued. Once a file starts uploading it shows the usual progress bar, then the success state when it finishes.

The queued state is only available in the default list. In inline mode a waiting file keeps the standard tag with a progress indicator, so use the default list when the queued state matters.

With type="button", the upload has two controls: the trigger that adds files and your own control that starts the upload. Label the trigger accordingly — for example Add files rather than Upload — so it is clear which one begins the transfer.

Click to upload

or drag and drop

Tech design requirements 1.pdf

<1 KB

Queued

Tech design requirements 2.pdf

<1 KB

Queued
Vue
html
<template>
  <HLUpload
    id="example-queued-upload"
    v-model:file-list="queuedFileList"
    :multiple="true"
    :default-upload="false"
    @change="handleQueuedChange"
  />
  <HLButton size="sm" :disabled="!queuedCount" @click="startQueuedUploads">Upload all</HLButton>
</template>
<script setup>
  import { HLUpload, HLButton } from '@platform-ui/highrise'
  import { computed, ref } from 'vue'

  // Selected files stay `pending` because uploads are deferred,
  // so the list renders them as queued.
  const queuedFileList = ref([])
  const queuedCount = computed(() => queuedFileList.value.filter(file => file.status === 'pending').length)

  const handleQueuedChange = data => {
    queuedFileList.value = data.fileList
  }

  const patchFile = (id, patch) => {
    queuedFileList.value = queuedFileList.value.map(file => (file.id === id ? { ...file, ...patch } : file))
  }

  const startQueuedUploads = () => {
    queuedFileList.value
      .filter(file => file.status === 'pending')
      .forEach(file => {
        // call your upload API here and patch the file as it progresses
        patchFile(file.id, { status: 'uploading', percentage: 0 })
      })
  }
</script>

Retry and Preview

Two callbacks handle interactions with files already in the list:

  • onRetry — fires when the retry button on a failed file is clicked. Return false to suppress the built-in retry and run your own, as below.
  • onPreview — fires when a finished file's name is clicked.

INFO

Both are callback props, not events — there is no @retry or @preview to listen for. Pass them as :on-retry / :on-preview.

Click the retry icon on the failed file, or the name of the finished one.

Click to upload

or drag and drop

Quarterly report.pdf

Failed to upload

Team photo.jpeg

<1 KB

Callback Log:

Nothing yet — try a retry or click a finished file's name.
vue
<template>
  <HLUpload id="example-upload-retry" v-model:file-list="fileList" :on-retry="handleRetry" :on-preview="handlePreview" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'

  const fileList = ref([
    { id: 'r1', name: 'Quarterly report.pdf', status: 'error', type: 'application/pdf', percentage: 40 },
    {
      id: 'r2',
      name: 'Team photo.jpeg',
      status: 'finished',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  // Return false to cancel the built-in retry and drive the upload yourself
  const handleRetry = ({ file }) => {
    fileList.value = fileList.value.map(item => (item.id === file.id ? { ...item, status: 'uploading', percentage: 0 } : item))
    // ...kick off your re-upload here, updating status/percentage/url as it runs
    return false
  }

  const handlePreview = file => {
    // e.g. open the file in a modal or a new tab
    window.open(file.url, '_blank')
  }
</script>

Download Support

  • Set the show-download-button prop to true to show a download button on finished files.
  • Pass an onDownload handler to run your own download logic when the button is clicked.

INFO

onDownload and @download are the same listener — in Vue, the onDownload prop is the @download handler. Use either spelling; don't wire up both. When a handler is provided, it replaces the default download (which otherwise saves the file's url directly in the browser) and receives the file. @retry / @preview have no such event form — pass onRetry / onPreview as callback props.

Click to upload

or drag and drop

Tech design requirements.pdf

<1 KB

vue
<template>
  <HLUpload v-model:file-list="downloadfileList" :show-download-button="true" :onDownload="handleDownload"> </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'

  const downloadfileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'finished',
      type: 'application/pdf',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleDownload = file => {
    // your download logic here
    console.log('downloaded file ', file)
  }
</script>
ts
// Fetch the file via XHR before saving — useful for cross-origin URLs.
import { downloadFromXHR } from '@platform-ui/highrise'

const handleDownload = file => {
  downloadFromXHR(file)
}

Disabled Upload

Set the disabled prop to true to prevent file selection and uploads.

Click to upload

or drag and drop

Tech design requirements.pdf

<1 KB

0%

Tech design requirements.pdf

<1 KB

Tech design requirements.pdf

<1 KB

50%

Tech design requirements.pdf

Failed to upload

vue
<template>
  <HLUpload id="example-upload-disabled" v-model:file-list="fileList" disabled @change="handleChange" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

Inline Upload

Set inline to render the upload as a compact label instead of a drop zone or button. Selected files appear as a row of removable chips beneath it, each showing its upload status. Customize the label with the inlineUploadLabelIcon and inlineUploadLabelText slots. This suits tight layouts like forms or table rows where a full drop zone is too large.

INFO

inline takes precedence over type. When inline is true, the component always renders the inline label and the type prop ('draggable' / 'button') is ignored.

INFO

Inline mode does not have a queued state. Files waiting to upload show the standard tag with a progress indicator — see Queued Uploads.

Attach Files

Tech design requirements.pdf
Tech design requirements.pdf
Tech design requirements.pdf
Tech design requirements.pdf
vue
<template>
  <HLUpload id="example-inline-upload" v-model:file-list="fileList" :inline="true" @change="handleChange">
    <template #inlineUploadLabelIcon>
      <UploadCloud01Icon class="w-4 h-4" />
    </template>
    <template #inlineUploadLabelText>
      <HLText size="lg" weight="medium" class="text-gray-600">Attach Files</HLText>
    </template>
  </HLUpload>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLUpload, HLText } from '@platform-ui/highrise'
  import { UploadCloud01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const fileList = ref([
    {
      id: 'a',
      name: 'Tech design requirements.pdf',
      status: 'pending',
      type: 'image/jpeg',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/640572bf27f37128ce68dcd2.jpeg',
    },
    {
      id: 'b',
      name: 'Tech design requirements.pdf',
      status: 'finished',
      type: 'video/mp4',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/ab8d4d61-33a6-48be-a56b-df60693544ae.jpeg',
    },
    {
      id: 'c',
      name: 'Tech design requirements.pdf',
      status: 'uploading',
      percentage: 50,
      type: 'application/pdf',
      url: 'https://storage.googleapis.com/msgsndr/Vnhvoz8w8g7iFEFz37aq/media/6396e0f2b5d8bd0ff06eb0df.jpeg',
    },
    {
      id: 'd',
      name: 'Tech design requirements.pdf',
      status: 'error',
      type: 'zip',
      percentage: 50,
    },
  ])

  const handleChange = data => {
    // your logic here
  }
</script>

Event Testing

HLUpload does not upload files for you — it surfaces the selected files through events and expects you to run the upload and update each file's status, percentage, and url as it progresses. Handle @change to start the upload; @remove fires when a file is removed and @update:file-list whenever the bound list changes. The @change payload carries the affected file, the full fileList, and the originating DOM event.

The demo below simulates an upload: when a pending file arrives it advances to uploading and finally finished. Add and remove files to watch each event fire. (Download is handled via the onDownload prop — see Download Support.)

Click to upload

or drag and drop

Event Log:

No events logged yet. Add or remove a file above.
vue
<template>
  <HLUpload
    id="upload-events"
    v-model:file-list="fileList"
    :multiple="true"
    @change="handleChange"
    @remove="handleRemove"
    @update:file-list="handleUpdateFileList"
  />
  <div class="text-sm">
    <p class="font-bold mb-2">Event Log:</p>
    <div v-if="eventLog.length === 0" class="text-gray-500">No events logged yet. Add or remove a file above.</div>
    <div v-for="(log, index) in eventLog" :key="index" class="text-gray-700">{{ log.timestamp }}: {{ log.event }}</div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { HLUpload } from '@platform-ui/highrise'

const fileList = ref([])
const eventLog = ref<{ event: string; timestamp: string }[]>([])
const addEventLog = (event: string) => {
  eventLog.value.unshift({ event, timestamp: new Date().toLocaleTimeString() })
  if (eventLog.value.length > 5) eventLog.value.pop()
}

// Replace this with your real upload API call, updating status/percentage/url as it progresses.
const simulateUpload = (fileId: string) => {
  let progress = 0
  const interval = setInterval(() => {
    progress += 25
    const done = progress >= 100
    fileList.value = fileList.value.map(file =>
      file.id === fileId
        ? { ...file, status: done ? 'finished' : 'uploading', percentage: Math.min(progress, 100), url: done ? '<uploaded-url>' : undefined }
        : file
    )
    if (done) clearInterval(interval)
  }, 400)
}

const handleChange = data => {
  addEventLog('@change → ' + data.file.name + ' (' + data.file.status + ')')
  fileList.value = data.fileList
  // A freshly selected file starts as `pending` — kick off the upload for it.
  if (data.file.status === 'pending') simulateUpload(data.file.id)
}
const handleRemove = data => addEventLog('@remove → ' + data.file.name)
const handleUpdateFileList = list => addEventLog('@update:file-list → ' + list.length + ' file(s)')
</script>

Accessibility

  • Give the trigger/input aria-label describing the accepted file types/count, and wire helper text via aria-describedby for size rules.
  • Surface validation or progress feedback inside role="status" / aria-live="polite" regions so updates announce automatically.
  • When drag-and-drop is enabled, toggle aria-busy or include text that announces when the drop target is ready.

Imports

ts
import { HLUpload } from '@platform-ui/highrise'

Props

NameTypeDefaultDescription
id *string | undefinedundefinedThe id of the element
multiplebooleanfalseEnables multiple file uploads
disabledboolean | undefinedundefinedDisables the upload functionality
fileListUploadFileInfo[][]The list of files being uploaded
maxnumber | undefinedundefinedMaximum number of files that can be uploaded
type'draggable' | 'button''draggable'Sets the style of the upload component. Ignored when inline is true.
inlinebooleanfalseDisplays the upload component in compact inline mode. Takes precedence over type.
buttonPropsHLButtonProps | undefinedundefinedProps for customizing the upload button. Refer HLButtonProps
showDownloadButtonbooleanfalseToggles the download button visibility for finished files
acceptstring | undefinedundefinedFile types allowed for upload. See accept for more details.
defaultUploadbooleantrueWhen false, selected files wait in the queued state until an upload is triggered. Not applicable to inline mode. See Queued Uploads
onDownload(file: UploadFileInfo) => voidundefinedCustom download handler. When set, it replaces the default browser download. Same listener as the @download event.
onRetry(data: { file: UploadFileInfo }) => boolean | Promise<boolean>undefinedCallback invoked when the retry button on a failed file is clicked. Return false to cancel the retry. Callback-only — there is no @retry event.
onPreview(file: UploadFileInfo, detail: { event: MouseEvent }) => voidundefinedCallback invoked when a finished file's name is clicked. Callback-only — there is no @preview event.

Types

Upload File Info

ts
interface UploadFileInfo {
  id: string
  name: string
  batchId?: string | null
  percentage?: number | null
  status: 'pending' | 'uploading' | 'finished' | 'removed' | 'error'
  url?: string | null
  file?: File | null
  thumbnailUrl?: string | null
  type?: string | null
  fullPath?: string | null
}

Emits

NameArgumentsDescription
@change(val: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event })Triggered when files are added or removed
@remove(val: { file: UploadFileInfo, fileList: Array<UploadFileInfo> })Triggered when a file is removed.
@update:file-list(val: UploadFileInfo[])Triggered when the file list is updated
@download(file: UploadFileInfo)Triggered when a file download is initiated. Equivalent to the onDownload prop — use one, not both. Refer Types

Slots

NameParametersDescription
buttonContent()Content inside the button when type is 'button'
buttonIcon()Icon slot for the button when type is 'button'
extra()Custom description for the upload area
inlineUploadLabelIcon()Icon slot for the inline upload label when inline is true
inlineUploadLabelText()Text slot for the inline upload label when inline is true

Exposed Methods

Access via template ref (e.g. ref="uploadRef"):

MethodDescription
openFileDialog()Opens the native file selection dialog programmatically
clear()Clears the current file list
submit()Submits all pending files