Skip to content

Commit

Permalink
feat(VFileUpload): add new component (#19667)
Browse files Browse the repository at this point in the history
Co-authored-by: MajesticPotatoe <[email protected]>
  • Loading branch information
johnleider and MajesticPotatoe authored Dec 11, 2024
1 parent 56fcb86 commit 89c58dd
Show file tree
Hide file tree
Showing 58 changed files with 996 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/docs/src/data/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@
"title": "date-inputs",
"subfolder": "components"
},
{
"title": "file-upload",
"subfolder": "components"
},
{
"title": "number-inputs",
"subfolder": "components"
Expand Down
8 changes: 8 additions & 0 deletions packages/docs/src/examples/v-file-upload/prop-content.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<v-file-upload
browse-text="Local Filesystem"
divider-text="or choose locally"
icon="mdi-upload"
title="Drag and Drop Here"
></v-file-upload>
</template>
19 changes: 19 additions & 0 deletions packages/docs/src/examples/v-file-upload/prop-density.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div class="text-center pa-2 mb-2">
<v-btn-toggle v-model="density" density="comfortable" border divided rounded>
<v-btn value="default">Default</v-btn>

<v-btn value="comfortable">Comfortable</v-btn>

<v-btn value="compact">Compact</v-btn>
</v-btn-toggle>
</div>

<v-file-upload :density="density"></v-file-upload>
</template>

<script setup>
import { shallowRef } from 'vue'
const density = shallowRef('default')
</script>
3 changes: 3 additions & 0 deletions packages/docs/src/examples/v-file-upload/prop-disabled.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<v-file-upload disabled></v-file-upload>
</template>
3 changes: 3 additions & 0 deletions packages/docs/src/examples/v-file-upload/prop-scrim.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<v-file-upload scrim="primary"></v-file-upload>
</template>
26 changes: 26 additions & 0 deletions packages/docs/src/examples/v-file-upload/slot-item.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<v-file-upload
v-model="model"
clearable
multiple
show-size
>
<template v-slot:item="{ props: itemProps }">
<v-file-upload-item v-bind="itemProps" lines="one" nav>
<template v-slot:prepend>
<v-avatar size="32" rounded></v-avatar>
</template>

<template v-slot:clear="{ props: clearProps }">
<v-btn color="primary" v-bind="clearProps"></v-btn>
</template>
</v-file-upload-item>
</template>
</v-file-upload>
</template>

<script setup>
import { shallowRef } from 'vue'
const model = shallowRef(null)
</script>
48 changes: 48 additions & 0 deletions packages/docs/src/examples/v-file-upload/usage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<ExamplesUsageExample
v-model="model"
:code="code"
:name="name"
:options="options"
>
<div>
<v-file-upload v-bind="props"></v-file-upload>
</div>

<template v-slot:configuration>
<v-text-field v-model="title" label="Title"></v-text-field>

<v-checkbox v-model="disabled" label="Disabled"></v-checkbox>

<v-checkbox v-model="clear" label="Clearable"></v-checkbox>
</template>
</ExamplesUsageExample>
</template>

<script setup>
const name = 'v-file-upload'
const model = ref('default')
const options = ['comfortable', 'compact']
const clear = ref(false)
const counter = ref(false)
const disabled = ref(false)
const title = ref()
const props = computed(() => {
return {
clearable: clear.value || undefined,
counter: counter.value || undefined,
disabled: disabled.value || undefined,
density: model.value,
title: title.value || undefined,
variant: model.value === 'default' ? undefined : model.value,
}
})
const slots = computed(() => {
return ``
})
const code = computed(() => {
return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`
})
</script>
99 changes: 99 additions & 0 deletions packages/docs/src/pages/en/components/file-upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
emphasized: true
meta:
title: File upload
description: The file upload component is a drag and drop area for uploading files.
keywords: file uploading, file upload, file drag and drop, file drop area, file dropzone, file upload component
related:
- /components/buttons/
- /components/file-inputs/
- /components/sheets/
features:
report: true
label: 'C: VFileUpload'
github: '/labs/VFileUpload/'
---

# File upload

<PageFeatures />

::: warning

This feature requires [v3.7.3](/getting-started/release-notes/?version=v3.7.3)

:::

## Installation

Labs components require a manual import and installation of the component.

```js { resource="src/plugins/vuetify.js" }
import { VFileUpload } from 'vuetify/labs/VFileUpload'

export default createVuetify({
components: {
VFileUpload,
},
})
```

## Usage

The `v-file-upload` component is a drag and drop area for uploading files. It can be customized with slots and has support for density and multiple styles.

<ExamplesUsage name="v-file-upload" />

<PromotedEntry />

## API

| Component | Description |
| - | - |
| [v-file-upload](/api/v-file-upload/) | Primary Component |
| [v-file-upload-item](/api/v-file-upload-item/) | Item Component |
| [v-file-input](/api/v-file-input/) | File input component |

<ApiInline hide-links />

## Guide

The v-file-upload component is a more visual counterpart to the [v-file-input](/components/file-inputs/) component. It provides a drag and drop area for files, and can be customized with slots.

### Props

Utilize various properties to customize the look and feel of the `v-file-upload` component.

#### Density

The **density** prop is used to control the vertical space the upload takes up.

<ExamplesExample file="v-file-upload/prop-density" />

#### Content

Use the **browse-text**, **divider-text**, **icon**, **title**, or **subtitle** props to customize the text displayed in the component.

<ExamplesExample file="v-file-upload/prop-content" />

#### Disabled

The **disabled** property reduces the opacity of the component and prevents interaction.

<ExamplesExample file="v-file-upload/prop-disabled" />

#### Scrim

The **scrim** property allows you to set a colored scrim when hovering over the component with files.

<ExamplesExample file="v-file-upload/prop-scrim" />

### Slots

The `v-file-upload` component has several slots that can be used to customize the component.

#### Item

The **item** slot is used to customize the appearance of the file item.

<ExamplesExample file="v-file-upload/slot-item" />
1 change: 1 addition & 0 deletions packages/vuetify/src/iconsets/mdi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const aliases: IconAliases = {
treeviewCollapse: 'mdi-menu-down',
treeviewExpand: 'mdi-menu-right',
eyeDropper: 'mdi-eyedropper',
upload: 'mdi-cloud-upload',
}

const mdi: IconSet = {
Expand Down
75 changes: 75 additions & 0 deletions packages/vuetify/src/labs/VFileUpload/VFileUpload.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
@use '../../styles/tools'
@use '../../styles/settings'
@use './variables' as *

@include tools.layer('components')
.v-file-upload
padding: $file-upload-padding
flex-direction: column
justify-content: center
align-items: center
position: relative

&.v-sheet
display: flex
border-radius: 4px
border-style: dashed
border-width: 2px

&.v-file-upload--density-compact
padding: 32px 0
flex-direction: row
gap: 1rem

.v-overlay__scrim
pointer-events: none

&--disabled
pointer-events: none
opacity: var(--v-disabled-opacity)

&--dragging
> *
pointer-events: none

&--clickable
cursor: pointer

input[type="file"]
left: 0
opacity: 0
position: absolute
cursor: pointer
top: 0
z-index: -1

.v-file-upload-title
font-size: $file-upload-title-font-size
font-weight: 600

.v-file-upload-icon
opacity: var(--v-medium-emphasis-opacity)
font-size: $file-upload-icon-font-size
margin-bottom: $file-upload-icon-margin-bottom

.v-file-upload--density-comfortable &
font-size: $file-upload-icon-font-size - .5rem
margin-bottom: $file-upload-icon-margin-bottom - .5rem

.v-file-upload--density-compact &
font-size: $file-upload-icon-font-size - 1rem
margin-bottom: $file-upload-icon-margin-bottom - 1rem

.v-file-upload-divider
align-items: center
display: flex
margin: $file-upload-divider-margin
justify-content: center
width: 100%

.v-file-upload-items
margin: $file-upload-items-margin

.v-file-upload-item
&:not(:first-child)
margin-top: 8px
Loading

0 comments on commit 89c58dd

Please sign in to comment.