Input
The VInput component is a form control for receiving user input. It can be used in various ways, such as a single line text input, a password input, or a search bar.
Usage
Basic Usage
To use the VInput component, simply add the component to your template:
INFO
The VInput component is registered globally when you install with @morpheme/ui. So you don't need to import it manually.
Placeholder
You can also provide a placeholder attribute to display a hint to the user:
<template>
<VInput placeholder="Enter your name" />
</template><template>
<VInput placeholder="Enter your name" />
</template>Colors
You can customize the color of the VInput component using the color prop. The available color options are: primary, secondary, info, warning, success, error, and dark.
Readonly
To make the VInput component readonly, set the readonly prop to true.
Disabled
To disable the VInput component, set the disabled prop to true.
Shadow
To add a shadow to the VInput component, set the shadow prop to true.
Rounded
To add a shadow to the VInput component, set the rounded prop to true.
Text
To use the VInput component as a text input, set the text prop to true and provide a model-value and label.
Error
To display an error message with the VInput component, set the error prop to true.
Icons
You can add icons to the VInput component using the prepend-icon and append-icon props.
To customize the icon classes, use the prepend-icon-class and append-icon-class props. To customize the wrapper element classes, use the prepend-class and append-class props.
Slots
You can use slots to insert custom content into the input field, such as icons, text, or buttons.
Prepend Slot (Outer Position)
The
prepend.outerslot allows you to insert content before the input field, outside of the input field's container. This can be useful for adding icons or buttons that are positioned on the left side of the input field.Append Slot (Outer Position)
The
prepend.outerslot allows you to insert content before the input field, outside of the input field's container. This can be useful for adding icons or buttons that are positioned on the left side of the input field.Prepend Slot (Inner Position)
The
prependslot allows you to insert content before the input field, inside of the input field's container. This can be useful for adding icons or text that are positioned on the left side of the input field and are aligned with the input text.Append Slot (Inner Position)
The
appendslot allows you to insert content after the input field, inside of the input field's container. This can be useful for adding icons or text that are positioned on the right side of the input field and are aligned with the input text.Button or Text Slots
You can use the
prepend.outerandappend.outerslots to insert button or text content on either side of the input field.
Validation
To use the VInput component with a form validation library, you can use the name prop to bind the component to a form control. For example, with VeeValidate, you can use the useForm hook to create a form with validation schema:
Validation Mode
There are 2 modes. The first is eager mode, and the second is aggressive mode. The eager mode validates input when the blur event occurs. Meanwhile, aggressive mode validates the input every time the input itself changes. This can be useful when you are validating for example the minimum or maximum limits of an input.
You can change the default value for this validation mode by adding an attribute or property named validation-mode to this component.
Field Array
Here is example of using VInput as field array with vee-validate.
Field Array of Objects
Here is example of using VInput as field array of object with vee-validate.
Field Array Nested
Here is example of using VInput as nested field array with vee-validate.
Props
| Name | Type | Default |
|---|---|---|
modelValue | [String, Number] | '' |
type | String | 'text' |
name | String | '' |
error | Boolean | false |
errorMessages | Array | [] |
readonly | Boolean | false |
disabled | Boolean | false |
size | String as PropType<'sm' | 'md' | 'lg'> | 'md' |
placeholder | String | '' |
prependIcon | String | '' |
appendIcon | String | '' |
color | String | 'default' |
text | Boolean | false |
shadow | Boolean | false |
rounded | Boolean | false |
validationMode | String | 'aggressive' |
classes | Object | {} |
label | String | '' |
rules | [Object, String] | null |
id | String | '' |
inputClass | String | '' |
wrapperClass | String | '' |
prependClass | String | '' |
prependIconClass | String | '' |
appendClass | String | '' |
appendIconClass | String | '' |
hint | String | '' |
hideError | Boolean | false |
Events
Emitted when the value of the v-model directive changes. Can be used to perform an action when the value changes, such as updating other data or displaying a message to the user.
<script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @update:modelValue="handle" />
</template><script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @update:modelValue="handle" />
</template>Triggered when the element with the prepend slot is clicked.
<script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-prepend="handle" />
</template><script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-prepend="handle" />
</template>Triggered when the element with the prepend-icon slot is clicked.
<script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-prepend-icon="handle" />
</template><script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-prepend-icon="handle" />
</template>Triggered when the element with the append slot is clicked.
<script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-append="handle" />
</template><script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-append="handle" />
</template>Triggered when the element with the append-icon slot is clicked.
<script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-append-icon="handle" />
</template><script setup lang="ts">
const handle = () => alert('Triggered!');
</script>
<template>
<VInput @click-append-icon="handle" />
</template>Slots
Allows you to customize the label of the input element.
<template>
<VInput>
<template #label>My Label</template>
</VInput>
</template><template>
<VInput>
<template #label>My Label</template>
</VInput>
</template>Allows you to customize the outer element of the prepend slot.
<template>
<VInput>
<template #prepend.outer>Prepend Outer</template>
</VInput>
</template><template>
<VInput>
<template #prepend.outer>Prepend Outer</template>
</VInput>
</template>Allows you to customize the prepend slot.
<template>
<VInput>
<template #prepend>Prepend</template>
</VInput>
</template><template>
<VInput>
<template #prepend>Prepend</template>
</VInput>
</template>Allows you to customize the outer element of the append slot.
<template>
<VInput>
<template #append.outer>Append Outer</template>
</VInput>
</template><template>
<VInput>
<template #append.outer>Append Outer</template>
</VInput>
</template>Allows you to customize the append slot.
<template>
<VInput>
<template #append>Append</template>
</VInput>
</template><template>
<VInput>
<template #append>Append</template>
</VInput>
</template>CSS Variables
:root {
/* input control */
--v-input-height: 44px;
--v-input-border-color: var(--color-gray-300);
--v-input-placeholder-color: var(--color-gray-500);
--v-input-border-radius: var(--border-radius-lg);
--v-input-padding-x: var(--size-spacing-3);
--v-input-padding-y: var(--size-spacing-3);
--v-input-font-size: var(--size-font-sm);
--v-input-line-height: 20px;
--v-input-bg-color: var(--color-white);
--v-input-color: var(--color-gray-700);
/* label */
--v-input-label-font-size: var(--size-font-sm);
--v-input-label-font-weight: var(--font-weight-semibold);
--v-input-label-display: block;
--v-input-label-margin-bottom: var(--size-spacing-1);
/* text */
--v-input-text-color: var(--color-gray-700);
--v-input-text-font-size: var(--size-font-sm);
--v-input-text-font-weight: var(--font-weight-regular);
/* icon */
--v-input-icon-width: var(--size-spacing-5);
--v-input-icon-height: var(--size-spacing-5);
--v-input-icon-color: var(--color-gray-500);
// disabled
--v-input-disabled-bg-color: var(--color-gray-50);
--v-input-disabled-color: var(--color-gray-500);
--v-input-disabled-border-color: var(--color-gray-300);
--v-input-disabled-placeholder-color: var(--color-gray-500);
--v-input-disabled-icon-color: var(--color-gray-500);
// hint
--v-input-hint-font-size: var(--size-font-sm);
--v-input-hint-color: var(--color-gray-600);
--v-input-hint-margin-top: var(--size-spacing-1);
// focus effect
--v-input-effect-border-color: var(--color-primary-300);
--v-input-effect-shadow-color: var(--color-primary-100);
// shadow
--v-input-shadow: var(--effect-shadow-xs);
}:root {
/* input control */
--v-input-height: 44px;
--v-input-border-color: var(--color-gray-300);
--v-input-placeholder-color: var(--color-gray-500);
--v-input-border-radius: var(--border-radius-lg);
--v-input-padding-x: var(--size-spacing-3);
--v-input-padding-y: var(--size-spacing-3);
--v-input-font-size: var(--size-font-sm);
--v-input-line-height: 20px;
--v-input-bg-color: var(--color-white);
--v-input-color: var(--color-gray-700);
/* label */
--v-input-label-font-size: var(--size-font-sm);
--v-input-label-font-weight: var(--font-weight-semibold);
--v-input-label-display: block;
--v-input-label-margin-bottom: var(--size-spacing-1);
/* text */
--v-input-text-color: var(--color-gray-700);
--v-input-text-font-size: var(--size-font-sm);
--v-input-text-font-weight: var(--font-weight-regular);
/* icon */
--v-input-icon-width: var(--size-spacing-5);
--v-input-icon-height: var(--size-spacing-5);
--v-input-icon-color: var(--color-gray-500);
// disabled
--v-input-disabled-bg-color: var(--color-gray-50);
--v-input-disabled-color: var(--color-gray-500);
--v-input-disabled-border-color: var(--color-gray-300);
--v-input-disabled-placeholder-color: var(--color-gray-500);
--v-input-disabled-icon-color: var(--color-gray-500);
// hint
--v-input-hint-font-size: var(--size-font-sm);
--v-input-hint-color: var(--color-gray-600);
--v-input-hint-margin-top: var(--size-spacing-1);
// focus effect
--v-input-effect-border-color: var(--color-primary-300);
--v-input-effect-shadow-color: var(--color-primary-100);
// shadow
--v-input-shadow: var(--effect-shadow-xs);
}Standalone Installation
You can also install the VInput component individually via @morpheme/forms package:
npm i @morpheme/formsnpm i @morpheme/forms<script setup lang="ts">
import {VInput} from '@morpheme/forms';
</script>
<template>
<VInput />
</template><script setup lang="ts">
import {VInput} from '@morpheme/forms';
</script>
<template>
<VInput />
</template>Storybook
View Storybook documentation here.
Morpheme