QInput component
QInput is kept as simple as possible to allow for a variety of use cases. It defaults to 100%
width and uses some basic aria attributes, including error handling.
HTML input types
An extensive list of HTML5 input elements can be found at the end of this page
Requirements
Type | Path / Version | Purpose | Optional |
---|---|---|---|
Styles | ../../assets/main.css | CSS Variables | No |
Functions | ../../use/uuid | Assign ids to items | No |
Usage
Import the following component/s:
import QInput from '../../components/Form/QInput.vue'
Basic use case
You can use v-model
& label
bindings on the component. The placeholder defaults to the label
Example
<template>
<q-input label="Name" v-model="inputValue" />
<p>Output: {{inputValue}}</p>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
</script>
Placeholder prefix
In case the label alone is not enough, you can extend it with a prefix. Doing so makes the placeholder become lower case
Example
<template>
<q-input labelPrefix="Type in your " label="Name" v-model="inputValue" />
<p>Output: {{inputValue}}</p>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
</script>
Required fields
Adding required
as an attribute also adds a requiredSign
. You can optionally customize its content.
Default ( * )
Custom sign ( required )
Example
<template>
<form @submit.prevent="onSubmit">
<q-input labelPrefix="Type in your " required requiredSign="(required)" label="Name" v-model="inputValue" />
<p>Output: {{inputValue}}</p>
</form>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
const onSubmit = () => alert(`Your input: ${inputValue.value}`);
</script>
Suggestions (datalist)
Example
<template>
<form @submit.prevent="onSubmit">
<q-input labelPrefix="Type in your " required requiredSign="(required)" label="Name" v-model="inputValue" />
<p>Output: {{inputValue}}</p>
</form>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
const inputOptions = [
'John Doe',
'Eric Sutherland',
'Jane Doenym',
];
const onSubmit = () => alert(`Your input: ${inputValue.value}`);
</script>
Error handling
Errors are rendered right below the input element. The form below will toggle errors when submitted to give you an idea of how they look like
Example
<template>
<form @submit.prevent="onError">
<q-input :error="inputError" labelPrefix="Type in your " label="Name" v-model="inputValue" />
<p>Erorr: {{inputError}}</p>
</form>
</template>
<script setup>
import { ref } from 'vue';
const inputError = ref('');
const onError = () => (inputError.value = inputError.value === "" ? "An error has occured" : "");
</script>
Full component's code
QInput
<template>
<label v-if="label" :for="id" class="q-input-label">
{{ label }}
<span class="q-input-required-sign" v-if="required">{{ requiredSign }}</span>
</label>
<input
:list="options ? `${id}-options` : null"
class="q-input-base"
:class="{
'q-error': !!error,
}"
v-bind="$attrs"
@input="$emit('update:modelValue', $event.target.value)"
:value="modelValue"
:id="id"
:required="required"
:placeholder="labelPrefix ? labelPrefix + label.toLowerCase() : label"
:aria-label="label"
:aria-required="required"
:aria-describedby="error ? `${id}-error` : null"
:aria-invalid="error ? true : null"
/>
<datalist :id="`${id}-options`">
<option v-for="option in options" :value="option.value ? option.value : option" :key="option"></option>
</datalist>
<small
v-if="error"
class="q-input-error-msg"
:id="`${id}-error`"
aria-live="assertive"
>{{ error }}</small>
</template>
<script setup>
import uuid from "../../use/uuid";
const id = uuid();
defineProps({
labelPrefix: {
type: String,
default: null,
},
label: {
type: String,
},
options: {
type: Array,
},
modelValue: {
type: [String, Number],
},
error: {
type: String,
},
required: {
type: Boolean,
default: false,
},
requiredSign: {
type: String,
default: "*",
},
})
</script>
<style scoped>
datalist {
width: 100%;
background-color: var(--background-color-primary);
color: var(--text-color-primary);
}
.q-input-base,
.q-input-label {
display: block;
width: 100%;
font-size: var(--text-size-sm);
}
.q-input-label {
color: var(--accent-color-primary);
font-size: var(--text-size-sm);
font-weight: 600;
}
.q-input-required-sign {
color: var(--color-error);
}
.q-input-base {
background-color: transparent;
color: var(--text-color-primary);
caret-color: var(--text-color-primary);
border: none;
border-bottom: var(--gap-xxs) solid transparent;
padding: var(--gap-sm) var(--gap-xs);
margin: var(--gap-sm) 0;
}
.q-input-base:focus {
outline: none;
transition: var(--duration-quickest);
border-bottom: var(--gap-xxs) solid var(--accent-color-primary);
}
.q-input-base:focus.q-error {
border-bottom: var(--gap-xxs) solid var(--color-error);
}
.q-input-error-msg {
font-size: var(--text-xs);
color: var(--color-error);
}
</style>
List of input types
Source: W3schools
TODO: Add a list element here