# PasswordEditor

A specialized password input component with visibility toggle functionality. Allows users to show/hide password text for better usability while maintaining security. Built on top of the CommonEditor base component.

## Installation

```bash
npm install @ticatec/uniface-element
```

## Import

```typescript
import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
```

## Basic Usage

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let password = '';
</script>

<PasswordEditor 
  bind:value={password} 
  placeholder="Enter password..."
/>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | `""` | Current password value |
| `disabled` | `boolean` | `false` | Whether the input is disabled |
| `readonly` | `boolean` | `false` | Whether the input is read-only |
| `variant` | `"" \| "plain" \| "outlined" \| "filled"` | `""` | Input visual variant |
| `compact` | `boolean` | `false` | Whether to use compact spacing |
| `style` | `string` | `""` | Additional CSS styles |
| `class` | `string` | `""` | CSS class name |
| `onfocus` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input gains focus |
| `onblur` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input loses focus |
| `onchange` | `((event: Event) => void) \| null` | `null` | Callback when value changes |

## Events

| Event | Description |
|-------|-------------|
| `focus` | Fired when input gains focus |
| `blur` | Fired when input loses focus |

## Examples

### Basic Password Input

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let password = '';
  let confirmPassword = '';
</script>

<div class="form-group">
  <label>Password:</label>
  <PasswordEditor bind:value={password} placeholder="Enter password" />
</div>

<div class="form-group">
  <label>Confirm Password:</label>
  <PasswordEditor bind:value={confirmPassword} placeholder="Confirm password" />
</div>

<style>
  .form-group {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
</style>
```

### With Event Handlers

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let password = '';
  let isFocused = false;
  
  function handleChange(event) {
    console.log('Password changed');
  }
  
  function handleFocus(event) {
    console.log('Password input focused');
    isFocused = true;
  }
  
  function handleBlur(event) {
    console.log('Password input blurred');
    isFocused = false;
  }
</script>

<PasswordEditor 
  bind:value={password}
  placeholder="Enter secure password..."
  onchange={handleChange}
  onfocus={handleFocus}
  onblur={handleBlur}
/>

{#if isFocused}
  <p>Password field is active</p>
{/if}
```

### Different Variants

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let pass1 = '', pass2 = '', pass3 = '';
</script>

<!-- Default variant -->
<PasswordEditor bind:value={pass1} placeholder="Default password" />

<!-- Outlined variant -->
<PasswordEditor bind:value={pass2} variant="outlined" placeholder="Outlined password" />

<!-- Filled variant -->
<PasswordEditor bind:value={pass3} variant="filled" placeholder="Filled password" />
```

### Disabled and Readonly States

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let normalPassword = '';
  let readonlyPassword = 'readonly-pass';
  let disabledPassword = '';
</script>

<!-- Normal password input -->
<PasswordEditor bind:value={normalPassword} placeholder="Normal password" />

<!-- Readonly password input -->
<PasswordEditor bind:value={readonlyPassword} readonly />

<!-- Disabled password input -->
<PasswordEditor bind:value={disabledPassword} disabled placeholder="Disabled password" />
```

### Compact Mode

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let compactPassword = '';
</script>

<div class="login-form">
  <PasswordEditor 
    bind:value={compactPassword} 
    compact 
    placeholder="Password" 
  />
</div>

<style>
  .login-form {
    max-width: 300px;
    padding: 16px;
    background: #f8f9fa;
    border-radius: 8px;
  }
</style>
```

### Login Form Example

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  import TextEditor from "@ticatec/uniface-element/TextEditor";
  import Button from "@ticatec/uniface-element/Button";
  
  let credentials = {
    username: '',
    password: ''
  };
  
  function handleLogin() {
    if (credentials.username && credentials.password) {
      console.log('Logging in...', credentials.username);
      // Perform login logic
    }
  }
  
  function handleKeydown(event) {
    if (event.key === 'Enter') {
      handleLogin();
    }
  }
</script>

<div class="login-container">
  <h2>Login</h2>
  
  <div class="form-field">
    <label>Username</label>
    <TextEditor 
      bind:value={credentials.username} 
      placeholder="Enter username"
      on:keydown={handleKeydown}
    />
  </div>
  
  <div class="form-field">
    <label>Password</label>
    <PasswordEditor 
      bind:value={credentials.password} 
      placeholder="Enter password"
      on:keydown={handleKeydown}
    />
  </div>
  
  <Button 
    type="primary" 
    label="Login" 
    onClick={handleLogin}
    disabled={!credentials.username || !credentials.password}
  />
</div>

<style>
  .login-container {
    max-width: 400px;
    margin: 0 auto;
    padding: 24px;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  h2 {
    text-align: center;
    margin-bottom: 24px;
  }
  
  .form-field {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
</style>
```

### Password Strength Indicator

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  
  let password = '';
  
  $: passwordStrength = calculateStrength(password);
  
  function calculateStrength(pass) {
    if (!pass) return { score: 0, label: '', color: '' };
    
    let score = 0;
    if (pass.length >= 8) score++;
    if (/[a-z]/.test(pass)) score++;
    if (/[A-Z]/.test(pass)) score++;
    if (/[0-9]/.test(pass)) score++;
    if (/[^A-Za-z0-9]/.test(pass)) score++;
    
    const labels = ['', 'Weak', 'Fair', 'Good', 'Strong', 'Very Strong'];
    const colors = ['', '#ff4444', '#ff8800', '#ffaa00', '#88cc00', '#44cc00'];
    
    return {
      score,
      label: labels[score],
      color: colors[score]
    };
  }
</script>

<div class="password-container">
  <label>Create Password</label>
  <PasswordEditor bind:value={password} placeholder="Enter a strong password" />
  
  {#if password}
    <div class="strength-indicator">
      <div class="strength-bar">
        <div 
          class="strength-fill" 
          style="width: {passwordStrength.score * 20}%; background-color: {passwordStrength.color}"
        ></div>
      </div>
      <span class="strength-label" style="color: {passwordStrength.color}">
        {passwordStrength.label}
      </span>
    </div>
  {/if}
  
  <div class="password-requirements">
    <p>Password should contain:</p>
    <ul>
      <li class:met={password.length >= 8}>At least 8 characters</li>
      <li class:met={/[a-z]/.test(password)}>Lowercase letter</li>
      <li class:met={/[A-Z]/.test(password)}>Uppercase letter</li>
      <li class:met={/[0-9]/.test(password)}>Number</li>
      <li class:met={/[^A-Za-z0-9]/.test(password)}>Special character</li>
    </ul>
  </div>
</div>

<style>
  .password-container {
    max-width: 400px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
  
  .strength-indicator {
    margin-top: 8px;
    display: flex;
    align-items: center;
    gap: 12px;
  }
  
  .strength-bar {
    flex: 1;
    height: 4px;
    background: #e0e0e0;
    border-radius: 2px;
    overflow: hidden;
  }
  
  .strength-fill {
    height: 100%;
    transition: width 0.3s ease, background-color 0.3s ease;
  }
  
  .strength-label {
    font-size: 12px;
    font-weight: 500;
  }
  
  .password-requirements {
    margin-top: 12px;
    font-size: 14px;
  }
  
  .password-requirements p {
    margin: 0 0 8px 0;
    font-weight: 500;
  }
  
  .password-requirements ul {
    margin: 0;
    padding-left: 20px;
  }
  
  .password-requirements li {
    color: #666;
    transition: color 0.3s ease;
  }
  
  .password-requirements li.met {
    color: #44cc00;
  }
</style>
```

### Registration Form

```svelte
<script>
  import { PasswordEditor } from "@ticatec/uniface-element/TextEditor";
  import TextEditor from "@ticatec/uniface-element/TextEditor";
  import Button from "@ticatec/uniface-element/Button";
  
  let formData = {
    email: '',
    password: '',
    confirmPassword: ''
  };
  
  $: passwordsMatch = formData.password && 
    formData.confirmPassword && 
    formData.password === formData.confirmPassword;
  
  $: isValid = formData.email && 
    formData.password && 
    passwordsMatch;
  
  function handleRegister() {
    if (isValid) {
      console.log('Registering user...', formData.email);
      // Perform registration logic
    }
  }
</script>

<div class="register-container">
  <h2>Create Account</h2>
  
  <div class="form-field">
    <label>Email</label>
    <TextEditor 
      bind:value={formData.email} 
      placeholder="Enter email address"
    />
  </div>
  
  <div class="form-field">
    <label>Password</label>
    <PasswordEditor 
      bind:value={formData.password} 
      placeholder="Create password"
    />
  </div>
  
  <div class="form-field">
    <label>Confirm Password</label>
    <PasswordEditor 
      bind:value={formData.confirmPassword} 
      placeholder="Confirm password"
    />
    {#if formData.confirmPassword && !passwordsMatch}
      <div class="error-message">Passwords do not match</div>
    {/if}
  </div>
  
  <Button 
    type="primary" 
    label="Create Account" 
    onClick={handleRegister}
    disabled={!isValid}
  />
</div>

<style>
  .register-container {
    max-width: 400px;
    margin: 0 auto;
    padding: 24px;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  h2 {
    text-align: center;
    margin-bottom: 24px;
  }
  
  .form-field {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
  
  .error-message {
    margin-top: 4px;
    color: #ff4444;
    font-size: 12px;
  }
</style>
```

## Features

- **Visibility Toggle**: Built-in eye icon to show/hide password text
- **Security**: Maintains password masking by default
- **Event Handling**: Custom focus, blur, and change event callbacks
- **Flexible Styling**: Multiple visual variants and custom styling
- **State Management**: Disabled and readonly states
- **Responsive**: Works well on all device sizes

## Behavior

1. **Default State**: Password text is hidden (masked)
2. **Toggle Visibility**: Click the eye icon to show/hide password
3. **Disabled/Readonly**: Eye icon is hidden when input is disabled or readonly
4. **Focus Management**: Proper focus handling for accessibility
5. **Input Type Switching**: Dynamically switches between `password` and `text` input types

## Security Considerations

- Password text is masked by default for security
- Visibility toggle helps with password entry accuracy
- No password content is logged or exposed in the component
- Follows standard password input security practices

## Accessibility

- Proper semantic HTML structure
- Keyboard navigation support
- Screen reader compatible
- Focus indicators and management
- Clear visual feedback for interaction states

## Best Practices

1. **Password Requirements**: Always provide clear password requirements
2. **Confirmation**: Use confirmation fields for new password creation
3. **Strength Indicators**: Consider adding password strength feedback
4. **Error Handling**: Provide clear validation messages
5. **Security**: Never store or log password values in plain text
6. **Accessibility**: Ensure proper labeling and keyboard navigation

## Browser Support

- Modern browsers with full input event support
- Compatible with Svelte 5+
- Touch-friendly interface
- Responsive design principles

## Related Components

- `TextEditor` - Basic text input component
- `SearchBox` - Search-specific input
- `NumberEditor` - Numeric input validation
- `Button` - For form submission and actions