78 lines
3.7 KiB
TypeScript
78 lines
3.7 KiB
TypeScript
import clsx from "clsx";
|
|
import {ReactNode} from "react";
|
|
import {BsArrowRepeat} from "react-icons/bs";
|
|
|
|
interface Props {
|
|
children: ReactNode;
|
|
color?: "rose" | "purple" | "red" | "green" | "gray" | "pink";
|
|
variant?: "outline" | "solid";
|
|
className?: string;
|
|
disabled?: boolean;
|
|
isLoading?: boolean;
|
|
onClick?: () => void;
|
|
type?: "button" | "reset" | "submit";
|
|
}
|
|
|
|
export default function Button({
|
|
color = "purple",
|
|
variant = "solid",
|
|
disabled = false,
|
|
isLoading = false,
|
|
className,
|
|
children,
|
|
type,
|
|
onClick,
|
|
}: Props) {
|
|
const colorClassNames: {[key in typeof color]: {[key in typeof variant]: string}} = {
|
|
green: {
|
|
solid: "bg-mti-green-light text-white border border-mti-green-light hover:bg-mti-green disabled:text-mti-green disabled:bg-mti-green-ultralight selection:bg-mti-green-dark",
|
|
outline:
|
|
"bg-transparent text-mti-green-light border border-mti-green-light hover:bg-mti-green-light disabled:text-mti-green disabled:bg-mti-green-ultralight disabled:border-none selection:bg-mti-green-dark hover:text-white selection:text-white",
|
|
},
|
|
purple: {
|
|
solid: "bg-mti-purple-light text-white border border-mti-purple-light hover:bg-mti-purple disabled:text-mti-purple disabled:bg-mti-purple-ultralight selection:bg-mti-purple-dark",
|
|
outline:
|
|
"bg-transparent text-mti-purple-light border border-mti-purple-light hover:bg-mti-purple-light disabled:text-mti-purple disabled:bg-mti-purple-ultralight disabled:border-none selection:bg-mti-purple-dark hover:text-white selection:text-white",
|
|
},
|
|
red: {
|
|
solid: "bg-mti-red-light text-white border border-mti-red-light hover:bg-mti-red disabled:text-mti-red disabled:bg-mti-red-ultralight selection:bg-mti-red-dark",
|
|
outline:
|
|
"bg-transparent text-mti-red-light border border-mti-red-light hover:bg-mti-red-light disabled:text-mti-red disabled:bg-mti-red-ultralight disabled:border-none selection:bg-mti-red-dark hover:text-white selection:text-white",
|
|
},
|
|
gray: {
|
|
solid: "bg-mti-gray-davy text-white border border-mti-gray-davy hover:bg-mti-gray-davy disabled:text-mti-gray-davy disabled:bg-mti-gray-davy selection:bg-mti-gray-davy",
|
|
outline:
|
|
"bg-transparent text-mti-gray-davy border border-mti-gray-davy hover:bg-mti-gray-davy disabled:text-mti-gray-davy disabled:bg-mti-gray-davy disabled:border-none selection:bg-mti-gray-davy hover:text-white selection:text-white",
|
|
},
|
|
rose: {
|
|
solid: "bg-mti-rose-light text-white border border-mti-rose-light hover:bg-mti-rose disabled:text-mti-rose disabled:bg-mti-rose-ultralight selection:bg-mti-rose-dark",
|
|
outline:
|
|
"bg-transparent text-mti-rose-light border border-mti-rose-light hover:bg-mti-rose-light disabled:text-mti-rose disabled:bg-mti-rose-ultralight disabled:border-none selection:bg-mti-rose-dark hover:text-white selection:text-white",
|
|
},
|
|
pink: {
|
|
solid: "bg-ielts-speaking text-white border border-ielts-speaking hover:bg-ielts-speaking disabled:text-ielts-speaking disabled:bg-ielts-speaking-transparent selection:bg-ielts-speaking",
|
|
outline:
|
|
"bg-transparent text-ielts-speaking border border-ielts-speaking hover:bg-ielts-speaking disabled:text-ielts-speaking disabled:bg-ielts-speaking-transparent disabled:border-none selection:bg-ielts-speaking hover:text-white selection:text-white",
|
|
},
|
|
};
|
|
|
|
return (
|
|
<button
|
|
type={type}
|
|
onClick={onClick}
|
|
className={clsx(
|
|
"py-4 px-6 rounded-full transition ease-in-out duration-300 disabled:cursor-not-allowed cursor-pointer",
|
|
className,
|
|
colorClassNames[color][variant],
|
|
)}
|
|
disabled={disabled || isLoading}>
|
|
{!isLoading && children}
|
|
{isLoading && (
|
|
<div className="flex items-center justify-center">
|
|
<BsArrowRepeat className="text-white animate-spin" size={25} />
|
|
</div>
|
|
)}
|
|
</button>
|
|
);
|
|
}
|