Add password visibility toggle to login form
- Implement show/hide password functionality with eye icon toggle button - Add dynamic input type switching between password and text - Position toggle button inside password input field with proper styling - Include hover, focus states and accessibility features (tabindex, title) - Use FontAwesome eye/eye-slash icons for visual feedback - Maintain secure default (password hidden) with optional visibility - Integrate proper tab order with existing form elements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,9 @@ pub fn Login(props: &LoginProps) -> Html {
|
|||||||
let remember_server = use_state(|| true);
|
let remember_server = use_state(|| true);
|
||||||
let remember_username = use_state(|| true);
|
let remember_username = use_state(|| true);
|
||||||
|
|
||||||
|
// Password visibility toggle
|
||||||
|
let show_password = use_state(|| false);
|
||||||
|
|
||||||
let server_url_ref = use_node_ref();
|
let server_url_ref = use_node_ref();
|
||||||
let username_ref = use_node_ref();
|
let username_ref = use_node_ref();
|
||||||
let password_ref = use_node_ref();
|
let password_ref = use_node_ref();
|
||||||
@@ -98,6 +101,13 @@ pub fn Login(props: &LoginProps) -> Html {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let on_toggle_password_visibility = {
|
||||||
|
let show_password = show_password.clone();
|
||||||
|
Callback::from(move |_| {
|
||||||
|
show_password.set(!*show_password);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
let on_submit = {
|
let on_submit = {
|
||||||
let server_url = server_url.clone();
|
let server_url = server_url.clone();
|
||||||
let username = username.clone();
|
let username = username.clone();
|
||||||
@@ -242,16 +252,27 @@ pub fn Login(props: &LoginProps) -> Html {
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">{"Password"}</label>
|
<label for="password">{"Password"}</label>
|
||||||
<input
|
<div class="password-input-container">
|
||||||
ref={password_ref}
|
<input
|
||||||
type="password"
|
ref={password_ref}
|
||||||
id="password"
|
type={if *show_password { "text" } else { "password" }}
|
||||||
placeholder="Enter your password"
|
id="password"
|
||||||
value={(*password).clone()}
|
placeholder="Enter your password"
|
||||||
onchange={on_password_change}
|
value={(*password).clone()}
|
||||||
disabled={*is_loading}
|
onchange={on_password_change}
|
||||||
tabindex="3"
|
disabled={*is_loading}
|
||||||
/>
|
tabindex="3"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="password-toggle-btn"
|
||||||
|
onclick={on_toggle_password_visibility}
|
||||||
|
tabindex="6"
|
||||||
|
title={if *show_password { "Hide password" } else { "Show password" }}
|
||||||
|
>
|
||||||
|
<i class={if *show_password { "fas fa-eye-slash" } else { "fas fa-eye" }}></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -534,6 +534,41 @@ body {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.password-input-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-input-container input {
|
||||||
|
padding-right: 3rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-toggle-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 0.75rem;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-toggle-btn:hover {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-toggle-btn:focus {
|
||||||
|
outline: none;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
.login-button, .register-button {
|
.login-button, .register-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--control-padding);
|
padding: var(--control-padding);
|
||||||
|
|||||||
Reference in New Issue
Block a user