# Login 03 - SSO-first (`login-03`) - SignalOS page block

> Minimal sign-in built around identity providers (Google, Microsoft, Okta, …) with an optional email magic-link fallback under an "or" divider.

- **Version:** 0.1.4
- **Kind:** block (group: login) · **Category:** pages
- **Install:** `npx shadcn@latest add @signalos/login-03`
- **Registry dependencies (pulled automatically):** @signalos/tokens, @signalos/utils, @signalos/button, @signalos/text-field
- **npm dependencies:** lucide-react@^1.7.0
- **Files installed:** `src/components/blocks/login-03/Login03.tsx`, `src/components/blocks/login-03/Login03.types.ts`

## Access

This is a private registry: pulling source requires a `SIGNALOS_REGISTRY_TOKEN`
(GitHub fine-grained PAT with read access to the signal-widgets repo) and an
`@signalos` entry in components.json `"registries"`. Previews and this document are public.

## Usage

```tsx
// after: npx shadcn@latest add @signalos/login-03
// mount the pulled page in a route, e.g. src/app/login/page.tsx
import { Login03 } from "@/components/blocks/login-03/Login03"

export default function Page() {
  return <Login03 />
}
```

## Props

### `LoginProvider`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `id` | `string` | yes | - | Stable id, also used in the button's data-testid. |
| `label` | `string` | yes | - | Button label, e.g. "Continue with Google". |
| `icon` | `ReactNode` | no | - | Provider mark (any ReactNode, typically a 16px logo). |
| `onClick` | `() => void` | yes | - |  |

### `Login03Props`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `brand` | `ReactNode` | no | - | Brand block above the form. |
| `title` | `string \| undefined` | no | `"Sign in to SignalOS"` |  |
| `subtitle` | `string \| undefined` | no | `"Choose how you want to continue."` |  |
| `providers` | `LoginProvider[]` | yes | - | SSO / OAuth providers rendered as buttons above the divider. |
| `onEmailContinue` | `((email: string) => void) \| undefined` | no | - | Email-only fallback under the divider; omit to render providers alone. |
| `isLoading` | `boolean \| undefined` | no | - |  |
| `error` | `string \| null \| undefined` | no | - |  |
| `footer` | `ReactNode` | no | - | Footer slot (terms, sign-up prompt). |
| `className` | `string \| undefined` | no | - |  |

## Changelog

# login-03

## 0.1.4

- Compose the `TextField` widget for the work-email input instead of
  hand-rolled `Label` + `Input` markup, matching the shared error/disabled/focus
  styling used across the registry. No prop, testid, or visual change.

## 0.1.3

- Use semantic status tokens (text-text-error, bg-bg-warning, border-border-*, bg-status-*) instead of raw palette scales so client theme overrides restyle status colors.


## 0.1.2

- Content sync fix to bring source in line with published registry payload.


## 0.1.1

- Standardize inline comment formatting (em dash → hyphen); no runtime or API change.

## 0.1.0

- Initial release: SSO-first sign-in with a generic `LoginProvider[]` prop
  (no vendor lock-in) and an optional email fallback form.
