@passcore/vanilla
JavaScript puro
@passcore/vanilla no necesita ningún framework ni jQuery: llama a createPasswordMeter() sobre un campo, o escribe un elemento <passcore-meter> donde quieras el indicador.
pnpm add @passcore/vanilla
Todos los indicadores de esta página hablan tu idioma. La zona de pruebas le da a cada uno los textos del idioma que elijas arriba y su nombre accesible. Para que los fragmentos de código sean breves, solo las demos de traducción muestran cómo se hace; el botón para mostrar y ocultar la contraseña es de la zona de pruebas, no del paquete.
Por defecto
Con hideUntilFocus el indicador se mantiene oculto hasta que el campo recibe el foco, y vuelve a ocultarse al perderlo si el campo está vacío.
import { createPasswordMeter } from '@passcore/vanilla'
import '@passcore/vanilla/styles.css'
createPasswordMeter('#default-password', { hideUntilFocus: true })
Lista de requisitos
El clásico formulario de registro: todas las condiciones, en rojo o en verde mientras se escribe. El callback onScore (o el evento passcore:score, que se propaga) trae el resultado completo, y result.rules enumera todas las reglas activas, por orden, con su id, passed y params. Al escribir el nombre de usuario se llama a refresh(), para que la regla de los datos personales lo tenga en cuenta. Cada elemento se queda en gris hasta que se escribe algo: una contraseña vacía tampoco es “común”, y mostrarlo en verde sería engañoso.
Requisitos
- Al menos 8 caracteres , cumplido , no cumplido
- Que no sea una contraseña común , cumplido , no cumplido
- Sin datos personales, como tu nombre de usuario , cumplido , no cumplido
- Una letra minúscula , cumplido , no cumplido
- Una letra mayúscula , cumplido , no cumplido
- Un número , cumplido , no cumplido
- Un símbolo , cumplido , no cumplido
7 requisitos por cumplir
// the list: <li data-rule="minLength" data-state="idle">At least 8 characters</li>, and so on
const input = document.querySelector('#signup-password')
const summary = document.querySelector('#checklist-summary')
function check(result) {
const typed = input.value !== ''
for (const rule of result.rules) {
const item = document.querySelector(`#checklist [data-rule="${rule.id}"]`)
item.dataset.state = !typed ? 'idle' : rule.passed ? 'met' : 'unmet'
}
// a live region: only touch it when the count changes
const met = result.rules.filter((rule) => rule.passed).length
const text = typed ? `${met} of ${result.rules.length} requirements met` : `${result.rules.length} requirements to meet`
if (summary.textContent !== text) {
summary.textContent = text
}
}
const meter = createPasswordMeter(input, {
userInputs: ['#signup-username'],
rules: { minLength: 8, lowercase: 1, uppercase: 1, numbers: 1, symbols: 1 },
onScore: (percent, result) => check(result),
})
// or: input.addEventListener('passcore:score', (event) => check(event.detail.result))
// the username is read on each update: refresh when it changes
document.querySelector('#signup-username').addEventListener('input', () => meter.refresh())
Siempre visible, con el porcentaje
Sin hideUntilFocus el indicador se ve desde el principio, y showPercent añade el número.
createPasswordMeter('#always-password', { showPercent: true })
Vinculado a un nombre de usuario
Con userInputs la contraseña no puede contener el nombre de usuario. Las cadenas son selectores y se leen con cada pulsación; también admite funciones.
createPasswordMeter('#linked-password', {
userInputs: ['#username'],
showPercent: true,
})
Traducciones incluidas
Los archivos incluidos van en translations, locale elige las formas del plural y label da nombre al indicador para los lectores de pantalla. Las opciones se leen una sola vez, así que otro idioma significa otro indicador.
import en from '@passcore/vanilla/locales/en.json'
import es from '@passcore/vanilla/locales/es.json'
import ca from '@passcore/vanilla/locales/ca.json'
const locales = { en, es, ca }
// the options are read once: create the meter again for another language
meter?.destroy()
meter = createPasswordMeter('#translations-password', {
translations: locales[lang],
locale: lang,
label: labels[lang],
showPercent: true,
})
Traducciones con i18next
translate recibe la función t de una instancia de i18next, aquí la de la propia zona de pruebas. Los textos se traducen en cada actualización, así que para cambiar de idioma basta con refresh().
import i18next from 'i18next'
import es from '@passcore/vanilla/locales/es.json'
import ca from '@passcore/vanilla/locales/ca.json'
i18next.addResourceBundle('es', 'passcore', es)
i18next.addResourceBundle('ca', 'passcore', ca)
const meter = createPasswordMeter('#i18next-password', {
translate: (key, params) => i18next.t(key, { ns: 'passcore', ...params }),
showPercent: true,
})
// the texts are translated on every update: refresh them
i18next.on('languageChanged', () => meter.refresh())
Callbacks y eventos
El callback onScore y el evento passcore:score, que se propaga, reciben el porcentaje en cada actualización. Aquí controlan el botón Enviar y la puntuación.
const input = document.querySelector('#events-password')
const send = document.querySelector('#send')
createPasswordMeter(input, {
onScore: (percent) => {
send.disabled = percent <= 75
},
})
input.addEventListener('passcore:score', (event) => {
document.querySelector('#events-score').textContent = `${event.detail.percent}%`
})
Contenedor propio
Por defecto, el indicador va justo después del campo. container lo añade en otro sitio: aquí, debajo de todo el grupo de campos.
createPasswordMeter('#group-password', { container: '#group-field' })
El elemento <passcore-meter>
<passcore-meter> dibuja el indicador justo donde lo escribes. Los atributos cubren las opciones sencillas: min-length, show-percent, user-inputs, locale, label y alguna más.
<script type="module">
import '@passcore/vanilla/element'
</script>
<input type="text" id="element-username">
<input type="password" id="element-password">
<passcore-meter
for="element-password"
min-length="10"
show-percent
user-inputs="#element-username"
></passcore-meter>
Opciones del elemento desde JavaScript
Lo que no cabe en un atributo (traducciones, reglas, callbacks) va en la propiedad options, que se combina con los atributos. Este, además, pide un número y un símbolo.
const element = document.querySelector('passcore-meter[for="options-password"]')
// merged over the attributes: show-percent still applies
element.options = {
translations: locales[lang],
locale: lang,
rules: { numbers: 1, symbols: 1 },
}
Temas
Los colores, la pista y la altura son propiedades personalizadas de CSS: de --pass-color-very-weak a --pass-color-strong, --pass-track y --pass-height. Juega con ellas aquí: el CSS de abajo cambia a la vez.
- Muy débil
- Débil
- Aceptable
- Buena
- Fuerte
.signup {
--pass-height: 6px;
--pass-track: #e4e2db;
--pass-color-very-weak: #d92d20;
--pass-color-weak: #e06a0f;
--pass-color-fair: #c99400;
--pass-color-good: #5e9e0f;
--pass-color-strong: #16884a;
}
Los controles solo cambian esta vista previa, así que las demás demos conservan su aspecto. Define las propiedades en :root para aplicar el tema a todo un sitio.