first commit

This commit is contained in:
maximus
2026-07-29 15:27:00 +02:00
commit 2f33cf9aba
37 changed files with 3444 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
import { InputHTMLAttributes } from "react";
import { cn } from "@utils/utils";
interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
label?: string;
}
export function Radio({ className, label, checked, ...props }: RadioProps) {
// Cercle extérieur (Creusé)
const lightInset = "shadow-[inset_4px_4px_8px_#c5c5c5,inset_-4px_-4px_8px_#ffffff]";
const darkInset = "dark:shadow-[inset_4px_4px_8px_#121926,inset_-4px_-4px_8px_#2a3850]";
// Bille intérieure (Bombée)
const lightExtrude = "shadow-[2px_2px_4px_#c5c5c5,-2px_-2px_4px_#ffffff]";
const darkExtrude = "dark:shadow-[2px_2px_4px_#121926,-2px_-2px_4px_#2a3850]";
return (
<label className="flex items-center gap-3 cursor-pointer group">
<div className="relative flex items-center justify-center w-6 h-6">
<input type="radio" className="sr-only peer" checked={checked} {...props} />
{/* Le Cercle */}
<div className={cn(
"absolute inset-0 rounded-full bg-[#e8e8e8] dark:bg-[#1e293b] transition-all duration-300",
lightInset,
darkInset,
"peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500/50"
)}></div>
{/* La Bille centrale */}
<div className={cn(
"w-2.5 h-2.5 rounded-full bg-[#e8e8e8] dark:bg-[#1e293b] relative z-10 transition-all duration-300",
lightExtrude,
darkExtrude,
"opacity-0 scale-50",
"peer-checked:opacity-100 peer-checked:scale-100 peer-checked:bg-blue-500 dark:peer-checked:bg-blue-500",
className
)}></div>
</div>
{label && (
<span className="text-sm font-bold text-slate-500 dark:text-slate-400 group-hover:text-slate-700 dark:group-hover:text-slate-200 transition-colors">
{label}
</span>
)}
</label>
);
}