import { clsx } from 'clsx'; import React from 'react'; /** * Props for the EmptyState component */ export interface EmptyStateProps { /** * Custom icon element to display above the title. * If not provided, no icon will be shown. * Should typically be an SVG or Icon component with appropriate styling. */ icon?: React.ReactNode; /** * Main heading text displayed prominently to describe the empty state. * This should be a clear, concise description of what's missing. */ title: string; /** * Optional descriptive message providing additional context or instructions. * Displayed below the title in smaller, muted text. */ message?: string; /** * Optional action element (typically a Button) to help users resolve the empty state. * Displayed below the message text if provided. * * @example * */ action?: React.ReactNode; /** * Additional CSS class names to apply to the root container. * Useful for custom styling, spacing adjustments, or theme variations. */ className?: string; /** * Optional accessible label for the empty state container. * If not provided, defaults to "Empty state". * Used by screen readers to describe the purpose of this section. */ ariaLabel?: string; /** * Controls the maximum width of the content area. * @default "md" - Sets max-width to 28rem (448px) */ maxWidth?: 'sm' | 'md' | 'lg' | 'xl'; /** * Controls the vertical alignment within the container. * @default "center" - Centers content vertically in available space */ verticalAlign?: 'top' | 'center' | 'bottom'; /** * Controls the horizontal alignment of text content. * @default "center" - Centers all text content */ textAlign?: 'left' | 'center' | 'right'; } /** * EmptyState molecule displays a message when no content is available * * Features: * - Flexible icon display with custom icon support * - Clear title and optional descriptive message * - Optional action button for user guidance * - Responsive design with configurable layout options * - Full accessibility support with ARIA labels and semantic HTML * - Consistent spacing and typography following design system * - Dark mode support with appropriate color variations * * Layout Structure: * - Icon (optional) - displayed prominently at the top * - Title - main heading describing the empty state * - Message (optional) - supporting text with additional context * - Action (optional) - call-to-action button or link * * @example * // Basic usage with title only * * * @example * // With custom icon and descriptive message * } * title="No rooms selected" * message="Choose a room from the sidebar to start chatting with your team" * /> * * @example * // With action button to resolve the empty state * } * title="No rooms available" * message="Create your first room to start collaborating" * action={ * * } * /> * * @example * // Custom styling and layout * */ export const EmptyState = ({ icon, title, message, action, className, ariaLabel = 'Empty state', maxWidth = 'md', verticalAlign = 'center', textAlign = 'center', }: EmptyStateProps) => { /** * Maps maxWidth prop to Tailwind CSS classes */ const maxWidthClasses = { sm: 'max-w-sm', md: 'max-w-md', lg: 'max-w-lg', xl: 'max-w-xl', }; /** * Maps verticalAlign prop to Tailwind CSS flexbox classes */ const verticalAlignClasses = { top: 'justify-start', center: 'justify-center', bottom: 'justify-end', }; /** * Maps textAlign prop to Tailwind CSS text alignment classes */ const textAlignClasses = { left: 'text-left', center: 'text-center', right: 'text-right', }; return (
{/* Icon Section */} {icon && ( )} {/* Title Section */}

{title}

{/* Message Section */} {message && (

{message}

)} {/* Action Section */} {action && (
{action}
)}
); }; // Set display name for better debugging experience EmptyState.displayName = 'EmptyState';