Segmented Control Billing Period
A pricing card where the period switch updates the price and submits with the form. The control is form-associated, so name puts the selected value straight into the FormData.
Code
The following example assumes that you have imported the component and set up the theme.
<form class="billing-period">15 collapsed lines
<div class="head"> <h3>Pro plan</h3> <sv-segmented-control class="control" aria-label="Billing period" name="period" value="monthly"> <button value="monthly">Monthly</button> <button value="yearly">Yearly</button> </sv-segmented-control> </div>
<p class="price"> <strong>$12</strong> <span class="unit">per month</span> </p> <p class="note">Billed every month</p>
<button type="submit">Continue</button></form>
<script type="application/x-typescript" module>18 collapsed lines
const form = document.querySelector<HTMLFormElement>(".billing-period")!; const control = form.querySelector<SegmentedControl>(".control")!; const price = form.querySelector(".price strong")!; const unit = form.querySelector(".price .unit")!; const note = form.querySelector(".note")!;
control.addEventListener("valuechange", () => { const isYearly = control.value === "yearly";
price.textContent = isYearly ? "$120" : "$12"; unit.textContent = isYearly ? "per year" : "per month"; note.textContent = isYearly ? "Billed once a year, two months free" : "Billed every month"; });
form.addEventListener("submit", event => { event.preventDefault(); note.textContent = `Continuing with the ${new FormData(form).get("period")} plan`; });</script>
<style>60 collapsed lines
.billing-period { max-inline-size: 24rem; padding: 1.25em; margin-inline: auto; background-color: var(--sv-gray-7); border: 1px solid var(--sv-gray-5); border-radius: var(--sv-bdr-rad-lg);
.head { display: flex; flex-wrap: wrap; gap: 1em; align-items: center; justify-content: space-between;
h3 { margin: 0; font-size: 1em; }
.control { flex-basis: 12em; }
.control button { font: inherit; font-size: 0.9em; } }
.price { margin: 0.75em 0 0;
strong { font-size: 1.8em; }
.unit { color: var(--sv-gray-3); } }
.note { margin: 0.25em 0 0; font-size: 0.85em; color: var(--sv-gray-3); }
button[type="submit"] { inline-size: 100%; padding: 0.6em 1em; margin-block-start: 1.25em; font: inherit; color: var(--sv-accent-content); cursor: pointer; background-color: var(--sv-accent); border: none; border-radius: var(--sv-bdr-rad-md); } }</style>