canina/frontend/application/components/HeaderButton.tsx

66 lines
2.2 KiB
TypeScript

"use client";
import React from "react";
import { motion } from "motion/react";
import { toPersian, cn } from "../lib/utils";
interface HeaderButtonProps {
onClick?: () => void;
children: React.ReactNode;
variant?: "primary" | "secondary" | "outline" | "ghost";
className?: string;
badge?: number;
icon?: React.ReactNode;
layout?: "row" | "col";
}
export default function HeaderButton({
onClick,
children,
variant = "primary",
className = "",
badge,
icon,
layout = "col"
}: HeaderButtonProps) {
const baseStyles = "relative flex items-center justify-center rounded-2xl transition-all duration-300 font-vazir select-none cursor-pointer overflow-visible focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none";
const layouts = {
col: "flex-col",
row: "flex-row gap-2"
};
const variants = {
primary: "bg-canina-blue text-white hover:bg-medical-gray-900 shadow-lg shadow-canina-blue/20",
secondary: "bg-medical-gray-50 text-medical-gray-600 hover:bg-medical-gray-100",
outline: "border-2 border-medical-gray-100 text-medical-gray-700 hover:border-canina-blue hover:text-canina-blue",
ghost: "text-medical-gray-600 hover:bg-medical-gray-50 hover:text-canina-blue"
};
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
setMounted(true);
}, []);
return (
<motion.button
whileHover={{ y: -2 }}
whileTap={{ scale: 0.95 }}
onClick={onClick}
className={cn(baseStyles, layouts[layout], variants[variant], className)}
>
{icon && <div className={cn(layout === "col" ? "mb-0.5" : "flex-shrink-0 flex items-center")}>{icon}</div>}
<div className="whitespace-nowrap flex items-center">{children}</div>
{mounted && badge !== undefined && badge > 0 && (
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
className="absolute -top-1 -left-1 w-5 h-5 bg-red-500 text-white rounded-full border-2 border-white text-[8px] font-black flex items-center justify-center font-vazir"
>
{toPersian(badge.toString())}
</motion.div>
)}
</motion.button>
);
}