Components

Input

Let users enter and edit a single line of text.

Import

import { Input } from "@dr-max/ui/input"

The entry carries its own precompiled CSS (including the styles of the Icon, Required and Spinner parts it composes) — no extra style imports needed.

Usage

Bind the value with v-model and always provide a label — a stable input ID is generated automatically:

<script setup lang="ts">
import { Input } from "@dr-max/ui/input"
import { ref } from "vue"

const email = ref("")
</script>

<template>
  <Input v-model="email" label="Email address" placeholder="[email protected]" />
</template>

Types

type accepts any native input type (text, email, number, password, …). Native number inputs intentionally emit strings for VInput compatibility:

<template>
  <Input v-model="email" type="email" label="Email address" />
  <Input v-model="quantity" type="number" label="Quantity" />
</template>

Required and optionality

required renders a visual required indicator, optionality-description describes an optional field beside its label, and additional-description adds supporting text below the field:

Only needed for business invoices.

<template>
  <Input v-model="street" label="Street and number" required />
  <Input
    v-model="company"
    label="Company"
    optionality-description="Optional"
    additional-description="Only needed for business invoices."
  />
</template>

Validation errors

errors renders validation messages below the input once touched marks the validation as active:

Enter a valid email address
<template>
  <Input
    v-model="email"
    label="Email address"
    touched
    :errors="[{ label: 'Enter a valid email address', param: 'email' }]"
  />
</template>

Keep errors-html off unless the error labels come from a trusted source — it renders them as raw HTML.

Warning

warning shows the warning state while no errors exist, with warning-message rendered below the field:

Did you mean gmail.com?
<template>
  <Input
    v-model="email"
    label="Email address"
    warning
    warning-message="Did you mean gmail.com?"
  />
</template>

Disabled and loading

loading shows a spinner and suppresses the validation state icons:

<template>
  <Input v-model="customerNumber" label="Customer number" disabled />
  <Input v-model="voucher" label="Voucher code" loading />
</template>

Password

type="password" renders a visibility toggle. Its accessible labels and the live-region announcements are configurable:

<template>
  <Input
    v-model="password"
    type="password"
    label="Password"
    show-password-label="Show password"
    hide-password-label="Hide password"
    password-visible-message="Password is visible"
    password-hidden-message="Password is hidden"
  />
</template>

Playground

<script setup lang="ts">
import { Input } from '@dr-max/ui/input'
</script>

<template>
  <Input label="Email address" placeholder="[email protected]" type="email" class="w-72" />
</template>
Dr. Max Design System • © 2026