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.jsonimport { BillingToggle } from "@/components/iris/billing-toggle/billing-toggle";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
SegmentedControlorTabs.
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.BillingPricemarks the old price as deleted content. - Reduced motion makes the thumb jump and swaps badge text without movement.
- Theming: the track uses
hoverandline-soft, the thumbsurface; the selected saving badge takesgreen, or--billing-accentwhen an ancestor sets it.BillingPricesets the amount in the display font.