Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at main 59 lines 1.5 kB view raw
1import React from "react"; 2import { clsx } from "clsx"; 3 4interface EmptyStateProps { 5 icon?: React.ReactNode; 6 title?: string; 7 message: string; 8 action?: React.ReactNode | { label: string; onClick: () => void }; 9 className?: string; 10} 11 12export default function EmptyState({ 13 icon, 14 title, 15 message, 16 action, 17 className, 18}: EmptyStateProps) { 19 return ( 20 <div 21 className={clsx( 22 "text-center py-16 px-6", 23 "bg-surface-50/50 dark:bg-surface-800/50 rounded-2xl", 24 "border border-dashed border-surface-200 dark:border-surface-700", 25 className, 26 )} 27 > 28 {icon && ( 29 <div className="flex justify-center mb-4 text-surface-300 dark:text-surface-600"> 30 {icon} 31 </div> 32 )} 33 {title && ( 34 <h3 className="text-lg font-display font-semibold text-surface-900 dark:text-white mb-2"> 35 {title} 36 </h3> 37 )} 38 <p className="text-surface-500 dark:text-surface-400 max-w-sm mx-auto"> 39 {message} 40 </p> 41 {action && ( 42 <div className="mt-6"> 43 {typeof action === "object" && 44 "label" in action && 45 "onClick" in action ? ( 46 <button 47 onClick={action.onClick} 48 className="inline-flex items-center gap-2 px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors" 49 > 50 {action.label} 51 </button> 52 ) : ( 53 action 54 )} 55 </div> 56 )} 57 </div> 58 ); 59}