Graphical PDS migrator for AT Protocol
at main 2.2 kB view raw
1import { JSX } from "preact"; 2 3type ButtonBaseProps = { 4 color?: "blue" | "amber"; 5 icon?: string; 6 iconAlt?: string; 7 label?: string; 8 className?: string; 9 condensed?: boolean; 10}; 11 12type ButtonProps = 13 & ButtonBaseProps 14 & Omit<JSX.HTMLAttributes<HTMLButtonElement>, keyof ButtonBaseProps>; 15type AnchorProps = 16 & ButtonBaseProps 17 & Omit<JSX.HTMLAttributes<HTMLAnchorElement>, keyof ButtonBaseProps> 18 & { href: string }; 19 20/** 21 * The button props or anchor props for a button or link. 22 * @type {Props} 23 */ 24type Props = ButtonProps | AnchorProps; 25 26/** 27 * Styled button component. 28 * @param props - The button props 29 * @returns The button component 30 * @component 31 */ 32export function Button(props: Props) { 33 const { 34 color = "blue", 35 icon, 36 iconAlt, 37 label, 38 className = "", 39 condensed = false, 40 ...rest 41 } = props; 42 const isAnchor = "href" in props; 43 44 const baseStyles = "airport-sign flex items-center [transition:none]"; 45 const paddingStyles = condensed ? "px-2 py-1.5" : "px-3 py-2 sm:px-6 sm:py-3"; 46 const colorStyles = { 47 blue: "bg-blue-500 text-white hover:bg-blue-500", 48 amber: "bg-amber-400 text-slate-900 hover:bg-amber-500", 49 }; 50 51 const buttonContent = ( 52 <> 53 {icon && ( 54 <img 55 src={icon} 56 alt={iconAlt || ""} 57 className={`${condensed ? "w-4 h-4" : "w-6 h-6"} mr-2`} 58 style={{ 59 filter: color === "blue" 60 ? "brightness(0) invert(1)" 61 : "brightness(0)", 62 }} 63 /> 64 )} 65 {label && ( 66 <span className="font-mono font-bold tracking-wider"> 67 {label} 68 </span> 69 )} 70 </> 71 ); 72 73 const buttonStyles = `${baseStyles} ${paddingStyles} ${ 74 colorStyles[color] 75 } ${className}`; 76 77 if (isAnchor) { 78 return ( 79 <a 80 href={props.href} 81 className={buttonStyles} 82 {...rest as JSX.HTMLAttributes<HTMLAnchorElement>} 83 > 84 {buttonContent} 85 </a> 86 ); 87 } 88 89 const buttonProps = rest as JSX.HTMLAttributes<HTMLButtonElement>; 90 return ( 91 <button 92 {...buttonProps} 93 className={buttonStyles} 94 > 95 {buttonContent} 96 </button> 97 ); 98}