because I got bored of customising my CV for every job
at main 123 lines 3.2 kB view raw
1import { cva, type VariantProps } from "class-variance-authority"; 2import { cn } from "../lib/cn"; 3 4const iconButtonVariants = cva( 5 "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ctp-blue focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 6 { 7 variants: { 8 variant: { 9 primary: "", 10 secondary: "", 11 outline: "border border-ctp-surface1 bg-transparent", 12 ghost: "", 13 destructive: "", 14 }, 15 size: { 16 xs: "h-6 w-6 text-xs", 17 sm: "h-8 w-8 text-sm", 18 md: "h-10 w-10", 19 lg: "h-12 w-12 text-lg", 20 }, 21 showColorOnHover: { 22 true: "", 23 false: "", 24 }, 25 }, 26 compoundVariants: [ 27 // Primary variants 28 { 29 variant: "primary", 30 showColorOnHover: true, 31 className: "text-ctp-text hover:bg-ctp-blue hover:text-ctp-base", 32 }, 33 { 34 variant: "primary", 35 showColorOnHover: false, 36 className: "bg-ctp-blue text-ctp-base hover:bg-ctp-blue/90", 37 }, 38 // Secondary variants 39 { 40 variant: "secondary", 41 showColorOnHover: true, 42 className: "text-ctp-text hover:bg-ctp-surface1", 43 }, 44 { 45 variant: "secondary", 46 showColorOnHover: false, 47 className: "bg-ctp-surface1 text-ctp-text hover:bg-ctp-surface1/80", 48 }, 49 // Outline variants 50 { 51 variant: "outline", 52 showColorOnHover: true, 53 className: "text-ctp-text hover:bg-ctp-surface0 hover:border-ctp-blue", 54 }, 55 { 56 variant: "outline", 57 showColorOnHover: false, 58 className: "text-ctp-text hover:bg-ctp-surface0", 59 }, 60 // Ghost variants 61 { 62 variant: "ghost", 63 showColorOnHover: true, 64 className: "text-ctp-text hover:bg-ctp-surface0", 65 }, 66 { 67 variant: "ghost", 68 showColorOnHover: false, 69 className: "text-ctp-text hover:bg-ctp-surface0", 70 }, 71 // Destructive variants 72 { 73 variant: "destructive", 74 showColorOnHover: true, 75 className: "text-ctp-text hover:bg-ctp-red hover:text-ctp-base", 76 }, 77 { 78 variant: "destructive", 79 showColorOnHover: false, 80 className: "bg-ctp-red text-ctp-base hover:bg-ctp-red/90", 81 }, 82 ], 83 defaultVariants: { 84 variant: "ghost", 85 size: "md", 86 showColorOnHover: true, 87 }, 88 }, 89); 90 91interface IconButtonProps extends VariantProps<typeof iconButtonVariants> { 92 icon: React.ReactNode; 93 label: string; 94 onClick?: () => void; 95 disabled?: boolean; 96 className?: string; 97} 98 99export const IconButton = ({ 100 icon, 101 label, 102 onClick, 103 disabled = false, 104 variant = "ghost", 105 size = "md", 106 className = "", 107 showColorOnHover = true, 108}: IconButtonProps) => { 109 return ( 110 <button 111 type="button" 112 onClick={onClick} 113 disabled={disabled} 114 aria-label={label} 115 className={cn( 116 iconButtonVariants({ variant, size, showColorOnHover }), 117 className, 118 )} 119 > 120 {icon} 121 </button> 122 ); 123};