(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

at frontend-rewrite 76 lines 2.1 kB view raw
1import React from "react"; 2import { clsx } from "clsx"; 3 4type ButtonVariant = "primary" | "secondary" | "ghost" | "danger"; 5type ButtonSize = "sm" | "md" | "lg"; 6 7interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { 8 variant?: ButtonVariant; 9 size?: ButtonSize; 10 loading?: boolean; 11 icon?: React.ReactNode; 12 children?: React.ReactNode; 13} 14 15const variants: Record<ButtonVariant, string> = { 16 primary: "bg-primary-600 text-white hover:bg-primary-500 shadow-sm", 17 secondary: 18 "bg-surface-100 dark:bg-surface-800 text-surface-900 dark:text-white hover:bg-surface-200 dark:hover:bg-surface-700", 19 ghost: 20 "text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-white", 21 danger: "bg-red-600 text-white hover:bg-red-500", 22}; 23 24const sizes: Record<ButtonSize, string> = { 25 sm: "px-3 py-1.5 text-sm gap-1.5", 26 md: "px-4 py-2 text-sm gap-2", 27 lg: "px-6 py-3 text-base gap-2", 28}; 29 30export default function Button({ 31 variant = "primary", 32 size = "md", 33 loading = false, 34 icon, 35 children, 36 className, 37 disabled, 38 ...props 39}: ButtonProps) { 40 return ( 41 <button 42 className={clsx( 43 "inline-flex items-center justify-center font-medium rounded-lg transition-all duration-200", 44 "focus:outline-none focus:ring-2 focus:ring-primary-500/20", 45 "disabled:opacity-50 disabled:cursor-not-allowed", 46 variants[variant], 47 sizes[size], 48 className, 49 )} 50 disabled={disabled || loading} 51 {...props} 52 > 53 {loading ? ( 54 <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24"> 55 <circle 56 className="opacity-25" 57 cx="12" 58 cy="12" 59 r="10" 60 stroke="currentColor" 61 strokeWidth="4" 62 fill="none" 63 /> 64 <path 65 className="opacity-75" 66 fill="currentColor" 67 d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" 68 /> 69 </svg> 70 ) : ( 71 icon 72 )} 73 {children && <span>{children}</span>} 74 </button> 75 ); 76}