A personal media tracker built on the AT Protocol opnshelf.xyz
at main 56 lines 1.3 kB view raw
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}