shadcn.io is not affiliated with official shadcn/ui
Manage Subscription Dialog Block for React
A design tool's account page with its subscription sheet shown open: the plan, billing cycle and seats editable in place, a next-invoice foot worked out from the controls, and a plan card behind it that changes when you save.
Installation
Overview
Let people edit what they pay for without leaving the page, with this subscription sheet for React with Base UI. It opens from the Subscription page of Studiofold, a design tool: the page's header holds an outline Manage subscription Button, and the page itself, a plan card with its price and a project meter, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Sheet slides in from the end edge and lists the subscription as rows, each editable where it can be: the plan in a Select, monthly or yearly in a Segment Group, and the seats in a Number Input that only the Team plan has. The card and the renewal date are read-only. The foot works out the next invoice from the controls as you change them, counts the changes and holds the only Shine Button, Save changes, beside a quiet Discard. Saving updates the plan card behind the sheet: its name, its price and how much of the project limit is used. For preview the sheet is drawn open in place when the page loads; the header's button opens the real sheet, with the same rows and the same state. For account pages, billing settings and any app with plans and seats.
FAQ
Why is the sheet already open, and what do I keep?
So you can see it without a click. On load the sheet is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Manage subscription button opens the real Sheet, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same SubscriptionFields and SubscriptionFoot components and share the block's state, so a plan chosen in the copy is there in the real sheet. In your app keep the Sheet and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
How is the next invoice worked out?
One small function, periodOf, takes the plan, the cycle and the seats and returns cents: the plan's monthly price, plus each seat past the ones it includes on Team, times 10 for a yearly cycle (ten months for twelve). Every figure on screen comes from it, so the foot, the sentence under the heading and the card behind the sheet always agree. It doesn't prorate: a change that takes effect mid-period needs an invoice preview from your billing provider, which you show in the same foot instead of the local sum.
Why are seats only on one plan?
Solo and Studio are a single seat, so the row says so and has no control; Team includes three seats and charges for each one after that, up to 25. What you type is kept between those limits, and the text is read the same in an Arabic page, where the number field prints Arabic-Indic digits. The field and the row keep their size when the plan changes, so nothing under them moves.
What stays local, and what happens to changes I don't save?
Everything. The prices and the Visa line are typed in the file (a real app takes cards with its payment provider's hosted fields, never in fields of its own), and Save changes only updates the plan card and the page's sentence and says, in the polite status, that nothing was charged. In your app send the draft to your billing API, show its result in the foot, and update the card from what it returns. There is no cancel here and no retention offer: those belong in a cancel flow of their own. Changes you don't save are dropped: Discard puts the controls back to what is saved and says so, and so do the close button and Escape. Save changes with nothing changed doesn't close anything: it says "No changes to save." Both buttons are always on screen and quiet when there is nothing to do, so the foot never changes size.
Is it accessible from the keyboard?
Yes. The real sheet is named by its title and described by its sentence, focus starts on the plan select and stays inside until it closes, and Escape and the close button return focus to Manage subscription. Each row's control is named by its label, the select and the segments by aria-labelledby. What is said while the sheet is open is said again inside it, because a modal hides the page's own status. The trigger is passed to SheetTrigger through render, and the sheet is controlled with open and onOpenChange.
Which edge does the sheet come from, and what about phones?
The end edge, in either direction: the sheet's sides are physical, so the block reads the page's direction when it opens and picks the matching edge. On a phone the copy shown on load docks to the foot of the page as a bottom sheet with its actions pinned, and the real sheet takes the full width.
Related
- Pro
Select Plan Dialog
Payments and plansA static-site host's Sites page with its plan chooser shown open: three plans as rows that unfold to their features, a yearly switch that rewrites the prices and what is due today, and a comparison table behind a disclosure.
- Pro
Upgrade Plan Dialog
Payments and plansA product-analytics usage page with its upgrade dialog shown open: your plan and the next joined by an arrow, a yearly switch, and a table of limits with what you have now and what you would have after.
- Pro
Cancel Subscription Dialog
Destructive confirmsA backup service's plan page with its exit flow shown open: an alert dialog in three steps, why you are leaving, an offer matched to the reason, and what ends and when, with a destructive final button and a thin progress bar.
- Pro
Payment Method Dialog
Payments and plansA ticket shop's order summary with its payment-method dialog shown open: a saved card, a bank transfer and an invoice as rows, each asking only for the one detail it needs, and a Pay with row behind the dialog that changes when you choose.
- Pro
Current Plan Billing
Plan and usageThe account's current plan in app settings: plan, price, renewal date and card, a change-plan action, every quota's usage this period on shared hairlines, and the next invoice.
- Pro
Seat Management Billing
Plan and usageSeats on a team plan: members with a role each (viewers are free), a stepper for the seats you pay for, and the monthly and prorated cost worked out before you save.