Download vetcopilot-app/src/components/FavoriteButton.tsx from WWsCa/VetNet-LCPS: direct link, hf CLI and curl.
- Browser
- Download file 1.75 kB
-
https://huggingface.co/WWsCa/VetNet-LCPS/resolve/main/vetcopilot-app/src/components/FavoriteButton.tsx
- Command line
-
hf download hf://WWsCa/VetNet-LCPS/vetcopilot-app/src/components/FavoriteButton.tsx
-
curl -L -o FavoriteButton.tsx https://huggingface.co/WWsCa/VetNet-LCPS/resolve/main/vetcopilot-app/src/components/FavoriteButton.tsx
1.75 kB
| import React, { useState } from 'react' | |
| import { useTranslation } from '../i18n' | |
| interface FavoriteButtonProps { | |
| active?: boolean | |
| onChange?: (active: boolean) => void | |
| size?: 'sm' | 'md' | 'lg' | |
| className?: string | |
| } | |
| export default function FavoriteButton({ active = false, onChange, size = 'md', className = '' }: FavoriteButtonProps) { | |
| const { t } = useTranslation() | |
| const [isActive, setIsActive] = useState(active) | |
| const [animating, setAnimating] = useState(false) | |
| const sizeClasses = { sm: 'w-6 h-6', md: 'w-8 h-8', lg: 'w-10 h-10' } | |
| const iconSizes = { sm: 'w-3.5 h-3.5', md: 'w-4 h-4', lg: 'w-5 h-5' } | |
| const handleClick = (e: React.MouseEvent) => { | |
| e.stopPropagation() | |
| const newState = !isActive | |
| setIsActive(newState) | |
| if (newState) { | |
| setAnimating(true) | |
| setTimeout(() => setAnimating(false), 400) | |
| } | |
| onChange?.(newState) | |
| } | |
| return ( | |
| <button | |
| onClick={handleClick} | |
| className={`${sizeClasses[size]} rounded-full flex items-center justify-center transition-all duration-300 | |
| ${isActive ? 'bg-red-50 text-red-500 scale-110' : 'bg-gray-100 text-gray-400 hover:bg-gray-200 hover:text-gray-500'} | |
| ${animating ? 'animate-heart-beat' : ''} | |
| ${className}`} | |
| aria-label={isActive ? t('components.favorite.remove') : t('components.favorite.add')} | |
| > | |
| <svg className={iconSizes[size]} viewBox="0 0 24 24" fill={isActive ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth={2}> | |
| <path strokeLinecap="round" strokeLinejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" /> | |
| </svg> | |
| </button> | |
| ) | |
| } | |