Forms inputpassword

Password Toggle

Password field with reveal toggle.

Preview

Usage

Copy the full block below to use this component with its imports.

astro
---
import { PasswordToggle } from 'astro-component-kit';
---

<FloatingPassword id="pass" placeholder="Enter Secure Password" />
--- import { PasswordToggle } from 'astro-component-kit'; --- <FloatingPassword id="pass" placeholder="Enter Secure Password" />

Manual Installation

If you are not using the npm package, create a new file src/components/lib/PasswordToggle.astro and paste the following code:

astro
---
/**
 * FloatingPassword — A password input field featuring a reveal/hide toggle inside the frame.
 * 
 * @param {string} id - Unique identifier linking toggle state securely.
 * @param {string} placeholder - Default text visible when empty. Default is "Password".
 * @param {string} name - HTML name binding.
 * @param {boolean} required - HTML required indicator.
 */
interface Props {
  id: string;
  placeholder?: string;
  name?: string;
  required?: boolean;
}

const { id, placeholder = "Password", name, required = false } = Astro.props;
---

<div class="pass-wrap">
  <input type="password" {id} {name} {placeholder} {required} class="pass-input" data-pwd-input />
  <button type="button" class="toggle-pass" aria-label="Toggle password visibility" data-pwd-toggle>👁️</button>
</div>

<style>
  .pass-wrap { position: relative; width: 100%; }
  .pass-input { 
    width: 100%; box-sizing: border-box;
    padding: 0.8rem 3rem 0.8rem 1rem; 
    background: var(--c-bg-elev, rgba(0,0,0,0.2)); 
    border: 1px solid var(--c-border, rgba(255,255,255,0.1)); 
    border-radius: var(--r-sm, 10px); 
    color: var(--c-text-1, #fff); outline: none; 
    font-family: inherit; transition: 0.2s;
  }
  .pass-input:focus { border-color: var(--c-primary, #6366f1); }
  .toggle-pass { 
    position: absolute; right: 10px; top: 50%; transform: translateY(-50%); 
    background: none; border: none; cursor: pointer; opacity: 0.5; transition: 0.2s;
  }
  .toggle-pass:hover { opacity: 1; }
</style>

<script>
  // Setup functional toggle without polluting global namespaces or clashing IDs
  document.querySelectorAll('.pass-wrap').forEach(wrap => {
    const btn = wrap.querySelector('[data-pwd-toggle]');
    const pass = wrap.querySelector('[data-pwd-input]') as HTMLInputElement;
    
    if (btn && pass) {
      btn.addEventListener('click', () => {
        const isPass = pass.type === 'password';
        pass.type = isPass ? 'text' : 'password';
        btn.textContent = isPass ? '🙈' : '👁️';
      });
    }
  });
</script>
--- /** * FloatingPassword — A password input field featuring a reveal/hide toggle inside the frame. * * @param {string} id - Unique identifier linking toggle state securely. * @param {string} placeholder - Default text visible when empty. Default is "Password". * @param {string} name - HTML name binding. * @param {boolean} required - HTML required indicator. */ interface Props { id: string; placeholder?: string; name?: string; required?: boolean; } const { id, placeholder = "Password", name, required = false } = Astro.props; --- <div class="pass-wrap"> <input type="password" {id} {name} {placeholder} {required} class="pass-input" data-pwd-input /> <button type="button" class="toggle-pass" aria-label="Toggle password visibility" data-pwd-toggle>👁️</button> </div> <style> .pass-wrap { position: relative; width: 100%; } .pass-input { width: 100%; box-sizing: border-box; padding: 0.8rem 3rem 0.8rem 1rem; background: var(--c-bg-elev, rgba(0,0,0,0.2)); border: 1px solid var(--c-border, rgba(255,255,255,0.1)); border-radius: var(--r-sm, 10px); color: var(--c-text-1, #fff); outline: none; font-family: inherit; transition: 0.2s; } .pass-input:focus { border-color: var(--c-primary, #6366f1); } .toggle-pass { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; opacity: 0.5; transition: 0.2s; } .toggle-pass:hover { opacity: 1; } </style> <script> // Setup functional toggle without polluting global namespaces or clashing IDs document.querySelectorAll('.pass-wrap').forEach(wrap => { const btn = wrap.querySelector('[data-pwd-toggle]'); const pass = wrap.querySelector('[data-pwd-input]') as HTMLInputElement; if (btn && pass) { btn.addEventListener('click', () => { const isPass = pass.type === 'password'; pass.type = isPass ? 'text' : 'password'; btn.textContent = isPass ? '🙈' : '👁️'; }); } }); </script>

Quick Info

Category
Forms
Filename
PasswordToggle.astro
Dependencies
None — pure Astro + CSS
Tags
inputpassword