# LoginForm

`<allegro-login-form>` is a web component that authenticates readers via a magic login link sent to their email, or via Google and Apple OAuth. On mobile the email input and button stack vertically; on wider screens (≥50em) they sit inline.

## Usage[​](#usage "Direct link to Usage")

```html
<allegro-login-form></allegro-login-form>

```

Customise the text labels via HTML attributes:

```html
<allegro-login-form
    placeholder-text="Your email"
    submit-text="Get my link"
    publisher-name="LAist"
    continue-text="Keep Reading"
    hide-third-party="true"
></allegro-login-form>

```

## Attributes[​](#attributes "Direct link to Attributes")

| Attribute          | Type      | Default            | Description                                                                                  |
| ------------------ | --------- | ------------------ | -------------------------------------------------------------------------------------------- |
| `placeholder-text` | `text`    | `Enter your email` | Placeholder shown inside the email input.                                                    |
| `submit-text`      | `text`    | `Send Login Link`  | Label for the magic-link submit button.                                                      |
| `hide-third-party` | `boolean` | `false`            | Set to `true` to hide the Google and Apple social login buttons.                             |
| `publisher-name`   | `text`    | *(empty)*          | Publisher name shown in the success state, e.g. "Welcome back to LAist!"                     |
| `continue-text`    | `text`    | *(empty)*          | Override the continue button label in the success state.                                     |
| `learn-more-url`   | `text`    | *(empty)*          | URL to navigate to when the continue button is clicked in success state.                     |
| `tracking-data`    | `text`    | *(empty)*          | JSON object of custom data merged into every tracked event, e.g. `"{'campaign': 'header'}"`. |

## States[​](#states "Direct link to States")

The component progresses through four states as the magic-link flow advances:

| State       | Trigger                                                                             | Description                                          |
| ----------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `email`     | Initial render (unauthenticated, no token in URL)                                   | Email input + social login buttons.                  |
| `loading`   | Initial render when `allegro_token` is present in the URL                           | Spinner shown while the SDK validates the token.     |
| `success`   | Initial render (already authenticated), or `allegro:magic-link:authenticated` fires | Checkmark + "Welcome back" with a continue button.   |
| `link-sent` | `allegro:login-form:magic-link:sent` fires                                          | "Check your email inbox" with a resend option.       |
| `expired`   | `allegro:magic-link:failed` fires                                                   | "Your link has expired" with a send-new-link button. |

If the user is already signed in when the component renders, it skips straight to the `success` state.

## Events[​](#events "Direct link to Events")

### Dispatched by this component[​](#dispatched-by-this-component "Direct link to Dispatched by this component")

| Name                                           | Bubbles | Detail                                                    | Description                                                                                                                                  |
| ---------------------------------------------- | ------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `allegro:login-form:magic-link:sent`           | yes     | `{ email: string, data?: Record<string, unknown> }`       | Fired after a magic link is successfully sent. Triggers the `link-sent` state.                                                               |
| `allegro:login-form:authenticated`             | yes     | *(none)*                                                  | Fired on both auth flows (magic link and social) before the flow-specific event.                                                             |
| `allegro:login-form:magic-link:authenticated`  | yes     | *(none)*                                                  | Fired after a magic link is validated successfully. Follows `allegro:login-form:authenticated`.                                              |
| `allegro:login-form:third-party:authenticated` | yes     | `{ provider: string, session_id: string, token: string }` | Fired after a successful Google or Apple login. Follows `allegro:login-form:authenticated`. `provider` is the provider name (e.g. `google`). |
| `allegro:login-form:continue`                  | yes     | *(none)*                                                  | Fired when the user clicks the continue button in the success state.                                                                         |

### Listened to by this component (on `window`)[​](#listened-to-by-this-component-on-window "Direct link to listened-to-by-this-component-on-window")

| Name                               | Detail              | Description                                                                                                      |
| ---------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `allegro:magic-link:authenticated` | *(none)*            | Dispatched by the SDK after a magic link is validated successfully. Transitions to the `success` state.          |
| `allegro:magic-link:failed`        | `{ error: string }` | Dispatched by the SDK when magic link validation fails (e.g. expired token). Transitions to the `expired` state. |

## Slots[​](#slots "Direct link to Slots")

| Slot name        | Appears in state | Description                                                                                                                                                                                                              |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `header`         | `email`          | Rendered above the email input. Use for a title or description. Hidden once the form transitions to another state.                                                                                                       |
| `footer`         | `email`          | Rendered below the email input (and social buttons when present). Use for supplementary links. Hidden once the form transitions to another state.                                                                        |
| `after-form`     | `email`          | Rendered between the email input and the social login buttons. Use for supplementary inputs such as newsletter opt-in checkboxes. Values from named inputs inside this slot are included in the magic link request data. |
| `success`        | `success`        | Replaces the entire success state UI (icon, heading, body, and continue button). When omitted, the default success UI is shown as fallback content.                                                                      |
| `after-continue` | `success`        | Rendered directly below the continue button in the default success UI. Ignored when the `success` slot is provided.                                                                                                      |

```html
<allegro-login-form publisher-name="LAist">
    <div slot="header">
        <h2>Sign in to continue</h2>
        <p>Access your account below.</p>
    </div>
    <p slot="footer">
        <a href="/register">Don't have an account? Sign up</a>
    </p>
</allegro-login-form>

```

To override the entire success state:

```html
<allegro-login-form publisher-name="LAist">
    <div slot="success">
        <h2>You're in!</h2>
        <p>Redirecting you now…</p>
    </div>
</allegro-login-form>

```

## Tracked Events[​](#tracked-events "Direct link to Tracked Events")

The component records the following events via the Allegro SDK.

| Event                  | When                                                                              | Data     |
| ---------------------- | --------------------------------------------------------------------------------- | -------- |
| `magic-link-requested` | Fired when the user successfully resends a magic link from the `link-sent` state. | *(none)* |

## CSS Variables[​](#css-variables "Direct link to CSS Variables")

All visual properties are exposed as CSS custom properties so the component can be themed from the host page without piercing the shadow DOM.

```css
allegro-login-form {
    --loginForm--input--background: #fff;
    --loginForm--submit--background: #1a1a1a;
}

```

### General[​](#general "Direct link to General")

| Variable                   | Default                 | Description                                  |
| -------------------------- | ----------------------- | -------------------------------------------- |
| `--loginForm--color`       | `black`                 | Base text colour for the component.          |
| `--loginForm--font-family` | `system-ui, sans-serif` | Font family applied to the entire component. |

### Input[​](#input "Direct link to Input")

| Variable                                 | Default          | Description                              |
| ---------------------------------------- | ---------------- | ---------------------------------------- |
| `--loginForm--input--background`         | `#fff`           | Input background colour.                 |
| `--loginForm--input--border`             | `1px solid #ccc` | Input border shorthand.                  |
| `--loginForm--input--border-radius`      | `0.375rem`       | Corner radius applied to the input.      |
| `--loginForm--input--font-size`          | `1rem`           | Input text size.                         |
| `--loginForm--input--padding`            | `0.75rem 1rem`   | Input padding shorthand.                 |
| `--loginForm--input--focus-border-color` | `#555`           | Border colour when the input is focused. |

### Submit button[​](#submit-button "Direct link to Submit button")

| Variable                              | Default           | Description                                                   |
| ------------------------------------- | ----------------- | ------------------------------------------------------------- |
| `--loginForm--submit--background`     | `#000`            | Button background colour.                                     |
| `--loginForm--submit--color`          | `#fff`            | Button text colour.                                           |
| `--loginForm--submit--border-radius`  | `0.375rem`        | Corner radius applied to the button.                          |
| `--loginForm--submit--font-size`      | `0.875rem`        | Button text size.                                             |
| `--loginForm--submit--font-weight`    | `700`             | Button font weight.                                           |
| `--loginForm--submit--font-family`    | `inherit`         | Button font family. Inherits the surrounding font by default. |
| `--loginForm--submit--padding`        | `0.75rem 1.25rem` | Button padding shorthand.                                     |
| `--loginForm--submit--text-transform` | `uppercase`       | CSS `text-transform` applied to button label.                 |

### Divider[​](#divider "Direct link to Divider")

| Variable                           | Default        | Description                                  |
| ---------------------------------- | -------------- | -------------------------------------------- |
| `--loginForm--divider--color`      | `#333`         | Text and line colour for the "OR" divider.   |
| `--loginForm--divider--line-color` | `currentColor` | Override only the line colour independently. |
| `--loginForm--divider--margin`     | `1rem 0`       | Vertical spacing around the divider.         |

### Social buttons[​](#social-buttons "Direct link to Social buttons")

| Variable                                | Default             | Description                                                                             |
| --------------------------------------- | ------------------- | --------------------------------------------------------------------------------------- |
| `--loginForm--social--background`       | `#fff`              | Social button background colour.                                                        |
| `--loginForm--social--hover-background` | `#f9fafb`           | Social button background on hover.                                                      |
| `--loginForm--social--border`           | `1px solid #d1d5db` | Social button border shorthand.                                                         |
| `--loginForm--social--border-radius`    | `0.5rem`            | Social button corner radius.                                                            |
| `--loginForm--social--color`            | `#111`              | Social button text colour.                                                              |
| `--loginForm--social--font-family`      | `inherit`           | Social button font family. Inherits the surrounding font by default.                    |
| `--loginForm--social--font-size`        | `1rem`              | Social button text size.                                                                |
| `--loginForm--social--line-height`      | `1.25`              | Social button line height.                                                              |
| `--loginForm--social--height`           | `42px`              | Minimum button height below the 640px breakpoint (stacked).                             |
| `--loginForm--social--height-desktop`   | `48px`              | Minimum button height at 640px and above (side-by-side).                                |
| `--loginForm--social--padding`          | `0.5rem 1rem`       | Social button padding shorthand.                                                        |
| `--loginForm--social--gap`              | `0.5rem`            | Gap between social buttons when stacked; same value applies in the side-by-side layout. |

### Loading spinner[​](#loading-spinner "Direct link to Loading spinner")

| Variable                            | Default        | Description                                                    |
| ----------------------------------- | -------------- | -------------------------------------------------------------- |
| `--loginForm--loading--track-color` | `currentColor` | Spinner colour. Inherits the component text colour by default. |

### State screens (link-sent, success, expired)[​](#state-screens-link-sent-success-expired "Direct link to State screens (link-sent, success, expired)")

| Variable                                  | Default     | Description                                                                   |
| ----------------------------------------- | ----------- | ----------------------------------------------------------------------------- |
| `--loginForm--state-icon--background`     | `#111`      | Background colour of the circular state icon.                                 |
| `--loginForm--state-heading--color`       | `#111`      | Heading text colour.                                                          |
| `--loginForm--state-heading--font-size`   | `1.25rem`   | Heading font size.                                                            |
| `--loginForm--state-heading--font-weight` | `700`       | Heading font weight.                                                          |
| `--loginForm--state-body--color`          | `#555`      | Body and disclaimer text colour.                                              |
| `--loginForm--state-body--font-size`      | `0.9375rem` | Body text size.                                                               |
| `--loginForm--resend--color`              | `#555`      | Resend link text colour.                                                      |
| `--loginForm--resend--hover-color`        | `#111`      | Resend link text colour on hover.                                             |
| `--loginForm--resend--font-size`          | `0.875rem`  | Resend link font size.                                                        |
| `--loginForm--resend-error--color`        | `#b91c1c`   | Text colour for the inline error shown below the resend/send-new-link button. |

### Error message[​](#error-message "Direct link to Error message")

| Variable                            | Default             | Description                                          |
| ----------------------------------- | ------------------- | ---------------------------------------------------- |
| `--loginForm--error--background`    | `#fef2f2`           | Error container background colour.                   |
| `--loginForm--error--border`        | `1px solid #fecaca` | Error container border shorthand.                    |
| `--loginForm--error--accent-color`  | `#dc2626`           | Left accent border colour.                           |
| `--loginForm--error--border-radius` | `0.375rem`          | Error container corner radius.                       |
| `--loginForm--error--color`         | `#b91c1c`           | Error message text colour.                           |
| `--loginForm--error--icon-color`    | `currentColor`      | Error icon colour (inherits text colour by default). |
| `--loginForm--error--padding`       | `0.625rem 0.875rem` | Error container padding.                             |

## Example: Dark Background[​](#example-dark-background "Direct link to Example: Dark Background")

When placing the component on a dark or coloured background, override the divider and social button colours so they read clearly:

```css
allegro-login-form {
    --loginForm--divider--color: rgba(255, 255, 255, 0.7);
    --loginForm--social--background: transparent;
    --loginForm--social--border: 1px solid rgba(255, 255, 255, 0.4);
    --loginForm--social--color: #fff;
    --loginForm--social--hover-background: rgba(255, 255, 255, 0.08);
}

```
