Skip to content

Commit

Permalink
feat(useFileDialog): new function (#1218)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
Co-authored-by: Jelf <353742991@qq.com>
  • Loading branch information
3 people committed Jul 6, 2022
1 parent 82510b8 commit 44526f0
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/contributors.json
Expand Up @@ -49,6 +49,7 @@
"danielroe",
"darrylnoakes",
"dblazhkun",
"dfreier",
"echoeureka",
"Flamenco",
"husayt",
Expand Down Expand Up @@ -115,7 +116,6 @@
"damienroche",
"danmindru",
"DesselBane",
"dfreier",
"eggsy",
"posva",
"Maiquu",
Expand Down
1 change: 1 addition & 0 deletions packages/core/index.ts
Expand Up @@ -45,6 +45,7 @@ export * from './useEventSource'
export * from './useEyeDropper'
export * from './useFavicon'
export * from './useFetch'
export * from './useFileDialog'
export * from './useFileSystemAccess'
export * from './useFocus'
export * from './useFocusWithin'
Expand Down
20 changes: 20 additions & 0 deletions packages/core/useFileDialog/demo.vue
@@ -0,0 +1,20 @@
<script setup lang="ts">
import { useFileDialog } from '.'
const { files, open, reset } = useFileDialog()
</script>

<template>
<button type="button" @click="open()">
Choose files
</button>
<button type="button" :disabled="!files" @click="reset()">
Reset
</button>
<template v-if="files">
<p>You have selected: <b>{{ files.length }} files</b></p>
<li v-for="file of files" :key="file.name">
{{ file.name }}
</li>
</template>
</template>
21 changes: 21 additions & 0 deletions packages/core/useFileDialog/index.md
@@ -0,0 +1,21 @@
---
category: Browser
---

# useFileDialog

Open file dialog with ease.

## Usage

```ts
import { useFileDialog } from '@vueuse/core'

const { files, open, reset } = useDialog()
```

```html
<template>
<button type="button" @click="open">Choose file</button>
</template>
```
65 changes: 65 additions & 0 deletions packages/core/useFileDialog/index.ts
@@ -0,0 +1,65 @@
import { readonly, ref } from 'vue-demi'

export interface UseFileDialogOptions {
/**
* @default true
*/
multiple?: boolean
/**
* @default '*'
*/
accept?: string
/**
* Select the input source for the capture file.
* @see [HTMLInputElement Capture](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/capture)
*/
capture?: string
}

const DEFAULT_OPTIONS: UseFileDialogOptions = {
multiple: true,
accept: '*',
}

/**
* Open file dialog with ease.
*
* @see https://vueuse.org/useFileDialog
* @param options
*/
export function useFileDialog(options?: Partial<UseFileDialogOptions>) {
const files = ref<FileList | null>(null)

const input = document.createElement('input')
input.type = 'file'

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

const open = (localOptions?: Partial<UseFileDialogOptions>) => {
const _options = {
...DEFAULT_OPTIONS,
...options,
...localOptions,
}
input.multiple = _options.multiple!
input.accept = _options.accept!
input.capture = _options.capture!

input.click()
}

const reset = () => {
files.value = null
}

return {
files: readonly(files),
open,
reset,
}
}

export type UseFileDialogReturn = ReturnType<typeof useFileDialog>

0 comments on commit 44526f0

Please sign in to comment.