Skip to content

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

Free

Plan Selection Dialog for Solid

A plan dialog with Hobby at $0, Pro at $29, and Enterprise at $99. Pro starts selected, and the button reads Continue with Pro.

UI library: Ark UI

Choose Plan opens three cards: Hobby at $0, Pro at $29, and Enterprise at $99. Pro starts selected. The same six features sit under every card. The button reads Continue with Pro, and Cancel is beside it.

Use it for a quick plan switch. If the lists differ, swap them with the selection. A change that cannot be undone belongs in an Alert Dialog. In Solid, Ark UI does not change the plan.

Preview

Preview width

Installation

MCP · Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

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

Usage

<Dialog>
      <DialogTrigger asChild={props => <Button {...props()} variant="outline">Choose Plan</Button>} />
      <DialogContent class="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Choose your plan</DialogTitle>
          <DialogDescription>
            Select the plan that best fits your needs.
          </DialogDescription>
        </DialogHeader>
        <RadioGroup aria-label="Plan" class="sm:grid-cols-3" onValueChange={handleValueChange} value={selectedPlan()}>
          {plans.map(plan => <FieldLabel>
              <Field orientation="horizontal">
                <FieldContent>
                  <FieldTitle>{plan.name}</FieldTitle>
                  <span class="font-bold text-lg">{plan.price}</span>
                  <FieldDescription class="text-xs">
                    {plan.description}
                  </FieldDescription>
                </FieldContent>
                <RadioGroupItem value={plan.value} />
              </Field>
            </FieldLabel>)}
        </RadioGroup>
        <div class="flex flex-col gap-2">
          <h3 class="font-semibold text-sm">Features included:</h3>
          <ul class="flex flex-col gap-2">
            {features.map(feature => <li class="flex items-center gap-2 text-sm">
                <CheckIcon aria-hidden="true" class="size-4 text-primary" />
                {feature}
              </li>)}
          </ul>
{/* The rest of the file is under Installation. */}

FAQ

How are the plan cards built?

Each is a FieldLabel around a horizontal Field with the name, price, description and a RadioGroupItem. The radio group is controlled, starts on Pro, and lays the cards out with sm:grid-cols-3.

How does the button know the plan?

It looks up the selected value in the static plans list and shows its name: Continue with Pro.

Should the features change with the plan?

If plans differ, yes: keep a feature list per plan and show the selected one's, or mark features missing from it.

Can I add a monthly or yearly toggle?

Yes, with a Switch or a second radio group above the cards that changes the prices, as the Checkout dialog example does.

Does Continue close the dialog?

Cancel is a DialogClose, so it does. Continue doesn't; close the dialog from your handler. Pass open and update it in onOpenChange, which receives { open }.

API Reference

Dialog

Sets asChild and props. The rest is on the Dialog page.

Button

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

Radio Group

Sets aria-label="Plan", onValueChange={handleValueChange}, value={selectedPlan()} and value={plan.value}. The rest is on the Radio Group page.

Field

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