You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.5 KiB
54 lines
1.5 KiB
<script setup lang="ts">
|
|
const props = defineProps<{ password: string }>()
|
|
|
|
const score = computed(() => {
|
|
const p = props.password
|
|
if (!p) return 0
|
|
|
|
let s = 0
|
|
const hasLower = /[a-z]/.test(p)
|
|
const hasUpper = /[A-Z]/.test(p)
|
|
const hasDigit = /\d/.test(p)
|
|
const hasSpecial = /[^a-zA-Z\d]/.test(p)
|
|
|
|
const hasLetter = hasLower || hasUpper
|
|
if (p.length >= 8 && hasLetter && hasDigit) s = 2
|
|
if (p.length >= 10 && hasLower && hasUpper && hasDigit) s = 3
|
|
if (p.length >= 12 && hasLower && hasUpper && hasDigit && hasSpecial) s = 4
|
|
// Fallback: any input < 8 or single-type = weak
|
|
if (s === 0 && p.length > 0) s = 1
|
|
|
|
return s
|
|
})
|
|
|
|
const label = computed(() => {
|
|
const labels = ['', '弱', '中', '强', '很强']
|
|
return labels[score.value]
|
|
})
|
|
|
|
const barWidth = computed(() => `${(score.value / 4) * 100}%`)
|
|
|
|
const barColor = computed(() => {
|
|
const colors = ['', 'bg-red-500', 'bg-amber-500', 'bg-green-500', 'bg-emerald-500']
|
|
return colors[score.value]
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="score > 0" class="mt-1 space-y-1">
|
|
<div class="h-1 w-full rounded-full bg-(--ui-bg-accented)">
|
|
<div
|
|
data-testid="strength-bar"
|
|
:data-score="score"
|
|
:class="[barColor, 'h-1 rounded-full transition-all duration-300']"
|
|
:style="{ width: barWidth }"
|
|
/>
|
|
</div>
|
|
<p class="text-xs" :class="{
|
|
'text-red-500': score === 1,
|
|
'text-amber-500': score === 2,
|
|
'text-green-500': score === 3,
|
|
'text-emerald-500': score === 4,
|
|
}">{{ label }}</p>
|
|
</div>
|
|
</template>
|
|
|