Password Input
The <x-wirekit:: component extends the standard text input with a visibility toggle (eye icon) and an optional password strength meter. The toggle switches between type="password" and type="text" via Alpine.js without re-rendering.
Basic Usage
Without Toggle
When toggle is false, the eye icon button is not rendered and the input behaves like a standard password field.
With Strength Meter
Use at least 8 characters with a mix of letters, numbers, and symbols.
The strength meter evaluates the input in real-time using Alpine.js and displays a colored bar below the field:
- Weak — short or common patterns
- Fair — meets minimum length but lacks variety
- Good — reasonable mix of character types
- Strong — long with diverse character types
The same bars are available without a field as Strength Meter, for a strength your application computes, such as that of a generated code.
An x-model of yours binds the password with the meter on as it does without it: the component hands the value the meter reads to your binding, so your model, the meter and the field always hold the same text.
Size Variants
Error State
Password must be at least 8 characters.
Width
Like all WireKit form components, the password input fills its container (w-full). Control the width via the parent element:
<div class="max-w-sm">
<x-wirekit::password-input label="Password" name="password" />
</div>
See Input — Width for more layout examples (grid columns, mixed widths).
Optimistic UI
Pass the name of the Livewire method the field should call and the value is sent when you leave the field, shown as saving while it goes:
<x-wirekit::password-input
name="secret"
autocomplete="new-password"
label="New password"
optimistic="savePassword"
/>
Load wirekit-optimistic. alongside whichever bundle you already use — below it, in your layout:
@wirekitScripts
<script src="{{ asset('vendor/wirekit/wirekit-optimistic.js') }}" defer></script>
Try it
The demo below runs the real path: the change shows immediately, the outline says it is provisional, and the server's answer either confirms it silently or takes it back.
The <livewire:demos.…> wrapper above exists only on this site — it supplies the demo
methods so the page can show a real round trip. The block under it is what you write.
A refusal does not take your value back. For a toggle or a select, putting the old value back costs you nothing — it is simply the other choice. Here it would delete what you typed because a save failed, and re-typing a password is the most expensive re-entry any field can ask for. The value stays, and you are told two things: that it did not save, and that it is still there.
Nothing reads your password back. The announcements name no value, and none is written into the page's markup either — the field is driven by the property it already owns rather than by a value handed to the script.
The field is not marked invalid. aria-invalid means this value is wrong, and a save that failed on the network says nothing about the value.
Required Fields
A required field the reader leaves empty is marked red once they try to submit — the same way
every other WireKit field is, because the styling lives on the shared wk-field class rather than
in each component's own class list.
It uses :user-invalid, not :invalid. The difference is when it fires: :user-invalid waits
until the reader has interacted with the control or tried to send the form, so an empty form does
not arrive painted red.
The mark is the browser's judgment, not a validation result of yours. For a rule the browser
cannot check — a password that is too short for your policy, one that does not match its
confirmation — pass the message through error, which paints the same border and announces it.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string|null |
null |
Label text above the input |
hideLabel |
bool |
false |
Render the label visually hidden (sr-only) but keep it for assistive tech — for a compact field in a toolbar or header |
hint |
string|null |
null |
Help text below the input |
help |
string|null |
null |
An explanation of the field, shown in a tooltip from a question mark beside the label and read as the field's description. Needs a label to stand beside. See Help beside the label |
error |
string|null |
null |
Error message (also reads from $errors) |
autocomplete |
string|false |
current-password |
Which password this field holds. Pass new-password on a registration or change-password form — three identical-looking fields are where an autofill heuristic guesses wrong. false omits the attribute for a field that is not a credential (WCAG 1.3.5) |
name |
string|null |
null |
Form field name |
id |
string|null |
auto-generated | Element id |
size |
string |
'md' |
'sm', 'md', 'lg' |
toggle |
bool |
true |
Show the show/hide password toggle button |
strengthMeter |
bool |
false |
Show password strength meter below input |
optimistic |
string|null |
null |
Livewire method to call when you leave the field, showing the change before the server answers |
optimisticArgs |
array |
[] |
Extra arguments appended to the optimistic action call, after the new value — the row this control belongs to. |
disabled |
bool |
false |
Disables the field and its show-password button |
scope |
string|null |
null |
Scoped personalization key |
announceError |
bool|null | null |
Render the error message in an aria-live="polite" region so a validation error that appears after render reaches a screen reader. Precedence: this prop, then the parent <x-wirekit::form :announce-errors>, then config('wirekit.a11y.announce_error'). Set false when the page runs its own live region. |
Slots
| Slot | Description |
|---|---|
labelAfter |
Markup after the label and its help question mark, in the same row and outside both, such as a badge that says a setting is not decided yet. See A Mark After the Label. |
Accessibility
- Uses native
<input type="password">— inherits browser autofill and AT support - The toggle button is named after the field it reveals, "Show New password" and "Hide New password" on a field labeled New password, so a form with a password and its confirmation does not offer two buttons with one name. A field with neither
labelnoraria-labelreads "Show password" and "Hide password". The name changes with the state, and it is the one place the state is reported: a pressed state beside it would report it twice, and "Hide password, pressed" leaves open whether the password is shown - Toggle icons (eye / eye-off) are
aria-hidden="true" - Strength meter bar uses
role="meter"witharia-valuenow,aria-valuemin="0",aria-valuemax="4",aria-label="Password strength", and anaria-valuetextthat names the level in words rather than as a number - While the field is empty the meter carries no
aria-valuetextat all, rather than an empty one. There is no verdict to announce on a password nobody has typed, andaria-valuetextis read instead of the number — so an empty value leaves it to the reader's software whether to fall back toaria-valuenow="0"or to say nothing - Strength level text ("Weak password" … "Strong password") sits in a visually-hidden
aria-live="polite"region, so the score reaches a screen reader instead of being carried by the bar colors alone — it is also what the field'saria-describedbypoints at aria-invalid="true"andaria-describedbyset on error or hint
Keyboard Interaction
| Key | Action |
|---|---|
Tab |
Move focus to the input |
| Any character | Insert the character (rendered as a masked dot when masked) |
Tab (twice) |
Move focus to the show/hide toggle button |
Enter / Space (on toggle) |
Toggle masked / plain rendering |
Pitfalls
- Don't disable the show-password toggle for "security." Hiding the toggle reduces password quality more than it adds security (cognitive load drives users to weak choices).
- Don't omit
autocomplete="current-password"/"new-password". Browsers and password managers use these to populate correctly; missing values block manager auto-fill.
Design Tokens
| Token | Purpose |
|---|---|
--color-wk-bg-input |
Input background |
--color-wk-border-strong |
Default border color |
--color-wk-border-error |
Border color on error |
--color-wk-text |
Input text color |
--color-wk-text-muted |
Toggle button icon color |
--color-wk-text |
Toggle button icon color on hover |
--color-wk-ring |
Focus ring color |
--color-wk-danger |
Strength meter — weak |
--color-wk-warning |
Strength meter — fair |
--color-wk-success |
Strength meter — strong |
--size-wk-sm / md / lg |
Input height per size variant |
--radius-wk-md |
Border radius |
--transition-wk-duration |
Toggle + meter transition speed |
Customization
Override defaults in config/:
'components' => [
'password-input' => ['size' => 'md', 'toggle' => true, 'strength-meter' => false],
],