Graphical PDS migrator for AT Protocol
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 transformStyles = 47 "translate-y-0 hover:translate-y-1 hover:transition-transform hover:duration-200 hover:ease-in-out"; 48 const colorStyles = { 49 blue: 50 "bg-gradient-to-r from-blue-400 to-blue-500 text-white hover:from-blue-500 hover:to-blue-600", 51 amber: 52 "bg-gradient-to-r from-amber-400 to-amber-500 text-slate-900 hover:from-amber-500 hover:to-amber-600", 53 }; 54 55 const buttonContent = ( 56 <> 57 {icon && ( 58 <img 59 src={icon} 60 alt={iconAlt || ""} 61 className={`${condensed ? "w-4 h-4" : "w-6 h-6"} mr-2`} 62 style={{ 63 filter: color === "blue" 64 ? "brightness(0) invert(1)" 65 : "brightness(0)", 66 }} 67 /> 68 )} 69 {label && ( 70 <span className="font-mono font-bold tracking-wider"> 71 {label} 72 </span> 73 )} 74 </> 75 ); 76 77 const buttonStyles = `${baseStyles} ${paddingStyles} ${transformStyles} ${ 78 colorStyles[color] 79 } ${className}`; 80 81 if (isAnchor) { 82 return ( 83 <a 84 href={props.href} 85 className={buttonStyles} 86 {...rest as JSX.HTMLAttributes<HTMLAnchorElement>} 87 > 88 {buttonContent} 89 </a> 90 ); 91 } 92 93 const buttonProps = rest as JSX.HTMLAttributes<HTMLButtonElement>; 94 return ( 95 <button 96 {...buttonProps} 97 className={buttonStyles} 98 > 99 {buttonContent} 100 </button> 101 ); 102}