Files
bakery-ia/frontend/src/components/ui/EmptyState/EmptyState.tsx
2025-10-27 16:33:26 +01:00

121 lines
2.6 KiB
TypeScript

import React from 'react';
import { LucideIcon } from 'lucide-react';
import { Button } from '../Button';
export interface EmptyStateProps {
/**
* Icon component to display (from lucide-react)
*/
icon: LucideIcon;
/**
* Main title text
*/
title: string;
/**
* Description text (can be a string or React node for complex content)
*/
description?: string | React.ReactNode;
/**
* Optional action button label
*/
actionLabel?: string;
/**
* Optional action button click handler
*/
onAction?: () => void;
/**
* Optional icon for the action button
*/
actionIcon?: LucideIcon;
/**
* Optional action button variant
*/
actionVariant?: 'primary' | 'secondary' | 'outline' | 'ghost';
/**
* Optional action button size
*/
actionSize?: 'sm' | 'md' | 'lg';
/**
* Additional CSS classes for the container
*/
className?: string;
}
/**
* EmptyState Component
*
* A reusable component for displaying empty states across the application
* with consistent styling and behavior.
*
* @example
* ```tsx
* <EmptyState
* icon={Package}
* title="No items found"
* description="Try adjusting your search or add a new item"
* actionLabel="Add Item"
* actionIcon={Plus}
* onAction={() => setShowModal(true)}
* />
* ```
*/
export const EmptyState: React.FC<EmptyStateProps> = ({
icon: Icon,
title,
description,
actionLabel,
onAction,
actionIcon: ActionIcon,
actionVariant = 'primary',
actionSize = 'md',
className = '',
}) => {
return (
<div className={`text-center py-12 ${className}`}>
{/* Icon */}
<Icon className="mx-auto h-12 w-12 text-[var(--text-tertiary)] mb-4" />
{/* Title */}
<h3 className="text-lg font-medium text-[var(--text-primary)] mb-2">
{title}
</h3>
{/* Description */}
{description && (
<div className="text-[var(--text-secondary)] mb-4">
{typeof description === 'string' ? (
<p>{description}</p>
) : (
description
)}
</div>
)}
{/* Action Button */}
{actionLabel && onAction && (
<Button
onClick={onAction}
variant={actionVariant}
size={actionSize}
className="font-medium px-4 sm:px-6 py-2 sm:py-3 shadow-sm hover:shadow-md transition-all duration-200"
>
{ActionIcon && (
<ActionIcon className="w-3 h-3 sm:w-4 sm:h-4 mr-1 sm:mr-2 flex-shrink-0" />
)}
<span className="text-sm sm:text-base">{actionLabel}</span>
</Button>
)}
</div>
);
};
export default EmptyState;