Xzero UI
Pro library

Hero signupPro

A full screen waitlist hero on a soft, drifting mesh gradient: the email field validates as you type and its button grows into the confirmation with your place in line.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/hero-signup
Live · keyboard ready

Use this as the first section of a waitlist or early access page. Add the email in onSubscribe and return the place in line; reject with an Error to show its message with a retry. Signups in the preview are simulated.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/hero-signup

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { HeroSignup } from "@/components/xzero/blocks/hero-signup/hero-signup";

export function Hero() {
  return (
    <HeroSignup
      count={2140}
      onSubscribe={async email => {
        const res = await fetch("/api/waitlist", { method: "POST", body: JSON.stringify({ email }) });
        if (!res.ok) throw new Error("We couldn't save your spot");
        const { position } = await res.json();
        return position;
      }}
    />
  );
}

API reference

HeroSignup

A full screen landing hero built around one email field, on a soft mesh gradient tinted from the page accent. The field validates as you type, the button holds a spinner while the request runs, and on success the button grows across the field into the confirmation, where your place in line rolls in.

PropTypeDefaultDescription
titleReactNode"Close the month in an afternoon"Headline. A string rises in word by word on load.
descriptionReactNode–One supporting line under the headline.
placeholderstring"you@company.com"Email field placeholder.
buttonLabelstring"Join waitlist"Submit label.
shortButtonLabelstring"Join"Submit label on very narrow layouts.
footnoteReactNode"One email when your invite is ready. Nothing else."Quiet line under the field. Validation, a typo fix, a failure with retry, and the confirmation replace it in place.
countnumber1283People already on the list. The social proof rolls up by one when the visitor joins.
people{ name: string; src: string }[]–Portraits in the social proof stack. Up to five are shown.
proof(count: ReactNode) => ReactNode–Social proof line. Receives the rolling count.
huenumber–Mesh hue in degrees. Defaults to the hue of the page accent, or a calm blue violet for the neutral accent. The palette stays pale and low in chroma in light mode and deep and calm in dark mode.
onSubscribe(email: string) => void | number | Promise<void | number>–Adds the email to the list. Resolve with the visitor's place in line, or nothing to use count + 1. Reject with an Error to show its message with Try again. Without it the preview simulates the request.
onStateChange(state: "idle" | "submitting" | "error" | "success") => void–Called on every state change, for analytics.
classNamestring–Extra class on the section.

Keyboard interactions

KeysAction
EnterSubmits the email. The field shows send on mobile keyboards.
TabMoves from the field to the button, then to the inline actions under it: the typo fix, Try again, or Change email.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components