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