A password input with less style than password-field.
Accessible by default — aria-* attributes, the id attribute, and a
label attribute, if present, are all handled correctly.
npm i -S @substrate-system/password-inputThis exposes ESM and common JS via package.json exports field.
import { PasswordInput } from '@substrate-system/password-input'require('@substrate-system/password-input')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>. |
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
- 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.
<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>This calls the global function customElements.define. Just import, then use
the tag in your HTML.
import '@substrate-system/password-input'<div>
<password-input></password-input>
</div>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.
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.css<head>
<link rel="stylesheet" href="./password-input.css">
</head>
<body>
<!-- ... -->
<script type="module" src="./password-input.min.js"></script>
</body>import '@substrate-system/password-input/css'Or minified:
import '@substrate-system/password-input/min/css'Implementation notes.
- 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.