Focus the email field after clearing it via "andere E-Mail-Adresse"
FormField is now forwardRef so the email input can be targeted imperatively — clicking the button clears the field (previous commit) and now also focuses it, so the shopper can start typing immediately instead of having to click in first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { forwardRef, useEffect, useRef, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -69,17 +69,20 @@ function validateVatIdFormat(value: string): string {
|
||||
return isValidVatId(normalizeVatId(value)) ? "" : "Ungültiges USt-IdNr.-Format (z. B. DE123456789).";
|
||||
}
|
||||
|
||||
function FormField({
|
||||
label,
|
||||
wrapperClassName = "flex-1 min-w-0",
|
||||
error,
|
||||
...props
|
||||
}: { label: string; wrapperClassName?: string; error?: string } & React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
// forwardRef so callers can imperatively .focus() a specific field (see
|
||||
// the "Andere E-Mail-Adresse verwenden" handler below) — plain props
|
||||
// couldn't do that, and every other FormField usage is unaffected since
|
||||
// ref is optional.
|
||||
const FormField = forwardRef<
|
||||
HTMLInputElement,
|
||||
{ label: string; wrapperClassName?: string; error?: string } & React.InputHTMLAttributes<HTMLInputElement>
|
||||
>(function FormField({ label, wrapperClassName = "flex-1 min-w-0", error, ...props }, ref) {
|
||||
return (
|
||||
<label className={`flex flex-col gap-2 items-start ${wrapperClassName}`}>
|
||||
<span className="text-label text-text-muted">{label}</span>
|
||||
<input
|
||||
{...props}
|
||||
ref={ref}
|
||||
aria-invalid={error ? true : undefined}
|
||||
className={`w-full border rounded-sm px-4 py-3 text-body-sm text-text-primary outline-none focus:border-brand transition-colors ${
|
||||
error ? "border-red-600" : "border-border"
|
||||
@@ -88,7 +91,7 @@ function FormField({
|
||||
{error && <span className="text-label text-red-600">{error}</span>}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export function CheckoutContent({
|
||||
shippingMethods,
|
||||
@@ -150,6 +153,10 @@ export function CheckoutContent({
|
||||
// down the page without ever blurring the email field first (e.g.
|
||||
// browser autofill).
|
||||
const loginGateRef = useRef<HTMLDivElement>(null);
|
||||
// Focused after "Andere E-Mail-Adresse verwenden" clears the field below
|
||||
// — the shopper explicitly asked to type a different one, so the cursor
|
||||
// should already be waiting there instead of making them click in.
|
||||
const emailInputRef = useRef<HTMLInputElement>(null);
|
||||
const [loginPassword, setLoginPassword] = useState("");
|
||||
const [loginError, setLoginError] = useState<string | null>(null);
|
||||
const [loggingIn, setLoggingIn] = useState(false);
|
||||
@@ -753,6 +760,7 @@ export function CheckoutContent({
|
||||
actual rendered width in the 2-col row above (each half of
|
||||
a gap-4 flex row), instead of stretching full-width. */}
|
||||
<FormField
|
||||
ref={emailInputRef}
|
||||
label="E-Mail-Adresse"
|
||||
name="email"
|
||||
type="email"
|
||||
@@ -812,6 +820,7 @@ export function CheckoutContent({
|
||||
setEmail("");
|
||||
setLoginPassword("");
|
||||
setFieldError("email", "");
|
||||
emailInputRef.current?.focus();
|
||||
}}
|
||||
className="text-label text-text-muted underline hover:text-text-primary transition-colors"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user