Localizated Input
LocalizatedInput renders one text input for each language and keeps their values in a single object. It is useful for translated fields such as product names, titles, descriptions, or SEO metadata.
Usage
<template>
<LocalizatedInput
v-model="translations"
:languages="languages"
placeholder="Enter a translation"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { LocalizatedInput } from '@/Components/LocalizatedInput'
const translations = ref<Record<string, string | undefined>>({
en: 'Component library',
sk: 'Knižnica komponentov',
})
const languages = [
{ code: 'en', label: 'EN', placeholder: 'English title' },
{ code: 'sk', label: 'SK', placeholder: 'Slovak title' },
]
</script>When a user edits an input, the component emits a new value object with the changed language code. Existing values for other languages are preserved.
Languages
The required languages prop accepts language codes as strings or language objects.
const languages = [
'en',
{
code: 'sk',
label: 'Slovenčina',
placeholder: 'Zadajte slovenský preklad',
},
]String entries use the code as their label in uppercase ('en' becomes EN). Object entries can override the displayed label and placeholder. A language-specific placeholder takes precedence over the component-level placeholder prop.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | Record<string, string | undefined> | {} | Translation values keyed by language code. Use with v-model. |
languages | Array<string | { code: string; label?: string; placeholder?: string }> | — | Languages and optional display configuration. Required. |
placeholder | string | 'Write a translation...' | Placeholder used when a language does not provide its own. |
type | InputHTMLAttributes['type'] | 'text' | Native input type applied to every language input. |
disabled | boolean | false | Disables every language input. |
invalid | boolean | false | Applies the error border and focus style, and sets aria-invalid on the inputs. |
class | HTMLAttributes['class'] | — | Additional classes for the component's outer container. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | Record<string, string | undefined> | Emitted whenever the value of one language changes. |
Examples
Simple language codes
<LocalizatedInput
v-model="title"
:languages="['en', 'sk', 'de']"
/>Validation state
Set invalid when the translated field has a validation error. The component will show an error border and expose the state to assistive technology.
<LocalizatedInput
v-model="title"
:languages="['en', 'sk']"
:invalid="Boolean(errors.title)"
/>Disabled state
<LocalizatedInput
v-model="title"
:languages="['en', 'sk']"
disabled
/>Programmatic focus
Use a template ref to focus a particular language input. The exposed focus method accepts a language code.
<template>
<button type="button" @click="localizatedInput?.focus('sk')">
Edit Slovak translation
</button>
<LocalizatedInput
ref="localizatedInput"
v-model="title"
:languages="['en', 'sk']"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { LocalizatedInput } from '@/Components/LocalizatedInput'
const title = ref<Record<string, string | undefined>>({})
const localizatedInput = ref<InstanceType<typeof LocalizatedInput> | null>(null)
</script>