Web component for password inputs
Featuring
An eyeball button that will change the visiblity of the password.
This state is tracked by the webcomponent itself, but it can also be set by
an attribute, visible. If visible is present on the tag, then you can see
the password.
See ./example for an example of using the attribute to control visiblity, and keeping two inputs in sync with each other.
npm i -S @substrate-system/password-fieldImport the JS component and CSS.
import { PasswordField } from '@substrate-system/password-field'
import '@substrate-system/password-field/css'
// or import minified css
import '@substrate-system/password-field/css/min'For Node.js:
import { render } from '@substrate-system/password-field/html'
const html = render({
name: 'password',
'display-name': 'Password'
})Use the tag in HTML
<form>
<password-field
name="password"
display-name="New Password"
></password-field>
</form>Listen for events in JS
import { PasswordField } from '@substrate-system/password-field'
const eventName = PasswordField.event('change-visibility')
form?.addEventListener(eventName, ev => {
const { isVisible } = ev.detail
console.log('is visible', isVisible)
})For server-side rendering or generating HTML strings in Node.js, you can
use the render function:
import { render } from '@substrate-system/password-field/html'
// Basic usage
const html = render()
// With attributes
const html = render({
name: 'password',
'display-name': 'New Password',
required: true,
isVisible: false
})name- Input name attributedisplay-name- Display name for the fieldrequired- Whether the field is requiredautocomplete- Autocomplete attribute (defaults to 'new-password')isVisible- Whether the password is visible (affects button icon)- Any other attributes will be passed through to the text-input component
Note
For server-side rendering, you'll need to include the CSS separately in your
HTML template. The render() function only generates the HTML structure.
import type { Attrs } from '@substrate-system/web-component/attributes'
// The render function accepts an optional Attrs object
function render(attributes?: Attrs): stringimport { render } from '@substrate-system/password-field/html'
// In your server-side template
function renderLoginForm() {
return `
<form>
<input type="email" name="email" required />
${render({
name: 'password',
'display-name': 'Password',
required: true
})}
<button type="submit">Login</button>
</form>
`
}# Test server-side rendering functions
npm run test:node
# Test both browser and Node.js functionality
npm test-
password-field:change-visiblityimport { PasswordField } from '../src/index.js' PasswordField.event('change-visiblity') // => 'password-field:change-visiblity'
Fired when someone clicks the eyeball button in the field. The event
.detailhas a propertyisVisibleform?.addEventListener(PasswordField.event('change-visibility'), ev => { const { isVisible } = ev.detail })
visibledisplay-namerequiredautocompletename
Note
The name attribute is used for an id on the element also, so it should
be unique.
This package provides multiple entry points:
Main component (client-side):
import { PasswordField, define } from '@substrate-system/password-field'Server-side rendering:
import { render } from '@substrate-system/password-field/html'CSS styles:
import '@substrate-system/password-field/css'
// or minified
import '@substrate-system/password-field/css/min'This exposes ESM and common JS via package.json exports field.
import '@namespace/package/module'require('@namespace/package/module')import '@namespace/package-name/css'Or minified:
import '@namespace/package-name/css/min'Use event bubbling to attach a single listener to the parent form. Use the imported component, PasswordField, to get the namespaced event name.
import { PasswordField } from '@substrate-system/password-field'
import '@substrate-field/password-field/css'
const form = document.querySelector('form')
form?.addEventListener(PasswordField.event('change-visibility'), ev => {
// synchronize changes in visibility, so
// both inputs are either visible or not visible
const { isVisible } = ev.detail
document.querySelectorAll('password-field').forEach(el => {
if (isVisible) {
el.setAttribute('visible', '')
} else {
el.removeAttribute('visible')
}
})
})