Staaarter

Billing Billing Cycle Info

A billing cycle info block that shows where a customer is in their current subscription period. Displays the cycle start and end dates, a progress bar for how much of the cycle has elapsed, days remaining until renewal, the next charge amount, and whether the plan bills in advance or arrears. Built to cut down on 'when will I be charged' support questions.

By Staaarter Team
Billing
Updated March 3, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-billing-cycle-info.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing27.tsx instead.

Usage

The file also exports billing27Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing27, billing27Demo } from "@/components/blocks/billing/billing27";

export default function Page() {
  return <Billing27 {...billing27Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Current billing cycle"Heading above the progress bar.
descriptionstringnoneOptional supporting line under the heading.
cycleStartstringnoneStart-of-cycle date shown at the left end of the progress bar.
cycleEndstringnoneEnd-of-cycle date shown at the right end of the progress bar.
renewalDatestringnoneDate shown in the 'Renews on' stat.
daysRemainingnumbernoneDays left in the cycle. Passed in rather than computed, so the render doesn't depend on when the page happens to load.
cycleLengthDaysnumbernoneTotal length of the current cycle in days, used with daysRemaining to size the progress bar.
billingType"advance" | "arrears""advance"Controls the badge text in the header.
amountstringnoneOptional next-charge amount shown as a third stat, omitted if not passed.
classNamestringnoneExtra classes for the outer container.

Behavior notes

  • The progress bar's width is derived from cycleLengthDays and daysRemaining at render time (elapsed = cycleLengthDays - daysRemaining), it isn't calculated from the current date, so server and client output always match and the bar stays accurate however stale the page's build time is.
  • elapsedDays is clamped between 0 and cycleLengthDays before computing the percentage, so an out-of-range daysRemaining value can't push the bar past either end.
  • The amount stat is only rendered when passed; omit it for cycle-info displays where the price isn't relevant, for example a free trial.
  • The progress bar carries role=progressbar with aria-valuenow/min/max so screen readers announce the elapsed percentage, not just a plain colored div.

Frequently asked questions