Files
emaui/libs/ui/src/lib/feedback/EmptyState.tsx
2026-08-02 22:44:08 +03:00

48 lines
1.3 KiB
TypeScript

import { Button, Paper, Stack, Text, ThemeIcon } from '@mantine/core';
import { IconInbox, type Icon } from '@tabler/icons-react';
import type { ReactNode } from 'react';
interface EmptyStateProps {
title: string;
description?: string;
icon?: Icon;
action?: { label: string; onClick: () => void; icon?: ReactNode };
}
/**
* The "nothing here" state.
*
* Distinct from an error: an empty queue is a normal, often good, outcome. It
* says so plainly and offers the next useful action rather than leaving a bare
* grey panel that reads as a failure.
*/
export function EmptyState({
title,
description,
icon: StateIcon = IconInbox,
action,
}: EmptyStateProps) {
return (
<Paper p="xl" withBorder>
<Stack align="center" gap="sm" py="xl">
<ThemeIcon size={52} radius="xl" variant="light" color="gray">
<StateIcon size={28} stroke={1.5} />
</ThemeIcon>
<Text fw={600} fz="lg" ta="center">
{title}
</Text>
{description && (
<Text c="dimmed" size="sm" ta="center" maw={440}>
{description}
</Text>
)}
{action && (
<Button mt="xs" variant="light" leftSection={action.icon} onClick={action.onClick}>
{action.label}
</Button>
)}
</Stack>
</Paper>
);
}