@substrate-system/password-input
v0.0.6
Published
[](https://github.com/substrate-system/password-input/actions/workflows/nodejs.yml) [Attributes
You can pass attributes on <password-input>, and the component maps them to
the inner <input> as described below. Do not pass the type attribute.
That is controlled by the component.
| Attribute | Should pass? | Behavior |
| --- | --- | --- |
| label | Optional, recommended | Renders visible label text above the input. |
| visible | Optional | If present, initial state is visible text (type="text"). If absent, initial state is hidden (type="password"). |
| id | Recommended when used with external labels/help text | Moved to the inner <input id="..."> and removed from <password-input>. |
| aria-* | Recommended for accessibility | Any supported ARIA attribute passed on <password-input> is moved to the inner <input> and removed from <password-input>. |
| Standard input attributes (name, placeholder, value, autocomplete, required, disabled, readonly, minlength, maxlength, pattern, etc.) | Optional as needed | Forwarded to the inner <input>. |
Supported aria-* attributes
aria-activedescendant, aria-atomic, aria-autocomplete,
aria-braillelabel, aria-brailleroledescription, aria-busy,
aria-checked, aria-colcount, aria-colindex, aria-colindextext,
aria-colspan, aria-controls, aria-current, aria-describedby,
aria-description, aria-details, aria-disabled, aria-dropeffect,
aria-errormessage, aria-expanded, aria-flowto, aria-grabbed,
aria-haspopup, aria-hidden, aria-invalid, aria-keyshortcuts,
aria-label, aria-labelledby, aria-level, aria-live, aria-modal,
aria-multiline, aria-multiselectable, aria-orientation, aria-owns,
aria-placeholder, aria-posinset, aria-pressed, aria-readonly,
aria-relevant, aria-required, aria-roledescription, aria-rowcount,
aria-rowindex, aria-rowindextext, aria-rowspan, aria-selected,
aria-setsize, aria-sort, aria-valuemax, aria-valuemin,
aria-valuenow, aria-valuetext
Usage Notes
- Do not pass
type. The component controlstypeinternally (passwordortext) based on the visibility toggle. - If an ARIA attribute changes later (
setAttribute('aria-label', '...')on<password-input>), the inner<input>is updated throughattributeChangedCallback.
Example
<password-input
id="account-password"
label="New Password"
name="password"
placeholder="At least 12 characters"
autocomplete="new-password"
required
minlength="12"
aria-describedby="password-help">
</password-input>
<p id="password-help">Use a strong, unique password.</p>Events
The component emits namespaced custom events whenever its visibility changes. The events bubble, so you can listen on the element itself or on any ancestor.
| Event | Emitted when |
| --- | --- |
| password-input:show | The input becomes visible (type="text"). |
| password-input:hide | The input becomes hidden (type="password"). |
Build the event name with the static PasswordInput.event(...) helper, or pass
the string directly. ev.target is the <password-input> that changed.
import { PasswordInput } from '@substrate-system/password-input'
const input = document.querySelector('password-input')
input.addEventListener(PasswordInput.event('show'), (ev) => {
console.log(ev.target.isVisible) // true
})There is also a short-hand .on(...) method on the element that namespaces the
event name for you:
input.on('hide', (ev) => { /* ... */ })Example: keep several inputs in sync
Because the events bubble, a single delegated listener can keep every
<password-input> on the page in sync — clicking any input's eye button
shows or hides them all.
import { PasswordInput } from '@substrate-system/password-input'
function syncVisibility (ev) {
const visible = ev.target.isVisible
document.querySelectorAll('password-input').forEach(el => {
el.isVisible = visible
})
}
document.addEventListener(PasswordInput.event('show'), syncVisibility)
document.addEventListener(PasswordInput.event('hide'), syncVisibility)Use
This calls the global function customElements.define. Just import, then use
the tag in your HTML.
JS
import '@substrate-system/password-input'HTML
<div>
<password-input></password-input>
</div>pre-built
This package exposes minified JS and CSS files too. Copy them to a location that is accessible to your web server, then link to them in HTML.
copy
cp ./node_modules/@substrate-system/password-input/dist/index.min.js ./public/password-input.min.js
cp ./node_modules/@substrate-system/password-input/dist/style.min.css ./public/password-input.cssHTML
<head>
<link rel="stylesheet" href="./password-input.css">
</head>
<body>
<!-- ... -->
<script type="module" src="./password-input.min.js"></script>
</body>CSS
Import CSS
import '@substrate-system/password-input/css'Or minified:
import '@substrate-system/password-input/min/css'Notes
Implementation notes.
ignoredAriaCallbackNames property
- You set an
aria-*attribute on<password-input>. attributeChangedCallbackroutes tohandleChange_aria(index.ts (line 105)).handleChange_ariacopies that value to the inner<input>(index.ts (line 189)).- Then it removes the same
aria-*from the host (index.ts (line 194)) so host stays clean. - That removal triggers
attributeChangedCallbackagain withnewValue === null. - The guard sees the name in
ignoredAriaCallbackNames, deletes it, and returns early (index.ts (line 178)), so it does not remove the attribute from the input/cache.
Without this guard, the second callback would treat the host removal as a real “delete” request and clear the input attribute you just transferred.
