File Input v1.0
The <e-file-input> component is a component that can be used for .
Usage
An e-file-input has attributes that must be provided,
<e-file-input
id=""
icon=""
label=""
checked=""
inherit=""
/>
Attributes
| Value | Type | Optional | Default |
|---|---|---|---|
| id | String | no | |
| icon | String | yes | 'upload' |
| label | String | yes | '' |
| accept | String | yes | '' |
| required | Boolean | yes | false |
Examples
Below a few interactive examples of e-file-input can be found.
Default
<e-file-input
id="fileInput"
:label="'fileInput'"
/>
Labelled, label='fileInput with Label'
<div class="input-example-field">
<e-input-label
:id="'fileInputWithLabel'"
:value="'fileInput with Label'"
/>
<e-file-input
:id="'fileInputWithOptions'"
:label="'fileInputWithOptions'"
/>
</div>
Source Code
e-file-input.vue
<script setup lang="ts">
import { ref } from 'vue';
import EIcon from '../e-icon/e-icon.vue';
export type Props = {
id: string;
icon?: string;
label?: string;
accept?: string;
required?: boolean;
};
withDefaults(defineProps<Props>(), {
icon: 'upload',
label: '',
accept: '',
required: false
});
const emit = defineEmits<{
(e: 'blur', event: FocusEvent): void;
(e: 'keyup.enter', event: KeyboardEvent): void;
(e: 'update:value', value: string): void;
}>();
const input = ref<HTMLInputElement>();
function emitUpdate(event: Event): void {
const target = event.target as HTMLInputElement;
if (target.files && target.files[0]) {
emit('update:value', target.files[0]);
} else {
emit('update:value', null);
}
}
const timer = ref<NodeJS.Timeout>();
function debounceEmit(event: Event, msDelay: number = 500): void {
clearTimeout(timer.value);
timer.value = setTimeout(() => {
emitUpdate(event);
}, msDelay);
}
</script>
<template>
<label
class="e-file-input"
:for="id"
>
<e-icon :icon="[icon]" />
<span v-text="label" />
</label>
<input
:id="id"
ref="input"
type="file"
:name="id"
:accept="accept"
:required="required"
@input="debounceEmit($event, 500)"
@blur="emit('blur', $event)"
@keyup.enter="emit('keyup.enter', $event)"
/>
</template>
<style scoped lang="scss">
input[type='file'] {
display: none;
}
.e-file-input {
background-color: var(--e-input-background);
border: none;
border-radius: 15px;
padding: 14px;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
cursor: pointer;
.e-icon {
max-width: 24px;
}
span {
color: var(--e-text-input-font-color);
font-family: var(--e-text-input-font-family);
font-size: var(--e-text-input-font-size);
font-weight: var(--e-text-input-font-weight);
line-height: var(--e-text-input-font-line-height);
}
&[required] {
+ label::after {
content: '*';
padding-left: 2px;
color: var(--e-required);
font-weight: bold;
}
}
}
</style>