import React from 'react' import { useTranslation } from '../i18n' /** * LoadingSpinner * * 兽医主题加载动画组件。 * 支持三种风格:paw(爪印)、heartbeat(心跳线)、dna(DNA 双螺旋) * * Props: * size - 尺寸:'sm' (24px) / 'md' (40px) / 'lg' (64px) * variant - 风格:'paw' / 'heartbeat' / 'dna' / 'spinner'(默认 paw) * label - 无障碍文本,默认 "加载中..." * className - 额外的包裹层 class * colorClass - 自定义颜色类(如 'text-blue-500') */ export type SpinnerSize = 'sm' | 'md' | 'lg' export type SpinnerVariant = 'paw' | 'heartbeat' | 'dna' | 'spinner' interface LoadingSpinnerProps { size?: SpinnerSize variant?: SpinnerVariant label?: string className?: string colorClass?: string } const SIZE_MAP: Record = { sm: 24, md: 40, lg: 64, } /** 爪印动画 SVG */ function PawSpinner({ size, colorClass }: { size: number; colorClass: string }) { const scale = size / 48 return ( {/* 主肉垫 */} {/* 四个趾垫 */} ) } /** 心跳线动画 SVG */ function HeartbeatSpinner({ size, colorClass }: { size: number; colorClass: string }) { return ( {/* 心跳线路径 */} {/* 脉冲点 */} ) } /** DNA 双螺旋动画 SVG */ function DnaSpinner({ size, colorClass }: { size: number; colorClass: string }) { return ( {/* 左侧螺旋 */} {/* 右侧螺旋(相位偏移) */} {/* 横杠 */} ) } /** 默认圆形旋转器 */ function DefaultSpinner({ size, colorClass }: { size: number; colorClass: string }) { const borderWidth = size <= 24 ? 3 : 4 return (
) } export default function LoadingSpinner({ size = 'md', variant = 'paw', label, className = '', colorClass = 'text-medical-600', }: LoadingSpinnerProps) { const { t } = useTranslation() const pxSize = SIZE_MAP[size] const renderSpinner = () => { switch (variant) { case 'paw': return case 'heartbeat': return case 'dna': return case 'spinner': default: return } } return (
{renderSpinner()} {label && ( {label} )} {!label && ( {t('common.loading')} )}
) } /** * 全屏加载覆盖层 * 用于页面级加载状态 */ export function LoadingOverlay({ message = '加载中...', variant = 'paw' as SpinnerVariant, }: { message?: string variant?: SpinnerVariant }) { return (
) }