Skip to content

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:

vue
<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.outer slot 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.outer slot 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 prepend slot 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 append slot 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.outer and append.outer slots 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 ​

NameTypeDefault
modelValue[String, Number]''
typeString'text'
nameString''
errorBooleanfalse
errorMessagesArray[]
readonlyBooleanfalse
disabledBooleanfalse
sizeString as PropType<'sm' | 'md' | 'lg'>'md'
placeholderString''
prependIconString''
appendIconString''
colorString'default'
textBooleanfalse
shadowBooleanfalse
roundedBooleanfalse
validationModeString'aggressive'
classesObject{}
labelString''
rules[Object, String]null
idString''
inputClassString''
wrapperClassString''
prependClassString''
prependIconClassString''
appendClassString''
appendIconClassString''
hintString''
hideErrorBooleanfalse

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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<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.

vue
<template>
  <VInput>
    <template #append>Append</template>
  </VInput>
</template>
<template>
  <VInput>
    <template #append>Append</template>
  </VInput>
</template>

CSS Variables ​

scss
: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:

bash
npm i @morpheme/forms
npm i @morpheme/forms
vue
<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.