components/we-inc/inline-newsletter-form-html-css.tsx
import { useState, type FormEvent } from "react";
const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
export default function InlineNewsletterForm() {
const [email, setEmail] = useState("");
const [state, setState] = useState<"idle" | "bad" | "done">("idle");
const submit = (e: FormEvent) => {
e.preventDefault();
setState(EMAIL.test(email) ? "done" : "bad");
};
return (
<section className="bg-[#10172a] px-4 py-14">
<div className="mx-auto flex max-w-5xl flex-col gap-8 lg:flex-row lg:items-center lg:justify-between">
<div className="max-w-md">
<h2 className="text-2xl font-semibold tracking-tight text-white">The Field Notes letter</h2>
<p className="mt-2 text-slate-300">One email on the first Sunday of each month: new trail guides, kit we have stopped using, and a map worth printing.</p>
</div>
<form noValidate onSubmit={submit} className="w-full lg:max-w-md">
<label htmlFor="inlf-email" className="sr-only">Email address</label>
<div className={`flex flex-col gap-2 rounded-2xl bg-white/5 p-1.5 ring-1 sm:flex-row sm:rounded-full ${state === "bad" ? "ring-rose-400" : "ring-white/15 focus-within:ring-2 focus-within:ring-lime-300"}`}>
<input
id="inlf-email"
type="email"
autoComplete="email"
required
value={email}
onChange={(e) => { setEmail(e.target.value); if (state !== "idle") setState("idle"); }}
placeholder="you@example.com"
aria-invalid={state === "bad" || undefined}
aria-describedby="inlf-msg"
className="h-11 min-w-0 flex-1 rounded-full bg-transparent px-4 text-[15px] text-white placeholder:text-slate-400 focus:outline-none"
/>
<button type="submit" className="h-11 shrink-0 rounded-full bg-lime-300 px-6 text-sm font-semibold text-slate-900 hover:bg-lime-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#10172a]">
{state === "done" ? "Subscribed" : "Subscribe"}
</button>
</div>
<p id="inlf-msg" role="status" className={`mt-2.5 px-4 text-sm ${state === "bad" ? "text-rose-300" : state === "done" ? "text-lime-200" : "text-slate-400"}`}>
{state === "bad" ? "Check the address, it needs an @ and a domain." : state === "done" ? "Done. The next letter goes out on Sunday." : "No tracking pixels. Leave with one click."}
</p>
</form>
</div>
</section>
);
}