Input
Displays a form input with a floating label, clean states and slots for leading or trailing icons.
Installation
npx alixan-ui-nuxt add input This command installs only the base Input component with built-in validation props.
Usage
The label moves when the input is focused or has a value. Use XControl for the value and validation state.
<script setup lang="ts">
import Input from '@/components/ui/input/Input.vue'
const control = useXControl('')
</script>
<template>
<Input :control="control" label="Name" />
</template>State
<script setup lang="ts">
import Input from '@/components/ui/input/Input.vue'
const readonlyControl = useXControl('readonly@example.com')
const disabledControl = useXControl('')
const errorControl = useXControl('')
</script>
<template>
<div class="grid w-full gap-3">
<Input :control="readonlyControl" label="Readonly" readonly />
<Input :control="disabledControl" label="Disabled" disabled />
<Input :control="errorControl" label="Required" error="Required field" />
</div>
</template>Validation
Parent invalid state: true
<script setup lang="ts">
import Button from '@/components/ui/button/Button.vue'
import Input from '@/components/ui/input/Input.vue'
const control = useXControl('')
const check = () => {
control.validate()
}
</script>
<template>
<Input :control="control" label="Username" required :min="3" :max="20" />
<Button @click="check">{{ $t('inputValidation.check') }}</Button>
<span>
{{ $t('inputValidation.parentInvalid') }}: {{ control.invalid }}
</span>
</template>Length
6-12 characters
<script setup lang="ts">
import Input from '@/components/ui/input/Input.vue'
const control = useXControl('')
</script>
<template>
<Input :control="control" label="Code" :min="6" :max="12" hint="6-12 characters" />
</template>With Icon
<script setup lang="ts">
import { Eye, EyeOff, Lock, Mail } from '@lucide/vue'
import EmailInput from '@/components/ui/input/EmailInput.vue'
import IconButton from '@/components/ui/icon-button/IconButton.vue'
import Input from '@/components/ui/input/Input.vue'
const emailControl = useXControl('')
const passwordControl = useXControl('')
const isPasswordVisible = ref(false)
</script>
<template>
<div class="grid w-full gap-3">
<EmailInput :control="emailControl">
<template #leading>
<Mail class="size-5" />
</template>
</EmailInput>
<Input
:control="passwordControl"
label="Password"
:type="isPasswordVisible ? 'text' : 'password'"
>
<template #leading>
<Lock class="size-5" />
</template>
<template #trailing>
<IconButton
variant="ghost"
color="default"
size="sm"
@click="isPasswordVisible = !isPasswordVisible"
>
<EyeOff v-if="isPasswordVisible" />
<Eye v-else />
</IconButton>
</template>
</Input>
</div>
</template>Variants
Install focused wrappers when you want a dedicated component for a specific input pattern.
Username Input
npx alixan-ui-nuxt add username-input<script setup lang="ts">
import UsernameInput from '@/components/ui/input/UsernameInput.vue'
const control = useXControl('')
</script>
<template>
<UsernameInput :control="control" />
</template>Email Input
npx alixan-ui-nuxt add email-input<script setup lang="ts">
import EmailInput from '@/components/ui/input/EmailInput.vue'
const control = useXControl('')
</script>
<template>
<EmailInput :control="control" required />
</template>Password Input
npx alixan-ui-nuxt add password-input<script setup lang="ts">
import PasswordInput from '@/components/ui/input/PasswordInput.vue'
const control = useXControl('')
</script>
<template>
<PasswordInput
:control="control"
required
:min="8"
:max="32"
/>
</template>Phone Input
npx alixan-ui-nuxt add phone-input Default country code is +7. The input keeps it as a prefix and applies ### ### ## ## to the number.
<script setup lang="ts">
import PhoneInput from '@/components/ui/input/PhoneInput.vue'
const control = useXControl('')
</script>
<template>
<PhoneInput
:control="control"
country-code="+7"
placeholder="777 777 77 77"
/>
</template>IIN
npx alixan-ui-nuxt add iin-input<script setup lang="ts">
import IinInput from '@/components/ui/input/IinInput.vue'
const control = useXControl('')
</script>
<template>
<IinInput :control="control" required />
</template>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| control | XControl<string | number | null> | - | Optional XControl that owns the value, validation state and form interaction markers. |
| id | string | - | Custom id. Generated automatically when omitted. |
| label | string | - | Floating label text. |
| type | 'text' | 'email' | 'password' | 'tel' | 'url' | 'number' | 'text' | Native input type. |
| placeholder | string | - | Native placeholder text. |
| autocomplete | 'on' | 'off' | - | Controls the native browser autocomplete behavior. |
| autofocus | boolean | false | Focuses the input on mount. |
| required | boolean | false | Shows a localized required message after blur when the value is empty. |
| min | number | - | Minimum text length validation shown after blur. |
| max | number | - | Maximum text length validation shown after blur. |
| pattern | string | - | Native pattern string. The value must match the whole pattern after blur. |
| patternMessage | string | 'validation.pattern' | Validation message shown when pattern does not match. |
| mask | string | - | Digit mask where # is a digit. |
| hint | string | - | Helper text shown below the input. |
| error | string | - | Error message. Also switches the input into destructive state. |
| disabled | boolean | false | Disables input interaction. |
| readonly | boolean | false | Makes the input readable but not editable. |
| hasClearButton | boolean | true | Shows a clear button when the input has a value and no trailing slot. |
XControl API
| Prop | Type | Default | Description |
|---|---|---|---|
| value | T | - | Current value owned by the control. |
| errors | Record<string, string> | {} | Current validation errors keyed by required, min, max, pattern or external. |
| valid / invalid | boolean | true / false | Derived validity markers based on the current errors. |
| touched / untouched | boolean | false / true | Tracks whether the user has left the field or validation was requested. |
| dirty / pristine | boolean | false / true | Tracks whether the value was changed through the field. |
| disabled / enabled | boolean | false / true | Derived enabled and disabled state used by Input. |
| setValue(value) | (value: T) => void | - | Updates the control value programmatically. |
| reset(value?) | (value?: T) => void | - | Resets the value, errors and interaction markers. |
| validate() | () => boolean | - | Marks the input as touched and returns whether it is valid. |
| hasError(key) | (key: string) => boolean | - | Checks whether a particular validation error is active. |
| disable() / enable() | () => void | - | Disables or enables the control and its Input. |