Xzero UI
Pro library

Trial bannerPro

A trial status banner where a ring counts down the days left, the copy names what the workspace loses, and the upgrade path is one click away. It comes as a slim banner, a sidebar card or a header pill. It shifts to a warning tone in the last days, has expired and upgraded states, and folds into the pill when dismissed or snoozed.

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

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/trial-banner

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 { TrialBanner } from "@/components/xzero/trial-banner/trial-banner";

export function AppTrialBanner({ trial }: { trial: { daysLeft: number; endsAt: string } }) {
  return (
    <TrialBanner
      daysLeft={trial.daysLeft}
      endsAt={trial.endsAt}
      onAddPayment={async signal => {
        const res = await fetch("/api/billing/checkout", { method: "POST", signal });
        if (!res.ok) throw new Error("Checkout failed");
        window.location.assign((await res.json()).url);
      }}
      onComparePlans={() => router.push("/pricing")}
      onSnooze={({ until }) => saveSnooze(until)}
      onDismiss={() => saveDismissed()}
    />
  );
}

API reference

TrialBanner

A trial status banner with a ring countdown, what the customer loses, and the upgrade path. Three variants share one state model: active, warning (the last days), expired and upgraded. Dismiss and snooze collapse it into the trial pill.

PropTypeDefaultDescription
variant"banner" | "card" | "pill""banner"banner: a slim row for the top of an app. card: a sidebar card with the feature list. pill: a compact header pill that opens the card in a popover.
planstring"Pro"The plan being trialed, used in every line of copy.
daysLeftnumber9Whole days left. 0 or less shows the expired state.
trialDaysnumber14Trial length in days. The ring shows daysLeft / trialDays.
endsAtDate | number | string–When the trial ends, for the date copy. Defaults to October 27, 2026 plus daysLeft, a sample date; pass your real end date.
warnAtnumber3The last N days switch to the warning tone, with copy that names the end day.
workspacestring"Northwind"The workspace name, used in the expired card copy.
featuresTrialFeature[]Okta SSO, Slack alerts, Linear sync, team seatsWhat the customer loses without paying, listed in the card: { id, label, detail?, icon? }. Icons are 14px marks.
lossSummarystring"Okta SSO and 12 seats"One short phrase for the banner copy. Keep it short so the slim banner stays on one line.
onAddPayment(signal: AbortSignal) => Promise<void> | void–Opens checkout or the billing portal. Resolve once a payment method is on file to show the upgraded state; throw to show the error state with Try again. Simulated (900ms) when left out.
onComparePlans() => void–Opens your plans page. Without it the banner shows a short simulated note.
onManageBilling() => void–The secondary action in the upgraded state.
onDismiss() => void–Called when the person dismisses the banner. Persist it.
onSnooze(snooze: TrialSnooze & { until: Date }) => void–Called with the chosen snooze (tomorrow, in 3 days, or when the warning starts). Persist until and stop rendering until then.
collapseTo"pill" | "none""pill"After dismiss or snooze: collapse to the trial pill, which reopens the banner, or render nothing.
dismissiblebooleantrueShows the dismiss button.
snoozablebooleantrueShows the snooze menu.
classNamestring–Class on the root.

Keyboard interactions

KeysAction
TabMoves through Compare plans, Add payment method, Snooze and Dismiss.
Enter / SpaceRuns the focused action, opens the snooze menu or opens the pill's card.
Arrow up / downMoves through snooze options; Escape closes the menu or the pill's popover.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Trial banner: A trial status banner where a ring counts down the days left, the copy names what the workspace loses, and the upgrade path is one click away. It comes as a slim banner, a sidebar card or a header pill. It shifts to a warning tone in the last days, has expired and upgraded states, and folds into the pill when dismissed or snoozed. 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