Selection card
Radio / checkbox cards. 2 types × 4 states.
import * as React from "react";
import { SelectionCard } from "@/components/ui/selection-card";
import { Zap } from "@/components/ui/icons";
export default function Example() {
const [plan, setPlan] = React.useState("monthly");
return (
<div style={{ width: 360, display: "grid", gap: 12 }} role="radiogroup" aria-label="Tea club plan">
<SelectionCard name="plan" checked={plan === "monthly"} onChange={() => setPlan("monthly")} title="Monthly tin" description="One 250g tin each month." price="৳480 / month" />
<SelectionCard name="plan" checked={plan === "yearly"} onChange={() => setPlan("yearly")} icon={<Zap />} title="Yearly club" description="Twelve tins, one free." price="৳5,280 / year" />
</div>
);
}
Installation
$ npx uix-ui@latest add selection-cardThis copies the file into components/ui/selection-card.tsx in your project. npx shadcn@latest add @uix/selection-card works too.
Usage
import { SelectionCard } from "@/components/ui/selection-card";
<div style={{ width: 360, display: "grid", gap: 12 }} role="radiogroup" aria-label="Tea club plan">
<SelectionCard name="plan" checked={plan === "monthly"} onChange={() => setPlan("monthly")} title="Monthly tin" description="One 250g tin each month." price="৳480 / month" />
<SelectionCard name="plan" checked={plan === "yearly"} onChange={() => setPlan("yearly")} icon={<Zap />} title="Yearly club" description="Twelve tins, one free." price="৳5,280 / year" />
</div>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | radio | checkbox | "radio" | |
title | React.ReactNode | – | |
description | React.ReactNode | – | |
price | React.ReactNode | – | Price or other fact under the description. |
icon | React.ReactNode | – | Replaces the default icon in the round badge. |
Everything else is passed to the root element, so className, aria-* and event handlers work as usual.
Dependencies
Installed for you by the CLI.
class-variance-authorityclsxtailwind-merge
lib/utils.tscomponents/ui/icons.tsx