@tvaliasek/vue-form-inputs

Wrapper components over the most commonly used bootstrap input components with support for vuelidate, vue i18n and vue 3 datepicker. Originally based on bootstrap-vue-next components, but since version 4 without this dependency.
3,922
Install
npm install @tvaliasek/vue-form-inputs
Latest Version:5.2.4
Vue:3
Older releases:2
License:MIT
Last Updated:May 6, 2026
Links: npm
Maintainer: tvaliasek

Customized bootstrap vue form inputs for BS 5 and Vue 3

Wrapper components over the most commonly used bootstrap input components with support for vuelidate, vue i18n and vue 3 datepicker. Originally based on bootstrap-vue-next components, but since version 4 without this dependency.

Main goal is to simplify common bootstrap form design in my own projects.

Install

npm install @tvaliasek/vue-form-inputs

# peer dependencies
npm install bootstrap
# for datepicker
npm install @vuepic/vue-datepicker
import { createApp } from 'vue'
import { FormInputsPlugin } from '@tvaliasek/vue-form-inputs'
import '@tvaliasek/vue-form-inputs/dist/vue-form-inputs.css'
import 'bootstrap/dist/css/bootstrap.css'

const app = createApp(App)
app.use(FormInputsPlugin())

Or import only what you need:

<script setup lang="ts">
import { FormInput, FormInputSelect } from '@tvaliasek/vue-form-inputs'
</script>

Components overview

Component Purpose v-model type
FormInput Text inputs (text, email, number, etc.) `string
FormInputTextarea Multi-line text string
FormInputSelect Single or multi select `string
FormInputRadioGroup Radio buttons `string
FormInputCheckbox Single checkbox / switch boolean
FormInputCheckboxGroup Multiple checkboxes / switches `Array<string
FormInputDatePicker Date / date-time picker (@vuepic/vue-datepicker) Date
FormInputDatePickerAlt Alternate simplified date picker Date
FormInputFile File input (single/multiple) with filtering `File

All components unify validation state, label composition and feedback rendering.

Events

Event Meaning Payload
update:modelValue v-model update new value
change User commits a change current value
update Intermediate update while typing (where applicable) current value
blur Input loses focus current value

FormInputFile emits update:modelValue, change, blur.

Slots

Slot Components Description
label all Override entire label contents
label-prepend all Insert before label text
label-text all Replace only text portion
label-append all Insert after label text
invalid-feedback all Override validation feedback node (normally auto)
input-text all Extra help text under input (besides hint)
prepend inputs with renderAsGroup (text, select, file) Input group prepend
append inputs with renderAsGroup (text, select, file) Input group append
default (checkbox when slot used) checkbox Custom label content for single checkbox

Input group example:

<FormInput v-model="amount" type="number" label="Amount" :renderAsGroup="true">
    <template #prepend><span class="input-group-text">€</span></template>
    <template #append><button class="btn btn-outline-secondary" @click="amount=0">Reset</button></template>
</FormInput>

Custom composed label example:

<FormInput v-model="name" label="Name">
    <template #label-prepend><span class="me-1 bi bi-person" /></template>
    <template #label-append><small class="text-muted">(required)</small></template>
</FormInput>

Basic usage example

<template>
    <!-- Common text input with validation -->
    <FormInput
        id="htmlId"
        label="Common text input"
        :validation="validations.example"
        v-model="example"
    />
</template>

<script setup>
import useVuelidate from '@vuelidate/core'
import { ref, computed } from 'vue'
import { required } from '@vuelidate/validators'

const example = ref('')
const validations = useVuelidate(computed(() => ({ example: { required } })), { example })
</script>

Common props (all components)

prop type required default description
label string false '' Input label text
size 'sm' 'lg' false undefined
validationMessages object false {} Key-value custom validation messages
validation vuelidate validation entry false {} Vuelidate validation instance
disabled boolean false false Disabled attribute
modelValue any false undefined Bound v-model value
hint string false undefined Static hint text under input
id string false auto Input id (auto-generated if absent)
readOnly boolean false false Readonly attribute
showAsRequired boolean false auto Force required styling regardless of validation rules
name string false undefined Native name attribute (where applicable)
renderAsGroup boolean false false Input group layout (where supported)
autocomplete string false undefined Native autocomplete (text)
modelModifiers object false undefined Vue model modifiers: { lazy, trim, number }

FormInput props

prop type required default description
type string false 'text' Input type
placeholder string false undefined Placeholder attribute
formatter (value: string, event: Event) => string false undefined Value transform function
lazyFormatter boolean false true Delay formatting until blur
renderAsGroup boolean false false Enable prepend / append slots
autocomplete string false undefined Native autocomplete

Formatting example:

<FormInput v-model="code" label="Code" :formatter="v=>v.toUpperCase()" :lazyFormatter="false" />

FormInputTextarea props

prop type required default description
rows number false undefined Rows attribute
placeholder string false undefined Placeholder
formatter function false undefined Value transform
lazyFormatter boolean false true Delay formatting until blur

FormInputSelect props

prop type required default description
options array true [] [{ value, text, disabled? }]
multi boolean false false Multi-select mode
selectSize number false undefined Height (rows) in multi-select
placeholder string false undefined Placeholder; if provided and no empty option exists, inserted as disabled option
renderAsGroup boolean false false Enable input group layout
name string false undefined Native select name

FormInputRadioGroup props

prop type required default description
options array true [] [{ value, text }]
stacked boolean false true Vertical layout; false renders inline

FormInputCheckboxGroup props

prop type required default description
options array true [] [{ value, text }]
stacked boolean false true Vertical vs inline
renderAsSwitch boolean false false Switch style variant

FormInputCheckbox props

prop type required default description
label string false '' Label text (ignored if label slot used)
renderAsSwitch boolean false false Switch style

Custom label:

<FormInputCheckbox v-model="agree">
    <template #label>I agree to the <a >Terms</a>.</template>
</FormInputCheckbox>

FormInputDatePicker props

Datepicker wraps @vuepic/vue-datepicker.

prop type required default description
locale Locale false cs Locale from date-fns lib as for vuepic/vue-datepicker
minDate Date false undefined Minimum selectable date
maxDate Date false undefined Maximum selectable date
enableTime boolean false false Allow time selection
ignoreTimeValidation boolean false true Limit validation to date part
dateFormat string function false internal
placeholder string false undefined Placeholder for input
enforceUtc boolean false false Use UTC when formatting
defaultTime { hours, minutes, seconds } false undefined Default time when enableTime

FormInputDatePickerAlt props

prop type required default description
locale Locale false cs Locale from date-fns
minDate Date false undefined Minimum date
maxDate Date false undefined Maximum date
enableTime boolean false false Time selection
ignoreTimeValidation boolean false true Date-only validation
dateFormat string function false internal
placeholder string false undefined Placeholder
showNowButton boolean false undefined Show "Now" button

Custom formatting:

<FormInputDatePicker v-model="picked" :dateFormat="d => d.toISOString().substring(0,10)" enforceUtc enableTime />

FormInputFile props & patterns

prop type required default description
multiple boolean false false Multiple file selection
accept string string[] false []
renderAsGroup boolean false false Enable input group layout
name string false undefined Native name

Filtering rules applied after selection:

  • .ext matches filename ending
  • image/* prefix wildcard
  • *suffix / prefix* MIME segments
  • Exact MIME type match

Example:

<FormInputFile v-model="files" :accept="['.pdf','image/*']" multiple label="Attachments" :renderAsGroup="true">
    <template #prepend><span class="input-group-text bi bi-paperclip" /></template>
</FormInputFile>

Validation integration

Pass a Vuelidate validation entry via validation. Component will call validation.$touch() on model updates and only show invalid state when dirty. Required style auto-applies if any rule is present unless overridden by showAsRequired.

Custom messages: supply validationMessages object or embed messages in validators (with $t: prefix for translation).

Formatting & modifiers

Use formatter functions plus lazyFormatter to adjust when they run. Combine with modelModifiers for numeric conversion, trimming or lazy updates.

<FormInput v-model="qty" type="number" label="Qty" :modelModifiers="{ number:true }" :formatter="v=>v.replace(/[^0-9]/g,'')" :lazyFormatter="false" />

Accessibility

aria-invalid is derived from validation state; labels remain associated via generated or provided id. Group layouts use Bootstrap input-group semantics.

Additional examples

Multi-select:

<FormInputSelect v-model="selected" :options="cities" multi :selectSize="6" placeholder="Choose cities" label="Cities" />

Inline radios:

<FormInputRadioGroup v-model="choice" :options="[{value:'a',text:'A'},{value:'b',text:'B'}]" :stacked="false" label="Choice" />

Switch-style checkbox group:

<FormInputCheckboxGroup v-model="features" :options="featureOptions" :renderAsSwitch="true" label="Features" />

Date-time with default time:

<FormInputDatePicker v-model="deadline" enableTime :defaultTime="{hours:9,minutes:0}" enforceUtc label="Deadline" placeholder="Select date & time" />

Styling

Include Bootstrap and the package CSS. Override classes like .form-group-required, .is-datepicker-invalid or input-group segments as needed.

Roadmap / contributions

Potential future docs: programmatic focus examples, migration guide from legacy bootstrap-vue-next versions, unit test patterns, Storybook showcase, dark mode notes. Contributions welcome.

i18n

If you want to automatically translate validation messages, you can use vue i18n, or custom function. Just add translations to your i18n instance and provide "t" function as below:

import { provide } from 'vue'
import { useI18n } from 'vue-i18n'
import { TRANSLATE_INJECTION_KEY } from '@tvaliasek/vue-form-inputs'

const { t } = useI18n()
provide<((message: string, params: Record<string, any>) => string)>(TRANSLATE_INJECTION_KEY, (message: string, params?: Record<string, any>) => t(message, params)) 

// for automatic translation of custom messages you could use $t: prefix
const v$ = useVuelidate({
    textInput: {
        required,
        minLength: minLength(4),
        custom: helpers.withMessage('$t:some.message', (value: string) => {
            return value === 'custom'
        })
    },
}, { textInput })

Add default translations to your i18n instance:

{
    "cs": {
        "vueFormInputs": {
            "feedback": {
                "required": "Toto pole je nutné vyplnit.",
                "minLength": "Hodnota musí být minimálně {minLength} znaků dlouhá.",
                "maxLength": "Hodnota musí být maximálně {maxLength} znaků dlouhá.",
                "minValue": "Hodnota musí být minimálně {minValue}.",
                "maxValue": "Hodnota musí být maximálně {maxValue}.",
                "between": "Hodnota musí být mezi {betweenMin} a {betweenMax}.",
                "alpha": "Jsou povoleny pouze písmena.",
                "alphaNum": "Jsou povoleny pouze písmena a čísla.",
                "numeric": "Jsou povoleny pouze čísla.",
                "integer": "Jsou povolena pouze celá čísla.",
                "decimal": "Jsou povolena pouze desetinná čísla.",
                "email": "Chybný formát emailové adresy.",
                "ipAddress": "Chybný formát IP adresy.",
                "macAddress": "Chybný formát MAC adresy.",
                "sameAs": "Hodnota není shodná.",
                "url": "Chybný formát URL adresy.",
                "validatedEmail": "Nefunkční nebo chybná emailová adresa.",
                "invalidValue": "Chybně vyplněná hodnota."
            }
        }
    },
    "en": {
        "vueFormInputs": {
            "feedback": {
                "required": "This field must be filled.",
                "minLength": "The value must be at least {minLength} characters long.",
                "maxLength": "The value must be at most {maxLength} characters long.",
                "minValue": "The value must be at least {minValue}.",
                "maxValue": "The value must be at most {maxValue}.",
                "between": "The value must be between {betweenMin} and {betweenMax}.",
                "alpha": "Only letters are allowed.",
                "alphaNum": "Only letters and numbers are allowed.",
                "numeric": "Only numbers are allowed.",
                "integer": "Only whole numbers are allowed.",
                "decimal": "Only decimal numbers are allowed.",
                "email": "Incorrect email address format.",
                "ipAddress": "Incorrect IP address format.",
                "macAddress": "Incorrect MAC address format.",
                "sameAs": "The values are not identical.",
                "url": "Incorrect URL address format.",
                "validatedEmail": "Broken or incorrect email address.",
                "invalidValue": "Incorrectly filled value."
            }
        }
    }
}

Related Packages

vue-formular

a comprehensive vue.js form component

4,451 43
vue-form-components

A collection of bootstrap form components for Vue 2

1,826 30
@vue-interface/form-control

An abstract form control Vue mixin.

9,987 3
@vue-interface/btn-activity

A Vue activity button component.

3,643 3
@rc-component/async-validator

Validate form asynchronous

99,929,287 16

Version History

Version Released Vue License
5.2.4 ^3.5.34 MIT
5.2.3 ^3.5.34 MIT
5.2.2 ^3.5.27 MIT
5.2.1 ^3.5.27 MIT
5.2.0 ^3.5.25 MIT