Radio
Radio buttons allow the user to select one option from a set.
Usage
Installation
Radio.tsx
1"use client";
2import React, { useState } from "react";
3import { cn } from "@/utils/cn";
4import { AnimatePresence, motion, Variants } from "framer-motion";
5
6type RadioProps = {
7 label?: string;
8 className?: string;
9} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "onChange">;
10
11const Radio: React.FC<RadioProps> = ({ label, className, ...props }) => {
12 const [isChecked, setIsChecked] = useState(false);
13
14 const handleChange = () => {
15 setIsChecked(!isChecked);
16 };
17
18 const radioSelectedVariants: Variants = {
19 hidden: {
20 opacity: 0,
21 },
22 initial: {
23 opacity: 1,
24 transition: {
25 duration: 0.1,
26 },
27 },
28 exit: {
29 opacity: 0,
30 transition: {
31 duration: 0.1,
32 },
33 },
34 };
35
36 return (
37 <div className="flex items-center">
38 <input
39 type="radio"
40 className={cn(
41 "relative hidden h-4 w-4 cursor-pointer appearance-none rounded-full border-2 border-pink-300 outline-none transition-colors duration-300 checked:border-pink-500 hover:border-pink-500 focus:border-pink-500",
42 className,
43 )}
44 checked={isChecked}
45 onChange={handleChange}
46 {...props}
47 />
48 <label
49 className="flex cursor-pointer items-center"
50 onClick={handleChange}
51 >
52 <div
53 className={cn(
54 "relative flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full border-2 border-rose-500 p-1",
55 className,
56 )}
57 >
58 <AnimatePresence>
59 {isChecked && (
60 <motion.div
61 className={cn(
62 "h-full w-full rounded-full bg-rose-500",
63 className,
64 )}
65 variants={radioSelectedVariants}
66 initial="hidden"
67 animate="initial"
68 exit="exit"
69 ></motion.div>
70 )}
71 </AnimatePresence>
72 </div>
73 <span
74 className={cn(
75 "ml-2 font-geist font-semibold text-rose-100",
76 className,
77 )}
78 >
79 {label}
80 </span>
81 </label>
82 </div>
83 );
84};
85
86export default Radio;
Props
The Radio component accepts the following props:
Prop | Type | Default | Description |
---|---|---|---|
label | string | - | Optional label for the radio button. |
className | string | - | Additional CSS classes for styling. |
The component also accepts all valid HTML input attributes except type
and onChange
.
Styling
The component uses the following Tailwind CSS classes by default:
- Radio button: rounded-full, border-2, transition colors
- Label: font-geist, font-semibold, text-rose-100
- Selected state: bg-rose-500
These can be overridden or extended using the className
prop.