A personal media tracker built on the AT Protocol
opnshelf.xyz
1import { Loader2 } from "lucide-react";
2import type { ReactNode } from "react";
3
4type AddToShelfButtonProps = {
5 onClick: () => void;
6 isPending?: boolean;
7 label: string;
8 icon: ReactNode;
9 colors: {
10 primary?: string;
11 secondary?: string;
12 };
13 size?: "compact" | "regular";
14 className?: string;
15 disabled?: boolean;
16};
17
18export function AddToShelfButton({
19 onClick,
20 isPending = false,
21 label,
22 icon,
23 colors,
24 size = "regular",
25 className = "",
26 disabled = false,
27}: AddToShelfButtonProps) {
28 const sizeClasses =
29 size === "compact" ? "py-3 px-6" : "py-4 px-6 hover:scale-[1.02]";
30
31 return (
32 <button
33 type="button"
34 onClick={onClick}
35 disabled={disabled || isPending}
36 className={`w-full rounded-full m3-label-large transition-all duration-200 flex items-center justify-center gap-2 disabled:opacity-70 ${sizeClasses} ${className}`}
37 style={{
38 background: `linear-gradient(135deg, ${colors.primary} 0%, ${colors.secondary} 100%)`,
39 boxShadow: `0 15px 35px -10px color-mix(in srgb, ${colors.primary} 38%, transparent)`,
40 color: "var(--md-sys-color-on-primary)",
41 }}
42 >
43 {isPending ? (
44 <>
45 <Loader2 className="w-5 h-5 animate-spin" />
46 Loading
47 </>
48 ) : (
49 <>
50 {icon}
51 {label}
52 </>
53 )}
54 </button>
55 );
56}