CredentialLoginCard UI component
Purpose
CredentialLoginCardChecked renders a reusable credential entry card for
email/password, token, or one-time-code sign-in. CredentialLoginCard remains
the string-returning compatibility wrapper for existing callers.
Inputs
| Field | Required | Type | Behavior |
|---|---|---|---|
ID |
yes | string |
Stable source identifier used as SourceID in callbacks and for derived field ids. |
Title |
no | string |
Panel heading; defaults to Sign in. |
Copy |
no | string |
Escaped public helper text above the form. |
FormMethod |
no | FormMethod |
Must be FormMethodPost; empty normalizes to POST. |
FormAction |
no | string |
Optional app-relative or same-origin action; schemes, protocol-relative URLs, backslashes, navigation whitespace, and .. path segments are rejected. |
FormTarget |
no | string |
Optional safe target; _self, _blank, _parent, _top, or named targets using letters, digits, -, ., or : are accepted. |
FormAttrs |
no | map[string]string |
Extra form attributes; method, action, target, and data-ui-action are normalized with the explicit form props taking precedence. |
SubmitAction |
no | string |
Submit routing token; defaults to credential.submit when OnSubmit is set and no form data-ui-action is supplied. |
RequestAction |
no | string |
Secondary request routing token; defaults to credential.request when OnRequest is set and no request control action is supplied. |
OnSubmit |
yes for interactive submit | func(CredentialSubmitEvent) |
Receives source and submit routing metadata without credential values. |
OnRequest |
no | func(CredentialRequestEvent) |
Enables a secondary request-code control. |
RequestLabel |
no | string |
Secondary control label; defaults to Send code. |
Request |
no | ButtonProps |
Secondary control props; Request.Control.Action or Request.Attrs["data-ui-action"] can override RequestAction. |
UsernameLabel |
yes | string |
Public label for the username field. |
UsernameName |
no | string |
Submitted username field name; defaults to username. |
UsernameType |
no | string |
Input type such as email; defaults to text. |
UsernameAutocomplete |
no | string |
Browser autocomplete token such as username or email; defaults to username. |
PasswordLabel |
yes | string |
Public label for the secret/code field. |
PasswordName |
no | string |
Submitted secret field name; defaults to password. |
PasswordAutocomplete |
no | string |
Autocomplete token such as one-time-code. |
Submit |
no | ButtonProps |
Submit button props; the button is rendered as native type="submit". |
Busy, ErrorText, ErrorID
|
no | mixed | Shared form busy and safe error display state. |
Boundary
The component only collects credentials and dispatches events. Auth APIs must perform credential validation, OTP/token checks, rate limiting, session creation, and authorization policy.
Events identify the card source and public routing metadata. Credential values stay in browser form controls and host-owned controller state; they are never copied into callback payloads, public markup, logs, or diagnostics.
Example
package loginui
import (
"context"
"github.com/busdk/bus-ui/pkg/uikit"
)
type CredentialState interface {
Username(sourceID string) string
Secret(sourceID string) string
}
type AuthClient interface {
SendCode(ctx context.Context, username string) error
VerifyCode(ctx context.Context, username string, secret string) error
}
type ErrorSink interface {
ShowProviderError(sourceID string, err error)
}
var loginState CredentialState
var authClient AuthClient
var loginErrors ErrorSink
var requestContext func(sourceID string) context.Context
func requestOTP(event uikit.CredentialRequestEvent) {
ctx := requestContext(event.SourceID)
username := loginState.Username(event.SourceID)
if err := authClient.SendCode(ctx, username); err != nil {
loginErrors.ShowProviderError(event.SourceID, err)
}
}
func verifyOTP(event uikit.CredentialSubmitEvent) {
ctx := requestContext(event.SourceID)
username := loginState.Username(event.SourceID)
secret := loginState.Secret(event.SourceID)
if err := authClient.VerifyCode(ctx, username, secret); err != nil {
loginErrors.ShowProviderError(event.SourceID, err)
}
}
func OTPLoginCard() (string, error) {
return uikit.CredentialLoginCardChecked(uikit.CredentialLoginCardProps{
ID: "otp-login",
Title: "Sign in",
Copy: "Use your work email and one-time code.",
FormAction: "/auth/login",
OnRequest: requestOTP,
OnSubmit: verifyOTP,
RequestLabel: "Send one-time code",
UsernameLabel: "Email",
UsernameName: "email",
UsernameType: string(uikit.InputTypeEmail),
UsernameAutocomplete: "email",
PasswordLabel: "One-time code",
PasswordName: "code",
PasswordAutocomplete: "one-time-code",
Submit: uikit.ButtonProps{
Label: "Continue",
},
})
}
authClient and loginState are application-owned. Callback code uses the
event SourceID to read host-owned credential state for that card, then sends
the provider request outside bus-ui.
Rendering Terms
CredentialLoginCardChecked fails before render when required labels are
missing, the card id is unsafe, the form method is not POST, the action or
target is unsafe, or an action token is invalid. Submit action tokens come from
SubmitAction first, then FormAttrs["data-ui-action"]; request action
tokens come from RequestAction, then Request.Control.Action, then
Request.Attrs["data-ui-action"]. A valid token is a non-empty string using
letters, digits, -, _, ., /, or :. The compatibility
CredentialLoginCard wrapper keeps historical defaults for callers that still
need a string-only render path.