import * as React from 'react'; import { FileTextIcon } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { useTranslations } from 'next-intl'; /** * 空状态展示组件属性 * 用于统一显示无数据、无内容等空状态 */ export interface EmptyStateProps extends React.ComponentProps<'div'> { title?: string; description?: string; icon?: React.ComponentType<{ className?: string }>; actionText?: string; onAction?: () => void; iconSize?: 'sm' | 'md' | 'lg'; } /** * 空状态展示组件 * 用于统一显示无数据、无内容等空状态 * * @example * ```tsx * // 基础用法 * * * // 带操作按钮 * router.push('/create')} * /> * * // 自定义图标 * * ``` * @param {EmptyStateProps} props - 空状态展示组件属性 * @returns {React.ReactNode} 空状态展示组件 */ export function EmptyState({ title, description, icon: Icon = FileTextIcon, actionText, onAction, className, iconSize = 'md', }: EmptyStateProps) { const t = useTranslations('layout.empty'); const displayTitle = title ?? t('noData'); const displayDescription = description ?? t('noContent'); const iconSizes = { sm: 'size-10', md: 'size-12', lg: 'size-16' }; const iconInnerSizes = { sm: 'size-5', md: 'size-6', lg: 'size-8' }; return (
{displayTitle && (

{displayTitle}

)} {displayDescription && (

{displayDescription}

)} {onAction && actionText && ( )}
); } /** * 带边框的空状态组件 * 适合在卡片或容器内使用 * * @example * ```tsx * * ``` * @param {EmptyStateProps} props - 空状态展示组件属性 * @returns {React.ReactNode} 带边框的空状态组件 */ export function EmptyStateWithBorder(props: EmptyStateProps) { return (
); } /** * 简化版空状态组件(内联使用) * 适合在较小的区域显示 * * @example * ```tsx * * ``` * @param {Pick & { message?: string }} props - 简化版空状态组件属性 * @returns {React.ReactNode} 简化版空状态组件 */ export function EmptyInline({ message, icon: Icon = FileTextIcon, className, }: Pick & { message?: string }) { const t = useTranslations('layout.empty'); const displayMessage = message ?? t('noData'); return (
{displayMessage}
); }