Components / Inputs

BillingToggle

A monthly and yearly switch with a savings badge and prices that roll to the new amount.

Install

npx shadcn@latest add https://irisui.dev/r/billing-toggle.json
import { BillingToggle } from "@/components/iris/billing-toggle/billing-toggle";
Registry item billing-toggleBrings in foundationRegistry JSON

Preview

BillingToggle

A monthly and yearly switch with a savings badge, paired with BillingPrice, whose digits roll to the new amount.

When to use

  • Pricing pages and plan pickers that offer two or three billing periods.
  • Showing the saving on the longer period and the struck-through previous price.
  • Not for general view switching; use SegmentedControl or Tabs.

Usage

import { BillingToggle } from "@/components/iris/billing-toggle/billing-toggle";

const [period, setPeriod] = useState("monthly");
const yearly = period === "yearly";
h(BillingToggle, {
  value: period,
  onValueChange: setPeriod,
  options: [
    { value: "monthly", label: "Monthly" },
    { value: "yearly", label: "Yearly", badge: "Save 33%", activeBadge: "You save €19.89" },
  ],
});
h(BillingPrice, {
  amount: yearly ? 3.33 : 4.99,
  was: yearly ? 4.99 : undefined,
  currency: "€",
  decimals: 2,
  period: yearly ? "per month, billed yearly" : "per month",
});

Props

BillingToggle

Prop Type Default Description
value string required Selected option value (controlled only).
onValueChange (value: string) => void required Called on click or arrow key.
options { value; label; badge?; activeBadge? }[] Monthly, Yearly with "Save 20%" Options in order; activeBadge replaces badge once selected.
label string "Billing period" Accessible name of the radio group.
size "md" | "lg" "md" 34px or 42px tall options (lg also sets the larger type size).
className string – Extra class on the group.

BillingPrice

Prop Type Default Description
amount number required Price to show.
currency string "$" Symbol before the amount and old price.
period string – Text after the price; swaps with a fade.
was number – Previous price, struck through only when higher than amount.
decimals number 0 Decimal places.
className string – Extra class.

Notes

  • Keyboard: one tab stop on the selected option; arrows select and wrap; Home/End jump.
  • The group is a radiogroup; badge text is part of each option's name so the saving is announced. BillingPrice marks the old price as deleted content.
  • Reduced motion makes the thumb jump and swaps badge text without movement.
  • Theming: the track uses hover and line-soft, the thumb surface; the selected saving badge takes green, or --billing-accent when an ancestor sets it. BillingPrice sets the amount in the display font.