release: WRNexusJS 0.5.10
This commit is contained in:
@@ -36,13 +36,9 @@ component AuthenticatorSetup {
|
||||
novalidate
|
||||
class='mt-5 space-y-4 {credentialId == "" ? "" : "hidden"}'
|
||||
>
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-authenticator-label" class="block text-sm font-medium">Authenticator name</label>
|
||||
<input id="auth-authenticator-label" name="label" value="Authenticator" autocomplete="off" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3" />
|
||||
<p data-error="label" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input id="auth-authenticator-label" name="label" label="Authenticator name" value="Authenticator" autocomplete="off" icon="icon-[lucide--smartphone]" color="{color}" size="{size}" />
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] text-sm font-semibold text-white disabled:opacity-60">{setupLabel}</button>
|
||||
<Button type="submit" label="{setupLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
|
||||
<div data-auth-authenticator-details class='{credentialId == "" ? "hidden" : ""}'>
|
||||
@@ -53,15 +49,11 @@ component AuthenticatorSetup {
|
||||
</div>
|
||||
<form method="post" action='{action}' data-schema='{schema}' data-auth-authenticator-confirm novalidate class="mt-5 space-y-4">
|
||||
<input type="hidden" name="credentialId" value='{credentialId}' />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-authenticator-code" class="block text-sm font-medium">Authenticator code</label>
|
||||
<input id="auth-authenticator-code" name="code" inputmode="numeric" autocomplete="one-time-code" maxlength="6" class="h-12 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-center text-xl tracking-[0.35em]" />
|
||||
<p data-error="code" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<PinInput label="Authenticator code" name="code" length="6" inputMode="numeric" autocomplete="one-time-code" color="{color}" size="{size}" />
|
||||
<p data-error="credentialId" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] text-sm font-semibold text-white disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -5,6 +5,7 @@ component ForgotPassword {
|
||||
title = "Recover your account"
|
||||
description = "Enter your email, phone, or username."
|
||||
identifierLabel = "Account identifier"
|
||||
identifierPlaceholder = "Enter your registered email, mobile number, or username"
|
||||
submitLabel = "Send recovery link"
|
||||
successMessage = "If an account matches, a recovery link has been sent."
|
||||
signInHref = "/sign-in"
|
||||
@@ -17,14 +18,11 @@ component ForgotPassword {
|
||||
<h1 class="m-0 text-2xl font-semibold">{title}</h1>
|
||||
<p class="mt-2 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<form method="post" action='{action}' data-schema='{schema}' novalidate class="mt-6 space-y-4">
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-recovery-identifier" class="block text-sm font-medium">{identifierLabel}</label>
|
||||
<input id="auth-recovery-identifier" name="identifier" autocomplete="username" aria-describedby="auth-recovery-identifier-error" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-sm outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p id="auth-recovery-identifier-error" data-error="identifier" role="alert" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input id="auth-recovery-identifier" name="identifier" label="{identifierLabel}" autocomplete="username" placeholder="{identifierPlaceholder}" icon="icon-[lucide--at-sign]" color="{color}" size="{size}" />
|
||||
<slot></slot>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
<a href='{signInHref}' class="mt-4 inline-flex text-sm text-[var(--wire-color-primary)] hover:underline">Back to sign in</a>
|
||||
</section>
|
||||
|
||||
@@ -22,12 +22,12 @@ component InvitationAccept {
|
||||
<div class="mt-5 rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] p-4 text-sm"><p class="m-0 font-semibold">{organization}</p><p class="mb-0 mt-1 text-[var(--wire-color-muted)]">Invited by {inviter}</p></div>
|
||||
<form method="post" action='{action}' data-schema='{schema}' data-redirect='{redirect}' novalidate class="mt-5 space-y-4">
|
||||
<input type="hidden" name="token" value='{token}' />
|
||||
<div class="space-y-1.5"><label for="auth-invitation-name" class="block text-sm font-medium">Display name</label><input id="auth-invitation-name" name="displayName" autocomplete="name" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3" /><p data-error="displayName" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p></div>
|
||||
<div class="space-y-1.5"><label for="auth-invitation-password" class="block text-sm font-medium">Create password</label><input id="auth-invitation-password" name="password" type="password" autocomplete="new-password" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3" /><p data-error="password" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p></div>
|
||||
<Input id="auth-invitation-name" name="displayName" label="Display name" autocomplete="name" placeholder="Enter your display name" icon="icon-[lucide--user]" color="{color}" size="{size}" />
|
||||
<StrongPassword label="Create password" name="password" autocomplete="new-password" minLength="12" requireLowercase="true" requireUppercase="true" requireNumber="true" requireSpecialCharacter="true" color="{color}" size="{size}" />
|
||||
<p data-error="token" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] text-sm font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
</section>
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ component MagicLinkSignIn {
|
||||
<h1 class="m-0 text-2xl font-semibold">{title}</h1>
|
||||
<p class="mb-0 mt-2 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<form method="post" action='{action}' data-schema='{schema}' novalidate class="mt-6 space-y-4">
|
||||
<div class="space-y-1.5"><label for="auth-magic-link-identifier" class="block text-sm font-medium">{emailLabel}</label><input id="auth-magic-link-identifier" name="identifier" type="email" autocomplete="email" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-sm outline-none focus:border-[var(--wire-color-primary)]" /><p data-error="identifier" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p></div>
|
||||
<Input id="auth-magic-link-identifier" name="identifier" type="email" label="{emailLabel}" autocomplete="email" placeholder="Enter your email address" icon="icon-[lucide--mail]" color="{color}" size="{size}" />
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
<a href='{signInHref}' class="mt-4 inline-flex text-sm font-medium text-[var(--wire-color-primary)] hover:underline">Return to password sign-in</a>
|
||||
</section>
|
||||
|
||||
@@ -41,15 +41,11 @@ component OtpSignIn {
|
||||
class='mt-6 space-y-4 {challengeId == "" ? "" : "hidden"}'
|
||||
>
|
||||
<input type="hidden" name="method" value='{method}' />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-otp-identifier" class="block text-sm font-medium">{identifierLabel}</label>
|
||||
<input id="auth-otp-identifier" name="identifier" type="text" autocomplete="username" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-sm outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="identifier" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input id="auth-otp-identifier" name="identifier" type="text" label="{identifierLabel}" autocomplete="username" placeholder="Enter your email address or phone number" icon="icon-[lucide--at-sign]" color="{color}" size="{size}" />
|
||||
<p data-error="method" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white disabled:cursor-wait disabled:opacity-60">{requestLabel}</button>
|
||||
<Button type="submit" label="{requestLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
|
||||
<form
|
||||
@@ -62,15 +58,11 @@ component OtpSignIn {
|
||||
>
|
||||
<input type="hidden" name="challengeId" value='{challengeId}' />
|
||||
<input type="hidden" name="returnTo" value='{returnTo}' />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-otp-code" class="block text-sm font-medium">One-time code</label>
|
||||
<input id="auth-otp-code" name="code" inputmode="numeric" autocomplete="one-time-code" maxlength="6" class="h-12 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-center text-xl tracking-[0.35em] outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="code" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<PinInput label="One-time code" name="code" length="6" inputMode="numeric" autocomplete="one-time-code" color="{color}" size="{size}" />
|
||||
<p data-error="challengeId" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white disabled:cursor-wait disabled:opacity-60">{verifyLabel}</button>
|
||||
<button type="button" data-auth-otp-back class="w-full text-sm text-[var(--wire-color-primary)] hover:underline">Use a different account</button>
|
||||
<Button type="submit" label="{verifyLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
<Button type="button" data-auth-otp-back label="Use a different account" variant="ghost" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
</section>
|
||||
}
|
||||
|
||||
@@ -18,16 +18,11 @@ component ResetPassword {
|
||||
<p class="mt-2 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<form method="post" action='{action}' data-schema='{schema}' data-redirect='{redirect}' novalidate class="mt-6 space-y-4">
|
||||
<input type="hidden" name="token" value='{token}' />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-reset-password" class="block text-sm font-medium">New password</label>
|
||||
<input id="auth-reset-password" name="password" type="password" autocomplete="new-password" aria-describedby="auth-reset-password-error" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p class="m-0 text-xs text-[var(--wire-color-muted)]">At least 12 characters with uppercase, lowercase, and a number.</p>
|
||||
<p id="auth-reset-password-error" data-error="password" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<StrongPassword label="New password" name="password" autocomplete="new-password" minLength="12" requireLowercase="true" requireUppercase="true" requireNumber="true" requireSpecialCharacter="true" color="{color}" size="{size}" />
|
||||
<p data-error="token" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
</section>
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ component SignIn {
|
||||
title = "Welcome back"
|
||||
description = "Sign in to continue to your account."
|
||||
identifierLabel = "Email, phone, or username"
|
||||
identifierPlaceholder = "Enter your email, mobile number, or username"
|
||||
passwordLabel = "Password"
|
||||
passwordPlaceholder = "Enter your password"
|
||||
submitLabel = "Sign in"
|
||||
forgotHref = "/recover"
|
||||
signUpHref = "/sign-up"
|
||||
@@ -29,22 +31,25 @@ component SignIn {
|
||||
<input type="hidden" name="returnTo" value='{returnTo}' />
|
||||
<input type="hidden" name="deviceFingerprint" value="" />
|
||||
<input type="hidden" name="deviceName" value="" />
|
||||
<Input id="auth-sign-in-identifier" name="identifier" type="text" label="{identifierLabel}" autocomplete="username webauthn" placeholder="{identifierPlaceholder}" icon="icon-[lucide--at-sign]" color="{color}" size="{size}" />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-sign-in-identifier" class="block text-sm font-medium">{identifierLabel}</label>
|
||||
<input id="auth-sign-in-identifier" name="identifier" type="text" autocomplete="username webauthn" aria-describedby="auth-sign-in-identifier-error" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-sm outline-none focus:border-[var(--wire-color-primary)] focus:ring-2 focus:ring-[color-mix(in_srgb,var(--wire-color-primary)_25%,transparent)]" />
|
||||
<p id="auth-sign-in-identifier-error" data-error="identifier" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<div class="flex items-center justify-between gap-3 text-sm font-medium"><label for="auth-sign-in-password">{passwordLabel}</label><a href='{forgotHref}' class="text-xs text-[var(--wire-color-primary)] hover:underline">Forgot password?</a></div>
|
||||
<input id="auth-sign-in-password" name="password" type="password" autocomplete="current-password" aria-describedby="auth-sign-in-password-error" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-sm outline-none focus:border-[var(--wire-color-primary)] focus:ring-2 focus:ring-[color-mix(in_srgb,var(--wire-color-primary)_25%,transparent)]" />
|
||||
<p id="auth-sign-in-password-error" data-error="password" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<div class="flex justify-end"><a href='{forgotHref}' class="text-xs text-[var(--wire-color-primary)] hover:underline">Forgot password?</a></div>
|
||||
<TogglePassword
|
||||
label="{passwordLabel}"
|
||||
name="password"
|
||||
placeholder="{passwordPlaceholder}"
|
||||
autocomplete="current-password"
|
||||
pattern=""
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
/>
|
||||
</div>
|
||||
{#if showRemember}
|
||||
<label class="flex items-center gap-2 text-sm text-[var(--wire-color-muted)]"><input name="rememberDevice" type="checkbox" class="size-4 rounded border-[var(--wire-color-border)]" />Trust this device</label>
|
||||
<Checkbox id="auth-sign-in-remember" name="rememberDevice" label="Trust this device" color="{color}" size="{size}" />
|
||||
{/if}
|
||||
<slot></slot>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="inline-flex h-11 w-full items-center justify-center rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white transition-opacity hover:opacity-90 disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
{#if showPasskey}
|
||||
<div class="my-4 flex items-center gap-3 text-xs text-[var(--wire-color-muted)]"><span class="h-px flex-1 bg-[var(--wire-color-border)]"></span><span>or</span><span class="h-px flex-1 bg-[var(--wire-color-border)]"></span></div>
|
||||
|
||||
@@ -7,6 +7,13 @@ component SignUp {
|
||||
description = "Use a strong password and verify your contact details."
|
||||
submitLabel = "Create account"
|
||||
signInHref = "/sign-in"
|
||||
termsHref = "/legal/terms"
|
||||
privacyHref = "/legal/privacy-policy"
|
||||
namePlaceholder = "Enter your full name"
|
||||
emailPlaceholder = "Enter your email address"
|
||||
phonePlaceholder = "Enter your mobile number"
|
||||
usernamePlaceholder = "Choose a username"
|
||||
passwordPlaceholder = "Create a strong password"
|
||||
showPhone = true
|
||||
showUsername = true
|
||||
requireConsent = true
|
||||
@@ -15,10 +22,24 @@ component SignUp {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<section {...attrs} data-wrnexus-runtime="auth" class='w-full max-w-lg rounded-[var(--wire-radius-lg)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] p-6 text-[var(--wire-color-text)] shadow-[var(--wire-shadow-2)] {class}'>
|
||||
<header class="mb-6 space-y-1.5">
|
||||
<h1 class="m-0 text-2xl font-semibold">{title}</h1>
|
||||
<p class="m-0 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<section
|
||||
{...attrs}
|
||||
data-wrnexus-runtime="auth"
|
||||
class='w-full max-w-lg rounded-[var(--wire-radius-lg)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] p-6 text-[var(--wire-color-text)] shadow-[var(--wire-shadow-2)] {class}'
|
||||
>
|
||||
<header
|
||||
class="mb-6 space-y-1.5"
|
||||
>
|
||||
<h1
|
||||
class="m-0 text-2xl font-semibold"
|
||||
>
|
||||
{title}
|
||||
</h1>
|
||||
<p
|
||||
class="m-0 text-sm text-[var(--wire-color-muted)]"
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<form
|
||||
@@ -29,62 +50,146 @@ component SignUp {
|
||||
novalidate
|
||||
class="grid gap-4 sm:grid-cols-2"
|
||||
>
|
||||
<div class="space-y-1.5 sm:col-span-2">
|
||||
<label for="auth-sign-up-name" class="text-sm font-medium">Full name</label>
|
||||
<input id="auth-sign-up-name" name="displayName" autocomplete="name" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="displayName" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input
|
||||
id="auth-sign-up-name"
|
||||
name="displayName"
|
||||
label="Full name"
|
||||
autocomplete="name"
|
||||
placeholder="{namePlaceholder}"
|
||||
icon="icon-[lucide--user]"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
class="sm:col-span-2"
|
||||
/>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-sign-up-email" class="text-sm font-medium">Email</label>
|
||||
<input id="auth-sign-up-email" name="email" type="email" autocomplete="email" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="email" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input
|
||||
id="auth-sign-up-email"
|
||||
name="email"
|
||||
type="email"
|
||||
label="Email"
|
||||
autocomplete="email"
|
||||
placeholder="{emailPlaceholder}"
|
||||
icon="icon-[lucide--mail]"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
/>
|
||||
|
||||
{#if showPhone}
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-sign-up-phone" class="text-sm font-medium">Phone</label>
|
||||
<input id="auth-sign-up-phone" name="phone" type="tel" autocomplete="tel" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="phone" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input
|
||||
id="auth-sign-up-phone"
|
||||
name="phone"
|
||||
type="tel"
|
||||
label="Phone"
|
||||
autocomplete="tel"
|
||||
placeholder="{phonePlaceholder}"
|
||||
icon="icon-[lucide--phone]"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if showUsername}
|
||||
<div class="space-y-1.5 sm:col-span-2">
|
||||
<label for="auth-sign-up-username" class="text-sm font-medium">Username</label>
|
||||
<input id="auth-sign-up-username" name="username" autocomplete="username" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p data-error="username" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Input
|
||||
id="auth-sign-up-username"
|
||||
name="username"
|
||||
label="Username"
|
||||
autocomplete="username"
|
||||
placeholder="{usernamePlaceholder}"
|
||||
icon="icon-[lucide--circle-user-round]"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
class="sm:col-span-2"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="space-y-1.5 sm:col-span-2">
|
||||
<label for="auth-sign-up-password" class="text-sm font-medium">Password</label>
|
||||
<input id="auth-sign-up-password" name="password" type="password" autocomplete="new-password" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 outline-none focus:border-[var(--wire-color-primary)]" />
|
||||
<p class="m-0 text-xs text-[var(--wire-color-muted)]">At least 12 characters with uppercase, lowercase, and a number.</p>
|
||||
<p data-error="password" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<div
|
||||
class="space-y-1.5 sm:col-span-2"
|
||||
>
|
||||
<StrongPassword
|
||||
label="Password"
|
||||
name="password"
|
||||
placeholder="{passwordPlaceholder}"
|
||||
autocomplete="new-password"
|
||||
minLength="12"
|
||||
requireLowercase="true"
|
||||
requireUppercase="true"
|
||||
requireNumber="true"
|
||||
requireSpecialCharacter="true"
|
||||
presentation="inline"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if requireConsent}
|
||||
<div class="space-y-1 sm:col-span-2">
|
||||
<label class="flex items-start gap-2 text-sm text-[var(--wire-color-muted)]">
|
||||
<input name="consent" type="checkbox" class="mt-0.5 size-4" />
|
||||
<span>I agree to the terms and privacy policy.</span>
|
||||
</label>
|
||||
<p data-error="consent" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Checkbox
|
||||
id="auth-sign-up-consent"
|
||||
name="consent"
|
||||
label="I agree to the"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
class="sm:col-span-2"
|
||||
>
|
||||
<span
|
||||
class="flex items-center"
|
||||
>
|
||||
<a
|
||||
href="{termsHref}"
|
||||
>
|
||||
terms
|
||||
</a>
|
||||
and
|
||||
<a
|
||||
href="{privacyHref}"
|
||||
>
|
||||
privacy policy
|
||||
</a>.
|
||||
</span>
|
||||
</Checkbox>
|
||||
{:else}
|
||||
<input type="hidden" name="consent" value="true" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="consent"
|
||||
value="true"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="sm:col-span-2"><slot></slot></div>
|
||||
<div
|
||||
class="sm:col-span-2"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)] sm:col-span-2"></p>
|
||||
<p data-success="Account created successfully." role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)] sm:col-span-2"></p>
|
||||
<p
|
||||
data-error="_form"
|
||||
role="alert"
|
||||
class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)] sm:col-span-2"
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
data-success="Account created successfully."
|
||||
role="status"
|
||||
hidden
|
||||
class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)] sm:col-span-2"
|
||||
>
|
||||
</p>
|
||||
|
||||
<button type="submit" class="h-11 rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] px-4 text-sm font-semibold text-white sm:col-span-2 disabled:cursor-not-allowed disabled:opacity-60">{submitLabel}</button>
|
||||
<Button
|
||||
type="submit"
|
||||
label="{submitLabel}"
|
||||
variant="solid"
|
||||
color="{color}"
|
||||
size="{size}"
|
||||
fullWidth="true"
|
||||
class="sm:col-span-2"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<p class="mb-0 mt-5 text-center text-sm text-[var(--wire-color-muted)]">Already have an account? <a href='{signInHref}' class="font-semibold text-[var(--wire-color-primary)] hover:underline">Sign in</a></p>
|
||||
<p
|
||||
class="mb-0 mt-5 text-center text-sm text-[var(--wire-color-muted)]"
|
||||
>
|
||||
Already have an account? <a href='{signInHref}' class="font-semibold text-[var(--wire-color-primary)] hover:underline">Sign in</a>
|
||||
</p>
|
||||
</section>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ component TwoFactorChallenge {
|
||||
size = "md"
|
||||
class = ""
|
||||
}
|
||||
state methodOptions = [
|
||||
{"label":"Authenticator app","value":"totp"},
|
||||
{"label":"Recovery code","value":"recovery-code"},
|
||||
{"label":"Email code","value":"email-otp"},
|
||||
{"label":"SMS code","value":"sms-otp"}
|
||||
]
|
||||
view {
|
||||
<section
|
||||
{...attrs}
|
||||
@@ -31,26 +37,13 @@ component TwoFactorChallenge {
|
||||
<input type="hidden" name="mfaToken" value='{mfaToken}' />
|
||||
<input type="hidden" name="challengeId" value='{challengeId}' />
|
||||
<input type="hidden" name="returnTo" value='{returnTo}' />
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-mfa-method" class="block text-sm font-medium">Verification method</label>
|
||||
<select id="auth-mfa-method" name="method" data-auth-mfa-method class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3">
|
||||
<option value="totp">Authenticator app</option>
|
||||
<option value="recovery-code">Recovery code</option>
|
||||
<option value="email-otp">Email code</option>
|
||||
<option value="sms-otp">SMS code</option>
|
||||
</select>
|
||||
<p data-error="method" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<label for="auth-mfa-code" class="block text-sm font-medium">Verification code</label>
|
||||
<input id="auth-mfa-code" name="code" inputmode="numeric" autocomplete="one-time-code" class="h-12 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3 text-center text-xl tracking-[0.35em]" />
|
||||
<p data-error="code" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
</div>
|
||||
<Select id="auth-mfa-method" name="method" data-auth-mfa-method label="Verification method" value="{method}" options="{methodOptions}" color="{color}" size="{size}" />
|
||||
<PinInput label="Verification code" name="code" length="6" inputMode="numeric" autocomplete="one-time-code" color="{color}" size="{size}" />
|
||||
<p data-auth-mfa-status role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-primary)_10%,transparent)] p-3 text-sm text-[var(--wire-color-primary)]"></p>
|
||||
<p data-error="mfaToken" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="challengeId" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
<a href='{recoveryHref}' class="mt-4 inline-flex text-sm text-[var(--wire-color-primary)] hover:underline">Account recovery options</a>
|
||||
</section>
|
||||
|
||||
@@ -20,17 +20,17 @@ component VerifyEmail {
|
||||
<h1 class="m-0 text-2xl font-semibold">{title}</h1>
|
||||
<p class="mt-2 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<form method="post" action='{action}' data-schema='{schema}' novalidate class="mt-6 space-y-4">
|
||||
<div class="space-y-1.5"><label for="auth-email-token" class="block text-sm font-medium">Verification token</label><input id="auth-email-token" name="token" value='{token}' autocomplete="one-time-code" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3" /><p data-error="token" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p></div>
|
||||
<Input id="auth-email-token" name="token" label="Verification token" value="{token}" autocomplete="one-time-code" placeholder="Enter your verification token" icon="icon-[lucide--badge-check]" color="{color}" size="{size}" />
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
<form method="post" action='{resendAction}' data-schema='{resendSchema}' novalidate class="mt-3">
|
||||
<input type="hidden" name="type" value='{kind}' />
|
||||
<input type="hidden" name="identifier" value='{identifier}' />
|
||||
<p data-error="type" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="text-sm text-[var(--wire-color-primary)] hover:underline disabled:opacity-60">Send a new code</button>
|
||||
<Button type="submit" label="Send a new code" variant="ghost" color="{color}" size="sm" />
|
||||
</form>
|
||||
</section>
|
||||
}
|
||||
|
||||
@@ -20,17 +20,17 @@ component VerifyPhone {
|
||||
<h1 class="m-0 text-2xl font-semibold">{title}</h1>
|
||||
<p class="mt-2 text-sm text-[var(--wire-color-muted)]">{description}</p>
|
||||
<form method="post" action='{action}' data-schema='{schema}' novalidate class="mt-6 space-y-4">
|
||||
<div class="space-y-1.5"><label for="auth-phone-token" class="block text-sm font-medium">Verification token</label><input id="auth-phone-token" name="token" value='{token}' autocomplete="one-time-code" inputmode="numeric" class="h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-3" /><p data-error="token" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p></div>
|
||||
<PinInput label="Verification token" name="token" value="{token}" length="6" inputMode="numeric" autocomplete="one-time-code" color="{color}" size="{size}" />
|
||||
<p data-error="_form" role="alert" class="m-0 hidden rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-danger)_10%,transparent)] p-3 text-sm text-[var(--wire-color-danger)]"></p>
|
||||
<p data-success='{successMessage}' role="status" hidden class="m-0 rounded-[var(--wire-radius-sm)] bg-[color-mix(in_srgb,var(--wire-color-success)_10%,transparent)] p-3 text-sm text-[var(--wire-color-success)]">{successMessage}</p>
|
||||
<button type="submit" class="h-11 w-full rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-primary)] font-semibold text-white disabled:cursor-wait disabled:opacity-60">{submitLabel}</button>
|
||||
<Button type="submit" label="{submitLabel}" variant="solid" color="{color}" size="{size}" fullWidth="true" />
|
||||
</form>
|
||||
<form method="post" action='{resendAction}' data-schema='{resendSchema}' novalidate class="mt-3">
|
||||
<input type="hidden" name="type" value='{kind}' />
|
||||
<input type="hidden" name="identifier" value='{identifier}' />
|
||||
<p data-error="type" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<p data-error="_form" role="alert" class="m-0 hidden text-xs text-[var(--wire-color-danger)]"></p>
|
||||
<button type="submit" class="text-sm text-[var(--wire-color-primary)] hover:underline disabled:opacity-60">Send a new code</button>
|
||||
<Button type="submit" label="Send a new code" variant="ghost" color="{color}" size="sm" />
|
||||
</form>
|
||||
</section>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user