36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import "../styles/components/empty-state.css";
|
|
|
|
interface EmptyStateProps {
|
|
icon?: ReactNode;
|
|
title: string;
|
|
description?: string;
|
|
actionLabel?: string;
|
|
onAction?: () => void;
|
|
}
|
|
|
|
export function EmptyState({ icon, title, description, actionLabel, onAction }: EmptyStateProps) {
|
|
return (
|
|
<div className="empty-state" role="status">
|
|
<div className="empty-state__illustration">
|
|
{icon || (
|
|
<svg width="120" height="96" viewBox="0 0 120 96" fill="none" aria-hidden="true">
|
|
<rect x="20" y="20" width="80" height="56" rx="8" stroke="currentColor" strokeWidth="2" strokeDasharray="4 3" opacity="0.3" />
|
|
<circle cx="60" cy="42" r="12" stroke="currentColor" strokeWidth="2" opacity="0.4" />
|
|
<path d="M54 42l4 4 8-8" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" opacity="0.4" />
|
|
<rect x="36" y="62" width="48" height="4" rx="2" fill="currentColor" opacity="0.15" />
|
|
<rect x="44" y="70" width="32" height="3" rx="1.5" fill="currentColor" opacity="0.1" />
|
|
</svg>
|
|
)}
|
|
</div>
|
|
<strong className="empty-state__title">{title}</strong>
|
|
{description ? <p className="empty-state__desc">{description}</p> : null}
|
|
{actionLabel && onAction ? (
|
|
<button type="button" className="empty-state__action" onClick={onAction}>
|
|
{actionLabel}
|
|
</button>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|