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 = ButtonBaseProps & Omit<JSX.HTMLAttributes<HTMLButtonElement>, keyof ButtonBaseProps>; 13type AnchorProps = ButtonBaseProps & Omit<JSX.HTMLAttributes<HTMLAnchorElement>, keyof ButtonBaseProps> & { href: string }; 14 15type Props = ButtonProps | AnchorProps; 16 17export function Button(props: Props) { 18 const { color = "blue", icon, iconAlt, label, className = "", condensed = false, ...rest } = props; 19 const isAnchor = 'href' in props; 20 21 const baseStyles = "airport-sign flex items-center [transition:none]"; 22 const paddingStyles = condensed ? 'px-2 py-1.5' : 'px-3 py-2 sm:px-6 sm:py-3'; 23 const transformStyles = "translate-y-0 hover:translate-y-1 hover:transition-transform hover:duration-200 hover:ease-in-out"; 24 const colorStyles = { 25 blue: "bg-gradient-to-r from-blue-400 to-blue-500 text-white hover:from-blue-500 hover:to-blue-600", 26 amber: "bg-gradient-to-r from-amber-400 to-amber-500 text-slate-900 hover:from-amber-500 hover:to-amber-600", 27 }; 28 29 const buttonContent = ( 30 <> 31 {icon && ( 32 <img 33 src={icon} 34 alt={iconAlt || ""} 35 className={`${condensed ? 'w-4 h-4' : 'w-6 h-6'} mr-2`} 36 style={{ filter: color === 'blue' ? "brightness(0) invert(1)" : "brightness(0)" }} 37 /> 38 )} 39 {label && ( 40 <span className="font-mono font-bold tracking-wider"> 41 {label} 42 </span> 43 )} 44 </> 45 ); 46 47 const buttonStyles = `${baseStyles} ${paddingStyles} ${transformStyles} ${colorStyles[color]} ${className}`; 48 49 if (isAnchor) { 50 return ( 51 <a 52 href={props.href} 53 className={buttonStyles} 54 {...rest as JSX.HTMLAttributes<HTMLAnchorElement>} 55 > 56 {buttonContent} 57 </a> 58 ); 59 } 60 61 const buttonProps = rest as JSX.HTMLAttributes<HTMLButtonElement>; 62 return ( 63 <button 64 {...buttonProps} 65 className={buttonStyles} 66 > 67 {buttonContent} 68 </button> 69 ); 70}