Skip to content

Input ​

Text input with shadcn/ui styling. Supports mask, debounce, formatter, textarea, number stepper, search, and more.

vue
<template>
  <VxInput v-model="value" placeholder="Type something..." />
</template>

Sizes ​

vue
<template>
  <VxInput size="sm" />
  <VxInput />
  <VxInput size="lg" />
</template>

Clearable ​

vue
<template>
  <VxInput v-model="value" clearable />
</template>

Password ​

vue
<template>
  <VxInput type="password" placeholder="Enter password..." />
</template>

Prefix & Suffix ​

vue
<template>
  <VxInput placeholder="Search...">
    <template #prefix><SearchIcon /></template>
  </VxInput>
</template>

Mask ​

# = digit, A = letter, * = any character. Separators auto-insert.

Phone: ###-###-####
Card: #### #### #### ####
vue
<template>
  <VxInput mask="###-###-####" placeholder="Phone" />
  <VxInput mask="#### #### #### ####" placeholder="Card" />
</template>

Mask with Unmasked Value ​

v-model returns the masked value (e.g. +1 (234) 567-89-01). Use v-model:unmasked-value to get the raw digits only.

Phone: +# (###) ###-##-##
v-model (masked): –
unmasked-value: –
Credit Card: #### #### #### ####
v-model (masked): –
unmasked-value: –
vue
<script setup>
const phone = ref('')
const phoneRaw = ref('')
// phone will be "+1 (234) 567-89-01" (masked)
// phoneRaw will be "12345678901" (unmasked)
</script>

<template>
  <VxInput v-model="phone" v-model:unmasked-value="phoneRaw" mask="+# (###) ###-##-##" />
</template>

Debounce ​

Delays v-model update. @input still fires immediately.

Debounced: –
vue
<template>
  <VxInput v-model="value" :debounce="500" />
</template>

Trim ​

Auto-trims whitespace on blur.

""
vue
<template>
  <VxInput v-model="value" trim />
</template>

Lazy ​

Updates v-model on blur, not on every keystroke.

v-model: –
vue
<template>
  <VxInput v-model="value" lazy />
</template>

Autofocus ​

vue
<template>
  <VxInput autofocus />
</template>

Loading ​

vue
<template>
  <VxInput v-model="value" loading />
</template>

Formatter / Parser ​

Display formatted value, store raw value. Formatter runs on blur, parser on input.

Raw: 1234567 (number)
vue
<script setup>
function formatter(v) { return Number(v).toLocaleString('en-US') }
function parser(v) { return v.replace(/,/g, '') }
</script>

<template>
  <VxInput v-model="value" :formatter="formatter" :parser="parser" />
</template>

Textarea ​

vue
<template>
  <VxInput v-model="value" type="textarea" :rows="4" />
</template>

Autosize Textarea ​

vue
<template>
  <VxInput type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" />
</template>

Number ​

With stepper buttons and arrow key support.

Basic
0
Min: 0, Max: 10, Step: 2
5
Precision: 2
1.5
vue
<template>
  <VxInput v-model="value" type="number" />
  <VxInput v-model="value" type="number" :min="0" :max="10" :step="2" />
  <VxInput v-model="value" type="number" :step="0.25" :precision="2" />
</template>

Regex ​

Restrict input to characters matching a regex pattern. Non-matching characters are stripped in real-time.

Numbers only (/[0-9]/)
Letters only (/[a-zA-Z]/)
Alphanumeric (/[a-zA-Z0-9]/)
vue
<template>
  <!-- Numbers only -->
  <VxInput v-model="value" :regex="/[0-9]/" />

  <!-- Letters only -->
  <VxInput v-model="value" :regex="/[a-zA-Z]/" />

  <!-- Alphanumeric -->
  <VxInput v-model="value" :regex="/[a-zA-Z0-9]/" />
</template>

Built-in search icon. Emits @search on Enter.

vue
<template>
  <VxInput type="search" placeholder="Search..." @search="onSearch" clearable />
</template>

Word Limit ​

0 / 50
vue
<template>
  <VxInput :maxlength="50" show-word-limit />
</template>

Floating Label ​

When floating-label is enabled, the placeholder animates to the top border on focus or when the input has a value.

vue
<template>
  <VxInput v-model="val" placeholder="Username" floating-label />
  <VxInput v-model="email" placeholder="Email" floating-label type="email" />
  <VxInput v-model="pass" placeholder="Password" floating-label type="password" />
</template>

Disabled & Readonly ​

vue
<template>
  <VxInput disabled />
  <VxInput readonly />
</template>

Props ​

PropTypeDefaultDescription
modelValuestring | number''Value (v-model)
placeholderstring''Placeholder
type'text' | 'password' | 'email' | 'number' | 'search' | 'tel' | 'url' | 'textarea''text'Input type
size'sm' | 'default' | 'lg''default'Size
disabledbooleanfalseDisable
readonlybooleanfalseRead only
clearablebooleanfalseClear button
debouncenumber0Debounce v-model update (ms)
maskstring''Input mask (#=digit, A=letter, *=any)
unmaskedValuestring—Raw value without mask chars (v-model:unmasked-value)
trimbooleanfalseTrim whitespace on blur
lazybooleanfalseUpdate v-model on blur only
autofocusbooleanfalseFocus on mount
loadingbooleanfalseShow loading spinner
formatter(v: string) => string—Format display value (on blur)
parser(v: string) => string—Parse value before emit
maxlengthnumber—Max characters
showWordLimitbooleanfalseShow character count
rowsnumber3Textarea rows
autosizeboolean | { minRows, maxRows }falseAuto-grow textarea
minnumber—Min value (number type)
maxnumber—Max value (number type)
stepnumber1Step increment (number type)
precisionnumber—Decimal places (number type)
regexRegExp—Allow only characters matching the regex
inputClassstring | string[] | Record''Custom wrapper class
inputStyleRecord<string, string>—Custom wrapper style
floatingLabelbooleanfalseAnimate placeholder to top border on focus

Events ​

EventTypeDescription
update:modelValue(v: string | number)Value changed
input(v: string | number)On every keystroke
change(v: string | number)On blur/enter
focus(e: FocusEvent)Focused
blur(e: FocusEvent)Blurred
clear()Cleared
search(v: string)Enter pressed (search type)

Slots ​

SlotDescription
prefixBefore input (auto search icon for type="search")
suffixAfter input