Skip to content

⬅️ Back to Table of Contents

📄 useFileDialog

📊 Analysis Summary

Metric Count
🔧 Functions 5
📦 Imports 14
📊 Variables & Constants 1
🟢 Vue Composition API 1
📐 Interfaces 2

📚 Table of Contents

🛠️ File Location:

📂 packages/core/useFileDialog/index.ts

📦 Imports

Name Source
EventHookOn @vueuse/shared
MaybeRef vue
Ref vue
ConfigurableDocument ../_configurable
MaybeElementRef ../unrefElement
createEventHook @vueuse/shared
hasOwn @vueuse/shared
computed vue
deepReadonly vue
deepRef vue
toValue vue
watchEffect vue
defaultDocument ../_configurable
unrefElement ../unrefElement

Variables & Constants

Name Type Kind Value Exported
DEFAULT_OPTIONS UseFileDialogOptions const { multiple: true, accept: '*', reset: false, directory: false, }

Vue Composition API

Name Type Reactive Variables Composables
computed computed none none

Functions

useFileDialog(options: UseFileDialogOptions): UseFileDialogReturn

Open file dialog with ease.

Parameters:

  • options any: No description

See: https://vueuse.org/useFileDialog

Raw JSDoc
/**
 * Open file dialog with ease.
 *
 * @see https://vueuse.org/useFileDialog
 * @param options
 */

Calls:

  • deepRef (from vue)
  • prepareInitialFiles
  • createEventHook (from @vueuse/shared)
  • computed (from vue)
  • unrefElement (from ../unrefElement)
  • document.createElement
  • changeTrigger
  • cancelTrigger
  • toValue (from vue)
  • hasOwn (from @vueuse/shared)
  • applyOptions
  • reset
  • el.click
  • watchEffect (from vue)
  • deepReadonly (from vue)

Internal Comments:

// webkitdirectory key is not stabled, maybe replaced in the future. (x4)

Code
export function useFileDialog(options: UseFileDialogOptions = {}): UseFileDialogReturn {
  const {
    document = defaultDocument,
  } = options

  const files = deepRef<FileList | null>(prepareInitialFiles(options.initialFiles))
  const { on: onChange, trigger: changeTrigger } = createEventHook()
  const { on: onCancel, trigger: cancelTrigger } = createEventHook()
  const inputRef = computed(() => {
    const input = unrefElement(options.input) ?? (document ? document.createElement('input') : undefined)
    if (input) {
      input.type = 'file'

      input.onchange = (event: Event) => {
        const result = event.target as HTMLInputElement
        files.value = result.files
        changeTrigger(files.value)
      }

      input.oncancel = () => {
        cancelTrigger()
      }
    }
    return input
  })

  const reset = () => {
    files.value = null
    if (inputRef.value && inputRef.value.value) {
      inputRef.value.value = ''
      changeTrigger(null)
    }
  }

  const applyOptions = (options: UseFileDialogOptions) => {
    const el = inputRef.value
    if (!el)
      return
    el.multiple = toValue(options.multiple)!
    el.accept = toValue(options.accept)!
    // webkitdirectory key is not stabled, maybe replaced in the future.
    el.webkitdirectory = toValue(options.directory)!
    if (hasOwn(options, 'capture'))
      el.capture = toValue(options.capture)!
  }

  const open = (localOptions?: Partial<UseFileDialogOptions>) => {
    const el = inputRef.value
    if (!el)
      return
    const mergedOptions = {
      ...DEFAULT_OPTIONS,
      ...options,
      ...localOptions,
    }
    applyOptions(mergedOptions)
    if (toValue(mergedOptions.reset))
      reset()
    el.click()
  }

  watchEffect(() => {
    applyOptions(options)
  })

  return {
    files: deepReadonly(files),
    open,
    reset,
    onCancel,
    onChange,
  }
}

prepareInitialFiles(files: UseFileDialogOptions['initialFiles']): FileList | null

Parameters:

  • files UseFileDialogOptions['initialFiles']

Returns: FileList | null

Calls:

  • dt.items.add
Code
function prepareInitialFiles(files: UseFileDialogOptions['initialFiles']): FileList | null {
  if (!files)
    return null

  if (files instanceof FileList)
    return files

  const dt = new DataTransfer()
  for (const file of files) {
    dt.items.add(file)
  }

  return dt.files
}

Internal helpers

Declared inside another function in this file.

reset(): void

Returns: void

Calls:

  • changeTrigger
Code
() => {
    files.value = null
    if (inputRef.value && inputRef.value.value) {
      inputRef.value.value = ''
      changeTrigger(null)
    }
  }

applyOptions(options: UseFileDialogOptions): void

Parameters:

  • options UseFileDialogOptions

Returns: void

Calls:

  • toValue (from vue)
  • hasOwn (from @vueuse/shared)

Internal Comments:

// webkitdirectory key is not stabled, maybe replaced in the future. (x4)

Code
(options: UseFileDialogOptions) => {
    const el = inputRef.value
    if (!el)
      return
    el.multiple = toValue(options.multiple)!
    el.accept = toValue(options.accept)!
    // webkitdirectory key is not stabled, maybe replaced in the future.
    el.webkitdirectory = toValue(options.directory)!
    if (hasOwn(options, 'capture'))
      el.capture = toValue(options.capture)!
  }

open(localOptions: Partial<UseFileDialogOptions>): void

Parameters:

  • localOptions Partial<UseFileDialogOptions>

Returns: void

Calls:

  • applyOptions
  • toValue (from vue)
  • reset
  • el.click
Code
(localOptions?: Partial<UseFileDialogOptions>) => {
    const el = inputRef.value
    if (!el)
      return
    const mergedOptions = {
      ...DEFAULT_OPTIONS,
      ...options,
      ...localOptions,
    }
    applyOptions(mergedOptions)
    if (toValue(mergedOptions.reset))
      reset()
    el.click()
  }

Interfaces

UseFileDialogOptions

Interface Code
export interface UseFileDialogOptions extends ConfigurableDocument {
  /**
   * @default true
   */
  multiple?: MaybeRef<boolean>
  /**
   * @default '*'
   */
  accept?: MaybeRef<string>
  /**
   * Select the input source for the capture file.
   * @see [HTMLInputElement Capture](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/capture)
   */
  capture?: MaybeRef<string>
  /**
   * Reset when open file dialog.
   * @default false
   */
  reset?: MaybeRef<boolean>
  /**
   * Select directories instead of files.
   * @see [HTMLInputElement webkitdirectory](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)
   * @default false
   */
  directory?: MaybeRef<boolean>

  /**
   * Initial files to set.
   * @default null
   */
  initialFiles?: Array<File> | FileList

  /**
   * The input element to use for file dialog.
   * @default document.createElement('input')
   */
  input?: MaybeElementRef<HTMLInputElement>
}

Properties

Name Type Optional Description
multiple MaybeRef<boolean> not shown
accept MaybeRef<string> not shown
capture MaybeRef<string> not shown
reset MaybeRef<boolean> not shown
directory MaybeRef<boolean> not shown
initialFiles Array<File> \| FileList not shown
input MaybeElementRef<HTMLInputElement> not shown

UseFileDialogReturn

Interface Code
export interface UseFileDialogReturn {
  files: Ref<FileList | null>
  open: (localOptions?: Partial<UseFileDialogOptions>) => void
  reset: () => void
  onChange: EventHookOn<FileList | null>
  onCancel: EventHookOn
}

Properties

Name Type Optional Description
files Ref<FileList \| null> not shown
open (localOptions?: Partial<UseFileDialogOptions>) => void not shown
reset () => void not shown
onChange EventHookOn<FileList \| null> not shown
onCancel EventHookOn not shown

Generated by Syntax Scribe