index.tsx raw
1 import { cn } from '@/lib/utils'
2 import { TEmoji } from '@/types'
3 import { Heart } from 'lucide-react'
4 import { HTMLAttributes, useState } from 'react'
5
6 export default function Emoji({
7 emoji,
8 classNames
9 }: Omit<HTMLAttributes<HTMLDivElement>, 'className'> & {
10 emoji: TEmoji | string
11 classNames?: {
12 text?: string
13 img?: string
14 }
15 }) {
16 const [hasError, setHasError] = useState(false)
17
18 if (typeof emoji === 'string') {
19 return emoji === '+' ? (
20 <Heart className={cn('size-5 text-red-400 fill-red-400', classNames?.img)} />
21 ) : (
22 <span className={cn('whitespace-nowrap', classNames?.text)}>{emoji}</span>
23 )
24 }
25
26 if (hasError) {
27 return (
28 <span className={cn('whitespace-nowrap', classNames?.text)}>{`:${emoji.shortcode}:`}</span>
29 )
30 }
31
32 return (
33 <img
34 src={emoji.url}
35 alt={emoji.shortcode}
36 draggable={false}
37 className={cn('inline-block size-5 rounded-sm pointer-events-none', classNames?.img)}
38 onLoad={() => {
39 setHasError(false)
40 }}
41 onError={() => {
42 setHasError(true)
43 }}
44 />
45 )
46 }
47