47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import * as React from 'react';
|
|
import { clsx } from 'clsx';
|
|
import { Inbox } from 'lucide-react';
|
|
import { Button } from './Button.js';
|
|
|
|
export interface EmptyStateProps {
|
|
icon?: React.ReactNode;
|
|
title: string;
|
|
description?: string;
|
|
actionLabel?: string;
|
|
onAction?: () => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function EmptyState({
|
|
icon,
|
|
title,
|
|
description,
|
|
actionLabel,
|
|
onAction,
|
|
className,
|
|
}: EmptyStateProps) {
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
'flex flex-col items-center justify-center rounded-xl border border-dashed border-[var(--bl-border)] bg-[var(--bl-surface-muted)]/35 px-6 py-14 text-center',
|
|
className
|
|
)}
|
|
>
|
|
<div className="mb-4 rounded-xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-3 text-[var(--bl-text-tertiary,#555)] shadow-sm shadow-black/[0.04]">
|
|
{icon ?? <Inbox className="h-12 w-12" />}
|
|
</div>
|
|
<h3 className="m-0 text-base font-semibold text-[var(--bl-text-primary,#fff)]">{title}</h3>
|
|
{description && (
|
|
<p className="mt-2 max-w-sm text-sm leading-6 text-[var(--bl-text-secondary,#a0a0b0)]">
|
|
{description}
|
|
</p>
|
|
)}
|
|
{actionLabel && onAction && (
|
|
<Button variant="primary" size="sm" className="mt-4" onClick={onAction}>
|
|
{actionLabel}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|