Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Checkout Dialog for Ark UI

A checkout dialog with Monthly at $29 and Yearly at $290, card fields, and a button that shows the price for the cycle.

Checkout opens Complete your purchase. Monthly is $29/mo and starts selected. Yearly is $290/yr with a Save 17% badge. The button reads Complete Purchase - $29 until Yearly is picked. Card fields and a default-method checkbox sit under the cards.

Use it when the cycle and the card are chosen together. If the charge cannot be undone, confirm in an Alert Dialog. In React, Ark UI does not charge the card.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Dialog anatomy: content, title, description, close, footer

Usage

<Dialog>
  <DialogTrigger asChild>
    <Button variant="outline">Checkout</Button>
  </DialogTrigger>
  <DialogContent className="sm:max-w-md">
    <DialogHeader>
      <DialogTitle>Complete your purchase</DialogTitle>
      <DialogDescription>
        Choose your billing cycle and enter payment details.
      </DialogDescription>
    </DialogHeader>
    <FieldGroup>
      <FieldSet>
        <FieldLegend variant="label">Billing cycle</FieldLegend>
        <RadioGroup
          className="grid-cols-2"
          onValueChange={handleValueChange}
          value={billingCycle}
        >
          {cycles.map((cycle) => (
            <FieldLabel key={cycle.value}>
              <Field orientation="horizontal">
                <FieldContent>
                  <FieldTitle>{cycle.label}</FieldTitle>
                  <FieldDescription>{cycle.price}</FieldDescription>
                  {cycle.saving ? (
                    <Badge className="w-fit" variant="success">
                      {cycle.saving}
                    </Badge>
                  ) : null}
                </FieldContent>
{/* The rest of the file is under Installation. */}

FAQ

How does the price follow the billing cycle?

The radio group is controlled, and the button reads the total for the selected cycle from a static list. Monthly shows $29, Yearly $290.

Why radio cards instead of buttons?

A billing cycle is one choice out of several, which is what a radio group is: arrow keys move between the options and screen readers announce the selection. Each card is a FieldLabel around a Field with the title, the price and the RadioGroupItem.

How is the yearly saving shown?

With a Badge using variant="success" inside the Yearly card, so it follows the theme's success color.

When should I validate the card fields?

When each field loses focus, with the error in a FieldError, and keep Complete Purchase disabled until everything is valid. Better still, use your payment provider's hosted fields.

What if the payment fails?

Keep the dialog open, show the error above the buttons and leave the fields filled so people can fix one and retry.

What happens after a successful payment?

Close the dialog from your handler and confirm with a toast or a receipt page. Pass open and update it in onOpenChange, which receives { open }.

API Reference

Dialog

Sets asChild. The rest is on the Dialog page.

Button

Sets variant="outline". The rest is on the Button page.

Field

Sets variant="label" and orientation="horizontal". The rest is on the Field page.

Radio Group

Sets onValueChange={handleValueChange}, value={billingCycle} and value={cycle.value}. The rest is on the Radio Group page.

Badge

Sets variant="success". The rest is on the Badge page.

Input

Sets autoComplete="cc-name", name="card-name", placeholder="John Doe", type="text", autoComplete="cc-number" and inputMode="numeric". The rest is on the Input page.

Checkbox

Sets name="default-method". The rest is on the Checkbox page.