Write on the margins of the internet. Powered by the AT Protocol.
margin.at
extension
web
atproto
comments
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}