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