npm package: @spacelr/auth-components
Description: Spacelr Auth Web Components - login, register, 2FA, social providers, profile management
Latest version: 0.0.5

# @spacelr/auth-components

Drop-in web components for authentication flows — login, registration, 2FA, social providers, password reset, and profile management. Built with [Stencil](https://stenciljs.com/) so they work in any framework (React, Angular, Vue, Svelte) or plain HTML.

## Install

```bash
npm install @spacelr/auth-components
```

## Setup

Initialize once before using any component:

```typescript
import { initAuthComponents } from '@spacelr/auth-components';
import { defineCustomElements } from '@spacelr/auth-components/loader';

initAuthComponents({
  baseUrl: 'https://api.example.com/api/v1',
  clientId: 'your-client-id',
  projectId: 'your-project-id',
  theme: {
    primaryColor: '#3880ff',
    borderRadius: '8px',
  },
});

defineCustomElements();
```

## Components

### `<auth-login>`

Email/password sign-in form with optional links to registration and password reset. Handles 2FA handoff automatically.

```html
<auth-login
  card-title="Sign In"
  show-forgot-password="true"
  show-register-link="true"
></auth-login>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `cardTitle` | `string` | `'Sign In'` | Form heading |
| `submitLabel` | `string` | `'Sign In'` | Button text |
| `showForgotPassword` | `boolean` | `true` | Show forgot password link |
| `showRegisterLink` | `boolean` | `true` | Show create account link |
| `emailPlaceholder` | `string` | `'Email address'` | Email field placeholder |
| `passwordPlaceholder` | `string` | `'Password'` | Password field placeholder |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `authSuccess` | `LoginSuccessPayload` | Login succeeded (contains user, tokens) |
| `authError` | `AuthErrorPayload` | Login failed |
| `forgotPasswordClick` | `void` | User clicked forgot password link |
| `registerClick` | `void` | User clicked create account link |

---

### `<auth-register>`

Registration form with email, username, password, and optional name fields. Supports email verification flows.

```html
<auth-register
  show-name-fields="true"
  show-login-link="true"
></auth-register>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `cardTitle` | `string` | `'Create Account'` | Form heading |
| `submitLabel` | `string` | `'Create Account'` | Button text |
| `showLoginLink` | `boolean` | `true` | Show back to login link |
| `showNameFields` | `boolean` | `true` | Show first/last name fields |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `authSuccess` | `RegisterSuccessPayload` | Registration succeeded |
| `authError` | `AuthErrorPayload` | Registration failed |
| `emailVerificationRequired` | `EmailVerificationPayload` | Email verification needed before login |
| `loginClick` | `void` | User clicked back to login link |

---

### `<auth-two-factor>`

6-digit OTP verification form shown after initial login when 2FA is enabled.

```html
<auth-two-factor
  two-factor-token="token-from-login-response"
></auth-two-factor>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `twoFactorToken` | `string` | *required* | Session token from login response |
| `cardTitle` | `string` | `'Verify Your Identity'` | Form heading |
| `submitLabel` | `string` | `'Verify'` | Button text |
| `resendStatus` | `'idle' \| 'sending' \| 'sent' \| 'error'` | `'idle'` | Status of resend attempt |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `authSuccess` | `LoginSuccessPayload` | 2FA verification succeeded |
| `authError` | `AuthErrorPayload` | Verification failed |
| `resendRequested` | `void` | User requested code resend |

---

### `<auth-social-providers>`

Social login buttons (Google, GitHub, Apple, Microsoft). Supports popup and redirect OAuth flows.

```html
<auth-social-providers
  ux-mode="popup"
></auth-social-providers>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `uxMode` | `'popup' \| 'redirect'` | `'popup'` | OAuth flow mode |
| `redirectUri` | `string` | — | Required when `uxMode='redirect'` |
| `scopes` | `string` | `'openid email profile'` | OAuth scopes |
| `useNativeFlow` | `boolean` | `false` | Skip web script loading, use native flow |
| `disabled` | `boolean` | `false` | Disable buttons |

| Event | Payload | Description |
|-------|---------|-------------|
| `authSuccess` | `LoginSuccessPayload` | Social login succeeded |
| `authError` | `AuthErrorPayload` | Social login failed |
| `providersLoaded` | `{ hasProviders: boolean }` | Provider configuration loaded |
| `googleLoginRequested` | `void` | Google login requested (native flow) |

---

### `<auth-forgot-password>`

Password reset request form. Sends a reset link to the provided email address.

```html
<auth-forgot-password
  show-back-to-login="true"
></auth-forgot-password>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `cardTitle` | `string` | `'Reset Password'` | Form heading |
| `submitLabel` | `string` | `'Reset Password'` | Button text |
| `description` | `string` | `'Enter your email...'` | Help text |
| `emailPlaceholder` | `string` | `'Email address'` | Input placeholder |
| `showBackToLogin` | `boolean` | `true` | Show back link |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `resetRequestSuccess` | `ResetRequestSuccessPayload` | Reset email sent |
| `resetRequestError` | `AuthErrorPayload` | Request failed |
| `backToLoginClick` | `void` | User clicked back to login |

---

### `<auth-reset-password>`

New password form used after clicking the reset link from email. Requires the token from the URL.

```html
<auth-reset-password
  token="reset-token-from-url"
></auth-reset-password>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `token` | `string` | `''` | Reset token from the email link |
| `cardTitle` | `string` | `'Set New Password'` | Form heading |
| `submitLabel` | `string` | `'Set New Password'` | Button text |
| `description` | `string` | `'Enter your new password below.'` | Help text |
| `showBackToLogin` | `boolean` | `true` | Show back link |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `resetPasswordSuccess` | `ResetPasswordSuccessPayload` | Password changed |
| `resetPasswordError` | `AuthErrorPayload` | Reset failed |
| `backToLoginClick` | `void` | User clicked back to login |

---

### `<auth-profile-edit>`

Profile editing form for authenticated users. Updates first name, last name, and display name.

```html
<auth-profile-edit
  .user=${currentUser}
  access-token="jwt-token"
></auth-profile-edit>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `user` | `AuthUser` | *required* | Current user data to prefill |
| `accessToken` | `string` | *required* | JWT for authenticated API calls |
| `cardTitle` | `string` | `'Edit Profile'` | Form heading |
| `submitLabel` | `string` | `'Save Changes'` | Button text |
| `disabled` | `boolean` | `false` | Disable form inputs |

| Event | Payload | Description |
|-------|---------|-------------|
| `profileUpdateSuccess` | `ProfileUpdateSuccessPayload` | Profile saved |
| `profileUpdateError` | `AuthErrorPayload` | Update failed |

---

### `<auth-logout-button>`

Logout button with optional confirmation dialog.

```html
<auth-logout-button
  confirm-logout="true"
  color="danger"
  fill="clear"
></auth-logout-button>
```

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `label` | `string` | `'Logout'` | Button text |
| `accessToken` | `string` | — | Token for logout API call |
| `color` | `string` | `'danger'` | Ionic color name |
| `fill` | `'clear' \| 'outline' \| 'solid'` | `'clear'` | Button style |
| `size` | `'small' \| 'default' \| 'large'` | `'default'` | Button size |
| `confirmLogout` | `boolean` | `false` | Show confirmation dialog |
| `confirmMessage` | `string` | `'Are you sure...'` | Dialog message |
| `disabled` | `boolean` | `false` | Disable button |

| Event | Payload | Description |
|-------|---------|-------------|
| `logoutRequested` | `void` | Logout confirmed |
| `logoutCancelled` | `void` | User cancelled logout |

## Configuration

### Theme

Customize appearance via the `theme` option:

```typescript
initAuthComponents({
  baseUrl: 'https://api.example.com/api/v1',
  theme: {
    primaryColor: '#6200ee',
    errorColor: '#cf6679',
    successColor: '#03dac5',
    borderRadius: '12px',
    fontFamily: '"Inter", sans-serif',
  },
});
```

### Custom Endpoints

Override default API paths:

```typescript
initAuthComponents({
  baseUrl: 'https://api.example.com/api/v1',
  endpoints: {
    login: '/auth/login',           // default
    register: '/auth/register',     // default
    forgotPassword: '/auth/forgot-password',
    resetPassword: '/auth/reset-password',
    profile: '/auth/me',
    logout: '/auth/logout',
    refresh: '/auth/refresh',
  },
});
```

## Events

All components emit typed CustomEvents. Listen in any framework:

```javascript
// Vanilla JS
document.querySelector('auth-login').addEventListener('authSuccess', (e) => {
  const { user, accessToken } = e.detail;
  console.log('Logged in as', user.email);
});

// React (via ref)
loginRef.current.addEventListener('authSuccess', handleLogin);

// Angular
<auth-login (authSuccess)="onLogin($event)"></auth-login>
```

## Validation

Built-in Zod schemas are available for custom form implementations:

```typescript
import { loginSchema, registerSchema, getFirstError } from '@spacelr/auth-components';

const result = loginSchema.safeParse({ email, password });
if (!result.success) {
  console.log(getFirstError(result.error));
}
```

## License

MIT