A drop-in wrapper block that adds a show/hide eye icon to any password field. Wrap your existing password Input, and users get a familiar eye toggle inside the field — click to reveal, click again to hide. Includes an optional auto-hide safety timer so revealed passwords don't stay on screen indefinitely. Pure client-side, no dependencies.
Almost every login and signup screen benefits from a show/hide password toggle — it prevents typos and reduces user frustration, especially on mobile. Password Toggle is a small wrapper block that gives you that behavior without replacing your existing password Input. Drop the block, put your password field inside it, and the eye appears automatically.
aria-label
type=button
OnVisibilityChanged
.oap
PasswordToggle AutoHideSeconds = 10 Content: Input (type=Password, Variable=MyPassword)
Wrap your existing password Input with the PasswordToggle block. The eye icon appears inside the field, and clicking it reveals or hides the password. That's the whole integration.
PasswordToggle
AutoHideSeconds
0
ShowLabel
"Show password"
HideLabel
"Hide password"
IsVisible
The block also exposes a Content placeholder where you drop the password Input.
Content
The block finds the first password Input inside its Content placeholder and toggles that one. You don't have to configure or wire anything — just drop the block around your existing field. Your Input keeps its variable binding, its validation, and any other properties as they were.
If for some reason you have multiple inputs inside the same wrapper, the block toggles the first password-type input it finds — so keep one field per wrapper.
Showing a password on-screen improves usability but creates a small risk: an unattended screen with a revealed password is a security concern. Set AutoHideSeconds to a positive value (5–30 is a good range) and the block will automatically re-hide the password that many seconds after it was revealed, firing OnVisibilityChanged(False) when it does.
OnVisibilityChanged(False)
If the user manually hides the password before the timer fires, the pending timer is cancelled so the state doesn't flicker. If the user reveals it again, the timer resets. Simple to configure, hard to get wrong.
Set AutoHideSeconds = 0 (the default) to disable this behavior entirely — the password stays visible until the user clicks the toggle again.
AutoHideSeconds = 0
The toggle is a real <button> with type="button" (so it never accidentally submits your form). Its aria-label updates dynamically between ShowLabel and HideLabel so screen readers announce what the button will do next. The button is keyboard-focusable with a visible focus ring, and both Enter and Space activate it (native button behavior).
<button>
type="button"
The ShowLabel and HideLabel inputs let you localize these strings — set them from your app's language variables if you support multiple languages.
The block uses these classes: pt-wrap (the wrapper), pt-toggle (the button), and pt-icon (the icon inside). The eye icons are inline SVG via CSS masks that adopt the button's text color via currentColor, so they follow your app's theme automatically. Override in your app theme to customize:
pt-wrap
pt-toggle
pt-icon
currentColor
.pt-toggle { color: #4f46e5; } /* icon color */ .pt-toggle:hover { background: #eef2ff; } /* hover background */ .pt-toggle { right: 12px; } /* distance from field's right edge */
The block also automatically adds right padding to the input so typed characters don't overlap the eye — no configuration needed.
Showing a password on-screen is a UX-vs-security trade-off:
Use the toggle where usability matters (self-service signup, personal-device login), and consider avoiding it on shared kiosks or high-security screens. The AutoHideSeconds timer is a partial mitigation — it reduces the time window of exposure — but doesn't eliminate the risk.
The eye doesn't appear.Confirm you put the password Input inside the block's Content placeholder, not next to it. The block searches its own descendants for the input.
The eye appears but clicking it does nothing.Check that the block found a password input: in the browser console, run document.querySelectorAll('.pt-wrap input[type="password"], .pt-wrap input[type="text"]').length — should be at least 1.
document.querySelectorAll('.pt-wrap input[type="password"], .pt-wrap input[type="text"]').length
The auto-hide timer doesn't fire.Confirm AutoHideSeconds is a positive number. If you also have a page that navigates or reloads shortly after reveal, the timer may not have a chance to fire before the page unloads.
Icon color is wrong.The icon uses currentColor, so it follows the toggle button's text color. Set .pt-toggle { color: <your-color> } in your theme, or just style the parent.
.pt-toggle { color: <your-color> }
Eye overlaps my typed characters.The block adds right padding to the input automatically, but if your theme forces a different padding rule via !important, that can override it. Increase the input's right padding in your theme or reduce the icon's right offset.
!important
right
Published on the OutSystems Forge as open, reusable code. Free to use and adapt in your OutSystems projects.