This component uses the zxcvbn-ts package to detect and validate the password input strength.
Ready to use password input component with validation and formatting.
<script lang="ts" setup>
const password = ref('')
</script>
<template>
<div class="max-w-md">
<BaseField label="Password">
<LazyAddonInputPassword v-model="password" />
</BaseField>
</div>
</template>
Changing the locale allows to change the language of the password strength feedback and the dictionaries used to validate the password.
You can install and load dictionaries from the zxcvbn-ts package or create your own dictionary.
<script lang="ts" setup>
const password = ref('')
const fr = () => import('@zxcvbn-ts/language-fr')
</script>
<template>
<div class="max-w-md">
<BaseField label="Mot de passe">
<LazyAddonInputPassword
v-model="password"
:locale="fr"
/>
</BaseField>
</div>
</template>
<script lang="ts" setup>
import type { AddonInputPassword } from '#components'
import type { ZxcvbnResult } from '@zxcvbn-ts/core'
const password = ref('qwerty')
const error = ref('')
const inputRef = ref<InstanceType<typeof AddonInputPassword>>()
function onSubmit() {
const score = inputRef.value?.validation?.score ?? 0
if (score < 5) {
// eslint-disable-next-line no-alert
alert(`Please enter a stronger password, current score: ${score}/5`)
return
}
// eslint-disable-next-line no-alert
alert(`Selected: ${inputRef.value?.validation?.password} with score ${score}`)
}
function onValidate(state: { validation: ZxcvbnResult | null, touched: boolean }) {
error.value = state.validation?.feedback.warning ?? ''
if (state.validation && state.validation.score < 5) {
error.value = 'Please enter a stronger password'
}
}
</script>
<template>
<form
class="max-w-md"
autocomplete="off"
@submit.prevent="onSubmit"
>
<BaseField
v-slot="{ inputAttrs }"
label="Password"
:state="error ? 'error' : 'idle'"
:error="error"
>
<LazyAddonInputPassword
ref="inputRef"
v-model="password"
placeholder="Type to try validation"
v-bind="inputAttrs"
@validation="onValidate"
/>
</BaseField>
</form>
</template>
<script lang="ts" setup>
const password = ref('F4k3P4ssw0rd')
</script>
<template>
<div class="max-w-md">
<BaseField label="Password">
<LazyAddonInputPassword
v-model="password"
disabled
/>
</BaseField>
</div>
</template>
<script lang="ts" setup>
import type { AddonInputPassword } from '#components'
const passwordRef = ref<InstanceType<typeof AddonInputPassword>>()
const hasError = computed(() => !!passwordRef.value?.validation?.feedback?.warning || !!passwordRef.value?.validation?.feedback?.suggestions?.length)
const loading = computed(() => passwordRef.value?.loading)
const username = ref('superuser')
const email = ref('contact@acme.com')
const password = ref('contact@acme.com')
const useUserInputs = ref(true)
const userInputs = computed(() => useUserInputs.value ? [username.value, email.value] : [])
</script>
<template>
<div class="grid grid-cols-2 gap-4 md:max-w-lg">
<BaseField label="Username">
<TairoInput
v-model="username"
icon="lucide:user"
/>
</BaseField>
<BaseField label="Email">
<TairoInput
v-model="email"
icon="lucide:mail"
/>
</BaseField>
<BaseField
v-slot="{ inputAttrs }"
label="Password"
:state="loading ? 'loading' : hasError ? 'error' : 'idle'"
:error="passwordRef?.validation?.feedback?.warning ?? ''"
class="col-span-2"
>
<LazyAddonInputPassword
ref="passwordRef"
v-model="password"
icon="lucide:lock"
:user-inputs="userInputs"
show
touched
v-bind="inputAttrs"
/>
</BaseField>
<div class="mt-2">
<BaseSwitchThin
v-model="useUserInputs"
label="Check other inputs"
/>
</div>
</div>
</template>