Show password at Login and Register pages.

Thanks to xet7 !

Fixes #6070
This commit is contained in:
Lauri Ojansivu 2026-01-17 19:40:07 +02:00
parent 7291617a77
commit d30192f7f9
4 changed files with 119 additions and 0 deletions

View file

@ -0,0 +1,14 @@
template(name='passwordInput')
.at-input
label(for='at-field-{{_id}}') {{displayName}}
.password-input-container
input.password-field(type="{{type}}" placeholder="{{displayName}}" autocomplete="{{autocomplete}}" required="{{required}}")
button.password-toggle-btn(type="button" aria-label="Toggle password visibility" title="Toggle password visibility")
.eye-container
span.eye-text 👁️
svg.eye-slash(width="20" height="20" viewBox="0 0 20 20" class="eye-slash-line")
line(x1="6" y1="14" x2="32" y2="-14" stroke="#000" stroke-width="2" stroke-linecap="round")
if errs
.at-error
each errs
div {{this}}

View file

@ -0,0 +1,46 @@
import { TAPi18n } from '/imports/i18n';
Template.passwordInput.onRendered(function() {
const template = this;
const input = template.find('input.password-field');
const label = template.find('label');
// Set the dynamic id and name based on the field _id
if (template.data && template.data._id) {
const fieldId = `at-field-${template.data._id}`;
input.id = fieldId;
input.name = fieldId;
label.setAttribute('for', fieldId);
// Ensure the input starts as password type for password fields
input.type = 'password';
// Initially hide the slash line since password starts hidden
const slashLine = template.find('.eye-slash-line');
if (slashLine) {
slashLine.style.display = 'none';
}
}
});
Template.passwordInput.events({
'click .password-toggle-btn'(event, template) {
event.preventDefault();
const input = template.find('input.password-field');
const slashLine = template.find('.eye-slash-line');
if (input.type === 'password') {
input.type = 'text';
// Show the slash line when password is visible
if (slashLine) {
slashLine.style.display = 'block';
}
} else {
input.type = 'password';
// Hide the slash line when password is hidden
if (slashLine) {
slashLine.style.display = 'none';
}
}
},
});

View file

@ -24,6 +24,63 @@
.auth-layout .auth-dialog .at-form input {
width: 100%;
}
.password-input-container {
position: relative;
display: flex;
align-items: center;
}
.password-input-container input {
flex: 1;
padding-right: 55px; /* More room for the bigger button */
box-sizing: border-box;
}
.password-toggle-btn {
position: absolute;
right: 5px; /* Adjusted for larger button */
top: calc(50% - 6px); /* Moved up by 6px total */
transform: translateY(-50%);
background: #f8f8f8 !important;
border: 1px solid #ddd !important;
border-radius: 3px !important;
color: #000 !important; /* Black color for the icon */
cursor: pointer;
padding: 8px 12px; /* 2x bigger padding */
font-size: 16px; /* 2x bigger font size */
width: auto !important;
height: auto !important;
line-height: 1;
display: flex !important;
align-items: center;
justify-content: center;
z-index: 10;
min-width: 40px; /* 2x bigger minimum width */
min-height: 32px; /* 2x bigger minimum height */
}
.password-toggle-btn .eye-text {
color: #000 !important;
font-size: 16px !important;
line-height: 1;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0.8;
}
.eye-slash-line {
position: absolute;
top: 10px;
left: 10px;
width: 20px;
height: 20px;
pointer-events: none;
stroke: #000;
stroke-width: 2;
fill: none;
}
.password-toggle-btn:hover .eye-text {
color: #000 !important;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0.8;
}
.auth-layout .auth-dialog .at-form button {
width: 100%;
background: #216694;

View file

@ -3,6 +3,7 @@ import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
const passwordField = AccountsTemplates.removeField('password');
passwordField.autocomplete = 'current-password';
passwordField.template = 'passwordInput';
const emailField = AccountsTemplates.removeField('email');
let disableRegistration = false;
let disableForgotPassword = false;
@ -70,6 +71,7 @@ AccountsTemplates.addFields([
required: true,
minLength: 6,
autocomplete: 'new-password',
template: 'passwordInput',
},
{
_id: 'invitationcode',