You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.4 KiB
80 lines
1.4 KiB
<template>
|
|
<div class="flex gap-2 items-center">
|
|
<BaseButton
|
|
:label="label"
|
|
:size="size"
|
|
type="primary"
|
|
icon="attachment"
|
|
@click="showFileDialog"
|
|
/>
|
|
<p class="text-gray-90">
|
|
{{ fileName }}
|
|
</p>
|
|
</div>
|
|
<input
|
|
ref="inputFile"
|
|
type="file"
|
|
class="hidden"
|
|
:accept="acceptFileType"
|
|
>
|
|
</template>
|
|
|
|
<script setup>
|
|
import BaseButton from "./BaseButton.vue"
|
|
import {computed, onMounted, ref} from "vue";
|
|
import {sizeValidator} from "./validators";
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: [File, null],
|
|
required: true,
|
|
},
|
|
label: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
accept: {
|
|
type: String,
|
|
default: '',
|
|
validator: (value) => {
|
|
if (value === '') { return true }
|
|
return ['image'].includes(value);
|
|
},
|
|
},
|
|
size: {
|
|
type: String,
|
|
default: "normal",
|
|
validator: sizeValidator,
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits(['fileSelected'])
|
|
|
|
const inputFile = ref(null)
|
|
const fileName = ref('')
|
|
|
|
const acceptFileType = computed(() => {
|
|
switch (props.accept) {
|
|
case '':
|
|
return ''
|
|
case 'image':
|
|
return 'image/*'
|
|
default:
|
|
return ''
|
|
}
|
|
})
|
|
|
|
onMounted(() => {
|
|
inputFile.value.addEventListener("change", fileSelected);
|
|
})
|
|
|
|
const fileSelected = () => {
|
|
let file = inputFile.value.files[0];
|
|
fileName.value = file.name
|
|
emit('fileSelected', file)
|
|
}
|
|
|
|
const showFileDialog = () => {
|
|
inputFile.value.click()
|
|
}
|
|
</script>
|
|
|