Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Membership Checkout Block for Radix UI

A climbing gym's join form with four start dates, a month strip that redraws to show the days you pay for, the first month prorated in cents, a joining fee, what is due today and the next charge, plus member fields and an agreement.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show exactly what the first month costs, with this membership checkout for React with Radix UI. A header from Lichen and Lark, a climbing gym, sits over a hairline frame with a plus mark on each corner. Four start dates (today, tomorrow, next Monday and the 1st of next month) are a single choice. Pick one and a month strip with a cell for every day of that month redraws: days already gone are dashed, the days you pay for are filled from the start. Under it the sum is worked out in whole cents: the monthly fee times the days paid over the days in the month, rounded half up, plus a one-time joining fee, what is due today and the date and amount of the next charge. Below, three member fields in Field and Input (name, email, an emergency contact's phone) and an agreement that starts unticked. Join is the only Shine Button, its label carrying the amount. A press with problems names each one under its field; an unticked agreement is said in the status line. For gyms, clubs, studios and any membership that starts part-way through a month.

FAQ

How is the first month worked out?

The fee in cents times the days from your start date to the end of that month, divided by the days in the month, rounded half up to the cent. For 6,400 cents starting Wed 14 October (18 of 31 days) that is 3,716 cents. The one-time joining fee is added to give what is due today, and the next charge is the full fee on the 1st of the following month. If you start on the 1st of a month the whole month is paid. Change MONTHLY, JOINING and STARTS at the top of the file.

What does the month strip show?

One cell per day of the start date's month. Filled cells are the days you pay for, plain cells are days in the month before your start, and dashed cells are days that have already passed (relative to a fixed today, not your clock). It is a picture of the sum, hidden from assistive technology, with a sentence beside it that says the same in words: how many days, from which date.

Why is Join not disabled while the agreement is unticked?

So it can still be pressed and explain itself. The button is marked aria-disabled and dimmed until you tick the agreement; pressing it anyway names what is missing in the status line and moves focus to the checkbox. Field problems (a missing name, a bad email or phone) are shown under their fields instead, and come first.

Does it use my clock?

No. Today is the constant AS_OF (14 October 2026), so the strip, the days paid and the next charge are the same for everyone and the same on the server and in the browser. In your app, set it from the server's date at render time.

What stays local, and how do I connect it for real?

Everything: confirming changes this block's state and the status line says nothing was charged, saved or sent. To connect it, create the member on your server with the chosen start date, charge the prorated fee and joining fee with your payment provider (add its hosted card fields to this layout; the demo takes no card), and schedule the next charge for the date shown.